我正在使用chart.js。
类似于this Question,我想将我的x轴标签旋转90度。目前,我的标签使用默认设置旋转了80度。
有人可以帮我适应条形图解决方案来旋转标签,以便可以在折线图上使用它吗?
使用与上一个答案相同的方法,唯一需要更改的是图形类型的扩展。这次是在扩展折线图,并且设置有所不同,因为在构建比例中创建了折线图比例,因此这次是覆盖buildScale
,因此使用了自定义比例,而新选项[ C0]可以传入。overrideRotation
也被覆盖,但仅是为了可以调用超级初始化,并在构建图时使球滚动。
initialize
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.Line.extend({
name: "MyLine",
initialize: function(data) {
Chart.types.Line.prototype.initialize.apply(this, arguments);
},
buildScale: function(labels) {
var self = this;
var dataTotal = function() {
var values = [];
self.eachPoints(function(point) {
values.push(point.value);
});
return values;
};
var scaleOptions = {
templateString: this.options.scaleLabel,
height: this.chart.height,
width: this.chart.width,
ctx: this.chart.ctx,
textColor: this.options.scaleFontColor,
offsetGridLines: this.options.offsetGridLines,
fontSize: this.options.scaleFontSize,
fontStyle: this.options.scaleFontStyle,
fontFamily: this.options.scaleFontFamily,
valuesCount: labels.length,
beginAtZero: this.options.scaleBeginAtZero,
integersOnly: this.options.scaleIntegersOnly,
calculateYRange: function(currentHeight) {
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly
);
helpers.extend(this, updatedRanges);
},
xLabels: labels,
font: helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth: this.options.scaleLineWidth,
lineColor: this.options.scaleLineColor,
showHorizontalLines: this.options.scaleShowHorizontalLines,
showVerticalLines: this.options.scaleShowVerticalLines,
gridLineWidth: (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor: (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
showLabels: this.options.scaleShowLabels,
display: this.options.showScale,
overrideRotation: this.options.overrideRotation,
};
if (this.options.scaleOverride) {
helpers.extend(scaleOptions, {
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
});
}
this.scale = new Chart.MyScale(scaleOptions);
},
});
var randomScalingFactor = function() {
return Math.round(Math.random() * 100)
};
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
fillColor: "rgba(20,20,220,0.2)",
strokeColor: "rgba(20,20,220,1)",
pointColor: "rgba(20,20,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(20,20,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
fillColor: "rgba(120,120,120,0.2)",
strokeColor: "rgba(120,220,120,1)",
pointColor: "rgba(120,120,120,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(120,120,120,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
}
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).MyLine(barChartData, {
overrideRotation: 90
});
}
[如果使用Chart.js 2.x,只需在刻度选项中设置<script src="http://www.chartjs.org/assets/Chart.min.js"></script>
<canvas id="canvas" height="150" width="300"></canvas>
和maxRotation: 90
。这个对我有用!并且,如果要使用所有x标签,则可能需要设置minRotation: 90
。以下是一个示例。
autoSkip: false
这里是一个稍微更hackable的版本(Quince的答案更好—如果Chart.js的将来实现与var myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
scales: {
xAxes: [{
ticks: {
autoSkip: false,
maxRotation: 90,
minRotation: 90
}
}]
}
}
});
不同,则以下内容可能会中断)
标签旋转是通过逐步旋转标签,使它们适合垂直网格线之间的-使用calculateXLabelRotation
计算它们之间的间距。我们在正确的位置跳入,以强制此计算的结果为0(通过使scale.calculateX(1) - scale.calculateX(0)
返回相同的值)-这又迫使旋转进行到最大(即90度)]
预览
scale.calculateX
脚本
然后
Chart.types.Line.extend({
name: "LineAlt",
initialize: function () {
Chart.types.Line.prototype.initialize.apply(this, arguments);
var scale = this.scale;
var originalCalculateXLabelRotation = scale.calculateXLabelRotation;
var originalXScalePaddingLeft = scale.xScalePaddingLeft;
scale.calculateXLabelRotation = function () {
var originalCalculateX = scale.calculateX;
scale.calculateX = function () {
return 0;
}
originalCalculateXLabelRotation.apply(this, arguments);
scale.xScalePaddingLeft = originalXScalePaddingLeft;
scale.calculateX = originalCalculateX;
}
this.scale.fit();
}
});
小提琴-...
new Chart(ctx).LineAlt(data);
对于x轴使用此
http://jsfiddle.net/gc5gdg7e/
并且可以使用bucle过滤标签
options: {
legend: {
display: false
},
scales: {
xAxes: [
{
ticks: {
autoSkip: false,
maxRotation: 0,
minRotation: 0
}
}
]
}
}
arrayLabels.forEach((date, i) => {
let label = "";
if (i % step == 0 && fecha) {
label = moment(date, "DD/MM").format("DD MMM");
}
labels.push(label);
});
chartOptions.data.labels = labels;