chartjs-plugin-chart2music 0.1.4 → 0.2.0
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/dist/plugin.cjs +502 -0
- package/dist/plugin.js +175 -132
- package/dist/plugin.mjs +175 -132
- package/package.json +20 -14
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = void 0;
|
|
7
|
+
var _chart2music = _interopRequireDefault(require("chart2music"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
9
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
10
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
11
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
12
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
13
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
14
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
15
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
16
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
17
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
18
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
19
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
20
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
21
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
22
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
23
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
24
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
25
|
+
var calcMedian = function calcMedian(nums) {
|
|
26
|
+
return nums.length % 2 ? nums[Math.floor(nums.length / 2)] : (nums[nums.length / 2] + nums[nums.length / 2 - 1]) / 2;
|
|
27
|
+
};
|
|
28
|
+
var fiveNumberSummary = function fiveNumberSummary(nums) {
|
|
29
|
+
var sortedNumbers = nums.sort();
|
|
30
|
+
var min, max, q1, q3;
|
|
31
|
+
var datamin = Math.min.apply(Math, _toConsumableArray(sortedNumbers));
|
|
32
|
+
var datamax = Math.max.apply(Math, _toConsumableArray(sortedNumbers));
|
|
33
|
+
var median = calcMedian(sortedNumbers);
|
|
34
|
+
var length = sortedNumbers.length;
|
|
35
|
+
if (length % 2) {
|
|
36
|
+
q1 = calcMedian(sortedNumbers.slice(0, Math.floor(length / 2)));
|
|
37
|
+
q3 = calcMedian(sortedNumbers.slice(Math.ceil(length % 2)));
|
|
38
|
+
} else {
|
|
39
|
+
q1 = calcMedian(sortedNumbers.slice(0, length / 2 - 1));
|
|
40
|
+
q3 = calcMedian(sortedNumbers.slice(length / 2));
|
|
41
|
+
}
|
|
42
|
+
var iqr = q3 - q1;
|
|
43
|
+
if (datamax < q3 + iqr) {
|
|
44
|
+
max = datamax;
|
|
45
|
+
} else {
|
|
46
|
+
var _sortedNumbers$revers;
|
|
47
|
+
max = (_sortedNumbers$revers = sortedNumbers.reverse().find(function (num) {
|
|
48
|
+
return num < datamax;
|
|
49
|
+
})) !== null && _sortedNumbers$revers !== void 0 ? _sortedNumbers$revers : datamax;
|
|
50
|
+
}
|
|
51
|
+
if (datamin < q1 - iqr) {
|
|
52
|
+
min = datamin;
|
|
53
|
+
} else {
|
|
54
|
+
var _sortedNumbers$revers2;
|
|
55
|
+
min = (_sortedNumbers$revers2 = sortedNumbers.reverse().find(function (num) {
|
|
56
|
+
return num < datamin;
|
|
57
|
+
})) !== null && _sortedNumbers$revers2 !== void 0 ? _sortedNumbers$revers2 : datamin;
|
|
58
|
+
}
|
|
59
|
+
var outlier = sortedNumbers.filter(function (num) {
|
|
60
|
+
return num < min || num > max;
|
|
61
|
+
});
|
|
62
|
+
return _objectSpread({
|
|
63
|
+
low: min,
|
|
64
|
+
high: max,
|
|
65
|
+
median: median,
|
|
66
|
+
q1: q1,
|
|
67
|
+
q3: q3
|
|
68
|
+
}, outlier.length > 0 ? {
|
|
69
|
+
outlier: outlier
|
|
70
|
+
} : {});
|
|
71
|
+
};
|
|
72
|
+
var whichBoxData = function whichBoxData(data) {
|
|
73
|
+
return data.map(function (row, index) {
|
|
74
|
+
if (_typeof(row) === "object" && "min" in row) {
|
|
75
|
+
return _objectSpread(_objectSpread({}, row), {}, {
|
|
76
|
+
low: row.min,
|
|
77
|
+
high: row.max,
|
|
78
|
+
x: index
|
|
79
|
+
}, "outliers" in row ? {
|
|
80
|
+
outlier: row.outliers
|
|
81
|
+
} : {});
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(row)) {
|
|
84
|
+
return _objectSpread(_objectSpread({}, fiveNumberSummary(row)), {}, {
|
|
85
|
+
x: index
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
var processBoxData = function processBoxData(data) {
|
|
91
|
+
if (data.datasets.length === 1) {
|
|
92
|
+
return {
|
|
93
|
+
data: whichBoxData(data.datasets[0].data)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
var groups = [];
|
|
97
|
+
var result = {};
|
|
98
|
+
data.datasets.forEach(function (obj, index) {
|
|
99
|
+
var _obj$label;
|
|
100
|
+
var groupName = (_obj$label = obj.label) !== null && _obj$label !== void 0 ? _obj$label : "Group ".concat(index + 1);
|
|
101
|
+
groups.push(groupName);
|
|
102
|
+
result[groupName] = whichBoxData(obj.data);
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
groups: groups,
|
|
106
|
+
data: result
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
var chartStates = new Map();
|
|
110
|
+
var chartjs_c2m_converter = {
|
|
111
|
+
bar: "bar",
|
|
112
|
+
line: "line",
|
|
113
|
+
pie: "pie",
|
|
114
|
+
polarArea: "bar",
|
|
115
|
+
doughnut: "pie",
|
|
116
|
+
boxplot: "box",
|
|
117
|
+
radar: "bar",
|
|
118
|
+
wordCloud: "bar",
|
|
119
|
+
scatter: "scatter"
|
|
120
|
+
};
|
|
121
|
+
var processChartType = function processChartType(chart) {
|
|
122
|
+
var topLevelType = chart.config.type;
|
|
123
|
+
var panelTypes = chart.data.datasets.map(function (_ref) {
|
|
124
|
+
var type = _ref.type;
|
|
125
|
+
return type !== null && type !== void 0 ? type : topLevelType;
|
|
126
|
+
});
|
|
127
|
+
var invalid = panelTypes.find(function (t) {
|
|
128
|
+
return !(t in chartjs_c2m_converter);
|
|
129
|
+
});
|
|
130
|
+
if (invalid) {
|
|
131
|
+
return {
|
|
132
|
+
valid: false,
|
|
133
|
+
invalidType: invalid
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (_toConsumableArray(new Set(panelTypes)).length === 1) {
|
|
137
|
+
return {
|
|
138
|
+
valid: true,
|
|
139
|
+
c2m_types: chartjs_c2m_converter[panelTypes[0]]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
valid: true,
|
|
144
|
+
c2m_types: panelTypes.map(function (t) {
|
|
145
|
+
return chartjs_c2m_converter[t];
|
|
146
|
+
})
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
var generateAxisInfo = function generateAxisInfo(chartAxisInfo, chart) {
|
|
150
|
+
var _chartAxisInfo$title;
|
|
151
|
+
var axis = {};
|
|
152
|
+
if (chartAxisInfo !== null && chartAxisInfo !== void 0 && chartAxisInfo.min) {
|
|
153
|
+
if (typeof chartAxisInfo.min === "string") {
|
|
154
|
+
axis.minimum = chart.data.labels.indexOf(chartAxisInfo.min);
|
|
155
|
+
} else {
|
|
156
|
+
axis.minimum = chartAxisInfo.min;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (chartAxisInfo !== null && chartAxisInfo !== void 0 && chartAxisInfo.max) {
|
|
160
|
+
if (typeof chartAxisInfo.max === "string") {
|
|
161
|
+
axis.maximum = chart.data.labels.indexOf(chartAxisInfo.max);
|
|
162
|
+
} else {
|
|
163
|
+
axis.maximum = chartAxisInfo.max;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
var label = chartAxisInfo === null || chartAxisInfo === void 0 || (_chartAxisInfo$title = chartAxisInfo.title) === null || _chartAxisInfo$title === void 0 ? void 0 : _chartAxisInfo$title.text;
|
|
167
|
+
if (label) {
|
|
168
|
+
axis.label = label;
|
|
169
|
+
}
|
|
170
|
+
if ((chartAxisInfo === null || chartAxisInfo === void 0 ? void 0 : chartAxisInfo.type) === "logarithmic") {
|
|
171
|
+
axis.type = "log10";
|
|
172
|
+
}
|
|
173
|
+
return axis;
|
|
174
|
+
};
|
|
175
|
+
var generateAxes = function generateAxes(chart) {
|
|
176
|
+
var _chart$options, _chart$options2;
|
|
177
|
+
var axes = {
|
|
178
|
+
x: _objectSpread(_objectSpread({}, generateAxisInfo((_chart$options = chart.options) === null || _chart$options === void 0 || (_chart$options = _chart$options.scales) === null || _chart$options === void 0 ? void 0 : _chart$options.x, chart)), {}, {
|
|
179
|
+
valueLabels: chart.data.labels.slice(0)
|
|
180
|
+
}),
|
|
181
|
+
y: _objectSpread(_objectSpread({}, generateAxisInfo((_chart$options2 = chart.options) === null || _chart$options2 === void 0 || (_chart$options2 = _chart$options2.scales) === null || _chart$options2 === void 0 ? void 0 : _chart$options2.y, chart)), {}, {
|
|
182
|
+
format: function format(value) {
|
|
183
|
+
return value.toLocaleString();
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
};
|
|
187
|
+
return axes;
|
|
188
|
+
};
|
|
189
|
+
var whichDataStructure = function whichDataStructure(data) {
|
|
190
|
+
if (Array.isArray(data[0])) {
|
|
191
|
+
return data.map(function (arr, x) {
|
|
192
|
+
var _arr$sort = arr.sort(),
|
|
193
|
+
_arr$sort2 = _slicedToArray(_arr$sort, 2),
|
|
194
|
+
low = _arr$sort2[0],
|
|
195
|
+
high = _arr$sort2[1];
|
|
196
|
+
return {
|
|
197
|
+
x: x,
|
|
198
|
+
low: low,
|
|
199
|
+
high: high
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return data;
|
|
204
|
+
};
|
|
205
|
+
var scrubX = function scrubX(data) {
|
|
206
|
+
var blackboard = JSON.parse(JSON.stringify(data));
|
|
207
|
+
var labels = [];
|
|
208
|
+
if (Array.isArray(data)) {
|
|
209
|
+
// console.log("not grouped");
|
|
210
|
+
// Not grouped
|
|
211
|
+
blackboard.forEach(function (item, x) {
|
|
212
|
+
if (_typeof(item) === "object" && item !== null && "x" in item) {
|
|
213
|
+
labels.push(item.x);
|
|
214
|
+
item.x = x;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
labels: labels,
|
|
219
|
+
data: blackboard
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
var processData = function processData(data, c2m_types) {
|
|
224
|
+
if (c2m_types === "box") {
|
|
225
|
+
return processBoxData(data);
|
|
226
|
+
}
|
|
227
|
+
var groups = [];
|
|
228
|
+
if (data.datasets.length === 1) {
|
|
229
|
+
return {
|
|
230
|
+
data: whichDataStructure(data.datasets[0].data)
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
var result = {};
|
|
234
|
+
data.datasets.forEach(function (obj, index) {
|
|
235
|
+
var _obj$label2;
|
|
236
|
+
var groupName = (_obj$label2 = obj.label) !== null && _obj$label2 !== void 0 ? _obj$label2 : "Group ".concat(index + 1);
|
|
237
|
+
groups.push(groupName);
|
|
238
|
+
result[groupName] = whichDataStructure(obj.data);
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
groups: groups,
|
|
242
|
+
data: result
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
var determineChartTitle = function determineChartTitle(options) {
|
|
246
|
+
var _options$plugins;
|
|
247
|
+
if ((_options$plugins = options.plugins) !== null && _options$plugins !== void 0 && (_options$plugins = _options$plugins.title) !== null && _options$plugins !== void 0 && _options$plugins.text) {
|
|
248
|
+
if (Array.isArray(options.plugins.title.text)) {
|
|
249
|
+
return options.plugins.title.text.join(", ");
|
|
250
|
+
}
|
|
251
|
+
return options.plugins.title.text;
|
|
252
|
+
}
|
|
253
|
+
return "";
|
|
254
|
+
};
|
|
255
|
+
var determineCCElement = function determineCCElement(canvas, provided) {
|
|
256
|
+
if (provided) {
|
|
257
|
+
return provided;
|
|
258
|
+
}
|
|
259
|
+
var cc = document.createElement("div");
|
|
260
|
+
canvas.insertAdjacentElement("afterend", cc);
|
|
261
|
+
return cc;
|
|
262
|
+
};
|
|
263
|
+
var displayPoint = function displayPoint(chart) {
|
|
264
|
+
if (!chartStates.has(chart)) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
var _chartStates$get = chartStates.get(chart),
|
|
268
|
+
ref = _chartStates$get.c2m,
|
|
269
|
+
visible_groups = _chartStates$get.visible_groups;
|
|
270
|
+
var _ref$getCurrent = ref.getCurrent(),
|
|
271
|
+
point = _ref$getCurrent.point,
|
|
272
|
+
index = _ref$getCurrent.index;
|
|
273
|
+
try {
|
|
274
|
+
var _chart$tooltip;
|
|
275
|
+
var highlightElements = [];
|
|
276
|
+
if ("custom" in point) {
|
|
277
|
+
highlightElements.push({
|
|
278
|
+
// @ts-ignore
|
|
279
|
+
datasetIndex: point.custom.group,
|
|
280
|
+
// @ts-ignore
|
|
281
|
+
index: point.custom.index
|
|
282
|
+
});
|
|
283
|
+
} else {
|
|
284
|
+
visible_groups.forEach(function (datasetIndex) {
|
|
285
|
+
highlightElements.push({
|
|
286
|
+
datasetIndex: datasetIndex,
|
|
287
|
+
index: index
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
chart === null || chart === void 0 || chart.setActiveElements(highlightElements);
|
|
292
|
+
chart === null || chart === void 0 || (_chart$tooltip = chart.tooltip) === null || _chart$tooltip === void 0 || _chart$tooltip.setActiveElements(highlightElements, {});
|
|
293
|
+
chart === null || chart === void 0 || chart.update();
|
|
294
|
+
} catch (e) {
|
|
295
|
+
// console.warn(e);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
var generateChart = function generateChart(chart, options) {
|
|
299
|
+
var _scrub$labels, _options$axes, _options$axes2, _scrub$data, _chart$config$options, _groups$map;
|
|
300
|
+
var _processChartType = processChartType(chart),
|
|
301
|
+
valid = _processChartType.valid,
|
|
302
|
+
c2m_types = _processChartType.c2m_types,
|
|
303
|
+
invalidType = _processChartType.invalidType;
|
|
304
|
+
if (!valid) {
|
|
305
|
+
var _options$errorCallbac;
|
|
306
|
+
// @ts-ignore
|
|
307
|
+
(_options$errorCallbac = options.errorCallback) === null || _options$errorCallbac === void 0 || _options$errorCallbac.call(options, "Unable to connect chart2music to chart. The chart is of type \"".concat(invalidType, "\", which is not one of the supported chart types for this plugin. This plugin supports: ").concat(Object.keys(chartjs_c2m_converter).join(", ")));
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
var axes = generateAxes(chart);
|
|
311
|
+
if (chart.config.type === "wordCloud") {
|
|
312
|
+
delete axes.x.minimum;
|
|
313
|
+
delete axes.x.maximum;
|
|
314
|
+
delete axes.y.minimum;
|
|
315
|
+
delete axes.y.maximum;
|
|
316
|
+
if (!axes.x.label) {
|
|
317
|
+
axes.x.label = "Word";
|
|
318
|
+
}
|
|
319
|
+
if (!axes.y.label) {
|
|
320
|
+
axes.y.label = "Emphasis";
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Generate CC element
|
|
324
|
+
var cc = determineCCElement(chart.canvas, options.cc);
|
|
325
|
+
var _processData = processData(chart.data, c2m_types),
|
|
326
|
+
data = _processData.data,
|
|
327
|
+
groups = _processData.groups;
|
|
328
|
+
// lastDataObj = JSON.stringify(data);
|
|
329
|
+
var scrub = scrubX(data);
|
|
330
|
+
if (scrub !== null && scrub !== void 0 && scrub.labels && (scrub === null || scrub === void 0 || (_scrub$labels = scrub.labels) === null || _scrub$labels === void 0 ? void 0 : _scrub$labels.length) > 0) {
|
|
331
|
+
// Something was scrubbed
|
|
332
|
+
if (!chart.data.labels || chart.data.labels.length === 0) {
|
|
333
|
+
axes.x.valueLabels = scrub.labels.slice(0);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (c2m_types === "scatter") {
|
|
337
|
+
scrub === null || scrub === void 0 || delete scrub.data;
|
|
338
|
+
delete axes.x.valueLabels;
|
|
339
|
+
}
|
|
340
|
+
axes = _objectSpread(_objectSpread({}, axes), {}, {
|
|
341
|
+
x: _objectSpread(_objectSpread({}, axes.x), (_options$axes = options.axes) === null || _options$axes === void 0 ? void 0 : _options$axes.x),
|
|
342
|
+
y: _objectSpread(_objectSpread({}, axes.y), (_options$axes2 = options.axes) === null || _options$axes2 === void 0 ? void 0 : _options$axes2.y)
|
|
343
|
+
});
|
|
344
|
+
var c2mOptions = {
|
|
345
|
+
cc: cc,
|
|
346
|
+
element: chart.canvas,
|
|
347
|
+
type: c2m_types,
|
|
348
|
+
data: (_scrub$data = scrub === null || scrub === void 0 ? void 0 : scrub.data) !== null && _scrub$data !== void 0 ? _scrub$data : data,
|
|
349
|
+
title: determineChartTitle(chart.options),
|
|
350
|
+
axes: axes,
|
|
351
|
+
options: {
|
|
352
|
+
// @ts-ignore
|
|
353
|
+
onFocusCallback: function onFocusCallback() {
|
|
354
|
+
displayPoint(chart);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
if (Array.isArray(c2mOptions.data)) {
|
|
359
|
+
if (isNaN(c2mOptions.data[0])) {
|
|
360
|
+
c2mOptions.data = c2mOptions.data.map(function (point, index) {
|
|
361
|
+
return _objectSpread(_objectSpread({}, point), {}, {
|
|
362
|
+
custom: {
|
|
363
|
+
group: 0,
|
|
364
|
+
index: index
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
} else {
|
|
369
|
+
c2mOptions.data = c2mOptions.data.map(function (num, index) {
|
|
370
|
+
return {
|
|
371
|
+
x: index,
|
|
372
|
+
y: num,
|
|
373
|
+
custom: {
|
|
374
|
+
group: 0,
|
|
375
|
+
index: index
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
} else {
|
|
381
|
+
var _groups = Object.keys(c2mOptions.data);
|
|
382
|
+
_groups.forEach(function (groupName, groupNumber) {
|
|
383
|
+
if (!isNaN(c2mOptions.data[groupName][0])) {
|
|
384
|
+
c2mOptions.data[groupName] = c2mOptions.data[groupName].map(function (num, index) {
|
|
385
|
+
return {
|
|
386
|
+
x: index,
|
|
387
|
+
y: num,
|
|
388
|
+
custom: {
|
|
389
|
+
group: groupNumber,
|
|
390
|
+
index: index
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
});
|
|
394
|
+
} else {
|
|
395
|
+
c2mOptions.data[groupName] = c2mOptions.data[groupName].map(function (point, index) {
|
|
396
|
+
return _objectSpread(_objectSpread({}, point), {}, {
|
|
397
|
+
custom: {
|
|
398
|
+
group: groupNumber,
|
|
399
|
+
index: index
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
// @ts-ignore
|
|
407
|
+
if ((_chart$config$options = chart.config.options) !== null && _chart$config$options !== void 0 && (_chart$config$options = _chart$config$options.scales) !== null && _chart$config$options !== void 0 && (_chart$config$options = _chart$config$options.x) !== null && _chart$config$options !== void 0 && _chart$config$options.stacked) {
|
|
408
|
+
// @ts-ignore
|
|
409
|
+
c2mOptions.options.stack = true;
|
|
410
|
+
}
|
|
411
|
+
// @ts-ignore
|
|
412
|
+
if (options.audioEngine) {
|
|
413
|
+
// @ts-ignore
|
|
414
|
+
c2mOptions.audioEngine = options.audioEngine;
|
|
415
|
+
}
|
|
416
|
+
if (c2mOptions.data.length === 0) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
var _c2mChart = (0, _chart2music["default"])(c2mOptions),
|
|
420
|
+
err = _c2mChart.err,
|
|
421
|
+
c2m = _c2mChart.data;
|
|
422
|
+
/* istanbul-ignore-next */
|
|
423
|
+
if (err) {
|
|
424
|
+
var _options$errorCallbac2;
|
|
425
|
+
// @ts-ignore
|
|
426
|
+
(_options$errorCallbac2 = options.errorCallback) === null || _options$errorCallbac2 === void 0 || _options$errorCallbac2.call(options, err);
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (!c2m) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
chartStates.set(chart, {
|
|
433
|
+
c2m: c2m,
|
|
434
|
+
visible_groups: (_groups$map = groups === null || groups === void 0 ? void 0 : groups.map(function (g, i) {
|
|
435
|
+
return i;
|
|
436
|
+
})) !== null && _groups$map !== void 0 ? _groups$map : []
|
|
437
|
+
});
|
|
438
|
+
};
|
|
439
|
+
var plugin = exports["default"] = {
|
|
440
|
+
id: "chartjs2music",
|
|
441
|
+
afterInit: function afterInit(chart, args, options) {
|
|
442
|
+
if (!chartStates.has(chart)) {
|
|
443
|
+
generateChart(chart, options);
|
|
444
|
+
// Remove tooltip when the chart blurs
|
|
445
|
+
chart.canvas.addEventListener("blur", function () {
|
|
446
|
+
var _chart$tooltip2;
|
|
447
|
+
chart.setActiveElements([]);
|
|
448
|
+
(_chart$tooltip2 = chart.tooltip) === null || _chart$tooltip2 === void 0 || _chart$tooltip2.setActiveElements([], {});
|
|
449
|
+
try {
|
|
450
|
+
chart.update();
|
|
451
|
+
} catch (e) {
|
|
452
|
+
// console.warn(e);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
// Show tooltip when the chart receives focus
|
|
456
|
+
chart.canvas.addEventListener("focus", function () {
|
|
457
|
+
displayPoint(chart);
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
afterDatasetUpdate: function afterDatasetUpdate(chart, args, options) {
|
|
462
|
+
if (!args.mode) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
if (!chartStates.has(chart)) {
|
|
466
|
+
generateChart(chart, options);
|
|
467
|
+
}
|
|
468
|
+
var _chartStates$get2 = chartStates.get(chart),
|
|
469
|
+
ref = _chartStates$get2.c2m,
|
|
470
|
+
visible_groups = _chartStates$get2.visible_groups;
|
|
471
|
+
if (!ref) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
// @ts-ignore
|
|
475
|
+
var groups = ref._groups.slice(0);
|
|
476
|
+
// @ts-ignore
|
|
477
|
+
if (ref._options.stack) {
|
|
478
|
+
groups.shift();
|
|
479
|
+
}
|
|
480
|
+
if (args.mode === "hide") {
|
|
481
|
+
var err = ref.setCategoryVisibility(groups[args.index], false);
|
|
482
|
+
visible_groups.splice(args.index, 1);
|
|
483
|
+
if (err) {
|
|
484
|
+
console.error(err);
|
|
485
|
+
}
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
if (args.mode === "show") {
|
|
489
|
+
var _err = ref.setCategoryVisibility(groups[args.index], true);
|
|
490
|
+
visible_groups.push(args.index);
|
|
491
|
+
if (_err) {
|
|
492
|
+
console.error(_err);
|
|
493
|
+
}
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
defaults: {
|
|
498
|
+
cc: null,
|
|
499
|
+
audioEngine: null,
|
|
500
|
+
errorCallback: null
|
|
501
|
+
}
|
|
502
|
+
};
|
package/dist/plugin.js
CHANGED
|
@@ -164,7 +164,7 @@ var chartjs2music = (function (c2mChart) {
|
|
|
164
164
|
// console.log("not grouped");
|
|
165
165
|
// Not grouped
|
|
166
166
|
blackboard.forEach((item, x) => {
|
|
167
|
-
if (typeof item === "object" && "x" in item) {
|
|
167
|
+
if (typeof item === "object" && item !== null && "x" in item) {
|
|
168
168
|
labels.push(item.x);
|
|
169
169
|
item.x = x;
|
|
170
170
|
}
|
|
@@ -207,171 +207,214 @@ var chartjs2music = (function (c2mChart) {
|
|
|
207
207
|
canvas.insertAdjacentElement("afterend", cc);
|
|
208
208
|
return cc;
|
|
209
209
|
};
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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 (
|
|
242
|
-
|
|
243
|
-
delete axes.x.valueLabels;
|
|
258
|
+
if (!axes.y.label) {
|
|
259
|
+
axes.y.label = "Emphasis";
|
|
244
260
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
-
|
|
288
|
-
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
-
|
|
332
|
+
x: index,
|
|
333
|
+
y: num,
|
|
298
334
|
custom: {
|
|
299
|
-
group:
|
|
335
|
+
group: groupNumber,
|
|
300
336
|
index
|
|
301
337
|
}
|
|
302
338
|
};
|
|
303
339
|
});
|
|
304
340
|
}
|
|
305
341
|
else {
|
|
306
|
-
c2mOptions.data = c2mOptions.data.map((
|
|
342
|
+
c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
|
|
307
343
|
return {
|
|
308
|
-
|
|
309
|
-
y: num,
|
|
344
|
+
...point,
|
|
310
345
|
custom: {
|
|
311
|
-
group:
|
|
346
|
+
group: groupNumber,
|
|
312
347
|
index
|
|
313
348
|
}
|
|
314
349
|
};
|
|
315
350
|
});
|
|
316
351
|
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
352
|
+
});
|
|
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
|
+
try {
|
|
392
|
+
chart.update();
|
|
332
393
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return {
|
|
336
|
-
...point,
|
|
337
|
-
custom: {
|
|
338
|
-
group: groupNumber,
|
|
339
|
-
index
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
});
|
|
394
|
+
catch (e) {
|
|
395
|
+
// console.warn(e);
|
|
343
396
|
}
|
|
344
397
|
});
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
if (options.audioEngine) {
|
|
350
|
-
// @ts-ignore
|
|
351
|
-
c2mOptions.audioEngine = options.audioEngine;
|
|
352
|
-
}
|
|
353
|
-
if (c2mOptions.data.length === 0) {
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
const { err, data: c2m } = c2mChart(c2mOptions);
|
|
357
|
-
chartStates.set(chart, {
|
|
358
|
-
c2m,
|
|
359
|
-
visible_groups: groups?.map((g, i) => i)
|
|
360
|
-
});
|
|
361
|
-
// /* istanbul-ignore-next */
|
|
362
|
-
if (err) {
|
|
363
|
-
options.errorCallback?.(err);
|
|
398
|
+
// Show tooltip when the chart receives focus
|
|
399
|
+
chart.canvas.addEventListener("focus", () => {
|
|
400
|
+
displayPoint(chart);
|
|
401
|
+
});
|
|
364
402
|
}
|
|
365
403
|
},
|
|
366
|
-
afterDatasetUpdate: (chart, args) => {
|
|
404
|
+
afterDatasetUpdate: (chart, args, options) => {
|
|
367
405
|
if (!args.mode) {
|
|
368
406
|
return;
|
|
369
407
|
}
|
|
408
|
+
if (!chartStates.has(chart)) {
|
|
409
|
+
generateChart(chart, options);
|
|
410
|
+
}
|
|
370
411
|
const { c2m: ref, visible_groups } = chartStates.get(chart);
|
|
371
412
|
if (!ref) {
|
|
372
413
|
return;
|
|
373
414
|
}
|
|
415
|
+
// @ts-ignore
|
|
374
416
|
const groups = ref._groups.slice(0);
|
|
417
|
+
// @ts-ignore
|
|
375
418
|
if (ref._options.stack) {
|
|
376
419
|
groups.shift();
|
|
377
420
|
}
|
package/dist/plugin.mjs
CHANGED
|
@@ -163,7 +163,7 @@ const scrubX = (data) => {
|
|
|
163
163
|
// console.log("not grouped");
|
|
164
164
|
// Not grouped
|
|
165
165
|
blackboard.forEach((item, x) => {
|
|
166
|
-
if (typeof item === "object" && "x" in item) {
|
|
166
|
+
if (typeof item === "object" && item !== null && "x" in item) {
|
|
167
167
|
labels.push(item.x);
|
|
168
168
|
item.x = x;
|
|
169
169
|
}
|
|
@@ -206,171 +206,214 @@ const determineCCElement = (canvas, provided) => {
|
|
|
206
206
|
canvas.insertAdjacentElement("afterend", cc);
|
|
207
207
|
return cc;
|
|
208
208
|
};
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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 (
|
|
241
|
-
|
|
242
|
-
delete axes.x.valueLabels;
|
|
257
|
+
if (!axes.y.label) {
|
|
258
|
+
axes.y.label = "Emphasis";
|
|
243
259
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
-
|
|
287
|
-
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
-
|
|
331
|
+
x: index,
|
|
332
|
+
y: num,
|
|
297
333
|
custom: {
|
|
298
|
-
group:
|
|
334
|
+
group: groupNumber,
|
|
299
335
|
index
|
|
300
336
|
}
|
|
301
337
|
};
|
|
302
338
|
});
|
|
303
339
|
}
|
|
304
340
|
else {
|
|
305
|
-
c2mOptions.data = c2mOptions.data.map((
|
|
341
|
+
c2mOptions.data[groupName] = c2mOptions.data[groupName].map((point, index) => {
|
|
306
342
|
return {
|
|
307
|
-
|
|
308
|
-
y: num,
|
|
343
|
+
...point,
|
|
309
344
|
custom: {
|
|
310
|
-
group:
|
|
345
|
+
group: groupNumber,
|
|
311
346
|
index
|
|
312
347
|
}
|
|
313
348
|
};
|
|
314
349
|
});
|
|
315
350
|
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
351
|
+
});
|
|
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
|
+
try {
|
|
391
|
+
chart.update();
|
|
331
392
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return {
|
|
335
|
-
...point,
|
|
336
|
-
custom: {
|
|
337
|
-
group: groupNumber,
|
|
338
|
-
index
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
});
|
|
393
|
+
catch (e) {
|
|
394
|
+
// console.warn(e);
|
|
342
395
|
}
|
|
343
396
|
});
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (options.audioEngine) {
|
|
349
|
-
// @ts-ignore
|
|
350
|
-
c2mOptions.audioEngine = options.audioEngine;
|
|
351
|
-
}
|
|
352
|
-
if (c2mOptions.data.length === 0) {
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
const { err, data: c2m } = c2mChart(c2mOptions);
|
|
356
|
-
chartStates.set(chart, {
|
|
357
|
-
c2m,
|
|
358
|
-
visible_groups: groups?.map((g, i) => i)
|
|
359
|
-
});
|
|
360
|
-
// /* istanbul-ignore-next */
|
|
361
|
-
if (err) {
|
|
362
|
-
options.errorCallback?.(err);
|
|
397
|
+
// Show tooltip when the chart receives focus
|
|
398
|
+
chart.canvas.addEventListener("focus", () => {
|
|
399
|
+
displayPoint(chart);
|
|
400
|
+
});
|
|
363
401
|
}
|
|
364
402
|
},
|
|
365
|
-
afterDatasetUpdate: (chart, args) => {
|
|
403
|
+
afterDatasetUpdate: (chart, args, options) => {
|
|
366
404
|
if (!args.mode) {
|
|
367
405
|
return;
|
|
368
406
|
}
|
|
407
|
+
if (!chartStates.has(chart)) {
|
|
408
|
+
generateChart(chart, options);
|
|
409
|
+
}
|
|
369
410
|
const { c2m: ref, visible_groups } = chartStates.get(chart);
|
|
370
411
|
if (!ref) {
|
|
371
412
|
return;
|
|
372
413
|
}
|
|
414
|
+
// @ts-ignore
|
|
373
415
|
const groups = ref._groups.slice(0);
|
|
416
|
+
// @ts-ignore
|
|
374
417
|
if (ref._options.stack) {
|
|
375
418
|
groups.shift();
|
|
376
419
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartjs-plugin-chart2music",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
7
7
|
"module": "dist/plugin.mjs",
|
|
8
8
|
"exports": {
|
|
9
|
-
"import": "./dist/plugin.mjs"
|
|
9
|
+
"import": "./dist/plugin.mjs",
|
|
10
|
+
"require": "./dist/plugin.cjs"
|
|
10
11
|
},
|
|
11
12
|
"files": [
|
|
12
13
|
"dist/*"
|
|
@@ -30,31 +31,36 @@
|
|
|
30
31
|
"license": "MIT",
|
|
31
32
|
"scripts": {
|
|
32
33
|
"start": "vite",
|
|
33
|
-
"build": "rollup -c rollup.config.js --silent",
|
|
34
|
+
"build": "rollup -c rollup.config.js --silent && yarn build-cjs",
|
|
35
|
+
"build-cjs": "babel ./dist/plugin.mjs --out-file ./dist/plugin.cjs",
|
|
34
36
|
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
|
|
35
37
|
"depcheck": "depcheck",
|
|
36
38
|
"clean": "rimraf dist coverage"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
41
|
+
"@babel/cli": "^7.23.9",
|
|
42
|
+
"@babel/core": "^7.23.9",
|
|
43
|
+
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
|
|
44
|
+
"@babel/preset-env": "^7.23.9",
|
|
45
|
+
"@rollup/plugin-typescript": "11.1.6",
|
|
46
|
+
"@sgratzl/chartjs-chart-boxplot": "4.2.8",
|
|
47
|
+
"@types/jest": "29.5.11",
|
|
42
48
|
"canvas": "2.11.2",
|
|
43
|
-
"chartjs-chart-wordcloud": "4.3.
|
|
49
|
+
"chartjs-chart-wordcloud": "4.3.3",
|
|
44
50
|
"chartjs-plugin-a11y-legend": "0.1.1",
|
|
45
51
|
"cross-env": "7.0.3",
|
|
46
|
-
"depcheck": "1.4.
|
|
52
|
+
"depcheck": "1.4.7",
|
|
47
53
|
"jest": "29.7.0",
|
|
48
54
|
"jest-environment-jsdom": "29.7.0",
|
|
49
55
|
"rimraf": "5.0.5",
|
|
50
|
-
"rollup": "4.
|
|
51
|
-
"ts-jest": "29.1.
|
|
56
|
+
"rollup": "4.9.6",
|
|
57
|
+
"ts-jest": "29.1.2",
|
|
52
58
|
"tslib": "2.6.2",
|
|
53
|
-
"typescript": "5.
|
|
54
|
-
"vite": "
|
|
59
|
+
"typescript": "5.3.3",
|
|
60
|
+
"vite": "5.0.12"
|
|
55
61
|
},
|
|
56
62
|
"dependencies": {
|
|
57
|
-
"chart.js": "4.4.
|
|
58
|
-
"chart2music": "1.
|
|
63
|
+
"chart.js": "4.4.1",
|
|
64
|
+
"chart2music": "1.13.0"
|
|
59
65
|
}
|
|
60
66
|
}
|