@mozaic-ds/chart 0.1.0-beta.4 → 0.1.0-beta.40

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/README.md +85 -9
  2. package/dist/mozaic-chart.js +4747 -2614
  3. package/dist/mozaic-chart.umd.cjs +17 -11
  4. package/dist/style.css +1 -1
  5. package/package.json +24 -11
  6. package/src/assets/base.css +1 -1
  7. package/src/assets/img/bubbles.svg +4 -0
  8. package/src/components/bar/BarChart.stories.ts +181 -101
  9. package/src/components/bar/BarChart.vue +370 -139
  10. package/src/components/bar/index.ts +3 -3
  11. package/src/components/bubble/BubbleChart.stories.ts +66 -0
  12. package/src/components/bubble/BubbleChart.vue +432 -0
  13. package/src/components/bubble/index.ts +8 -0
  14. package/src/components/doughnut/DoughnutChart.stories.ts +38 -36
  15. package/src/components/doughnut/DoughnutChart.vue +243 -114
  16. package/src/components/doughnut/index.ts +3 -3
  17. package/src/components/index.ts +4 -4
  18. package/src/components/line/LineChart.stories.ts +52 -27
  19. package/src/components/line/LineChart.vue +381 -255
  20. package/src/components/line/index.ts +3 -3
  21. package/src/components/mixed/MixedBarLineChart.stories.ts +91 -0
  22. package/src/components/mixed/MixedBarLineChart.vue +469 -0
  23. package/src/components/mixed/index.ts +8 -0
  24. package/src/components/radar/RadarChart.stories.ts +102 -102
  25. package/src/components/radar/RadarChart.vue +222 -167
  26. package/src/components/radar/index.ts +3 -3
  27. package/src/main.ts +14 -5
  28. package/src/plugin.ts +9 -7
  29. package/src/services/BarChartFunctions.ts +139 -35
  30. package/src/services/BubbleTooltipService.ts +67 -0
  31. package/src/services/ChartsCommonLegend.ts +315 -139
  32. package/src/services/ColorFunctions.ts +1 -1
  33. package/src/services/DoughnutChartFunctions.ts +132 -55
  34. package/src/services/FormatUtilities.ts +25 -19
  35. package/src/services/GenericTooltipService.ts +141 -66
  36. package/src/services/MixedBarLineFunctions.ts +262 -0
  37. package/src/services/PatternFunctions.ts +25 -18
  38. package/src/services/RadarChartFunctions.ts +39 -12
  39. package/src/services/patterns/ChartDesign.ts +35 -24
  40. package/src/services/patterns/patternCircles.ts +63 -36
  41. package/src/services/patterns/patternDashedDiagonals.ts +64 -57
  42. package/src/services/patterns/patternDiagonals.ts +138 -106
  43. package/src/services/patterns/patternSquares.ts +86 -80
  44. package/src/services/patterns/patternVerticalLines.ts +76 -69
  45. package/src/services/patterns/patternZigzag.ts +92 -85
  46. package/src/stories/Changelog.mdx +6 -0
  47. package/src/stories/Contributing.mdx +101 -0
  48. package/src/stories/GettingStarted.mdx +92 -0
  49. package/src/stories/SupportAndOnboarding.mdx +44 -0
  50. package/src/types/AxisDefinition.ts +4 -0
  51. package/src/types/BarData.ts +1 -0
  52. package/src/types/Chart.ts +9 -7
  53. package/src/types/DoughnutData.ts +8 -0
  54. package/src/types/GenericData.ts +10 -10
  55. package/src/types/LineChart.ts +5 -4
  56. package/src/types/MixedBarLineData.ts +7 -0
  57. package/src/types/RadarData.ts +33 -29
  58. package/src/types/TooltipChartType.ts +7 -6
  59. package/src/vite-env.d.ts +3 -3
@@ -1,102 +1,206 @@
1
1
  import { reactive, ref } from 'vue';
2
2
  import type { Ref } from 'vue';
3
- import {
4
- getHtmlLegendPlugin
5
- } from './ChartsCommonLegend';
3
+ import { getHtmlLegendPlugin } from './ChartsCommonLegend';
6
4
  import PatternFunctions from './PatternFunctions';
