我终于找到了解决方案,但这并不简单。
感谢@jordanwillis 为使用scaleMerge() 辅助函数提供了正确的方向。
我创建了一个完成所有工作的插件:
var changeScaleTypePlugin = {
beforeUpdate: function(chartInstance) {
var self = this;
chartInstance.beforeInit = null;
if (chartInstance.options.changeScale) {
self.changeScales(chartInstance);
if (chartInstance.options.scaleTypeChanged) {
chartInstance.options.scaleTypeChanged = false;
Object.keys(chartInstance.scales).forEach(function(axisName) {
var scale = chartInstance.scales[axisName];
Chart.layoutService.removeBox(chartInstance, scale);
});
chartInstance.initialize();
}
}
},
changeScales: function(chartInstance) {
var maxValue = Math.max.apply(null, chartInstance.data.datasets.map(function(dataset) {
return Math.max.apply(null, dataset.data);
}));
var minValue = Math.min.apply(null, chartInstance.data.datasets.map(function(dataset) {
return Math.min.apply(null, dataset.data);
}));
var logMax = Math.floor(Math.log(maxValue) / Math.LN10);
var logMin = Math.floor(Math.log(minValue) / Math.LN10);
if (logMax - logMin > chartInstance.options.maxRankDifference) {
if (!chartInstance.options.scaleTypeChanged && chartInstance.options.scales.yAxes.filter(function(axis) {
return axis.type !== 'logarithmic';
}).length) {
console.log('logarithmic');
chartInstance.options.scaleTypeChanged = true;
chartInstance.options.scales.yAxes = Chart.helpers.scaleMerge(Chart.defaults.scale, {
yAxes: chartInstance.options.logarithmicScaleOptions
}).yAxes;
}
} else {
if (!chartInstance.options.scaleTypeChanged && chartInstance.options.scales.yAxes.filter(function(axis) {
return axis.type !== 'linear';
}).length) {
console.log('linear');
chartInstance.options.scaleTypeChanged = true;
chartInstance.options.scales.yAxes = Chart.helpers.scaleMerge(Chart.defaults.scale, {
yAxes: chartInstance.options.linearScaleOptions
}).yAxes;
}
}
}
};
Chart.pluginService.register(changeScaleTypePlugin);
要应用它,只需在图表的选项中添加一些属性:
options: {
linearScaleOptions: [{
id: 'y-axis-0',
type: 'linear',
tick: {
// callback: Chart.Ticks.formatters.linear,
min: 0
}
}],
logarithmicScaleOptions: [{
id: 'y-axis-0',
type: 'logarithmic',
ticks: {
// callback: function (tickValue, index, ticks) {
// var remain = tickValue / (Math.pow(10, Math.floor(Math.log(tickValue) / Math.LN10)));
// if (tickValue === 0) {
// return '0';
// } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
// return tickValue;
// }
// return '';
//},
min: 0
}
}],
changeScale: true,
maxRankDifference: 1,
}
刻度上注释掉的回调适用于(像我一样)您不希望刻度值在对数刻度上以科学计数法显示的情况。
这给出了如下所示的输出:
将最大排名属性设置为 1
或
设置为 3
或使用回调集: