ChartJS - aligning axis labels after rotation - chart.js

I am using Chart.js for generating BarChart. How can I align labels, so that rotation is 90 and all labels are aligned to start of each label. Currently, all labels are aligned to end of each label.
I am trying to display all labels to start at same vertical position - where 'A' of Avengers is. Currently all labels are ending at same vertical position - where 'r' of War is.
I need text turned towards right (not left) and coming from bottom to top (not top to bottom)
public barChartOptions: ChartOptions = {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
ticks: {
// maxRotation: 90,
minRotation: 90,
labelOffset: 0,
padding:-140
},
}]
},
};
Stackblitz link: https://ng2-charts-bar-template-tdpncj.stackblitz.io
Stackblitz code link: https://stackblitz.com/edit/ng2-charts-bar-template-tdpncj

You can put it like this:
xAxes: [{
ticks: {
minRotation: -90,
labelOffset: 0,
padding: -30
},
}]
Only problem is the text will be facing to the left

you can align labels like this but issue might be you pacing with text lenght size issue of handle that then it work for you , Sey minRotation: 360 so that rotation is 90 and all labels are aligned to start of each label
if you think text size you cannot make it short then i suggest you go with minRotation: 0 so it showing you proper text that every buddy like
export class AppComponent {
public barChartOptions: ChartOptions = {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
ticks: {
minRotation: 360,
labelOffset: 0,
padding: -30
},
}]
},
};
public barChartLabels: Label[] = ['A', 'Br', 'In', 'Aq', 'V', 'Mis'];
public barChartType: ChartType = 'bar';
public barChartLegend = true;
public barChartPlugins = [];
public barChartData: ChartDataSets[] = [
{ data: [65, 59, 80, 81, 56, 55, 40] }
];
constructor() { }
ngOnInit() {
}
}
Also check here updated code
https://stackblitz.com/edit/ng2-charts-bar-template-42mpft?file=src/app/app.component.ts

Related

chartjs backdropcolor of y scale ticks not showing

I played around with the stacked bar chart at
https://www.chartjs.org/docs/latest/samples/bar/stacked.html
Its currently looking like that:
config:
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
indexAxis: 'y',
scales: {
x: {
stacked: true,
title: {
display: true,
text: 'x-axis description',
},
},
y: {
ticks: {
mirror: true,
z: 1,
backdropColor: 'rgba(255, 0, 255, 0.75)'
},
stacked: true,
title: {
display: true,
text: 'y-axis description',
},
}
}
}
};
setup:
const labels = ['Short Label', 'vryshrtlbl', 'a litle bit more longer label', 'pretty veeeeeeeeeeeeeeeeeeeeeerylong label', 'ultra extreeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeemly long label']
const data = {
labels: labels,
datasets: [
{
label: 'Losers',
data: [-1,-2,-3,-44,-5],
backgroundColor: 'rgba(255, 0, 0, 0.5)',
},
{
label: 'Winners',
data: [6,12,23,55,5],
backgroundColor: 'rgba(255, 0, 0, 1)',
}
]
};
The thing is, that I may have such long labels. Since I dont want to waste space for them which makes the actual chart smaller I decided to bring the tick labels into the chart area.
But I would make them a bit better visible:
may move then to the right/center a bit
I already tried padding but this also shrinks the chart area, thats a no-go
bring a backgroundcolor like a grey box behind the tick labels such that there is no switch from white background to red bar behind the text
I was sure to achive that with backdropColor bit this option does not do anything.
from documentation I am sure I placed the setting correctly but I dont see any background behind the tick labels
Any Ideas why this does not work?
btw: I tried to provide a jsfiddle but when I place my code there it is ignoring the 'indexAxis' property and the 'stacked: true' as well. The first one I can workaround by using "type: 'horizontalBar'". But not the stacked one. Is this any kind of old writing this 'horizontalBar'? On chartjs page itself they are using 'bar' only.
If this may also could be answered then I may can prepare a fiddle in the future.
But one can reproduce my problem by going to
https://www.chartjs.org/docs/latest/samples/bar/stacked.html
and replace the contents with mine above.
Thanks.
Well for your first part of your question I have no solution. (it might be possible if you write a plugin or so, but no out-of-the-box solution, that I know of)
For part two "the grey box", check the demo below.
In short you will have to set the parameter showLabelBackdrop to true.
Here a demo, how I would do this:
let labels = ['Short Label', 'vryshrtlbl', 'a litle bit more longer label', 'pretty veeeeeeeeeeeeeeeeeeeeeerylong label', 'ultra extreeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeemly long label']
const data = {
labels: labels,
datasets: [
{
label: 'Losers',
data: [-1,-2,-3,-44,-5],
backgroundColor: 'rgba(255, 0, 0, 0.5)',
},
{
label: 'Winners',
data: [6,12,23,55,5],
backgroundColor: 'rgba(255, 0, 0, 1)',
}
]
};
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
indexAxis: 'y',
scales: {
x: {
stacked: true,
title: {
display: true,
text: 'x-axis description',
},
},
y: {
ticks: {
mirror: true,
backdropColor: '#cdcdcd',
backdropPadding: 0, // <- Adjust the box padding
showLabelBackdrop: true,
z: 1,
},
stacked: true,
title: {
display: true,
text: 'y-axis description',
},
}
}
}
};
new Chart(
document.getElementById('chart'),
config
);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart" style="height:300px; width:500px;">
<canvas id="chart" ></canvas>
</div>

