@peter.prib/renderengine 0.1.0 → 0.2.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 CHANGED
@@ -124,7 +124,7 @@ Each model can hold several diagrams, with line styles inherited from the diagra
124
124
  ## The chart library
125
125
 
126
126
  The engine underneath draws 24 chart types: bar, line, area, pie, scatter, bubble, heatmap, candlestick,
127
- waterfall, histogram, box plot, violin, radar, funnel, treemap, sunburst, gauges, 3D bars and others. It also
127
+ waterfall, histogram, box plot, violin, radar, funnel, treemap, sunburst, gauges (dial, arc, ring, rings, bar, bullet, thermometer, KPI tiles; with bands, targets, LED segments and animation), 3D bars and others. It also
128
128
  draws graph and railroad diagrams, all to SVG or Canvas. `test/charts.html` is the full gallery, and
129
129
  `examples/csv-chart-builder.html` builds a chart from a CSV file without code.
130
130
 
package/REFERENCE.md CHANGED
@@ -81,9 +81,14 @@ catalog `key` for you.
81
81
  | `treemap` | `treemapChart(data, opts)` | `Array<{label, value?, children?}>` (hierarchical) | squarified layout, palette by top-level branch |
82
82
  | `sunburst` | `sunburstChart(data, opts)` | same hierarchical shape as `treemap` | nested rings by depth |
83
83
  | `outline` | `outlineChart(data, opts)` | same hierarchical shape as `treemap`/`sunburst` | `onNodeClick`; collapsible indented list |
84
- | `gauge-dial` | `dialGauge(value, opts)` | `number` (0–100) | `color`, `title` |
85
- | `gauge-bar` | `barGauge(value, opts)` | `number` (0–100) | `color`, `title` |
86
- | `bullet` | `bulletGauge(data, opts)` | `number` or `{value, target?, ranges?:Array<{max,label?,color?}>}` | `target`, `ranges`, `barColor`, `targetColor`, `min`, `max`, `title` |
84
+ | `gauge-dial` | `dialGauge(value, opts)` | `number`, `{value, target?}`, or `[{value, label?, color?}]` for a needle each (0–100 unless `min`/`max`) | the gauge options below; `cx`, `cy`, `r`, `thickness`, `startAngle`, `sweep`, `needleColors`; several needles get a legend, the first fills the arc |
85
+ | `gauge-bar` | `barGauge(value, opts)` | `number` or `{value, target?}` (0–100 unless `min`/`max`) | the gauge options below; `x`, `y`, `width`, `height`, `orientation: 'vertical'` |
86
+ | `gauge-arc` | `arcGauge(value, opts)` | `number` or `{value, target?}` | the gauge options below; `cx`, `cy`, `r`, `thickness`, `startAngle`, `sweep` (a half circle by default), `cap` |
87
+ | `gauge-thermometer` | `thermometerGauge(value, opts)` | `number` or `{value, target?}` | the gauge options below; `x`, `y`, `width`, `height` (the tube), `bulb` (its radius) |
88
+ | `gauge-ring` | `ringGauge(value, opts)` | `number` or `{value, target?}` | the gauge options below; a whole circle from the top, the value in the middle |
89
+ | `gauge-rings` | `multiRingGauge(values, opts)` | numbers or `{value, label?, color?, min?, max?}`, outer first | one ring per value on its own scale; `gap`, `colors`, `legend` |
90
+ | `kpi-tile` | `kpiTile(data, opts)` | `number` or `{value?, previous?, history?:number[]}` | the figure (grouped), its change (`change`: `'percent'` or `'value'`; `upIsGood`), a sparkline of the history; `x`, `y`, `width`, `height`, `bands`, `sparkColor`, `background` |
91
+ | `bullet` | `bulletGauge(data, opts)` | `number` or `{value, target?, ranges?:Array<{max,label?,color?}>}` | the gauge options below; `ranges` (its name for `bands`), `barColor`, `rangeColors`, `showLabels` |
87
92
  | `bar3D` | `barChart3D(data, opts)` | `Array<{label, value, depth?}>` | `depthScale`; fixed-angle isometric, not a real camera |
88
93
  | `bubble3D` | `bubbleChart3D(data, opts)` | `Array<{label, x, y, z, size?, category?}>` | real orbit camera — drag to rotate, wheel to zoom |
89
94
  | `bar3DOrbit` | `barChart3DOrbit(data, opts)` | `Array<{x, z, value}>` (grid) | real orbit camera |
