@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.
Files changed (59) hide show
  1. package/dist/mozaic-chart.js +4453 -2623
  2. package/dist/mozaic-chart.umd.cjs +17 -11
  3. package/dist/style.css +1 -1
  4. package/package.json +25 -10
  5. package/src/assets/base.css +1 -1
  6. package/src/assets/img/bubbles.svg +4 -0
  7. package/src/components/bar/BarChart.stories.ts +105 -103
  8. package/src/components/bar/BarChart.vue +257 -131
  9. package/src/components/bar/index.ts +3 -3
  10. package/src/components/bubble/BubbleChart.stories.ts +66 -0
  11. package/src/components/bubble/BubbleChart.vue +363 -0
  12. package/src/components/bubble/index.ts +8 -0
  13. package/src/components/doughnut/DoughnutChart.stories.ts +38 -36
  14. package/src/components/doughnut/DoughnutChart.vue +210 -111
  15. package/src/components/doughnut/index.ts +3 -3
  16. package/src/components/index.ts +4 -4
  17. package/src/components/line/LineChart.stories.ts +52 -27
  18. package/src/components/line/LineChart.vue +346 -254
  19. package/src/components/line/index.ts +3 -3
  20. package/src/components/mixed/MixedBarLineChart.stories.ts +91 -0
  21. package/src/components/mixed/MixedBarLineChart.vue +413 -0
  22. package/src/components/mixed/index.ts +8 -0
  23. package/src/components/radar/RadarChart.stories.ts +102 -102
  24. package/src/components/radar/RadarChart.vue +204 -165
  25. package/src/components/radar/index.ts +3 -3
  26. package/src/main.ts +14 -4
  27. package/src/plugin.ts +10 -8
  28. package/src/services/BarChartFunctions.ts +136 -35
  29. package/src/services/BubbleTooltipService.ts +67 -0
  30. package/src/services/ChartsCommonLegend.ts +309 -137
  31. package/src/services/ColorFunctions.ts +1 -1
  32. package/src/services/DoughnutChartFunctions.ts +132 -55
  33. package/src/services/FormatUtilities.ts +28 -14
  34. package/src/services/GenericTooltipService.ts +140 -65
  35. package/src/services/MixedBarLineFunctions.ts +262 -0
  36. package/src/services/PatternFunctions.ts +25 -18
  37. package/src/services/RadarChartFunctions.ts +33 -12
  38. package/src/services/patterns/ChartDesign.ts +35 -24
  39. package/src/services/patterns/patternCircles.ts +63 -36
  40. package/src/services/patterns/patternDashedDiagonals.ts +64 -57
  41. package/src/services/patterns/patternDiagonals.ts +138 -106
  42. package/src/services/patterns/patternSquares.ts +86 -80
  43. package/src/services/patterns/patternVerticalLines.ts +76 -69
  44. package/src/services/patterns/patternZigzag.ts +92 -85
  45. package/src/stories/Changelog.mdx +6 -0
  46. package/src/stories/Contributing.mdx +101 -0
  47. package/src/stories/GettingStarted.mdx +92 -0
  48. package/src/stories/SupportAndOnboarding.mdx +44 -0
  49. package/src/types/AxisDefinition.ts +4 -0
  50. package/src/types/BarData.ts +1 -0
  51. package/src/types/Chart.ts +9 -7
  52. package/src/types/DoughnutData.ts +8 -0
  53. package/src/types/GenericData.ts +10 -10
  54. package/src/types/LineChart.ts +4 -4
  55. package/src/types/MixedBarLineData.ts +7 -0
  56. package/src/types/RadarData.ts +33 -29
  57. package/src/types/TooltipChartType.ts +7 -6
  58. package/src/vite-env.d.ts +3 -3
  59. package/src/App.vue +0 -80
@@ -1,5 +1,5 @@
1
1
  import type { Ref } from 'vue';
2
- import type { HTMLLegendPlugin } from "../types/Chart";
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 = 18;
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 (): void;
17
+ update(): void;
17
18
 
18
- toggleDataVisibility (datasetIndex: number): void;
19
+ toggleDataVisibility(datasetIndex: number): void;
19
20
 
