如何更改Y轴标签

时间:2015-03-16 06:18:58

标签: html5 chart.js

我使用Chartjs制作折线图。
如何将y轴标签更改为颜色? (即红色为1,绿色为2,黑色为3,......)

1 个答案:

答案 0 :(得分:1)

更新我现在已将此功能添加到https://github.com/leighquince/Chart.js的chartjs分支中,表示您不必覆盖或扩展新的图表类型。只需像往常一样传递选项,这是一个示例http://fiddle.jshell.net/leighking2/jLzvhf4f/

所以这可以通过覆盖scale draw方法来实现,以运行我们在声明图表时提供的自定义函数,而不仅仅是添加。

以下是摘录,但正如此处的解释是发生了什么

  1. 创建了一个新图表,并重写了buildScale方法以传递一个名为customYLabel的新选项。这是您在声明它时传递给图表的选项,它有4个参数;标签的值,x位置,y位置,画布,标签的索引

    1. 构建比例也使用自定义比例
    2. 创建一个自定义比例,该比例覆盖正常比例绘制方法以检查此customYLabel选项并使用它(如果存在)
  2. 重置是正常的,你的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;
    &#13;
    &#13;