我使用Chartjs制作折线图。
如何将y轴标签更改为颜色? (即红色为1,绿色为2,黑色为3,......)
答案 0 :(得分:1)
更新我现在已将此功能添加到https://github.com/leighquince/Chart.js的chartjs分支中,表示您不必覆盖或扩展新的图表类型。只需像往常一样传递选项,这是一个示例http://fiddle.jshell.net/leighking2/jLzvhf4f/
所以这可以通过覆盖scale draw方法来实现,以运行我们在声明图表时提供的自定义函数,而不仅仅是添加。
以下是摘录,但正如此处的解释是发生了什么
创建了一个新图表,并重写了buildScale方法以传递一个名为customYLabel
的新选项。这是您在声明它时传递给图表的选项,它有4个参数;标签的值,x位置,y位置,画布,标签的索引
重置是正常的,你的customYLabel所做的取决于你,但它应该至少调用`ctx.fillText(value,x,y),以便在画布上绘制标签。在下面的示例中,我根据标签的索引为标签着色,但选项很多。
(如果更容易查看http://fiddle.jshell.net/leighking2/2cac5t34/)
,这也是一个小提琴
//extract helpers so we can use them in our custom scale class
var helpers = Chart.helpers,
each = helpers.each,
aliasPixel = helpers.aliasPixel,
toRadians = helpers.radians;
//new line chart which has an overridden buildscale that will pass the new option customYLabel
Chart.types.Line.extend({
// Passing in a name registers this chart in the Chart namespace in the same way
name: "LineAlt",
initialize: function (data) {
Chart.types.Line.prototype.initialize.apply(this, arguments);
},
buildScale: function (labels) {
var self = this;
var dataTotal = function () {
var values = [];
self.eachPoints(function (point) {
values.push(point.value);
});
return values;
};
var scaleOptions = {
templateString: this.options.scaleLabel,
height: this.chart.height,
width: this.chart.width,
ctx: this.chart.ctx,
textColor: this.options.scaleFontColor,
fontSize: this.options.scaleFontSize,
fontStyle: this.options.scaleFontStyle,
fontFamily: this.options.scaleFontFamily,
valuesCount: labels.length,
beginAtZero: this.options.scaleBeginAtZero,
integersOnly: this.options.scaleIntegersOnly,
//new options for custom y label
customYLabel: this.options.customYLabel,
calculateYRange: function (currentHeight) {
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly);
helpers.extend(this, updatedRanges);
},
xLabels: labels,
font: helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth: this.options.scaleLineWidth,
lineColor: this.options.scaleLineColor,
showHorizontalLines: this.options.scaleShowHorizontalLines,
showVerticalLines: this.options.scaleShowVerticalLines,
gridLineWidth: (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor: (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
showLabels: this.options.scaleShowLabels,
display: this.options.showScale
};
if (this.options.scaleOverride) {
helpers.extend(scaleOptions, {
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
});
}
this.scale = new Chart.CustomScale(scaleOptions);
},
});
//custom scale to use new customYLabel option
Chart.CustomScale = Chart.Scale.extend({
draw: function () {
var ctx = this.ctx,
yLabelGap = (this.endPoint - this.startPoint) / this.steps,
xStart = Math.round(this.xScalePaddingLeft);
if (this.display) {
ctx.fillStyle = this.textColor;
ctx.font = this.font;
each(this.yLabels, function (labelString, index) {
var yLabelCenter = this.endPoint - (yLabelGap * index),
linePositionY = Math.round(yLabelCenter),
drawHorizontalLine = this.showHorizontalLines;
ctx.textAlign = "right";
ctx.textBaseline = "middle";
if (this.showLabels) {
//if we have a customYLabel use it passing the value, x, y , canvas and index
if (this.customYLabel) {
this.customYLabel(labelString, xStart - 10, yLabelCenter, ctx, index);
} else {
ctx.fillText(labelString, xStart - 10, yLabelCenter);
}
}
// This is X axis, so draw it
if (index === 0 && !drawHorizontalLine) {
drawHorizontalLine = true;
}
if (drawHorizontalLine) {
ctx.beginPath();
}
if (index > 0) {
// This is a grid line in the centre, so drop that
ctx.lineWidth = this.gridLineWidth;
ctx.strokeStyle = this.gridLineColor;
} else {
// This is the first line on the scale
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
}
linePositionY += helpers.aliasPixel(ctx.lineWidth);
if (drawHorizontalLine) {
ctx.moveTo(xStart, linePositionY);
ctx.lineTo(this.width, linePositionY);
ctx.stroke();
ctx.closePath();
}
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
ctx.beginPath();
ctx.moveTo(xStart - 5, linePositionY);
ctx.lineTo(xStart, linePositionY);
ctx.stroke();
ctx.closePath();
}, this);
each(this.xLabels, function (label, index) {
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
// Check to see if line/bar here and decide where to place the line
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
isRotated = (this.xLabelRotation > 0),
drawVerticalLine = this.showVerticalLines;
// This is Y axis, so draw it
if (index === 0 && !drawVerticalLine) {
drawVerticalLine = true;
}
if (drawVerticalLine) {
ctx.beginPath();
}
if (index > 0) {
// This is a grid line in the centre, so drop that
ctx.lineWidth = this.gridLineWidth;
ctx.strokeStyle = this.gridLineColor;
} else {
// This is the first line on the scale
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
}
if (drawVerticalLine) {
ctx.moveTo(linePos, this.endPoint);
ctx.lineTo(linePos, this.startPoint - 3);
ctx.stroke();
ctx.closePath();
}
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
// Small lines at the bottom of the base grid line
ctx.beginPath();
ctx.moveTo(linePos, this.endPoint);
ctx.lineTo(linePos, this.endPoint + 5);
ctx.stroke();
ctx.closePath();
ctx.save();
ctx.translate(xPos, (isRotated) ? this.endPoint + 12 : this.endPoint + 8);
ctx.rotate(toRadians(this.xLabelRotation) * -1);
ctx.font = this.font;
ctx.textAlign = (isRotated) ? "right" : "center";
ctx.textBaseline = (isRotated) ? "middle" : "top";
ctx.fillText(label, 0, 0);
ctx.restore();
}, this);
}
}
});
var randomScalingFactor = function () {
return Math.round(Math.random() * 100)
};
//example colour generator from
//https://www.designedbyaturtle.co.uk/2014/convert-string-to-hexidecimal-colour-with-javascript-vanilla/
// Convert an int to hexadecimal with a max length
// of six characters.
var intToARGB = function (i) {
var h = ((i >> 24) & 0xFF).toString(16) + ((i >> 16) & 0xFF).toString(16) + ((i >> 8) & 0xFF).toString(16) + (i & 0xFF).toString(16);
return h.substring(0, 6);
}
var lineChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [null, 10, null, null, 60, null, null]
}]
}
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx).LineAlt(lineChartData, {
//example of how this can be used, could use the value instead of the index
customYLabel: function (value, x, y, ctx, index) {
var defaultStyle = ctx.fillStyle;
ctx.fillStyle = '#' + intToARGB(index * 123456);
ctx.fillText(value, x, y);
ctx.fillStyle = defaultStyle;
}
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.1/Chart.js"></script>
<div style="width:100%">
<div>
<canvas id="canvas" height="200" width="600"></canvas>
</div>
</div>
&#13;