why the main and axis title does not show in chart.js

I have the following code to make a chart with chart.js but the main and axis title just does not work. Also I have put the legend to the bottom but does not work. Can anybody tell why it is not working?
let dataSize = 30;
let readings = new Array(dataSize);
const data = {
// X axis labels
labels: new Array(dataSize),
datasets: [{
//label: 'My Input', // chart label
data: readings, // the data to chart
//borderColor: '#272323', // line color (lavender)
backgroundColor: 'rgba(123, 83, 252, 80)',
borderColor: "rgba(255, 0, 0,1)",
borderWidth: 1.2,
pointBorderColor: "rgba(255, 0, 0, 1)",
pointRadius: 0.2 // point size
}]
};
const config = {
type: 'line', // type of chart
data: data, // the data
options: {
animation: false, // remove animation to speed drawing up
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: 'Tarrif'
},
legend:{
position: 'bottom'
},
scales: { // axis ranges:
y: {
//type: 'linear',
scaleLabel: {
display: true,
labelString: 'X axis Title'
},
min: 0,
max: 260,
gridLines: {
display: true,
drawBorder: false //hide the chart edge line
}
},
x:[{
gridLines: {
display: false
},
scaleLabel: {
display: true,
labelString: 'X axis Title'
},
min:0
}]
}
}
};
Below is screenshot of my graph:
I followed the advice here:
In Chart.js set chart title, name of x axis and y axis?
thanks
First of all don't use an array for your X scales, all the scales need to be defined as objects. Second you are placing the options in the wrong part, it has to be configured in the title namespace like so:
scales: {
y: {
title: {
display: true,
text: 'yTitle'
}
},
x: {
title: {
display: true,
text: 'xTitle'
}
}
}

Chartjs Datasets overlapping and z-index