7
5
  import { addAlpha } from './ColorFunctions';
8
6
 
9
7
  const { getPatternIndexWithShift } = PatternFunctions();
10
8
 
11
9
  interface Dataset {
12
- data: any,
13
- label: any,
10
+ data: number[];
11
+ label: any;
12
+ stack?: number;
14
13
  }
15
14
 
16
15
  export default function () {
17
16
  const borderWidth = ref(3);
18
17
  const barChartRef = ref(null as any);
19
- const onHoverIndex: { dataSetIndex: number, columnIndex: number } = reactive({
18
+ const onHoverIndex: { dataSetIndex: number; columnIndex: number } = reactive({
20
19
  dataSetIndex: -1,
21
20
  columnIndex: -1
22
21
  });
23
22
 
24
-
25
- function privateGetHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref<((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[]>) {
26
- return getHtmlLegendPlugin(legendContainer, selectMode, onHoverIndex, disableAccessibility, patternsColors, patternsList);
23
+ function privateGetHtmlLegendPlugin(
24
+ legendContainer: Ref,
25
+ selectMode: Ref<boolean>,
26
+ disableAccessibility: Ref<boolean>,
27
+ patternsColors: Ref<string[]>,
28
+ patternsList: Ref<
29
+ ((
30
+ hover: boolean,
31
+ color: string,
32
+ disableAccessibility: boolean
33
+ ) => CanvasPattern)[]
34
+ >,
35
+ enableHoverFeature: Ref<boolean>,
36
+ disableLegendClick: Ref<boolean>
37
+ ) {
38
+ return getHtmlLegendPlugin(
39
+ legendContainer,
40
+ selectMode,
41
+ onHoverIndex,
42
+ disableAccessibility,
43
+ patternsColors,
44
+ patternsList,
45
+ enableHoverFeature,
46
+ undefined,
47
+ null,
48
+ disableLegendClick
49
+ );
27
50
  }
28
51
  // Hack to force the chart to reload on Hover
29
- function reloadChart () {
52
+ function reloadChart() {
30
53
  borderWidth.value = 4;
31
54
  borderWidth.value = 3;
32
55
  }
33
56
 
34
- function getStackedDatasets (datasets: Dataset[], stackDatasets: boolean, disableAccessibility: boolean, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], patternShifting?: number) {
57
+ function getStackedDatasets(
58
+ datasets: Dataset[],
59
+ stackDatasets: boolean,
60
+ disableAccessibility: boolean,
61
+ patternsColors: string[],
62
+ patternsList: ((
63
+ hover: boolean,
64
+ color: string,
65
+ disableAccessibility: boolean
66
+ ) => CanvasPattern)[],
67
+ patternShifting?: number
68
+ ) {
35
69
  // Hack to force refresh
36
70
  const borderWithValue = borderWidth.value;
37
- return datasets.map((dataset, index) => {
71
+ return datasets.map((dataset, datasetIndex) => {
38
72
  return {
39
73
  borderColor: function (context: any) {
40
- return disableAccessibility ? '#00000000' : getBorderColor(index, context.index, patternsColors, patternShifting);
74
+ return disableAccessibility
75
+ ? '#00000000'
76
+ : getBorderColor(
77
+ datasetIndex,
78
+ context.index,
79
+ patternsColors,
80
+ patternShifting
81
+ );
41
82
  },
42
83
  backgroundColor: function (context: any) {
43
- return getPattern(index, context.index, disableAccessibility, patternsColors, patternsList, patternShifting);
84
+ return getPattern(
85
+ datasetIndex,
86
+ context.index,
87
+ disableAccessibility,
88
+ patternsColors,
89
+ patternsList,
90
+ patternShifting
91
+ );
92
+ },
93
+ borderWidth: function () {
94
+ return disableAccessibility ? 1 : borderWithValue;
44
95
  },
45
- borderWidth: function () {return disableAccessibility ? 1 : borderWithValue},
96
+
46
97
  data: dataset.data,
47
98
  label: dataset.label,
48
- stack: `Stack ${stackDatasets ? '0' : index}`
99
+ stack: `Stack ${stackDatasets ? dataset.stack : datasetIndex}`
49
100
  };
50
101
  });
51
102
  }
52
103
 
53
- function getDatasets (firstDataSet: Dataset, secondDataSet: Dataset, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], disableAccessibility: boolean) {
54
- return getStackedDatasets([firstDataSet, secondDataSet], false, disableAccessibility, patternsColors, patternsList);
104
+ function getDatasets(
105
+ firstDataSet: Dataset,
106
+ secondDataSet: Dataset,
107
+ patternsColors: string[],
108
+ patternsList: ((
109
+ hover: boolean,
110
+ color: string,
111
+ disableAccessibility: boolean
112
+ ) => CanvasPattern)[],
113
+ disableAccessibility: boolean
114
+ ) {
115
+ return getStackedDatasets(
116
+ [firstDataSet, secondDataSet],
117
+ false,
118
+ disableAccessibility,
119
+ patternsColors,
120
+ patternsList
121
+ );
55
122
  }
56
123
 
57
- function getBorderColor (dataSetIndex: number, contextIndex: number, patternsColors: string[], patternShifting?: number) {
124
+ function getBorderColor(
125
+ dataSetIndex: number,
126
+ contextIndex: number,
127
+ patternsColors: string[],
128
+ patternShifting?: number
129
+ ) {
58
130
  const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
59
131
  if (displayFullOpacity(dataSetIndex, contextIndex)) {
60
132
  return patternsColors[index];
61
133
  } else {
62
- return addAlpha(patternsColors[index],0.2);
134
+ return addAlpha(patternsColors[index], 0.2);
63
135
  }
64
136
  }
65
137
 
66
- function getPattern (dataSetIndex: number, contextIndex: number, disableAccessibility: boolean, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], patternShifting?: number) {
138
+ function getPattern(
139
+ dataSetIndex: number,
140
+ contextIndex: number,
141
+ disableAccessibility: boolean,
142
+ patternsColors: string[],
143
+ patternsList: ((
144
+ hover: boolean,
145
+ color: string,
146
+ disableAccessibility: boolean
147
+ ) => CanvasPattern)[],
148
+ patternShifting?: number
149
+ ) {
67
150
  const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
68
151
  if (displayFullOpacity(dataSetIndex, contextIndex)) {
69
- return patternsList[index](false, patternsColors[index], disableAccessibility);
152
+ return patternsList[index](
153
+ false,
154
+ patternsColors[index],
155
+ disableAccessibility
156
+ );
70
157
  } else {
71
- return patternsList[index](true, patternsColors[index], disableAccessibility);
158
+ return patternsList[index](
159
+ true,
160
+ patternsColors[index],
161
+ disableAccessibility
162
+ );
72
163
  }
73
164
  }
74
165
 
75
- function nothingHovered (): boolean {
166
+ function nothingHovered(): boolean {
76
167
  return onHoverIndex.dataSetIndex < 0;
77
168
  }
78
169
 
79
- function columnHovered (dataSetIndex: number, contextIndex: number): boolean {
80
- return onHoverIndex.dataSetIndex === dataSetIndex && onHoverIndex.columnIndex === contextIndex;
170
+ function columnHovered(dataSetIndex: number, contextIndex: number): boolean {
171
+ return (
172
+ onHoverIndex.dataSetIndex === dataSetIndex &&
173
+ onHoverIndex.columnIndex === contextIndex
174
+ );
81
175
  }
82
176
 
83
- function legendHovered (dataSetIndex: number): boolean {
84
- return onHoverIndex.dataSetIndex === dataSetIndex && onHoverIndex.columnIndex < 0;
177
+ function legendHovered(dataSetIndex: number): boolean {
178
+ return (
179
+ onHoverIndex.dataSetIndex === dataSetIndex && onHoverIndex.columnIndex < 0
180
+ );
85
181
  }
86
182
 
87
- function displayFullOpacity (dataSetIndex: number, contextIndex: number): boolean {
88
- return nothingHovered() ||
183
+ function displayFullOpacity(
184
+ dataSetIndex: number,
185
+ contextIndex: number
186
+ ): boolean {
187
+ return (
188
+ nothingHovered() ||
89
189
  columnHovered(dataSetIndex, contextIndex) ||
90
- legendHovered(dataSetIndex);
190
+ legendHovered(dataSetIndex)
191
+ );
91
192
  }
92
193
 
93
- function resetOnHoverIndex () {
194
+ function resetOnHoverIndex() {
94
195
  onHoverIndex.dataSetIndex = -1;
95
196
  onHoverIndex.columnIndex = -1;
96
197
  }
97
198
 
98
- function getOnHoverOptions () {
99
- return (_ignore: unknown, activeElements: Array<{ index: number, datasetIndex: number }>) => {
199
+ function getOnHoverOptions() {
200
+ return (
201
+ _ignore: unknown,
202
+ activeElements: Array<{ index: number; datasetIndex: number }>
203
+ ) => {
100
204
  if (activeElements[0] !== undefined) {
101
205
  onHoverIndex.dataSetIndex = activeElements[0].datasetIndex;
102
206
  onHoverIndex.columnIndex = activeElements[0].index;
@@ -117,6 +221,6 @@ export default function () {
117
221
  privateGetHtmlLegendPlugin,
118
222
  getPatternIndexWithShift,
119
223
  barChartRef,
120
- borderWidth,
224
+ borderWidth
121
225
  };
122
226
  }
@@ -0,0 +1,67 @@
1
+ import { Context, GenericTooltipService } from './GenericTooltipService';
2
+
3
+ export type BubbleTooltipLine = {
4
+ label: string;
5
+ value: string;
6
+ unit: string;
7
+ };
8
+ const tooltipLineStyle =
9
+ 'background: white; border-bottom: 1px solid #CCCCCC; border-radius: 5px; padding: 10px 20px';
10
+
11
+ export class BubbleTooltipService extends GenericTooltipService {
12
+ fontProperties = 'font-family: Arial; font-size: 16px';
13
+
14
+ createBubbleTooltip(
15
+ context: Context,
16
+ lines: BubbleTooltipLine[],
17
+ title: string
18
+ ) {
19
+ if (!title || title === '') {
20
+ return;
21
+ }
22
+ let tooltipEl = document.querySelector(
23
+ '#chartjs-tooltip'
24
+ ) as HTMLElement | null;
25
+ if (!tooltipEl) {
26
+ tooltipEl = this.createNewTooltipElement();
27
+ }
28
+ const tooltipModel = context.tooltip;
29
+ if (tooltipModel.opacity === 0) {
30
+ tooltipEl.style.opacity = '0';
31
+ return;
32
+ }
33
+ if (tooltipModel.body) {
34
+ this.titleLines = tooltipModel.title || [];
35
+ const bodyLines = tooltipModel.body.map(this.getBody);
36
+ const body = bodyLines[0];
37
+ this.addBubbleLegendToDom(lines, body, tooltipEl, title);
38
+ }
39
+ this.handleTooltipPosition(context, tooltipModel, tooltipEl);
40
+ }
41
+
42
+ addBubbleLegendToDom(
43
+ lines: BubbleTooltipLine[],
44
+ body: Array<string>,
45
+ tooltipEl: HTMLElement,
46
+ title: string
47
+ ) {
48
+ const legendText = body[0].split(':')[0];
49
+ const spanText = `<span style="${this.fontProperties}">${title}</span>`;
50
+ let innerHtml = `<div style="${tooltipLineStyle}; font-weight: bold" class="tooltipTitle">${spanText}</div>`;
51
+ const innerHtmlToAdd = this.getBubbleInnerHtml(lines);
52
+ innerHtml += innerHtmlToAdd;
53
+ const tableRoot = tooltipEl?.querySelector('.tooltipCtn') as HTMLElement;
54
+ tableRoot.innerHTML = innerHtml;
55
+ }
56
+
57
+ getBubbleInnerHtml(lines: BubbleTooltipLine[]): string {
58
+ let innerLinesHtml = '';
59
+ lines.forEach((line) => {
60
+ innerLinesHtml += `<div style="${this.fontProperties}; ${tooltipLineStyle}; display:flex; justify-content: space-between;">`;
61
+ innerLinesHtml += `<div>${line.label}</div>`;
62
+ innerLinesHtml += `<div>${line.value} ${line.unit}</div>`;
63
+ innerLinesHtml += `</div>`;
64
+ });
65
+ return `<div>${innerLinesHtml}</div>`;
66
+ }
67
+ }