Handle X-axis label position in chart js - javascript

Please look into this fiddle
If you resize the output window you will notice that the labels of x-axis becomes slanted. which is fine for me. But if you notice that the end position of label is center of bar. I want the end position of label to be the right-side end of bar. How can achieve this?
My config is
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["2 Jan", "9 Jan", "16 Jan", "23 Jan", "30 Jan", "6 Feb", "13 Feb"],
datasets: [{
data: [6, 87, 56, 15, 88, 60, 12],
}]
},
options: {
legend: {
"display": false
},
tooltips: {
"enabled": false
},
scales: {
yAxes: [{
display: false,
gridLines: {
display : false
},
ticks: {
display: false,
beginAtZero:true
}
}],
xAxes: [{
gridLines: {
display : false
},
ticks: {
beginAtZero:true
}
}]
}
}
});

It is certainly possible to achieve a 'right' aligned scale tick label instead of the original 'center' aligned scale tick label, but unfortunately it is not very straight forward to implement. Let me walk you through how to do it and then provide an example.
1) First, since there is no configuration option to control this, we have to look at doing some sort of custom implementation. It turns out that the scale tick labels in a bar chart are rendered as part of the Category scale's draw method. Therefore, we must somehow overwrite this draw method to change to a new alignment.
2) According to the API there is a documented way to create new scale types, so we should be able to use a similar approach to extend the Category scale type and overwrite it's draw method.
Since all scales are wrapped up in the ScaleService we have to use the below approach to extend an existing scale type.
var CategoryRightAligned = Chart.scaleService.getScaleConstructor('category').extend({});
3) Now its just a matter of figuring out what part of the draw method we need to modify. After looking it over, it looks like we need to change the logic for calculating labelX (the pixel position to render the tick label). Here would be the new logic.
// current logic for getting pixel value of each label (we will use the logic below to
// adjust if necessary)
labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset;
// get a reference to the bar chart controller so we can determine the chart's bar width
var meta = me.chart.getDatasetMeta(0);
// use the bart chart controller to calculate the bar width
var barWidth = meta.controller.calculateBarWidth(meta.controller.getRuler());
// if the labels are rotated, then move the pixel location from the middle of the bar
// to the far right of the bar
if (labelRotationRadians != 0) {
labelX += barWidth / 2;
}
4) Now we just need to register our new scale and configure the chart to use it (instead of the bar chart default category scale).
Chart.scaleService.registerScaleType('categoryRightAligned', CategoryRightAligned, {position: 'bottom'});
xAxes: [{
type: 'categoryRightAligned',
gridLines: {
display : false,
offsetGridLines: true
},
ticks: {
beginAtZero:true,
}
}]
Refer to this jsfiddle example to see it in action and to see how everything fits together.

Related

Charts.js - How to create a custom X axis

I'm trying to create a mix chart, a bar chart with a line chart. Below is a picture of a standard example.
I need to change the x-axis as shown in the picture below, how can I do that?
In other words, I want to remove the dependence of x-axis labels on the number of bars and their points and make the x-axis arbitrary, which sets the maximum and minimum values and its step
Change the labels as shown in this example:
const data = {
// Put whatever you want
labels: [0, 5, 10, 15, 20],
datasets: [
{
/* ........ */
},
]
};
I found a solution, we need to add a new dataset and bind it to a custom X axis.
datasets: [{
type: chartTypes.Line,
xAxisID: 'custom-X-axis',
},
/*...*/]
Then we need to add this custom axis and hide the default one
scales: {
xAxes: [
{
display: false,
}, {
id: 'custom-X-axis',
type: 'linear',
ticks: {
min: 0,
max: 20,
}
}
],
}

How to set custom scale to polar area chart?

The Problem:
I am using polar area chart. For slices in this chart, each value after the largest value should appear one level smaller. The level is as follows: for example, if the value after a 38 slice is 6, it should look like 37. Or I should be able to set it to the level I want. My question is all about sizing the slices on the polar area.
What I get:
What I want:
Sorry for my bad drawing. You can think what i want is like:
scaling very small slices close to large slice.
Methods I tried:
I tried changing the scale and ticks parameters from the link chartjs axes settings but without success.
I put the index data after sorting the array as data into the dataset. It worked as I wanted, but this time the values appeared as index values.
Charts.js polar area scales I tried this also but not worked.
A solution can be reached from the two methods I tried, but I could not.
Code example here:
function SetWorkflowChart(labels, datas, labelColors) {
//label colors
// workflow stats chart
const workflowdata = {
labels: labels,
datasets: [{
normalized: true,
data: datas, // example data: [38, 5,3]
backgroundColor: labelColors,
borderColor: "rgba(0, 0, 0, 0.0)"
}]
};
const workflowconfig = {
type: 'polarArea',
data: workflowdata,
options: {
scales: {
r: {
grid: {
display: false
},
ticks: {
display: false //try2 i tried to set ticks for scale
},
suggestedMin: 5, //try1
suggestedMax: 20,//try1
}
},
plugins: {
legend: {
display: false,
position: "right"
},
},
responsive: false
}
};
workflowChart = new Chart(
document.getElementById('WorkFlowStatsChart'),
workflowconfig
);
}
I'll be pleased if you pay attention.

