热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

图表Js在Ox轴上更改文本标签方向

如何解决《图表Js在Ox轴上更改文本标签方向》经验,为你挑选了2个好方法。

我正在使用chartJS库 - http://www.chartjs.org/

如果文本标签太大,chartJs会显示45度的文本.请告诉我如何将文本旋转更改为30度.

请参阅以下内容:

    var data = {   labels:['Large Text Very Large','Text1','Text2'],
                 datasets:[ { label:'DS1',
                              fillColor:'rgba(228,218,86,0.5)',  
                             strokeColor:'rgba(228,218,86,0.8)',
                              highlightFill:'rgba(228,218,86,0.75)',
                              highlightStroke: 'rgba(228,218,86,1)', data:[0,1,0]
                            }
                 ]
           }


    var optiOns= {
        animation: false
    };

    //Get the context of the canvas element we want to select
    var c = $('#myChart');
    var ct = c.get(0).getContext('2d');
    var ctx = document.getElementById("myChart").getContext("2d");
    /*************************************************************************/
    myNewChart = new Chart(ct).Bar(data, options);

同样在jsfiddle:

http://jsfiddle.net/cvL9fk2t/

谢谢 !



1> 小智..:

如果您使用的是chart.js 2.x,只需在ticks选项中设置maxRotation:90minRotation:90.这个对我有用!如果你想要所有的x标签,你可能想要设置autoSkip:false.以下是一个例子.

var myChart = new Chart(ctx, {
  type: 'bar',
  data: chartData,
  options: {
    scales: {
      xAxes: [{
        ticks: {
          autoSkip: false,
          maxRotation: 90,
          minRotation: 90
        }
      }]
    }
  }
});



2> Quince..:

您需要扩展缩放类并覆盖该calculateXLabelRotation方法以使用用户输入的旋转而不是尝试将其自行解决.如果这样做,则需要扩展条形图或折线图并覆盖init方法以使用此缩放类.(或者您可以直接对比例,条形和线类进行这些更改,然后无需覆盖).

所以首先扩展scale类并使其使用用户定义的选项

var helpers = Chart.helpers;
Chart.MyScale = Chart.Scale.extend({
    calculateXLabelRotation: function() {
        //Get the width of each grid by calculating the difference
        //between x offsets between 0 and 1.

        this.ctx.fOnt= this.font;

        var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
            lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
            firstRotated,
            lastRotated;


        this.xScalePaddingRight = lastWidth / 2 + 3;
        this.xScalePaddingLeft = (firstWidth / 2 > this.yLabelWidth + 10) ? firstWidth / 2 : this.yLabelWidth + 10;

        this.xLabelRotation = 0;
        if (this.display) {
            var originalLabelWidth = helpers.longestText(this.ctx, this.font, this.xLabels),
                cosRotation,
                firstRotatedWidth;
            this.xLabelWidth = originalLabelWidth;
            //Allow 3 pixels x2 padding either side for label readability
            var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
            //check if option is set if so use that
            if (this.overrideRotation) {
                // do the same as before but manualy set the rotation rather than looping
                 this.xLabelRotation = this.overrideRotation;
                 cosRotation = Math.cos(helpers.radians(this.xLabelRotation));
                  // We're right aligning the text now.
                    if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8) {
                        this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
                    }
                    this.xScalePaddingRight = this.fontSize / 2;
                    this.xLabelWidth = cosRotation * originalLabelWidth;
            } else {
                //Max label rotate should be 90 - also act as a loop counter
                while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)) {
                    cosRotation = Math.cos(helpers.radians(this.xLabelRotation));

                    firstRotated = cosRotation * firstWidth;
                    lastRotated = cosRotation * lastWidth;

                    // We're right aligning the text now.
                    if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8) {
                        this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
                    }
                    this.xScalePaddingRight = this.fontSize / 2;


                    this.xLabelRotation++;
                    this.xLabelWidth = cosRotation * originalLabelWidth;

                }
            }
            if (this.xLabelRotation > 0) {
                this.endPoint -= Math.sin(helpers.radians(this.xLabelRotation)) * originalLabelWidth + 3;
            }
        } else {
            this.xLabelWidth = 0;
            this.xScalePaddingRight = this.padding;
            this.xScalePaddingLeft = this.padding;
        }

    },

});

然后在扩展bar类中创建一个新的图类型并覆盖init方法以使用new

