chartjs-plugin-chart2music 0.0.4 → 0.0.6
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/README.md +47 -5
- package/dist/plugin.js +90 -7
- package/dist/plugin.mjs +90 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
# chartjs-plugin-chart2music
|
|
2
|
-
chartjs
|
|
2
|
+
[](https://badge.fury.io/js/chartjs-plugin-chart2music)
|
|
3
3
|
|
|
4
4
|
**This is a beta release of this plugin**
|
|
5
5
|
|
|
6
6
|
Turns your chart.js charts into music so the blind can hear data. This plugin will automatically add Chart2Music, an interactive sonification library, to your chart.js charts. The contents of the chart element will be modified to best support screen reader users, and the interactions will be visually synchronized to provide support for keyboard-only users.
|
|
7
7
|
|
|
8
|
+
[Check out our CodePen collection of examples using the plugin.](https://codepen.io/collection/VYEvEQ)
|
|
9
|
+
|
|
8
10
|
## Getting started
|
|
9
11
|
|
|
10
12
|
Add the chartjs2music plugin to your existing chart.js code like this:
|
|
11
13
|
|
|
12
14
|
```js
|
|
13
15
|
import {Chart} from "chart.js/auto";
|
|
14
|
-
import
|
|
16
|
+
import chartjs2music from "chartjs-plugin-chart2music";
|
|
15
17
|
|
|
16
|
-
Chart.register(
|
|
18
|
+
Chart.register(chartjs2music);
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
That will register the plugin globally. Alternatively, if you only want to enable for a given chart, you can do this:
|
|
@@ -34,13 +36,54 @@ new Chart(canvasElement, {
|
|
|
34
36
|
|
|
35
37
|
```
|
|
36
38
|
|
|
39
|
+
## Available options
|
|
40
|
+
|
|
41
|
+
The following plugin options are available:
|
|
42
|
+
* `errorCallback` - A callback that will return errors if any arise while the plugin works.
|
|
43
|
+
* `cc` - the equivalent of the [chart2music option `cc`](https://chart2music.com/docs/API/Config#axes)
|
|
44
|
+
* `audioEngine` - the equivalent of the [chart2music option `audioEngine`](https://chart2music.com/docs/API/Config#cc)
|
|
45
|
+
* `axes` - the equivalent of the [chart2music option `axes`](https://chart2music.com/docs/API/Config#axes)
|
|
46
|
+
|
|
47
|
+
Here's an example for providing options:
|
|
48
|
+
```js
|
|
49
|
+
import {Chart} from "chart.js/auto";
|
|
50
|
+
import chartjs2music from "chartjs-plugin-chart2music";
|
|
51
|
+
|
|
52
|
+
new Chart(canvasElement, {
|
|
53
|
+
type: "bar",
|
|
54
|
+
data: {
|
|
55
|
+
datasets: [{
|
|
56
|
+
data: [1,4,2,8]
|
|
57
|
+
}]
|
|
58
|
+
},
|
|
59
|
+
options: {
|
|
60
|
+
plugins: {
|
|
61
|
+
chartjs2music: {
|
|
62
|
+
// All errors should be logged as errors
|
|
63
|
+
errorCallback: console.error,
|
|
64
|
+
// Here's a div I made to be the CC
|
|
65
|
+
cc: myDiv,
|
|
66
|
+
// The Y values should all be money
|
|
67
|
+
axes: {
|
|
68
|
+
y: {
|
|
69
|
+
format: (value) => "$" + value
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
plugins: [chartjs2music]
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
37
79
|
## Supported features
|
|
38
80
|
|
|
39
81
|
This plugin is currently in beta, so not all of the chart.js features are currently supported.
|
|
40
82
|
|
|
41
83
|
A quick list of chart.js features we currently support includes:
|
|
42
|
-
* Chart types: bar, line, pie,
|
|
84
|
+
* Chart types: bar, doughnut, line, pie, polar, radar, scatter, and combinations therein.
|
|
43
85
|
* Boxplots using the `@sgratzl/chartjs-chart-boxplot` plugin (only support boxplots when there are no other chart types present)
|
|
86
|
+
* Wordclouds using the `chartjs-chart-wordcloud` plugin
|
|
44
87
|
* Axes options: `title`, `min`, `max`, `type="linear"`, `type="logarithmic"`.
|
|
45
88
|
* Chart title
|
|
46
89
|
* Most data structures (not including `parsing` or non-standard axes identifiers)
|
|
@@ -62,5 +105,4 @@ Plugins we plan to support in the future:
|
|
|
62
105
|
* [chartjs-char-error-bars](https://www.npmjs.com/package/chartjs-chart-error-bars)
|
|
63
106
|
* [chartjs-chart-matrix](https://www.npmjs.com/package/chartjs-chart-matrix)
|
|
64
107
|
* [chartjs-chart-pcp](https://www.npmjs.com/package/chartjs-chart-pcp)
|
|
65
|
-
* [chartjs-chart-wordcloud](https://www.npmjs.com/package/chartjs-chart-wordcloud)
|
|
66
108
|
* [chartjs-plugin-zoom](https://www.npmjs.com/package/chartjs-plugin-zoom)
|
package/dist/plugin.js
CHANGED
|
@@ -84,7 +84,8 @@ var chartjs2music = (function (c2mChart) {
|
|
|
84
84
|
doughnut: "pie",
|
|
85
85
|
boxplot: "box",
|
|
86
86
|
radar: "bar",
|
|
87
|
-
wordCloud: "bar"
|
|
87
|
+
wordCloud: "bar",
|
|
88
|
+
scatter: "scatter"
|
|
88
89
|
};
|
|
89
90
|
const processChartType = (chart) => {
|
|
90
91
|
const topLevelType = chart.config.type;
|
|
@@ -214,7 +215,7 @@ var chartjs2music = (function (c2mChart) {
|
|
|
214
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(", ")}`);
|
|
215
216
|
return;
|
|
216
217
|
}
|
|
217
|
-
|
|
218
|
+
let axes = generateAxes(chart);
|
|
218
219
|
if (chart.config.type === "wordCloud") {
|
|
219
220
|
delete axes.x.minimum;
|
|
220
221
|
delete axes.x.maximum;
|
|
@@ -237,6 +238,21 @@ var chartjs2music = (function (c2mChart) {
|
|
|
237
238
|
axes.x.valueLabels = scrub.labels.slice(0);
|
|
238
239
|
}
|
|
239
240
|
}
|
|
241
|
+
if (c2m_types === "scatter") {
|
|
242
|
+
delete scrub?.data;
|
|
243
|
+
delete axes.x.valueLabels;
|
|
244
|
+
}
|
|
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
|
+
};
|
|
240
256
|
const c2mOptions = {
|
|
241
257
|
cc,
|
|
242
258
|
element: chart.canvas,
|
|
@@ -246,12 +262,23 @@ var chartjs2music = (function (c2mChart) {
|
|
|
246
262
|
axes,
|
|
247
263
|
options: {
|
|
248
264
|
// @ts-ignore
|
|
249
|
-
onFocusCallback: ({
|
|
265
|
+
onFocusCallback: ({ point, index }) => {
|
|
250
266
|
try {
|
|
251
|
-
const highlightElements = [
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
+
for (let i = 0; i < (groups?.length ?? 1); i++) {
|
|
276
|
+
highlightElements.push({
|
|
277
|
+
datasetIndex: i,
|
|
278
|
+
index
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
255
282
|
chart?.setActiveElements(highlightElements);
|
|
256
283
|
chart?.tooltip?.setActiveElements(highlightElements, {});
|
|
257
284
|
chart?.update();
|
|
@@ -262,6 +289,62 @@ var chartjs2music = (function (c2mChart) {
|
|
|
262
289
|
}
|
|
263
290
|
}
|
|
264
291
|
};
|
|
292
|
+
if (Array.isArray(c2mOptions.data)) {
|
|
293
|
+
if (isNaN(c2mOptions.data[0])) {
|
|
294
|
+
c2mOptions.data = c2mOptions.data.map((point, index) => {
|
|
295
|
+
return {
|
|
296
|
+
...point,
|
|
297
|
+
custom: {
|
|
298
|
+
group: 0,
|
|
299
|
+
index
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
c2mOptions.data = c2mOptions.data.map((num, index) => {
|
|
306
|
+
return {
|
|
307
|
+
x: index,
|
|
308
|
+
y: num,
|
|
309
|
+
custom: {
|
|
310
|
+
group: 0,
|
|
311
|
+
index
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
}
|
|
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
|
+
}
|
|
265
348
|
if (options.audioEngine) {
|
|
266
349
|
// @ts-ignore
|
|
267
350
|
c2mOptions.audioEngine = options.audioEngine;
|
package/dist/plugin.mjs
CHANGED
|
@@ -83,7 +83,8 @@ const chartjs_c2m_converter = {
|
|
|
83
83
|
doughnut: "pie",
|
|
84
84
|
boxplot: "box",
|
|
85
85
|
radar: "bar",
|
|
86
|
-
wordCloud: "bar"
|
|
86
|
+
wordCloud: "bar",
|
|
87
|
+
scatter: "scatter"
|
|
87
88
|
};
|
|
88
89
|
const processChartType = (chart) => {
|
|
89
90
|
const topLevelType = chart.config.type;
|
|
@@ -213,7 +214,7 @@ const plugin = {
|
|
|
213
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(", ")}`);
|
|
214
215
|
return;
|
|
215
216
|
}
|
|
216
|
-
|
|
217
|
+
let axes = generateAxes(chart);
|
|
217
218
|
if (chart.config.type === "wordCloud") {
|
|
218
219
|
delete axes.x.minimum;
|
|
219
220
|
delete axes.x.maximum;
|
|
@@ -236,6 +237,21 @@ const plugin = {
|
|
|
236
237
|
axes.x.valueLabels = scrub.labels.slice(0);
|
|
237
238
|
}
|
|
238
239
|
}
|
|
240
|
+
if (c2m_types === "scatter") {
|
|
241
|
+
delete scrub?.data;
|
|
242
|
+
delete axes.x.valueLabels;
|
|
243
|
+
}
|
|
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
|
+
};
|
|
239
255
|
const c2mOptions = {
|
|
240
256
|
cc,
|
|
241
257
|
element: chart.canvas,
|
|
@@ -245,12 +261,23 @@ const plugin = {
|
|
|
245
261
|
axes,
|
|
246
262
|
options: {
|
|
247
263
|
// @ts-ignore
|
|
248
|
-
onFocusCallback: ({
|
|
264
|
+
onFocusCallback: ({ point, index }) => {
|
|
249
265
|
try {
|
|
250
|
-
const highlightElements = [
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
+
for (let i = 0; i < (groups?.length ?? 1); i++) {
|
|
275
|
+
highlightElements.push({
|
|
276
|
+
datasetIndex: i,
|
|
277
|
+
index
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
254
281
|
chart?.setActiveElements(highlightElements);
|
|
255
282
|
chart?.tooltip?.setActiveElements(highlightElements, {});
|
|
256
283
|
chart?.update();
|
|
@@ -261,6 +288,62 @@ const plugin = {
|
|
|
261
288
|
}
|
|
262
289
|
}
|
|
263
290
|
};
|
|
291
|
+
if (Array.isArray(c2mOptions.data)) {
|
|
292
|
+
if (isNaN(c2mOptions.data[0])) {
|
|
293
|
+
c2mOptions.data = c2mOptions.data.map((point, index) => {
|
|
294
|
+
return {
|
|
295
|
+
...point,
|
|
296
|
+
custom: {
|
|
297
|
+
group: 0,
|
|
298
|
+
index
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
c2mOptions.data = c2mOptions.data.map((num, index) => {
|
|
305
|
+
return {
|
|
306
|
+
x: index,
|
|
307
|
+
y: num,
|
|
308
|
+
custom: {
|
|
309
|
+
group: 0,
|
|
310
|
+
index
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
const groups = Object.keys(c2mOptions.data);
|
|
318
|
+
groups.forEach((groupName, groupNumber) => {
|
|
319
|
+
if (!isNaN(c2mOptions.data[groupName][0])) {
|
|
320
|
+
c2mOptions.data[groupName] = c2mOptions.data[groupName].map((num, index) => {
|
|
321
|
+
return {
|
|
322
|
+
x: index,
|
|
323
|
+
y: num,
|
|
324
|
+
custom: {
|
|
325
|
+
group: groupNumber,
|
|
326
|
+
index
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
|
|
333
|
+
return {
|
|
334
|
+
...point,
|
|
335
|
+
custom: {
|
|
336
|
+
group: groupNumber,
|
|
337
|
+
index
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
if (chart.config.options?.scales?.x?.stacked) {
|
|
345
|
+
c2mOptions.options.stack = true;
|
|
346
|
+
}
|
|
264
347
|
if (options.audioEngine) {
|
|
265
348
|
// @ts-ignore
|
|
266
349
|
c2mOptions.audioEngine = options.audioEngine;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartjs-plugin-chart2music",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
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",
|
|
@@ -54,6 +54,6 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"chart.js": "^4.2.1",
|
|
57
|
-
"chart2music": "^1.
|
|
57
|
+
"chart2music": "^1.9.0"
|
|
58
58
|
}
|
|
59
59
|
}
|