@mozaic-ds/chart 0.1.0-beta.3 → 0.1.0-beta.30
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/dist/mozaic-chart.js +4453 -2623
- package/dist/mozaic-chart.umd.cjs +17 -11
- package/dist/style.css +1 -1
- package/package.json +25 -10
- package/src/assets/base.css +1 -1
- package/src/assets/img/bubbles.svg +4 -0
- package/src/components/bar/BarChart.stories.ts +105 -103
- package/src/components/bar/BarChart.vue +257 -131
- package/src/components/bar/index.ts +3 -3
- package/src/components/bubble/BubbleChart.stories.ts +66 -0
- package/src/components/bubble/BubbleChart.vue +363 -0
- package/src/components/bubble/index.ts +8 -0
- package/src/components/doughnut/DoughnutChart.stories.ts +38 -36
- package/src/components/doughnut/DoughnutChart.vue +210 -111
- package/src/components/doughnut/index.ts +3 -3
- package/src/components/index.ts +4 -4
- package/src/components/line/LineChart.stories.ts +52 -27
- package/src/components/line/LineChart.vue +346 -254
- package/src/components/line/index.ts +3 -3
- package/src/components/mixed/MixedBarLineChart.stories.ts +91 -0
- package/src/components/mixed/MixedBarLineChart.vue +413 -0
- package/src/components/mixed/index.ts +8 -0
- package/src/components/radar/RadarChart.stories.ts +102 -102
- package/src/components/radar/RadarChart.vue +204 -165
- package/src/components/radar/index.ts +3 -3
- package/src/main.ts +14 -4
- package/src/plugin.ts +10 -8
- package/src/services/BarChartFunctions.ts +136 -35
- package/src/services/BubbleTooltipService.ts +67 -0
- package/src/services/ChartsCommonLegend.ts +309 -137
- package/src/services/ColorFunctions.ts +1 -1
- package/src/services/DoughnutChartFunctions.ts +132 -55
- package/src/services/FormatUtilities.ts +28 -14
- package/src/services/GenericTooltipService.ts +140 -65
- package/src/services/MixedBarLineFunctions.ts +262 -0
- package/src/services/PatternFunctions.ts +25 -18
- package/src/services/RadarChartFunctions.ts +33 -12
- package/src/services/patterns/ChartDesign.ts +35 -24
- package/src/services/patterns/patternCircles.ts +63 -36
- package/src/services/patterns/patternDashedDiagonals.ts +64 -57
- package/src/services/patterns/patternDiagonals.ts +138 -106
- package/src/services/patterns/patternSquares.ts +86 -80
- package/src/services/patterns/patternVerticalLines.ts +76 -69
- package/src/services/patterns/patternZigzag.ts +92 -85
- package/src/stories/Changelog.mdx +6 -0
- package/src/stories/Contributing.mdx +101 -0
- package/src/stories/GettingStarted.mdx +92 -0
- package/src/stories/SupportAndOnboarding.mdx +44 -0
- package/src/types/AxisDefinition.ts +4 -0
- package/src/types/BarData.ts +1 -0
- package/src/types/Chart.ts +9 -7
- package/src/types/DoughnutData.ts +8 -0
- package/src/types/GenericData.ts +10 -10
- package/src/types/LineChart.ts +4 -4
- package/src/types/MixedBarLineData.ts +7 -0
- package/src/types/RadarData.ts +33 -29
- package/src/types/TooltipChartType.ts +7 -6
- package/src/vite-env.d.ts +3 -3
- package/src/App.vue +0 -80
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Ref } from 'vue';
|
|
2
|
-
import type { HTMLLegendPlugin } from
|
|
2
|
+
import type { HTMLLegendPlugin } from '../types/Chart';
|
|
3
3
|
import type { ChartOptions } from 'chart.js';
|
|
4
4
|
import PatternFunctions from './PatternFunctions';
|
|
5
5
|
import { formatValueAndRate } from './FormatUtilities';
|
|
@@ -9,87 +9,151 @@ const { getPatternCanvas } = PatternFunctions();
|
|
|
9
9
|
|
|
10
10
|
export const LEGEND_FONT_SIZE = 14;
|
|
11
11
|
export const LEGEND_LABEL_LEFT_MARGIN = '6px';
|
|
12
|
-
export const LEGEND_BOX_SIZE =
|
|
12
|
+
export const LEGEND_BOX_SIZE = '22px';
|
|
13
13
|
export const LEGEND_BOX_POINT_SIZE = 6;
|
|
14
|
+
export const LEGEND_BOX_BORDER = '2px';
|
|
14
15
|
|
|
15
16
|
export interface Chart {
|
|
16
|
-
update
|
|
17
|
+
update(): void;
|
|
17
18
|
|
|
18
|
-
toggleDataVisibility
|
|
19
|
+
toggleDataVisibility(datasetIndex: number): void;
|
|
19
20
|
|
|
20
|
-
isDatasetVisible
|
|
21
|
+
isDatasetVisible(datasetIndex: number): boolean;
|
|
21
22
|
|
|
22
23
|
getDataVisibility(index: number): boolean;
|
|
23
24
|
|
|
24
|
-
setDatasetVisibility
|
|
25
|
+
setDatasetVisibility(datasetIndex: number, visible: boolean): void;
|
|
25
26
|
|
|
26
|
-
plugins: HTMLLegendPlugin
|
|
27
|
+
plugins: HTMLLegendPlugin;
|
|
27
28
|
|
|
28
|
-
options:
|
|
29
|
+
options:
|
|
30
|
+
| ChartOptions<'radar'>
|
|
31
|
+
| ChartOptions<'doughnut'>
|
|
32
|
+
| ChartOptions<'bar'>
|
|
33
|
+
| ChartOptions<'line'>;
|
|
29
34
|
|
|
30
|
-
config: {
|
|
35
|
+
config: {
|
|
36
|
+
type?: string;
|
|
37
|
+
data: { labels: string[]; datasets: unknown[]; data?: unknown[] };
|
|
38
|
+
};
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
export interface ChartItem {
|
|
34
|
-
fontColor: string
|
|
35
|
-
hidden: boolean
|
|
36
|
-
text: string
|
|
37
|
-
fillStyle: string
|
|
38
|
-
strokeStyle: string
|
|
39
|
-
lineWidth: number
|
|
40
|
-
datasetIndex: number
|
|
41
|
-
index: number
|
|
42
|
+
fontColor: string;
|
|
43
|
+
hidden: boolean;
|
|
44
|
+
text: string;
|
|
45
|
+
fillStyle: string;
|
|
46
|
+
strokeStyle: string;
|
|
47
|
+
lineWidth: number;
|
|
48
|
+
datasetIndex: number;
|
|
49
|
+
index: number;
|
|
50
|
+
lineCap?: string;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
export function getHtmlLegendPlugin(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
export function getHtmlLegendPlugin(
|
|
54
|
+
legendContainer: Ref,
|
|
55
|
+
selectMode: Ref<boolean>,
|
|
56
|
+
onHoverIndex: any,
|
|
57
|
+
disableAccessibility: Ref<boolean>,
|
|
58
|
+
patternsColors: Ref<string[]>,
|
|
59
|
+
patternsList: Ref<
|
|
60
|
+
((
|
|
61
|
+
hover: boolean,
|
|
62
|
+
color: string,
|
|
63
|
+
disableAccessibility: boolean
|
|
64
|
+
) => CanvasPattern)[]
|
|
65
|
+
>,
|
|
66
|
+
enableHoverFeature: Ref<boolean>,
|
|
67
|
+
maxValueToDisplay?: number,
|
|
68
|
+
chartData?: any
|
|
69
|
+
): HTMLLegendPlugin {
|
|
70
|
+
return {
|
|
71
|
+
id: 'htmlLegend',
|
|
72
|
+
afterUpdate(chart: any) {
|
|
73
|
+
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
74
|
+
const flexDirection = isDoughnut ? 'column' : 'row';
|
|
75
|
+
const ul: HTMLLIElement = getOrCreateLegendList(
|
|
76
|
+
legendContainer,
|
|
77
|
+
flexDirection
|
|
78
|
+
);
|
|
79
|
+
ul.style.margin = '1.375rem 1.0625rem';
|
|
80
|
+
while (ul.firstChild) {
|
|
81
|
+
ul.firstChild.remove();
|
|
82
|
+
}
|
|
83
|
+
const items: ChartItem[] =
|
|
84
|
+
chart.options.plugins.legend.labels.generateLabels(chart);
|
|
85
|
+
items.forEach((item: ChartItem): void => {
|
|
48
86
|
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const isOthersElement: boolean = index + 1 === maxValueToDisplay ? true : false;
|
|
62
|
-
li.style.marginTop = '12px';
|
|
63
|
-
if (isOthersElement) {
|
|
64
|
-
li.style.position = 'relative';
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
li.style.marginRight = '12px'
|
|
68
|
-
}
|
|
69
|
-
li.style.width = 'max-content';
|
|
70
|
-
li.style.cursor = 'pointer';
|
|
71
|
-
let liContent: HTMLElement;
|
|
72
|
-
if (!selectMode.value) {
|
|
73
|
-
liContent = createLegendElementWithPatterns(item, chart, onHoverIndex, disableAccessibility.value, patternsColors.value, patternsList.value);
|
|
74
|
-
} else {
|
|
75
|
-
liContent = createLegendElementWithCheckbox(chart, item, selectMode, onHoverIndex, disableAccessibility.value);
|
|
76
|
-
}
|
|
77
|
-
li.appendChild(liContent);
|
|
78
|
-
li.appendChild(createHtmlLegendItemText(item));
|
|
79
|
-
if (isDoughnut && maxValueToDisplay && hasOthersTooltipToDisplay(chartData, maxValueToDisplay, index)) {
|
|
80
|
-
li.appendChild(createTooltipAndItsIcon(chartData, maxValueToDisplay));
|
|
87
|
+
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
88
|
+
const li: HTMLElement = createHtmlLegendListElement(
|
|
89
|
+
chart,
|
|
90
|
+
selectMode,
|
|
91
|
+
index
|
|
92
|
+
);
|
|
93
|
+
if (isDoughnut) {
|
|
94
|
+
const isOthersElement: boolean =
|
|
95
|
+
index + 1 === maxValueToDisplay ? true : false;
|
|
96
|
+
li.style.marginTop = '12px';
|
|
97
|
+
if (isOthersElement) {
|
|
98
|
+
li.style.position = 'relative';
|
|
81
99
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
} else {
|
|
101
|
+
li.style.marginRight = '10px';
|
|
102
|
+
}
|
|
103
|
+
li.style.width = 'max-content';
|
|
104
|
+
li.style.cursor = 'pointer';
|
|
105
|
+
let liContent: HTMLElement;
|
|
106
|
+
if (!selectMode.value) {
|
|
107
|
+
liContent = createLegendElementWithPatterns(
|
|
108
|
+
item,
|
|
109
|
+
chart,
|
|
110
|
+
onHoverIndex,
|
|
111
|
+
disableAccessibility.value,
|
|
112
|
+
patternsColors.value,
|
|
113
|
+
patternsList.value,
|
|
114
|
+
enableHoverFeature.value
|
|
115
|
+
);
|
|
116
|
+
} else {
|
|
117
|
+
liContent = createLegendElementWithCheckbox(
|
|
118
|
+
chart,
|
|
119
|
+
item,
|
|
120
|
+
selectMode,
|
|
121
|
+
onHoverIndex,
|
|
122
|
+
patternsColors.value,
|
|
123
|
+
enableHoverFeature.value
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
liContent.style.boxSizing = 'border-box';
|
|
127
|
+
li.appendChild(liContent);
|
|
128
|
+
li.appendChild(createHtmlLegendItemText(item));
|
|
129
|
+
if (
|
|
130
|
+
isDoughnut &&
|
|
131
|
+
maxValueToDisplay &&
|
|
132
|
+
hasOthersTooltipToDisplay(chartData, maxValueToDisplay, index)
|
|
133
|
+
) {
|
|
134
|
+
li.appendChild(createTooltipAndItsIcon(chartData, maxValueToDisplay));
|
|
135
|
+
}
|
|
136
|
+
ul.appendChild(li);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
};
|
|
86
140
|
}
|
|
87
141
|
|
|
88
|
-
export function hasOthersTooltipToDisplay
|
|
89
|
-
|
|
142
|
+
export function hasOthersTooltipToDisplay(
|
|
143
|
+
doughnutData: any,
|
|
144
|
+
maxValueToDisplay: number,
|
|
145
|
+
index: number
|
|
146
|
+
) {
|
|
147
|
+
return (
|
|
148
|
+
doughnutData.data.length > maxValueToDisplay &&
|
|
149
|
+
index === maxValueToDisplay - 1
|
|
150
|
+
);
|
|
90
151
|
}
|
|
91
152
|
|
|
92
|
-
export function createTooltipAndItsIcon
|
|
153
|
+
export function createTooltipAndItsIcon(
|
|
154
|
+
doughnutData: any,
|
|
155
|
+
maxValueToDisplay: number
|
|
156
|
+
): HTMLDivElement {
|
|
93
157
|
const iconTopWrapper = document.createElement('div');
|
|
94
158
|
const iconWrapper = document.createElement('div');
|
|
95
159
|
const icon = document.createElement('img');
|
|
@@ -98,22 +162,29 @@ export function createTooltipAndItsIcon (doughnutData: any, maxValueToDisplay: n
|
|
|
98
162
|
icon.src = QuestionMarkSvg;
|
|
99
163
|
icon.style.top = '0';
|
|
100
164
|
icon.style.width = '1.5rem';
|
|
101
|
-
icon.style.filter =
|
|
165
|
+
icon.style.filter =
|
|
166
|
+
'invert(38%) sepia(19%) saturate(18%) hue-rotate(337deg) brightness(97%) contrast(85%)';
|
|
102
167
|
iconWrapper.style.position = 'relative';
|
|
103
168
|
iconWrapper.style.display = 'flex';
|
|
104
169
|
const tooltip = createLegendOthersTooltip(doughnutData, maxValueToDisplay);
|
|
105
170
|
icon.onmouseover = () => {
|
|
106
171
|
(iconWrapper.firstElementChild as HTMLElement).style.visibility = 'visible';
|
|
107
172
|
};
|
|
173
|
+
icon.onmouseleave = () => {
|
|
174
|
+
(iconWrapper.firstElementChild as HTMLElement).style.visibility = 'hidden';
|
|
175
|
+
};
|
|
108
176
|
iconTopWrapper.appendChild(iconWrapper);
|
|
109
177
|
iconWrapper.appendChild(tooltip);
|
|
110
178
|
iconWrapper.appendChild(icon);
|
|
111
179
|
return iconTopWrapper;
|
|
112
180
|
}
|
|
113
181
|
|
|
114
|
-
function createLegendOthersTooltip
|
|
182
|
+
function createLegendOthersTooltip(
|
|
183
|
+
doughnutData: any,
|
|
184
|
+
maxValueToDisplay: number
|
|
185
|
+
) {
|
|
115
186
|
const tooltip = document.createElement('div');
|
|
116
|
-
tooltip.style.visibility= 'hidden';
|
|
187
|
+
tooltip.style.visibility = 'hidden';
|
|
117
188
|
tooltip.style.position = 'absolute';
|
|
118
189
|
tooltip.style.zIndex = '10';
|
|
119
190
|
tooltip.style.width = '350px';
|
|
@@ -129,9 +200,13 @@ function createLegendOthersTooltip (doughnutData: any, maxValueToDisplay: number
|
|
|
129
200
|
return tooltip;
|
|
130
201
|
}
|
|
131
202
|
|
|
132
|
-
function addOthersTooltipLines
|
|
133
|
-
|
|
134
|
-
|
|
203
|
+
function addOthersTooltipLines(
|
|
204
|
+
doughnutData: any,
|
|
205
|
+
maxValueToDisplay: number,
|
|
206
|
+
tooltip: HTMLDivElement
|
|
207
|
+
) {
|
|
208
|
+
const startIndex = maxValueToDisplay - 1;
|
|
209
|
+
doughnutData.data.slice(startIndex).forEach((_ignore: any, index: number) => {
|
|
135
210
|
const dataIndex = startIndex + index;
|
|
136
211
|
const textWrapper = document.createElement('div');
|
|
137
212
|
textWrapper.style.display = 'flex';
|
|
@@ -141,65 +216,103 @@ doughnutData.data.slice(startIndex).forEach((_ignore: any, index: number) => {
|
|
|
141
216
|
const label = document.createElement('span');
|
|
142
217
|
label.appendChild(document.createTextNode(doughnutData.labels[dataIndex]));
|
|
143
218
|
const value = document.createElement('span');
|
|
144
|
-
value.appendChild(
|
|
219
|
+
value.appendChild(
|
|
220
|
+
document.createTextNode(formatValueAndRate(doughnutData, dataIndex))
|
|
221
|
+
);
|
|
145
222
|
textWrapper.appendChild(label);
|
|
146
223
|
textWrapper.appendChild(value);
|
|
147
224
|
tooltip.appendChild(textWrapper);
|
|
148
|
-
}
|
|
149
|
-
);
|
|
225
|
+
});
|
|
150
226
|
}
|
|
151
227
|
|
|
152
|
-
export function createLegendElementWithPatterns
|
|
153
|
-
|
|
154
|
-
:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
228
|
+
export function createLegendElementWithPatterns(
|
|
229
|
+
item: ChartItem,
|
|
230
|
+
chart: Chart,
|
|
231
|
+
onHoverIndex: any | null,
|
|
232
|
+
disableAccessibility: boolean,
|
|
233
|
+
patternsColors: string[],
|
|
234
|
+
patternsList: ((
|
|
235
|
+
hover: boolean,
|
|
236
|
+
color: string,
|
|
237
|
+
disableAccessibility: boolean
|
|
238
|
+
) => CanvasPattern)[],
|
|
239
|
+
enableHoverFeature: boolean
|
|
240
|
+
): HTMLElement {
|
|
241
|
+
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
242
|
+
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
243
|
+
const img: HTMLImageElement = new Image();
|
|
244
|
+
const boxSpan: HTMLElement = createHtmlLegendLine(item, chart.config.type);
|
|
245
|
+
const pattern: CanvasPattern = patternsList[index](
|
|
246
|
+
false,
|
|
247
|
+
patternsColors[index],
|
|
248
|
+
disableAccessibility
|
|
249
|
+
);
|
|
250
|
+
const patternCanvas: HTMLCanvasElement = getPatternCanvas(pattern);
|
|
251
|
+
img.src = patternCanvas.toDataURL();
|
|
252
|
+
boxSpan.style.background = `url(${img.src})`;
|
|
253
|
+
boxSpan.style.backgroundSize = 'cover';
|
|
254
|
+
boxSpan.style.borderColor = patternsColors[index];
|
|
255
|
+
boxSpan.style.borderWidth = LEGEND_BOX_BORDER;
|
|
256
|
+
|
|
257
|
+
if (enableHoverFeature) {
|
|
258
|
+
boxSpan.onmouseover = (): void => {
|
|
259
|
+
isDoughnut
|
|
260
|
+
? (onHoverIndex.value = index)
|
|
261
|
+
: (onHoverIndex.dataSetIndex = index);
|
|
169
262
|
};
|
|
170
263
|
boxSpan.onmouseleave = (): void => {
|
|
171
|
-
isDoughnut
|
|
264
|
+
isDoughnut
|
|
265
|
+
? (onHoverIndex.value = null)
|
|
266
|
+
: (onHoverIndex.dataSetIndex = -1);
|
|
172
267
|
};
|
|
173
|
-
|
|
268
|
+
}
|
|
269
|
+
return boxSpan;
|
|
174
270
|
}
|
|
175
271
|
|
|
176
|
-
export function createLegendElementWithCheckbox
|
|
177
|
-
|
|
272
|
+
export function createLegendElementWithCheckbox(
|
|
273
|
+
chart: Chart,
|
|
274
|
+
item: ChartItem,
|
|
275
|
+
selectMode: Ref<boolean>,
|
|
276
|
+
onHoverIndex: any | null,
|
|
277
|
+
patternsColors: string[],
|
|
278
|
+
enableHoverFeature: boolean
|
|
279
|
+
): HTMLElement {
|
|
178
280
|
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
179
281
|
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
180
|
-
const checkbox: HTMLElement = createLegendCheckbox(
|
|
282
|
+
const checkbox: HTMLElement = createLegendCheckbox(
|
|
283
|
+
chart,
|
|
284
|
+
item,
|
|
285
|
+
patternsColors
|
|
286
|
+
);
|
|
181
287
|
const labels = chart.config.data.labels;
|
|
182
|
-
const allCheckBoxesVisible: boolean =
|
|
183
|
-
|
|
288
|
+
const allCheckBoxesVisible: boolean = labels.every((_, index: number) =>
|
|
289
|
+
chart.getDataVisibility(index)
|
|
290
|
+
);
|
|
184
291
|
if (allCheckBoxesVisible) {
|
|
185
292
|
if (isDoughnut) {
|
|
186
|
-
onHoverIndex.value = -1;
|
|
187
293
|
selectMode.value = false;
|
|
188
|
-
|
|
189
|
-
onHoverIndex.dataSetIndex = -1;
|
|
294
|
+
onHoverIndex.value = -1;
|
|
190
295
|
}
|
|
191
296
|
return checkbox;
|
|
192
297
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
298
|
+
if (enableHoverFeature) {
|
|
299
|
+
checkbox.onmouseover = (): void => {
|
|
300
|
+
isDoughnut
|
|
301
|
+
? (onHoverIndex.value = index)
|
|
302
|
+
: (onHoverIndex.dataSetIndex = index);
|
|
303
|
+
chart.update();
|
|
304
|
+
};
|
|
305
|
+
checkbox.onmouseleave = (): void => {
|
|
306
|
+
isDoughnut
|
|
307
|
+
? (onHoverIndex.value = null)
|
|
308
|
+
: (onHoverIndex.dataSetIndex = -1);
|
|
309
|
+
chart.update();
|
|
310
|
+
};
|
|
311
|
+
}
|
|
199
312
|
return checkbox;
|
|
200
313
|
}
|
|
201
314
|
|
|
202
|
-
export function createHtmlLegendItemText
|
|
315
|
+
export function createHtmlLegendItemText(item: ChartItem) {
|
|
203
316
|
const textContainer = document.createElement('p');
|
|
204
317
|
textContainer.style.color = item.fontColor;
|
|
205
318
|
textContainer.style.fontSize = `${LEGEND_FONT_SIZE}px`;
|
|
@@ -211,37 +324,43 @@ export function createHtmlLegendItemText (item: ChartItem) {
|
|
|
211
324
|
return textContainer;
|
|
212
325
|
}
|
|
213
326
|
|
|
214
|
-
export function createHtmlLegendLine
|
|
327
|
+
export function createHtmlLegendLine(
|
|
328
|
+
item: ChartItem,
|
|
329
|
+
type: string | undefined
|
|
330
|
+
) {
|
|
215
331
|
const boxSpan = document.createElement('div');
|
|
216
332
|
if (type !== 'doughnut') {
|
|
217
|
-
boxSpan.style.background =
|
|
333
|
+
boxSpan.style.background = 'rgba(0, 0, 0, 0.1)';
|
|
218
334
|
boxSpan.style.borderColor = item.strokeStyle;
|
|
219
|
-
boxSpan.style.borderWidth =
|
|
335
|
+
boxSpan.style.borderWidth = LEGEND_BOX_BORDER;
|
|
220
336
|
}
|
|
221
337
|
boxSpan.style.borderRadius = '5px';
|
|
222
338
|
boxSpan.style.borderStyle = 'solid';
|
|
223
339
|
boxSpan.style.display = 'flex';
|
|
224
340
|
boxSpan.style.justifyContent = 'center';
|
|
225
341
|
boxSpan.style.alignItems = 'center';
|
|
226
|
-
boxSpan.style.
|
|
342
|
+
boxSpan.style.minWidth = LEGEND_BOX_SIZE;
|
|
227
343
|
boxSpan.style.marginRight = LEGEND_LABEL_LEFT_MARGIN;
|
|
228
|
-
boxSpan.style.
|
|
344
|
+
boxSpan.style.minHeight = LEGEND_BOX_SIZE;
|
|
229
345
|
return boxSpan;
|
|
230
346
|
}
|
|
231
347
|
|
|
232
|
-
export function createHtmlLegendDatasetSquare
|
|
348
|
+
export function createHtmlLegendDatasetSquare(item: ChartItem) {
|
|
233
349
|
const divPoint = document.createElement('div');
|
|
234
350
|
divPoint.style.height = LEGEND_BOX_POINT_SIZE + 'px';
|
|
235
351
|
divPoint.style.width = LEGEND_BOX_POINT_SIZE + 'px';
|
|
236
352
|
divPoint.style.background = 'white';
|
|
237
353
|
divPoint.style.borderStyle = 'solid';
|
|
238
354
|
divPoint.style.borderColor = item.strokeStyle;
|
|
239
|
-
divPoint.style.borderWidth =
|
|
355
|
+
divPoint.style.borderWidth = LEGEND_BOX_BORDER;
|
|
240
356
|
return divPoint;
|
|
241
357
|
}
|
|
242
358
|
|
|
243
|
-
export function createHtmlLegendListElement
|
|
244
|
-
|
|
359
|
+
export function createHtmlLegendListElement(
|
|
360
|
+
chart: Chart,
|
|
361
|
+
selectMode: Ref,
|
|
362
|
+
elementIndex: number
|
|
363
|
+
) {
|
|
245
364
|
const li: HTMLElement = document.createElement('li');
|
|
246
365
|
li.style.alignItems = 'center';
|
|
247
366
|
li.style.cursor = selectMode.value ? '' : 'pointer';
|
|
@@ -259,39 +378,57 @@ export function createHtmlLegendListElement
|
|
|
259
378
|
return li;
|
|
260
379
|
}
|
|
261
380
|
|
|
262
|
-
export function addCheckboxStyle
|
|
381
|
+
export function addCheckboxStyle(
|
|
382
|
+
isDataSetVisible: boolean,
|
|
383
|
+
item: ChartItem,
|
|
384
|
+
checkbox: Element,
|
|
385
|
+
patternColor: string
|
|
386
|
+
) {
|
|
263
387
|
let backgroundColor = '#fff';
|
|
264
388
|
let borderColor = '#666';
|
|
265
389
|
if (isDataSetVisible) {
|
|
266
|
-
|
|
267
|
-
|
|
390
|
+
//Default white for patterns chart
|
|
391
|
+
backgroundColor = isDefaultWhiteColor(item.strokeStyle)
|
|
392
|
+
? patternColor
|
|
393
|
+
: item.strokeStyle;
|
|
394
|
+
borderColor = isDefaultWhiteColor(item.strokeStyle)
|
|
395
|
+
? patternColor
|
|
396
|
+
: item.strokeStyle;
|
|
397
|
+
checkbox.setAttribute('checked', '' + isDataSetVisible);
|
|
268
398
|
}
|
|
269
|
-
checkbox.setAttribute('checked', '' + isDataSetVisible);
|
|
270
399
|
checkbox.setAttribute('class', 'mc-checkbox__input');
|
|
271
|
-
checkbox.setAttribute(
|
|
272
|
-
|
|
273
|
-
|
|
400
|
+
checkbox.setAttribute(
|
|
401
|
+
'style',
|
|
402
|
+
`background-color: ${backgroundColor};
|
|
403
|
+
min-width: ${LEGEND_BOX_SIZE};
|
|
404
|
+
min-height: ${LEGEND_BOX_SIZE};
|
|
274
405
|
margin-right: ${LEGEND_LABEL_LEFT_MARGIN};
|
|
275
|
-
border-color: ${borderColor};`
|
|
406
|
+
border-color: ${borderColor};`
|
|
407
|
+
);
|
|
276
408
|
}
|
|
277
409
|
|
|
278
|
-
export function createLegendCheckbox
|
|
410
|
+
export function createLegendCheckbox(
|
|
411
|
+
chart: Chart,
|
|
412
|
+
item: ChartItem,
|
|
413
|
+
patternsColors: string[]
|
|
414
|
+
) {
|
|
279
415
|
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
280
416
|
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
281
417
|
const checkbox = document.createElement('input');
|
|
282
418
|
checkbox.setAttribute('type', 'checkbox');
|
|
283
419
|
checkbox.setAttribute('data-test-id', `legend-checkbox-${index}`);
|
|
284
|
-
const isDataSetVisible =
|
|
285
|
-
|
|
420
|
+
const isDataSetVisible = isChartDataVisible(chart, index);
|
|
421
|
+
const patternColor = patternsColors ? patternsColors[index] : undefined;
|
|
422
|
+
addCheckboxStyle(isDataSetVisible, item, checkbox, patternColor as string);
|
|
286
423
|
return checkbox;
|
|
287
424
|
}
|
|
288
425
|
|
|
289
|
-
function isMonoDataSetChart
|
|
426
|
+
function isMonoDataSetChart(chart: Chart) {
|
|
290
427
|
const { type } = chart.config;
|
|
291
428
|
return type === 'pie' || type === 'doughnut';
|
|
292
429
|
}
|
|
293
430
|
|
|
294
|
-
function getChartsData
|
|
431
|
+
function getChartsData(chart: any) {
|
|
295
432
|
let dataSets: unknown[] = chart.config.data.datasets;
|
|
296
433
|
if (isMonoDataSetChart(chart)) {
|
|
297
434
|
dataSets = chart.config.data.datasets[0].data;
|
|
@@ -299,7 +436,11 @@ function getChartsData (chart: any) {
|
|
|
299
436
|
return dataSets;
|
|
300
437
|
}
|
|
301
438
|
|
|
302
|
-
export function hideAllButThis
|
|
439
|
+
export function hideAllButThis(
|
|
440
|
+
chart: Chart,
|
|
441
|
+
elementIndex: number,
|
|
442
|
+
selectMode: Ref
|
|
443
|
+
) {
|
|
303
444
|
if (!selectMode.value) {
|
|
304
445
|
const dataSets: unknown[] = getChartsData(chart);
|
|
305
446
|
selectMode.value = true;
|
|
@@ -311,43 +452,70 @@ export function hideAllButThis (chart: Chart, elementIndex: number, selectMode:
|
|
|
311
452
|
}
|
|
312
453
|
}
|
|
313
454
|
|
|
314
|
-
function allDataVisible
|
|
455
|
+
function allDataVisible(chart: Chart): boolean {
|
|
315
456
|
let allVisible = true;
|
|
316
457
|
const chartsData: unknown[] = getChartsData(chart);
|
|
317
458
|
chartsData.forEach((_data, dataIndex) => {
|
|
318
|
-
allVisible = allVisible && chart
|
|
459
|
+
allVisible = allVisible && isChartDataVisible(chart, dataIndex);
|
|
319
460
|
});
|
|
320
461
|
return allVisible;
|
|
321
462
|
}
|
|
322
463
|
|
|
323
|
-
|
|
464
|
+
function isChartDataVisible(chart: Chart, dataIndex: number): boolean {
|
|
465
|
+
if (isMonoDataSetChart(chart)) {
|
|
466
|
+
return chart.getDataVisibility(dataIndex);
|
|
467
|
+
} else {
|
|
468
|
+
return chart.isDatasetVisible(dataIndex);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export function switchItemVisibility(
|
|
473
|
+
chart: Chart,
|
|
474
|
+
elementIndex: number,
|
|
475
|
+
selectMode?: Ref
|
|
476
|
+
) {
|
|
324
477
|
if (isMonoDataSetChart(chart)) {
|
|
325
478
|
chart.toggleDataVisibility(elementIndex);
|
|
326
479
|
} else {
|
|
327
|
-
chart.setDatasetVisibility(
|
|
480
|
+
chart.setDatasetVisibility(
|
|
481
|
+
elementIndex,
|
|
482
|
+
!chart.isDatasetVisible(elementIndex)
|
|
483
|
+
);
|
|
328
484
|
}
|
|
485
|
+
|
|
329
486
|
if (selectMode && allDataVisible(chart)) {
|
|
330
487
|
selectMode.value = false;
|
|
331
488
|
}
|
|
332
489
|
chart.update();
|
|
333
490
|
}
|
|
334
491
|
|
|
335
|
-
|
|
336
|
-
|
|
492
|
+
export function createLegendElementWithSquareArea(
|
|
493
|
+
item: ChartItem,
|
|
494
|
+
mainSerieFirstDataset?: boolean
|
|
495
|
+
) {
|
|
337
496
|
const liContent = createHtmlLegendLine(item, '');
|
|
338
497
|
const divPoint = createHtmlLegendDatasetSquare(item);
|
|
339
498
|
const index = item.index || item.datasetIndex;
|
|
340
|
-
|
|
341
|
-
|
|
499
|
+
|
|
500
|
+
divPoint.style.width = '10px';
|
|
501
|
+
divPoint.style.height = '10px';
|
|
502
|
+
if (index % 2 === 0) {
|
|
503
|
+
mainSerieFirstDataset
|
|
504
|
+
? (divPoint.style.borderRadius = '25px')
|
|
505
|
+
: (divPoint.style.transform = 'rotate(45deg)');
|
|
342
506
|
} else {
|
|
343
|
-
mainSerieFirstDataset
|
|
507
|
+
mainSerieFirstDataset
|
|
508
|
+
? (divPoint.style.transform = 'rotate(45deg)')
|
|
509
|
+
: (divPoint.style.borderRadius = '25px');
|
|
344
510
|
}
|
|
345
511
|
liContent.appendChild(divPoint);
|
|
346
512
|
return liContent;
|
|
347
513
|
}
|
|
348
514
|
|
|
349
|
-
|
|
350
|
-
|
|
515
|
+
export function getOrCreateLegendList(
|
|
516
|
+
legendContainer: Ref,
|
|
517
|
+
flexDirection: string
|
|
518
|
+
) {
|
|
351
519
|
let listContainer = legendContainer.value?.querySelector('ul');
|
|
352
520
|
if (!listContainer) {
|
|
353
521
|
listContainer = document.createElement('ul');
|
|
@@ -359,3 +527,7 @@ export function getOrCreateLegendList (legendContainer: Ref, flexDirection: stri
|
|
|
359
527
|
}
|
|
360
528
|
return listContainer;
|
|
361
529
|
}
|
|
530
|
+
|
|
531
|
+
function isDefaultWhiteColor(color: string) {
|
|
532
|
+
return color === '#00000000';
|
|
533
|
+
}
|