I have the below Chart implemented using chart.js version 3.x.
https://jsfiddle.net/Lxya0u98/12/
I have multiple datasets in my charts to achieve the behavior I want.
I am facing an issue with the datasets overlapping. In the chart, I have end of the blue color line overlapping with the green color dot dataset. Is there a way to avoid this issue?
I have the below two datasets:
// Data set for the Big Dot
{
showLine: false,
borderWidth: 0,
lineTension: 0,
borderColor: colorVal,
backgroundColor: colorVal,
pointBackgroundColor: colorVal,
pointBorderColor: colorVal,
pointBorderWidth: 2,
pointRadius: 15,
};
// Data set for the Connecting Lines
{
showLine: true,
lineTension: 0,
borderWidth: 5,
borderColor: colorVal,
pointRadius: 0,
pointBorderWidth: 0,
spanGaps: true,
};
Is there a Z-Index for the Datasets so that they appear on top of the previous one in the stack?
The option dataset.order has similar effect as the z-index.
Datasets with higher order are drawn first
Datasets with no or lower order are drawn last, hence appear on top
Therefore, adding order: 1 to your line datasets should solve the problem.
var newDataLine = {
...
order: 1
};
Instead of defining multiple datasets, you could proceed as follows:
First convert your line chart into a scatter chart.
Then draw the lines directly on the canvas using the Plugin Core API. The API offers a range of hooks that may be used for performing custom code. You can use the beforeDraw hook to draw connection lines of different colors between data points and to the open end of the chart.
Note that you have to define xAxes.ticks.max in order to obtain the open end line at the right of the chart.
Please take a look at below runnable code snippet and see how it works.
new Chart('line-chart', {
type: "scatter",
plugins: [{
beforeDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
var xAxis = chart.scales['x-axis-1'];
var yAxis = chart.scales['y-axis-1'];
var dataset = chart.data.datasets[0];
var y = yAxis.getPixelForValue(0);
dataset.data.forEach((value, index) => {
var xFrom = xAxis.getPixelForValue(value.x);
var xTo;
if (index + 1 < dataset.data.size) {
xTo = xAxis.getPixelForValue(dataset.data[index + 1].x);
} else {
xTo = xAxis.right;
}
ctx.strokeStyle = dataset.backgroundColor[index];
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(xFrom, y);
ctx.lineTo(xTo, y);
ctx.stroke();
});
ctx.restore();
}
}],
data: {
datasets: [{
data: [
{ x: 0, y: 0 },
{ x: 1, y: 0 },
{ x: 2, y: 0 }
],
backgroundColor: ['red', 'blue', 'green'],
borderColor: ['red', 'blue', 'green'],
pointRadius: 8,
pointHoverRadius: 8,
}],
},
options: {
layout: {
padding: {
left: 10,
right: 10
}
},
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
display: false
},
gridLines: {
display: false,
}
}],
xAxes: [{
ticks: {
display: false,
max: 3
},
gridLines: {
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="line-chart" height="30"></canvas>

Is there a way to create a chart with only a single axis?

I'm trying to create a "chart" where I only want to show the x-axis. Basically I'm trying to create visualization of a range (min-max) and a point that sits in between like:
I'm unable to find any resources online on how to make this, or what this type of plot is even called. If anyone could help out, that would be awesome!
This is straightforward to achieve through styling a line chart appropriately and using linear x- & y-axes with points defined via x and y coordinates.
By keeping y at 0 you can assure the points all appear in the same horizontal position.
The example below gets the visual result you want, but you'll probably want to disable tooltips for the 'fake' x-axis line via a callback:
let range = {
min: 0,
max: 100
},
pointVal = 65;
new Chart(document.getElementById("chart"), {
type: "line",
data: {
labels: ["", "", ""],
datasets: [{
pointBackgroundColor: "green",
pointRadius: 10,
pointHoverRadius: 10,
pointStyle: "rectRot",
data: [{
x: pointVal,
y: 0
}]
}, {
// this dataset becomes the 'fake' x-axis line.
pointBackgroundColor: "black",
borderColor: "black",
data: [{
x: range.min,
y: 0
},
{
x: range.max / 2,
y: 0
},
{
x: range.max,
y: 0
}
]
}]
},
options: {
legend: {
display: false
},
hover: {
mode: "point"
},
layout: {
padding: {
left: 10,
right: 10,
top: 0,
bottom: 0
}
},
scales: {
xAxes: [{
type: "linear",
display: false
}],
yAxes: [{
display: false
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<div style="width:200px">
<canvas id="chart"></canvas>
</div>

Draw borders on line chartjs

I'm using ChartJS to create a line chart with elements. I'm wondering if it possible to set borders on left and right of a element? This is my chart and it gets confusing if you have two elements next to each other and they have the same color.
I've found nothing in the docs that supports it, so I figure that I have to draw it myself using js but I was hoping someone had an solution first :)
In case I have to draw it myself I would run into a problem since every element can have different widths due to the time axis (X). What would be your idea to solve that?
Update
Every element in the chart is a new dataset and gets a gradient object as backgroundColor and fill sets as true. Here is an example of me pushing a new dataset into the chart
chart.data.datasets.push({
fill: true,
backgroundColor: gradient,
data: [
{
x: aIstartX,
y: yAxis_value,
.. Other attributes
},
{
x: newEntryXend,
y: yAxis_value,
..Other attributes
}]
});
xAxes: [
{
stacked: false,
type: 'time',
unit: 'minute',
position: 'bottom',
scaleLabel: {
display: true
},
time: {
displayFormats: {
'minute': 'mm:ss'
}
},
ticks: {
autoSkip: true,
beginAtZero: true,
stepSize: 2,
autoSkipPadding: 5,
padding: 10,
labelOffset: 5,
},
gridLines: {
display: false,
tickMarkLength: 20
},
}
]
Here is a fiddle of my issue
https://jsfiddle.net/fa8hvhtv/1/
Any reason why you can wanted to keep the same background colors for ,
Why cant you try as below
Demo
fill: true,
backgroundColor: 'red',
I've found a solution to my problem. The issue was that I was trying to create some space between my datasets and my datas attribute Y doesnt start and end at 0. Therefor I added two extra datapoints in each dataset with a borderWidth of 3 and borderColor that matches the backgroundColor of the chart. Each extra added datapoint will have a Y with the value of 0. An example of adding a dataset to my chart is below.
chart.data.datasets.push({
fill: true,
backgroundColor: gradient,
borderWidth: 3,
borderColor: '#333',
data: [
{
x: startXvalue,
y: 0
},
{
x: startXvalue,
y: startY,
.. Other attributes
},
{
x: newEntryXend,
y: endY,
.. Other attributes
},
{
x: newEntryXend,
y : 0
}]
});