scope/internal/cards/plot.go

90 lines
1.7 KiB
Go

package cards
import (
"fmt"
"html/template"
"strings"
)
const plotExtraHead = `
<script src="/static/function-plot.js"></script>
<style>
.top-right-legend {
display: none;
}
</style>`
const plotScript = `
<div id="plot-content" class="container"></div>
<script>
plotFn = () => functionPlot({
target: '#plot-content',
grid: true,
width: document.getElementById('plot-content').offsetWidth,
data: [{
fn: '%s'
}]
})
new ResizeObserver(plotFn).observe(document.getElementById('plot-content'))
</script>`
func init() {
// Register plot card
Register("plot", 2, NewPlotCard)
}
// PlotCard represents a card with an equation plot
type PlotCard struct {
query string
}
// NewPlotCard is a NewCardFunc that creates a new PlotCard
func NewPlotCard(query, _ string) Card {
return &PlotCard{query: query}
}
func (pc *PlotCard) Matches() bool {
return strings.HasPrefix(pc.query, "plot") ||
strings.HasPrefix(pc.query, "graph") ||
strings.HasPrefix(pc.query, "draw")
}
func (pc *PlotCard) StripKey() string {
query := strings.TrimPrefix(pc.query, "plot")
query = strings.TrimPrefix(query, "graph")
query = strings.TrimPrefix(query, "draw")
return strings.TrimSpace(query)
}
func (pc *PlotCard) Content() template.HTML {
return template.HTML(fmt.Sprintf(
plotScript,
pc.StripKey(),
))
}
// Since this card is frontend, this cannot be checked.
// Therefore, it will always return true.
func (pc *PlotCard) Returned() bool {
return true
}
func (pc *PlotCard) Title() string {
return "Plot (" + pc.StripKey() + ")"
}
func (pc *PlotCard) Head() template.HTML {
return plotExtraHead
}
func (pc *PlotCard) Footer() template.HTML {
return ""
}
func (pc *PlotCard) RunQuery() error {
return nil
}