@hsu-react/ui 2.4.0 → 2.4.1
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/es/components/Chart/Bar/index.js +12 -5
- package/es/components/Chart/Heatmap/index.js +12 -4
- package/es/components/Chart/Line/index.js +12 -4
- package/es/components/Chart/_utils/cartesian.d.ts +3 -2
- package/es/components/Chart/_utils/cartesian.js +9 -10
- package/es/components/Chart/_utils/chartTheme.d.ts +22 -0
- package/es/components/Chart/_utils/chartTheme.js +23 -0
- package/es/components/Chart/_utils/heatmap.d.ts +3 -2
- package/es/components/Chart/_utils/heatmap.js +7 -10
- package/es/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
- package/lib/components/Chart/Bar/index.js +10 -5
- package/lib/components/Chart/Heatmap/index.js +10 -4
- package/lib/components/Chart/Line/index.js +10 -4
- package/lib/components/Chart/_utils/cartesian.d.ts +3 -2
- package/lib/components/Chart/_utils/cartesian.js +9 -11
- package/lib/components/Chart/_utils/chartTheme.d.ts +22 -0
- package/lib/components/Chart/_utils/chartTheme.js +29 -0
- package/lib/components/Chart/_utils/heatmap.d.ts +3 -2
- package/lib/components/Chart/_utils/heatmap.js +7 -10
- package/lib/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
- package/package.json +1 -1
- package/src/components/Chart/Bar/index.tsx +10 -4
- package/src/components/Chart/Heatmap/index.tsx +10 -3
- package/src/components/Chart/Line/index.tsx +10 -3
- package/src/components/Chart/_utils/cartesian.ts +11 -10
- package/src/components/Chart/_utils/chartTheme.ts +34 -0
- package/src/components/Chart/_utils/heatmap.ts +10 -10
- package/src/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
|
@@ -13,6 +13,8 @@ import styles from "../index.module.scss";
|
|
|
13
13
|
import { autoScrollLegend } from "../_utils/autoScrollLegend";
|
|
14
14
|
import { autoScrollByItem } from "../_utils/autoSmooth";
|
|
15
15
|
import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
|
|
16
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
17
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
16
18
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
19
|
var ChartBar = function ChartBar(props) {
|
|
18
20
|
var className = props.className,
|
|
@@ -50,12 +52,18 @@ var ChartBar = function ChartBar(props) {
|
|
|
50
52
|
var normalizedScroll = useMemo(function () {
|
|
51
53
|
return resolveScrollConfig(scrollConfig);
|
|
52
54
|
}, [scrollConfig]);
|
|
55
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
56
|
+
// legend colours have to be resolved against the active appearance here
|
|
57
|
+
var isDark = useIsDark();
|
|
58
|
+
var chrome = useMemo(function () {
|
|
59
|
+
return resolveChartChrome(isDark);
|
|
60
|
+
}, [isDark]);
|
|
53
61
|
|
|
54
62
|
// Cache the chart option with useMemo
|
|
55
63
|
var chartOption = useMemo(function () {
|
|
56
64
|
var _xAxisData$length, _ref, _ref2;
|
|
57
|
-
var def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
58
|
-
var def_yAxis = createDefaultValueYAxis("bar");
|
|
65
|
+
var def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
66
|
+
var def_yAxis = createDefaultValueYAxis("bar", chrome);
|
|
59
67
|
|
|
60
68
|
// Process xAxis config
|
|
61
69
|
var processedXAxis = Array.isArray(xAxis) ? xAxis === null || xAxis === void 0 ? void 0 : xAxis.map(function (item) {
|
|
@@ -150,8 +158,7 @@ var ChartBar = function ChartBar(props) {
|
|
|
150
158
|
data: legendData,
|
|
151
159
|
icon: "circle",
|
|
152
160
|
textStyle: {
|
|
153
|
-
color:
|
|
154
|
-
fontSize: 16
|
|
161
|
+
color: chrome.text
|
|
155
162
|
},
|
|
156
163
|
itemWidth: 8,
|
|
157
164
|
itemHeight: 8
|
|
@@ -175,7 +182,7 @@ var ChartBar = function ChartBar(props) {
|
|
|
175
182
|
series: buildCartesianSeriesOptions("bar", seriesData, series)
|
|
176
183
|
}, coreOption);
|
|
177
184
|
return option;
|
|
178
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
185
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
179
186
|
|
|
180
187
|
// Callback for handling chart resize
|
|
181
188
|
var handleResize = useCallback(function () {
|
|
@@ -17,6 +17,8 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
17
17
|
import styles from "../index.module.scss";
|
|
18
18
|
import * as echarts from "echarts";
|
|
19
19
|
import { createDefaultHeatmapXAxis, createDefaultHeatmapYAxis } from "../_utils/heatmap";
|
|
20
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
21
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
20
22
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
23
|
var Heatmap = function Heatmap(props) {
|
|
22
24
|
var className = props.className,
|
|
@@ -41,6 +43,12 @@ var Heatmap = function Heatmap(props) {
|
|
|
41
43
|
var chartRef = useRef(null);
|
|
42
44
|
var chartInstanceRef = useRef(null);
|
|
43
45
|
var resizeObserverRef = useRef(null);
|
|
46
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
47
|
+
// colours have to be resolved against the active appearance here
|
|
48
|
+
var isDark = useIsDark();
|
|
49
|
+
var chrome = useMemo(function () {
|
|
50
|
+
return resolveChartChrome(isDark);
|
|
51
|
+
}, [isDark]);
|
|
44
52
|
|
|
45
53
|
// Process the data and generate the chart option
|
|
46
54
|
var chartOption = useMemo(function () {
|
|
@@ -85,7 +93,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
85
93
|
left: "right",
|
|
86
94
|
top: "center",
|
|
87
95
|
textStyle: {
|
|
88
|
-
color:
|
|
96
|
+
color: chrome.text
|
|
89
97
|
},
|
|
90
98
|
inRange: {
|
|
91
99
|
color: inRangeColor
|
|
@@ -93,7 +101,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
93
101
|
};
|
|
94
102
|
|
|
95
103
|
// Process xAxis config
|
|
96
|
-
var def_xAxis = createDefaultHeatmapXAxis(xAxisData);
|
|
104
|
+
var def_xAxis = createDefaultHeatmapXAxis(xAxisData, chrome);
|
|
97
105
|
var processedXAxis = Array.isArray(xAxis) ? xAxis === null || xAxis === void 0 ? void 0 : xAxis.map(function (item) {
|
|
98
106
|
return _objectSpread(_objectSpread({}, def_xAxis), {}, {
|
|
99
107
|
data: (item === null || item === void 0 ? void 0 : item.type) === "value" ? undefined : xAxisData
|
|
@@ -103,7 +111,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
103
111
|
}, xAxis);
|
|
104
112
|
|
|
105
113
|
// Process yAxis config
|
|
106
|
-
var def_yAxis = createDefaultHeatmapYAxis(yAxisData);
|
|
114
|
+
var def_yAxis = createDefaultHeatmapYAxis(yAxisData, chrome);
|
|
107
115
|
var processedYAxis = Array.isArray(yAxis) ? yAxis === null || yAxis === void 0 ? void 0 : yAxis.map(function (item) {
|
|
108
116
|
return _objectSpread(_objectSpread({}, def_yAxis), {}, {
|
|
109
117
|
data: (item === null || item === void 0 ? void 0 : item.type) === "value" ? undefined : yAxisData
|
|
@@ -170,7 +178,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
170
178
|
}, series)]
|
|
171
179
|
}, coreOption);
|
|
172
180
|
return option;
|
|
173
|
-
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor]);
|
|
181
|
+
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor, chrome]);
|
|
174
182
|
|
|
175
183
|
// Callback for handling chart resize
|
|
176
184
|
var handleResize = useCallback(function () {
|
|
@@ -13,6 +13,8 @@ import styles from "../index.module.scss";
|
|
|
13
13
|
import { autoScrollLegend } from "../_utils/autoScrollLegend";
|
|
14
14
|
import { autoScrollByItem } from "../_utils/autoSmooth";
|
|
15
15
|
import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
|
|
16
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
17
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
16
18
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
19
|
var ChartLine = function ChartLine(props) {
|
|
18
20
|
var className = props.className,
|
|
@@ -50,12 +52,18 @@ var ChartLine = function ChartLine(props) {
|
|
|
50
52
|
var normalizedScroll = useMemo(function () {
|
|
51
53
|
return resolveScrollConfig(scrollConfig);
|
|
52
54
|
}, [scrollConfig]);
|
|
55
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
56
|
+
// legend colours have to be resolved against the active appearance here
|
|
57
|
+
var isDark = useIsDark();
|
|
58
|
+
var chrome = useMemo(function () {
|
|
59
|
+
return resolveChartChrome(isDark);
|
|
60
|
+
}, [isDark]);
|
|
53
61
|
|
|
54
62
|
// Cache the chart option with useMemo
|
|
55
63
|
var chartOption = useMemo(function () {
|
|
56
64
|
var _xAxisData$length, _ref, _ref2;
|
|
57
|
-
var def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
58
|
-
var def_yAxis = createDefaultValueYAxis("line");
|
|
65
|
+
var def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
66
|
+
var def_yAxis = createDefaultValueYAxis("line", chrome);
|
|
59
67
|
|
|
60
68
|
// Process xAxis config
|
|
61
69
|
var processedXAxis = Array.isArray(xAxis) ? xAxis === null || xAxis === void 0 ? void 0 : xAxis.map(function (item) {
|
|
@@ -144,7 +152,7 @@ var ChartLine = function ChartLine(props) {
|
|
|
144
152
|
top: "5%",
|
|
145
153
|
icon: "circle",
|
|
146
154
|
textStyle: {
|
|
147
|
-
color:
|
|
155
|
+
color: chrome.text
|
|
148
156
|
},
|
|
149
157
|
itemWidth: 8,
|
|
150
158
|
itemHeight: 8
|
|
@@ -171,7 +179,7 @@ var ChartLine = function ChartLine(props) {
|
|
|
171
179
|
series: buildCartesianSeriesOptions("line", seriesData, series)
|
|
172
180
|
}, coreOption);
|
|
173
181
|
return option;
|
|
174
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
182
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
175
183
|
|
|
176
184
|
// Callback for handling chart resize
|
|
177
185
|
var handleResize = useCallback(function () {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
2
|
import { ChartOptionType, SeriesDataType } from "..";
|
|
3
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
4
|
export interface ChartScrollConfig {
|
|
4
5
|
enabled?: boolean;
|
|
5
6
|
autoScroll?: boolean;
|
|
@@ -29,8 +30,8 @@ export interface DataZoomIndexWindow {
|
|
|
29
30
|
* percentages produced by native echarts interactions are rounded outward, so each boundary may include at most one extra item, without affecting the axis magnitude.
|
|
30
31
|
*/
|
|
31
32
|
export declare const percentWindowToIndexWindow: (startPercent: number, endPercent: number, total: number) => DataZoomIndexWindow;
|
|
32
|
-
export declare const createDefaultCategoryXAxis: (xAxisData
|
|
33
|
-
export declare const createDefaultValueYAxis: (mode
|
|
33
|
+
export declare const createDefaultCategoryXAxis: (xAxisData: Array<string> | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
|
+
export declare const createDefaultValueYAxis: (mode: "bar" | "line" | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
35
|
export declare const buildCartesianSeriesOptions: (mode: "bar" | "line", seriesData?: SeriesDataType, series?: echarts.SeriesOption | echarts.SeriesOption[]) => echarts.SeriesOption[];
|
|
35
36
|
export declare const getSliderShow: (zoom?: echarts.DataZoomComponentOption | Record<string, unknown>) => boolean | undefined;
|
|
36
37
|
export declare const resolveScrollConfig: (scrollConfig?: ChartScrollConfig) => NormalizedScrollConfig;
|
|
@@ -23,7 +23,7 @@ export var percentWindowToIndexWindow = function percentWindowToIndexWindow(star
|
|
|
23
23
|
endIndex: endIndex
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
|
-
export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData) {
|
|
26
|
+
export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData, chrome) {
|
|
27
27
|
return {
|
|
28
28
|
type: "category",
|
|
29
29
|
boundaryGap: true,
|
|
@@ -31,10 +31,10 @@ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxi
|
|
|
31
31
|
axisLabel: {
|
|
32
32
|
interval: 0,
|
|
33
33
|
hideOverlap: true,
|
|
34
|
-
textStyle:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
// echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
|
|
35
|
+
// properties are silently dropped *and* a deprecation warning is logged on every render.
|
|
36
|
+
fontSize: chrome.fontSize,
|
|
37
|
+
color: chrome.axis
|
|
38
38
|
},
|
|
39
39
|
axisTick: {
|
|
40
40
|
show: false
|
|
@@ -43,17 +43,16 @@ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxi
|
|
|
43
43
|
};
|
|
44
44
|
export var createDefaultValueYAxis = function createDefaultValueYAxis() {
|
|
45
45
|
var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "bar";
|
|
46
|
+
var chrome = arguments.length > 1 ? arguments[1] : undefined;
|
|
46
47
|
return {
|
|
47
48
|
type: "value",
|
|
48
49
|
axisLabel: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
color: "#373D48"
|
|
52
|
-
}
|
|
50
|
+
fontSize: chrome.fontSize,
|
|
51
|
+
color: chrome.axis
|
|
53
52
|
},
|
|
54
53
|
splitLine: mode === "line" ? {
|
|
55
54
|
lineStyle: {
|
|
56
|
-
color:
|
|
55
|
+
color: chrome.splitLine,
|
|
57
56
|
type: "dashed"
|
|
58
57
|
}
|
|
59
58
|
} : {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
3
|
+
*
|
|
4
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
5
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
6
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
7
|
+
* nearly invisible once the page switched to the dark palette.
|
|
8
|
+
*
|
|
9
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
10
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChartChrome {
|
|
13
|
+
/** Legend labels — a real label, so it sits on the foreground ramp */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Axis tick labels — secondary information, one step down */
|
|
16
|
+
axis: string;
|
|
17
|
+
/** Split lines behind the plot area */
|
|
18
|
+
splitLine: string;
|
|
19
|
+
/** Base font size, same scale the rest of the library uses */
|
|
20
|
+
fontSize: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const resolveChartChrome: (dark: boolean) => ChartChrome;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { darkTokens, fontTokens, lightTokens } from "../../../styles/tokens";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
5
|
+
*
|
|
6
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
7
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
8
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
9
|
+
* nearly invisible once the page switched to the dark palette.
|
|
10
|
+
*
|
|
11
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
12
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export var resolveChartChrome = function resolveChartChrome(dark) {
|
|
16
|
+
var t = dark ? darkTokens : lightTokens;
|
|
17
|
+
return {
|
|
18
|
+
text: t.foreground,
|
|
19
|
+
axis: t.mutedForeground,
|
|
20
|
+
splitLine: t.border,
|
|
21
|
+
fontSize: fontTokens.size
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ChartOptionType } from "..";
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
2
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
|
+
export declare const createDefaultHeatmapXAxis: (xAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
4
|
+
export declare const createDefaultHeatmapYAxis: (yAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisData) {
|
|
1
|
+
export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisData, chrome) {
|
|
2
2
|
return {
|
|
3
3
|
type: "category",
|
|
4
4
|
data: xAxisData,
|
|
@@ -8,17 +8,16 @@ export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisD
|
|
|
8
8
|
axisLabel: {
|
|
9
9
|
interval: 0,
|
|
10
10
|
hideOverlap: true,
|
|
11
|
-
textStyle
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
11
|
+
// See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
|
|
12
|
+
fontSize: chrome.fontSize,
|
|
13
|
+
color: chrome.axis
|
|
15
14
|
},
|
|
16
15
|
axisTick: {
|
|
17
16
|
show: false
|
|
18
17
|
}
|
|
19
18
|
};
|
|
20
19
|
};
|
|
21
|
-
export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisData) {
|
|
20
|
+
export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisData, chrome) {
|
|
22
21
|
return {
|
|
23
22
|
type: "category",
|
|
24
23
|
data: yAxisData,
|
|
@@ -26,10 +25,8 @@ export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisD
|
|
|
26
25
|
show: true
|
|
27
26
|
},
|
|
28
27
|
axisLabel: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
color: "#373D48"
|
|
32
|
-
}
|
|
28
|
+
fontSize: chrome.fontSize,
|
|
29
|
+
color: chrome.axis
|
|
33
30
|
},
|
|
34
31
|
axisTick: {
|
|
35
32
|
show: false
|
|
@@ -21,8 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
|
|
24
|
+
// Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
|
|
25
|
+
// card standing on the grey page background; in a modal the body is already `--vita-surface`,
|
|
26
|
+
// so the same treatment paints a white card on white and only the border survives — a stray
|
|
27
|
+
// outline around the search row. The padding was already being cleared here; the background and
|
|
28
|
+
// border are the other half of the same intent, and `.tableContainer` below is flush for
|
|
29
|
+
// exactly this reason.
|
|
24
30
|
.search {
|
|
25
31
|
padding: 0px;
|
|
32
|
+
|
|
33
|
+
background: transparent;
|
|
34
|
+
|
|
35
|
+
border: none;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.tableContainer {
|
|
@@ -10,6 +10,8 @@ var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
|
10
10
|
var _autoScrollLegend = require("../_utils/autoScrollLegend");
|
|
11
11
|
var _autoSmooth = require("../_utils/autoSmooth");
|
|
12
12
|
var _cartesian = require("../_utils/cartesian");
|
|
13
|
+
var _chartTheme = require("../_utils/chartTheme");
|
|
14
|
+
var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
|
|
13
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -47,11 +49,15 @@ const ChartBar = props => {
|
|
|
47
49
|
const prevXAxisKeyRef = (0, _react.useRef)(null);
|
|
48
50
|
const legendScrollRef = (0, _react.useRef)(null);
|
|
49
51
|
const normalizedScroll = (0, _react.useMemo)(() => (0, _cartesian.resolveScrollConfig)(scrollConfig), [scrollConfig]);
|
|
52
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
53
|
+
// legend colours have to be resolved against the active appearance here
|
|
54
|
+
const isDark = (0, _useIsDark.default)();
|
|
55
|
+
const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
|
|
50
56
|
|
|
51
57
|
// Cache the chart option with useMemo
|
|
52
58
|
const chartOption = (0, _react.useMemo)(() => {
|
|
53
|
-
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData);
|
|
54
|
-
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("bar");
|
|
59
|
+
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData, chrome);
|
|
60
|
+
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("bar", chrome);
|
|
55
61
|
|
|
56
62
|
// Process xAxis config
|
|
57
63
|
const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
|
|
@@ -155,8 +161,7 @@ const ChartBar = props => {
|
|
|
155
161
|
data: legendData,
|
|
156
162
|
icon: "circle",
|
|
157
163
|
textStyle: {
|
|
158
|
-
color:
|
|
159
|
-
fontSize: 16
|
|
164
|
+
color: chrome.text
|
|
160
165
|
},
|
|
161
166
|
itemWidth: 8,
|
|
162
167
|
itemHeight: 8,
|
|
@@ -183,7 +188,7 @@ const ChartBar = props => {
|
|
|
183
188
|
...coreOption
|
|
184
189
|
};
|
|
185
190
|
return option;
|
|
186
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
191
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
187
192
|
|
|
188
193
|
// Callback for handling chart resize
|
|
189
194
|
const handleResize = (0, _react.useCallback)(() => {
|
|
@@ -8,6 +8,8 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
9
9
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
10
10
|
var _heatmap = require("../_utils/heatmap");
|
|
11
|
+
var _chartTheme = require("../_utils/chartTheme");
|
|
12
|
+
var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
|
|
11
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
15
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -36,6 +38,10 @@ const Heatmap = props => {
|
|
|
36
38
|
const chartRef = (0, _react.useRef)(null);
|
|
37
39
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
38
40
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
41
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
42
|
+
// colours have to be resolved against the active appearance here
|
|
43
|
+
const isDark = (0, _useIsDark.default)();
|
|
44
|
+
const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
|
|
39
45
|
|
|
40
46
|
// Process the data and generate the chart option
|
|
41
47
|
const chartOption = (0, _react.useMemo)(() => {
|
|
@@ -76,7 +82,7 @@ const Heatmap = props => {
|
|
|
76
82
|
left: "right",
|
|
77
83
|
top: "center",
|
|
78
84
|
textStyle: {
|
|
79
|
-
color:
|
|
85
|
+
color: chrome.text
|
|
80
86
|
},
|
|
81
87
|
inRange: {
|
|
82
88
|
color: inRangeColor
|
|
@@ -84,7 +90,7 @@ const Heatmap = props => {
|
|
|
84
90
|
};
|
|
85
91
|
|
|
86
92
|
// Process xAxis config
|
|
87
|
-
const def_xAxis = (0, _heatmap.createDefaultHeatmapXAxis)(xAxisData);
|
|
93
|
+
const def_xAxis = (0, _heatmap.createDefaultHeatmapXAxis)(xAxisData, chrome);
|
|
88
94
|
const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
|
|
89
95
|
...def_xAxis,
|
|
90
96
|
data: item?.type === "value" ? undefined : xAxisData,
|
|
@@ -96,7 +102,7 @@ const Heatmap = props => {
|
|
|
96
102
|
};
|
|
97
103
|
|
|
98
104
|
// Process yAxis config
|
|
99
|
-
const def_yAxis = (0, _heatmap.createDefaultHeatmapYAxis)(yAxisData);
|
|
105
|
+
const def_yAxis = (0, _heatmap.createDefaultHeatmapYAxis)(yAxisData, chrome);
|
|
100
106
|
const processedYAxis = Array.isArray(yAxis) ? yAxis?.map(item => ({
|
|
101
107
|
...def_yAxis,
|
|
102
108
|
data: item?.type === "value" ? undefined : yAxisData,
|
|
@@ -172,7 +178,7 @@ const Heatmap = props => {
|
|
|
172
178
|
...coreOption
|
|
173
179
|
};
|
|
174
180
|
return option;
|
|
175
|
-
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor]);
|
|
181
|
+
}, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor, chrome]);
|
|
176
182
|
|
|
177
183
|
// Callback for handling chart resize
|
|
178
184
|
const handleResize = (0, _react.useCallback)(() => {
|
|
@@ -10,6 +10,8 @@ var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
|
10
10
|
var _autoScrollLegend = require("../_utils/autoScrollLegend");
|
|
11
11
|
var _autoSmooth = require("../_utils/autoSmooth");
|
|
12
12
|
var _cartesian = require("../_utils/cartesian");
|
|
13
|
+
var _chartTheme = require("../_utils/chartTheme");
|
|
14
|
+
var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
|
|
13
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -47,11 +49,15 @@ const ChartLine = props => {
|
|
|
47
49
|
const prevXAxisKeyRef = (0, _react.useRef)(null);
|
|
48
50
|
const legendScrollRef = (0, _react.useRef)(null);
|
|
49
51
|
const normalizedScroll = (0, _react.useMemo)(() => (0, _cartesian.resolveScrollConfig)(scrollConfig), [scrollConfig]);
|
|
52
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
53
|
+
// legend colours have to be resolved against the active appearance here
|
|
54
|
+
const isDark = (0, _useIsDark.default)();
|
|
55
|
+
const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
|
|
50
56
|
|
|
51
57
|
// Cache the chart option with useMemo
|
|
52
58
|
const chartOption = (0, _react.useMemo)(() => {
|
|
53
|
-
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData);
|
|
54
|
-
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("line");
|
|
59
|
+
const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData, chrome);
|
|
60
|
+
const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("line", chrome);
|
|
55
61
|
|
|
56
62
|
// Process xAxis config
|
|
57
63
|
const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
|
|
@@ -148,7 +154,7 @@ const ChartLine = props => {
|
|
|
148
154
|
top: "5%",
|
|
149
155
|
icon: "circle",
|
|
150
156
|
textStyle: {
|
|
151
|
-
color:
|
|
157
|
+
color: chrome.text
|
|
152
158
|
},
|
|
153
159
|
itemWidth: 8,
|
|
154
160
|
itemHeight: 8,
|
|
@@ -179,7 +185,7 @@ const ChartLine = props => {
|
|
|
179
185
|
...coreOption
|
|
180
186
|
};
|
|
181
187
|
return option;
|
|
182
|
-
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption]);
|
|
188
|
+
}, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
|
|
183
189
|
|
|
184
190
|
// Callback for handling chart resize
|
|
185
191
|
const handleResize = (0, _react.useCallback)(() => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
2
|
import { ChartOptionType, SeriesDataType } from "..";
|
|
3
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
4
|
export interface ChartScrollConfig {
|
|
4
5
|
enabled?: boolean;
|
|
5
6
|
autoScroll?: boolean;
|
|
@@ -29,8 +30,8 @@ export interface DataZoomIndexWindow {
|
|
|
29
30
|
* percentages produced by native echarts interactions are rounded outward, so each boundary may include at most one extra item, without affecting the axis magnitude.
|
|
30
31
|
*/
|
|
31
32
|
export declare const percentWindowToIndexWindow: (startPercent: number, endPercent: number, total: number) => DataZoomIndexWindow;
|
|
32
|
-
export declare const createDefaultCategoryXAxis: (xAxisData
|
|
33
|
-
export declare const createDefaultValueYAxis: (mode
|
|
33
|
+
export declare const createDefaultCategoryXAxis: (xAxisData: Array<string> | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
|
+
export declare const createDefaultValueYAxis: (mode: "bar" | "line" | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
34
35
|
export declare const buildCartesianSeriesOptions: (mode: "bar" | "line", seriesData?: SeriesDataType, series?: echarts.SeriesOption | echarts.SeriesOption[]) => echarts.SeriesOption[];
|
|
35
36
|
export declare const getSliderShow: (zoom?: echarts.DataZoomComponentOption | Record<string, unknown>) => boolean | undefined;
|
|
36
37
|
export declare const resolveScrollConfig: (scrollConfig?: ChartScrollConfig) => NormalizedScrollConfig;
|
|
@@ -24,34 +24,32 @@ const percentWindowToIndexWindow = (startPercent, endPercent, total) => {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
exports.percentWindowToIndexWindow = percentWindowToIndexWindow;
|
|
27
|
-
const createDefaultCategoryXAxis = xAxisData => ({
|
|
27
|
+
const createDefaultCategoryXAxis = (xAxisData, chrome) => ({
|
|
28
28
|
type: "category",
|
|
29
29
|
boundaryGap: true,
|
|
30
30
|
data: xAxisData,
|
|
31
31
|
axisLabel: {
|
|
32
32
|
interval: 0,
|
|
33
33
|
hideOverlap: true,
|
|
34
|
-
textStyle:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
// echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
|
|
35
|
+
// properties are silently dropped *and* a deprecation warning is logged on every render.
|
|
36
|
+
fontSize: chrome.fontSize,
|
|
37
|
+
color: chrome.axis
|
|
38
38
|
},
|
|
39
39
|
axisTick: {
|
|
40
40
|
show: false
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
exports.createDefaultCategoryXAxis = createDefaultCategoryXAxis;
|
|
44
|
-
const createDefaultValueYAxis = (mode = "bar") => ({
|
|
44
|
+
const createDefaultValueYAxis = (mode = "bar", chrome) => ({
|
|
45
45
|
type: "value",
|
|
46
46
|
axisLabel: {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
color: "#373D48"
|
|
50
|
-
}
|
|
47
|
+
fontSize: chrome.fontSize,
|
|
48
|
+
color: chrome.axis
|
|
51
49
|
},
|
|
52
50
|
splitLine: mode === "line" ? {
|
|
53
51
|
lineStyle: {
|
|
54
|
-
color:
|
|
52
|
+
color: chrome.splitLine,
|
|
55
53
|
type: "dashed"
|
|
56
54
|
}
|
|
57
55
|
} : {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
3
|
+
*
|
|
4
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
5
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
6
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
7
|
+
* nearly invisible once the page switched to the dark palette.
|
|
8
|
+
*
|
|
9
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
10
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChartChrome {
|
|
13
|
+
/** Legend labels — a real label, so it sits on the foreground ramp */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Axis tick labels — secondary information, one step down */
|
|
16
|
+
axis: string;
|
|
17
|
+
/** Split lines behind the plot area */
|
|
18
|
+
splitLine: string;
|
|
19
|
+
/** Base font size, same scale the rest of the library uses */
|
|
20
|
+
fontSize: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const resolveChartChrome: (dark: boolean) => ChartChrome;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.resolveChartChrome = void 0;
|
|
7
|
+
var _tokens = require("../../../styles/tokens");
|
|
8
|
+
/**
|
|
9
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
10
|
+
*
|
|
11
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
12
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
13
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
14
|
+
* nearly invisible once the page switched to the dark palette.
|
|
15
|
+
*
|
|
16
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
17
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const resolveChartChrome = dark => {
|
|
21
|
+
const t = dark ? _tokens.darkTokens : _tokens.lightTokens;
|
|
22
|
+
return {
|
|
23
|
+
text: t.foreground,
|
|
24
|
+
axis: t.mutedForeground,
|
|
25
|
+
splitLine: t.border,
|
|
26
|
+
fontSize: _tokens.fontTokens.size
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
exports.resolveChartChrome = resolveChartChrome;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ChartOptionType } from "..";
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
2
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
|
+
export declare const createDefaultHeatmapXAxis: (xAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
4
|
+
export declare const createDefaultHeatmapYAxis: (yAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createDefaultHeatmapYAxis = exports.createDefaultHeatmapXAxis = void 0;
|
|
7
|
-
const createDefaultHeatmapXAxis = xAxisData => ({
|
|
7
|
+
const createDefaultHeatmapXAxis = (xAxisData, chrome) => ({
|
|
8
8
|
type: "category",
|
|
9
9
|
data: xAxisData,
|
|
10
10
|
splitArea: {
|
|
@@ -13,27 +13,24 @@ const createDefaultHeatmapXAxis = xAxisData => ({
|
|
|
13
13
|
axisLabel: {
|
|
14
14
|
interval: 0,
|
|
15
15
|
hideOverlap: true,
|
|
16
|
-
textStyle
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
16
|
+
// See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
|
|
17
|
+
fontSize: chrome.fontSize,
|
|
18
|
+
color: chrome.axis
|
|
20
19
|
},
|
|
21
20
|
axisTick: {
|
|
22
21
|
show: false
|
|
23
22
|
}
|
|
24
23
|
});
|
|
25
24
|
exports.createDefaultHeatmapXAxis = createDefaultHeatmapXAxis;
|
|
26
|
-
const createDefaultHeatmapYAxis = yAxisData => ({
|
|
25
|
+
const createDefaultHeatmapYAxis = (yAxisData, chrome) => ({
|
|
27
26
|
type: "category",
|
|
28
27
|
data: yAxisData,
|
|
29
28
|
splitArea: {
|
|
30
29
|
show: true
|
|
31
30
|
},
|
|
32
31
|
axisLabel: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
color: "#373D48"
|
|
36
|
-
}
|
|
32
|
+
fontSize: chrome.fontSize,
|
|
33
|
+
color: chrome.axis
|
|
37
34
|
},
|
|
38
35
|
axisTick: {
|
|
39
36
|
show: false
|
|
@@ -21,8 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
|
|
24
|
+
// Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
|
|
25
|
+
// card standing on the grey page background; in a modal the body is already `--vita-surface`,
|
|
26
|
+
// so the same treatment paints a white card on white and only the border survives — a stray
|
|
27
|
+
// outline around the search row. The padding was already being cleared here; the background and
|
|
28
|
+
// border are the other half of the same intent, and `.tableContainer` below is flush for
|
|
29
|
+
// exactly this reason.
|
|
24
30
|
.search {
|
|
25
31
|
padding: 0px;
|
|
32
|
+
|
|
33
|
+
background: transparent;
|
|
34
|
+
|
|
35
|
+
border: none;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.tableContainer {
|
package/package.json
CHANGED
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
percentWindowToIndexWindow,
|
|
22
22
|
resolveScrollConfig,
|
|
23
23
|
} from "../_utils/cartesian";
|
|
24
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
25
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
24
26
|
|
|
25
27
|
export interface ChartBarProps extends ChartCommonProps {
|
|
26
28
|
chartTitle?: string;
|
|
@@ -79,11 +81,15 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
79
81
|
() => resolveScrollConfig(scrollConfig),
|
|
80
82
|
[scrollConfig],
|
|
81
83
|
);
|
|
84
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
85
|
+
// legend colours have to be resolved against the active appearance here
|
|
86
|
+
const isDark = useIsDark();
|
|
87
|
+
const chrome = useMemo(() => resolveChartChrome(isDark), [isDark]);
|
|
82
88
|
|
|
83
89
|
// Cache the chart option with useMemo
|
|
84
90
|
const chartOption = useMemo(() => {
|
|
85
|
-
const def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
86
|
-
const def_yAxis = createDefaultValueYAxis("bar");
|
|
91
|
+
const def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
92
|
+
const def_yAxis = createDefaultValueYAxis("bar", chrome);
|
|
87
93
|
|
|
88
94
|
// Process xAxis config
|
|
89
95
|
const processedXAxis = Array.isArray(xAxis)
|
|
@@ -212,8 +218,7 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
212
218
|
data: legendData,
|
|
213
219
|
icon: "circle",
|
|
214
220
|
textStyle: {
|
|
215
|
-
color:
|
|
216
|
-
fontSize: 16,
|
|
221
|
+
color: chrome.text,
|
|
217
222
|
},
|
|
218
223
|
itemWidth: 8,
|
|
219
224
|
itemHeight: 8,
|
|
@@ -259,6 +264,7 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
259
264
|
series,
|
|
260
265
|
enableLegendAutoScroll,
|
|
261
266
|
coreOption,
|
|
267
|
+
chrome,
|
|
262
268
|
]);
|
|
263
269
|
|
|
264
270
|
// Callback for handling chart resize
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
createDefaultHeatmapXAxis,
|
|
7
7
|
createDefaultHeatmapYAxis,
|
|
8
8
|
} from "../_utils/heatmap";
|
|
9
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
10
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
9
11
|
|
|
10
12
|
export interface HeatmapDataItem {
|
|
11
13
|
/** X-axis index or name */
|
|
@@ -73,6 +75,10 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
73
75
|
const chartRef = useRef<HTMLDivElement>(null);
|
|
74
76
|
const chartInstanceRef = useRef<echarts.ECharts | null>(null);
|
|
75
77
|
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
78
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
79
|
+
// colours have to be resolved against the active appearance here
|
|
80
|
+
const isDark = useIsDark();
|
|
81
|
+
const chrome = useMemo(() => resolveChartChrome(isDark), [isDark]);
|
|
76
82
|
|
|
77
83
|
// Process the data and generate the chart option
|
|
78
84
|
const chartOption = useMemo(() => {
|
|
@@ -120,7 +126,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
120
126
|
left: "right",
|
|
121
127
|
top: "center",
|
|
122
128
|
textStyle: {
|
|
123
|
-
color:
|
|
129
|
+
color: chrome.text,
|
|
124
130
|
},
|
|
125
131
|
inRange: {
|
|
126
132
|
color: inRangeColor,
|
|
@@ -128,7 +134,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
128
134
|
};
|
|
129
135
|
|
|
130
136
|
// Process xAxis config
|
|
131
|
-
const def_xAxis = createDefaultHeatmapXAxis(xAxisData);
|
|
137
|
+
const def_xAxis = createDefaultHeatmapXAxis(xAxisData, chrome);
|
|
132
138
|
const processedXAxis = Array.isArray(xAxis)
|
|
133
139
|
? xAxis?.map((item) => ({
|
|
134
140
|
...def_xAxis,
|
|
@@ -142,7 +148,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
142
148
|
};
|
|
143
149
|
|
|
144
150
|
// Process yAxis config
|
|
145
|
-
const def_yAxis = createDefaultHeatmapYAxis(yAxisData);
|
|
151
|
+
const def_yAxis = createDefaultHeatmapYAxis(yAxisData, chrome);
|
|
146
152
|
const processedYAxis = Array.isArray(yAxis)
|
|
147
153
|
? yAxis?.map((item) => ({
|
|
148
154
|
...def_yAxis,
|
|
@@ -244,6 +250,7 @@ const Heatmap: React.FC<ChartHeatmapProps> = (props) => {
|
|
|
244
250
|
series,
|
|
245
251
|
coreOption,
|
|
246
252
|
zeroColor,
|
|
253
|
+
chrome,
|
|
247
254
|
]);
|
|
248
255
|
|
|
249
256
|
// Callback for handling chart resize
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
percentWindowToIndexWindow,
|
|
22
22
|
resolveScrollConfig,
|
|
23
23
|
} from "../_utils/cartesian";
|
|
24
|
+
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
25
|
+
import useIsDark from "../../../hooks/useIsDark";
|
|
24
26
|
|
|
25
27
|
export interface ChartLineProps extends ChartCommonProps {
|
|
26
28
|
chartTitle?: string;
|
|
@@ -80,11 +82,15 @@ const ChartLine: React.FC<ChartLineProps> = (props) => {
|
|
|
80
82
|
() => resolveScrollConfig(scrollConfig),
|
|
81
83
|
[scrollConfig],
|
|
82
84
|
);
|
|
85
|
+
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
|
|
86
|
+
// legend colours have to be resolved against the active appearance here
|
|
87
|
+
const isDark = useIsDark();
|
|
88
|
+
const chrome = useMemo(() => resolveChartChrome(isDark), [isDark]);
|
|
83
89
|
|
|
84
90
|
// Cache the chart option with useMemo
|
|
85
91
|
const chartOption = useMemo(() => {
|
|
86
|
-
const def_xAxis = createDefaultCategoryXAxis(xAxisData);
|
|
87
|
-
const def_yAxis = createDefaultValueYAxis("line");
|
|
92
|
+
const def_xAxis = createDefaultCategoryXAxis(xAxisData, chrome);
|
|
93
|
+
const def_yAxis = createDefaultValueYAxis("line", chrome);
|
|
88
94
|
|
|
89
95
|
// Process xAxis config
|
|
90
96
|
const processedXAxis = Array.isArray(xAxis)
|
|
@@ -206,7 +212,7 @@ const ChartLine: React.FC<ChartLineProps> = (props) => {
|
|
|
206
212
|
top: "5%",
|
|
207
213
|
icon: "circle",
|
|
208
214
|
textStyle: {
|
|
209
|
-
color:
|
|
215
|
+
color: chrome.text,
|
|
210
216
|
},
|
|
211
217
|
itemWidth: 8,
|
|
212
218
|
itemHeight: 8,
|
|
@@ -256,6 +262,7 @@ const ChartLine: React.FC<ChartLineProps> = (props) => {
|
|
|
256
262
|
series,
|
|
257
263
|
enableLegendAutoScroll,
|
|
258
264
|
coreOption,
|
|
265
|
+
chrome,
|
|
259
266
|
]);
|
|
260
267
|
|
|
261
268
|
// Callback for handling chart resize
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
2
|
import { ChartOptionType, SeriesData, SeriesDataType } from "..";
|
|
3
|
+
import { ChartChrome } from "./chartTheme";
|
|
3
4
|
|
|
4
5
|
export interface ChartScrollConfig {
|
|
5
6
|
enabled?: boolean;
|
|
@@ -50,7 +51,8 @@ export const percentWindowToIndexWindow = (
|
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
export const createDefaultCategoryXAxis = (
|
|
53
|
-
xAxisData
|
|
54
|
+
xAxisData: Array<string> | undefined,
|
|
55
|
+
chrome: ChartChrome,
|
|
54
56
|
): ChartOptionType => ({
|
|
55
57
|
type: "category",
|
|
56
58
|
boundaryGap: true,
|
|
@@ -58,10 +60,10 @@ export const createDefaultCategoryXAxis = (
|
|
|
58
60
|
axisLabel: {
|
|
59
61
|
interval: 0,
|
|
60
62
|
hideOverlap: true,
|
|
61
|
-
textStyle:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
// echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
|
|
64
|
+
// properties are silently dropped *and* a deprecation warning is logged on every render.
|
|
65
|
+
fontSize: chrome.fontSize,
|
|
66
|
+
color: chrome.axis,
|
|
65
67
|
},
|
|
66
68
|
axisTick: {
|
|
67
69
|
show: false,
|
|
@@ -70,19 +72,18 @@ export const createDefaultCategoryXAxis = (
|
|
|
70
72
|
|
|
71
73
|
export const createDefaultValueYAxis = (
|
|
72
74
|
mode: "bar" | "line" = "bar",
|
|
75
|
+
chrome: ChartChrome,
|
|
73
76
|
): ChartOptionType => ({
|
|
74
77
|
type: "value",
|
|
75
78
|
axisLabel: {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
color: "#373D48",
|
|
79
|
-
},
|
|
79
|
+
fontSize: chrome.fontSize,
|
|
80
|
+
color: chrome.axis,
|
|
80
81
|
},
|
|
81
82
|
splitLine:
|
|
82
83
|
mode === "line"
|
|
83
84
|
? {
|
|
84
85
|
lineStyle: {
|
|
85
|
-
color:
|
|
86
|
+
color: chrome.splitLine,
|
|
86
87
|
type: "dashed",
|
|
87
88
|
},
|
|
88
89
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { darkTokens, fontTokens, lightTokens } from "../../../styles/tokens";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Colours for the chart *chrome* — axis ticks, split lines, legend labels.
|
|
5
|
+
*
|
|
6
|
+
* echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
|
|
7
|
+
* library styles itself with; the literal values have to be resolved here instead. These used to
|
|
8
|
+
* be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
|
|
9
|
+
* nearly invisible once the page switched to the dark palette.
|
|
10
|
+
*
|
|
11
|
+
* The plotted data is deliberately *not* covered here: series colours come from echarts' own
|
|
12
|
+
* palette or from whatever the caller passes as `color`, and both read fine on either background.
|
|
13
|
+
*/
|
|
14
|
+
export interface ChartChrome {
|
|
15
|
+
/** Legend labels — a real label, so it sits on the foreground ramp */
|
|
16
|
+
text: string;
|
|
17
|
+
/** Axis tick labels — secondary information, one step down */
|
|
18
|
+
axis: string;
|
|
19
|
+
/** Split lines behind the plot area */
|
|
20
|
+
splitLine: string;
|
|
21
|
+
/** Base font size, same scale the rest of the library uses */
|
|
22
|
+
fontSize: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const resolveChartChrome = (dark: boolean): ChartChrome => {
|
|
26
|
+
const t = dark ? darkTokens : lightTokens;
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
text: t.foreground,
|
|
30
|
+
axis: t.mutedForeground,
|
|
31
|
+
splitLine: t.border,
|
|
32
|
+
fontSize: fontTokens.size,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ChartOptionType } from "..";
|
|
2
|
+
import { ChartChrome } from "./chartTheme";
|
|
2
3
|
|
|
3
4
|
export const createDefaultHeatmapXAxis = (
|
|
4
|
-
xAxisData
|
|
5
|
+
xAxisData: string[] | undefined,
|
|
6
|
+
chrome: ChartChrome,
|
|
5
7
|
): ChartOptionType => ({
|
|
6
8
|
type: "category",
|
|
7
9
|
data: xAxisData,
|
|
@@ -11,10 +13,9 @@ export const createDefaultHeatmapXAxis = (
|
|
|
11
13
|
axisLabel: {
|
|
12
14
|
interval: 0,
|
|
13
15
|
hideOverlap: true,
|
|
14
|
-
textStyle
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
},
|
|
16
|
+
// See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
|
|
17
|
+
fontSize: chrome.fontSize,
|
|
18
|
+
color: chrome.axis,
|
|
18
19
|
},
|
|
19
20
|
axisTick: {
|
|
20
21
|
show: false,
|
|
@@ -22,7 +23,8 @@ export const createDefaultHeatmapXAxis = (
|
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
export const createDefaultHeatmapYAxis = (
|
|
25
|
-
yAxisData
|
|
26
|
+
yAxisData: string[] | undefined,
|
|
27
|
+
chrome: ChartChrome,
|
|
26
28
|
): ChartOptionType => ({
|
|
27
29
|
type: "category",
|
|
28
30
|
data: yAxisData,
|
|
@@ -30,10 +32,8 @@ export const createDefaultHeatmapYAxis = (
|
|
|
30
32
|
show: true,
|
|
31
33
|
},
|
|
32
34
|
axisLabel: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
color: "#373D48",
|
|
36
|
-
},
|
|
35
|
+
fontSize: chrome.fontSize,
|
|
36
|
+
color: chrome.axis,
|
|
37
37
|
},
|
|
38
38
|
axisTick: {
|
|
39
39
|
show: false,
|
|
@@ -21,8 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
|
|
24
|
+
// Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
|
|
25
|
+
// card standing on the grey page background; in a modal the body is already `--vita-surface`,
|
|
26
|
+
// so the same treatment paints a white card on white and only the border survives — a stray
|
|
27
|
+
// outline around the search row. The padding was already being cleared here; the background and
|
|
28
|
+
// border are the other half of the same intent, and `.tableContainer` below is flush for
|
|
29
|
+
// exactly this reason.
|
|
24
30
|
.search {
|
|
25
31
|
padding: 0px;
|
|
32
|
+
|
|
33
|
+
background: transparent;
|
|
34
|
+
|
|
35
|
+
border: none;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
.tableContainer {
|