layerchart 0.6.2 → 0.6.5
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/components/AxisY.svelte +1 -4
- package/components/ChartClipPath.svelte +1 -0
- package/components/ChartClipPath.svelte.d.ts +2 -0
- package/components/CircleClipPath.svelte +1 -1
- package/components/CircleClipPath.svelte.d.ts +2 -0
- package/components/HighlightLine.svelte +57 -21
- package/components/HighlightRect.svelte +11 -3
- package/components/RectClipPath.svelte +1 -1
- package/components/RectClipPath.svelte.d.ts +2 -0
- package/components/Text2.svelte +43 -0
- package/components/Text2.svelte.d.ts +22 -0
- package/components/Tooltip.svelte +31 -9
- package/components/Zoom.svelte +13 -9
- package/components/Zoom.svelte.d.ts +2 -0
- package/package.json +2 -1
- package/utils/genData.js +2 -2
- package/utils/index.d.ts +4 -0
- package/utils/index.js +4 -0
- package/utils/scales.d.ts +10 -2
- package/utils/scales.js +24 -2
- package/utils/stack.d.ts +3 -1
- package/utils/stack.js +2 -2
package/components/AxisY.svelte
CHANGED
|
@@ -20,10 +20,7 @@ $: tickVals = Array.isArray(ticks)
|
|
|
20
20
|
|
|
21
21
|
<g class="axis y-axis" transform="translate({-$padding.left}, 0)">
|
|
22
22
|
{#each tickVals as tick, i}
|
|
23
|
-
<g
|
|
24
|
-
class="tick tick-{tick}"
|
|
25
|
-
transform="translate({$xRange[0] + (isBand ? $padding.left : 0)}, {$yScale(tick)})"
|
|
26
|
-
>
|
|
23
|
+
<g class="tick tick-{tick}" transform="translate({$xRange[0]}, {$yScale(tick)})">
|
|
27
24
|
{#if gridlines !== false}
|
|
28
25
|
<line
|
|
29
26
|
x1={$padding.left}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<script>import {
|
|
1
|
+
<script>import { isScaleBand } from '../utils/scales';
|
|
2
|
+
import { getContext } from 'svelte';
|
|
2
3
|
import { get } from 'svelte/store';
|
|
3
4
|
import Circle from './Circle.svelte';
|
|
4
5
|
import Line from './Line.svelte';
|
|
@@ -10,33 +11,68 @@ $: x = $xGet(data);
|
|
|
10
11
|
function getColor(index) {
|
|
11
12
|
return color ?? get(zScale)(index) ?? 'var(--color-blue-500)';
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
let lines = [];
|
|
15
|
+
$: if (Array.isArray(x)) {
|
|
16
|
+
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
17
|
+
lines = x.map((xItem, i) => ({
|
|
18
|
+
x1: xItem,
|
|
19
|
+
y1: 0,
|
|
20
|
+
x2: xItem,
|
|
21
|
+
y2: $yRange[0]
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
lines = [
|
|
26
|
+
{
|
|
27
|
+
x1: x,
|
|
28
|
+
y1: 0,
|
|
29
|
+
x2: x,
|
|
30
|
+
y2: $yRange[0]
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
let points = [];
|
|
35
|
+
$: yOffset = isScaleBand($yScale) ? $yScale.bandwidth() / 2 : 0;
|
|
36
|
+
$: if (Array.isArray(x)) {
|
|
37
|
+
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
38
|
+
points = x.map((xItem, i) => ({
|
|
39
|
+
x: xItem,
|
|
40
|
+
y: $yGet(data) + yOffset,
|
|
41
|
+
color: getColor(i)
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
else if (Array.isArray(data)) {
|
|
45
|
+
// Stack series
|
|
46
|
+
points = data.map((yValue, i) => ({
|
|
47
|
+
x,
|
|
48
|
+
y: $yScale(yValue) + yOffset,
|
|
49
|
+
color: getColor(i)
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
points = [
|
|
21
54
|
{
|
|
22
55
|
x,
|
|
23
|
-
y: $yGet(data)
|
|
56
|
+
y: $yGet(data) + yOffset,
|
|
24
57
|
color: getColor(0)
|
|
25
58
|
}
|
|
26
59
|
];
|
|
60
|
+
}
|
|
27
61
|
</script>
|
|
28
62
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
63
|
+
{#each lines as line}
|
|
64
|
+
<Line
|
|
65
|
+
spring
|
|
66
|
+
x1={line.x1}
|
|
67
|
+
y1={line.y1}
|
|
68
|
+
x2={line.x2}
|
|
69
|
+
y2={line.y2}
|
|
70
|
+
stroke="rgba(0,0,0,.5)"
|
|
71
|
+
stroke-width={2}
|
|
72
|
+
style="pointerEvents: none"
|
|
73
|
+
stroke-dasharray="2,2"
|
|
74
|
+
/>
|
|
75
|
+
{/each}
|
|
40
76
|
|
|
41
77
|
{#each points as point}
|
|
42
78
|
<Circle
|
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
<script>import { getContext } from 'svelte';
|
|
2
|
+
import { max, min } from 'd3-array';
|
|
2
3
|
import { isScaleBand } from '../utils/scales';
|
|
3
4
|
import Rect from './Rect.svelte';
|
|
4
5
|
export let data;
|
|
5
6
|
const { flatData, xScale, x, xGet, yRange, padding } = getContext('LayerCake');
|
|
6
7
|
$: isBand = isScaleBand($xScale);
|
|
8
|
+
$: xCoord = $xGet(data);
|
|
7
9
|
let width = 0;
|
|
8
10
|
$: if (isBand) {
|
|
9
11
|
width = $xScale.step();
|
|
10
12
|
}
|
|
13
|
+
else if (Array.isArray(xCoord)) {
|
|
14
|
+
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
15
|
+
// Use first/last values for width
|
|
16
|
+
width = max(xCoord) - min(xCoord);
|
|
17
|
+
xCoord = min(xCoord); // Use left-most value for top left of rect
|
|
18
|
+
}
|
|
11
19
|
else {
|
|
12
20
|
// Find width to next data point
|
|
13
21
|
let index = $flatData.findIndex((d) => Number($x(d)) === Number($x(data)));
|
|
14
22
|
let nextDataPoint = $x($flatData[index + 1]);
|
|
15
|
-
width = ($xScale(nextDataPoint) ?? 0) - (
|
|
23
|
+
width = ($xScale(nextDataPoint) ?? 0) - (xCoord ?? 0);
|
|
16
24
|
}
|
|
17
25
|
$: dimensions = {
|
|
18
|
-
x:
|
|
19
|
-
y:
|
|
26
|
+
x: xCoord - (isBand ? ($xScale.padding() * $xScale.step()) / 2 : 0),
|
|
27
|
+
y: 0,
|
|
20
28
|
width,
|
|
21
29
|
height: $yRange[0]
|
|
22
30
|
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script>import '$lib/utils/string';
|
|
2
|
+
/*
|
|
3
|
+
TODO:
|
|
4
|
+
- [ ] Handle styled text (use <slot /> to measure?)
|
|
5
|
+
- [ ] Simplify by using `alignment-baseline` / `dominant-baseline`, rework multiline or drop support, etc
|
|
6
|
+
- https://svelte.dev/repl/f12d3003313a43ba8a0be53e5786f1c7?version=3.44.3
|
|
7
|
+
- https://observablehq.com/@neocartocnrs/cheat-sheet-on-texts-in-svg
|
|
8
|
+
|
|
9
|
+
Reference:
|
|
10
|
+
- https://bl.ocks.org/mbostock/7555321
|
|
11
|
+
- https://github.com/airbnb/visx/blob/master/packages/visx-text/src/Text.tsx
|
|
12
|
+
- https://airbnb.io/visx/text
|
|
13
|
+
- https://github.com/airbnb/visx/blob/master/packages/visx-demo/src/pages/text.tsx
|
|
14
|
+
*/
|
|
15
|
+
/** x position of the text. */
|
|
16
|
+
export let x = 0;
|
|
17
|
+
/** y position of the text. */
|
|
18
|
+
export let y = 0;
|
|
19
|
+
/** dx offset of the text. */
|
|
20
|
+
export let dx = 0;
|
|
21
|
+
/** dy offset of the text. */
|
|
22
|
+
export let dy = 0;
|
|
23
|
+
/** Horizontal text anchor. */
|
|
24
|
+
export let textAnchor = 'start';
|
|
25
|
+
/** Vertical text anchor. */
|
|
26
|
+
export let verticalAnchor = 'end'; // default SVG behavior
|
|
27
|
+
/** Rotational angle of the text. */
|
|
28
|
+
export let rotate = undefined;
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<!-- overflow: visible; allow contents to be shown outside element -->
|
|
32
|
+
<!-- paint-order: stroke; support stroke outlining text -->
|
|
33
|
+
<!-- <svg x={dx} y={dy} style="overflow: visible; paint-order: stroke;">
|
|
34
|
+
{#if isValidXOrY(x) && isValidXOrY(y)}
|
|
35
|
+
<text {x} {y} {transform} text-anchor={textAnchor} {...$$restProps}>
|
|
36
|
+
{#each wordsByLines as line, index}
|
|
37
|
+
<tspan {x} dy={index === 0 ? startDy : lineHeight}>
|
|
38
|
+
{line.words.join(' ')}
|
|
39
|
+
</tspan>
|
|
40
|
+
{/each}
|
|
41
|
+
</text>
|
|
42
|
+
{/if}
|
|
43
|
+
</svg> -->
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
/** x position of the text. */ x?: string | number;
|
|
5
|
+
/** y position of the text. */ y?: string | number;
|
|
6
|
+
/** dx offset of the text. */ dx?: string | number;
|
|
7
|
+
/** dy offset of the text. */ dy?: string | number;
|
|
8
|
+
/** Horizontal text anchor. */ textAnchor?: 'start' | 'middle' | 'end' | 'inherit';
|
|
9
|
+
/** Vertical text anchor. */ verticalAnchor?: 'start' | 'middle' | 'end' | 'inherit';
|
|
10
|
+
/** Rotational angle of the text. */ rotate?: number;
|
|
11
|
+
};
|
|
12
|
+
events: {
|
|
13
|
+
[evt: string]: CustomEvent<any>;
|
|
14
|
+
};
|
|
15
|
+
slots: {};
|
|
16
|
+
};
|
|
17
|
+
export declare type Text2Props = typeof __propDef.props;
|
|
18
|
+
export declare type Text2Events = typeof __propDef.events;
|
|
19
|
+
export declare type Text2Slots = typeof __propDef.slots;
|
|
20
|
+
export default class Text2 extends SvelteComponentTyped<Text2Props, Text2Events, Text2Slots> {
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -46,21 +46,43 @@ function handleTooltip(event) {
|
|
|
46
46
|
const localY = point?.y ?? 0;
|
|
47
47
|
let tooltipData;
|
|
48
48
|
if (isScaleBand($xScale)) {
|
|
49
|
-
// `x` value at mouse coordinate
|
|
50
|
-
const
|
|
51
|
-
tooltipData = $flatData.find((d) => $x(d) ===
|
|
49
|
+
// `x` value at mouse/touch coordinate
|
|
50
|
+
const valueAtPoint = scaleBandInvert($xScale)(localX);
|
|
51
|
+
tooltipData = $flatData.find((d) => $x(d) === valueAtPoint);
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
// `x` value at mouse coordinate
|
|
55
|
-
const
|
|
56
|
-
const bisectX = bisector(
|
|
57
|
-
|
|
54
|
+
// `x` value at mouse/touch coordinate
|
|
55
|
+
const valueAtPoint = $xScale.invert(localX);
|
|
56
|
+
const bisectX = bisector((d) => {
|
|
57
|
+
const value = $x(d);
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
60
|
+
// Using first value. Consider using average, max, etc
|
|
61
|
+
// const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
|
|
62
|
+
// return midpoint;
|
|
63
|
+
return value[0];
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
}).left;
|
|
69
|
+
const index = bisectX($flatData, valueAtPoint, 1);
|
|
58
70
|
const data0 = $flatData[index - 1];
|
|
59
71
|
const data1 = $flatData[index];
|
|
60
72
|
switch (findTooltipData) {
|
|
61
73
|
case 'closest':
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
if (data1 === undefined) {
|
|
75
|
+
tooltipData = data0;
|
|
76
|
+
}
|
|
77
|
+
else if (data0 === undefined) {
|
|
78
|
+
tooltipData = data1;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
tooltipData =
|
|
82
|
+
Number(valueAtPoint) - Number($x(data0)) > Number($x(data1)) - Number(valueAtPoint)
|
|
83
|
+
? data1
|
|
84
|
+
: data0;
|
|
85
|
+
}
|
|
64
86
|
break;
|
|
65
87
|
case 'left':
|
|
66
88
|
tooltipData = data0;
|
package/components/Zoom.svelte
CHANGED
|
@@ -114,16 +114,20 @@ $: newTranslate = {
|
|
|
114
114
|
};
|
|
115
115
|
</script>
|
|
116
116
|
|
|
117
|
-
<
|
|
118
|
-
x={-$padding.left}
|
|
119
|
-
y={-$padding.top}
|
|
120
|
-
width={$width + $padding.left + $padding.right}
|
|
121
|
-
height={$height + $padding.top + $padding.bottom}
|
|
117
|
+
<g
|
|
122
118
|
on:mousewheel={handleWheel}
|
|
123
119
|
on:mousedown={handleMouseDown}
|
|
124
120
|
on:dblclick={handleDoubleClick}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<
|
|
128
|
-
|
|
121
|
+
on:click
|
|
122
|
+
>
|
|
123
|
+
<rect
|
|
124
|
+
x={-$padding.left}
|
|
125
|
+
y={-$padding.top}
|
|
126
|
+
width={$width + $padding.left + $padding.right}
|
|
127
|
+
height={$height + $padding.top + $padding.bottom}
|
|
128
|
+
fill="transparent"
|
|
129
|
+
/>
|
|
130
|
+
<g transform="translate({newTranslate.x},{newTranslate.y}) scale({$scale.x},{$scale.y})">
|
|
131
|
+
<slot scale={$scale} />
|
|
132
|
+
</g>
|
|
129
133
|
</g>
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"author": "Sean Lynch <techniq35@gmail.com>",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "techniq/layerchart",
|
|
6
|
-
"version": "0.6.
|
|
6
|
+
"version": "0.6.5",
|
|
7
7
|
"devDependencies": {
|
|
8
8
|
"@rollup/plugin-dsv": "^2.0.3",
|
|
9
9
|
"@sveltejs/adapter-vercel": "^1.0.0-next.58",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"./components/RectClipPath.svelte": "./components/RectClipPath.svelte",
|
|
81
81
|
"./components/Sankey.svelte": "./components/Sankey.svelte",
|
|
82
82
|
"./components/Text.svelte": "./components/Text.svelte",
|
|
83
|
+
"./components/Text2.svelte": "./components/Text2.svelte",
|
|
83
84
|
"./components/Threshold.svelte": "./components/Threshold.svelte",
|
|
84
85
|
"./components/Tooltip.svelte": "./components/Tooltip.svelte",
|
|
85
86
|
"./components/Tree.svelte": "./components/Tree.svelte",
|
package/utils/genData.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { subDays } from 'date-fns';
|
|
1
|
+
import { startOfToday, subDays } from 'date-fns';
|
|
2
2
|
import { degreesToRadians, radiansToDegrees } from './math';
|
|
3
3
|
/**
|
|
4
4
|
* Get random number between min (inclusive) and max (exclusive)
|
|
@@ -17,7 +17,7 @@ export function getRandomInteger(min, max, includeMax = true) {
|
|
|
17
17
|
return Math.floor(Math.random() * (max - min + (includeMax ? 1 : 0)) + min);
|
|
18
18
|
}
|
|
19
19
|
export function createDateSeries(options) {
|
|
20
|
-
const now =
|
|
20
|
+
const now = startOfToday();
|
|
21
21
|
const count = options.count ?? 10;
|
|
22
22
|
const min = options.min;
|
|
23
23
|
const max = options.max;
|
package/utils/index.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
+
export { graphFromCsv, graphFromHierarchy, graphFromNode } from './graph';
|
|
2
|
+
export { findAncestor } from './hierarchy';
|
|
3
|
+
export { degreesToRadians, radiansToDegrees } from './math';
|
|
4
|
+
export { createStackData, stackOffsetSeparated } from './stack';
|
|
1
5
|
export { getMajorTicks, getMinorTicks } from './ticks';
|
package/utils/index.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
+
export { graphFromCsv, graphFromHierarchy, graphFromNode } from './graph';
|
|
2
|
+
export { findAncestor } from './hierarchy';
|
|
3
|
+
export { degreesToRadians, radiansToDegrees } from './math';
|
|
4
|
+
export { createStackData, stackOffsetSeparated } from './stack';
|
|
1
5
|
export { getMajorTicks, getMinorTicks } from './ticks';
|
package/utils/scales.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tweened } from 'svelte/motion';
|
|
1
|
+
import { tweened, spring } from 'svelte/motion';
|
|
2
2
|
import { MotionOptions } from '../stores/motionStore';
|
|
3
3
|
/**
|
|
4
4
|
* Implemenation for missing `scaleBand().invert()`
|
|
@@ -19,7 +19,15 @@ export declare function tweenedScale(scale: any, tweenedOptions?: Parameters<typ
|
|
|
19
19
|
range: (values: any) => Promise<void>;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Animate d3-scale as domain and/or range are updated using spring store
|
|
23
|
+
*/
|
|
24
|
+
export declare function springScale(scale: any, springOptions?: Parameters<typeof spring>[1]): {
|
|
25
|
+
subscribe: (this: void, run: import("svelte/store").Subscriber<any>, invalidate?: (value?: any) => void) => import("svelte/store").Unsubscriber;
|
|
26
|
+
domain: (values: any) => Promise<void>;
|
|
27
|
+
range: (values: any) => Promise<void>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Create a store wrapper around a d3-scale which interpolates the domain and/or range using `tweened()` or `spring()` stores. Fallbacks to `writable()` store if not interpolating
|
|
23
31
|
*/
|
|
24
32
|
export declare function motionScale(scale: any, options: MotionOptions): {
|
|
25
33
|
subscribe: (this: void, run: import("svelte/store").Subscriber<any>, invalidate?: (value?: any) => void) => import("svelte/store").Unsubscriber;
|
package/utils/scales.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { derived } from 'svelte/store';
|
|
2
|
-
import { tweened } from 'svelte/motion';
|
|
2
|
+
import { tweened, spring } from 'svelte/motion';
|
|
3
3
|
import { motionStore } from '../stores/motionStore';
|
|
4
4
|
/**
|
|
5
5
|
* Implemenation for missing `scaleBand().invert()`
|
|
@@ -45,7 +45,29 @@ export function tweenedScale(scale, tweenedOptions = {}) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* Animate d3-scale as domain and/or range are updated using spring store
|
|
49
|
+
*/
|
|
50
|
+
export function springScale(scale, springOptions = {}) {
|
|
51
|
+
const domainStore = spring(undefined, springOptions);
|
|
52
|
+
const rangeStore = spring(undefined, springOptions);
|
|
53
|
+
const tweenedScale = derived([domainStore, rangeStore], ([domain, range]) => {
|
|
54
|
+
const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
|
|
55
|
+
if (domain) {
|
|
56
|
+
scaleInstance.domain(domain);
|
|
57
|
+
}
|
|
58
|
+
if (range) {
|
|
59
|
+
scaleInstance.range(range);
|
|
60
|
+
}
|
|
61
|
+
return scaleInstance;
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
subscribe: tweenedScale.subscribe,
|
|
65
|
+
domain: (values) => domainStore.set(values),
|
|
66
|
+
range: (values) => rangeStore.set(values)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create a store wrapper around a d3-scale which interpolates the domain and/or range using `tweened()` or `spring()` stores. Fallbacks to `writable()` store if not interpolating
|
|
49
71
|
*/
|
|
50
72
|
export function motionScale(scale, options) {
|
|
51
73
|
const domainStore = motionStore(undefined, options);
|
package/utils/stack.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { stackOffsetNone } from 'd3-shape';
|
|
1
|
+
import { stackOffsetNone, stackOrderNone } from 'd3-shape';
|
|
2
|
+
declare type OrderType = typeof stackOrderNone;
|
|
2
3
|
declare type OffsetType = typeof stackOffsetNone;
|
|
3
4
|
export declare function createStackData(data: any[], options: {
|
|
4
5
|
xKey: string;
|
|
5
6
|
groupBy?: string;
|
|
6
7
|
stackBy?: string;
|
|
8
|
+
order?: OrderType;
|
|
7
9
|
offset?: OffsetType;
|
|
8
10
|
}): any[];
|
|
9
11
|
/**
|
package/utils/stack.js
CHANGED
|
@@ -10,7 +10,7 @@ export function createStackData(data, options) {
|
|
|
10
10
|
const itemData = d.slice(-1)[0]; // last item
|
|
11
11
|
const pivotData = pivotWider(itemData, options.xKey, options.stackBy, 'value');
|
|
12
12
|
const stackKeys = [...new Set(itemData.map((d) => d[options.stackBy]))];
|
|
13
|
-
const stackData = stack().keys(stackKeys).offset(options.offset)(pivotData);
|
|
13
|
+
const stackData = stack().keys(stackKeys).order(options.order).offset(options.offset)(pivotData);
|
|
14
14
|
//console.log({ pivotData, stackData })
|
|
15
15
|
return stackData.flatMap((series) => {
|
|
16
16
|
//console.log({ series })
|
|
@@ -29,7 +29,7 @@ export function createStackData(data, options) {
|
|
|
29
29
|
// Stack only
|
|
30
30
|
const pivotData = pivotWider(data, options.xKey, options.stackBy, 'value');
|
|
31
31
|
const stackKeys = [...new Set(data.map((d) => d[options.stackBy]))];
|
|
32
|
-
const stackData = stack().keys(stackKeys).offset(options.offset)(pivotData);
|
|
32
|
+
const stackData = stack().keys(stackKeys).order(options.order).offset(options.offset)(pivotData);
|
|
33
33
|
const result = stackData.flatMap((series) => {
|
|
34
34
|
return series.flatMap((s) => {
|
|
35
35
|
return {
|