Chart Js 更改 Ox 轴上的文本标签方向
Chart Js change text label orientation on Ox axis
我正在使用 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 上:
谢谢!
您需要扩展比例尺 class 并覆盖 calculateXLabelRotation
方法以使用用户输入的旋转而不是尝试自行计算。如果这样做,则需要扩展条形图或折线图并覆盖 init 方法以使用此比例 class。 (或者您可以直接对刻度、条形和线条进行这些更改 classes,然后无需覆盖)。
所以首先扩展规模 class 并使其使用用户定义的选项
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;
}
},
});
然后在扩展栏中 class 创建一个新的图形类型并覆盖 init 方法以使用新的
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
这里有一个 fiddle 例子 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
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.1/Chart.js"></script>
<canvas id="canvas" height="150" width="300"></canvas>
如果您使用的是chart.js 2.x,只需设置 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
}
}]
}
}
});
请注意,对于 chart.js 3.x 指定轴比例选项的方式已更改:请参阅 https://www.chartjs.org/docs/master/getting-started/v3-migration.html#scales
因此,在上述 2.x 的答案中,您需要像这样删除方括号:
var myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
scales: {
xAxes: {
ticks: {
autoSkip: false,
maxRotation: 90,
minRotation: 90
}
}
}
}
});
我正在使用 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 上:
谢谢!
您需要扩展比例尺 class 并覆盖 calculateXLabelRotation
方法以使用用户输入的旋转而不是尝试自行计算。如果这样做,则需要扩展条形图或折线图并覆盖 init 方法以使用此比例 class。 (或者您可以直接对刻度、条形和线条进行这些更改 classes,然后无需覆盖)。
所以首先扩展规模 class 并使其使用用户定义的选项
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;
}
},
});
然后在扩展栏中 class 创建一个新的图形类型并覆盖 init 方法以使用新的
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
这里有一个 fiddle 例子 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
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.1/Chart.js"></script>
<canvas id="canvas" height="150" width="300"></canvas>
如果您使用的是chart.js 2.x,只需设置 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
}
}]
}
}
});
请注意,对于 chart.js 3.x 指定轴比例选项的方式已更改:请参阅 https://www.chartjs.org/docs/master/getting-started/v3-migration.html#scales
因此,在上述 2.x 的答案中,您需要像这样删除方括号:
var myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
scales: {
xAxes: {
ticks: {
autoSkip: false,
maxRotation: 90,
minRotation: 90
}
}
}
}
});