apex-analyst
v0.4.1
Published
In-chart analysis toolbar: summary statistics, data inspection and trend fitting, via the Weave plugin API.
Readme
apex-analyst
An in-chart analysis toolbar for the ApexCharts product family. It attaches to a chart through the Weave plugin API and puts sixteen tools above it, in three menus: summary statistics, the data behind the chart, correlations, contribution and distribution; trend, moving average, EMA, bands, control limits and anomalies drawn over the chart; cumulative totals, a forecast and a focus filter; what every chart on the page says about one category; and a generated walkthrough of everything the others found.
It is a plugin, not a fork. Nothing here reaches into chart internals, so the package can move at its own pace and, in time, sit over the sibling products rather than only over charts.
Requires apexcharts 7.2.0 or later, which is the first release carrying the Weave contract this package attaches through.
Installation
npm install apex-analyst apexchartsInstalling an older apexcharts beside this package does not fail outright, which is the trap: npm warns that the peer is unmet, installs the older core anyway, and at runtime the chart logs plugin "analyst" targets Weave API v2, host is v1; skipped and no toolbar appears. If no toolbar shows up, check the installed core first.
apexcharts is a peer dependency. The Weave plugin host must be present: it is in the full bundle, and with the lean core you add it explicitly.
Use
One chart
import ApexCharts from 'apexcharts';
import 'apexcharts/features/weave'; // already in the full bundle
import {install} from 'apex-analyst';
install(ApexCharts);
new ApexCharts(el, {
chart: {type: 'line'},
series: [
{
name: 'MRR',
data: [/* ... */],
},
],
plugins: [{name: 'analyst'}],
}).render();Every chart on the page
import {installOnEveryChart} from 'apex-analyst';
installOnEveryChart(ApexCharts); // BEFORE creating any chartThat writes the plugin into the chart library's global defaults, so no chart needs a plugins entry of its own.
Order matters. Plugins are resolved when a chart is constructed, so a chart created before this call cannot be reached and nothing can retrofit it. A chart that declares its own top-level plugins array overrides the global default rather than merging with it, so such a chart must list analyst itself.
Script tag
<script src="apexcharts.js"></script>
<script src="apex-analyst.min.js"></script>
<script>
ApexAnalyst.installOnEveryChart(ApexCharts);
</script>Options
Passed per chart as plugins: [{name: 'analyst', options: {...}}], or once via the second argument to installOnEveryChart.
| Option | Type | Meaning |
| --- | --- | --- |
| tools | string[] | Narrow and order the toolbar by id: summary, data, trend, limits, anomalies, contribution, correlations, distribution, movingAverage, ema, bands, cumulative, forecast, focus, selection. |
| enabled | boolean | false keeps the plugin loaded but renders no toolbar until page(). |
The toolbar and the pane
The tools sit in three menus, and the grouping is the same promise the kinds make, so learning the menus is learning what each tool may do to your chart:
| Menu | Holds | What every tool in it promises | | --- | --- | --- | | Inspect | Summary, Data, Correlations, Contribution, Distribution, Selection, Narrative | Reads the chart. Nothing is drawn on it and nothing is written to it | | Overlay | Trend, Moving average, EMA, Bands, Limits, Anomalies | Drawn on the chart's own SVG until switched off. No series is added | | Transform | Cumulative, Forecast, Focus | Changes what is on the chart, or what is shown of it |
Present stays outside the menus as a button of its own: it is the one tool that reads every other tool's findings, and burying it in a menu of one would hide the thing that assembles everything else.
A menu with no applicable tools is not rendered at all, so a pie has no Overlay menu rather than one that opens onto an empty list. Each menu button carries a count of how many of its tools are currently on, which a flat row of buttons showed for free. options.tools still controls order: menus are laid out by where their first tool appears in your list.
Menus open with the pointer or with Enter, Space or ArrowDown; ArrowUp / ArrowDown walk the items and wrap, Home and End jump to the ends, Escape closes and returns focus to the menu button, and clicking anywhere outside closes it.
Light and dark
The toolbar and the pane follow the chart, not the operating system. The host resolves its own light/dark (theme.mode) and this takes that answer, so an application whose dark mode is a class it sets itself gets dark chrome even while prefers-color-scheme says light. Where the host reports no mode at all, prefers-color-scheme is the fallback.
Every colour is a CSS custom property on the toolbar's host element, so a page that wants its own palette sets --apx-analyst-bg, --apx-analyst-fg, --apx-analyst-muted, --apx-analyst-border, --apx-analyst-accent, --apx-analyst-accent-fg, --apx-analyst-hover, --apx-analyst-radius or --apx-analyst-font on .apexcharts-analyst and .apexcharts-analyst-panel. Those win over both the mode and the media query.
Where the readout goes
A readout opens in a pane with the tool's name and a close button. On a container at least 720px wide the pane docks to the right of the chart, and the chart gives up a gutter of a third of the container, held between 260 and 380px. Below that width, the pane sits under the chart with its height capped to the chart's own (minimum 220px) and scrolls inside itself.
Both layouts exist for one reason: a readout and the chart it describes have to be on screen together. An unbounded panel under a chart is taller than the viewport as soon as a data table runs to two dozen categories, and reading the bottom of it scrolls the chart off the top.
The chart is never pushed down the page by an opening pane, in either layout.
Docking works because the chart gives the room up: a chart sizes itself from its container, so nothing placed inside that container can narrow it, and the host has to do the arithmetic. That is api.reserve, added in apexcharts 7.2.0 (Weave v3), which is the floor this package's peer range declares. The call is feature-detected rather than declared, so the package still runs against a host without it and simply stacks; there is no such published version any more.
While docked, the package sets position: relative on your chart's container if it has no inline position of its own, and puts it back on teardown. A container you have already positioned is left exactly as you set it.
Tools
Tools come in five kinds, and the difference is a promise rather than an implementation detail.
Panel tools never touch the chart. Open one on any chart on any page and nothing has been mutated.
- Summary: n, min, max, mean, median, sample standard deviation and sum per visible series. Gaps are excluded and the count of excluded values is stated.
- Data: the values behind the chart, with the real category labels. A gap and a zero are shown differently. Long series are capped and the cap is reported. Point at a row, or walk the table with the arrow keys, and that category is marked on the chart: a dot on each visible series and a rule through them, so you can see where in the shape of the chart the row you are reading actually sits. The table takes one tab stop rather than one per row. Offered only where the layer can place an x, so a pie's table is just a table.
- Correlations (Premium): Pearson's r for every pair of visible series, strongest first by absolute value so a strong inverse pair ranks with a strong direct one. Values are paired on the x axis rather than by array position, so two series sampled at different points produce no row instead of a confident number relating observations taken at different times. The count behind each coefficient is shown, and a pair with fewer than five shared observations is left out: two points always give exactly 1.
- Contribution (Premium): what share of the total each part accounts for, ranked largest first. Several series are split by series, a single series (which is how a pie reads) by category. Everything past the top twelve is folded into one row, so the column still adds to the total. Offered only on charts whose values are amounts rather than levels: bar, column, pie, donut and polar area. A share of a total is undefined when the parts do not all share the sign of the whole, so a chart mixing positive and negative values gets that stated in the panel rather than a percentage over 100.
- Narrative (Premium): everything the other tools found, written out as continuous prose, with Copy and Download. The one readout meant to leave the page: it is the same findings Present walks through, set down as paragraphs you can paste into a ticket or send to someone who will read it without the chart in front of them. No tool names are printed against the paragraphs, because a report attributed line by line reads as several tools that happen to be adjacent rather than one account of the data. The export is Markdown, which is both a file you can keep and plain text that loses nothing pasted somewhere that has never heard of Markdown. It carries no generated-on date: a date is the most locale-sensitive thing a document can print, and these sentences are English only. Offered once the data has earned at least two findings, on the same reasoning as Present.
- Distribution (Premium): a histogram of each visible series, as a bar per bin with its count. The one tool here that throws the order away and asks what the numbers look like as a pile: where the mass sits, whether it is one lump or two, how long the tail is. Two clusters that a mean and a standard deviation would average into one show up immediately. Bin edges are chosen by the narrower of Freedman-Diaconis and Sturges (NumPy's
auto, robust to outliers with a guard for the case where more than half the values agree), capped at twenty bins so the block stays readable. Every series is binned on one shared set of edges framed on their combined extent, so the blocks can be read against each other. Bars are scaled to the tallest bin rather than to the total, so a flat distribution is a row of equal bars and not a row of stubs. Gaps are not observations and are not counted; how many were skipped is stated. A series under 8 observations is left out. Point at a bar, or walk it with the arrow keys, and every observation in that bin is marked on the chart, which hands back the order a histogram throws away: you can see whether a tall bin is one stretch of the series or scattered right through it. - Selection (Premium): what every chart on the page says about the category you have selected, one row per series. Offered only on a chart that is coordinated with another, which is a property of the page rather than of this chart. It reports values and nothing else: no total, no mean, no share. See Charts that are views of the same thing for what makes a selection and which charts answer it.
Toggle tools draw on the chart until switched off.
- Trend: a dashed least-squares guide line per visible series, in that series' own colour, repainted whenever the data changes.
- Moving average (Premium): a trailing simple mean per visible series, drawn solid so it reads apart from the dashed trend line. Trend answers which way the series is going overall; this answers what the level is now with the noise taken out, and follows the shape of the data. The window is a tenth of the series, bounded to between 3 and 30 points, so a year of months gets 3 and a year of days gets 30. A window containing a gap produces no value rather than an average of fewer points, so the line breaks where the data does. A series under 6 points is not smoothed. The averaging comes from
@apex/commons, shared with the stock product so both compute it the same way. - EMA (Premium): an exponentially weighted moving average per visible series, short-dashed so it stays apart from the solid moving average and the long-dashed trend line. Same window as Moving average, and seeded from the mean of the first complete window rather than the first value, so the two lines start at the same x and can be read against each other. It weights recent points more heavily, so it turns at a change sooner and rings a little afterwards; on a quiet series the two sit almost on top of each other. Worth switching on when the question is when something turned, not what the level is.
- Bands (Premium): a moving standard deviation drawn either side of the moving mean, two deviations out, as a faint filled ribbon with an edge on each side. Where Limits computes one level from the whole series and asks whether the process is stable, this travels with the data and asks whether the last few points are unusual against the few just before them, so a steadily drifting series stays inside its bands the whole way and breaks its control limits at both ends. No middle line is drawn: the centre of the band is exactly what Moving average draws, from the same window, so switching both on gives the conventional three-line picture with nothing drawn twice. Where the band leaves the visible range the fill is clipped to the plot and the edge stops, rather than being flattened along the axis where it would claim a boundary that is not there.
- Limits (Premium): the mean of each visible series with a three-sigma band around it. The band is clipped to the plot, so it reads as "everything visible is within limits" when the limits themselves sit outside the axis, which for a typical series is most of the time. A limit that does fall inside the view gets its own dashed edge.
- Anomalies (Premium): a ring around each point that falls outside its series' Tukey fences, a quartile and a half beyond the middle half of the data, which is the same rule a box plot draws its whiskers to. The ring is the series' own colour, so on a chart with several series it says which one the outlier belongs to, and it is drawn well clear of the point with a backing stroke in the chart's ground beneath it, so it reads as a mark around the point rather than a restyling of it even where it crosses the series' own line. Deliberately not a standard-deviation rule: a large spike inflates the standard deviation enough to hide itself, and the quartiles cannot be moved that way, so this and Limits can disagree about the same point. That is the two tools answering different questions, not a contradiction. A series needs at least five points, and some spread in its middle half, to be assessed at all; one that has neither is skipped rather than covered in marks. Switching it on and seeing no rings is the answer: nothing in view is unusual.
Derived tools put a computed series on the chart until switched off. One kind only, and used sparingly, because a series changes your chart: the legend gains an entry, the tooltip a row, the export a column, and the axis rescales. The bar for it is that the VALUES are the point rather than the shape.
Cumulative (Premium): a running total of each visible series, added as a real series so the numbers are in the tooltip and the CSV export. Offered on bar and column only, the same amounts-not-levels judgement Contribution makes: a running total of monthly revenue is a total, a running total of temperature is nonsense, and nothing in the data says which you have. The total stops at the first gap rather than treating a missing value as zero, which would understate every point after it while looking correct. If one of your own series is already called
X (cumulative)the tool declines rather than replacing it.Forecast (Premium): the least-squares fit projected past the last observation, joined to it so the line continues rather than floating. Offered on line and area only, because adding a series to a bar chart regroups every bar and your existing ones get narrower. It also needs an explicit numeric x, so a datetime or numeric axis: a category axis has no future slot, and inventing one would mean writing your
xaxis.categories, which this package does not do. The horizon is a tenth of the series up to twelve points, because a straight line stops meaning anything long before it stops being drawable. It is a straight-line projection: not seasonal, no confidence interval. The projected series says twice that it is computed rather than measured: it is drawn dashed, the same way the drawn tools mark a computed line, and it takes its source series' own hue, muted toward the chart's background, so you can see which series it projects while it stays clearly behind the data. The colour matters on its own, because the palette is indexed by series position and cycles: a chart that names one colour for its one series would otherwise hand that same colour to the projection. That needs a host that reports your ownstroke.dashArray(Weave v5), which 7.3.0 does not: dashing one series means writing the array that covers all of them, and this package will not do that without knowing what to put back. Feature-detected, so on a host without it the forecast is solid and told apart by its name and colour, exactly as before.
Filter tools change what is shown, never what is there. Everything they do is something a viewer can already do by clicking the legend, so nothing is stored and there is nothing to restore incorrectly.
- Focus (Premium): every series ranked by total magnitude, with one click to show only that one and one to bring them all back. A legend toggles a single series at a time, so isolating one of eight is seven clicks; this is one. Ranking on magnitude rather than the signed sum, so a series that swings hard in both directions still ranks as a big one. The category and value-range filters this feature normally carries are deliberately absent: there is no chart API for them, so they would mean rewriting your series data and holding a copy to put back, and that copy goes stale the moment you update the chart yourself.
Present steps through what the other tools found. The only tool of its kind, and the only one that computes nothing of its own.
Present (Premium): a generated walkthrough of your chart, one finding at a time, with the chart put into the state each finding describes. On the trend slide the trend line is on the chart, on the anomalies slide the rings are, on the forecast slide the projection is, and nothing else is, so you are looking at the evidence for the sentence you are reading and at nothing that competes with it. Advance with the buttons or the arrow keys,
HomeandEndfor the ends,Escapeto leave; whatever you had switched on before you opened it comes back when you do.The deck is generated, not authored: there is no editor, and it does not advance on a timer. Slides are contributed by the tools themselves, and only when they found something worth saying, which is a higher bar than being applicable. Anomalies offers its button on any series whose fences can be computed, because "nothing here is unusual" is an answer; it contributes a slide only when something is actually outside them. So a well-behaved chart gets a short deck, and the button is absent entirely below two findings, because one finding is a sentence and the tool that found it is already in the toolbar saying it better.
The order is a narrative rather than the toolbar's: what the data is, then its shape, its direction, how it divides up and relates, what broke, and last of all a projection, after all the evidence for it. On a live chart the deck changes as the data does, and a finding can vanish mid-presentation; the position clamps rather than the deck closing under you.
Every tool declares which charts it can read. A tool that cannot work on this chart type is not rendered at all, so the toolbar is shorter on a pie than on a time series rather than offering a button that fails.
A tool your licence does not cover is dropped the same way, for the same reason: absent from the toolbar rather than present and refusing on click. Tools marked Premium above need a Premium licence or above; the rest need none.
Drawing tools need a chart the host can place an x on
The six tools that draw (Trend, Moving average, EMA, Bands, Limits, Anomalies) put their pixels on the chart through the host's own projection, which is what keeps them on the data under zoom, pan and resize. One chart shape defeats that projection in apexcharts 7.2.0-rc.2: a bar or column chart on a category axis, where the host never computes an x range, so every value in your data projects to the same pixel.
Rather than draw nothing, those six are absent from the toolbar there, the same as on a chart type they cannot read. The readouts (Summary, Data, Contribution, Distribution, Correlations) and the derived tools (Cumulative, Forecast) are unaffected, because none of them needs a pixel.
The same bar chart with a datetime or numeric x is fine and gets all six, so this is that one combination rather than bar charts in general. It is tested live against the host on every render rather than hardcoded as a list of chart types, so the day the host places a category bar the tools come back on their own.
Charts that are views of the same thing (Premium)
On a page carrying several charts, point at or click a point on one of them and every chart showing the same category marks it too: a dot on each visible series and a rule through them, exactly as a readout's own marking looks. Nothing is filtered and nothing is recomputed; this is the selection being shown in more than one place at once.
A click sticks until you click it again, so you can look away and the selection is still there. A hover on top of a selection shows the hovered point and puts the selection back when you move off.
Which charts count as related is inferred, conservatively. Two charts are views of the same thing when they share at least two category labels AND the overlap covers at least half the smaller of the two label lists. One shared label is a coincidence, because "Total", "Other" and "N/A" turn up on charts that have nothing to do with each other, and half the smaller list is what lets a chart of three months relate to a chart of twelve without letting two long lists relate on a handful of names they happen to share. Relations are transitive: if A relates to B and B to C, all three coordinate, so a selection always means the same thing whichever chart you made it on.
Categories are what the charts are matched on, so a pie of regions and a bar chart of regions coordinate without either knowing about the other. A chart whose categories are all numbers is not coordinated, which rules out datetime and numeric axes: where an axis carries no labels of its own the chart library numbers the slots, so two unrelated scatter charts of ten points each report the same ten "labels", and grouping on that would relate charts on the strength of both having ten points. Exact timestamps would be a sound key for two series sampled at the same instants, and that narrower case is left until what "close enough" means for a timestamp has an answer.
Selection, the readout (Premium)
With a selection made, the Selection readout in the Inspect menu lists what every chart in the group says about it: one row per series, with the chart it is on and its value at the selected category. It is offered only on a chart that is actually coordinated with another, and only under a Premium licence.
An open readout follows the selection rather than holding the one it was opened on. The selection is made on some other chart, and nothing about that click renders this one, so the readout repaints itself: point somewhere else in the group and the table is rebuilt from the page as it is now.
It carries no total, no mean and no share, and that is a decision rather than an omission. Adding a revenue series to a margin percentage produces a number with no meaning, and a readout would present it as confidently as a real one. A page-level aggregate needs the page to declare what its columns mean, and nothing in a chart's config says that, so the numbers come back per series, where the units are known.
Sending a selection to someone (Premium)
import {shareSelection} from 'apex-analyst';
shareSelection();With that called once, a clicked selection goes into the URL and a URL that carries one restores it:
https://example.com/reports#apex-analyst=revenue,heads:EUCharts are named by their container's id, which is the one name that survives a reload, so give your containers ids if you want links that keep working. A chart with no id gets a generated one that is only good for the session.
It is opt-in because the URL is yours, not ours. A drop-in script that rewrote your fragment uninvited would be a hazard rather than a feature, since plenty of applications route on the hash. With it on, this package is still a good neighbour there:
- Every other segment of the fragment keeps its text and its position, including a bare anchor like
#section-2. Only theapex-analystentry is touched, and it goes back where it was rather than moving to the end. - The URL is written with
replaceState, so nohashchangefires (a hash router does not navigate) and a selection does not fill the back button with steps nobody took. - Only a clicked selection is written. A hover is where the pointer happens to be rather than a view anyone chose.
- A link is opened before any chart has rendered, so a selection it carries is applied as each group of related charts forms, and only once: clear it and it stays cleared.
- A key the charts no longer carry is dropped rather than restored onto nothing, so a link outliving a data change still works as far as it can.
A link can carry several keys per group, and restores them all. Nothing in the interface produces more than one yet: a click selects a category and clicking it again clears it.
A selection is shown on a pie's partner charts, but not on the pie itself: marks are placed through the host's projection and a pie has none, so there is no pixel here this package is entitled to compute.
Needs apexcharts 7.3.0 or later, which added the pointer surface (Weave v4) this reads. It is feature-detected, not declared, so on an older core every tool above works exactly as documented and only this coordination is absent.
What it will not do to your chart
An add-on that mutates a chart it did not create can damage it in ways that look like library bugs. This package's answer is architectural: panel and toggle tools DRAW on the plugin's own layer inside the chart's SVG, through the host's projection, and never write to the chart itself.
Everything below holds for every tool except the derived ones, which are listed separately above and named as such wherever they appear.
- No series is added: your legend, tooltip, CSV export and
resetSeries()snapshot stay exactly yours. - No config is written:
markers,stroke,dataLabelsand every other series-indexed option keep the values you set. - Drawings carry no pointer events and are hidden from screen readers, so tooltips and accessibility read the chart, not the analysis.
- Drawings are clipped to the grid and projected through the same scales your series were painted with, so they stay aligned under zoom, pan and resize.
- The drawing rides inside the chart's own SVG, so
dataURI()and the PNG/SVG exports include it with no extra work. - Switching a tool off leaves the chart exactly as it was, because there is nothing to undo.
- A readout may mark the points you are pointing at, and another chart on the page may mark the category it is selecting. Both are drawn on the plugin's own layer. Your chart's own marks are never restyled to make ours stand out, so there is no state to restore and nothing that can be left behind if a render lands mid-hover.
- A selection made on another chart changes nothing about this one: no series is hidden, no data is filtered, no option is written. Coordination is a mark and nothing else.
A filter tool touches only visibility, through the same mechanism the legend uses. Your data and options are untouched.
A derived tool is the one exception, and it is bounded rather than open-ended. It adds series and nothing else: it never rewrites your series, your data or your options, beyond narrowing dataLabels.enabledOnSeries so the chart does not print labels over its output, which is restored when the last derived series goes. Its series are declared to the host, so resetSeries() and the toolbar's reset restore your data and not ours. Switching it off removes them and leaves your own series byte for byte as they were.
What the legend does while a derived series is on the chart
Hiding a series in the legend is yours, and adding a computed one is not a reason to change what you chose to look at. So a write this layer makes keeps every legend hide exactly as it found it, including a hide of the computed series itself: switch our series off in the legend and it stays off.
Hiding every series a derived tool reads is the one case where it stops recomputing and keeps what it already drew, instead of taking its series off. That is deliberate. Its series is a legend entry too, and on a chart that would be left with one series the legend is not drawn at all, so removing ours would take away the control you were about to use to bring yours back. Un-hiding recomputes; the tool's own button is still there and still switches it off.
API
Attaching
| Member | Description |
| --- | --- |
| install | Register the plugin on a chart constructor. Charts then opt in with plugins: [{name: 'analyst'}]. |
| installOnEveryChart | Register the plugin and write it into the chart library's global defaults, so every chart created afterwards carries it. Takes the shared AnalystOptions as its second argument. |
| page | Attach to charts already on the page, for a plugin loaded with enabled: false. |
| shareSelection | Keep the page's selection in the URL, and restore one that is already there. Opt-in; pass false to stop. |
| analystPlugin | The raw Weave plugin definition, for passing to a host yourself. |
| PLUGIN_NAME | The name the plugin registers under: 'analyst'. |
| Analyst | The per-chart instance the plugin creates. Rarely constructed directly. |
| AnalystOptions | The options above, as a type. |
Reading the chart
The model a tool sees. Useful for writing a tool of your own, or for reading the chart's data without one.
| Member | Description |
| --------------- | ----------------------------------------------------------------------------- |
| buildModel | Build the analysis model from a Weave API handle. |
| AnalystModel | The whole model: the visible series and the chart's categories. |
| AnalystSeries | One series in the model: its name, values and the x basis the scales project. |
Statistics
Standalone and chart-free, so they can be used on their own.
| Member | Description |
| ----------- | --------------------------------------------------------------------------------- |
| summarize | n, min, max, mean, median, sample standard deviation and sum for a set of values. |
| Summary | What summarize returns, including the count of excluded gaps. |
| finite | The finite numbers in a set, dropping gaps and non-numbers. |
| linearFit | Least-squares fit over [x, y] points. |
| LinearFit | The fitted line: slope, intercept and the predictor. |
| FitPoint | One point given to linearFit. |
Drawing
Exported because any tool drawing on someone else's chart needs them.
| Member | Description |
| ------------- | ---------------------------------------------------------------------------- |
| clipSegment | Clip a line segment to a rectangle, so a drawing cannot paint over the axes. |
| PixelRect | The grid rectangle clipSegment clips to, in pixel space. |
Formatting
| Member | Description |
| --------------- | --------------------------------------------------------------------- |
| formatNumber | Format a number for a readout, at a sensible precision. |
| formatPercent | Format a fraction as a percentage. |
| NO_VALUE | What a readout shows for a gap, so a gap and a zero read differently. |
Writing a tool
| Member | Description |
| --- | --- |
| Tool | Union of the five tool kinds. |
| PanelTool | A tool that only reads, and renders into the panel. |
| PanelContext | What a panel tool is given beyond the model: findings(), emphasise(), canEmphasise and page(). Ignored by most. |
| PageSelection | What the rest of the page says about the current selection, or null when this chart is coordinated with nothing. Carries no aggregate, on purpose. |
| PageSelectionRow | One chart's one series under that selection, with its value at each selected key. |
| EmphasisPoint | One point a panel tool wants marked on the chart, addressed by series index and position. |
| drawEmphasis | Draw those marks on an overlay surface. Used by the layer's own repaint pass; exported for a host driving the drawing itself. |
| ToggleTool | A tool that draws on the chart's overlay layer until switched off. |
| DerivedTool | A tool that puts a computed series on the chart until switched off. |
| DerivedSeries | One series a derived tool wants added, in the source series' own data shape, and whether to draw it dashed. |
| FilterTool | A tool that changes which series are shown, and nothing else. |
| FilterActions | The two visibility operations a filter tool is given: isolate and showAll. |
| PresentTool | A tool that steps through the other tools' findings. Present is the only one. |
| PresentActions | What a present tool is given: the deck, the position, goTo and exit. |
| OverlaySurface | What a toggle tool draws with: the layer, the scales, the chart's palette and the ground it is drawn on. Per paint. |
| Finding | What a tool has to say about this data: a headline, and the evidence for it. |
| Slide | One tool's finding, with the id and label of the tool that found it. |
| buildDeck | Build the narrative-ordered deck from a model and a set of tools. |
| MIN_SLIDES | Findings needed before a deck is a walkthrough rather than a sentence. |
A tool contributes a slide by implementing the optional finding(model), which is a higher bar than appliesTo: it returns null unless the numbers that came back are worth saying out loud. Several built-in tools deliberately have none.
Weave host types
The shape of the plugin host, for typing your own plugin against it.
| Member | Description |
| ----------------------- | ------------------------------------------------------------------------------------ |
| WeaveAPI | The frozen facade a plugin is handed. |
| WeavePluginDefinition | A plugin: its name, api version, setup and teardown. |
| WeaveHook | The lifecycle hooks a plugin can subscribe to. |
| WeaveSeries | One series as the host presents it, parsed values and raw data alike. |
| WeaveChartInfo | What the host reports about the chart: type, axis kind, data-label and stroke state. |
| WeaveChartMethods | The chart methods the host lets a plugin call, such as updateSeries. |
| WeaveLayer | The plugin's own <g> in the chart's SVG, wrapped in drawing primitives. |
| WeaveScales | Data-to-pixel projection, built from the same ratios the series were painted with. |
| WeaveTheme | The host's resolved theme: mode, foreground colour and the series palette. |
| WeavePointerEvent | A point the viewer is pointing at, as the host resolved it for its own tooltip. |
| ApexChartsCtor | The chart constructor shape install accepts. |
Licensing
Not open source. The source being readable on GitHub does not make it so.
Free under the Community terms for organisations under the revenue threshold; a Commercial licence is required otherwise. Without a valid key the toolbar keeps working and the chart carries a trial watermark, which is deterrence and honest-customer compliance rather than DRM: it never degrades a tool. Keys are shared across the ApexCharts family, so one key covers this too.
