@flux-ui/statistics 3.0.0-next.67 → 3.0.0-next.69
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 +1 -1
- package/dist/component/FluxStatisticsAreaChart.vue.d.ts +11 -4
- package/dist/component/FluxStatisticsBarChart.vue.d.ts +11 -4
- package/dist/component/FluxStatisticsBase.vue.d.ts +1 -0
- package/dist/component/FluxStatisticsBoxPlotChart.vue.d.ts +15 -0
- package/dist/component/FluxStatisticsBubbleChart.vue.d.ts +14 -0
- package/dist/component/FluxStatisticsCandlestickChart.vue.d.ts +15 -0
- package/dist/component/FluxStatisticsChart.vue.d.ts +7 -5
- package/dist/component/FluxStatisticsChartPane.vue.d.ts +1 -0
- package/dist/component/FluxStatisticsComparison.vue.d.ts +16 -0
- package/dist/component/FluxStatisticsDonutChart.vue.d.ts +8 -4
- package/dist/component/FluxStatisticsEmpty.vue.d.ts +19 -0
- package/dist/component/FluxStatisticsHeatmapChart.vue.d.ts +15 -0
- package/dist/component/FluxStatisticsLegendItem.vue.d.ts +1 -0
- package/dist/component/FluxStatisticsLegendScope.vue.d.ts +13 -0
- package/dist/component/FluxStatisticsLineChart.vue.d.ts +11 -4
- package/dist/component/FluxStatisticsMixedChart.vue.d.ts +17 -0
- package/dist/component/FluxStatisticsPercentageBar.vue.d.ts +8 -0
- package/dist/component/FluxStatisticsPieChart.vue.d.ts +8 -4
- package/dist/component/FluxStatisticsPolarAreaChart.vue.d.ts +14 -0
- package/dist/component/FluxStatisticsRadarChart.vue.d.ts +12 -0
- package/dist/component/FluxStatisticsRadialBar.vue.d.ts +11 -0
- package/dist/component/FluxStatisticsScatterChart.vue.d.ts +14 -0
- package/dist/component/FluxStatisticsSparkline.vue.d.ts +13 -0
- package/dist/component/FluxStatisticsTreemapChart.vue.d.ts +11 -0
- package/dist/component/index.d.ts +15 -0
- package/dist/composable/index.d.ts +12 -0
- package/dist/composable/useChartBaseSetup.d.ts +8 -0
- package/dist/composable/useChartHoverSync.d.ts +9 -0
- package/dist/composable/useChartLegend.d.ts +14 -0
- package/dist/composable/useChartSeriesSetup.d.ts +23 -0
- package/dist/composable/useChartSlicesSetup.d.ts +14 -0
- package/dist/composable/useECharts.d.ts +9 -0
- package/dist/echarts.d.ts +1 -0
- package/dist/index.css +262 -34
- package/dist/index.d.ts +5 -2
- package/dist/index.js +9176 -6895
- package/dist/index.js.map +1 -1
- package/dist/util/colors.d.ts +4 -0
- package/dist/util/icons.d.ts +2 -0
- package/dist/util/index.d.ts +6 -0
- package/dist/util/options/buildBaseOptions.d.ts +2 -0
- package/dist/util/options/buildCartesianBaseOptions.d.ts +13 -0
- package/dist/util/options/buildCircularBaseOptions.d.ts +2 -0
- package/dist/util/options/cartesian/buildAreaChartOptions.d.ts +17 -0
- package/dist/util/options/cartesian/buildBarChartOptions.d.ts +17 -0
- package/dist/util/options/cartesian/buildBoxPlotChartOptions.d.ts +16 -0
- package/dist/util/options/cartesian/buildBubbleChartOptions.d.ts +15 -0
- package/dist/util/options/cartesian/buildCandlestickChartOptions.d.ts +17 -0
- package/dist/util/options/cartesian/buildHeatmapChartOptions.d.ts +15 -0
- package/dist/util/options/cartesian/buildLineChartOptions.d.ts +17 -0
- package/dist/util/options/cartesian/buildMixedChartOptions.d.ts +17 -0
- package/dist/util/options/cartesian/buildScatterChartOptions.d.ts +15 -0
- package/dist/util/options/cartesian/index.d.ts +18 -0
- package/dist/util/options/circular/buildDonutChartOptions.d.ts +15 -0
- package/dist/util/options/circular/buildGaugeChartOptions.d.ts +14 -0
- package/dist/util/options/circular/buildPieChartOptions.d.ts +15 -0
- package/dist/util/options/circular/buildPolarAreaChartOptions.d.ts +15 -0
- package/dist/util/options/circular/buildRadarChartOptions.d.ts +13 -0
- package/dist/util/options/circular/buildTreemapChartOptions.d.ts +12 -0
- package/dist/util/options/circular/index.d.ts +12 -0
- package/dist/util/options/index.d.ts +6 -0
- package/dist/util/series/chartColors.d.ts +3 -0
- package/dist/util/series/converters.d.ts +17 -0
- package/dist/util/series/defaults.d.ts +15 -0
- package/dist/util/series/index.d.ts +4 -0
- package/dist/util/series/labels.d.ts +5 -0
- package/dist/util/sparkline.d.ts +7 -0
- package/dist/util/tooltips/buildBoxPlotTooltip.d.ts +22 -0
- package/dist/util/tooltips/buildCartesianTooltip.d.ts +10 -0
- package/dist/util/tooltips/buildGaugeTooltip.d.ts +14 -0
- package/dist/util/tooltips/buildHeatmapTooltip.d.ts +17 -0
- package/dist/util/tooltips/buildRadarTooltip.d.ts +11 -0
- package/dist/util/tooltips/buildSharedItemTooltip.d.ts +10 -0
- package/dist/util/tooltips/buildTreemapTooltip.d.ts +12 -0
- package/dist/util/tooltips/index.d.ts +15 -0
- package/dist/util/tooltips/render.d.ts +4 -0
- package/dist/util/tooltips/types.d.ts +24 -0
- package/package.json +14 -15
- package/src/component/FluxStatisticsAreaChart.vue +36 -43
- package/src/component/FluxStatisticsBarChart.vue +36 -35
- package/src/component/FluxStatisticsBase.vue +14 -1
- package/src/component/FluxStatisticsBoxPlotChart.vue +49 -0
- package/src/component/FluxStatisticsBubbleChart.vue +46 -0
- package/src/component/FluxStatisticsCandlestickChart.vue +50 -0
- package/src/component/FluxStatisticsChart.vue +19 -169
- package/src/component/FluxStatisticsChartPane.vue +22 -11
- package/src/component/FluxStatisticsComparison.vue +113 -0
- package/src/component/FluxStatisticsDonutChart.vue +31 -19
- package/src/component/FluxStatisticsEmpty.vue +44 -0
- package/src/component/FluxStatisticsHeatmapChart.vue +47 -0
- package/src/component/FluxStatisticsLegend.vue +33 -1
- package/src/component/FluxStatisticsLegendItem.vue +3 -1
- package/src/component/FluxStatisticsLegendScope.vue +16 -0
- package/src/component/FluxStatisticsLineChart.vue +36 -43
- package/src/component/FluxStatisticsMixedChart.vue +52 -0
- package/src/component/FluxStatisticsPercentageBar.vue +90 -0
- package/src/component/FluxStatisticsPieChart.vue +31 -19
- package/src/component/FluxStatisticsPolarAreaChart.vue +44 -0
- package/src/component/FluxStatisticsRadarChart.vue +40 -0
- package/src/component/FluxStatisticsRadialBar.vue +39 -0
- package/src/component/FluxStatisticsScatterChart.vue +46 -0
- package/src/component/FluxStatisticsSparkline.vue +67 -0
- package/src/component/FluxStatisticsTreemapChart.vue +35 -0
- package/src/component/index.ts +15 -0
- package/src/composable/index.ts +12 -0
- package/src/composable/useChartBaseSetup.ts +16 -0
- package/src/composable/useChartHoverSync.ts +92 -0
- package/src/composable/useChartLegend.ts +23 -0
- package/src/composable/useChartSeriesSetup.ts +75 -0
- package/src/composable/useChartSlicesSetup.ts +58 -0
- package/src/composable/useECharts.ts +55 -0
- package/src/css/Base.module.scss +28 -1
- package/src/css/Chart.module.scss +59 -30
- package/src/css/ChartPane.module.scss +20 -12
- package/src/css/Comparison.module.scss +52 -0
- package/src/css/Empty.module.scss +39 -0
- package/src/css/Grid.module.scss +1 -0
- package/src/css/Legend.module.scss +22 -4
- package/src/css/Meter.module.scss +1 -0
- package/src/css/Metric.module.scss +6 -0
- package/src/css/PercentageBar.module.scss +36 -0
- package/src/css/Sparkline.module.scss +13 -0
- package/src/echarts.ts +47 -0
- package/src/index.ts +7 -3
- package/src/util/colors.ts +86 -0
- package/src/util/icons.ts +20 -0
- package/src/util/index.ts +6 -0
- package/src/util/options/buildBaseOptions.ts +31 -0
- package/src/util/options/buildCartesianBaseOptions.ts +67 -0
- package/src/util/options/buildCircularBaseOptions.ts +10 -0
- package/src/util/options/cartesian/buildAreaChartOptions.ts +44 -0
- package/src/util/options/cartesian/buildBarChartOptions.ts +44 -0
- package/src/util/options/cartesian/buildBoxPlotChartOptions.ts +63 -0
- package/src/util/options/cartesian/buildBubbleChartOptions.ts +48 -0
- package/src/util/options/cartesian/buildCandlestickChartOptions.ts +77 -0
- package/src/util/options/cartesian/buildHeatmapChartOptions.ts +72 -0
- package/src/util/options/cartesian/buildLineChartOptions.ts +44 -0
- package/src/util/options/cartesian/buildMixedChartOptions.ts +44 -0
- package/src/util/options/cartesian/buildScatterChartOptions.ts +48 -0
- package/src/util/options/cartesian/index.ts +18 -0
- package/src/util/options/circular/buildDonutChartOptions.ts +31 -0
- package/src/util/options/circular/buildGaugeChartOptions.ts +45 -0
- package/src/util/options/circular/buildPieChartOptions.ts +31 -0
- package/src/util/options/circular/buildPolarAreaChartOptions.ts +31 -0
- package/src/util/options/circular/buildRadarChartOptions.ts +52 -0
- package/src/util/options/circular/buildTreemapChartOptions.ts +28 -0
- package/src/util/options/circular/index.ts +12 -0
- package/src/util/options/index.ts +6 -0
- package/src/util/series/chartColors.ts +20 -0
- package/src/util/series/converters.ts +318 -0
- package/src/util/series/defaults.ts +210 -0
- package/src/util/series/index.ts +4 -0
- package/src/util/series/labels.ts +30 -0
- package/src/util/sparkline.ts +67 -0
- package/src/util/tooltips/buildBoxPlotTooltip.ts +66 -0
- package/src/util/tooltips/buildCartesianTooltip.ts +44 -0
- package/src/util/tooltips/buildGaugeTooltip.ts +49 -0
- package/src/util/tooltips/buildHeatmapTooltip.ts +57 -0
- package/src/util/tooltips/buildRadarTooltip.ts +53 -0
- package/src/util/tooltips/buildSharedItemTooltip.ts +38 -0
- package/src/util/tooltips/buildTreemapTooltip.ts +49 -0
- package/src/util/tooltips/index.ts +15 -0
- package/src/util/tooltips/render.ts +66 -0
- package/src/util/tooltips/types.ts +29 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script
|
|
8
|
+
lang="ts"
|
|
9
|
+
setup>
|
|
10
|
+
import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSlicesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildPolarAreaChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
|
|
14
|
+
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
advancedOptions,
|
|
19
|
+
slices,
|
|
20
|
+
title,
|
|
21
|
+
tooltip = false,
|
|
22
|
+
tooltipValueFormatter
|
|
23
|
+
} = defineProps<{
|
|
24
|
+
readonly advancedOptions?: EChartsOption;
|
|
25
|
+
readonly slices: readonly FluxStatisticsChartPieSlice[];
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
readonly tooltip?: boolean;
|
|
28
|
+
readonly tooltipValueFormatter?: ChartTooltipValueFormatter;
|
|
29
|
+
}>();
|
|
30
|
+
|
|
31
|
+
const { t, palette, tooltipItems } = useChartSlicesSetup(() => slices);
|
|
32
|
+
|
|
33
|
+
const mergedOptions = computed(() => buildPolarAreaChartOptions({
|
|
34
|
+
slices,
|
|
35
|
+
palette: palette.value,
|
|
36
|
+
tooltipItems: tooltipItems.value,
|
|
37
|
+
title,
|
|
38
|
+
t,
|
|
39
|
+
styles: $style,
|
|
40
|
+
tooltip,
|
|
41
|
+
tooltipValueFormatter,
|
|
42
|
+
advancedOptions
|
|
43
|
+
}));
|
|
44
|
+
</script>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script
|
|
8
|
+
lang="ts"
|
|
9
|
+
setup>
|
|
10
|
+
import type { FluxStatisticsChartRadarIndicator, FluxStatisticsChartRadarSeries } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildRadarChartOptions } from '~flux/statistics/util';
|
|
14
|
+
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
advancedOptions,
|
|
19
|
+
indicators,
|
|
20
|
+
series,
|
|
21
|
+
tooltip = false
|
|
22
|
+
} = defineProps<{
|
|
23
|
+
readonly advancedOptions?: EChartsOption;
|
|
24
|
+
readonly indicators: readonly FluxStatisticsChartRadarIndicator[];
|
|
25
|
+
readonly series: readonly FluxStatisticsChartRadarSeries[];
|
|
26
|
+
readonly tooltip?: boolean;
|
|
27
|
+
}>();
|
|
28
|
+
|
|
29
|
+
const { t, palette } = useChartSeriesSetup(() => series, { mode: 'data' });
|
|
30
|
+
|
|
31
|
+
const mergedOptions = computed(() => buildRadarChartOptions({
|
|
32
|
+
series,
|
|
33
|
+
indicators,
|
|
34
|
+
palette: palette.value,
|
|
35
|
+
t,
|
|
36
|
+
styles: $style,
|
|
37
|
+
tooltip,
|
|
38
|
+
advancedOptions
|
|
39
|
+
}));
|
|
40
|
+
</script>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script
|
|
8
|
+
lang="ts"
|
|
9
|
+
setup>
|
|
10
|
+
import type { FluxStatisticsChartGaugeSeries } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildGaugeChartOptions, gaugeLegendItemBuilder } from '~flux/statistics/util';
|
|
14
|
+
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
advancedOptions,
|
|
19
|
+
series,
|
|
20
|
+
tooltip = false
|
|
21
|
+
} = defineProps<{
|
|
22
|
+
readonly advancedOptions?: EChartsOption;
|
|
23
|
+
readonly series: readonly FluxStatisticsChartGaugeSeries[];
|
|
24
|
+
readonly tooltip?: boolean;
|
|
25
|
+
}>();
|
|
26
|
+
|
|
27
|
+
const { t, palette } = useChartSeriesSetup(() => series, {
|
|
28
|
+
getLegendItem: gaugeLegendItemBuilder
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const mergedOptions = computed(() => buildGaugeChartOptions({
|
|
32
|
+
series,
|
|
33
|
+
palette: palette.value,
|
|
34
|
+
t,
|
|
35
|
+
styles: $style,
|
|
36
|
+
tooltip,
|
|
37
|
+
advancedOptions
|
|
38
|
+
}));
|
|
39
|
+
</script>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script
|
|
8
|
+
lang="ts"
|
|
9
|
+
setup>
|
|
10
|
+
import type { FluxStatisticsChartScatterSeries } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildScatterChartOptions } from '~flux/statistics/util';
|
|
14
|
+
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
advancedOptions,
|
|
19
|
+
series,
|
|
20
|
+
splitLines = false,
|
|
21
|
+
tooltip = false,
|
|
22
|
+
xAxisLabels = false,
|
|
23
|
+
yAxisLabels = false
|
|
24
|
+
} = defineProps<{
|
|
25
|
+
readonly advancedOptions?: EChartsOption;
|
|
26
|
+
readonly series: readonly FluxStatisticsChartScatterSeries[];
|
|
27
|
+
readonly splitLines?: boolean;
|
|
28
|
+
readonly tooltip?: boolean;
|
|
29
|
+
readonly xAxisLabels?: boolean;
|
|
30
|
+
readonly yAxisLabels?: boolean;
|
|
31
|
+
}>();
|
|
32
|
+
|
|
33
|
+
const { t, palette } = useChartSeriesSetup(() => series);
|
|
34
|
+
|
|
35
|
+
const mergedOptions = computed(() => buildScatterChartOptions({
|
|
36
|
+
series,
|
|
37
|
+
palette: palette.value,
|
|
38
|
+
t,
|
|
39
|
+
styles: $style,
|
|
40
|
+
tooltip,
|
|
41
|
+
xAxisLabels,
|
|
42
|
+
yAxisLabels,
|
|
43
|
+
splitLines,
|
|
44
|
+
advancedOptions
|
|
45
|
+
}));
|
|
46
|
+
</script>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
data-sparkline
|
|
4
|
+
:class="$style.statisticsSparkline"
|
|
5
|
+
:style="{
|
|
6
|
+
'--color': resolvedColor
|
|
7
|
+
}">
|
|
8
|
+
<div
|
|
9
|
+
ref="chart"
|
|
10
|
+
:class="$style.statisticsSparklineChart"/>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script
|
|
15
|
+
lang="ts"
|
|
16
|
+
setup>
|
|
17
|
+
import type { FluxColor } from '@flux-ui/types';
|
|
18
|
+
import { merge } from 'lodash-es';
|
|
19
|
+
import { computed, useTemplateRef } from 'vue';
|
|
20
|
+
import { type EChartsOption, useECharts } from '~flux/statistics/composable';
|
|
21
|
+
import { buildSparklineOptions, deepResolveCssVars, type SparklineSeriesItem, useCssVarVersion } from '~flux/statistics/util';
|
|
22
|
+
import $style from '~flux/statistics/css/Sparkline.module.scss';
|
|
23
|
+
|
|
24
|
+
const FLUX_COLORS: FluxColor[] = ['gray', 'primary', 'danger', 'info', 'success', 'warning'];
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
color,
|
|
28
|
+
options = {},
|
|
29
|
+
series,
|
|
30
|
+
variant = 'line'
|
|
31
|
+
} = defineProps<{
|
|
32
|
+
readonly color?: FluxColor | `#${string}`;
|
|
33
|
+
readonly options?: EChartsOption;
|
|
34
|
+
readonly series: readonly SparklineSeriesItem[];
|
|
35
|
+
readonly variant?: 'line' | 'bar' | 'area';
|
|
36
|
+
}>();
|
|
37
|
+
|
|
38
|
+
const chart = useTemplateRef('chart');
|
|
39
|
+
|
|
40
|
+
const resolvedColor = computed(() => {
|
|
41
|
+
if (!color) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (FLUX_COLORS.includes(color as FluxColor)) {
|
|
46
|
+
return `var(--${color}-600)`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return color;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const themeVersion = useCssVarVersion();
|
|
53
|
+
|
|
54
|
+
const mergedOptions = computed<EChartsOption>(() => {
|
|
55
|
+
themeVersion.value;
|
|
56
|
+
|
|
57
|
+
const merged = merge(
|
|
58
|
+
{},
|
|
59
|
+
buildSparklineOptions(variant, resolvedColor.value ?? 'var(--chart-1)', series),
|
|
60
|
+
options
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return deepResolveCssVars(merged);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
useECharts(chart, mergedOptions);
|
|
67
|
+
</script>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
:options="mergedOptions"/>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script
|
|
7
|
+
lang="ts"
|
|
8
|
+
setup>
|
|
9
|
+
import type { FluxStatisticsChartTreemapNode } from '@flux-ui/types';
|
|
10
|
+
import { computed } from 'vue';
|
|
11
|
+
import { useChartBaseSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
12
|
+
import { buildTreemapChartOptions } from '~flux/statistics/util';
|
|
13
|
+
import Chart from './FluxStatisticsChart.vue';
|
|
14
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
advancedOptions,
|
|
18
|
+
nodes,
|
|
19
|
+
tooltip = false
|
|
20
|
+
} = defineProps<{
|
|
21
|
+
readonly advancedOptions?: EChartsOption;
|
|
22
|
+
readonly nodes: readonly FluxStatisticsChartTreemapNode[];
|
|
23
|
+
readonly tooltip?: boolean;
|
|
24
|
+
}>();
|
|
25
|
+
|
|
26
|
+
const { t } = useChartBaseSetup();
|
|
27
|
+
|
|
28
|
+
const mergedOptions = computed(() => buildTreemapChartOptions({
|
|
29
|
+
nodes,
|
|
30
|
+
t,
|
|
31
|
+
styles: $style,
|
|
32
|
+
tooltip,
|
|
33
|
+
advancedOptions
|
|
34
|
+
}));
|
|
35
|
+
</script>
|
package/src/component/index.ts
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
export { default as FluxStatisticsAreaChart } from './FluxStatisticsAreaChart.vue';
|
|
2
2
|
export { default as FluxStatisticsBarChart } from './FluxStatisticsBarChart.vue';
|
|
3
3
|
export { default as FluxStatisticsBase } from './FluxStatisticsBase.vue';
|
|
4
|
+
export { default as FluxStatisticsBoxPlotChart } from './FluxStatisticsBoxPlotChart.vue';
|
|
5
|
+
export { default as FluxStatisticsBubbleChart } from './FluxStatisticsBubbleChart.vue';
|
|
6
|
+
export { default as FluxStatisticsCandlestickChart } from './FluxStatisticsCandlestickChart.vue';
|
|
4
7
|
export { default as FluxStatisticsChange } from './FluxStatisticsChange.vue';
|
|
5
8
|
export { default as FluxStatisticsChart } from './FluxStatisticsChart.vue';
|
|
6
9
|
export { default as FluxStatisticsChartPane } from './FluxStatisticsChartPane.vue';
|
|
10
|
+
export { default as FluxStatisticsComparison } from './FluxStatisticsComparison.vue';
|
|
7
11
|
export { default as FluxStatisticsDetailsTable } from './FluxStatisticsDetailsTable.vue';
|
|
8
12
|
export { default as FluxStatisticsDetailsTableRow } from './FluxStatisticsDetailsTableRow.vue';
|
|
9
13
|
export { default as FluxStatisticsDonutChart } from './FluxStatisticsDonutChart.vue';
|
|
14
|
+
export { default as FluxStatisticsEmpty } from './FluxStatisticsEmpty.vue';
|
|
10
15
|
export { default as FluxStatisticsGrid } from './FluxStatisticsGrid.vue';
|
|
16
|
+
export { default as FluxStatisticsHeatmapChart } from './FluxStatisticsHeatmapChart.vue';
|
|
11
17
|
export { default as FluxStatisticsLineChart } from './FluxStatisticsLineChart.vue';
|
|
12
18
|
export { default as FluxStatisticsKpi } from './FluxStatisticsKpi.vue';
|
|
13
19
|
export { default as FluxStatisticsLegend } from './FluxStatisticsLegend.vue';
|
|
14
20
|
export { default as FluxStatisticsLegendItem } from './FluxStatisticsLegendItem.vue';
|
|
21
|
+
export { default as FluxStatisticsLegendScope } from './FluxStatisticsLegendScope.vue';
|
|
15
22
|
export { default as FluxStatisticsMeter } from './FluxStatisticsMeter.vue';
|
|
16
23
|
export { default as FluxStatisticsMetric } from './FluxStatisticsMetric.vue';
|
|
24
|
+
export { default as FluxStatisticsMixedChart } from './FluxStatisticsMixedChart.vue';
|
|
25
|
+
export { default as FluxStatisticsPercentageBar } from './FluxStatisticsPercentageBar.vue';
|
|
17
26
|
export { default as FluxStatisticsPieChart } from './FluxStatisticsPieChart.vue';
|
|
27
|
+
export { default as FluxStatisticsPolarAreaChart } from './FluxStatisticsPolarAreaChart.vue';
|
|
28
|
+
export { default as FluxStatisticsRadarChart } from './FluxStatisticsRadarChart.vue';
|
|
29
|
+
export { default as FluxStatisticsRadialBar } from './FluxStatisticsRadialBar.vue';
|
|
30
|
+
export { default as FluxStatisticsScatterChart } from './FluxStatisticsScatterChart.vue';
|
|
31
|
+
export { default as FluxStatisticsSparkline } from './FluxStatisticsSparkline.vue';
|
|
32
|
+
export { default as FluxStatisticsTreemapChart } from './FluxStatisticsTreemapChart.vue';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type { UseChartBaseSetupReturn } from './useChartBaseSetup';
|
|
2
|
+
export { useChartBaseSetup } from './useChartBaseSetup';
|
|
3
|
+
export type { ChartLegendContext, ChartLegendItem } from './useChartLegend';
|
|
4
|
+
export { createChartLegendContext, FluxStatisticsChartLegendInjectionKey } from './useChartLegend';
|
|
5
|
+
export type { ChartHoverSyncMode, UseChartHoverSyncOptions } from './useChartHoverSync';
|
|
6
|
+
export { useChartHoverSync } from './useChartHoverSync';
|
|
7
|
+
export type { ChartLegendItemBuilder, ChartSeriesShape, UseChartSeriesSetupOptions, UseChartSeriesSetupReturn } from './useChartSeriesSetup';
|
|
8
|
+
export { useChartSeriesSetup } from './useChartSeriesSetup';
|
|
9
|
+
export type { UseChartSlicesSetupReturn } from './useChartSlicesSetup';
|
|
10
|
+
export { useChartSlicesSetup } from './useChartSlicesSetup';
|
|
11
|
+
export type { EChartsInstance, EChartsOption, UseEChartsReturn } from './useECharts';
|
|
12
|
+
export { useECharts } from './useECharts';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { computed, useTemplateRef, type ComputedRef } from 'vue';
|
|
2
|
+
import { useI18n } from 'vue-i18n';
|
|
3
|
+
import type { EChartsInstance } from './useECharts';
|
|
4
|
+
|
|
5
|
+
export interface UseChartBaseSetupReturn {
|
|
6
|
+
readonly t: ReturnType<typeof useI18n>['t'];
|
|
7
|
+
readonly chartInstance: ComputedRef<EChartsInstance | null>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function useChartBaseSetup(): UseChartBaseSetupReturn {
|
|
11
|
+
const { t } = useI18n({ useScope: 'parent' });
|
|
12
|
+
const chartRef = useTemplateRef<{ chartInstance: EChartsInstance | null } | null>('chartRef');
|
|
13
|
+
const chartInstance = computed<EChartsInstance | null>(() => chartRef.value?.chartInstance ?? null);
|
|
14
|
+
|
|
15
|
+
return { t, chartInstance };
|
|
16
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { onBeforeUnmount, watch, type Ref } from 'vue';
|
|
2
|
+
import type { ChartLegendContext } from './useChartLegend';
|
|
3
|
+
import type { EChartsInstance } from './useECharts';
|
|
4
|
+
|
|
5
|
+
export type ChartHoverSyncMode = 'series' | 'data';
|
|
6
|
+
|
|
7
|
+
export interface UseChartHoverSyncOptions {
|
|
8
|
+
readonly mode: ChartHoverSyncMode;
|
|
9
|
+
readonly seriesIndex?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useChartHoverSync(
|
|
13
|
+
chartInstance: Ref<EChartsInstance | null>,
|
|
14
|
+
legendContext: ChartLegendContext | null,
|
|
15
|
+
options: UseChartHoverSyncOptions
|
|
16
|
+
): void {
|
|
17
|
+
if (!legendContext) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { mode, seriesIndex: forcedSeriesIndex = 0 } = options;
|
|
22
|
+
|
|
23
|
+
let attached: EChartsInstance | null = null;
|
|
24
|
+
let syncing = false;
|
|
25
|
+
|
|
26
|
+
const onMouseOver = (params: { seriesIndex?: number; dataIndex?: number }) => {
|
|
27
|
+
if (syncing) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const index = mode === 'series'
|
|
32
|
+
? params.seriesIndex ?? null
|
|
33
|
+
: params.dataIndex ?? null;
|
|
34
|
+
|
|
35
|
+
legendContext.hoveredIndex.value = index;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const onMouseOut = () => {
|
|
39
|
+
if (syncing) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
legendContext.hoveredIndex.value = null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const dispatchHighlight = (instance: EChartsInstance, index: number | null) => {
|
|
47
|
+
syncing = true;
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
instance.dispatchAction({ type: 'downplay' });
|
|
51
|
+
|
|
52
|
+
if (index !== null) {
|
|
53
|
+
if (mode === 'series') {
|
|
54
|
+
instance.dispatchAction({ type: 'highlight', seriesIndex: index });
|
|
55
|
+
} else {
|
|
56
|
+
instance.dispatchAction({ type: 'highlight', seriesIndex: forcedSeriesIndex, dataIndex: index });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} finally {
|
|
60
|
+
syncing = false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
watch(chartInstance, instance => {
|
|
65
|
+
if (attached) {
|
|
66
|
+
attached.off('mouseover', onMouseOver as never);
|
|
67
|
+
attached.off('mouseout', onMouseOut as never);
|
|
68
|
+
attached = null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (instance) {
|
|
72
|
+
instance.on('mouseover', onMouseOver as never);
|
|
73
|
+
instance.on('mouseout', onMouseOut as never);
|
|
74
|
+
attached = instance;
|
|
75
|
+
dispatchHighlight(instance, legendContext.hoveredIndex.value);
|
|
76
|
+
}
|
|
77
|
+
}, { immediate: true });
|
|
78
|
+
|
|
79
|
+
watch(() => legendContext.hoveredIndex.value, index => {
|
|
80
|
+
if (chartInstance.value) {
|
|
81
|
+
dispatchHighlight(chartInstance.value, index);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
onBeforeUnmount(() => {
|
|
86
|
+
if (attached) {
|
|
87
|
+
attached.off('mouseover', onMouseOver as never);
|
|
88
|
+
attached.off('mouseout', onMouseOut as never);
|
|
89
|
+
attached = null;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FluxIconName } from '@flux-ui/types';
|
|
2
|
+
import { ref, type InjectionKey, type Ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
export interface ChartLegendItem {
|
|
5
|
+
readonly color?: string;
|
|
6
|
+
readonly icon?: FluxIconName;
|
|
7
|
+
readonly label: string;
|
|
8
|
+
readonly value?: string | number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ChartLegendContext {
|
|
12
|
+
readonly items: Ref<readonly ChartLegendItem[]>;
|
|
13
|
+
readonly hoveredIndex: Ref<number | null>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const FluxStatisticsChartLegendInjectionKey: InjectionKey<ChartLegendContext> = Symbol('flux-statistics-chart-legend');
|
|
17
|
+
|
|
18
|
+
export function createChartLegendContext(): ChartLegendContext {
|
|
19
|
+
return {
|
|
20
|
+
items: ref<readonly ChartLegendItem[]>([]),
|
|
21
|
+
hoveredIndex: ref<number | null>(null)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { FluxIconName, FluxStatisticsChartColor } from '@flux-ui/types';
|
|
2
|
+
import { computed, inject, useTemplateRef, watchEffect, type ComputedRef } from 'vue';
|
|
3
|
+
import { useI18n } from 'vue-i18n';
|
|
4
|
+
import { CHART_DEFAULT_COLORS, resolveChartColor } from '~flux/statistics/util';
|
|
5
|
+
import { type ChartHoverSyncMode, useChartHoverSync } from './useChartHoverSync';
|
|
6
|
+
import { type ChartLegendContext, type ChartLegendItem, FluxStatisticsChartLegendInjectionKey } from './useChartLegend';
|
|
7
|
+
import type { EChartsInstance } from './useECharts';
|
|
8
|
+
|
|
9
|
+
export interface ChartSeriesShape {
|
|
10
|
+
readonly name?: string;
|
|
11
|
+
readonly icon?: FluxIconName;
|
|
12
|
+
readonly color?: FluxStatisticsChartColor;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type ChartLegendItemBuilder<S> = (
|
|
16
|
+
series: S,
|
|
17
|
+
color: string,
|
|
18
|
+
index: number,
|
|
19
|
+
t: ReturnType<typeof useI18n>['t']
|
|
20
|
+
) => ChartLegendItem | readonly ChartLegendItem[];
|
|
21
|
+
|
|
22
|
+
export interface UseChartSeriesSetupOptions<S extends ChartSeriesShape> {
|
|
23
|
+
readonly mode?: ChartHoverSyncMode;
|
|
24
|
+
readonly getLegendItem?: ChartLegendItemBuilder<S>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface UseChartSeriesSetupReturn {
|
|
28
|
+
readonly t: ReturnType<typeof useI18n>['t'];
|
|
29
|
+
readonly palette: ComputedRef<readonly string[]>;
|
|
30
|
+
readonly legendContext: ChartLegendContext | null;
|
|
31
|
+
readonly chartInstance: ComputedRef<EChartsInstance | null>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const defaultLegendItem = <S extends ChartSeriesShape>(
|
|
35
|
+
s: S,
|
|
36
|
+
color: string,
|
|
37
|
+
_index: number,
|
|
38
|
+
t: ReturnType<typeof useI18n>['t']
|
|
39
|
+
): ChartLegendItem => ({
|
|
40
|
+
color,
|
|
41
|
+
icon: s.icon,
|
|
42
|
+
label: s.name ? t(String(s.name)) : ''
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export function useChartSeriesSetup<S extends ChartSeriesShape>(
|
|
46
|
+
seriesGetter: () => readonly S[],
|
|
47
|
+
options: UseChartSeriesSetupOptions<S> = {}
|
|
48
|
+
): UseChartSeriesSetupReturn {
|
|
49
|
+
const { mode = 'series', getLegendItem = defaultLegendItem } = options;
|
|
50
|
+
const { t } = useI18n({ useScope: 'parent' });
|
|
51
|
+
const legendContext = inject(FluxStatisticsChartLegendInjectionKey, null);
|
|
52
|
+
const chartRef = useTemplateRef<{ chartInstance: EChartsInstance | null } | null>('chartRef');
|
|
53
|
+
const chartInstance = computed<EChartsInstance | null>(() => chartRef.value?.chartInstance ?? null);
|
|
54
|
+
|
|
55
|
+
useChartHoverSync(chartInstance, legendContext, { mode });
|
|
56
|
+
|
|
57
|
+
const palette = computed<readonly string[]>(() =>
|
|
58
|
+
seriesGetter().map((s, i) => resolveChartColor(s.color) ?? CHART_DEFAULT_COLORS[i % CHART_DEFAULT_COLORS.length])
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const legendItems = computed<readonly ChartLegendItem[]>(() =>
|
|
62
|
+
seriesGetter().flatMap((s, i) => {
|
|
63
|
+
const item = getLegendItem(s, palette.value[i], i, t);
|
|
64
|
+
return Array.isArray(item) ? item : [item as ChartLegendItem];
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
watchEffect(() => {
|
|
69
|
+
if (legendContext) {
|
|
70
|
+
legendContext.items.value = legendItems.value;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return { t, palette, legendContext, chartInstance };
|
|
75
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
|
|
2
|
+
import { computed, inject, useTemplateRef, watchEffect, type ComputedRef } from 'vue';
|
|
3
|
+
import { useI18n } from 'vue-i18n';
|
|
4
|
+
import { CHART_DEFAULT_COLORS, resolveChartColor, type SharedTooltipItem } from '~flux/statistics/util';
|
|
5
|
+
import { useChartHoverSync } from './useChartHoverSync';
|
|
6
|
+
import { type ChartLegendContext, type ChartLegendItem, FluxStatisticsChartLegendInjectionKey } from './useChartLegend';
|
|
7
|
+
import type { EChartsInstance } from './useECharts';
|
|
8
|
+
|
|
9
|
+
export interface UseChartSlicesSetupReturn {
|
|
10
|
+
readonly t: ReturnType<typeof useI18n>['t'];
|
|
11
|
+
readonly palette: ComputedRef<readonly string[]>;
|
|
12
|
+
readonly tooltipItems: ComputedRef<readonly SharedTooltipItem[]>;
|
|
13
|
+
readonly legendContext: ChartLegendContext | null;
|
|
14
|
+
readonly chartInstance: ComputedRef<EChartsInstance | null>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useChartSlicesSetup(
|
|
18
|
+
slicesGetter: () => readonly FluxStatisticsChartPieSlice[]
|
|
19
|
+
): UseChartSlicesSetupReturn {
|
|
20
|
+
const { t } = useI18n({ useScope: 'parent' });
|
|
21
|
+
const legendContext = inject(FluxStatisticsChartLegendInjectionKey, null);
|
|
22
|
+
const chartRef = useTemplateRef<{ chartInstance: EChartsInstance | null } | null>('chartRef');
|
|
23
|
+
const chartInstance = computed<EChartsInstance | null>(() => chartRef.value?.chartInstance ?? null);
|
|
24
|
+
|
|
25
|
+
useChartHoverSync(chartInstance, legendContext, { mode: 'data' });
|
|
26
|
+
|
|
27
|
+
const palette = computed<readonly string[]>(() =>
|
|
28
|
+
slicesGetter().map((slice, i) => resolveChartColor(slice.color) ?? CHART_DEFAULT_COLORS[i % CHART_DEFAULT_COLORS.length])
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const tooltipItems = computed<readonly SharedTooltipItem[]>(() =>
|
|
32
|
+
slicesGetter().map((slice, i) => ({
|
|
33
|
+
name: slice.label,
|
|
34
|
+
value: slice.formatted ?? slice.value,
|
|
35
|
+
color: palette.value[i],
|
|
36
|
+
icon: slice.icon,
|
|
37
|
+
seriesIndex: 0,
|
|
38
|
+
dataIndex: i
|
|
39
|
+
}))
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const legendItems = computed<readonly ChartLegendItem[]>(() =>
|
|
43
|
+
slicesGetter().map((slice, i) => ({
|
|
44
|
+
color: palette.value[i],
|
|
45
|
+
icon: slice.icon,
|
|
46
|
+
label: slice.label ? t(String(slice.label)) : '',
|
|
47
|
+
value: slice.formatted ?? slice.value
|
|
48
|
+
}))
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
watchEffect(() => {
|
|
52
|
+
if (legendContext) {
|
|
53
|
+
legendContext.items.value = legendItems.value;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return { t, palette, tooltipItems, legendContext, chartInstance };
|
|
58
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useResizeObserver } from '@basmilius/common';
|
|
2
|
+
import { init, type EChartsCoreOption } from 'echarts/core';
|
|
3
|
+
import { markRaw, onBeforeUnmount, onMounted, ref, toValue, type MaybeRefOrGetter, type Ref } from 'vue';
|
|
4
|
+
import '~flux/statistics/echarts';
|
|
5
|
+
|
|
6
|
+
export type EChartsOption = EChartsCoreOption;
|
|
7
|
+
export type EChartsInstance = ReturnType<typeof init>;
|
|
8
|
+
|
|
9
|
+
export interface UseEChartsReturn {
|
|
10
|
+
readonly chartInstance: Ref<EChartsInstance | null>;
|
|
11
|
+
resize(): void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useECharts(
|
|
15
|
+
target: Ref<HTMLElement | null>,
|
|
16
|
+
options: MaybeRefOrGetter<EChartsOption>
|
|
17
|
+
): UseEChartsReturn {
|
|
18
|
+
const chartInstance = ref<EChartsInstance | null>(null);
|
|
19
|
+
let pendingResize: number | null = null;
|
|
20
|
+
|
|
21
|
+
onMounted(() => {
|
|
22
|
+
if (!target.value) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
chartInstance.value = markRaw(init(target.value));
|
|
27
|
+
chartInstance.value.setOption(toValue(options));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
onBeforeUnmount(() => {
|
|
31
|
+
if (pendingResize !== null) {
|
|
32
|
+
cancelAnimationFrame(pendingResize);
|
|
33
|
+
pendingResize = null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
chartInstance.value?.dispose();
|
|
37
|
+
chartInstance.value = null;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
useResizeObserver(target as any, () => {
|
|
41
|
+
if (pendingResize !== null) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pendingResize = requestAnimationFrame(() => {
|
|
46
|
+
pendingResize = null;
|
|
47
|
+
chartInstance.value?.resize();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
chartInstance: chartInstance as Ref<EChartsInstance | null>,
|
|
53
|
+
resize: () => chartInstance.value?.resize()
|
|
54
|
+
};
|
|
55
|
+
}
|