@mozaic-ds/chart 0.1.0-beta.2 → 0.1.0-beta.23

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 (37) hide show
  1. package/dist/mozaic-chart.js +4111 -2476
  2. package/dist/mozaic-chart.umd.cjs +17 -11
  3. package/dist/style.css +1 -1
  4. package/package.json +23 -10
  5. package/src/assets/img/bubbles.svg +4 -0
  6. package/src/components/bar/BarChart.stories.ts +12 -10
  7. package/src/components/bar/BarChart.vue +248 -141
  8. package/src/components/bubble/BubbleChart.stories.ts +66 -0
  9. package/src/components/bubble/BubbleChart.vue +336 -0
  10. package/src/components/bubble/index.ts +8 -0
  11. package/src/components/doughnut/DoughnutChart.stories.ts +1 -0
  12. package/src/components/doughnut/DoughnutChart.vue +182 -101
  13. package/src/components/line/LineChart.stories.ts +2 -1
  14. package/src/components/line/LineChart.vue +331 -258
  15. package/src/components/mixed/MixedBarLineChart.stories.ts +91 -0
  16. package/src/components/mixed/MixedBarLineChart.vue +411 -0
  17. package/src/components/mixed/index.ts +8 -0
  18. package/src/components/radar/RadarChart.stories.ts +2 -2
  19. package/src/components/radar/RadarChart.vue +203 -157
  20. package/src/main.ts +3 -1
  21. package/src/plugin.ts +2 -0
  22. package/src/services/BarChartFunctions.ts +10 -7
  23. package/src/services/BubbleTooltipService.ts +65 -0
  24. package/src/services/ChartsCommonLegend.ts +86 -58
  25. package/src/services/DoughnutChartFunctions.ts +107 -59
  26. package/src/services/FormatUtilities.ts +1 -1
  27. package/src/services/GenericTooltipService.ts +25 -10
  28. package/src/services/MixedBarLineFunctions.ts +258 -0
  29. package/src/services/RadarChartFunctions.ts +33 -12
  30. package/src/stories/Changelog.mdx +6 -0
  31. package/src/stories/Contributing.mdx +101 -0
  32. package/src/stories/GettingStarted.mdx +92 -0
  33. package/src/stories/SupportAndOnboarding.mdx +44 -0
  34. package/src/types/AxisDefinition.ts +6 -0
  35. package/src/types/BarData.ts +1 -0
  36. package/src/types/MixedBarLineData.ts +7 -0
  37. package/src/types/TooltipChartType.ts +1 -0
@@ -2,24 +2,24 @@
2
2
  <div class="container">
3
3
  <div class="main">
4
4
  <Doughnut
5
- v-if="doughnutChartData"
6
- ref='doughnutRef'
7
- :data='doughnutChartData as ChartData<"doughnut", number[], unknown>'
8
- :options='options'
9
- :plugins='htmlLegendPlugin'
10
- :cssClasses:="cssClasses"
11
- :max-values="maxValues"
12
- :style='{width, height, cursor:"pointer"}'
13
- />
14
- </div>
15
- <div ref="legendContainer" />
5
+ v-if="doughnutChartData"
6
+ ref="doughnutRef"
7
+ :id="chartId"
8
+ :data="doughnutChartData"
9
+ :options="options"
10
+ :plugins="htmlLegendPlugin"
11
+ :max-values="maxValues"
12
+ :class="cssClasses"
13
+ :style="[{ width, height, cursor: 'pointer' }, styles]"
14
+ />
15
+ </div>
16
+ <div ref="legendContainer" />
16
17
  </div>
17
18
  </template>
18
19
 
19
20
  <script setup lang="ts">
20
21
  import { onMounted, watch } from 'vue';
21
22
  import { Doughnut } from 'vue-chartjs';
22
- import type { ChartData } from 'chart.js';
23
23
  import { computed, ref, PropType } from 'vue';
