chart.js之:使用maxTicksLimit时均匀分布蜱

问题描述 投票:9回答:2

我做了使用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');
        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
                        }
                    }]
                }
            }
        });

输出结果如下:

Screenshot

正如你所看到的,我通过maxTicksLimit限制蜱的最大数为8。然而,分布也不均匀。我怎样才能让蜱虫分布均匀?

附:总有289条记录中的数据集,每5分钟记录数据。 prices变量的样本值是:

[
  {"14:10", 1280.3},
  {"14:15", 1280.25},
  {"14:20", 1282.85}
]

我尝试maxTicksLimit的不同值,结果仍然没有均匀分布。

javascript chart.js
2个回答
18
投票

chart.js之使用积分skipRatio(找出多少标签跳过)。随着chart.js之v2.1.x,您可以编写自己的插件使用分数skipRatio


预习

enter image description here


脚本

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

小提琴 - http://jsfiddle.net/bh63pe1v/


3
投票

一种更简单的解决方案,直到这个永久由图表JS贡献者固定是包括在maxTicksLimit小数。

例如:

maxTicksLimit: 8,

产生在端部的巨大差距。

maxTicksLimit: 8.1,

不会产生在最后一个巨大的差距。

根据你想你的maxTicksLimit设置什么,你需要玩不同的小数,看看哪一个会产生最好的结果。

© www.soinside.com 2019 - 2024. All rights reserved.