20
- isDatasetVisible (datasetIndex: number): boolean;
21
+ isDatasetVisible(datasetIndex: number): boolean;
21
22
 
22
23
  getDataVisibility(index: number): boolean;
23
24
 
24
- setDatasetVisibility (datasetIndex: number, visible: boolean): void;
25
+ setDatasetVisibility(datasetIndex: number, visible: boolean): void;
25
26
 
26
- plugins: HTMLLegendPlugin,
27
+ plugins: HTMLLegendPlugin;
27
28
 
28
- options: ChartOptions<'radar'> | ChartOptions<'doughnut'> | ChartOptions<'bar'> | ChartOptions<'line'>,
29
+ options:
30
+ | ChartOptions<'radar'>
31
+ | ChartOptions<'doughnut'>
32
+ | ChartOptions<'bar'>
33
+ | ChartOptions<'line'>;
29
34
 
30
- config: { type?: string, data: { labels: string[] ,datasets: unknown[], data?: unknown[] } },
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(legendContainer: Ref, selectMode: Ref<boolean>, onHoverIndex: any, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref<((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[]>, maxValueToDisplay?: number, chartData?: any): HTMLLegendPlugin[] {
45
- return [{
46
- id: 'htmlLegend',
47
- afterUpdate (chart: any) {
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 flexDirection = isDoughnut ? 'column' : 'row';
50
- const ul: HTMLLIElement = getOrCreateLegendList(legendContainer, flexDirection);
51
- ul.style.margin = '1.375rem 1.0625rem';
52
- while (ul.firstChild) {
53
- ul.firstChild.remove();
54
- }
55
- const items: ChartItem[] = chart.options.plugins.legend.labels.generateLabels(chart);
56
- items.forEach((item: ChartItem): void => {
57
- const isDoughnut: boolean = chart.config.type === 'doughnut';
58
- const index: number = isDoughnut ? item.index : item.datasetIndex;
59
- const li: HTMLElement = createHtmlLegendListElement(chart, selectMode, index);
60
- if (isDoughnut) {
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
- ul.appendChild(li);
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 (doughnutData: any, maxValueToDisplay: number, index: number) {
89
- return doughnutData.data.length > maxValueToDisplay && index === maxValueToDisplay - 1;
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 (doughnutData: any, maxValueToDisplay: number): HTMLDivElement {
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 = 'invert(38%) sepia(19%) saturate(18%) hue-rotate(337deg) brightness(97%) contrast(85%)';
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 (doughnutData: any, maxValueToDisplay: number) {
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 (doughnutData: any, maxValueToDisplay: number, tooltip: HTMLDivElement) {
133
- const startIndex = maxValueToDisplay - 1;
134
- doughnutData.data.slice(startIndex).forEach((_ignore: any, index: number) => {
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(document.createTextNode(formatValueAndRate(doughnutData, dataIndex)));
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
- (item: ChartItem, chart: Chart, onHoverIndex: any | null, disableAccessibility: boolean, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[])
154
- : HTMLElement {
155
- const isDoughnut: boolean = chart.config.type === 'doughnut';
156
- const index: number = isDoughnut ? item.index : item.datasetIndex;
157
- const img: HTMLImageElement = new Image();
158
- const boxSpan: HTMLElement = createHtmlLegendLine(item, chart.config.type);
159
- const pattern: CanvasPattern = patternsList[index](false, patternsColors[index], disableAccessibility);
160
- const patternCanvas: HTMLCanvasElement = getPatternCanvas(pattern);
161
- img.src = patternCanvas.toDataURL();
162
- boxSpan.style.background = `url(${img.src})`;
163
- boxSpan.style.backgroundSize = 'cover';
164
- boxSpan.style.borderColor = patternsColors[index];
165
- boxSpan.style.borderWidth = '2px';
166
-
167
- boxSpan.onmouseover = ():void => {
168
- isDoughnut ? onHoverIndex.value = index : onHoverIndex.dataSetIndex = index;
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 ? onHoverIndex.value = null : onHoverIndex.dataSetIndex = null;
264
+ isDoughnut
265
+ ? (onHoverIndex.value = null)
266
+ : (onHoverIndex.dataSetIndex = -1);
172
267
  };
173
- return boxSpan;
268
+ }
269
+ return boxSpan;
174
270
  }
175
271
 
176
- export function createLegendElementWithCheckbox
177
- (chart: Chart, item: ChartItem, selectMode: Ref<boolean>, onHoverIndex: any | null, disableAccessibility: boolean): HTMLElement {
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(chart, item, disableAccessibility);
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
- labels.every((label: string, index: number) => chart.getDataVisibility(index));
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
- } else {
189
- onHoverIndex.dataSetIndex = -1;
294
+ onHoverIndex.value = -1;
190
295
  }
191
296
  return checkbox;
192
297
  }
193
- checkbox.onmouseover = ():void => {
194
- isDoughnut ? onHoverIndex.value = index : onHoverIndex.dataSetIndex = index;
195
- };
196
- checkbox.onmouseleave = (): void => {
197
- isDoughnut ? onHoverIndex.value = null : onHoverIndex.dataSetIndex = null;
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 (item: ChartItem) {
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 (item: ChartItem, type: string | undefined) {
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 = item.fillStyle;
333
+ boxSpan.style.background = 'rgba(0, 0, 0, 0.1)';
218
334
  boxSpan.style.borderColor = item.strokeStyle;
219
- boxSpan.style.borderWidth = item.lineWidth + 'px';
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.width = LEGEND_BOX_SIZE + 'px';
342
+ boxSpan.style.minWidth = LEGEND_BOX_SIZE;
227
343
  boxSpan.style.marginRight = LEGEND_LABEL_LEFT_MARGIN;
228
- boxSpan.style.height = LEGEND_BOX_SIZE + 'px';
344
+ boxSpan.style.minHeight = LEGEND_BOX_SIZE;
229
345
  return boxSpan;
230
346
  }
231
347
 
232
- export function createHtmlLegendDatasetSquare (item: ChartItem) {
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 = item.lineWidth + 'px';
355
+ divPoint.style.borderWidth = LEGEND_BOX_BORDER;
240
356
  return divPoint;
241
357
  }
242
358
 
243
- export function createHtmlLegendListElement
244
- (chart: Chart, selectMode: Ref, elementIndex: number) {
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 (isDataSetVisible: boolean, item: ChartItem, checkbox: Element, disableAccessibility: boolean) {
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
- backgroundColor = disableAccessibility? item.fillStyle : item.strokeStyle;
267
- borderColor = item.strokeStyle;
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('style', `background-color: ${backgroundColor};
272
- width: ${LEGEND_BOX_SIZE + 4 + 'px'};
273
- height: ${LEGEND_BOX_SIZE + 4 + 'px'};
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 (chart: Chart, item: ChartItem, disableAccessibility: boolean = false) {
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 = isDoughnut ? chart.getDataVisibility(index) : chart.isDatasetVisible(index);
285
- addCheckboxStyle(isDataSetVisible, item, checkbox, disableAccessibility);
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 (chart: Chart) {
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 (chart: any) {
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 (chart: Chart, elementIndex: number, selectMode: Ref) {
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 (chart: Chart): boolean {
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.isDatasetVisible(dataIndex);
459
+ allVisible = allVisible && isChartDataVisible(chart, dataIndex);
319
460
  });
320
461
  return allVisible;
321
462
  }
322
463
 
323
- export function switchItemVisibility (chart: Chart, elementIndex: number, selectMode?: Ref) {
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(elementIndex, !chart.isDatasetVisible(elementIndex));
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
- export function createLegendElementWithSquareArea (item: ChartItem, mainSerieFirstDataset?: boolean) {
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
- if (index === 0) {
341
- mainSerieFirstDataset ? divPoint.style.borderRadius = '25px' : divPoint.style.transform = 'rotate(45deg)';
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 ? divPoint.style.transform = 'rotate(45deg)' : divPoint.style.borderRadius = '25px';
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
- export function getOrCreateLegendList (legendContainer: Ref, flexDirection: string) {
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
+ }
@@ -1,4 +1,4 @@
1
1
  export function addAlpha(color: string, opacity: number) {
2
2
  const _opacity = Math.round(Math.min(Math.max(opacity || 1, 0), 1) * 255);
3
3
  return color + _opacity.toString(16).toUpperCase();
4
- }
4
+ }