@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,113 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Base
|
|
3
|
+
is-small
|
|
4
|
+
:icon="icon"
|
|
5
|
+
:title="title">
|
|
6
|
+
<div :class="$style.statisticsComparison">
|
|
7
|
+
<div :class="$style.statisticsComparisonItem">
|
|
8
|
+
<div :class="$style.statisticsComparisonItemLabel">
|
|
9
|
+
{{ currentLabel ?? 'Current' }}
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div :class="$style.statisticsComparisonItemValue">
|
|
13
|
+
{{ formattedCurrent }}
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div :class="$style.statisticsComparisonDivider"/>
|
|
18
|
+
|
|
19
|
+
<div :class="$style.statisticsComparisonItem">
|
|
20
|
+
<div :class="$style.statisticsComparisonItemLabel">
|
|
21
|
+
{{ previousLabel ?? 'Previous' }}
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div :class="$style.statisticsComparisonItemValueMuted">
|
|
25
|
+
{{ formattedPrevious }}
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div
|
|
31
|
+
v-if="showDelta"
|
|
32
|
+
:class="$style.statisticsComparisonBottom">
|
|
33
|
+
<Change
|
|
34
|
+
:color="deltaColor"
|
|
35
|
+
:icon="deltaIcon"
|
|
36
|
+
:value="formattedDelta"/>
|
|
37
|
+
|
|
38
|
+
<span
|
|
39
|
+
v-if="footer"
|
|
40
|
+
:class="$style.statisticsComparisonFooter">
|
|
41
|
+
{{ footer }}
|
|
42
|
+
</span>
|
|
43
|
+
</div>
|
|
44
|
+
</Base>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<script
|
|
48
|
+
lang="ts"
|
|
49
|
+
setup>
|
|
50
|
+
import type { FluxColor, FluxIconName } from '@flux-ui/types';
|
|
51
|
+
import { computed } from 'vue';
|
|
52
|
+
import Base from './FluxStatisticsBase.vue';
|
|
53
|
+
import Change from './FluxStatisticsChange.vue';
|
|
54
|
+
import $style from '~flux/statistics/css/Comparison.module.scss';
|
|
55
|
+
|
|
56
|
+
const {
|
|
57
|
+
current,
|
|
58
|
+
format,
|
|
59
|
+
previous,
|
|
60
|
+
showDelta = true
|
|
61
|
+
} = defineProps<{
|
|
62
|
+
readonly current: number;
|
|
63
|
+
readonly currentLabel?: string;
|
|
64
|
+
readonly footer?: string;
|
|
65
|
+
readonly format?: (value: number) => string;
|
|
66
|
+
readonly icon?: FluxIconName;
|
|
67
|
+
readonly previous: number;
|
|
68
|
+
readonly previousLabel?: string;
|
|
69
|
+
readonly showDelta?: boolean;
|
|
70
|
+
readonly title: string;
|
|
71
|
+
}>();
|
|
72
|
+
|
|
73
|
+
const formattedCurrent = computed(() => format ? format(current) : current);
|
|
74
|
+
const formattedPrevious = computed(() => format ? format(previous) : previous);
|
|
75
|
+
|
|
76
|
+
const deltaValue = computed(() => {
|
|
77
|
+
if (previous === 0) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return ((current - previous) / Math.abs(previous)) * 100;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const deltaColor = computed<FluxColor>(() => {
|
|
85
|
+
if (deltaValue.value > 0) {
|
|
86
|
+
return 'success';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (deltaValue.value < 0) {
|
|
90
|
+
return 'danger';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return 'gray';
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const deltaIcon = computed<FluxIconName | undefined>(() => {
|
|
97
|
+
if (deltaValue.value > 0) {
|
|
98
|
+
return 'arrow-trend-up';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (deltaValue.value < 0) {
|
|
102
|
+
return 'arrow-trend-down';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return undefined;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const formattedDelta = computed(() => {
|
|
109
|
+
const sign = deltaValue.value > 0 ? '+' : '';
|
|
110
|
+
|
|
111
|
+
return `${sign}${deltaValue.value.toFixed(1)}%`;
|
|
112
|
+
});
|
|
113
|
+
</script>
|
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Chart
|
|
3
|
-
|
|
4
|
-
:options="
|
|
5
|
-
chart: {
|
|
6
|
-
type: 'donut'
|
|
7
|
-
},
|
|
8
|
-
legend: {
|
|
9
|
-
show: false
|
|
10
|
-
},
|
|
11
|
-
tooltip: {
|
|
12
|
-
enabled: false
|
|
13
|
-
}
|
|
14
|
-
}, options)"
|
|
15
|
-
:series="series"/>
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
16
5
|
</template>
|
|
17
6
|
|
|
18
7
|
<script
|
|
19
8
|
lang="ts"
|
|
20
9
|
setup>
|
|
21
|
-
import type {
|
|
22
|
-
import {
|
|
10
|
+
import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSlicesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildDonutChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
|
|
23
14
|
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
24
16
|
|
|
25
17
|
const {
|
|
26
|
-
|
|
18
|
+
advancedOptions,
|
|
19
|
+
slices,
|
|
20
|
+
title,
|
|
21
|
+
tooltip = false,
|
|
22
|
+
tooltipValueFormatter
|
|
27
23
|
} = defineProps<{
|
|
28
|
-
readonly
|
|
29
|
-
readonly
|
|
30
|
-
readonly
|
|
24
|
+
readonly advancedOptions?: EChartsOption;
|
|
25
|
+
readonly slices: readonly FluxStatisticsChartPieSlice[];
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
readonly tooltip?: boolean;
|
|
28
|
+
readonly tooltipValueFormatter?: ChartTooltipValueFormatter;
|
|
31
29
|
}>();
|
|
30
|
+
|
|
31
|
+
const { t, palette, tooltipItems } = useChartSlicesSetup(() => slices);
|
|
32
|
+
|
|
33
|
+
const mergedOptions = computed(() => buildDonutChartOptions({
|
|
34
|
+
slices,
|
|
35
|
+
palette: palette.value,
|
|
36
|
+
tooltipItems: tooltipItems.value,
|
|
37
|
+
title,
|
|
38
|
+
t,
|
|
39
|
+
styles: $style,
|
|
40
|
+
tooltip,
|
|
41
|
+
tooltipValueFormatter,
|
|
42
|
+
advancedOptions
|
|
43
|
+
}));
|
|
32
44
|
</script>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.statisticsEmpty">
|
|
3
|
+
<FluxIcon
|
|
4
|
+
v-if="icon"
|
|
5
|
+
:class="$style.statisticsEmptyIcon"
|
|
6
|
+
:name="icon"/>
|
|
7
|
+
|
|
8
|
+
<div
|
|
9
|
+
v-if="title"
|
|
10
|
+
:class="$style.statisticsEmptyTitle">
|
|
11
|
+
{{ title }}
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div
|
|
15
|
+
v-if="description"
|
|
16
|
+
:class="$style.statisticsEmptyDescription">
|
|
17
|
+
{{ description }}
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div
|
|
21
|
+
v-if="slots.default"
|
|
22
|
+
:class="$style.statisticsEmptyActions">
|
|
23
|
+
<slot/>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script
|
|
29
|
+
lang="ts"
|
|
30
|
+
setup>
|
|
31
|
+
import { FluxIcon } from '@flux-ui/components';
|
|
32
|
+
import type { FluxIconName } from '@flux-ui/types';
|
|
33
|
+
import $style from '~flux/statistics/css/Empty.module.scss';
|
|
34
|
+
|
|
35
|
+
defineProps<{
|
|
36
|
+
readonly description?: string;
|
|
37
|
+
readonly icon?: FluxIconName;
|
|
38
|
+
readonly title?: string;
|
|
39
|
+
}>();
|
|
40
|
+
|
|
41
|
+
const slots = defineSlots<{
|
|
42
|
+
default?(): any;
|
|
43
|
+
}>();
|
|
44
|
+
</script>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
:options="mergedOptions"/>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script
|
|
7
|
+
lang="ts"
|
|
8
|
+
setup>
|
|
9
|
+
import type { FluxStatisticsChartHeatmapSeries } from '@flux-ui/types';
|
|
10
|
+
import { computed } from 'vue';
|
|
11
|
+
import { useChartBaseSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
12
|
+
import { buildHeatmapChartOptions } 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
|
+
series,
|
|
19
|
+
tooltip = false,
|
|
20
|
+
xAxisLabels = false,
|
|
21
|
+
xLabels = [],
|
|
22
|
+
yAxisLabels = false,
|
|
23
|
+
yLabels = []
|
|
24
|
+
} = defineProps<{
|
|
25
|
+
readonly advancedOptions?: EChartsOption;
|
|
26
|
+
readonly series: readonly FluxStatisticsChartHeatmapSeries[];
|
|
27
|
+
readonly tooltip?: boolean;
|
|
28
|
+
readonly xAxisLabels?: boolean;
|
|
29
|
+
readonly xLabels?: readonly string[];
|
|
30
|
+
readonly yAxisLabels?: boolean;
|
|
31
|
+
readonly yLabels?: readonly string[];
|
|
32
|
+
}>();
|
|
33
|
+
|
|
34
|
+
const { t } = useChartBaseSetup();
|
|
35
|
+
|
|
36
|
+
const mergedOptions = computed(() => buildHeatmapChartOptions({
|
|
37
|
+
series,
|
|
38
|
+
xLabels,
|
|
39
|
+
yLabels,
|
|
40
|
+
t,
|
|
41
|
+
styles: $style,
|
|
42
|
+
tooltip,
|
|
43
|
+
xAxisLabels,
|
|
44
|
+
yAxisLabels,
|
|
45
|
+
advancedOptions
|
|
46
|
+
}));
|
|
47
|
+
</script>
|
|
@@ -1,11 +1,43 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="$style.statisticsLegend">
|
|
3
|
-
<slot/>
|
|
3
|
+
<slot v-if="hasSlot"/>
|
|
4
|
+
<FluxStatisticsLegendItem
|
|
5
|
+
v-else
|
|
6
|
+
v-for="(item, index) in autoItems"
|
|
7
|
+
:key="item.label"
|
|
8
|
+
:color="item.color as `#${string}` | undefined"
|
|
9
|
+
:icon="item.icon"
|
|
10
|
+
:is-hovered="legendContext?.hoveredIndex.value === index"
|
|
11
|
+
:label="item.label"
|
|
12
|
+
:value="item.value"
|
|
13
|
+
@mouseenter="onItemMouseEnter(index)"
|
|
14
|
+
@mouseleave="onItemMouseLeave"/>
|
|
4
15
|
</div>
|
|
5
16
|
</template>
|
|
6
17
|
|
|
7
18
|
<script
|
|
8
19
|
lang="ts"
|
|
9
20
|
setup>
|
|
21
|
+
import { computed, inject, useSlots } from 'vue';
|
|
22
|
+
import { FluxStatisticsChartLegendInjectionKey } from '~flux/statistics/composable';
|
|
23
|
+
import FluxStatisticsLegendItem from './FluxStatisticsLegendItem.vue';
|
|
10
24
|
import $style from '~flux/statistics/css/Legend.module.scss';
|
|
25
|
+
|
|
26
|
+
const slots = useSlots();
|
|
27
|
+
const legendContext = inject(FluxStatisticsChartLegendInjectionKey, null);
|
|
28
|
+
|
|
29
|
+
const hasSlot = computed(() => !!slots.default);
|
|
30
|
+
const autoItems = computed(() => legendContext?.items.value ?? []);
|
|
31
|
+
|
|
32
|
+
function onItemMouseEnter(index: number): void {
|
|
33
|
+
if (legendContext) {
|
|
34
|
+
legendContext.hoveredIndex.value = index;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function onItemMouseLeave(): void {
|
|
39
|
+
if (legendContext) {
|
|
40
|
+
legendContext.hoveredIndex.value = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
11
43
|
</script>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
:class="$style.statisticsLegendItem"
|
|
3
|
+
:class="clsx($style.statisticsLegendItem, isHovered && $style.isHovered)"
|
|
4
4
|
:style="{
|
|
5
5
|
'--color': colorValue
|
|
6
6
|
}">
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
setup>
|
|
34
34
|
import { FluxIcon } from '@flux-ui/components';
|
|
35
35
|
import type { FluxColor, FluxIconName } from '@flux-ui/types';
|
|
36
|
+
import { clsx } from 'clsx';
|
|
36
37
|
import { computed } from 'vue';
|
|
37
38
|
import $style from '~flux/statistics/css/Legend.module.scss';
|
|
38
39
|
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
} = defineProps<{
|
|
42
43
|
readonly color?: FluxColor | `#${string}`;
|
|
43
44
|
readonly icon?: FluxIconName;
|
|
45
|
+
readonly isHovered?: boolean;
|
|
44
46
|
readonly label: string;
|
|
45
47
|
readonly value?: string | number;
|
|
46
48
|
}>();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<slot/>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script
|
|
6
|
+
lang="ts"
|
|
7
|
+
setup>
|
|
8
|
+
import { provide } from 'vue';
|
|
9
|
+
import { createChartLegendContext, FluxStatisticsChartLegendInjectionKey } from '~flux/statistics/composable';
|
|
10
|
+
|
|
11
|
+
defineSlots<{
|
|
12
|
+
default(): any;
|
|
13
|
+
}>();
|
|
14
|
+
|
|
15
|
+
provide(FluxStatisticsChartLegendInjectionKey, createChartLegendContext());
|
|
16
|
+
</script>
|
|
@@ -1,59 +1,52 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Chart
|
|
3
|
-
|
|
4
|
-
:options="
|
|
5
|
-
chart: {
|
|
6
|
-
type: 'line',
|
|
7
|
-
sparkline: {
|
|
8
|
-
enabled: true
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
fill: {
|
|
12
|
-
gradient: {
|
|
13
|
-
enabled: true,
|
|
14
|
-
opacityFrom: 0.5,
|
|
15
|
-
opacityTo: 0
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
grid: {
|
|
19
|
-
show: true,
|
|
20
|
-
clipMarkers: false
|
|
21
|
-
},
|
|
22
|
-
legend: {
|
|
23
|
-
show: false
|
|
24
|
-
},
|
|
25
|
-
stroke: {
|
|
26
|
-
curve: 'smooth',
|
|
27
|
-
width: 2
|
|
28
|
-
}
|
|
29
|
-
}, options)"
|
|
30
|
-
:series="translatedSeries"/>
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
31
5
|
</template>
|
|
32
6
|
|
|
33
7
|
<script
|
|
34
8
|
lang="ts"
|
|
35
9
|
setup>
|
|
36
|
-
import type {
|
|
37
|
-
import { merge } from 'lodash-es';
|
|
10
|
+
import type { FluxStatisticsChartLineSeries } from '@flux-ui/types';
|
|
38
11
|
import { computed } from 'vue';
|
|
39
|
-
import {
|
|
12
|
+
import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildLineChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
|
|
40
14
|
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
41
16
|
|
|
42
17
|
const {
|
|
43
|
-
|
|
44
|
-
|
|
18
|
+
advancedOptions,
|
|
19
|
+
labels,
|
|
20
|
+
series,
|
|
21
|
+
splitLines = false,
|
|
22
|
+
tooltip = false,
|
|
23
|
+
tooltipValueFormatter,
|
|
24
|
+
xAxisLabels = false,
|
|
25
|
+
yAxisLabels = false
|
|
45
26
|
} = defineProps<{
|
|
46
|
-
readonly
|
|
47
|
-
readonly
|
|
48
|
-
readonly series:
|
|
27
|
+
readonly advancedOptions?: EChartsOption;
|
|
28
|
+
readonly labels?: readonly string[];
|
|
29
|
+
readonly series: readonly FluxStatisticsChartLineSeries[];
|
|
30
|
+
readonly splitLines?: boolean;
|
|
31
|
+
readonly tooltip?: boolean;
|
|
32
|
+
readonly tooltipValueFormatter?: ChartTooltipValueFormatter;
|
|
33
|
+
readonly xAxisLabels?: boolean;
|
|
34
|
+
readonly yAxisLabels?: boolean;
|
|
49
35
|
}>();
|
|
50
36
|
|
|
51
|
-
const {t} =
|
|
37
|
+
const { t, palette } = useChartSeriesSetup(() => series);
|
|
52
38
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
const mergedOptions = computed(() => buildLineChartOptions({
|
|
40
|
+
series,
|
|
41
|
+
labels,
|
|
42
|
+
palette: palette.value,
|
|
43
|
+
t,
|
|
44
|
+
styles: $style,
|
|
45
|
+
tooltip,
|
|
46
|
+
tooltipValueFormatter,
|
|
47
|
+
xAxisLabels,
|
|
48
|
+
yAxisLabels,
|
|
49
|
+
splitLines,
|
|
50
|
+
advancedOptions
|
|
51
|
+
}));
|
|
59
52
|
</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Chart
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script
|
|
8
|
+
lang="ts"
|
|
9
|
+
setup>
|
|
10
|
+
import type { FluxStatisticsChartMixedSeries } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSeriesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildMixedChartOptions, 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
|
+
labels,
|
|
20
|
+
series,
|
|
21
|
+
splitLines = false,
|
|
22
|
+
tooltip = false,
|
|
23
|
+
tooltipValueFormatter,
|
|
24
|
+
xAxisLabels = false,
|
|
25
|
+
yAxisLabels = false
|
|
26
|
+
} = defineProps<{
|
|
27
|
+
readonly advancedOptions?: EChartsOption;
|
|
28
|
+
readonly labels?: readonly string[];
|
|
29
|
+
readonly series: readonly FluxStatisticsChartMixedSeries[];
|
|
30
|
+
readonly splitLines?: boolean;
|
|
31
|
+
readonly tooltip?: boolean;
|
|
32
|
+
readonly tooltipValueFormatter?: ChartTooltipValueFormatter;
|
|
33
|
+
readonly xAxisLabels?: boolean;
|
|
34
|
+
readonly yAxisLabels?: boolean;
|
|
35
|
+
}>();
|
|
36
|
+
|
|
37
|
+
const { t, palette } = useChartSeriesSetup(() => series);
|
|
38
|
+
|
|
39
|
+
const mergedOptions = computed(() => buildMixedChartOptions({
|
|
40
|
+
series,
|
|
41
|
+
labels,
|
|
42
|
+
palette: palette.value,
|
|
43
|
+
t,
|
|
44
|
+
styles: $style,
|
|
45
|
+
tooltip,
|
|
46
|
+
tooltipValueFormatter,
|
|
47
|
+
xAxisLabels,
|
|
48
|
+
yAxisLabels,
|
|
49
|
+
splitLines,
|
|
50
|
+
advancedOptions
|
|
51
|
+
}));
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.statisticsPercentageBar">
|
|
3
|
+
<div :class="clsx($style.statisticsPercentageBarTrack, hoveredIndex !== null && $style.isHoverActive)">
|
|
4
|
+
<FluxTooltip
|
|
5
|
+
v-for="(item, index) of items"
|
|
6
|
+
:key="index">
|
|
7
|
+
<template #content>
|
|
8
|
+
<div :class="$style.statisticsPercentageBarTooltip">
|
|
9
|
+
<FluxIcon
|
|
10
|
+
v-if="item.icon"
|
|
11
|
+
:name="item.icon"
|
|
12
|
+
:size="16"/>
|
|
13
|
+
|
|
14
|
+
<span>{{ formatPercentage(item.value) }} {{ item.label }}</span>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<div
|
|
19
|
+
:class="clsx($style.statisticsPercentageBarSegment, hoveredIndex === index && $style.isHovered)"
|
|
20
|
+
:style="{
|
|
21
|
+
backgroundColor: resolveColor(item.color),
|
|
22
|
+
flexGrow: item.value
|
|
23
|
+
}"
|
|
24
|
+
@mouseenter="onSegmentEnter(index)"
|
|
25
|
+
@mouseleave="onSegmentLeave"/>
|
|
26
|
+
</FluxTooltip>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script
|
|
32
|
+
lang="ts"
|
|
33
|
+
setup>
|
|
34
|
+
import { formatPercentage } from '@basmilius/utils';
|
|
35
|
+
import { FluxIcon, FluxTooltip } from '@flux-ui/components';
|
|
36
|
+
import type { FluxStatisticsChartColor, FluxStatisticsPercentageBarItemObject } from '@flux-ui/types';
|
|
37
|
+
import { clsx } from 'clsx';
|
|
38
|
+
import { computed, inject, watchEffect } from 'vue';
|
|
39
|
+
import { FluxStatisticsChartLegendInjectionKey, type ChartLegendItem } from '~flux/statistics/composable';
|
|
40
|
+
import $style from '~flux/statistics/css/PercentageBar.module.scss';
|
|
41
|
+
|
|
42
|
+
const SEMANTIC_COLORS = ['gray', 'primary', 'danger', 'info', 'success', 'warning'] as const;
|
|
43
|
+
|
|
44
|
+
const props = defineProps<{
|
|
45
|
+
readonly items: FluxStatisticsPercentageBarItemObject[];
|
|
46
|
+
}>();
|
|
47
|
+
|
|
48
|
+
const legendContext = inject(FluxStatisticsChartLegendInjectionKey, null);
|
|
49
|
+
|
|
50
|
+
const legendItems = computed<ChartLegendItem[]>(() =>
|
|
51
|
+
props.items.map(item => ({
|
|
52
|
+
color: resolveColor(item.color),
|
|
53
|
+
icon: item.icon,
|
|
54
|
+
label: item.label,
|
|
55
|
+
value: item.displayValue
|
|
56
|
+
}))
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const hoveredIndex = computed<number | null>(() => legendContext?.hoveredIndex.value ?? null);
|
|
60
|
+
|
|
61
|
+
watchEffect(() => {
|
|
62
|
+
if (legendContext) {
|
|
63
|
+
legendContext.items.value = legendItems.value;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
function resolveColor(color?: FluxStatisticsChartColor): string | undefined {
|
|
68
|
+
if (!color) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (SEMANTIC_COLORS.includes(color as typeof SEMANTIC_COLORS[number])) {
|
|
73
|
+
return `var(--${color}-600)`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return color;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function onSegmentEnter(index: number): void {
|
|
80
|
+
if (legendContext) {
|
|
81
|
+
legendContext.hoveredIndex.value = index;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function onSegmentLeave(): void {
|
|
86
|
+
if (legendContext) {
|
|
87
|
+
legendContext.hoveredIndex.value = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
</script>
|
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Chart
|
|
3
|
-
|
|
4
|
-
:options="
|
|
5
|
-
chart: {
|
|
6
|
-
type: 'pie'
|
|
7
|
-
},
|
|
8
|
-
legend: {
|
|
9
|
-
show: false
|
|
10
|
-
},
|
|
11
|
-
tooltip: {
|
|
12
|
-
enabled: false
|
|
13
|
-
}
|
|
14
|
-
}, options)"
|
|
15
|
-
:series="series"/>
|
|
3
|
+
ref="chartRef"
|
|
4
|
+
:options="mergedOptions"/>
|
|
16
5
|
</template>
|
|
17
6
|
|
|
18
7
|
<script
|
|
19
8
|
lang="ts"
|
|
20
9
|
setup>
|
|
21
|
-
import type {
|
|
22
|
-
import {
|
|
10
|
+
import type { FluxStatisticsChartPieSlice } from '@flux-ui/types';
|
|
11
|
+
import { computed } from 'vue';
|
|
12
|
+
import { useChartSlicesSetup, type EChartsOption } from '~flux/statistics/composable';
|
|
13
|
+
import { buildPieChartOptions, type ChartTooltipValueFormatter } from '~flux/statistics/util';
|
|
23
14
|
import Chart from './FluxStatisticsChart.vue';
|
|
15
|
+
import $style from '~flux/statistics/css/Chart.module.scss';
|
|
24
16
|
|
|
25
17
|
const {
|
|
26
|
-
|
|
18
|
+
advancedOptions,
|
|
19
|
+
slices,
|
|
20
|
+
title,
|
|
21
|
+
tooltip = false,
|
|
22
|
+
tooltipValueFormatter
|
|
27
23
|
} = defineProps<{
|
|
28
|
-
readonly
|
|
29
|
-
readonly
|
|
30
|
-
readonly
|
|
24
|
+
readonly advancedOptions?: EChartsOption;
|
|
25
|
+
readonly slices: readonly FluxStatisticsChartPieSlice[];
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
readonly tooltip?: boolean;
|
|
28
|
+
readonly tooltipValueFormatter?: ChartTooltipValueFormatter;
|
|
31
29
|
}>();
|
|
30
|
+
|
|
31
|
+
const { t, palette, tooltipItems } = useChartSlicesSetup(() => slices);
|
|
32
|
+
|
|
33
|
+
const mergedOptions = computed(() => buildPieChartOptions({
|
|
34
|
+
slices,
|
|
35
|
+
palette: palette.value,
|
|
36
|
+
tooltipItems: tooltipItems.value,
|
|
37
|
+
title,
|
|
38
|
+
t,
|
|
39
|
+
styles: $style,
|
|
40
|
+
tooltip,
|
|
41
|
+
tooltipValueFormatter,
|
|
42
|
+
advancedOptions
|
|
43
|
+
}));
|
|
32
44
|
</script>
|