@@ -92,6 +97,40 @@ catalog `key` for you.
92
97
  | `parallelCoordinates` | `parallelCoordinates(data, opts)` | `Array<{label?, category?, [dim: number]}>` | one vertical axis per numeric dimension; category-driven colors; `dimensions` |
93
98
  | `geoMap` | `geoMap(data, opts)` | `{features: Array<{id, name, value?, color?, geometry}>, bubbles?: Array<{lat, lon, value}>}` | equirectangular projection; `center`, `scale`, `colorScale`; see note below |
94
99
 
100
+ **Gauges.** Every gauge is a `GaugeChart` (`src/charting/charts/GaugeChart.js`) and takes the same options:
101
+
102
+ | Option | Meaning |
103
+ |---|---|
104
+ | `min`, `max` | The scale (0 and 100). A 0–100 scale reads as a percentage ("75.0%"), any other as its number |
105
+ | `format`, `units` | How numbers read: `(v) => string`, or `{decimals, prefix, suffix, grouping, compact}` ("$1,234.5", "12.3K"); `units` is a suffix ("120.0 ms") |
106
+ | `bands` | `[{to, color?, label?}]` in order, each from where the one before ended; drawn lighter behind the value, and the value takes its band's colour. `bandColors` colours the bands without their own |
107
+ | `color` | The value's colour (wins over its band's): one, a gradient array of colours or `{stop, color}`, or `(percent) => colour` |
108
+ | `target`, `targetColor` | A marker across the track at a value (or the data's `target`) |
109
+ | `ticks` | That many equal steps, marked outside the track and labelled with only the decimals a step needs |
110
+ | `segments`, `segmentGap` | The track as that many blocks, `segmentGap` pixels apart (2), lit up to the value (LED style); with bands each lit block takes its own band's colour, a level meter |
111
+ | `animate` | `true` (400 ms) or milliseconds: drawing the same type of gauge again on the same engine eases from the value it shows to the new one (the value, target and each of several values; ease-out). A newer value stops an older animation and starts from where it got to |
112
+ | `title` | |
113
+
114
+ ```js
115
+ engine.dialGauge(72, { min: 0, max: 120, units: 'km/h', ticks: 6, target: 100,
116
+ bands: [{ to: 80, color: '#6bcb77' }, { to: 100, color: '#ffd93d' }, { to: 120, color: '#ff6b6b' }] });
117
+ engine.barGauge({ value: 40, target: 55 }, { orientation: 'vertical', ticks: 4 });
118
+ engine.ringGauge({ value: 380 }, { max: 500, format: { decimals: 0, suffix: ' / 500' } });
119
+ engine.multiRingGauge([{ label: 'Move', value: 420, max: 600 }, { label: 'Stand', value: 9, max: 12 }]);
120
+ engine.kpiTile({ history: [182000, 191200, 214300] }, { title: 'Revenue', format: { prefix: '$', grouping: true } });
121
+ engine.dialGauge([{ label: 'Actual', value: 68 }, { label: 'Budget', value: 80 }], { animate: true });
122
+ engine.barGauge(84, { segments: 20, bands: [{ to: 70, color: '#2ed573' }, { to: 100, color: '#ff4757' }] });
123
+ ```
124
+
125
+ The pieces are in `src/charting/gauges/`: `GaugeScale` (range, fractions, ticks, formatting), `GaugeBands`
126
+ (the bands and which one a value is in), `GaugeValue` (value, target, previous, history, several values) and the
127
+ tracks a value moves along, `HorizontalTrack`, `VerticalTrack` (both `LinearTrack`s) and `ArcTrack` (any start
128
+ angle and sweep, a full ring included), `Sparkline` (a series fitted to a box) and `GaugeAnimation` (frames from `GaugeValue.between(from, to, t)` on an
129
+ injectable clock). A new gauge picks a track and
130
+ draws with `drawBackground`, `drawValue`, `drawTarget` and `drawTicks`; its `static LAYOUT` gives its default place
131
+ and size (`cx`, `cy`, `r`, ...), which the options of the same names override. `ArcGauge` → `RingGauge` is the
132
+ pattern: the ring only changes the layout and where the labels go.
133
+
95
134
  **`geoMap` note:** the `test/charts.html` demo uses deliberately rough, hand-drawn continental
96
135
  polygons so the page needs no external map file. Real use should pass proper GeoJSON-like
97
136
  `Polygon`/`MultiPolygon` features; the engine itself has no bundled world geometry and makes no