chart.js を使用しています。
この質問 と同様に、x軸ラベルを90度回転させたいと思います。現在、ラベルはデフォルト設定で約80度回転しています。
誰かが私が折れ線グラフで使用できるように、ラベルを回転させるために棒グラフソリューションを適応させるのを手伝ってもらえますか?
前の回答と同じ方法を使用して変更する必要があるのは、グラフタイプの拡張だけです。今回は折れ線グラフを拡張し、折れ線グラフスケールがビルドスケールで作成されるため、セットアップが少し異なります。したがって、カスタムスケールが使用されるようにbuildScale
がオーバーライドされます。新しいオプション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
});
}
<script src="http://www.chartjs.org/assets/Chart.min.js"></script>
<canvas id="canvas" height="150" width="300"></canvas>
Chart.js 2.xを使用している場合は、maxRotation: 90
およびminRotation: 90
in ticksオプション。わたしにはできる!また、すべてのxラベルが必要な場合は、autoSkip: false
。以下に例を示します。
var myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
scales: {
xAxes: [{
ticks: {
autoSkip: false,
maxRotation: 90,
minRotation: 90
}
}]
}
}
});
これはもう少しハッカーのバージョンです(クインセの答えが優れています-Chart.jsの将来の実装がcalculateXLabelRotation
を異なる方法で実行すると、以下が壊れる可能性があります)
ラベルの回転は、垂直グリッド線の間に収まるようにラベルを段階的に回転させることで計算されます。ラベル間のスペースは、scale.calculateX(1) - scale.calculateX(0)
を使用して計算されます。正しいポイントにジャンプして、この計算の結果を強制的に0にします(scale.calculateX
同じ値を返します)-これにより、回転が最大値(つまり90度)まで強制的に進行します
プレビュー
スクリプト
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);