Chart.types.Bar.extend({
    name: "MyBar",
    initialize: function(data) {

        //Expose options as a scope variable here so we can access it in the ScaleClass
        var optiOns= this.options;

        this.ScaleClass = Chart.MyScale.extend({
            overrideRotation: options.overrideRotation,
            offsetGridLines: true,
            calculateBarX: function(datasetCount, datasetIndex, barIndex) {
                //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
                var xWidth = this.calculateBaseWidth(),
                    xAbsolute = this.calculateX(barIndex) - (xWidth / 2),
                    barWidth = this.calculateBarWidth(datasetCount);

                return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth / 2;
            },
            calculateBaseWidth: function() {
                return (this.calculateX(1) - this.calculateX(0)) - (2 * options.barValueSpacing);
            },
            calculateBarWidth: function(datasetCount) {
                //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
                var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);

                return (baseWidth / datasetCount);
            }
        });

        this.datasets = [];

        //Set up tooltip events on the chart
        if (this.options.showTooltips) {
            helpers.bindEvents(this, this.options.tooltipEvents, function(evt) {
                var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];

                this.eachBars(function(bar) {
                    bar.restore(['fillColor', 'strokeColor']);
                });
                helpers.each(activeBars, function(activeBar) {
                    activeBar.fillColor = activeBar.highlightFill;
                    activeBar.strokeColor = activeBar.highlightStroke;
                });
                this.showTooltip(activeBars);
            });
        }

        //Declare the extension of the default point, to cater for the options passed in to the constructor
        this.BarClass = Chart.Rectangle.extend({
            strokeWidth: this.options.barStrokeWidth,
            showStroke: this.options.barShowStroke,
            ctx: this.chart.ctx
        });

        //Iterate through each of the datasets, and build this into a property of the chart
        helpers.each(data.datasets, function(dataset, datasetIndex) {

            var datasetObject = {
                label: dataset.label || null,
                fillColor: dataset.fillColor,
                strokeColor: dataset.strokeColor,
                bars: []
            };

            this.datasets.push(datasetObject);

            helpers.each(dataset.data, function(dataPoint, index) {
                //Add a new point for each piece of data, passing any required data to draw.
                datasetObject.bars.push(new this.BarClass({
                    value: dataPoint,
                    label: data.labels[index],
                    datasetLabel: dataset.label,
                    strokeColor: dataset.strokeColor,
                    fillColor: dataset.fillColor,
                    highlightFill: dataset.highlightFill || dataset.fillColor,
                    highlightStroke: dataset.highlightStroke || dataset.strokeColor
                }));
            }, this);

        }, this);

        this.buildScale(data.labels);

        this.BarClass.prototype.base = this.scale.endPoint;

        this.eachBars(function(bar, index, datasetIndex) {
            helpers.extend(bar, {
                width: this.scale.calculateBarWidth(this.datasets.length),
                x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
                y: this.scale.endPoint
            });
            bar.save();
        }, this);

        this.render();
    },
});

现在您可以使用此图表类型声明图表并传入选项 overrideRotation

这是一个小提琴的例子http://jsfiddle.net/leighking2/ye3usuhu/

和一个片段

var helpers = Chart.helpers;
Chart.MyScale = Chart.Scale.extend({
    calculateXLabelRotation: function() {
        //Get the width of each grid by calculating the difference
        //between x offsets between 0 and 1.

        this.ctx.fOnt= this.font;

        var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
            lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
            firstRotated,
            lastRotated;


        this.xScalePaddingRight = lastWidth / 2 + 3;
        this.xScalePaddingLeft = (firstWidth / 2 > this.yLabelWidth + 10) ? firstWidth / 2 : this.yLabelWidth + 10;

        this.xLabelRotation = 0;
        if (this.display) {
            var originalLabelWidth = helpers.longestText(this.ctx, this.font, this.xLabels),
                cosRotation,
                firstRotatedWidth;
            this.xLabelWidth = originalLabelWidth;
            //Allow 3 pixels x2 padding either side for label readability
            var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
            
            if (this.overrideRotation) {
                 this.xLabelRotation = this.overrideRotation;
                 cosRotation = Math.cos(helpers.radians(this.xLabelRotation));
                  // We're right aligning the text now.
                    if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8) {
                        this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
                    }
                    this.xScalePaddingRight = this.fontSize / 2;
                    this.xLabelWidth = cosRotation * originalLabelWidth;
            } else {
                //Max label rotate should be 90 - also act as a loop counter
                while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)) {
                    cosRotation = Math.cos(helpers.radians(this.xLabelRotation));

                    firstRotated = cosRotation * firstWidth;
                    lastRotated = cosRotation * lastWidth;

                    // We're right aligning the text now.
                    if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8) {
                        this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
                    }
                    this.xScalePaddingRight = this.fontSize / 2;


                    this.xLabelRotation++;
                    this.xLabelWidth = cosRotation * originalLabelWidth;

                }
            }
            if (this.xLabelRotation > 0) {
                this.endPoint -= Math.sin(helpers.radians(this.xLabelRotation)) * originalLabelWidth + 3;
            }
        } else {
            this.xLabelWidth = 0;
            this.xScalePaddingRight = this.padding;
            this.xScalePaddingLeft = this.padding;
        }

    },

});