24
24
  import type { DoughnutData } from '../../types/DoughnutData';
25
25
  import { TooltipChartType } from '../../types/TooltipChartType';
@@ -35,19 +35,11 @@ import {
35
35
  Tooltip,
36
36
  Legend,
37
37
  ArcElement,
38
- Plugin
38
+ Plugin,
39
39
  } from 'chart.js';
40
- ChartJS.register(
41
- Title,
42
- Tooltip,
43
- Legend,
44
- ArcElement
45
- );
40
+ ChartJS.register(Title, Tooltip, Legend, ArcElement);
46
41
 
47
- const {
48
- colourSets,
49
- patternsStandardList
50
- } = ChartDesign();
42
+ const { colourSets, patternsStandardList } = ChartDesign();
51
43
 
52
44
  const {
53
45
  onHoverIndex,
@@ -57,117 +49,173 @@ const {
57
49
  getOnHoverOptions,
58
50
  groupDataAfterNthValue,
59
51
  getDoughnutLabels,
60
- getBorderColor
52
+ getBorderColor,
61
53
  } = doughnutChartFunction();
62
54
  const selectMode = ref(false);
63
55
  const legendContainer = ref<HTMLElement | null>(null);
64
56
 
65
57
  const doughnutDataProps = defineProps({
58
+ /**
59
+ * Value of the id attribute present on the <canvas> element containing the chart
60
+ */
66
61
  chartId: {
67
62
  type: String,
68
63
  default: 'doughnut-chart',
69
64
  },
65
+ /**
66
+ * Data to be passed to Chart
67
+ */
70
68
  data: {
71
69
  type: Array as PropType<DoughnutData[]>,
72
- default: () => []
70
+ default: () => [],
73
71
  },
72
+ /**
73
+ * Labels used to label the index axis (default x axes). See [Data structures documentation](https://www.chartjs.org/docs/latest/general/data-structures.html)
74
+ */
74
75
  labels: {
75
76
  type: Array as PropType<string[]>,
76
- default: () => []
77
+ default: () => [],
77
78
  },
79
+ /**
80
+ * Add custom CSS classes to the <canvas> element
81
+ */
78
82
  cssClasses: {
79
- default: '',
80
83
  type: String,
84
+ default: undefined,
81
85
  },
82
- // disable accessibility patterns
86
+ /**
87
+ * Disable accessibility patterns
88
+ */
83
89
  disableAccessibility: {
84
90
  type: Boolean,
85
- default: false
91
+ default: false,
92
+ },
93
+ /**
94
+ * Enable hover feature (may cause strange behavior when used with width and height in %)
95
+ */
96
+ enableHoverFeature: {
97
+ type: Boolean,
98
+ default: false,
86
99
  },
87
- // colourSet props is used to choose the colour set of the charts as defined in the Figma prototypes.
88
- // 7 colour sets are currently defined :
89
- // - Default 0 corresponds to the current one
90
- // - 1 to 6 corresponds to the "new" colour sets : https://www.figma.com/file/Hn6PyvnR385Ta0XN3KqOI9/04.-Dataviz---Documentation-(read-only)?type=design&node-id=1-69316&mode=design&t=sDytQ5BipsryWkuA-0
91
- // Remark : All the sets are defined in /src/services/patterns/ChartDesign.ts
100
+ /**
101
+ * Used to choose the colour set of the charts as defined in the Figma prototypes.
102
+ * 7 colour sets are currently defined:
103
+ * - Default 0 corresponds to the current one
104
+ * - 1 to 6 corresponds to the "new" [colour sets](https://www.figma.com/file/Hn6PyvnR385Ta0XN3KqOI9/04.-Dataviz---Documentation-(read-only)?type=design&node-id=1-69316&mode=design&t=sDytQ5BipsryWkuA-0)
105
+ * Note: All the sets are defined in /src/services/patterns/ChartDesign.ts
106
+ */
92
107
  colourSet: {
93
- default:'0',
94
- type: Number
108
+ type: Number,
109
+ default: 0,
95
110
  },
96
- // 6 patterns exist and are not randomly given but follow the order defined in patternsStandardList /src/services/patterns/ChartDesign.ts
97
- // Additionally, a pattern has only one possible colour per colour set as defined in the Figma prototype.
98
- // In some use cases, the chart may need to show a different orders of these patterns, this can be changed using the props newPatternsOrder
111
+ /**
112
+ * 6 patterns exist and are not randomly given but follow the order defined in [patternsStandardList](/src/services/patterns/ChartDesign.ts)
113
+ * Additionally, a pattern has only one possible colour per colour set as defined in the Figma prototype.
114
+ * In some use cases, the chart may need to show a different orders of these patterns, this can be changed using the props newPatternsOrder
115
+ */
99
116
  newPatternsOrder: {
100
- type: Array as PropType<number[]>,
101
- default: () => [0,1,2,3,4,5]
102
- },
117
+ type: Array as PropType<number[]>,
118
+ default: () => [0, 1, 2, 3, 4, 5],
119
+ },
120
+ /**
121
+ * Value of the `width` css property used to define the width of the <canvas> element
122
+ */
103
123
  width: {
104
- type: String,
105
- default: '400px',
124
+ type: String,
125
+ default: '400px',
106
126
  },
127
+ /**
128
+ * Value of the `height` css property used to define the height of the <canvas> element
129
+ */
107
130
  height: {
108
131
  type: String,
109
132
  default: '400px',
110
133
  },
134
+ /**
135
+ * Maximum number of data to be displayed in the Chart
136
+ */
111
137
  maxValues: {
112
138
  type: Number,
113
139
  default: 5,
114
140
  },
141
+ /**
142
+ * Add custom CSS styles to the <canvas> element
143
+ */
115
144
  styles: {
116
145
  type: Object as PropType<Partial<CSSStyleDeclaration>>,
117
- default: () => {
118
- },
146
+ default: () => {},
119
147
  },
148
+ /**
149
+ * Value of the `plugins` key passed to the Chart config
150
+ */
120
151
  plugins: {
121
152
  type: Array as PropType<Plugin<'doughnut'>[]>,
122
153
  default: () => [],
123
154
  },
124
- })
155
+ /**
156
+ * Value of the 'others' label if maxValue is reached
157
+ */
158
+ othersLabel: {
159
+ type: String,
160
+ default: 'others',
161
+ },
162
+ });
125
163
 
