chartjs-plugin-chart2music 0.1.3 → 0.1.5

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 (3) hide show
  1. package/dist/plugin.js +171 -130
  2. package/dist/plugin.mjs +171 -130
  3. package/package.json +9 -9
package/dist/plugin.js CHANGED
@@ -207,168 +207,209 @@ var chartjs2music = (function (c2mChart) {
207
207
  canvas.insertAdjacentElement("afterend", cc);
208
208
  return cc;
209
209
  };
210
- const plugin = {
211
- id: "chartjs2music",
212
- afterInit: (chart, args, options) => {
213
- const { valid, c2m_types, invalidType } = processChartType(chart);
214
- if (!valid) {
215
- options.errorCallback?.(`Unable to connect chart2music to chart. The chart is of type "${invalidType}", which is not one of the supported chart types for this plugin. This plugin supports: ${Object.keys(chartjs_c2m_converter).join(", ")}`);
216
- return;
210
+ const displayPoint = (chart) => {
211
+ if (!chartStates.has(chart)) {
212
+ return;
213
+ }
214
+ const { c2m: ref, visible_groups } = chartStates.get(chart);
215
+ const { point, index } = ref.getCurrent();
216
+ try {
217
+ const highlightElements = [];
218
+ if ("custom" in point) {
219
+ highlightElements.push({
220
+ // @ts-ignore
221
+ datasetIndex: point.custom.group,
222
+ // @ts-ignore
223
+ index: point.custom.index
224
+ });
217
225
  }
218
- let axes = generateAxes(chart);
219
- if (chart.config.type === "wordCloud") {
220
- delete axes.x.minimum;
221
- delete axes.x.maximum;
222
- delete axes.y.minimum;
223
- delete axes.y.maximum;
224
- if (!axes.x.label) {
225
- axes.x.label = "Word";
226
- }
227
- if (!axes.y.label) {
228
- axes.y.label = "Emphasis";
229
- }
226
+ else {
227
+ visible_groups.forEach((datasetIndex) => {
228
+ highlightElements.push({
229
+ datasetIndex,
230
+ index
231
+ });
232
+ });
230
233
  }
231
- // Generate CC element
232
- const cc = determineCCElement(chart.canvas, options.cc);
233
- const { data, groups } = processData(chart.data, c2m_types);
234
- // lastDataObj = JSON.stringify(data);
235
- let scrub = scrubX(data);
236
- if (scrub?.labels && scrub?.labels?.length > 0) { // Something was scrubbed
237
- if (!chart.data.labels || chart.data.labels.length === 0) {
238
- axes.x.valueLabels = scrub.labels.slice(0);
239
- }
234
+ chart?.setActiveElements(highlightElements);
235
+ chart?.tooltip?.setActiveElements(highlightElements, {});
236
+ chart?.update();
237
+ }
238
+ catch (e) {
239
+ // console.warn(e);
240
+ }
241
+ };
242
+ const generateChart = (chart, options) => {
243
+ const { valid, c2m_types, invalidType } = processChartType(chart);
244
+ if (!valid) {
245
+ // @ts-ignore
246
+ options.errorCallback?.(`Unable to connect chart2music to chart. The chart is of type "${invalidType}", which is not one of the supported chart types for this plugin. This plugin supports: ${Object.keys(chartjs_c2m_converter).join(", ")}`);
247
+ return;
248
+ }
249
+ let axes = generateAxes(chart);
250
+ if (chart.config.type === "wordCloud") {
251
+ delete axes.x.minimum;
252
+ delete axes.x.maximum;
253
+ delete axes.y.minimum;
254
+ delete axes.y.maximum;
255
+ if (!axes.x.label) {
256
+ axes.x.label = "Word";
240
257
  }
241
- if (c2m_types === "scatter") {
242
- delete scrub?.data;
243
- delete axes.x.valueLabels;
258
+ if (!axes.y.label) {
259
+ axes.y.label = "Emphasis";
244
260
  }
245
- axes = {
246
- ...axes,
247
- x: {
248
- ...axes.x,
249
- ...(options.axes?.x)
250
- },
251
- y: {
252
- ...axes.y,
253
- ...(options.axes?.y)
254
- },
255
- };
256
- const c2mOptions = {
257
- cc,
258
- element: chart.canvas,
259
- type: c2m_types,
260
- data: scrub?.data ?? data,
261
- title: determineChartTitle(chart.options),
262
- axes,
263
- options: {
264
- // @ts-ignore
265
- onFocusCallback: ({ point, index }) => {
266
- try {
267
- const highlightElements = [];
268
- if ("custom" in point) {
269
- highlightElements.push({
270
- datasetIndex: point.custom.group,
271
- index: point.custom.index
272
- });
273
- }
274
- else {
275
- const { visible_groups } = chartStates.get(chart);
276
- visible_groups.forEach((datasetIndex) => {
277
- highlightElements.push({
278
- datasetIndex,
279
- index
280
- });
281
- });
282
- }
283
- chart?.setActiveElements(highlightElements);
284
- chart?.tooltip?.setActiveElements(highlightElements, {});
285
- chart?.update();
261
+ }
262
+ // Generate CC element
263
+ const cc = determineCCElement(chart.canvas, options.cc);
264
+ const { data, groups } = processData(chart.data, c2m_types);
265
+ // lastDataObj = JSON.stringify(data);
266
+ let scrub = scrubX(data);
267
+ if (scrub?.labels && scrub?.labels?.length > 0) { // Something was scrubbed
268
+ if (!chart.data.labels || chart.data.labels.length === 0) {
269
+ axes.x.valueLabels = scrub.labels.slice(0);
270
+ }
271
+ }
272
+ if (c2m_types === "scatter") {
273
+ delete scrub?.data;
274
+ delete axes.x.valueLabels;
275
+ }
276
+ axes = {
277
+ ...axes,
278
+ x: {
279
+ ...axes.x,
280
+ ...(options.axes?.x)
281
+ },
282
+ y: {
283
+ ...axes.y,
284
+ ...(options.axes?.y)
285
+ },
286
+ };
287
+ const c2mOptions = {
288
+ cc,
289
+ element: chart.canvas,
290
+ type: c2m_types,
291
+ data: scrub?.data ?? data,
292
+ title: determineChartTitle(chart.options),
293
+ axes,
294
+ options: {
295
+ // @ts-ignore
296
+ onFocusCallback: () => {
297
+ displayPoint(chart);
298
+ }
299
+ }
300
+ };
301
+ if (Array.isArray(c2mOptions.data)) {
302
+ if (isNaN(c2mOptions.data[0])) {
303
+ c2mOptions.data = c2mOptions.data.map((point, index) => {
304
+ return {
305
+ ...point,
306
+ custom: {
307
+ group: 0,
308
+ index
286
309
  }
287
- catch (e) {
288
- // console.warn(e);
310
+ };
311
+ });
312
+ }
313
+ else {
314
+ c2mOptions.data = c2mOptions.data.map((num, index) => {
315
+ return {
316
+ x: index,
317
+ y: num,
318
+ custom: {
319
+ group: 0,
320
+ index
289
321
  }
290
- }
291
- }
292
- };
293
- if (Array.isArray(c2mOptions.data)) {
294
- if (isNaN(c2mOptions.data[0])) {
295
- c2mOptions.data = c2mOptions.data.map((point, index) => {
322
+ };
323
+ });
324
+ }
325
+ }
326
+ else {
327
+ const groups = Object.keys(c2mOptions.data);
328
+ groups.forEach((groupName, groupNumber) => {
329
+ if (!isNaN(c2mOptions.data[groupName][0])) {
330
+ c2mOptions.data[groupName] = c2mOptions.data[groupName].map((num, index) => {
296
331
  return {
297
- ...point,
332
+ x: index,
333
+ y: num,
298
334
  custom: {
299
- group: 0,
335
+ group: groupNumber,
300
336
  index
301
337
  }
302
338
  };
303
339
  });
304
340
  }
305
341
  else {
306
- c2mOptions.data = c2mOptions.data.map((num, index) => {
342
+ c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
307
343
  return {
308
- x: index,
309
- y: num,
344
+ ...point,
310
345
  custom: {
311
- group: 0,
346
+ group: groupNumber,
312
347
  index
313
348
  }
314
349
  };
315
350
  });
316
351
  }
317
- }
318
- else {
319
- const groups = Object.keys(c2mOptions.data);
320
- groups.forEach((groupName, groupNumber) => {
321
- if (!isNaN(c2mOptions.data[groupName][0])) {
322
- c2mOptions.data[groupName] = c2mOptions.data[groupName].map((num, index) => {
323
- return {
324
- x: index,
325
- y: num,
326
- custom: {
327
- group: groupNumber,
328
- index
329
- }
330
- };
331
- });
332
- }
333
- else {
334
- c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
335
- return {
336
- ...point,
337
- custom: {
338
- group: groupNumber,
339
- index
340
- }
341
- };
342
- });
343
- }
344
- });
345
- }
346
- if (chart.config.options?.scales?.x?.stacked) {
347
- c2mOptions.options.stack = true;
348
- }
349
- if (options.audioEngine) {
350
- // @ts-ignore
351
- c2mOptions.audioEngine = options.audioEngine;
352
- }
353
- const { err, data: c2m } = c2mChart(c2mOptions);
354
- chartStates.set(chart, {
355
- c2m,
356
- visible_groups: groups?.map((g, i) => i)
357
352
  });
358
- // /* istanbul-ignore-next */
359
- if (err) {
360
- options.errorCallback?.(err);
353
+ }
354
+ // @ts-ignore
355
+ if (chart.config.options?.scales?.x?.stacked) {
356
+ // @ts-ignore
357
+ c2mOptions.options.stack = true;
358
+ }
359
+ // @ts-ignore
360
+ if (options.audioEngine) {
361
+ // @ts-ignore
362
+ c2mOptions.audioEngine = options.audioEngine;
363
+ }
364
+ if (c2mOptions.data.length === 0) {
365
+ return;
366
+ }
367
+ const { err, data: c2m } = c2mChart(c2mOptions);
368
+ /* istanbul-ignore-next */
369
+ if (err) {
370
+ // @ts-ignore
371
+ options.errorCallback?.(err);
372
+ return;
373
+ }
374
+ if (!c2m) {
375
+ return;
376
+ }
377
+ chartStates.set(chart, {
378
+ c2m,
379
+ visible_groups: groups?.map((g, i) => i) ?? []
380
+ });
381
+ };
382
+ const plugin = {
383
+ id: "chartjs2music",
384
+ afterInit: (chart, args, options) => {
385
+ if (!chartStates.has(chart)) {
386
+ generateChart(chart, options);
387
+ // Remove tooltip when the chart blurs
388
+ chart.canvas.addEventListener("blur", () => {
389
+ chart.setActiveElements([]);
390
+ chart.tooltip?.setActiveElements([], {});
391
+ chart.update();
392
+ });
393
+ // Show tooltip when the chart receives focus
394
+ chart.canvas.addEventListener("focus", () => {
395
+ displayPoint(chart);
396
+ });
361
397
  }
362
398
  },
363
- afterDatasetUpdate: (chart, args) => {
399
+ afterDatasetUpdate: (chart, args, options) => {
364
400
  if (!args.mode) {
365
401
  return;
366
402
  }
403
+ if (!chartStates.has(chart)) {
404
+ generateChart(chart, options);
405
+ }
367
406
  const { c2m: ref, visible_groups } = chartStates.get(chart);
368
407
  if (!ref) {
369
408
  return;
370
409
  }
410
+ // @ts-ignore
371
411
  const groups = ref._groups.slice(0);
412
+ // @ts-ignore
372
413
  if (ref._options.stack) {
373
414
  groups.shift();
374
415
  }
package/dist/plugin.mjs CHANGED
@@ -206,168 +206,209 @@ const determineCCElement = (canvas, provided) => {
206
206
  canvas.insertAdjacentElement("afterend", cc);
207
207
  return cc;
208
208
  };
209
- const plugin = {
210
- id: "chartjs2music",
211
- afterInit: (chart, args, options) => {
212
- const { valid, c2m_types, invalidType } = processChartType(chart);
213
- if (!valid) {
214
- options.errorCallback?.(`Unable to connect chart2music to chart. The chart is of type "${invalidType}", which is not one of the supported chart types for this plugin. This plugin supports: ${Object.keys(chartjs_c2m_converter).join(", ")}`);
215
- return;
209
+ const displayPoint = (chart) => {
210
+ if (!chartStates.has(chart)) {
211
+ return;
212
+ }
213
+ const { c2m: ref, visible_groups } = chartStates.get(chart);
214
+ const { point, index } = ref.getCurrent();
215
+ try {
216
+ const highlightElements = [];
217
+ if ("custom" in point) {
218
+ highlightElements.push({
219
+ // @ts-ignore
220
+ datasetIndex: point.custom.group,
221
+ // @ts-ignore
222
+ index: point.custom.index
223
+ });
216
224
  }
217
- let axes = generateAxes(chart);
218
- if (chart.config.type === "wordCloud") {
219
- delete axes.x.minimum;
220
- delete axes.x.maximum;
221
- delete axes.y.minimum;
222
- delete axes.y.maximum;
223
- if (!axes.x.label) {
224
- axes.x.label = "Word";
225
- }
226
- if (!axes.y.label) {
227
- axes.y.label = "Emphasis";
228
- }
225
+ else {
226
+ visible_groups.forEach((datasetIndex) => {
227
+ highlightElements.push({
228
+ datasetIndex,
229
+ index
230
+ });
231
+ });
229
232
  }
230
- // Generate CC element
231
- const cc = determineCCElement(chart.canvas, options.cc);
232
- const { data, groups } = processData(chart.data, c2m_types);
233
- // lastDataObj = JSON.stringify(data);
234
- let scrub = scrubX(data);
235
- if (scrub?.labels && scrub?.labels?.length > 0) { // Something was scrubbed
236
- if (!chart.data.labels || chart.data.labels.length === 0) {
237
- axes.x.valueLabels = scrub.labels.slice(0);
238
- }
233
+ chart?.setActiveElements(highlightElements);
234
+ chart?.tooltip?.setActiveElements(highlightElements, {});
235
+ chart?.update();
236
+ }
237
+ catch (e) {
238
+ // console.warn(e);
239
+ }
240
+ };
241
+ const generateChart = (chart, options) => {
242
+ const { valid, c2m_types, invalidType } = processChartType(chart);
243
+ if (!valid) {
244
+ // @ts-ignore
245
+ options.errorCallback?.(`Unable to connect chart2music to chart. The chart is of type "${invalidType}", which is not one of the supported chart types for this plugin. This plugin supports: ${Object.keys(chartjs_c2m_converter).join(", ")}`);
246
+ return;
247
+ }
248
+ let axes = generateAxes(chart);
249
+ if (chart.config.type === "wordCloud") {
250
+ delete axes.x.minimum;
251
+ delete axes.x.maximum;
252
+ delete axes.y.minimum;
253
+ delete axes.y.maximum;
254
+ if (!axes.x.label) {
255
+ axes.x.label = "Word";
239
256
  }
240
- if (c2m_types === "scatter") {
241
- delete scrub?.data;
242
- delete axes.x.valueLabels;
257
+ if (!axes.y.label) {
258
+ axes.y.label = "Emphasis";
243
259
  }
244
- axes = {
245
- ...axes,
246
- x: {
247
- ...axes.x,
248
- ...(options.axes?.x)
249
- },
250
- y: {
251
- ...axes.y,
252
- ...(options.axes?.y)
253
- },
254
- };
255
- const c2mOptions = {
256
- cc,
257
- element: chart.canvas,
258
- type: c2m_types,
259
- data: scrub?.data ?? data,
260
- title: determineChartTitle(chart.options),
261
- axes,
262
- options: {
263
- // @ts-ignore
264
- onFocusCallback: ({ point, index }) => {
265
- try {
266
- const highlightElements = [];
267
- if ("custom" in point) {
268
- highlightElements.push({
269
- datasetIndex: point.custom.group,
270
- index: point.custom.index
271
- });
272
- }
273
- else {
274
- const { visible_groups } = chartStates.get(chart);
275
- visible_groups.forEach((datasetIndex) => {
276
- highlightElements.push({
277
- datasetIndex,
278
- index
279
- });
280
- });
281
- }
282
- chart?.setActiveElements(highlightElements);
283
- chart?.tooltip?.setActiveElements(highlightElements, {});
284
- chart?.update();
260
+ }
261
+ // Generate CC element
262
+ const cc = determineCCElement(chart.canvas, options.cc);
263
+ const { data, groups } = processData(chart.data, c2m_types);
264
+ // lastDataObj = JSON.stringify(data);
265
+ let scrub = scrubX(data);
266
+ if (scrub?.labels && scrub?.labels?.length > 0) { // Something was scrubbed
267
+ if (!chart.data.labels || chart.data.labels.length === 0) {
268
+ axes.x.valueLabels = scrub.labels.slice(0);
269
+ }
270
+ }
271
+ if (c2m_types === "scatter") {
272
+ delete scrub?.data;
273
+ delete axes.x.valueLabels;
274
+ }
275
+ axes = {
276
+ ...axes,
277
+ x: {
278
+ ...axes.x,
279
+ ...(options.axes?.x)
280
+ },
281
+ y: {
282
+ ...axes.y,
283
+ ...(options.axes?.y)
284
+ },
285
+ };
286
+ const c2mOptions = {
287
+ cc,
288
+ element: chart.canvas,
289
+ type: c2m_types,
290
+ data: scrub?.data ?? data,
291
+ title: determineChartTitle(chart.options),
292
+ axes,
293
+ options: {
294
+ // @ts-ignore
295
+ onFocusCallback: () => {
296
+ displayPoint(chart);
297
+ }
298
+ }
299
+ };
300
+ if (Array.isArray(c2mOptions.data)) {
301
+ if (isNaN(c2mOptions.data[0])) {
302
+ c2mOptions.data = c2mOptions.data.map((point, index) => {
303
+ return {
304
+ ...point,
305
+ custom: {
306
+ group: 0,
307
+ index
285
308
  }
286
- catch (e) {
287
- // console.warn(e);
309
+ };
310
+ });
311
+ }
312
+ else {
313
+ c2mOptions.data = c2mOptions.data.map((num, index) => {
314
+ return {
315
+ x: index,
316
+ y: num,
317
+ custom: {
318
+ group: 0,
319
+ index
288
320
  }
289
- }
290
- }
291
- };
292
- if (Array.isArray(c2mOptions.data)) {
293
- if (isNaN(c2mOptions.data[0])) {
294
- c2mOptions.data = c2mOptions.data.map((point, index) => {
321
+ };
322
+ });
323
+ }
324
+ }
325
+ else {
326
+ const groups = Object.keys(c2mOptions.data);
327
+ groups.forEach((groupName, groupNumber) => {
328
+ if (!isNaN(c2mOptions.data[groupName][0])) {
329
+ c2mOptions.data[groupName] = c2mOptions.data[groupName].map((num, index) => {
295
330
  return {
296
- ...point,
331
+ x: index,
332
+ y: num,
297
333
  custom: {
298
- group: 0,
334
+ group: groupNumber,
299
335
  index
300
336
  }
301
337
  };
302
338
  });
303
339
  }
304
340
  else {
305
- c2mOptions.data = c2mOptions.data.map((num, index) => {
341
+ c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
306
342
  return {
307
- x: index,
308
- y: num,
343
+ ...point,
309
344
  custom: {
310
- group: 0,
345
+ group: groupNumber,
311
346
  index
312
347
  }
313
348
  };
314
349
  });
315
350
  }
316
- }
317
- else {
318
- const groups = Object.keys(c2mOptions.data);
319
- groups.forEach((groupName, groupNumber) => {
320
- if (!isNaN(c2mOptions.data[groupName][0])) {
321
- c2mOptions.data[groupName] = c2mOptions.data[groupName].map((num, index) => {
322
- return {
323
- x: index,
324
- y: num,
325
- custom: {
326
- group: groupNumber,
327
- index
328
- }
329
- };
330
- });
331
- }
332
- else {
333
- c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
334
- return {
335
- ...point,
336
- custom: {
337
- group: groupNumber,
338
- index
339
- }
340
- };
341
- });
342
- }
343
- });
344
- }
345
- if (chart.config.options?.scales?.x?.stacked) {
346
- c2mOptions.options.stack = true;
347
- }
348
- if (options.audioEngine) {
349
- // @ts-ignore
350
- c2mOptions.audioEngine = options.audioEngine;
351
- }
352
- const { err, data: c2m } = c2mChart(c2mOptions);
353
- chartStates.set(chart, {
354
- c2m,
355
- visible_groups: groups?.map((g, i) => i)
356
351
  });
357
- // /* istanbul-ignore-next */
358
- if (err) {
359
- options.errorCallback?.(err);
352
+ }
353
+ // @ts-ignore
354
+ if (chart.config.options?.scales?.x?.stacked) {
355
+ // @ts-ignore
356
+ c2mOptions.options.stack = true;
357
+ }
358
+ // @ts-ignore
359
+ if (options.audioEngine) {
360
+ // @ts-ignore
361
+ c2mOptions.audioEngine = options.audioEngine;
362
+ }
363
+ if (c2mOptions.data.length === 0) {
364
+ return;
365
+ }
366
+ const { err, data: c2m } = c2mChart(c2mOptions);
367
+ /* istanbul-ignore-next */
368
+ if (err) {
369
+ // @ts-ignore
370
+ options.errorCallback?.(err);
371
+ return;
372
+ }
373
+ if (!c2m) {
374
+ return;
375
+ }
376
+ chartStates.set(chart, {
377
+ c2m,
378
+ visible_groups: groups?.map((g, i) => i) ?? []
379
+ });
380
+ };
381
+ const plugin = {
382
+ id: "chartjs2music",
383
+ afterInit: (chart, args, options) => {
384
+ if (!chartStates.has(chart)) {
385
+ generateChart(chart, options);
386
+ // Remove tooltip when the chart blurs
387
+ chart.canvas.addEventListener("blur", () => {
388
+ chart.setActiveElements([]);
389
+ chart.tooltip?.setActiveElements([], {});
390
+ chart.update();
391
+ });
392
+ // Show tooltip when the chart receives focus
393
+ chart.canvas.addEventListener("focus", () => {
394
+ displayPoint(chart);
395
+ });
360
396
  }
361
397
  },
362
- afterDatasetUpdate: (chart, args) => {
398
+ afterDatasetUpdate: (chart, args, options) => {
363
399
  if (!args.mode) {
364
400
  return;
365
401
  }
402
+ if (!chartStates.has(chart)) {
403
+ generateChart(chart, options);
404
+ }
366
405
  const { c2m: ref, visible_groups } = chartStates.get(chart);
367
406
  if (!ref) {
368
407
  return;
369
408
  }
409
+ // @ts-ignore
370
410
  const groups = ref._groups.slice(0);
411
+ // @ts-ignore
371
412
  if (ref._options.stack) {
372
413
  groups.shift();
373
414
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chartjs-plugin-chart2music",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "description": "Chart.js plugin for Chart2Music. Turns chart.js charts into music so the blind can hear data.",
6
6
  "main": "dist/plugin.js",
@@ -36,22 +36,22 @@
36
36
  "clean": "rimraf dist coverage"
37
37
  },
38
38
  "devDependencies": {
39
- "@rollup/plugin-typescript": "11.1.4",
40
- "@sgratzl/chartjs-chart-boxplot": "4.2.5",
41
- "@types/jest": "29.5.5",
39
+ "@rollup/plugin-typescript": "11.1.5",
40
+ "@sgratzl/chartjs-chart-boxplot": "4.2.7",
41
+ "@types/jest": "29.5.6",
42
42
  "canvas": "2.11.2",
43
- "chartjs-chart-wordcloud": "4.3.0",
44
- "chartjs-plugin-a11y-legend": "0.1.0",
43
+ "chartjs-chart-wordcloud": "4.3.2",
44
+ "chartjs-plugin-a11y-legend": "0.1.1",
45
45
  "cross-env": "7.0.3",
46
- "depcheck": "1.4.6",
46
+ "depcheck": "1.4.7",
47
47
  "jest": "29.7.0",
48
48
  "jest-environment-jsdom": "29.7.0",
49
49
  "rimraf": "5.0.5",
50
- "rollup": "3.29.4",
50
+ "rollup": "4.1.5",
51
51
  "ts-jest": "29.1.1",
52
52
  "tslib": "2.6.2",
53
53
  "typescript": "5.2.2",
54
- "vite": "4.4.9"
54
+ "vite": "4.5.0"
55
55
  },
56
56
  "dependencies": {
57
57
  "chart.js": "4.4.0",