Chart.js: evenly distribute ticks when using maxTicksLimit

前端 未结 2 398
清酒与你
清酒与你 2020-12-08 22:07

I made a line chart using Chart.js version 2.1.3.

        var canvas = $(\'#gold_chart\').get(0);
        var ctx = canvas.getContext(\'2d\');
        var f         


        
相关标签:
2条回答
  • 2020-12-08 22:44

    A simpler solution until this is permanently fixed by the Chart JS contributors is to include a decimal in maxTicksLimit.

    For example:

    maxTicksLimit: 8,
    

    produces a huge gap at the end.

    maxTicksLimit: 8.1,
    

    Does not produce a huge gap at the end.

    Depending on what you want to set your maxTicksLimit to, you need to play around with different decimals to see which one produces the best result.

    0 讨论(0)
  • 2020-12-08 22:54

    Chart.js uses an integral skipRatio (to figure out how many labels to skip). With Chart.js v2.1.x, you can write your own plugin to use a fractional skipRatio


    Preview


    Script

    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);
                    }
                };
            }
        },
    });
    

    Fiddle - http://jsfiddle.net/bh63pe1v/

    0 讨论(0)
提交回复
热议问题