126
- const patternsColors = computed( () => {
164
+ const patternsColors = computed(() => {
127
165
  return doughnutDataProps.newPatternsOrder.length !== 6
128
- ? colourSets[doughnutDataProps.colourSet]
129
- : doughnutDataProps.newPatternsOrder.map((id) => {
130
- return colourSets[doughnutDataProps.colourSet][id]
131
- })
166
+ ? colourSets[doughnutDataProps.colourSet]
167
+ : doughnutDataProps.newPatternsOrder.map((id) => {
168
+ return colourSets[doughnutDataProps.colourSet][id];
169
+ });
132
170
  });
133
171
 
134
172
  const patternsOrderedList = computed(() => {
135
- return doughnutDataProps.newPatternsOrder.length !== 6
136
- ? patternsStandardList
137
- : doughnutDataProps.newPatternsOrder.map((id) => {
138
- return patternsStandardList[id]
139
- })
140
- }
141
- );
173
+ return doughnutDataProps.newPatternsOrder.length !== 6
174
+ ? patternsStandardList
175
+ : doughnutDataProps.newPatternsOrder.map((id) => {
176
+ return patternsStandardList[id];
177
+ });
178
+ });
142
179
 
143
- const doughnutChartData = computed(() => {
180
+ const doughnutChartData = computed<any>(() => {
144
181
  return {
145
- labels: getDoughnutLabels(doughnutDataProps.labels,
146
- doughnutDataProps.data, doughnutDataProps.maxValues),
182
+ labels: getDoughnutLabels(
183
+ doughnutDataProps.labels,
184
+ doughnutDataProps.data,
185
+ doughnutDataProps.maxValues,
186
+ doughnutDataProps.othersLabel
187
+ ),
147
188
  datasets: [
148
189
  {
149
- data: groupDataAfterNthValue(doughnutDataProps.data, doughnutDataProps.maxValues).map((x: GenericData) => x.rate),
150
- backgroundColor: getBackgroundColor(patternsColors.value, patternsOrderedList.value, doughnutDataProps.disableAccessibility),
151
- borderColor: getBorderColor(patternsColors.value)
152
- }
153
- ]
154
- }
190
+ data: groupDataAfterNthValue(
191
+ doughnutDataProps.data,
192
+ doughnutDataProps.maxValues
193
+ ).map((x: GenericData) => x.rate),
194
+ backgroundColor: getBackgroundColor(
195
+ patternsColors.value,
196
+ patternsOrderedList.value,
197
+ doughnutDataProps.disableAccessibility,
198
+ doughnutDataProps.enableHoverFeature
199
+ ),
200
+ borderColor: getBorderColor(patternsColors.value, doughnutDataProps.enableHoverFeature),
201
+ },
202
+ ],
203
+ };
155
204
  });
