/
utils.ts
145 lines (127 loc) Β· 3.5 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { isProxy, toRaw, version } from 'vue'
import type {
Chart,
ChartType,
ChartData,
ChartDataset,
ChartOptions,
DefaultDataPoint
} from 'chart.js'
export const compatProps =
version[0] === '2'
? <I extends {}, T extends {}>(internals: I, props: T) =>
Object.assign(internals, { attrs: props }) as unknown as I & T
: <I extends {}, T extends {}>(internals: I, props: T) =>
Object.assign(internals, props)
export function toRawIfProxy<T>(obj: T) {
return isProxy(obj) ? toRaw(obj) : obj
}
export function cloneProxy<T extends object>(obj: T, src = obj) {
return isProxy(src) ? new Proxy(obj, {}) : obj
}
export function setOptions<
TType extends ChartType = ChartType,
TData = DefaultDataPoint<TType>,
TLabel = unknown
>(chart: Chart<TType, TData, TLabel>, nextOptions: ChartOptions<TType>) {
const options = chart.options
if (options && nextOptions) {
Object.assign(options, nextOptions)
}
}
export function setLabels<
TType extends ChartType = ChartType,
TData = DefaultDataPoint<TType>,
TLabel = unknown
>(
currentData: ChartData<TType, TData, TLabel>,
nextLabels: TLabel[] | undefined
) {
currentData.labels = nextLabels
}
export function setDatasets<
TType extends ChartType = ChartType,
TData = DefaultDataPoint<TType>,
TLabel = unknown
>(
currentData: ChartData<TType, TData, TLabel>,
nextDatasets: ChartDataset<TType, TData>[],
datasetIdKey: string
) {
const addedDatasets: ChartDataset<TType, TData>[] = []
currentData.datasets = nextDatasets.map(
(nextDataset: Record<string, unknown>) => {
// given the new set, find it's current match
const currentDataset = currentData.datasets.find(
(dataset: Record<string, unknown>) =>
dataset[datasetIdKey] === nextDataset[datasetIdKey]
)
// There is no original to update, so simply add new one
if (
!currentDataset ||
!nextDataset.data ||
addedDatasets.includes(currentDataset)
) {
return { ...nextDataset } as ChartDataset<TType, TData>
}
addedDatasets.push(currentDataset)
Object.assign(currentDataset, nextDataset)
return currentDataset
}
)
}
export function cloneData<
TType extends ChartType = ChartType,
TData = DefaultDataPoint<TType>,
TLabel = unknown
>(data: ChartData<TType, TData, TLabel>, datasetIdKey: string) {
const nextData: ChartData<TType, TData, TLabel> = {
labels: [],
datasets: []
}
setLabels(nextData, data.labels)
setDatasets(nextData, data.datasets, datasetIdKey)
return nextData
}
/**
* Get dataset from mouse click event
* @param chart - Chart.js instance
* @param event - Mouse click event
* @returns Dataset
*/
export function getDatasetAtEvent(chart: Chart, event: MouseEvent) {
return chart.getElementsAtEventForMode(
event,
'dataset',
{ intersect: true },
false
)
}
/**
* Get single dataset element from mouse click event
* @param chart - Chart.js instance
* @param event - Mouse click event
* @returns Dataset
*/
export function getElementAtEvent(chart: Chart, event: MouseEvent) {
return chart.getElementsAtEventForMode(
event,
'nearest',
{ intersect: true },
false
)
}
/**
* Get all dataset elements from mouse click event
* @param chart - Chart.js instance
* @param event - Mouse click event
* @returns Dataset
*/
export function getElementsAtEvent(chart: Chart, event: MouseEvent) {
return chart.getElementsAtEventForMode(
event,
'index',
{ intersect: true },
false
)
}