我正在使用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/
谢谢 !
如果您使用的是chart.js 2.x,只需在ticks选项中设置maxRotation:90和minRotation:90.这个对我有用!如果你想要所有的x标签,你可能想要设置autoSkip:false.以下是一个例子.
var myChart = new Chart(ctx, { type: 'bar', data: chartData, options: { scales: { xAxes: [{ ticks: { autoSkip: false, maxRotation: 90, minRotation: 90 } }] } } });
您需要扩展缩放类并覆盖该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
});
}