156
205
 
157
206
  const getTooltipData = (context: Context) => {
158
- const dataIndex = context.tooltip.dataPoints[0].dataIndex;
159
- if (!dataIndex) {
160
- return '';
161
- }
162
- const tooltipData =
163
- groupDataAfterNthValue(doughnutDataProps.data, doughnutDataProps.maxValues)[dataIndex];
207
+ const dataIndex = context.tooltip.dataPoints[0].dataIndex as number;
208
+ const tooltipData = groupDataAfterNthValue(
209
+ doughnutDataProps.data,
210
+ doughnutDataProps.maxValues
211
+ )[dataIndex];
164
212
  const rate = formatWithThousandsSeprators(tooltipData.rate);
165
213
  const value = formatWithThousandsSeprators(tooltipData.value);
166
214
  const unit = tooltipData.unit || '';
167
215
  return `${value}${unit} (${rate})%`;
168
216
  };
169
217
 
170
- function getSpacing () {
218
+ function getSpacing() {
171
219
  return doughnutDataProps.labels.length <= 1 ? 0 : 12;
172
220
  }
173
221
 
@@ -176,7 +224,7 @@ const options = computed(() => {
176
224
  const colors = patternsColors.value;
177
225
  const patterns = patternsOrderedList.value;
178
226
  return {
179
- onHover: getOnHoverOptions(),
227
+ onHover: doughnutDataProps.enableHoverFeature? getOnHoverOptions() : () => {},
180
228
  plugins: {
181
229
  legend: {
182
230
  display: false,
@@ -185,57 +233,90 @@ const options = computed(() => {
185
233
  align: 'start' as const,
186
234
  labels: {
187
235
  pointStyle: 'rectRounded',
188
- usePointStyle: true
189
- }
236
+ usePointStyle: true,
237
+ },
190
238
  },
191
239
  title: {
240
+ display: false,
241
+ },
242
+ datalabels: {
192
243
  display: false
193
244
  },
194
245
  tooltip: {
195
246
  enabled: false,
196
247
  external: function (context: Context) {
197
248
  new GenericTooltipService().createTooltip(
198
- context,
199
- getTooltipData,
200
- {
201
- chartType: TooltipChartType.DOUGHNUT
202
- },
203
- colors,
204
- patterns,
205
- disablePattern.value
249
+ context,
250
+ getTooltipData,
251
+ {
252
+ chartType: TooltipChartType.DOUGHNUT,
253
+ },
254
+ colors,
255
+ patterns,
256
+ disablePattern.value
206
257
  );
207
- }
208
- }
258
+ },
259
+ },
209
260
  },
210
261
  radius: '90%',
211
262
  cutout: '70%',
212
263
  borderWidth: 3,
213
264
  spacing: getSpacing(),
214
- hoverOffset: 4
215
- }
265
+ hoverOffset: 4,
266
+ };
216
267
  });
