Javascript Chart.js:使用maxTicksLimit时均匀分布刻度
我使用chart.js 2.1.3版制作了一个折线图Javascript Chart.js:使用maxTicksLimit时均匀分布刻度,javascript,chart.js,Javascript,Chart.js,我使用chart.js 2.1.3版制作了一个折线图 var canvas = $('#gold_chart').get(0); var ctx = canvas.getContext('2d'); var fillPatternGold = ctx.createLinearGradient(0, 0, 0, canvas.height); fillPatternGold.addColorStop(0, '#fdca55');
var canvas = $('#gold_chart').get(0);
var ctx = canvas.getContext('2d');
var fillPatternGold = ctx.createLinearGradient(0, 0, 0, canvas.height);
fillPatternGold.addColorStop(0, '#fdca55');
fillPatternGold.addColorStop(1, '#ffffff');
var goldChart = new Chart(ctx, {
type: 'line',
animation: false,
data: {
labels: dates,
datasets: [{
label: '',
data: prices,
pointRadius: 0,
borderWidth: 1,
borderColor: '#a97f35',
backgroundColor: fillPatternGold
}]
},
title: {
position: 'bottom',
text: '\u7F8E\u5143 / \u76CE\u53F8'
},
options: {
legend: {
display: false
},
tooltips: {
callback: function(tooltipItem) {
return tooltipItem.yLabel;
}
},
scales: {
xAxes: [{
ticks: {
maxTicksLimit: 8
}
}]
}
}
});
输出如下:
如您所见,我通过maxTicksLimit
将最大滴答数限制为8。然而,分布并不均匀。如何使蜱虫均匀分布
p、 数据集中始终有289条记录,并且每5分钟记录一次数据。价格
变量的样本值为:
[
{"14:10", 1280.3},
{"14:15", 1280.25},
{"14:20", 1282.85}
]
我尝试了不同的
maxTicksLimit
值,结果仍然不均匀。Chart.js使用积分skipRatio
(计算要跳过多少标签)。使用Chart.jsv2.1.x,您可以编写自己的插件来使用分数skipRatio
预览
脚本
Chart.pluginService.register({
afterUpdate: function (chart) {
var xScale = chart.scales['x-axis-0'];
if (xScale.options.ticks.maxTicksLimit) {
// store the original maxTicksLimit
xScale.options.ticks._maxTicksLimit = xScale.options.ticks.maxTicksLimit;
// let chart.js draw the first and last label
xScale.options.ticks.maxTicksLimit = (xScale.ticks.length % xScale.options.ticks._maxTicksLimit === 0) ? 1 : 2;
var originalXScaleDraw = xScale.draw
xScale.draw = function () {
originalXScaleDraw.apply(this, arguments);
var xScale = chart.scales['x-axis-0'];
if (xScale.options.ticks.maxTicksLimit) {
var helpers = Chart.helpers;
var tickFontColor = helpers.getValueOrDefault(xScale.options.ticks.fontColor, Chart.defaults.global.defaultFontColor);
var tickFontSize = helpers.getValueOrDefault(xScale.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
var tickFontStyle = helpers.getValueOrDefault(xScale.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
var tickFontFamily = helpers.getValueOrDefault(xScale.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
var tl = xScale.options.gridLines.tickMarkLength;
var isRotated = xScale.labelRotation !== 0;
var yTickStart = xScale.top;
var yTickEnd = xScale.top + tl;
var chartArea = chart.chartArea;
// use the saved ticks
var maxTicks = xScale.options.ticks._maxTicksLimit - 1;
var ticksPerVisibleTick = xScale.ticks.length / maxTicks;
// chart.js uses an integral skipRatio - this causes all the fractional ticks to be accounted for between the last 2 labels
// we use a fractional skipRatio
var ticksCovered = 0;
helpers.each(xScale.ticks, function (label, index) {
if (index < ticksCovered)
return;
ticksCovered += ticksPerVisibleTick;
// chart.js has already drawn these 2
if (index === 0 || index === (xScale.ticks.length - 1))
return;
// copy of chart.js code
var xLineValue = this.getPixelForTick(index);
var xLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines);
if (this.options.gridLines.display) {
this.ctx.lineWidth = this.options.gridLines.lineWidth;
this.ctx.strokeStyle = this.options.gridLines.color;
xLineValue += helpers.aliasPixel(this.ctx.lineWidth);
// Draw the label area
this.ctx.beginPath();
if (this.options.gridLines.drawTicks) {
this.ctx.moveTo(xLineValue, yTickStart);
this.ctx.lineTo(xLineValue, yTickEnd);
}
// Draw the chart area
if (this.options.gridLines.drawOnChartArea) {
this.ctx.moveTo(xLineValue, chartArea.top);
this.ctx.lineTo(xLineValue, chartArea.bottom);
}
// Need to stroke in the loop because we are potentially changing line widths & colours
this.ctx.stroke();
}
if (this.options.ticks.display) {
this.ctx.save();
this.ctx.translate(xLabelValue + this.options.ticks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl);
this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
this.ctx.font = tickLabelFont;
this.ctx.textAlign = (isRotated) ? "right" : "center";
this.ctx.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top";
this.ctx.fillText(label, 0, 0);
this.ctx.restore();
}
}, xScale);
}
};
}
},
});
Chart.pluginService.register({
更新后:功能(图表){
var xScale=图表刻度['x轴-0'];
if(xScale.options.ticks.maxTicksLimit){
//存储原始的maxTicksLimit
xScale.options.ticks.\u maxTicksLimit=xScale.options.ticks.maxTicksLimit;
//让chart.js绘制第一个和最后一个标签
xScale.options.ticks.maxTicksLimit=(xScale.ticks.length%xScale.options.ticks.\u maxTicksLimit==0)?1:2;
var originalXScaleDraw=xScale.draw
xScale.draw=函数(){
originalXScaleDraw.apply(这是参数);
var xScale=图表刻度['x轴-0'];
if(xScale.options.ticks.maxTicksLimit){
var helpers=Chart.helpers;
var tickFontColor=helpers.getValueOrDefault(xScale.options.ticks.fontColor,Chart.defaults.global.defaultFontColor);
var tickFontSize=helpers.getValueOrDefault(xScale.options.ticks.fontSize,Chart.defaults.global.defaultFontSize);
var tickFontStyle=helpers.getValueOrDefault(xScale.options.ticks.fontStyle,Chart.defaults.global.defaultFontStyle);
var tickFontFamily=helpers.getValueOrDefault(xScale.options.ticks.fontFamily,Chart.defaults.global.defaultFontFamily);
var tickLabelFont=helpers.fontString(tickFontSize、tickFontStyle、tickFontFamily);
var tl=xScale.options.gridLines.tickMarkLength;
var isRotated=xScale.labelRotation!==0;
var yTickStart=xScale.top;
var yTickEnd=xScale.top+tl;
var chartArea=chart.chartArea;
//使用保存的记号
var maxTicks=xScale.options.ticks.\u maxTicks-1;
var ticksPerVisibleTick=xScale.ticks.length/maxsticks;
//chart.js使用一个整数skipRatio-这会导致最后两个标签之间的所有小数点
//我们使用分数技巧
var ticksCovered=0;
helpers.each(xScale.ticks、函数(标签、索引){
如果(索引<勾选)
返回;
ticksCovered+=ticksPerVisibleTick;
//chart.js已经绘制了以下2个
if(index==0 | | index==(xScale.ticks.length-1))
返回;
//chart.js代码的副本
var xLineValue=this.getPixelForTick(索引);
var xLabelValue=this.getPixelForTick(索引,this.options.gridLines.offsetGridLines);
if(this.options.gridLines.display){
this.ctx.lineWidth=this.options.gridLines.lineWidth;
this.ctx.strokeStyle=this.options.gridLines.color;
xLineValue+=helpers.aliasPixel(this.ctx.lineWidth);
//绘制标签区域
this.ctx.beginPath();
if(this.options.gridLines.drawTicks){
this.ctx.moveTo(xLineValue,yTickStart);
this.ctx.lineTo(xLineValue,yTickEnd);
}
//绘制图表区域
if(this.options.gridLines.drawOnChartArea){
this.ctx.moveTo(xLineValue,chartArea.top);
这个.ctx.lineTo(xLineValue,chartArea.bottom);
}
//需要在循环中划水,因为我们可能会改变线宽和颜色
这个.ctx.stroke();
}
if(this.options.ticks.display){
这个.ctx.save();
this.ctx.translate(xLabelValue+this.options.ticks.labelOffset,(isRotated)?this.top+12:this.options.position==“top”?this.bottom-tl:this.top+tl);
this.ctx.rotate(helpers.toRadians(this.labelRotation)*-1);
this.ctx.font=tickLabelFont;
this.ctx.textAlign=(isRotated)?“右”:“中心”;
this.ctx.textBaseline=(isRotated)?“middle”:this.options.position==“top”?“bottom”:“top”;
this.ctx.fillText(标签,0,0);
这个.ctx.restore();
}
},xScale);
}
};
}
},
});
Fiddle-一个更简单的解决方案是在
maxTicksLimit
中包含一个小数点,直到这个问题被图表永久解决
例如:
maxTicksLimit: 8,
在最后产生一个巨大的缺口
maxTicksLimit: 8.1,
最终不会产生巨大的差距
取决于你想要什么
yAxes: [{
ticks: {
stepSize: Math.round((Math.max.apply(Math, myListOfyValues) / 10)/5)*5,
beginAtZero: true,
precision: 0
}
}]