Chart.types.Bar.extend({
    name: "MyBar",
    initialize: function(data) {

        //Expose options as a scope variable here so we can access it in the ScaleClass
        var optiOns= this.options;

        this.ScaleClass = Chart.MyScale.extend({
            overrideRotation: options.overrideRotation,
            offsetGridLines: true,
            calculateBarX: function(datasetCount, datasetIndex, barIndex) {
                //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
                var xWidth = this.calculateBaseWidth(),
                    xAbsolute = this.calculateX(barIndex) - (xWidth / 2),
                    barWidth = this.calculateBarWidth(datasetCount);

                return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth / 2;
            },
            calculateBaseWidth: function() {
                return (this.calculateX(1) - this.calculateX(0)) - (2 * options.barValueSpacing);
            },
            calculateBarWidth: function(datasetCount) {
                //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
                var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);

                return (baseWidth / datasetCount);
            }
        });

        this.datasets = [];

        //Set up tooltip events on the chart
        if (this.options.showTooltips) {
            helpers.bindEvents(this, this.options.tooltipEvents, function(evt) {
                var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];

                this.eachBars(function(bar) {
                    bar.restore(['fillColor', 'strokeColor']);
                });
                helpers.each(activeBars, function(activeBar) {
                    activeBar.fillColor = activeBar.highlightFill;
                    activeBar.strokeColor = activeBar.highlightStroke;
                });
                this.showTooltip(activeBars);
            });
        }

        //Declare the extension of the default point, to cater for the options passed in to the constructor
        this.BarClass = Chart.Rectangle.extend({
            strokeWidth: this.options.barStrokeWidth,
            showStroke: this.options.barShowStroke,
            ctx: this.chart.ctx
        });

        //Iterate through each of the datasets, and build this into a property of the chart
        helpers.each(data.datasets, function(dataset, datasetIndex) {

            var datasetObject = {
                label: dataset.label || null,
                fillColor: dataset.fillColor,
                strokeColor: dataset.strokeColor,
                bars: []
            };

            this.datasets.push(datasetObject);

            helpers.each(dataset.data, function(dataPoint, index) {
                //Add a new point for each piece of data, passing any required data to draw.
                datasetObject.bars.push(new this.BarClass({
                    value: dataPoint,
                    label: data.labels[index],
                    datasetLabel: dataset.label,
                    strokeColor: dataset.strokeColor,
                    fillColor: dataset.fillColor,
                    highlightFill: dataset.highlightFill || dataset.fillColor,
                    highlightStroke: dataset.highlightStroke || dataset.strokeColor
                }));
            }, this);

        }, this);

        this.buildScale(data.labels);

        this.BarClass.prototype.base = this.scale.endPoint;

        this.eachBars(function(bar, index, datasetIndex) {
            helpers.extend(bar, {
                width: this.scale.calculateBarWidth(this.datasets.length),
                x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
                y: this.scale.endPoint
            });
            bar.save();
        }, this);

        this.render();
    },
});



var randomScalingFactor = function() {
    return Math.round(Math.random() * 100)
};

var barChartData = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
        fillColor: "rgba(220,220,220,0.5)",
        strokeColor: "rgba(220,220,220,0.8)",
        highlightFill: "rgba(220,220,220,0.75)",
        highlightStroke: "rgba(220,220,220,1)",
        data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
    }, {
        fillColor: "rgba(151,187,205,0.5)",
        strokeColor: "rgba(151,187,205,0.8)",
        highlightFill: "rgba(151,187,205,0.75)",
        highlightStroke: "rgba(151,187,205,1)",
        data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
    }, {
        fillColor: "rgba(15,18,20,0.5)",
        strokeColor: "rgba(15,18,20,0.8)",
        highlightFill: "rgba(15,18,20,0.75)",
        highlightStroke: "rgba(15,18,20,1)",
        data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
    }]

}
window.Onload= function() {
    var ctx = document.getElementById("canvas").getContext("2d");
    window.myBar = new Chart(ctx).MyBar(barChartData, {
        overrideRotation: 30
    });
}


    

推荐阅读
author-avatar
手机用户2502868585
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有