217
268
 
218
269
  const doughnutDataAndLabels = {
219
270
  data: doughnutDataProps.data,
220
- labels: doughnutDataProps.labels
221
- }
222
- const disablePattern = computed(() => {return doughnutDataProps.disableAccessibility})
271
+ labels: doughnutDataProps.labels,
272
+ };
273
+ const disablePattern = computed(() => {
274
+ return doughnutDataProps.disableAccessibility;
275
+ });
276
+ const enableHover = computed(() => {
277
+ return doughnutDataProps.enableHoverFeature;
278
+ })
223
279
 
224
- const htmlLegendPlugin = computed(() => privateGetHtmlLegendPlugin(legendContainer, selectMode, disablePattern, patternsColors, patternsOrderedList, doughnutDataProps.maxValues, doughnutDataAndLabels));
280
+ const htmlLegendPlugin = computed(() =>
281
+ privateGetHtmlLegendPlugin(
282
+ legendContainer,
283
+ selectMode,
284
+ disablePattern,
285
+ patternsColors,
286
+ patternsOrderedList,
287
+ doughnutDataProps.maxValues,
288
+ doughnutDataAndLabels,
289
+ enableHover
290
+ )
291
+ );
225
292
 
226
- onMounted(() =>{
227
- getBackgroundColor(patternsColors.value, patternsOrderedList.value, doughnutDataProps.disableAccessibility);
293
+ onMounted(() => {
294
+ getBackgroundColor(
295
+ patternsColors.value,
296
+ patternsOrderedList.value,
297
+ doughnutDataProps.disableAccessibility,
298
+ enableHover.value
299
+ );
228
300
  });
229
301
  watch(onHoverIndex, (newValue, oldValue) => {
230
- if (newValue !== oldValue) {
231
- getBackgroundColor(patternsColors.value, patternsOrderedList.value, doughnutDataProps.disableAccessibility);
302
+ if (newValue !== oldValue && enableHover.value) {
303
+ getBackgroundColor(
304
+ patternsColors.value,
305
+ patternsOrderedList.value,
306
+ doughnutDataProps.disableAccessibility,
307
+ enableHover.value
308
+ );
232
309
  }
233
310
  });
234
311
 
235
312
  watch(disablePattern, () => {
236
- getBackgroundColor(patternsColors.value, patternsOrderedList.value, doughnutDataProps.disableAccessibility)
313
+ getBackgroundColor(
314
+ patternsColors.value,
315
+ patternsOrderedList.value,
316
+ doughnutDataProps.disableAccessibility,
317
+ enableHover.value
318
+ );
237
319
  });
238
-
239
320
  </script>
240
321
 
241
322
  <style scoped>
@@ -252,4 +333,4 @@ watch(disablePattern, () => {
252
333
  justify-content: center;
253
334
  align-items: center;
254
335
  }
255
- </style>
336
+ </style>
@@ -13,7 +13,6 @@ type Story = StoryObj<typeof meta>;
13
13
 
14
14
  export const Default = {
15
15
  args: {
16
- rawTitle: "Line title",
17
16
  width: "600px",
18
17
  height: "400px",
19
18
  labels: ["Data One", "Data Two", "Data Three"],
@@ -29,6 +28,8 @@ export const Default = {
29
28
  unit: "%",
30
29
  },
31
30
  ],
31
+ xAxisTitle: 'X Axis Title',
32
+ yAxisTitle: 'Y Axis Title',
32
33
  },
33
34
  } satisfies Story;
34
35