Chart.js - mixed chart types (line/bar) on time scale causing offset problems after migration to v3

I'm using chart.js in my project where I'm having a daily-ticked time scale on the X axis and two linear scales on the Y axis. On one linear scale I'm rendering an usual line chart representing a chronological trend while rendering multiple stacked bar charts on the other linear scale, representing average stats for each day. Pre-v3 versions of chart.js were dictating to use a general chart type bar for this to work, and in my case it did even on a time scale. Only workaround I had to use to was to set the bar chart data to 12:00pm to have it centered on the day while also setting the barThickness manually, as it will default to 0 (?) on a time scale otherwise.
Now I've recently updated to v3.2.0 and adjusted my options and datasets according to the migration documentation. Rendering the charts I noticed that the scale ticks were offset by half a day, thus both charts being off. After some research I found out that it was due to the offset option for the scale being enabled as I was using a bar chart.
Manually turning off the offset option is to no avail either though. Besides the time scale not using up another day anymore, the ticks are still off by half a day.
Cutting out the bar chart dataset resets the ticks back to normal. Unfortunately there doesn't seem to be a way to apply the offset only to the bar charts. Does anyone have an idea how to deal with this?
I have now created a Codepen example for this.
scales: {
x: { // time scale
type: 'time',
offset: false,
time: {
unit: 'day',
displayFormats: {
day: 'iii, dd.MM'
}
},
bounds: 'ticks',
grid: {
color: "#444",
zeroLineColor: "#888",
zeroLineWidth: 2
},
title: {
display: true,
text: 'Date'
}
},
yT: { // line chart scale
position: 'right',
beginAtZero: false,
grid: {
color: "#444",
zeroLineColor: "#888",
zeroLineWidth: 2
},
ticks: {
maxTicksLimit: 24,
stepSize: 9000,
callback: (duration) => String(duration / 3600) + 'h'
}
},
yR: { // bar chart scale
position: 'right',
beginAtZero: false,
grid: {
color: "#444",
zeroLineColor: "#888",
zeroLineWidth: 2
},
ticks: {
maxTicksLimit: 48,
stepSize: 10800,
callback: (duration) => String(duration / 3600) + 'h'
},
title: {
display: true,
text: 'Duration'
},
stacked: true
}
}
I opened an issue on GitHub where I was told that I also had to explicitly set the grid.offset option to false, and this fixed it for me.

How to modify bar width in Chartjs 2 bar charts

Can someone told me how to modify bar width in Chartjs 2 bar charts. There is nothing about it in the documentation.
https://github.com/nnnick/Chart.js/tree/v2.0-dev/docsI don't know what to do.
For version 2.4.0
barThickness - Manually set width of each bar in pixels. If not set, the bars are sized automatically.
options = {
scales: {
xAxes: [{
barThickness : 73
}]
}
}
For me, trying 2.0 beta, what worked was to set the barPercentage on the xAxes scale option.
This is what I used:
var options = {
data: chartData,
type: "bar",
options: {
scales: {
xAxes: [{ barPercentage: 0.5 }]
}
}
};
var chart = new Chart(chartCtx, options);
Note that there seems to be some changes going on. The actual configuration would depend on which v2.0 you are using.
For Version 2.0.0-alpha
Set categorySpacing for the xAxes. You can do this globally
Chart.defaults.bar.scales.xAxes[0].categorySpacing = 0
or you can do it by chart
...
scales: {
xAxes: [{
categorySpacing: 0
}],
...
Fiddle - http://jsfiddle.net/beehe4eg/
For Version 1.0.2
Adjust the options barValueSpacing and barDatasetSpacing to make the bars closer. This will automatically increase their width.

Highcharts Speedometer, dataLabel for mileage counter

There are several examples with the Speedometer in Highcharts.
Is there a way, to show an additional dataLabel only, without dial in the gauge?
It could show a trip recorder, mileage counter or day counter.
I tried additional series and dataLabels, but could not get it running.
http://jsfiddle.net/uqa0t3xw
series: [{
name: 'mileage counter',
data: [],
dataLabels: {
x: 0, y: 20,
format: '{y:.0f} km',
}
}]
If you want to have an additional data label by adding another series and hiding the dial you can do so by setting the color of the dial to "transparent" (JSFiddle):
series: [
// Our "hidden" series
{
name: 'mileage counter',
data: [0],
dataLabels: {
x: 0, y: 50,
format: '{y:.0f} km',
},
dial: {
backgroundColor: 'transparent'
}
},
// ... Other series
]
Also note how the y value has to be big enough to not overlap with the other data labels. If it overlaps it will be hidden, since gauge has allowOverlap: false by default. Alternatively you could set that to true, but overlapping might not be pretty.
It should be noted that this can also be solved by creating your own div and placing it in the correct spot or perhaps copying the data label from the first series and moving it slightly.

Categories

Resources