问题
I am working on the chart.js vertical chart and I want to make a slight change in the way it displays.
Basically the first data will be displayed from the left but I want to display first data from right. Is that possible?
Here is the working version of what I have so far:
https://jsfiddle.net/wxaL6en0/4/
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false,
}
}
This is what i have done for the option.
The result I am expecting is, April
to be on the right and first bar to display on the right.
I am not sure this is possible since I didn't find any solution over the internet. But I hope someone tried this before.
回答1:
Unfortunately it seems that Chart.js 2.8.0 supports reverse boolean parameter only for ticks object of yAxes.
This means, that without hacking or monkey patching it cannot be done within Chart.js API.
Also this dirty solution I came up with seems to be over-engineered, because simply changing dataset.data array item by referring to it by its index does not trigger Chart.js animations properly, therefore one needs to use splice.
Explanation:
Actually the idea is pretty simple:
In order to show bars from right to left for a priori known number of them
One needs to first create an array of length equal to number of bars and fill it with nulls.
In other words an array containing as many nulls as there are bars to be displayed.
Then each new value has to be inserted (using splice) from the right (end of the array) at first index under which array item is null or just simply at correct index, counting down from the array.length - 1 to 0.
"Visualisation":
let value = 1;
const graphData = Array(3).fill(null);
console.log(graphData)
for(let i = graphData.length - 1; i >= 0; --i){
graphData.splice(i, 1, value++);
console.log(graphData)
}
Example:
class GraphController {
size = 0;
data = [];
labels = [];
graphData = [];
ctx = null;
chart = null;
constructor(size, data, labels, canvasId) {
this.size = size;
this.data = data;
this.labels = labels;
this.ctx = document.getElementById(canvasId).getContext('2d');
this.graphData = Array(size).fill(null);
}
fetchAndDraw(index = 1) {
const item = this.data[index - 1];
if (item.TotalReward) {
this.graphData[this.size - index] = item.TotalReward;
}
if (index > 1 && index < this.size) {
this.chart.data.datasets[0].data.splice(this.size - index, 1, item.TotalReward);
this.chart.update();
} else {
if (this.chart) {
this.chart.destroy();
}
this.chart = new Chart(this.ctx, {
type: 'bar',
data: {
labels: this.labels,
datasets: [{
data: [...this.graphData],
backgroundColor: '#fff',
hoverBackgroundColor: '#d5d5d5',
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false,
},
title: {
display: false,
},
tooltips: {
enabled: false,
},
scales: {
xAxes: [{
barPercentage: 1.0,
categoryPercentage: 0.55,
gridLines: {
display: false,
color: '#fff',
drawBorder: false,
zeroLineColor: '#fff'
},
ticks: {
fontFamily: '"Avenir Next", "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
fontSize: 16,
fontColor: '#fff',
padding: 15,
}
}],
yAxes: [{
categoryPercentage: 0.8,
barPercentage: 0.8,
gridLines: {
display: false,
color: '#fff',
drawBorder: false,
zeroLineColor: '#fff'
},
ticks: {
min: 0,
stepSize: 10,
fontFamily: '"Avenir Next", "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
fontSize: 16,
fontColor: '#fff',
padding: 10,
callback: function (value) {
return '$' + value;
}
}
}],
},
},
});
}
index++;
if (index <= this.size) {
setTimeout(() => {
this.fetchAndDraw(index);
}, 1000);
}
}
}
const data = [
{ "Month": "April ‘18", "TotalReward": 10.37 },
{ "Month": "May ‘18", "TotalReward": 18.11 },
{ "Month": "June ‘18", "TotalReward": 25.49 },
{ "Month": "January", "TotalReward": 35.55 },
{ "Month": "February", "TotalReward": 50.25 },
{ "Month": "March", "TotalReward": 59.15 },
]
const rewardLabels = ["April ‘18", "May ‘18", "June ‘18", "January", "February", "March"].reverse();
const graph = new GraphController(6, data, rewardLabels, 'rewardChart');
graph.fetchAndDraw();
.chart-wrap {
background: #333;
padding: 20px 10px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chart-wrap">
<canvas id="rewardChart" width="600" height="165"></canvas>
</div>
来源:https://stackoverflow.com/questions/58803539/chart-js-show-x-axis-data-from-right-to-left