@peter.prib/renderengine 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +454 -302
- package/dist/renderengine-workspace.umd.js +2203 -113
- package/dist/renderengine.umd.js +2203 -113
- package/documentation/REFERENCE.md +30 -1
- package/package.json +8 -3
- package/src/chartCatalog.js +50 -3
- package/src/charting/Chart3D.js +4 -2
- package/src/charting/Hierarchy.js +28 -0
- package/src/charting/ask/AskBar.js +388 -0
- package/src/charting/ask/AskView.js +400 -0
- package/src/charting/charts/AreaChart.js +20 -3
- package/src/charting/charts/BarChart3D.js +2 -2
- package/src/charting/charts/BarChart3DOrbit.js +3 -1
- package/src/charting/charts/BoxPlotChart.js +2 -2
- package/src/charting/charts/BubbleChart.js +4 -1
- package/src/charting/charts/ChordDiagram.js +4 -4
- package/src/charting/charts/DensityChart.js +1 -1
- package/src/charting/charts/FunnelChart.js +1 -1
- package/src/charting/charts/HeatmapChart.js +4 -1
- package/src/charting/charts/HistogramChart.js +2 -2
- package/src/charting/charts/IcicleChart.js +47 -0
- package/src/charting/charts/LollipopChart.js +104 -0
- package/src/charting/charts/MarimekkoChart.js +75 -0
- package/src/charting/charts/OutlineChart.js +10 -8
- package/src/charting/charts/ParallelCoordinatesChart.js +2 -2
- package/src/charting/charts/ParetoChart.js +92 -0
- package/src/charting/charts/PipeChart.js +5 -2
- package/src/charting/charts/PopulationPyramidChart.js +4 -4
- package/src/charting/charts/RadarChart.js +5 -4
- package/src/charting/charts/RadialBarChart.js +2 -2
- package/src/charting/charts/SankeyDiagram.js +4 -4
- package/src/charting/charts/ScatterChart.js +6 -3
- package/src/charting/charts/StackedBarChart.js +82 -11
- package/src/charting/charts/StackedBarChart3DOrbit.js +5 -2
- package/src/charting/charts/StreamGraphChart.js +8 -0
- package/src/charting/charts/SunburstChart.js +2 -2
- package/src/charting/charts/TreemapChart.js +4 -4
- package/src/charting/charts/ViolinChart.js +2 -2
- package/src/charting/charts/WaterfallChart.js +2 -2
- package/src/charting/charts/WordCloudChart.js +2 -2
- package/src/charting/pivot/PivotChart.js +205 -13
- package/src/charting/pivot/PivotGridChart.js +1 -1
- package/src/charting/pivot/PivotView.js +544 -21
- package/src/index.js +98 -2
package/src/index.js
CHANGED
|
@@ -33,6 +33,10 @@ import { LagPlotChart } from './charting/charts/LagPlotChart.js';
|
|
|
33
33
|
import { TreemapChart } from './charting/charts/TreemapChart.js';
|
|
34
34
|
import { SunburstChart } from './charting/charts/SunburstChart.js';
|
|
35
35
|
import { OutlineChart } from './charting/charts/OutlineChart.js';
|
|
36
|
+
import { IcicleChart } from './charting/charts/IcicleChart.js';
|
|
37
|
+
import { ParetoChart } from './charting/charts/ParetoChart.js';
|
|
38
|
+
import { LollipopChart } from './charting/charts/LollipopChart.js';
|
|
39
|
+
import { MarimekkoChart } from './charting/charts/MarimekkoChart.js';
|
|
36
40
|
import { TableChart } from './charting/charts/TableChart.js';
|
|
37
41
|
import { ChartChooser } from './charting/ChartChooser.js';
|
|
38
42
|
import { TableView } from './charting/table/TableView.js';
|
|
@@ -40,6 +44,8 @@ import { TableViewChart } from './charting/table/TableViewChart.js';
|
|
|
40
44
|
import { PivotView } from './charting/pivot/PivotView.js';
|
|
41
45
|
import { PivotGridChart } from './charting/pivot/PivotGridChart.js';
|
|
42
46
|
import { PivotChart } from './charting/pivot/PivotChart.js';
|
|
47
|
+
import { AskView } from './charting/ask/AskView.js';
|
|
48
|
+
import { AskBar } from './charting/ask/AskBar.js';
|
|
43
49
|
import { RadarChart } from './charting/charts/RadarChart.js';
|
|
44
50
|
import { FunnelChart } from './charting/charts/FunnelChart.js';
|
|
45
51
|
import { WaterfallChart } from './charting/charts/WaterfallChart.js';
|
|
@@ -228,7 +234,8 @@ import {
|
|
|
228
234
|
// separate browser-only entry: import 'renderengine/src/workspace.js' directly.
|
|
229
235
|
|
|
230
236
|
export {
|
|
231
|
-
Mat4, OrbitCamera, CHART_CATALOG, getChartCatalogEntry, chartRegistry, ChartChooser, TableChart, TableView, TableViewChart, PivotView, PivotGridChart, PivotChart,
|
|
237
|
+
Mat4, OrbitCamera, CHART_CATALOG, getChartCatalogEntry, chartRegistry, ChartChooser, TableChart, TableView, TableViewChart, PivotView, PivotGridChart, PivotChart, AskView, AskBar,
|
|
238
|
+
ParetoChart, LollipopChart, MarimekkoChart, IcicleChart,
|
|
232
239
|
DIAGRAM_CATALOG, getDiagramCatalogEntry, diagramRegistry,
|
|
233
240
|
TREE_MODE_CATALOG, treeModeRegistry, getTreeModeCatalogEntry,
|
|
234
241
|
AXIS_KIND, ENCODING_CHANNEL, COORD_SYSTEM, COLOR_MODE, CAMERA_MODE,
|
|
@@ -1500,6 +1507,39 @@ export class RenderEngine {
|
|
|
1500
1507
|
const back = this.renderer.text('◂ Table', 8, 14, { fill: '#2b5fd9', fontSize: '12px', verticalAlign: 'middle' });
|
|
1501
1508
|
back?.addEventListener?.('click', () => this._drawResultTable(view, options));
|
|
1502
1509
|
if (back?.style) back.style.cursor = 'pointer';
|
|
1510
|
+
const choices = view.chartChoices();
|
|
1511
|
+
if (choices.length > 1) {
|
|
1512
|
+
const pick = this.renderer.text(`${choice.label} ▾`, 68, 14, { fill: '#2b5fd9', fontSize: '12px', verticalAlign: 'middle', tooltip: choice.reason });
|
|
1513
|
+
const show = options.showMenu ?? ((x, y, items) => PopupMenu.show(x, y, items));
|
|
1514
|
+
pick?.addEventListener?.('click', (e) => show(e.clientX, e.clientY, choices.map(c => ({
|
|
1515
|
+
label: `${c.label}${c.key === choice.key ? ' ✓' : ''}`,
|
|
1516
|
+
action: () => this._drawResultChart(view, c, options),
|
|
1517
|
+
}))));
|
|
1518
|
+
if (pick?.style) pick.style.cursor = 'pointer';
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
/**
|
|
1523
|
+
* Mounts an interactive `AskBar` (question input, configurable next-word prediction in a
|
|
1524
|
+
* scrollable list, semantic sense/reference/relation badges, and sample query pills) into
|
|
1525
|
+
* `container` (or links `resultEngine: this` when called as `engine.askBar(container, options)`).
|
|
1526
|
+
* @param {HTMLElement|string|object} containerOrOptions host container element/id, or options when mounting into `this.container`
|
|
1527
|
+
* @param {object} [options] `AskBar` / `AskView` options (`suggest`, `measures`, `dimensions`, `members`, `sampleQuestions`, `visibleCount`, `predictChoices`, `onAsk`, etc.)
|
|
1528
|
+
* @returns {AskBar}
|
|
1529
|
+
*/
|
|
1530
|
+
askBar(containerOrOptions, options = {}) {
|
|
1531
|
+
const isPlainOptions = containerOrOptions
|
|
1532
|
+
&& typeof containerOrOptions === 'object'
|
|
1533
|
+
&& !containerOrOptions.nodeType
|
|
1534
|
+
&& typeof containerOrOptions.appendChild !== 'function';
|
|
1535
|
+
const container = isPlainOptions ? this.container : containerOrOptions;
|
|
1536
|
+
const opts = isPlainOptions ? containerOrOptions : options;
|
|
1537
|
+
return new AskBar(container, { resultEngine: this, ...opts });
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
/** Static helper: `RenderEngine.askBar(container, options)` constructs and mounts an `AskBar`. */
|
|
1541
|
+
static askBar(container, options = {}) {
|
|
1542
|
+
return new AskBar(container, options);
|
|
1503
1543
|
}
|
|
1504
1544
|
|
|
1505
1545
|
/**
|
|
@@ -1550,7 +1590,8 @@ export class RenderEngine {
|
|
|
1550
1590
|
pivotChart(view, options = {}) {
|
|
1551
1591
|
if (!this.renderer) return null;
|
|
1552
1592
|
const chart = new PivotChart(view, options);
|
|
1553
|
-
chart.
|
|
1593
|
+
chart.redraw = () => this._drawPivotChart(chart, options);
|
|
1594
|
+
chart.detach = view.listen(chart.redraw);
|
|
1554
1595
|
this._drawPivotChart(chart, options);
|
|
1555
1596
|
return chart;
|
|
1556
1597
|
}
|
|
@@ -1561,15 +1602,19 @@ export class RenderEngine {
|
|
|
1561
1602
|
if (choice === null) {
|
|
1562
1603
|
this.renderer.clear();
|
|
1563
1604
|
this.renderer.text('No chart fits what the grid shows', 8, 14, { fill: '#666', fontSize: '12px', verticalAlign: 'middle' });
|
|
1605
|
+
options.onDraw?.(null, chart);
|
|
1564
1606
|
return;
|
|
1565
1607
|
}
|
|
1566
1608
|
// No title unless one is given: the grid beside it says what is charted, and the link below
|
|
1567
1609
|
// names the chart (with the chooser's reason as its tooltip).
|
|
1568
1610
|
this.renderChartType(choice.key, choice.data, {
|
|
1611
|
+
...choice.options,
|
|
1569
1612
|
title: options.title,
|
|
1570
1613
|
legend: true, // a series per column member: which colour is which must be said
|
|
1571
1614
|
onDatumClick: (datum) => chart.click(datum),
|
|
1615
|
+
onNodeClick: (node) => chart.click({ label: node.label }),
|
|
1572
1616
|
});
|
|
1617
|
+
options.onDraw?.(choice, chart);
|
|
1573
1618
|
// Which chart, and the menu to change it, drawn over the chart as resultView's "◂ Table" is.
|
|
1574
1619
|
if (!this.renderer.supportsSceneGraph) return;
|
|
1575
1620
|
const pick = this.renderer.text(`${choice.label} ▾`, 8, 14, { fill: '#2b5fd9', fontSize: '12px', verticalAlign: 'middle', tooltip: choice.reason });
|
|
@@ -1587,6 +1632,57 @@ export class RenderEngine {
|
|
|
1587
1632
|
this.fitToContainer();
|
|
1588
1633
|
}
|
|
1589
1634
|
|
|
1635
|
+
/**
|
|
1636
|
+
* Renders an icicle chart — rectangular hierarchical partition chart (top-down bands by depth,
|
|
1637
|
+
* width proportional to value within each parent's span).
|
|
1638
|
+
* @param {Array<{label: string, value?: number, children?: Array}>} data
|
|
1639
|
+
* @param {object} [options]
|
|
1640
|
+
*/
|
|
1641
|
+
icicleChart(data, options = {}) {
|
|
1642
|
+
if (!this.renderer) return;
|
|
1643
|
+
this._chart3D = false;
|
|
1644
|
+
this._chartState = { type: 'icicle', data, options };
|
|
1645
|
+
this._renderChart(new IcicleChart(this.renderer, data, options));
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
/**
|
|
1649
|
+
* Renders a Pareto chart — categories sorted descending with a cumulative percentage line (0–100%)
|
|
1650
|
+
* on a right-hand axis and an 80% cutoff reference line.
|
|
1651
|
+
* @param {Array<{label: string, value: number}>} data
|
|
1652
|
+
* @param {object} [options]
|
|
1653
|
+
*/
|
|
1654
|
+
paretoChart(data, options = {}) {
|
|
1655
|
+
if (!this.renderer) return;
|
|
1656
|
+
this._chart3D = false;
|
|
1657
|
+
this._chartState = { type: 'pareto', data, options };
|
|
1658
|
+
this._renderChart(new ParetoChart(this.renderer, data, options));
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/**
|
|
1662
|
+
* Renders a lollipop chart — stem-and-dot alternative to bars for 1D or multi-series comparisons.
|
|
1663
|
+
* @param {Array<{label: string, value: number}>|Array<{name: string, values: Array<{label: string, value: number}>}>} data
|
|
1664
|
+
* @param {object} [options]
|
|
1665
|
+
*/
|
|
1666
|
+
lollipopChart(data, options = {}) {
|
|
1667
|
+
if (!this.renderer) return;
|
|
1668
|
+
this._chart3D = false;
|
|
1669
|
+
this._chartState = { type: 'lollipop', data, options };
|
|
1670
|
+
this._renderChart(new LollipopChart(this.renderer, data, options));
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
/**
|
|
1674
|
+
* Renders a Marimekko (mosaic) chart — variable-width 100%-stacked columns where column width is
|
|
1675
|
+
* proportional to each category's total and segment height is each series' share within that category.
|
|
1676
|
+
* @param {Array<{name: string, values: Array<{label: string, value: number}>}>|Array<{label: string, values: number[]}>} data
|
|
1677
|
+
* @param {object} [options]
|
|
1678
|
+
*/
|
|
1679
|
+
marimekkoChart(data, options = {}) {
|
|
1680
|
+
if (!this.renderer) return;
|
|
1681
|
+
this._chart3D = false;
|
|
1682
|
+
this._chartState = { type: 'marimekko', data, options };
|
|
1683
|
+
this._renderChart(new MarimekkoChart(this.renderer, data, options));
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1590
1686
|
/**
|
|
1591
1687
|
* Renders a waterfall chart — running-total bars, each floating from the
|
|
1592
1688
|
* previous cumulative value to the new one (a "delta" bar), except
|