I am using a bar chart of chart.js in angular 7.This chart shows the relationship between policies and their number of sales. If the maximum number of sales is 2 or 1 or a small number, the chart shows the values along the y-axis in points, starts from 1 and ends on the maximum value.Right now i have maximum 6 policies, hence the values do not have points in them, but when the number of maximum policies reduce to 2, the values are as 1.0, 1.1, 1.2, 1.3....2.0. I want the values to be non-decimal in the y-axis and also they should start from zero up to the maximum number as 0,1,2,3...,. Is it possible?
//component
chartData1 = [
{
label: 'Policies',
data: this.policies
},
];
chartOptions = {
responsive: true // THIS WILL MAKE THE CHART RESPONSIVE (VISIBLE IN ANY DEVICE).
}
//template
<canvas
baseChart
[chartType]="'bar'"
[datasets]="chartData"
[labels]="labels"
[options]="chartOptions"
[legend]="true"
height="80"
width="100"
[colors]="colors"
(chartClick)="onChartClick($event)">
</canvas>
Within your component, try to define chartOptions as follows:
chartOptions = {
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1
}
}]
}
}
Related
I would like to set the color of y-axis tick labels in Chart.js bar and line charts based on the numeric label value. Specifically, I'd like negative values to be rendered red. Additionally rather than displaying "-1", "-2", etc., I'd like to override to display "(1)", "(2)", etc.
I've seen examples for changing tick labels based on index / position, but not conditionally based on the label value. Thanks in advance for any guidance.
You can define the scriptable option scales.x.ticks.color as an array of colors that depend on the corresponding data value each. The following definition for example shows red tick labels for every bar of a value less than 10.
scales: {
x: {
ticks: {
color: data.map(v => v < 10 ? 'red' : undefined)
}
}
}
For further information, consult Tick Configuration from the Chart.js documentation.
Please take a look at below runnable code and see how it works.
const data = [4, 12, 5, 13, 15, 8];
new Chart('myChart', {
type: 'bar',
data: {
labels: ['A', 'B', 'C', 'D', 'E', 'F'],
datasets: [{
label: 'Dataset',
data: data,
}]
},
options: {
responsive: false,
scales: {
x: {
ticks: {
color: data.map(v => v < 10 ? 'red' : undefined)
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<canvas id="myChart" height="180"></canvas>
I'm trying to create a line chart with chart.js where the data in a dataset contains points:
data: [{x:0,y:5},{x:2.1,y:4.3},{x:3.9,y:3}]
The x values of those points contain decimals. The resulting chart looks like this:
Instead of showing the second data point at (2.1 | 4.3) it is drawn at (1 | 4.3)!
Can someone point me into the right direction on this one?
The code to reproduce this behavior:
<body>
<div>
<canvas id="myChart" width="400" height="200"></canvas>
</div>
<script>
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0],
datasets: [{
label: 'some label',
data: [{x:0,y:5},{x:2.1,y:4.3},{x:3.9,y:3}],
borderColor: 'red',
fill: false,
lineTension: 0
}]
},
options: {
scales: {
xAxes: [{
ticks: {
max: 10,
min: 0,
stepSize: 0.1
}
}],
yAxes: [{
ticks: {
max: 6,
min: 0,
stepSize: 1
}
}]
}
}
});
</script>
</body>
For the y-axis, using the stepSize variable of the ticks option does the trick. Doing the same for the x-axis is a little more complex but not impossible.
The first issue is that your x-axis labels are at integer intervals so the chart has nowhere to position the decimal values than at the closest integer. This can be fixed by specifying all the values in the desired intervals (ie: 0.1, 0.2,...,3.0) in the labels.
Then, making use of the autoSkip and maxTicksLimit, you can hide the labels not needed and so create the chart seen in your image, but with the points in the correct position.
I made a working version of this using your code in this fiddle. Hope this helps!
I have this chart:
...which is displaying exactly how I want it to with one exception... The data in the bars is for between the two times in the x axis... so all the labels need shifting to lie on the grid lines, not between them as default for a bar chart. So the red and blue bar is data between 8:00 and 9:00. I hope I've explained that clearly enough.
I'm trawling through the Chart.js docs and it just doesn't seem like this is possible! I know I could change my labels to be, for example, 8pm - 9pm, but that seems a much more visually clunky way of doing it. Is there a way anyone know of achieving this? Ideally there would be another '12am' on the last vertical grid line too.
You can draw the tick lables at the desired position directly on to the canvas using the Plugin Core API. It offers number of hooks that may be used for performing custom code. In below code snippet, I use the afterDraw hook to draw my own labels on the xAxis.
const hours = ['00', '01', '02', '03', '04', '05', '06'];
const values = [0, 0, 0, 0, 10, 6, 0];
const chart = new Chart(document.getElementById('myChart'), {
type: 'bar',
plugins: [{
afterDraw: chart => {
var xAxis = chart.scales['x-axis-0'];
var tickDistance = xAxis.width / (xAxis.ticks.length - 1);
xAxis.ticks.forEach((value, index) => {
if (index > 0) {
var x = -tickDistance + tickDistance * 0.66 + tickDistance * index;
var y = chart.height - 10;
chart.ctx.save();
chart.ctx.fillText(value == '0am' ? '12am' : value, x, y);
chart.ctx.restore();
}
});
}
}],
data: {
labels: hours,
datasets: [{
label: 'Dataset 1',
data: values,
categoryPercentage: 0.99,
barPercentage: 0.99,
backgroundColor: 'blue'
}]
},
options: {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
time: {
parser: 'HH',
unit: 'hour',
displayFormats: {
hour: 'Ha'
},
tooltipFormat: 'Ha'
},
gridLines: {
offsetGridLines: true
},
ticks: {
min: moment(hours[0], 'HH').subtract(1, 'hours'),
fontColor: 'white'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>
For my charts, I am trying to have thin gridlines and thicker axis lines (both x and y).
I found an option to adjust zeroLineWidth but this is only applicable for 0 and my axis does not start at 0 (E.g. x-axis are years, so starting at 0 makes no sense).
I found some discussions about it but as far as I can tell this does not work yet: https://github.com/chartjs/Chart.js/pull/4117.
I also tried to supply an array for the gridLines lineWidth option. The first value changes the thickness of the axis but also of the first gridline. So this is not fully independent.
scales: {
yAxes: [{
gridLines: {
lineWidth: [5,1,1,1,1,1,1,1,1]
}
}]
}
Maybe there is no way to do this right now but if anyone has a solution that would be great. Even a hacky one would be welcome.
It looks like there's no way to do this since (as you noticed) the axis line width is directly derived from the gridline width via this line in the Chart.js source:
var axisWidth = gridLines.drawBorder ? valueAtIndexOrDefault(gridLines.lineWidth, 0, 0) : 0;
But, since you say a hacky solution is welcome...
The below snippet demonstrates combining two axes to achieve the desired affect; one for the border and one for the gridlines.
It's ugly, but functional.
let border_axis = {
gridLines: {
drawOnChartArea: false,
lineWidth: 10,
color: "rgba(255, 127, 0, 0.25)"
},
ticks: {
beginAtZero: true
}
},
gridline_axis = {
beforeBuildTicks: function(axis) {
if (axis.id == "y-axis-1") {
// this callback ensures both axes have the same min/max to keep ticks and gridlines aligned.
axis.max = axis.chart.scales["y-axis-0"].max;
axis.min = axis.chart.scales["y-axis-0"].min;
}
},
gridLines: {
drawTicks: false,
drawBorder: false
},
ticks: {
display: false
}
},
chart = new Chart(document.getElementById("chart"), {
type: "line",
data: {
labels: [2001, 2002, 2003, 2004, 2005],
datasets: [{
data: [1, 2, 3, 4, 5]
}]
},
options: {
scales: {
xAxes: [border_axis, gridline_axis],
yAxes: [border_axis, gridline_axis]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas id="chart"></canvas>
I want to have x, y-axis like the following image.
It is really sample, but the x,y across on (0,0). and I want the negative part always shows whatever there is a point or now.
Thanks
You can get a result close to your example image, but not exactly the same. You would probably need to create a custom axis to align the tick labels to the zero line.
let axisConfig = {
drawBorder: false,
gridLines: {
lineWidth: 0,
zeroLineWidth: 1
},
ticks: {
max: 6,
min: -6
}
};
new Chart(document.getElementById("chart"), {
type: "scatter",
options: {
scales: {
xAxes: [axisConfig],
yAxes: [axisConfig]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas id="chart"></canvas>