chartist 2.0.0-rc.3 → 2.0.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 +4 -4
- package/dist/chartist.min.js +2 -2
- package/dist/compat.cjs +7 -0
- package/dist/compat.cjs.map +1 -1
- package/dist/compat.js +7 -0
- package/dist/compat.js.map +1 -1
- package/dist/compat.min.js +1 -1
- package/dist/compat.min.js.map +1 -1
- package/dist/compat.umd.js +1 -1
- package/dist/compat.umd.js.map +1 -1
- package/dist/index.cjs +387 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +384 -128
- package/dist/index.d.ts +384 -128
- package/dist/index.js +384 -85
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/live.cjs +770 -0
- package/dist/live.cjs.map +1 -0
- package/dist/live.d.cts +203 -0
- package/dist/live.d.ts +202 -0
- package/dist/live.js +767 -0
- package/dist/live.js.map +1 -0
- package/dist/live.min.js +4 -0
- package/dist/live.min.js.map +1 -0
- package/dist/live.umd.js +4 -0
- package/dist/live.umd.js.map +1 -0
- package/package.json +12 -1
package/dist/index.cjs
CHANGED
|
@@ -797,6 +797,160 @@ const easings = {
|
|
|
797
797
|
1.55
|
|
798
798
|
]
|
|
799
799
|
};
|
|
800
|
+
/** The CSS easing keywords as cubic Bézier curves. */
|
|
801
|
+
const CSS_EASINGS = {
|
|
802
|
+
linear: [
|
|
803
|
+
0,
|
|
804
|
+
0,
|
|
805
|
+
1,
|
|
806
|
+
1
|
|
807
|
+
],
|
|
808
|
+
ease: [
|
|
809
|
+
.25,
|
|
810
|
+
.1,
|
|
811
|
+
.25,
|
|
812
|
+
1
|
|
813
|
+
],
|
|
814
|
+
"ease-in": [
|
|
815
|
+
.42,
|
|
816
|
+
0,
|
|
817
|
+
1,
|
|
818
|
+
1
|
|
819
|
+
],
|
|
820
|
+
"ease-out": [
|
|
821
|
+
0,
|
|
822
|
+
0,
|
|
823
|
+
.58,
|
|
824
|
+
1
|
|
825
|
+
],
|
|
826
|
+
"ease-in-out": [
|
|
827
|
+
.42,
|
|
828
|
+
0,
|
|
829
|
+
.58,
|
|
830
|
+
1
|
|
831
|
+
]
|
|
832
|
+
};
|
|
833
|
+
const NUMBER = /-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi;
|
|
834
|
+
/** The four numbers of a cubic Bézier easing, or nothing for other easings. */
|
|
835
|
+
function curveOf(easing) {
|
|
836
|
+
const css = easing.trim();
|
|
837
|
+
if (CSS_EASINGS[css]) return CSS_EASINGS[css];
|
|
838
|
+
if (easings[css]) return easings[css];
|
|
839
|
+
const numbers = css.startsWith("cubic-bezier(") ? css.match(NUMBER) : null;
|
|
840
|
+
return numbers?.length === 4 ? numbers.map(Number) : void 0;
|
|
841
|
+
}
|
|
842
|
+
/** A cubic Bézier easing as a function of time, solved for x by bisection. */
|
|
843
|
+
function bezier([x1, y1, x2, y2]) {
|
|
844
|
+
const at = (a, b, t) => 3 * a * t * (1 - t) ** 2 + 3 * b * t ** 2 * (1 - t) + t ** 3;
|
|
845
|
+
return (time) => {
|
|
846
|
+
let low = 0;
|
|
847
|
+
let high = 1;
|
|
848
|
+
let t = time;
|
|
849
|
+
for (let i = 0; i < 30; i++) {
|
|
850
|
+
const x = at(x1, x2, t);
|
|
851
|
+
if (Math.abs(x - time) < 1e-6) break;
|
|
852
|
+
if (x < time) low = t;
|
|
853
|
+
else high = t;
|
|
854
|
+
t = (low + high) / 2;
|
|
855
|
+
}
|
|
856
|
+
return at(y1, y2, t);
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
/** `steps(n, position)` as a function of time. */
|
|
860
|
+
function steps(css) {
|
|
861
|
+
const count = Math.max(1, Math.round(Number(css.match(NUMBER)?.[0] ?? 1)));
|
|
862
|
+
const position = css.match(/(jump-)?(start|end|none|both)\s*\)/)?.[2] ?? "end";
|
|
863
|
+
const jumps = position === "none" ? count - 1 : position === "both" ? count + 1 : count;
|
|
864
|
+
const offset = position === "start" || position === "both" ? 1 : 0;
|
|
865
|
+
return (time) => Math.min(1, (Math.min(Math.floor(time * count), count - 1) + offset) / Math.max(1, jumps));
|
|
866
|
+
}
|
|
867
|
+
/** `linear(…)` as a function of time: its stops, evenly spread where not given. */
|
|
868
|
+
function linearStops(css) {
|
|
869
|
+
const stops = css.slice(css.indexOf("(") + 1, css.lastIndexOf(")")).split(",").map((stop) => stop.trim().split(/\s+/).map(parseFloat));
|
|
870
|
+
const ys = stops.map(([value]) => value);
|
|
871
|
+
const xs = stops.map(([, at], index) => at === void 0 || Number.isNaN(at) ? index / Math.max(1, stops.length - 1) : at / 100);
|
|
872
|
+
return (time) => {
|
|
873
|
+
let i = 1;
|
|
874
|
+
while (i < xs.length - 1 && time > xs[i]) i++;
|
|
875
|
+
const span = xs[i] - xs[i - 1] || 1;
|
|
876
|
+
return ys[i - 1] + (ys[i] - ys[i - 1]) * (time - xs[i - 1]) / span;
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
/** An easing as a function of time, `ease` for easings it doesn't know. */
|
|
880
|
+
function easingFunction(easing) {
|
|
881
|
+
if (typeof easing !== "string") return bezier(easing);
|
|
882
|
+
const css = easing.trim();
|
|
883
|
+
if (css.startsWith("steps(")) return steps(css);
|
|
884
|
+
if (css.startsWith("linear(")) return linearStops(css);
|
|
885
|
+
return bezier(curveOf(css) ?? CSS_EASINGS.ease);
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* The SMIL `keySplines` of an easing SMIL can express: a cubic Bézier
|
|
889
|
+
* curve whose four numbers lie within 0 and 1 (the CSS keywords, many
|
|
890
|
+
* `cubic-bezier()` curves, most names of {@link easings}). Browsers ignore
|
|
891
|
+
* an animation whose `keySplines` leave that range, so for other easings
|
|
892
|
+
* it returns nothing: sample them with {@link sampleEasing} instead.
|
|
893
|
+
*
|
|
894
|
+
* @example
|
|
895
|
+
* ```ts
|
|
896
|
+
* import { keySplinesOf } from 'chartist';
|
|
897
|
+
*
|
|
898
|
+
* keySplinesOf('ease-out'); // '0 0 0.58 1'
|
|
899
|
+
* keySplinesOf('easeOutBack'); // undefined: it overshoots
|
|
900
|
+
* ```
|
|
901
|
+
* @param easing A CSS easing, a name of {@link easings}, or four numbers
|
|
902
|
+
* @returns The `keySplines` value, or nothing
|
|
903
|
+
*/
|
|
904
|
+
function keySplinesOf(easing) {
|
|
905
|
+
const curve = typeof easing === "string" ? curveOf(easing) : easing;
|
|
906
|
+
return curve?.length === 4 && curve.every((value) => value >= 0 && value <= 1) ? curve.join(" ") : void 0;
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* The eased progress of an animation at evenly spaced times, for SMIL
|
|
910
|
+
* `values` with even `keyTimes`: 12 points, and one per 50 ms for
|
|
911
|
+
* animations longer than 600 ms, at most 40. It takes the CSS easings
|
|
912
|
+
* (the keywords, `cubic-bezier()` curves, also ones that overshoot,
|
|
913
|
+
* `linear()` and `steps()`), the names of {@link easings} and four
|
|
914
|
+
* numbers of a cubic Bézier curve; anything else is sampled as `ease`.
|
|
915
|
+
* Points lie below 0 or above 1 where the easing overshoots.
|
|
916
|
+
*
|
|
917
|
+
* @example
|
|
918
|
+
* ```ts
|
|
919
|
+
* import { sampleEasing } from 'chartist';
|
|
920
|
+
*
|
|
921
|
+
* // A value that grows from 10 to 20 and overshoots a little on the way.
|
|
922
|
+
* const progress = sampleEasing('cubic-bezier(0.34, 1.56, 0.64, 1)', 400);
|
|
923
|
+
* const values = progress.map(p => 10 + (20 - 10) * p).join(';');
|
|
924
|
+
* ```
|
|
925
|
+
* @param easing The easing
|
|
926
|
+
* @param duration The animation's duration in ms
|
|
927
|
+
* @returns The progress at each point, from 0 to 1
|
|
928
|
+
*/
|
|
929
|
+
function sampleEasing(easing, duration) {
|
|
930
|
+
const count = duration > 600 ? Math.min(40, Math.max(12, Math.round(duration / 50))) : 12;
|
|
931
|
+
const at = easingFunction(easing);
|
|
932
|
+
return Array.from({ length: count }, (_, index) => {
|
|
933
|
+
const time = index / (count - 1);
|
|
934
|
+
return index === 0 ? 0 : index === count - 1 ? 1 : at(time);
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* The value between `from` and `to` at `progress`: the numbers in `to`
|
|
939
|
+
* moved from their counterparts in `from`, when both have the same shape
|
|
940
|
+
* (`10px` and `40px`, two paths with the same commands), else `from`
|
|
941
|
+
* until halfway and `to` after.
|
|
942
|
+
*/
|
|
943
|
+
function between(from, to, progress) {
|
|
944
|
+
const fromNumbers = from.match(NUMBER) ?? [];
|
|
945
|
+
const toNumbers = to.match(NUMBER) ?? [];
|
|
946
|
+
if (fromNumbers.length !== toNumbers.length || from.replace(NUMBER, "#") !== to.replace(NUMBER, "#")) return progress < .5 ? from : to;
|
|
947
|
+
let index = 0;
|
|
948
|
+
return to.replace(NUMBER, () => {
|
|
949
|
+
const start = Number(fromNumbers[index]);
|
|
950
|
+
const end = Number(toNumbers[index++]);
|
|
951
|
+
return String(+(start + (end - start) * progress).toFixed(4));
|
|
952
|
+
});
|
|
953
|
+
}
|
|
800
954
|
/**
|
|
801
955
|
* The property of an element that holds the emitter its descendants'
|
|
802
956
|
* animations report to when `animate()` gets none. The compat plugin
|
|
@@ -816,13 +970,22 @@ function createAnimation(element, attribute, animationDefinition, createGuided =
|
|
|
816
970
|
const attributeProperties = {};
|
|
817
971
|
let animationEasing;
|
|
818
972
|
let timeout;
|
|
819
|
-
if (easing) animationEasing = Array.isArray(easing) ? easing : easings[easing];
|
|
973
|
+
if (easing) animationEasing = Array.isArray(easing) ? easing : easings[easing] ?? easing;
|
|
820
974
|
def.begin = ensureUnit(def.begin, "ms");
|
|
821
975
|
def.dur = ensureUnit(def.dur, "ms");
|
|
822
976
|
if (animationEasing) {
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
977
|
+
const keySplines = keySplinesOf(animationEasing);
|
|
978
|
+
if (keySplines) {
|
|
979
|
+
def.calcMode = "spline";
|
|
980
|
+
def.keySplines = keySplines;
|
|
981
|
+
def.keyTimes = "0;1";
|
|
982
|
+
} else if (def.from !== void 0 && def.to !== void 0) {
|
|
983
|
+
const duration = quantity(def.dur);
|
|
984
|
+
const progress = sampleEasing(animationEasing, duration.unit === "s" ? duration.value * 1e3 : duration.value);
|
|
985
|
+
def.calcMode = String(animationEasing).trim().startsWith("steps(") ? "discrete" : "linear";
|
|
986
|
+
def.values = progress.map((at) => between(String(def.from), String(def.to), at)).join(";");
|
|
987
|
+
def.keyTimes = progress.map((_, index) => +(index / (progress.length - 1)).toFixed(4)).join(";");
|
|
988
|
+
}
|
|
826
989
|
}
|
|
827
990
|
if (createGuided) {
|
|
828
991
|
def.fill = "freeze";
|
|
@@ -2234,7 +2397,6 @@ function seriesOption(series, options, key) {
|
|
|
2234
2397
|
* ]
|
|
2235
2398
|
* });
|
|
2236
2399
|
* ```
|
|
2237
|
-
* @experimental
|
|
2238
2400
|
*/
|
|
2239
2401
|
function line(options = {}) {
|
|
2240
2402
|
const classNames = {
|
|
@@ -2263,10 +2425,11 @@ function line(options = {}) {
|
|
|
2263
2425
|
const seriesName = safeHasProperty(series, "name") && series.name;
|
|
2264
2426
|
const seriesClassName = safeHasProperty(series, "className") && series.className;
|
|
2265
2427
|
const seriesMeta = safeHasProperty(series, "meta") ? series.meta : void 0;
|
|
2428
|
+
const smoothing = interpolationOf(seriesOption(series, options, "lineSmooth"));
|
|
2266
2429
|
const path = seriesPath(values, {
|
|
2267
2430
|
x: axisX,
|
|
2268
2431
|
y: axisY
|
|
2269
|
-
}, area, shift,
|
|
2432
|
+
}, area, shift, smoothing, (valueIndex) => getMetaData(series, valueIndex));
|
|
2270
2433
|
const seriesContext = {
|
|
2271
2434
|
series,
|
|
2272
2435
|
seriesIndex,
|
|
@@ -2304,7 +2467,8 @@ function line(options = {}) {
|
|
|
2304
2467
|
ctx: {
|
|
2305
2468
|
...seriesContext,
|
|
2306
2469
|
values,
|
|
2307
|
-
path: path.clone()
|
|
2470
|
+
path: path.clone(),
|
|
2471
|
+
smoothing
|
|
2308
2472
|
}
|
|
2309
2473
|
}), ...children];
|
|
2310
2474
|
if (seriesOption(series, options, "showArea") && axisY.range) {
|
|
@@ -2313,14 +2477,15 @@ function line(options = {}) {
|
|
|
2313
2477
|
path.splitByCommand("M").filter((segment) => segment.pathElements.length > 1).map((segment) => {
|
|
2314
2478
|
const first = segment.pathElements[0];
|
|
2315
2479
|
const last = segment.pathElements[segment.pathElements.length - 1];
|
|
2316
|
-
return segment.clone(true).position(0).remove(1).move(first.x, areaBaseProjected).line(first.x, first.y).position(segment.pathElements.length + 1).line(last.x, areaBaseProjected);
|
|
2480
|
+
return segment.clone(true).position(0).remove(1).move(first.x, areaBaseProjected).line(first.x, first.y, false, first.data).position(segment.pathElements.length + 1).line(last.x, areaBaseProjected);
|
|
2317
2481
|
}).forEach((areaPath) => {
|
|
2318
2482
|
children = [node("path", { d: areaPath.stringify() }, classNames.area, {
|
|
2319
2483
|
role: "area",
|
|
2320
2484
|
ctx: {
|
|
2321
2485
|
...seriesContext,
|
|
2322
2486
|
values,
|
|
2323
|
-
path: areaPath.clone()
|
|
2487
|
+
path: areaPath.clone(),
|
|
2488
|
+
smoothing
|
|
2324
2489
|
}
|
|
2325
2490
|
}), ...children];
|
|
2326
2491
|
});
|
|
@@ -2729,7 +2894,6 @@ function presetAxes(config, boundOf) {
|
|
|
2729
2894
|
* `{ x, y }` form.
|
|
2730
2895
|
* @param extra `reverseData` and `normalize`, for the list form (the
|
|
2731
2896
|
* `{ x, y }` form takes them inline).
|
|
2732
|
-
* @experimental
|
|
2733
2897
|
*/
|
|
2734
2898
|
function cartesianAxes(input, extra = {}) {
|
|
2735
2899
|
const withOffset = (setup, dimension) => ({
|
|
@@ -2796,7 +2960,6 @@ const valueOf = (value, dimension) => Number(getMultiValue(value, dimension));
|
|
|
2796
2960
|
* layers: [axisGrid(), line(), axisLabels()]
|
|
2797
2961
|
* });
|
|
2798
2962
|
* ```
|
|
2799
|
-
* @experimental
|
|
2800
2963
|
*/
|
|
2801
2964
|
function stepAxis() {
|
|
2802
2965
|
return {
|
|
@@ -2855,7 +3018,6 @@ function stepAxis() {
|
|
|
2855
3018
|
* layers: [axisGrid(), line(), axisLabels()]
|
|
2856
3019
|
* });
|
|
2857
3020
|
* ```
|
|
2858
|
-
* @experimental
|
|
2859
3021
|
*/
|
|
2860
3022
|
function autoScaleAxis() {
|
|
2861
3023
|
return {
|
|
@@ -2915,7 +3077,6 @@ function autoScaleAxis() {
|
|
|
2915
3077
|
* layers: [axisGrid(), line({ showLine: false }), axisLabels()]
|
|
2916
3078
|
* });
|
|
2917
3079
|
* ```
|
|
2918
|
-
* @experimental
|
|
2919
3080
|
*/
|
|
2920
3081
|
function fixedScaleAxis() {
|
|
2921
3082
|
return {
|
|
@@ -3049,8 +3210,9 @@ function createPhaseEmitter() {
|
|
|
3049
3210
|
return current;
|
|
3050
3211
|
},
|
|
3051
3212
|
notify(name, value) {
|
|
3052
|
-
(listeners.get(name) ?? []).
|
|
3213
|
+
const results = (listeners.get(name) ?? []).map(({ listener }) => listener(value));
|
|
3053
3214
|
observe(name, value);
|
|
3215
|
+
return results;
|
|
3054
3216
|
},
|
|
3055
3217
|
clear() {
|
|
3056
3218
|
listeners.clear();
|
|
@@ -3117,7 +3279,6 @@ function findAll(scene, query = {}) {
|
|
|
3117
3279
|
* });
|
|
3118
3280
|
* const markup = mapped ? renderToString(mapped) : '';
|
|
3119
3281
|
* ```
|
|
3120
|
-
* @experimental
|
|
3121
3282
|
*/
|
|
3122
3283
|
function mapNodes(scene, mapper) {
|
|
3123
3284
|
let children = scene.children;
|
|
@@ -3262,7 +3423,7 @@ function layout(emitter, config, width, height) {
|
|
|
3262
3423
|
validate(result);
|
|
3263
3424
|
return result;
|
|
3264
3425
|
}
|
|
3265
|
-
function compose(emitter, config, data, area, measureText, axes = {}, normalized, padding = config.padding, bindings = [], labels = "html", measureStyle) {
|
|
3426
|
+
function compose(emitter, config, data, area, measureText, axes = {}, normalized, padding = config.padding, bindings = [], labels = "html", measureStyle, drawn = []) {
|
|
3266
3427
|
const byId = new Map((axes.all ?? []).map((axis) => [axis.id, axis]));
|
|
3267
3428
|
const layers = config.layers.map((layer, layerIndex) => {
|
|
3268
3429
|
const binding = bindings[layerIndex] ?? {};
|
|
@@ -3292,10 +3453,16 @@ function compose(emitter, config, data, area, measureText, axes = {}, normalized
|
|
|
3292
3453
|
labels,
|
|
3293
3454
|
measureStyle
|
|
3294
3455
|
};
|
|
3456
|
+
const nodes = layer.compose(context).map((top) => assignKeys(top, layerIndex));
|
|
3457
|
+
drawn.push({
|
|
3458
|
+
nodes: [],
|
|
3459
|
+
context
|
|
3460
|
+
});
|
|
3295
3461
|
return {
|
|
3296
3462
|
layer,
|
|
3297
3463
|
context,
|
|
3298
|
-
nodes
|
|
3464
|
+
nodes,
|
|
3465
|
+
layerIndex
|
|
3299
3466
|
};
|
|
3300
3467
|
});
|
|
3301
3468
|
const refiners = layers.flatMap(({ layer, context }) => layer.refine ? [{
|
|
@@ -3310,9 +3477,12 @@ function compose(emitter, config, data, area, measureText, axes = {}, normalized
|
|
|
3310
3477
|
}) : refined;
|
|
3311
3478
|
}, current);
|
|
3312
3479
|
const composed = [];
|
|
3313
|
-
for (const { nodes } of layers) for (const top of nodes) {
|
|
3480
|
+
for (const { nodes, layerIndex } of layers) for (const top of nodes) {
|
|
3314
3481
|
const result = mapNodes(top, (current) => current.role === void 0 ? void 0 : emitter.transform("compose", refiners.length > 0 ? refine(current) : current));
|
|
3315
|
-
if (result)
|
|
3482
|
+
if (result) {
|
|
3483
|
+
drawn[layerIndex].nodes.push(result);
|
|
3484
|
+
composed.push(result);
|
|
3485
|
+
}
|
|
3316
3486
|
}
|
|
3317
3487
|
return composed;
|
|
3318
3488
|
}
|
|
@@ -3341,6 +3511,7 @@ function runPipeline(emitter, options, environment, previous, from = "resolve")
|
|
|
3341
3511
|
rootClass: className,
|
|
3342
3512
|
...measureOptions
|
|
3343
3513
|
}) : measure;
|
|
3514
|
+
const drawn = [];
|
|
3344
3515
|
const measureText = withRootClass(environment.measureText);
|
|
3345
3516
|
const measureStyle = withRootClass(environment.measureStyle);
|
|
3346
3517
|
return {
|
|
@@ -3349,10 +3520,11 @@ function runPipeline(emitter, options, environment, previous, from = "resolve")
|
|
|
3349
3520
|
layout: laidOut,
|
|
3350
3521
|
axes,
|
|
3351
3522
|
normalized,
|
|
3352
|
-
scene: scene(emitter, config, compose(emitter, config, data, laidOut.area, measureText, axes, normalized, laidOut.padding, bindings, config.labels ?? environment.labels ?? "html", measureStyle), environment.rootSize ?? {
|
|
3523
|
+
scene: scene(emitter, config, compose(emitter, config, data, laidOut.area, measureText, axes, normalized, laidOut.padding, bindings, config.labels ?? environment.labels ?? "html", measureStyle, drawn), environment.rootSize ?? {
|
|
3353
3524
|
width: config.width ?? laidOut.width,
|
|
3354
3525
|
height: config.height ?? laidOut.height
|
|
3355
|
-
})
|
|
3526
|
+
}),
|
|
3527
|
+
drawn
|
|
3356
3528
|
};
|
|
3357
3529
|
}
|
|
3358
3530
|
/**
|
|
@@ -3360,7 +3532,6 @@ function runPipeline(emitter, options, environment, previous, from = "resolve")
|
|
|
3360
3532
|
* below the top of the line (a typical font's ascent). Lines are one font
|
|
3361
3533
|
* size apart, so a renderer finds a line's vertical center at
|
|
3362
3534
|
* `y - (textAscent - 0.5) * fontSize` from its `y`.
|
|
3363
|
-
* @experimental
|
|
3364
3535
|
*/
|
|
3365
3536
|
const textAscent = .85;
|
|
3366
3537
|
/**
|
|
@@ -3378,7 +3549,6 @@ const textAscent = .85;
|
|
|
3378
3549
|
* return { ...size, width: size.width * 1.1 };
|
|
3379
3550
|
* };
|
|
3380
3551
|
* ```
|
|
3381
|
-
* @experimental
|
|
3382
3552
|
*/
|
|
3383
3553
|
const estimateText = (text, options = {}) => {
|
|
3384
3554
|
const fontSize = options.fontSize ?? 12;
|
|
@@ -3390,7 +3560,27 @@ const estimateText = (text, options = {}) => {
|
|
|
3390
3560
|
};
|
|
3391
3561
|
//#endregion
|
|
3392
3562
|
//#region src/render/dom.ts
|
|
3393
|
-
|
|
3563
|
+
/**
|
|
3564
|
+
* Sets one scene attribute on an element as the DOM renderer does: names
|
|
3565
|
+
* with a known prefix (`ct:value`) in their namespace, and `style` through
|
|
3566
|
+
* the CSSOM, which a Content Security Policy allows. For renderers that
|
|
3567
|
+
* change elements they keep.
|
|
3568
|
+
*
|
|
3569
|
+
* @example
|
|
3570
|
+
* ```ts
|
|
3571
|
+
* import { applyAttribute } from 'chartist';
|
|
3572
|
+
*
|
|
3573
|
+
* const point = document.querySelector('.ct-point');
|
|
3574
|
+
* if (point) {
|
|
3575
|
+
* applyAttribute(point, 'ct:value', 12);
|
|
3576
|
+
* applyAttribute(point, 'style', 'stroke-width: 12px;');
|
|
3577
|
+
* }
|
|
3578
|
+
* ```
|
|
3579
|
+
* @param element The element to change
|
|
3580
|
+
* @param name The attribute's name, as in a scene node's `attrs`
|
|
3581
|
+
* @param value The attribute's value
|
|
3582
|
+
*/
|
|
3583
|
+
function applyAttribute(element, name, value) {
|
|
3394
3584
|
const separator = name.indexOf(":");
|
|
3395
3585
|
const prefix = separator > 0 ? name.slice(0, separator) : "";
|
|
3396
3586
|
if (name === "style") setStyle(element, String(value));
|
|
@@ -3398,17 +3588,34 @@ function setAttribute(element, name, value) {
|
|
|
3398
3588
|
else element.setAttribute(name, String(value));
|
|
3399
3589
|
}
|
|
3400
3590
|
/**
|
|
3401
|
-
* Creates the element tree
|
|
3402
|
-
*
|
|
3591
|
+
* Creates the element tree of a scene node as the DOM renderer does: SVG
|
|
3592
|
+
* elements, HTML elements inside a `foreignObject`, attributes set with
|
|
3593
|
+
* {@link applyAttribute}. For renderers that create elements.
|
|
3594
|
+
*
|
|
3595
|
+
* @example
|
|
3596
|
+
* ```ts
|
|
3597
|
+
* import { node, renderElement } from 'chartist';
|
|
3598
|
+
*
|
|
3599
|
+
* const dot = renderElement(node('circle', { cx: 5, cy: 5, r: 4 }, 'ct-dot'), document);
|
|
3600
|
+
* document.querySelector('svg')?.append(dot);
|
|
3601
|
+
* ```
|
|
3602
|
+
* @param current The node to create
|
|
3603
|
+
* @param document The document to create the elements in
|
|
3604
|
+
* @param options The namespace, and a callback for each created element
|
|
3605
|
+
* @returns The node's element, with its children
|
|
3403
3606
|
*/
|
|
3404
|
-
function
|
|
3607
|
+
function renderElement(current, document, options = {}) {
|
|
3608
|
+
const { html = false, created } = options;
|
|
3405
3609
|
const element = document.createElementNS(html ? namespaces.xhtml : namespaces.svg, current.name);
|
|
3406
3610
|
if (current.classes.length) element.setAttribute("class", current.classes.join(" "));
|
|
3407
|
-
for (const [name, value] of Object.entries(current.attrs))
|
|
3611
|
+
for (const [name, value] of Object.entries(current.attrs)) applyAttribute(element, name, value);
|
|
3408
3612
|
if (current.content) element.appendChild(document.createTextNode(current.content));
|
|
3409
|
-
const
|
|
3410
|
-
|
|
3411
|
-
|
|
3613
|
+
const childOptions = html || current.name !== "foreignObject" ? options : {
|
|
3614
|
+
...options,
|
|
3615
|
+
html: true
|
|
3616
|
+
};
|
|
3617
|
+
for (const child of current.children) element.appendChild(renderElement(child, document, childOptions));
|
|
3618
|
+
created?.(current, element);
|
|
3412
3619
|
return element;
|
|
3413
3620
|
}
|
|
3414
3621
|
/** Removes Chartist SVGs (the ones with the ct namespace) from a container. */
|
|
@@ -3456,8 +3663,10 @@ function measureInDocument(document) {
|
|
|
3456
3663
|
/**
|
|
3457
3664
|
* Creates the renderer `chart()` uses by default: it renders scenes as
|
|
3458
3665
|
* inline SVG into the container, replacing an earlier Chartist SVG there
|
|
3459
|
-
* (as 1.x does), and measures text and reads styles for
|
|
3460
|
-
* container, so its CSS applies.
|
|
3666
|
+
* (as 1.x does) on every render, and measures text and reads styles for
|
|
3667
|
+
* layout in the container, so its CSS applies. It ignores the previous
|
|
3668
|
+
* render it gets from a chart's second render on; `liveDomRenderer()`
|
|
3669
|
+
* from `chartist/live` keeps its SVG and changes it instead.
|
|
3461
3670
|
* Wrap it to change what every render puts on the page.
|
|
3462
3671
|
*
|
|
3463
3672
|
* @example
|
|
@@ -3483,7 +3692,6 @@ function measureInDocument(document) {
|
|
|
3483
3692
|
* renderer
|
|
3484
3693
|
* });
|
|
3485
3694
|
* ```
|
|
3486
|
-
* @experimental
|
|
3487
3695
|
*/
|
|
3488
3696
|
function domRenderer() {
|
|
3489
3697
|
return {
|
|
@@ -3491,7 +3699,7 @@ function domRenderer() {
|
|
|
3491
3699
|
render(scene, container) {
|
|
3492
3700
|
const document = container.ownerDocument;
|
|
3493
3701
|
const elements = /* @__PURE__ */ new WeakMap();
|
|
3494
|
-
const svg =
|
|
3702
|
+
const svg = renderElement(scene, document, { created: (node, element) => elements.set(node, element) });
|
|
3495
3703
|
svg.setAttributeNS(namespaces.xmlns, "xmlns:ct", namespaces.ct);
|
|
3496
3704
|
removePrevious(container);
|
|
3497
3705
|
container.appendChild(svg);
|
|
@@ -3513,6 +3721,35 @@ function domRenderer() {
|
|
|
3513
3721
|
};
|
|
3514
3722
|
}
|
|
3515
3723
|
//#endregion
|
|
3724
|
+
//#region src/chart/changes.ts
|
|
3725
|
+
/** Adds an entry for `current` and each of its descendants, in document order. */
|
|
3726
|
+
function each$1(current, op, into) {
|
|
3727
|
+
into.push({
|
|
3728
|
+
op,
|
|
3729
|
+
node: current
|
|
3730
|
+
});
|
|
3731
|
+
current.children.forEach((child) => each$1(child, op, into));
|
|
3732
|
+
}
|
|
3733
|
+
/**
|
|
3734
|
+
* The changes of a render that replaced its output: every node of the
|
|
3735
|
+
* previous scene removed, every node of the new one added.
|
|
3736
|
+
*/
|
|
3737
|
+
function replacementChanges(previous, next) {
|
|
3738
|
+
const changes = [];
|
|
3739
|
+
if (previous) each$1(previous, "remove", changes);
|
|
3740
|
+
each$1(next, "add", changes);
|
|
3741
|
+
return changes;
|
|
3742
|
+
}
|
|
3743
|
+
/**
|
|
3744
|
+
* Set on a chart handle by the 1.x classes and the compat plugin: the
|
|
3745
|
+
* chart never hands its renderer the previous render, so every render
|
|
3746
|
+
* draws new elements, as 1.x code expects. A global symbol, so the compat
|
|
3747
|
+
* build sets the same one as the core.
|
|
3748
|
+
*/
|
|
3749
|
+
const REPLACES_OUTPUT = Symbol.for("chartist.replacesOutput");
|
|
3750
|
+
/** Whether the chart must replace its output on every render. */
|
|
3751
|
+
const replacesOutput = (handle) => handle[REPLACES_OUTPUT] === true;
|
|
3752
|
+
//#endregion
|
|
3516
3753
|
//#region src/chart/className.ts
|
|
3517
3754
|
/**
|
|
3518
3755
|
* The chart type class for a chart's layers, so the stylesheet's chart
|
|
@@ -3565,7 +3802,6 @@ function withChartTypeClass(config) {
|
|
|
3565
3802
|
* { plugins: [withOptions(lastPoint, { className: 'ct-last' })] }
|
|
3566
3803
|
* );
|
|
3567
3804
|
* ```
|
|
3568
|
-
* @experimental
|
|
3569
3805
|
*/
|
|
3570
3806
|
function withOptions(plugin, options) {
|
|
3571
3807
|
return [plugin, options];
|
|
@@ -3631,16 +3867,37 @@ function asUserListeners(chart, add) {
|
|
|
3631
3867
|
else add();
|
|
3632
3868
|
}
|
|
3633
3869
|
/**
|
|
3634
|
-
* Installs v2 plugins in order and
|
|
3635
|
-
* Provided names are known before any plugin installs, so a
|
|
3636
|
-
* listen to events another plugin provides. Listeners added
|
|
3637
|
-
* plugin installs belong to plugins.
|
|
3870
|
+
* Installs v2 plugins in order and adds the event names they provide to
|
|
3871
|
+
* `provided`. Provided names are known before any plugin installs, so a
|
|
3872
|
+
* plugin may listen to events another plugin provides. Listeners added
|
|
3873
|
+
* while a plugin installs belong to plugins.
|
|
3638
3874
|
*/
|
|
3639
3875
|
function installPlugins(chart, plugins = [], provided, scope) {
|
|
3640
3876
|
scopes.set(chart, scope);
|
|
3641
3877
|
const entries = normalize(plugins);
|
|
3642
3878
|
for (const [plugin] of entries) plugin.provides?.forEach((name) => provided.add(name));
|
|
3643
|
-
|
|
3879
|
+
const cleanups = [];
|
|
3880
|
+
for (const [plugin, options] of entries) addingAs(scope, "plugin", () => {
|
|
3881
|
+
const cleanup = plugin.install(chart, options);
|
|
3882
|
+
if (typeof cleanup === "function") cleanups.push(cleanup);
|
|
3883
|
+
});
|
|
3884
|
+
return {
|
|
3885
|
+
plugins: entries.map(([plugin]) => plugin),
|
|
3886
|
+
cleanups
|
|
3887
|
+
};
|
|
3888
|
+
}
|
|
3889
|
+
/**
|
|
3890
|
+
* Calls every function, also when one throws, and throws the first error
|
|
3891
|
+
* afterwards.
|
|
3892
|
+
*/
|
|
3893
|
+
function runAll(functions) {
|
|
3894
|
+
const errors = [];
|
|
3895
|
+
for (const run of functions) try {
|
|
3896
|
+
run();
|
|
3897
|
+
} catch (error) {
|
|
3898
|
+
errors.push(error);
|
|
3899
|
+
}
|
|
3900
|
+
if (errors.length) throw errors[0];
|
|
3644
3901
|
}
|
|
3645
3902
|
/** Registers `config.on` listeners. */
|
|
3646
3903
|
function registerListeners(chart, listeners = {}) {
|
|
@@ -3741,7 +3998,6 @@ function resolveTarget(target) {
|
|
|
3741
3998
|
* @param target The container element, or a CSS selector for it.
|
|
3742
3999
|
* @param config The data, axes, layers and the rest of the chart.
|
|
3743
4000
|
* @returns A handle to update the chart, listen to it or remove it.
|
|
3744
|
-
* @experimental
|
|
3745
4001
|
*/
|
|
3746
4002
|
function chart(target, config) {
|
|
3747
4003
|
const container = resolveTarget(target);
|
|
@@ -3767,6 +4023,12 @@ function chart(target, config) {
|
|
|
3767
4023
|
let watcher;
|
|
3768
4024
|
let state;
|
|
3769
4025
|
let output;
|
|
4026
|
+
let cleanups = [];
|
|
4027
|
+
let installed = {
|
|
4028
|
+
plugins: [],
|
|
4029
|
+
cleanups: []
|
|
4030
|
+
};
|
|
4031
|
+
let layerOf;
|
|
3770
4032
|
let observer;
|
|
3771
4033
|
let destroyed = false;
|
|
3772
4034
|
let attached = true;
|
|
@@ -3774,7 +4036,7 @@ function chart(target, config) {
|
|
|
3774
4036
|
const view = container.ownerDocument.defaultView;
|
|
3775
4037
|
const fonts = container.ownerDocument.fonts;
|
|
3776
4038
|
const onFontsLoaded = () => {
|
|
3777
|
-
if (!destroyed && state && measuredText) render("layout");
|
|
4039
|
+
if (!destroyed && state && measuredText) render("layout", "fonts");
|
|
3778
4040
|
};
|
|
3779
4041
|
let printed;
|
|
3780
4042
|
let printing = false;
|
|
@@ -3820,9 +4082,33 @@ function chart(target, config) {
|
|
|
3820
4082
|
height: effective.viewBox?.height || svg.height || (fixedSize(effective.height) ?? container.clientHeight)
|
|
3821
4083
|
};
|
|
3822
4084
|
}
|
|
3823
|
-
|
|
4085
|
+
/**
|
|
4086
|
+
* Asks the plugins with `keyframes`, in order, then the layer that drew
|
|
4087
|
+
* the node, for the keyframes of a node's update animation.
|
|
4088
|
+
*/
|
|
4089
|
+
function keyframes(previous, next, progress) {
|
|
4090
|
+
for (const plugin of installed.plugins) {
|
|
4091
|
+
const frames = plugin.keyframes?.(previous, next, progress);
|
|
4092
|
+
if (frames) return frames;
|
|
4093
|
+
}
|
|
4094
|
+
if (!state) return;
|
|
4095
|
+
if (!layerOf) {
|
|
4096
|
+
const map = /* @__PURE__ */ new WeakMap();
|
|
4097
|
+
const mark = (drawnNode, index) => {
|
|
4098
|
+
map.set(drawnNode, index);
|
|
4099
|
+
drawnNode.children.forEach((child) => mark(child, index));
|
|
4100
|
+
};
|
|
4101
|
+
state.drawn.forEach(({ nodes }, index) => nodes.forEach((top) => mark(top, index)));
|
|
4102
|
+
layerOf = map;
|
|
4103
|
+
}
|
|
4104
|
+
const index = layerOf.get(next);
|
|
4105
|
+
return index === void 0 ? void 0 : state.config.layers[index].keyframes?.(previous, next, state.drawn[index].context, progress);
|
|
4106
|
+
}
|
|
4107
|
+
function render(from, cause) {
|
|
3824
4108
|
const { width, height } = size();
|
|
3825
4109
|
measuredText = false;
|
|
4110
|
+
const previous = state;
|
|
4111
|
+
const previousOutput = output;
|
|
3826
4112
|
state = runPipeline(emitter, withChartTypeClass(effective), {
|
|
3827
4113
|
width,
|
|
3828
4114
|
height,
|
|
@@ -3835,18 +4121,35 @@ function chart(target, config) {
|
|
|
3835
4121
|
}
|
|
3836
4122
|
}, state, from);
|
|
3837
4123
|
const { scene } = state;
|
|
3838
|
-
|
|
4124
|
+
layerOf = void 0;
|
|
4125
|
+
const pending = cleanups;
|
|
4126
|
+
cleanups = [];
|
|
4127
|
+
runAll(pending);
|
|
4128
|
+
const update = previous && previousOutput && !replacesOutput(handle) ? {
|
|
4129
|
+
previous: previousOutput,
|
|
4130
|
+
previousScene: previous.scene,
|
|
4131
|
+
cause,
|
|
4132
|
+
labels: state.data.labels,
|
|
4133
|
+
previousLabels: previous.data.labels,
|
|
4134
|
+
keyframes
|
|
4135
|
+
} : void 0;
|
|
4136
|
+
const rendered = renderer.render(scene, container, update);
|
|
4137
|
+
output = rendered;
|
|
3839
4138
|
if (printing) applyPrintViewBox();
|
|
3840
|
-
|
|
4139
|
+
const event = {
|
|
3841
4140
|
scene,
|
|
3842
|
-
output
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
4141
|
+
output: rendered,
|
|
4142
|
+
cause,
|
|
4143
|
+
changes: update && rendered.patched && rendered.changes ? rendered.changes : replacementChanges(previous?.scene, scene),
|
|
4144
|
+
previous: previous?.scene
|
|
4145
|
+
};
|
|
4146
|
+
emitter.notify("render", event);
|
|
4147
|
+
const elementOf = (node) => rendered.elementOf?.(node) ?? previousOutput?.elementOf?.(node);
|
|
4148
|
+
cleanups = emitter.notify("mount", {
|
|
4149
|
+
...event,
|
|
4150
|
+
elementOf,
|
|
4151
|
+
animation: rendered.animation
|
|
4152
|
+
}).filter((result) => typeof result === "function");
|
|
3850
4153
|
}
|
|
3851
4154
|
function resolveResponsive() {
|
|
3852
4155
|
const entries = current.responsive?.entries;
|
|
@@ -3862,7 +4165,7 @@ function chart(target, config) {
|
|
|
3862
4165
|
previousConfig,
|
|
3863
4166
|
currentConfig: effective
|
|
3864
4167
|
});
|
|
3865
|
-
render("resolve");
|
|
4168
|
+
render("resolve", "responsive");
|
|
3866
4169
|
}
|
|
3867
4170
|
/** (Re)creates the watcher of the responsive entries. */
|
|
3868
4171
|
function watch() {
|
|
@@ -3881,7 +4184,7 @@ function chart(target, config) {
|
|
|
3881
4184
|
};
|
|
3882
4185
|
if ("responsive" in changes) watch();
|
|
3883
4186
|
else resolveResponsive();
|
|
3884
|
-
render("resolve");
|
|
4187
|
+
render("resolve", "update");
|
|
3885
4188
|
return handle;
|
|
3886
4189
|
},
|
|
3887
4190
|
detach() {
|
|
@@ -3900,8 +4203,15 @@ function chart(target, config) {
|
|
|
3900
4203
|
if (destroyed) return;
|
|
3901
4204
|
destroyed = true;
|
|
3902
4205
|
handle.detach();
|
|
3903
|
-
|
|
3904
|
-
|
|
4206
|
+
const pending = cleanups;
|
|
4207
|
+
cleanups = [];
|
|
4208
|
+
try {
|
|
4209
|
+
runAll(pending);
|
|
4210
|
+
} finally {
|
|
4211
|
+
output?.remove?.();
|
|
4212
|
+
emitter.clear();
|
|
4213
|
+
runAll([...installed.cleanups].reverse());
|
|
4214
|
+
}
|
|
3905
4215
|
},
|
|
3906
4216
|
...eventMethods(emitter, () => handle, provided, scope)
|
|
3907
4217
|
};
|
|
@@ -3917,15 +4227,15 @@ function chart(target, config) {
|
|
|
3917
4227
|
return;
|
|
3918
4228
|
}
|
|
3919
4229
|
const { width, height } = size();
|
|
3920
|
-
if (width !== state.layout.width || height !== state.layout.height) render("layout");
|
|
4230
|
+
if (width !== state.layout.width || height !== state.layout.height) render("layout", "resize");
|
|
3921
4231
|
});
|
|
3922
4232
|
observer.observe(container);
|
|
3923
4233
|
}
|
|
3924
|
-
installPlugins(handle, config.plugins, provided, scope);
|
|
4234
|
+
installed = installPlugins(handle, config.plugins, provided, scope);
|
|
3925
4235
|
registerListeners(handle, config.on);
|
|
3926
4236
|
if (attached) watch();
|
|
3927
4237
|
else resolveResponsive();
|
|
3928
|
-
render("resolve");
|
|
4238
|
+
render("resolve", "create");
|
|
3929
4239
|
return handle;
|
|
3930
4240
|
}
|
|
3931
4241
|
//#endregion
|
|
@@ -4158,7 +4468,9 @@ function svgLabels(measureText, kind, override = {}) {
|
|
|
4158
4468
|
* ]
|
|
4159
4469
|
* );
|
|
4160
4470
|
* ```
|
|
4161
|
-
* @experimental
|
|
4471
|
+
* @experimental It rests on `Element.matchContainer()`, a draft standard
|
|
4472
|
+
* (w3c/csswg-drafts#6205), through a polyfill: it may still change in a
|
|
4473
|
+
* 2.x minor.
|
|
4162
4474
|
*/
|
|
4163
4475
|
function container(query) {
|
|
4164
4476
|
return Object.freeze({
|
|
@@ -4275,7 +4587,6 @@ function watchResponsive(entries, host, onChange, observeResize = false) {
|
|
|
4275
4587
|
* ])
|
|
4276
4588
|
* });
|
|
4277
4589
|
* ```
|
|
4278
|
-
* @experimental
|
|
4279
4590
|
*/
|
|
4280
4591
|
function responsive(entries) {
|
|
4281
4592
|
return {
|
|
@@ -4383,7 +4694,7 @@ function rootStyle(getOptions, state) {
|
|
|
4383
4694
|
*/
|
|
4384
4695
|
function presetConfig(spec, data, options) {
|
|
4385
4696
|
const resolved = extend({}, spec.defaults, options);
|
|
4386
|
-
const { plugins, on } = options ?? {};
|
|
4697
|
+
const { plugins, on, renderer } = options ?? {};
|
|
4387
4698
|
return {
|
|
4388
4699
|
...spec.config({
|
|
4389
4700
|
...data,
|
|
@@ -4391,7 +4702,8 @@ function presetConfig(spec, data, options) {
|
|
|
4391
4702
|
series: data.series || []
|
|
4392
4703
|
}, resolved),
|
|
4393
4704
|
plugins,
|
|
4394
|
-
on
|
|
4705
|
+
on,
|
|
4706
|
+
...renderer && { renderer }
|
|
4395
4707
|
};
|
|
4396
4708
|
}
|
|
4397
4709
|
/** Internal: creates a preset chart; used by the preset functions and classes. */
|
|
@@ -4447,7 +4759,8 @@ function createPreset(spec, target, initialData, options = {}, responsiveOptions
|
|
|
4447
4759
|
const inner = chart(target, {
|
|
4448
4760
|
...withState(spec.config(data, current)),
|
|
4449
4761
|
plugins: [rootStyle(() => current, state), ...plugins ?? []],
|
|
4450
|
-
on: options.on
|
|
4762
|
+
on: options.on,
|
|
4763
|
+
renderer: options.renderer
|
|
4451
4764
|
});
|
|
4452
4765
|
function onResponsiveChange() {
|
|
4453
4766
|
const previousOptions = current;
|
|
@@ -4582,7 +4895,6 @@ const lineSpec = {
|
|
|
4582
4895
|
* toScene(config, { width: 600, height: 300 })
|
|
4583
4896
|
* );
|
|
4584
4897
|
* ```
|
|
4585
|
-
* @experimental
|
|
4586
4898
|
*/
|
|
4587
4899
|
function lineChartConfig(data, options = {}) {
|
|
4588
4900
|
return presetConfig(lineSpec, data, options);
|
|
@@ -4595,7 +4907,6 @@ function createLineChart(target, data, options = {}, responsiveOptions, plugins)
|
|
|
4595
4907
|
* Creates a line chart with the 1.x options and output, rendered
|
|
4596
4908
|
* synchronously. Plugins must be v2 plugins; convert 1.x plugins with
|
|
4597
4909
|
* `fromLegacyPlugin` from `chartist/compat`.
|
|
4598
|
-
* @experimental
|
|
4599
4910
|
*/
|
|
4600
4911
|
function lineChart(target, data, options = {}, responsiveOptions) {
|
|
4601
4912
|
return createLineChart(target, data, options, responsiveOptions).handle;
|
|
@@ -4667,6 +4978,7 @@ var PresetChart = class extends BaseChart {
|
|
|
4667
4978
|
name: "chart-listeners",
|
|
4668
4979
|
install: (handle) => {
|
|
4669
4980
|
this.installing = handle;
|
|
4981
|
+
handle[REPLACES_OUTPUT] = true;
|
|
4670
4982
|
asUserListeners(handle, () => queued.forEach(([event, listener]) => this.on(event, listener)));
|
|
4671
4983
|
}
|
|
4672
4984
|
};
|
|
@@ -4860,7 +5172,6 @@ function rawSeries(series) {
|
|
|
4860
5172
|
* className: 'ct-chart-bar'
|
|
4861
5173
|
* });
|
|
4862
5174
|
* ```
|
|
4863
|
-
* @experimental
|
|
4864
5175
|
*/
|
|
4865
5176
|
function bar(options = {}) {
|
|
4866
5177
|
const classNames = {
|
|
@@ -5160,7 +5471,6 @@ const barSpec = {
|
|
|
5160
5471
|
* options, without a container: the bar layer with its axes, grid and labels, horizontal or stacked as the options say. Pass it to `toScene()` to render
|
|
5161
5472
|
* the preset chart with another renderer. Responsive options and the
|
|
5162
5473
|
* inline size style of the root svg are left out; both need a container.
|
|
5163
|
-
* @experimental
|
|
5164
5474
|
*/
|
|
5165
5475
|
function barChartConfig(data, options = {}) {
|
|
5166
5476
|
return presetConfig(barSpec, data, options);
|
|
@@ -5173,7 +5483,6 @@ function createBarChart(target, data, options = {}, responsiveOptions, plugins)
|
|
|
5173
5483
|
* Creates a bar chart with the 1.x options and output, rendered
|
|
5174
5484
|
* synchronously. Plugins must be v2 plugins; convert 1.x plugins with
|
|
5175
5485
|
* `fromLegacyPlugin` from `chartist/compat`.
|
|
5176
|
-
* @experimental
|
|
5177
5486
|
*/
|
|
5178
5487
|
function barChart(target, data, options = {}, responsiveOptions) {
|
|
5179
5488
|
return createBarChart(target, data, options, responsiveOptions).handle;
|
|
@@ -5289,7 +5598,6 @@ function labelText(text, position, anchor, className, ctx) {
|
|
|
5289
5598
|
* className: 'ct-chart-donut'
|
|
5290
5599
|
* });
|
|
5291
5600
|
* ```
|
|
5292
|
-
* @experimental
|
|
5293
5601
|
*/
|
|
5294
5602
|
function pie(options = {}) {
|
|
5295
5603
|
const classNames = {
|
|
@@ -5493,7 +5801,6 @@ const pieSpec = {
|
|
|
5493
5801
|
* options, without a container: the pie layer with its labels. Pass it to `toScene()` to render
|
|
5494
5802
|
* the preset chart with another renderer. Responsive options and the
|
|
5495
5803
|
* inline size style of the root svg are left out; both need a container.
|
|
5496
|
-
* @experimental
|
|
5497
5804
|
*/
|
|
5498
5805
|
function pieChartConfig(data, options = {}) {
|
|
5499
5806
|
return presetConfig(pieSpec, data, options);
|
|
@@ -5506,7 +5813,6 @@ function createPieChart(target, data, options = {}, responsiveOptions, plugins)
|
|
|
5506
5813
|
* Creates a pie or donut chart with the 1.x options and output, rendered
|
|
5507
5814
|
* synchronously. Plugins must be v2 plugins; convert 1.x plugins with
|
|
5508
5815
|
* `fromLegacyPlugin` from `chartist/compat`.
|
|
5509
|
-
* @experimental
|
|
5510
5816
|
*/
|
|
5511
5817
|
function pieChart(target, data, options = {}, responsiveOptions) {
|
|
5512
5818
|
return createPieChart(target, data, options, responsiveOptions).handle;
|
|
@@ -5818,7 +6124,6 @@ var interpolation_exports = /* @__PURE__ */ __exportAll({
|
|
|
5818
6124
|
* // The color of series `c`, the third.
|
|
5819
6125
|
* export const third = seriesColors[2];
|
|
5820
6126
|
* ```
|
|
5821
|
-
* @experimental
|
|
5822
6127
|
*/
|
|
5823
6128
|
const seriesColors = [
|
|
5824
6129
|
"#d70206",
|
|
@@ -5901,7 +6206,6 @@ function serialize$1(current, position) {
|
|
|
5901
6206
|
* return renderToString(scene);
|
|
5902
6207
|
* }
|
|
5903
6208
|
* ```
|
|
5904
|
-
* @experimental
|
|
5905
6209
|
*/
|
|
5906
6210
|
function renderToString(scene) {
|
|
5907
6211
|
return serialize$1(scene, "root");
|
|
@@ -5964,7 +6268,6 @@ function unavailable(method) {
|
|
|
5964
6268
|
*
|
|
5965
6269
|
* export const markup = renderToString(scene);
|
|
5966
6270
|
* ```
|
|
5967
|
-
* @experimental
|
|
5968
6271
|
*/
|
|
5969
6272
|
function toScene(config, size) {
|
|
5970
6273
|
const emitter = createPhaseEmitter();
|
|
@@ -6131,7 +6434,6 @@ function edgeContext(option, context) {
|
|
|
6131
6434
|
* ]
|
|
6132
6435
|
* });
|
|
6133
6436
|
* ```
|
|
6134
|
-
* @experimental
|
|
6135
6437
|
*/
|
|
6136
6438
|
function band(options) {
|
|
6137
6439
|
const hasEdges = options.low !== void 0 || options.high !== void 0;
|
|
@@ -6171,6 +6473,7 @@ function band(options) {
|
|
|
6171
6473
|
const clamp = (value) => range ? Math.min(Math.max(value, range.min), range.max) : value;
|
|
6172
6474
|
const edges = bandEdges(options, context, clamp);
|
|
6173
6475
|
let pieces;
|
|
6476
|
+
const interpolation = interpolationOf(options.lineSmooth ?? true);
|
|
6174
6477
|
if (edges.constant) {
|
|
6175
6478
|
const { low, high } = edges.at(0);
|
|
6176
6479
|
const lowY = area.y1 - axisY.project(low);
|
|
@@ -6191,7 +6494,6 @@ function band(options) {
|
|
|
6191
6494
|
});
|
|
6192
6495
|
}
|
|
6193
6496
|
const shift = centerShift(axisX, options.align);
|
|
6194
|
-
const interpolation = interpolationOf(options.lineSmooth ?? true);
|
|
6195
6497
|
const pathOf = (values) => seriesPath(values, {
|
|
6196
6498
|
x: axisX,
|
|
6197
6499
|
y: axisY
|
|
@@ -6214,7 +6516,8 @@ function band(options) {
|
|
|
6214
6516
|
role: "band",
|
|
6215
6517
|
ctx: {
|
|
6216
6518
|
...edgesContext,
|
|
6217
|
-
path: path.clone()
|
|
6519
|
+
path: path.clone(),
|
|
6520
|
+
smoothing: interpolation
|
|
6218
6521
|
}
|
|
6219
6522
|
}));
|
|
6220
6523
|
return [withFields(node("g", {}, options.className ? `${classNames.band} ${options.className}` : classNames.band), { children })];
|
|
@@ -6285,7 +6588,6 @@ const LABEL_INSET = 4;
|
|
|
6285
6588
|
* ]
|
|
6286
6589
|
* });
|
|
6287
6590
|
* ```
|
|
6288
|
-
* @experimental
|
|
6289
6591
|
*/
|
|
6290
6592
|
function targetLine(options) {
|
|
6291
6593
|
const { value, label, className } = options;
|
|
@@ -6455,7 +6757,6 @@ function hasX(values) {
|
|
|
6455
6757
|
* layers: [axisGrid(), line(), trendLine(), axisLabels()]
|
|
6456
6758
|
* });
|
|
6457
6759
|
* ```
|
|
6458
|
-
* @experimental
|
|
6459
6760
|
*/
|
|
6460
6761
|
function trendLine(options = {}) {
|
|
6461
6762
|
const classNames = {
|
|
@@ -6630,7 +6931,6 @@ function nodesOf(axis, context, classNames, svgLabel) {
|
|
|
6630
6931
|
* ```
|
|
6631
6932
|
* @param options The axes to draw and their classes; `background` adds a
|
|
6632
6933
|
* `rect.ct-grid-background` over the chart area, behind the lines.
|
|
6633
|
-
* @experimental
|
|
6634
6934
|
*/
|
|
6635
6935
|
function axisGrid(options = {}) {
|
|
6636
6936
|
const classNames = {
|
|
@@ -6685,7 +6985,6 @@ function axisGrid(options = {}) {
|
|
|
6685
6985
|
* ]
|
|
6686
6986
|
* });
|
|
6687
6987
|
* ```
|
|
6688
|
-
* @experimental
|
|
6689
6988
|
*/
|
|
6690
6989
|
function axisLabels(options = {}) {
|
|
6691
6990
|
const classNames = {
|
|
@@ -6726,6 +7025,7 @@ exports.Svg = Svg;
|
|
|
6726
7025
|
exports.SvgList = SvgList;
|
|
6727
7026
|
exports.SvgPath = SvgPath;
|
|
6728
7027
|
exports.alphaNumerate = alphaNumerate;
|
|
7028
|
+
exports.applyAttribute = applyAttribute;
|
|
6729
7029
|
exports.autoScaleAxis = autoScaleAxis;
|
|
6730
7030
|
exports.axisGrid = axisGrid;
|
|
6731
7031
|
exports.axisLabels = axisLabels;
|
|
@@ -6765,6 +7065,7 @@ exports.isDataHoleValue = isDataHoleValue;
|
|
|
6765
7065
|
exports.isFalseyButZero = isFalseyButZero;
|
|
6766
7066
|
exports.isMultiValue = isMultiValue;
|
|
6767
7067
|
exports.isNumeric = isNumeric;
|
|
7068
|
+
exports.keySplinesOf = keySplinesOf;
|
|
6768
7069
|
exports.line = line;
|
|
6769
7070
|
exports.lineChart = lineChart;
|
|
6770
7071
|
exports.lineChartConfig = lineChartConfig;
|
|
@@ -6783,11 +7084,13 @@ exports.polarToCartesian = polarToCartesian;
|
|
|
6783
7084
|
exports.precision = precision;
|
|
6784
7085
|
exports.projectLength = projectLength;
|
|
6785
7086
|
exports.quantity = quantity;
|
|
7087
|
+
exports.renderElement = renderElement;
|
|
6786
7088
|
exports.renderToString = renderToString;
|
|
6787
7089
|
exports.responsive = responsive;
|
|
6788
7090
|
exports.rho = rho;
|
|
6789
7091
|
exports.roundWithPrecision = roundWithPrecision;
|
|
6790
7092
|
exports.safeHasProperty = safeHasProperty;
|
|
7093
|
+
exports.sampleEasing = sampleEasing;
|
|
6791
7094
|
exports.serialMap = serialMap;
|
|
6792
7095
|
exports.serialize = serialize;
|
|
6793
7096
|
exports.seriesColors = seriesColors;
|