@vuu-ui/vuu-chart 4.0.0 → 4.1.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 +324 -0
- package/package.json +7 -7
- package/src/Chart.css.js +22 -0
- package/src/Chart.js +2 -2
- package/src/ChartSeries.js +20 -3
- package/src/chart-data/ChartDataStore.js +131 -0
- package/src/chart-data/projection-utils.js +119 -0
- package/src/charts/CandlestickChart.js +31 -0
- package/src/charts/CartesianChart.js +28 -0
- package/src/charts/DepthChart.js +28 -0
- package/src/charts/HeatmapChart.js +31 -0
- package/src/charts/HierarchyChart.js +41 -0
- package/src/charts/candlestick-model.js +373 -0
- package/src/charts/cartesian-model.js +234 -0
- package/src/charts/depth-model.js +159 -0
- package/src/charts/heatmap-model.js +243 -0
- package/src/charts/hierarchy-model.js +224 -0
- package/src/echarts.js +26 -0
- package/src/engine/ChartModel.js +2 -0
- package/src/engine/VuuChartContainer.js +196 -0
- package/src/engine/useStructuralMemo.js +18 -0
- package/src/index.js +8 -0
- package/src/options/common.js +181 -0
- package/src/options/mergeOptions.js +37 -0
- package/src/theme/chartTheme.js +74 -0
- package/src/useChartOptions.js +25 -2
- package/src/vuu-chart-types.js +0 -0
- package/types/Chart.d.ts +1 -1
- package/types/ChartSeries.d.ts +15 -0
- package/types/charts/CandlestickChart.d.ts +1 -1
- package/types/charts/CartesianChart.d.ts +1 -1
- package/types/charts/DepthChart.d.ts +1 -1
- package/types/charts/HeatmapChart.d.ts +1 -1
- package/types/charts/HierarchyChart.d.ts +4 -4
- package/types/engine/VuuChartContainer.d.ts +1 -1
- package/types/index.d.ts +18 -4
- package/types/useChartContextMenu.d.ts +1 -1
- package/types/useChartOptions.d.ts +1 -1
- package/types/useChartSelection.d.ts +1 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const isPlainObject = (value)=>null !== value && "object" == typeof value && (Object.getPrototypeOf(value) === Object.prototype || null === Object.getPrototypeOf(value));
|
|
2
|
+
const hasId = (value)=>isPlainObject(value) && void 0 !== value.id;
|
|
3
|
+
const mergeArrays = (base, override)=>{
|
|
4
|
+
const result = base.slice();
|
|
5
|
+
override.forEach((item, i)=>{
|
|
6
|
+
if (hasId(item)) {
|
|
7
|
+
const index = result.findIndex((b)=>hasId(b) && b.id === item.id);
|
|
8
|
+
if (-1 !== index) result[index] = mergeValues(result[index], item);
|
|
9
|
+
else result.push(item);
|
|
10
|
+
} else if (i < result.length) result[i] = mergeValues(result[i], item);
|
|
11
|
+
else result.push(item);
|
|
12
|
+
});
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
const mergeValues = (base, override)=>{
|
|
16
|
+
if (void 0 === override) return base;
|
|
17
|
+
if (isPlainObject(base) && isPlainObject(override)) {
|
|
18
|
+
const result = {
|
|
19
|
+
...base
|
|
20
|
+
};
|
|
21
|
+
for (const [key, value] of Object.entries(override))result[key] = mergeValues(base[key], value);
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(override) && (Array.isArray(base) || isPlainObject(base))) {
|
|
25
|
+
const baseArray = Array.isArray(base) ? base : [
|
|
26
|
+
base
|
|
27
|
+
];
|
|
28
|
+
if (override.every((o)=>isPlainObject(o))) return mergeArrays(baseArray, override);
|
|
29
|
+
return override;
|
|
30
|
+
}
|
|
31
|
+
if (Array.isArray(base) && isPlainObject(override)) return mergeArrays(base, [
|
|
32
|
+
override
|
|
33
|
+
]);
|
|
34
|
+
return override;
|
|
35
|
+
};
|
|
36
|
+
const mergeEChartsOptions = (base, ...overrides)=>overrides.reduce((result, override)=>override ? mergeValues(result, override) : result, base);
|
|
37
|
+
export { mergeEChartsOptions };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const defaultPalette = [
|
|
2
|
+
"#4676bf",
|
|
3
|
+
"#ab6528",
|
|
4
|
+
"#9f55c2",
|
|
5
|
+
"#2a8285",
|
|
6
|
+
"#697694",
|
|
7
|
+
"#b0549d",
|
|
8
|
+
"#c69d26",
|
|
9
|
+
"#5c8a3a"
|
|
10
|
+
];
|
|
11
|
+
const defaultChartTheme = {
|
|
12
|
+
axisLineColor: "#9fa3a8",
|
|
13
|
+
backgroundColor: "transparent",
|
|
14
|
+
crosshairColor: "#697694",
|
|
15
|
+
downColor: "#e52135",
|
|
16
|
+
fontFamily: "sans-serif",
|
|
17
|
+
foregroundColor: "#15171b",
|
|
18
|
+
heatmapColors: [
|
|
19
|
+
"#e2ebf8",
|
|
20
|
+
"#1b4f9c"
|
|
21
|
+
],
|
|
22
|
+
palette: defaultPalette,
|
|
23
|
+
secondaryForegroundColor: "#5f646d",
|
|
24
|
+
splitLineColor: "#e6e8ea",
|
|
25
|
+
tooltipBackgroundColor: "#ffffff",
|
|
26
|
+
tooltipBorderColor: "#2670a9",
|
|
27
|
+
upColor: "#00875d"
|
|
28
|
+
};
|
|
29
|
+
const PALETTE_SIZE = 8;
|
|
30
|
+
const read = (style, name, fallback)=>{
|
|
31
|
+
const value = style.getPropertyValue(name).trim();
|
|
32
|
+
return "" === value ? fallback : value;
|
|
33
|
+
};
|
|
34
|
+
const resolveChartTheme = (element, overrides)=>{
|
|
35
|
+
let theme = defaultChartTheme;
|
|
36
|
+
if (element && "function" == typeof getComputedStyle) {
|
|
37
|
+
const style = getComputedStyle(element);
|
|
38
|
+
const d = defaultChartTheme;
|
|
39
|
+
const palette = [];
|
|
40
|
+
for(let i = 0; i < PALETTE_SIZE; i++)palette.push(read(style, `--vuuChart-color-${i + 1}`, d.palette[i]));
|
|
41
|
+
theme = {
|
|
42
|
+
axisLineColor: read(style, "--vuuChart-axisLineColor", d.axisLineColor),
|
|
43
|
+
backgroundColor: read(style, "--vuuChart-background", d.backgroundColor),
|
|
44
|
+
crosshairColor: read(style, "--vuuChart-crosshairColor", d.crosshairColor),
|
|
45
|
+
downColor: read(style, "--vuuChart-downColor", d.downColor),
|
|
46
|
+
fontFamily: read(style, "--vuuChart-fontFamily", d.fontFamily),
|
|
47
|
+
foregroundColor: read(style, "--vuuChart-foreground", d.foregroundColor),
|
|
48
|
+
heatmapColors: [
|
|
49
|
+
read(style, "--vuuChart-heatmap-lowColor", d.heatmapColors[0]),
|
|
50
|
+
read(style, "--vuuChart-heatmap-highColor", d.heatmapColors[1])
|
|
51
|
+
],
|
|
52
|
+
palette,
|
|
53
|
+
secondaryForegroundColor: read(style, "--vuuChart-secondaryForeground", d.secondaryForegroundColor),
|
|
54
|
+
splitLineColor: read(style, "--vuuChart-splitLineColor", d.splitLineColor),
|
|
55
|
+
tooltipBackgroundColor: read(style, "--vuuChart-tooltip-background", d.tooltipBackgroundColor),
|
|
56
|
+
tooltipBorderColor: read(style, "--vuuChart-tooltip-borderColor", d.tooltipBorderColor),
|
|
57
|
+
upColor: read(style, "--vuuChart-upColor", d.upColor)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return overrides ? {
|
|
61
|
+
...theme,
|
|
62
|
+
...overrides
|
|
63
|
+
} : theme;
|
|
64
|
+
};
|
|
65
|
+
const resolveColor = (color, theme)=>{
|
|
66
|
+
if ("up" === color) return theme.upColor;
|
|
67
|
+
if ("down" === color) return theme.downColor;
|
|
68
|
+
if (color?.startsWith("palette-")) {
|
|
69
|
+
const index = parseInt(color.slice(8), 10) - 1;
|
|
70
|
+
return theme.palette[index % theme.palette.length];
|
|
71
|
+
}
|
|
72
|
+
return color;
|
|
73
|
+
};
|
|
74
|
+
export { defaultChartTheme, defaultPalette, resolveChartTheme, resolveColor };
|
package/src/useChartOptions.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { itemsChanged } from "@vuu-ui/vuu-utils";
|
|
2
|
-
import { useMemo, useState } from "react";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { ChartSeries } from "./ChartSeries.js";
|
|
4
4
|
import { chartTooltip } from "./chartTooltip.js";
|
|
5
5
|
const defaultPalette = [
|
|
@@ -16,6 +16,7 @@ const combineConfig = (config, overrides)=>({
|
|
|
16
16
|
});
|
|
17
17
|
const useChartOptions = ({ categoryColumnName, config, dataExclusions, dataSource, itemColorFunction, palette = defaultPalette, seriesColumnNames, showTooltip = true, symbolSizeFunction: symbolSize })=>{
|
|
18
18
|
const [, forceRender] = useState({});
|
|
19
|
+
const frameRef = useRef(void 0);
|
|
19
20
|
const chartSeries = useMemo(()=>{
|
|
20
21
|
const cs = new ChartSeries({
|
|
21
22
|
config: combineConfig(config, {
|
|
@@ -26,12 +27,34 @@ const useChartOptions = ({ categoryColumnName, config, dataExclusions, dataSourc
|
|
|
26
27
|
dataSource,
|
|
27
28
|
palette
|
|
28
29
|
});
|
|
29
|
-
cs.on("update", ()=>
|
|
30
|
+
cs.on("update", ()=>{
|
|
31
|
+
if (void 0 === frameRef.current) frameRef.current = requestAnimationFrame(()=>{
|
|
32
|
+
frameRef.current = void 0;
|
|
33
|
+
forceRender({});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
30
36
|
return cs;
|
|
31
37
|
}, [
|
|
32
38
|
dataSource,
|
|
33
39
|
config
|
|
34
40
|
]);
|
|
41
|
+
const chartSeriesRef = useRef(chartSeries);
|
|
42
|
+
chartSeriesRef.current = chartSeries;
|
|
43
|
+
useEffect(()=>{
|
|
44
|
+
chartSeries.subscribe();
|
|
45
|
+
return ()=>{
|
|
46
|
+
if (void 0 !== frameRef.current) {
|
|
47
|
+
cancelAnimationFrame(frameRef.current);
|
|
48
|
+
frameRef.current = void 0;
|
|
49
|
+
}
|
|
50
|
+
chartSeries.detach();
|
|
51
|
+
};
|
|
52
|
+
}, [
|
|
53
|
+
chartSeries
|
|
54
|
+
]);
|
|
55
|
+
useEffect(()=>()=>{
|
|
56
|
+
chartSeriesRef.current.dispose();
|
|
57
|
+
}, []);
|
|
35
58
|
useMemo(()=>{
|
|
36
59
|
if (categoryColumnName !== chartSeries.categoryColumn) chartSeries.categoryColumn = categoryColumnName;
|
|
37
60
|
if (itemsChanged(seriesColumnNames, chartSeries.seriesColumnNames)) chartSeries.seriesColumnNames = seriesColumnNames;
|
|
File without changes
|
package/types/Chart.d.ts
CHANGED
|
@@ -24,5 +24,5 @@ export interface ChartProps extends ChartOptionsProps, Omit<MeasuredContainerPro
|
|
|
24
24
|
palette?: string[];
|
|
25
25
|
showTooltip?: boolean;
|
|
26
26
|
}
|
|
27
|
-
export declare const Chart: ({ categoryColumnName, chartSettings, className, config, dataExclusions, dataSource, height, optionSettings, palette, resizeStrategy, showTooltip, style, seriesColumnNames, width, ...htmlAttributes }: ChartProps) => import("react
|
|
27
|
+
export declare const Chart: ({ categoryColumnName, chartSettings, className, config, dataExclusions, dataSource, height, optionSettings, palette, resizeStrategy, showTooltip, style, seriesColumnNames, width, ...htmlAttributes }: ChartProps) => import("react").JSX.Element;
|
|
28
28
|
export {};
|
package/types/ChartSeries.d.ts
CHANGED
|
@@ -21,6 +21,21 @@ export declare class ChartSeries extends EventEmitter<ChartEvents> {
|
|
|
21
21
|
handleData: DataSourceSubscribeCallback;
|
|
22
22
|
buildCategoriesAndSeries(): void;
|
|
23
23
|
constructor({ config, dataExclusions, dataSource, palette, }: ChartSeriesConstructorProps);
|
|
24
|
+
/**
|
|
25
|
+
* Subscribes to the DataSource. Invoked by the constructor, only needs to
|
|
26
|
+
* be invoked again after dispose.
|
|
27
|
+
*/
|
|
28
|
+
subscribe(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Stops processing data from the DataSource, without unsubscribing it.
|
|
31
|
+
* Used when the DataSource is replaced, the caller may still be using
|
|
32
|
+
* the previous DataSource (e.g. as the source of an edit session).
|
|
33
|
+
*/
|
|
34
|
+
detach(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Stops processing data and unsubscribes from the DataSource.
|
|
37
|
+
*/
|
|
38
|
+
dispose(): void;
|
|
24
39
|
get palette(): (string | undefined)[];
|
|
25
40
|
get categoryColumn(): string;
|
|
26
41
|
set categoryColumn(categoryColumn: string);
|
|
@@ -6,4 +6,4 @@ export interface CandlestickChartProps extends Omit<VuuChartBaseProps, "legend">
|
|
|
6
6
|
* OHLC candlestick chart with optional volume pane and overlay series
|
|
7
7
|
* (e.g. a vwap line, or fills as scatter markers from a second DataSource).
|
|
8
8
|
*/
|
|
9
|
-
export declare const CandlestickChart: ({ crosshair, dataSource, dataZoom, formatTime, legend, markLines, ohlcColumnNames, overlays, showTooltip, timeColumnName, volumeColumnName, volumePaneHeight, xAxisType, ...props }: CandlestickChartProps) => import("react
|
|
9
|
+
export declare const CandlestickChart: ({ crosshair, dataSource, dataZoom, formatTime, legend, markLines, ohlcColumnNames, overlays, showTooltip, timeColumnName, volumeColumnName, volumePaneHeight, xAxisType, ...props }: CandlestickChartProps) => import("react").JSX.Element;
|
|
@@ -7,4 +7,4 @@ export interface CartesianChartProps extends Omit<VuuChartBaseProps, "legend">,
|
|
|
7
7
|
* scatter series, on a category, time or value x axis. Series may be read
|
|
8
8
|
* from multiple DataSources.
|
|
9
9
|
*/
|
|
10
|
-
export declare const CartesianChart: ({ aggregation, crosshair, dataSource, dataZoom, legend, orientation, series, showTooltip, xAxis, yAxes, ...props }: CartesianChartProps) => import("react
|
|
10
|
+
export declare const CartesianChart: ({ aggregation, crosshair, dataSource, dataZoom, legend, orientation, series, showTooltip, xAxis, yAxes, ...props }: CartesianChartProps) => import("react").JSX.Element;
|
|
@@ -5,4 +5,4 @@ export interface DepthChartProps extends Omit<VuuChartBaseProps, "legend">, Dept
|
|
|
5
5
|
/**
|
|
6
6
|
* Market depth chart: stepped cumulative bid and ask areas, by price.
|
|
7
7
|
*/
|
|
8
|
-
export declare const DepthChart: ({ askValue, bidValue, cumulativeSizeColumnName, dataSource, legend, priceColumnName, showMidPrice, showTooltip, sideColumnName, sizeColumnName, ...props }: DepthChartProps) => import("react
|
|
8
|
+
export declare const DepthChart: ({ askValue, bidValue, cumulativeSizeColumnName, dataSource, legend, priceColumnName, showMidPrice, showTooltip, sideColumnName, sizeColumnName, ...props }: DepthChartProps) => import("react").JSX.Element;
|
|
@@ -6,4 +6,4 @@ export interface HeatmapChartProps extends Omit<VuuChartBaseProps, "legend">, He
|
|
|
6
6
|
* Heatmap of a value column by two dimensions, e.g. traded quantity by
|
|
7
7
|
* price level and time bucket.
|
|
8
8
|
*/
|
|
9
|
-
export declare const HeatmapChart: ({ aggregation, colorScale, dataSource, dataZoom, formatTime, max, min, showTooltip, showVisualMap, valueColumnName, where, xAxis, yAxis, ...props }: HeatmapChartProps) => import("react
|
|
9
|
+
export declare const HeatmapChart: ({ aggregation, colorScale, dataSource, dataZoom, formatTime, max, min, showTooltip, showVisualMap, valueColumnName, where, xAxis, yAxis, ...props }: HeatmapChartProps) => import("react").JSX.Element;
|
|
@@ -6,10 +6,10 @@ export interface HierarchyChartProps extends Omit<VuuChartBaseProps, "legend">,
|
|
|
6
6
|
* Treemap, sunburst or pie breakdown of a value column, grouped by one or
|
|
7
7
|
* more columns e.g. exposure by sector -> ric.
|
|
8
8
|
*/
|
|
9
|
-
export declare const HierarchyChart: ({ aggregation, colorMode, dataSource, donut, formatValue, groupByColumnNames, legend, showTooltip, type, valueColumnName, where, ...props }: HierarchyChartProps) => import("react
|
|
9
|
+
export declare const HierarchyChart: ({ aggregation, colorMode, dataSource, donut, formatValue, groupByColumnNames, legend, showTooltip, type, valueColumnName, where, ...props }: HierarchyChartProps) => import("react").JSX.Element;
|
|
10
10
|
export type TreemapChartProps = Omit<HierarchyChartProps, "type" | "donut">;
|
|
11
|
-
export declare const TreemapChart: (props: TreemapChartProps) => import("react
|
|
11
|
+
export declare const TreemapChart: (props: TreemapChartProps) => import("react").JSX.Element;
|
|
12
12
|
export type SunburstChartProps = Omit<HierarchyChartProps, "type" | "donut">;
|
|
13
|
-
export declare const SunburstChart: (props: SunburstChartProps) => import("react
|
|
13
|
+
export declare const SunburstChart: (props: SunburstChartProps) => import("react").JSX.Element;
|
|
14
14
|
export type PieChartProps = Omit<HierarchyChartProps, "type">;
|
|
15
|
-
export declare const PieChart: (props: PieChartProps) => import("react
|
|
15
|
+
export declare const PieChart: (props: PieChartProps) => import("react").JSX.Element;
|
|
@@ -14,4 +14,4 @@ export interface VuuChartContainerProps extends VuuChartBaseProps {
|
|
|
14
14
|
* - applies data updates as a partial option, merged by component id, at
|
|
15
15
|
* most once per animation frame, without re-rendering React
|
|
16
16
|
*/
|
|
17
|
-
export declare const VuuChartContainer: ({ chartType, className, echartsOptions, height, legend: _legend, maxRows, model, onChartReady, onItemClick, onItemContextMenu, renderer, resizeStrategy, showTooltip: _showTooltip, style, theme: themeOverrides, width, ...htmlAttributes }: VuuChartContainerProps) => import("react
|
|
17
|
+
export declare const VuuChartContainer: ({ chartType, className, echartsOptions, height, legend: _legend, maxRows, model, onChartReady, onItemClick, onItemContextMenu, renderer, resizeStrategy, showTooltip: _showTooltip, style, theme: themeOverrides, width, ...htmlAttributes }: VuuChartContainerProps) => import("react").JSX.Element;
|
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
export { Chart, type ChartProps } from "./Chart";
|
|
2
|
-
export type { ItemColorFunction, LineSeries as Series } from
|
|
3
|
-
export { ChartSeries, type DataSourceValue } from "./ChartSeries";
|
|
4
|
-
export type { ChartContextMenuOptions, ChartMenuLocation } from "./useChartContextMenu";
|
|
5
|
-
export type { ChartConfig, DataExclusionOptions } from
|
|
2
|
+
export type { ItemColorFunction, LineSeries as Series } from "./chart-types";
|
|
3
|
+
export { ChartSeries, type DataSourceValue, } from "./ChartSeries";
|
|
4
|
+
export type { ChartContextMenuOptions, ChartMenuLocation, } from "./useChartContextMenu";
|
|
5
|
+
export type { ChartConfig, DataExclusionOptions } from "./useChartOptions";
|
|
6
|
+
export { CandlestickChart, type CandlestickChartProps, } from "./charts/CandlestickChart";
|
|
7
|
+
export type { CandlestickChartOptions, CandlestickOverlayDef, OhlcColumnNames, } from "./charts/candlestick-model";
|
|
8
|
+
export { CartesianChart, type CartesianChartProps, } from "./charts/CartesianChart";
|
|
9
|
+
export type { CartesianChartOptions, CartesianSeriesDef, CartesianSeriesType, CartesianXAxisDef, CartesianYAxisDef, } from "./charts/cartesian-model";
|
|
10
|
+
export { DepthChart, type DepthChartProps } from "./charts/DepthChart";
|
|
11
|
+
export type { DepthChartOptions } from "./charts/depth-model";
|
|
12
|
+
export { HeatmapChart, type HeatmapChartProps } from "./charts/HeatmapChart";
|
|
13
|
+
export type { HeatmapAxisDef, HeatmapChartOptions, } from "./charts/heatmap-model";
|
|
14
|
+
export { HierarchyChart, type HierarchyChartProps, PieChart, type PieChartProps, SunburstChart, type SunburstChartProps, TreemapChart, type TreemapChartProps, } from "./charts/HierarchyChart";
|
|
15
|
+
export type { HierarchyChartOptions, HierarchyChartType, HierarchyColorMode, } from "./charts/hierarchy-model";
|
|
16
|
+
export { ChartDataStore } from "./chart-data/ChartDataStore";
|
|
17
|
+
export { mergeEChartsOptions } from "./options/mergeOptions";
|
|
18
|
+
export { defaultChartTheme, resolveChartTheme, } from "./theme/chartTheme";
|
|
19
|
+
export type * from "./vuu-chart-types";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DataSourceRow } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import { ECElementEvent } from "echarts";
|
|
2
|
+
import type { ECElementEvent } from "echarts/core";
|
|
3
3
|
import { ColumnMap } from "@vuu-ui/vuu-utils";
|
|
4
4
|
export type ChartMenuLocation = "canvas" | "series";
|
|
5
5
|
export type ChartContextMenuOptions = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataSource, DataSourceRow } from "@vuu-ui/vuu-data-types";
|
|
2
2
|
import { ColumnMap } from "@vuu-ui/vuu-utils";
|
|
3
|
-
import { type EChartsCoreOption } from "echarts";
|
|
3
|
+
import { type EChartsCoreOption } from "echarts/core";
|
|
4
4
|
import type { ChartSelectionModel, ItemColorFunction, SymbolSize, SymbolSizeFunction, SymbolType } from "./chart-types";
|
|
5
5
|
export interface ChartConfig {
|
|
6
6
|
itemColorFunction?: ItemColorFunction;
|