2๐
โ
I was able to implement an effective x-axis jitter with this custom beforeDatasetDraw
plugin:
beforeDatasetDraw(chart, args) {
if (chart.animating || chart.$deferred.loaded) {
const { index: dataIndex, meta } = args;
const points = meta.data.map(el => ({ x: el._model.x, y: el._model.y }));
const { length: dsLength } = chart.data.datasets;
const adjustedMap = []; // keeps track of adjustments to prevent double offsets
for (let datasetIndex = 0; datasetIndex < dsLength; datasetIndex += 1) {
if (dataIndex !== datasetIndex) {
const datasetMeta = chart.getDatasetMeta(datasetIndex);
datasetMeta.data.forEach(el => {
const overlap = points.find(point => point.x === el._model.x && point.y === el._model.y);
if (overlap) {
const adjusted = adjustedMap.find(item => item.datasetIndex === datasetIndex && item.dataIndex === dataIndex);
if (!adjusted && datasetIndex % 2) { el._model.x += 7; } else { el._model.x -= 7; }
adjustedMap.push({ datasetIndex, dataIndex });
}
});
}
}
}
}
1๐
Thanks Quanda. I had modified the above code to support IE browsers as well.
var jitterEffectPlugin = {
beforeDatasetDraw: function (ctx, args) {
if (ctx.animating) {
var _args = args,
dataIndex = _args.index,
meta = _args.meta;
var points = meta.data.map(function (el) {
return {
x: el._model.x,
y: el._model.y
};
});
var dsLength = ctx.data.datasets.length;
var adjustedMap = []; // keeps track of adjustments to prevent double offsets
for (var datasetIndex = 0; datasetIndex < dsLength; datasetIndex += 1) {
if (dataIndex !== datasetIndex) {
var datasetMeta = ctx.getDatasetMeta(datasetIndex);
datasetMeta.data.forEach(function (el) {
var overlapFilter = points.filter(function (point) {
return point.x === el._model.x && point.y === el._model.y;
});
var overlap = false;
var overObj = JSON.parse(JSON.stringify(overlapFilter));
for (var i = 0; i < overObj.length; i++) {
if(overObj[i]['x'] === el._model.x && overObj[i]['y'] === el._model.y){
overlap = true;
break;
}
}
if (overlap) {
var adjusted = false;
var adjustedFilter = adjustedMap.filter(function (item) {
return item.datasetIndex === datasetIndex && item.dataIndex === dataIndex;
});
var adjObj = JSON.parse(JSON.stringify(adjustedFilter));
for (var i = 0; i < adjObj.length; i++) {
if(adjObj[i]['datasetIndex'] === datasetIndex && adjObj[i]['dataIndex'] === dataIndex){
adjusted = true;
break;
}
}
if (!adjusted && datasetIndex % 2) {
el._model.x += 7;
} else {
el._model.x -= 7;
}
adjustedMap.push({
datasetIndex: datasetIndex,
dataIndex: dataIndex
});
}
});
}
}
}
}
}
Chart.pluginService.register(jitterEffectPlugin);
0๐
Must have been changes in Chartjs, I had to modify this plugin for current version. Basically I just removed _model from el._model.x and el.model.y and added the id:
var jitterEffectsPlugin = {
id: 'jitterEffects',
beforeDatasetDraw: function (ctx, args) {
var _args = args,
dataIndex = _args.index,
meta = _args.meta;
var points = meta.data.map(function (el) {
return {
x: el.x,
y: el.y
};
});
var dsLength = ctx.data.datasets.length;
var adjustedMap = []; // keeps track of adjustments to prevent double offsets
for (var datasetIndex = 0; datasetIndex < dsLength; datasetIndex += 1) {
if (dataIndex !== datasetIndex) {
var datasetMeta = ctx.getDatasetMeta(datasetIndex);
datasetMeta.data.forEach(function (el) {
var overlapFilter = points.filter(function (point) {
return point.x === el.x && point.y === el.y;
});
var overlap = false;
var overObj = JSON.parse(JSON.stringify(overlapFilter));
for (var i = 0; i < overObj.length; i++) {
if(overObj[i]['x'] === el.x && overObj[i]['y'] === el.y){
overlap = true;
break;
}
}
if (overlap) {
var adjusted = false;
var adjustedFilter = adjustedMap.filter(function (item) {
return item.datasetIndex === datasetIndex && item.dataIndex === dataIndex;
});
var adjObj = JSON.parse(JSON.stringify(adjustedFilter));
for (var i = 0; i < adjObj.length; i++) {
if(adjObj[i]['datasetIndex'] === datasetIndex && adjObj[i]['dataIndex'] === dataIndex){
adjusted = true;
break;
}
}
if (!adjusted && datasetIndex % 2) {
el.x += 7;
} else {
el.x -= 7;
}
adjustedMap.push({
datasetIndex: datasetIndex,
dataIndex: dataIndex
});
}
});
}
}
}
}
Source:stackexchange.com