How to specify ticks locations in chart.js? - charts

I am looking for a way to manually specify x/y ticks locations on a chart.js chart, an equivalent of matplotlib's matplotlib.pyplot.xticks. The documentation explains how to create custom tick formats, but this works on automatically calculated tick locations. How can I specify the ticks locations?
This is the config that I am using:
var config = {
type: "line",
data: {
labels: [],
datasets: [{
data: [{x: 1, y: 2}, {x: 5, y: 3}, {x: 6, y: 4}],
fill: false,
borderColor: "#1f77b4",
}],
},
options: {
scales: {
xAxes: [{
type: 'linear',
distribution: 'series',
ticks: {
min: 0.,
max: 7.,
},
}]
},
},
}
which produces this file:
I would like to specify xticks locations, e.g. [0., 3.5, 5.7, 6.1], so that the plot would look more like (not taking into account grid lines and smooth plot line):

Apparently with Chart.js v3, the accpted solution no longer works as expected. Trying afterBuildTicks as suggested by b1000 in his comment, it also didn't work.
To make it work with afterBuildTicks, you need to map the number values into objects that have the property value each ([{ value: 0 }, { value: 3.5 }, ... ]). This can be done as follows:
afterBuildTicks: axis => axis.ticks = [0, 3.5, 5.7, 6.1].map(v => ({ value: v }))
Please take a look at below runnable sample:
new Chart('line-chart', {
type: 'scatter',
data: {
datasets: [{
data: [{x: 1, y: 2}, {x: 5, y: 3}, {x: 6, y: 4}],
showLine : true,
borderColor: '#1f77b4',
}]
},
options: {
scales: {
x: {
min: 0,
afterBuildTicks: axis => axis.ticks = [0, 3.5, 5.7, 6.1].map(v => ({ value: v }))
}
}
}
});
canvas {
max-height: 180px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="line-chart"></canvas>

For not drawing grid lines on the chart, you need to add the following to your axes as described at Grid Line Configuration.
gridLines: {
drawOnChartArea: false
}
In order to obtain the ticks at the desired position only, you would define xAxis.ticks as shown below and documented at Tick Option and Creating Custom Tick Formats.
ticks: {
...
stepSize: 0.1,
autoSkip: false,
callback: value => [0, 3.5, 5.7, 6.1].includes(value) ? value : undefined,
maxRotation: 0
},
Finally, to obtain a straight line between the data points, define lineTension: 0 on your dataset as explained at Line Styling.
Please have a look at your amended code below.
var config = {
type: "line",
data: {
labels: [],
datasets: [{
data: [{x: 1, y: 2}, {x: 5, y: 3}, {x: 6, y: 4}],
fill: false,
lineTension: 0,
borderColor: "#1f77b4",
}],
},
options: {
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0.,
max: 7.,
stepSize: 0.1,
autoSkip: false,
callback: value => [0, 3.5, 5.7, 6.1].includes(value) ? value : undefined,
maxRotation: 0
},
gridLines: {
drawOnChartArea: false
}
}],
yAxes: [{
ticks: {
showLabelBackdrop: true
},
gridLines: {
drawOnChartArea: false
}
}]
},
},
};
new Chart('line-chart', config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="line-chart" height="80"></canvas>

Related

(Chart.js 3.7.0) change position of x-axis ticks to alternate between each tick?

I have a chart which effectively renders a timeline, but sometimes the tick positions are too close together
Current graph (padding: 25)
I can change the padding to be negative which puts them above the x-axis:
Ticks above x-axis (padding: -60)
But I'd prefer them to alternate to above and below eg 1st tick below, 2nd tick above, 3rd tick below etc.
Can I access the individual ticks padding to do this? See below my current code:
ticks: {
source: 'data',
maxRotation: 90,
minRotation: 90,
font: {
size: 12,
},
autoskip: true,
padding: -60,
},
TIA for any help! :-)
You can define two identical datasets together with two x-axes. One of the x-axes with position: 'top', the other one with default position ('bottom').
A slightly different ticks.callback function on both x-axes makes sure that only every second tick is displayed.
ticks: {
source: 'data',
...
callback: (v, i) => i % 2 ? v : ''
},
Please take a look at the following runnable code and see how it works.
const data = [
{ x: "2022-03-22", y: 0 },
{ x: "2022-04-01", y: 0 },
{ x: "2022-04-02", y: 0 },
{ x: "2022-04-03", y: 0 },
{ x: "2022-04-08", y: 0 },
{ x: "2022-04-12", y: 0 },
{ x: "2022-04-15", y: 0 }
];
new Chart('chart', {
type: 'line',
data: {
datasets: [{
data: data,
backgroundColor: 'black',
pointRadius: 5,
pointHoverRadius: 5,
borderWidth: 2,
xAxisID: 'x'
},
{
data: data,
backgroundColor: 'black',
pointRadius: 5,
pointHoverRadius: 5,
borderWidth: 2,
xAxisID: 'x2'
}]
},
options: {
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: context => undefined
}
}
},
scales: {
y: {
ticks: {
display: false,
},
grid: {
display: false,
drawBorder: false
}
},
x: {
position: 'top',
type: 'time',
time: {
unit: 'day',
tooltipFormat: 'MMM DD'
},
ticks: {
source: 'data',
minRotation: 90,
callback: (v, i) => i % 2 ? v : ''
},
grid: {
display:false,
drawBorder: false
}
},
x2: {
type: 'time',
time: {
unit: 'day',
tooltipFormat: 'MMM DD'
},
ticks: {
source: 'data',
minRotation: 90,
callback: (v, i) => i % 2 ? '' : v
},
grid: {
display:false,
drawBorder: false
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#1.0.0"></script>
<canvas id="chart" height="50"></canvas>

echarts: bar chart start at value?

echarts: bar chart bars are located left and right of the value on the category axis:
How to tell echarts to start the bar with the value on the category axis? Like this:
To clarify the problem, here ist another example. This is a chart of the hourly sum of precipitation. Every bar should show the sum from the bottom to the top of the hour, the data values are conencted to every bottom of the hour.
as you can see, the bars are not starting at 8:00, they are starting at 7:30.
Data: (timestamps are shown in CET)
series: [
{
name: "Niederschlag",
type: "bar",
data: [[1608534000000, 3], [1608537600000, 5], [1608541200000, 2], [1608544800000, 0], [1608548400000, 1] ],
barWidth: '100%'
}
]
It should look like this:
Start point of bar here doesn't matter, you need align labels to left: https://echarts.apache.org/en/option.html#series-bar.label.align
you need a hidden xAxis like below:
option = {
xAxis: [{
type: 'category',
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
show: false
}, {
type: 'category',
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
boundaryGap: false,
axisTick: { alignWithLabel: true },
position: 'bottom'
}],
yAxis: {
type: 'value'
},
series: [{
data: [120, 200, 150, 80, 70, 110, 130,120,210,110,210],
type: 'bar',
barCategoryGap:'20%',
itemStyle: {
},
xAxisIndex: 0,
backgroundStyle: {
color: 'rgba(220, 220, 220, 0.8)'
}
}]
};
You have not provided the complete chart config, so I recommend using this one. Also pay attention on method useUTC and you need to know that "By default, echarts uses local timezone to formate time labels"
So I see this state of Chart by you data with offset -180:
var myChart = echarts.init(document.getElementById('chart'));
var chartData = [
[1608534000000, 3],
[1608537600000, 5],
[1608541200000, 2],
[1608544800000, 0],
[1608548400000, 1],
];
var option = {
tooltip: {},
xAxis: {
type: 'time',
data: ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'],
splitNumber: 24,
},
yAxis: {
type: 'value'
},
series: [{
name: "Niederschlag",
type: "bar",
data: chartData,
barWidth: '100%',
}],
useUTC: false,
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.9.0/dist/echarts.min.js"></script>
<div id="chart" style="width: 1024px;height:400px;"></div>

echarts - visualMap according to y axis

I am trying to add a visual map according to the y axis in echarts.
Taking one of their example:
https://echarts.apache.org/examples/en/editor.html?c=area-pieces
The results looks as follow:
what I'm trying to achieve is:
Obviously here, I have just rotated the picture by 90 degree.
How can this be achieve in echarts directly (so not by saving the picture first)?
The simplest solution would be inverting the axis, data index, and visual map axis. See chart options below:
option = {
backgroundColor: '#fff',
xAxis: {
type: 'value',
boundaryGap: [0, '30%'],
position: 'top'
},
yAxis: {
type: 'category',
boundaryGap: false
},
visualMap: {
type: 'piecewise',
show: false,
dimension: 1,
seriesIndex: 0,
pieces: [{
gt: 1,
lt: 3,
color: 'rgba(0, 180, 0, 0.5)'
}, {
gt: 5,
lt: 7,
color: 'rgba(0, 180, 0, 0.5)'
}]
},
series: [
{
type: 'line',
smooth: 0.6,
symbol: 'none',
lineStyle: {
color: 'green',
width: 5
},
markLine: {
symbol: ['none', 'none'],
label: {show: false},
data: [
{yAxis: 1},
{yAxis: 3},
{yAxis: 5},
{yAxis: 7}
]
},
areaStyle: {},
data: [
[200, '2019-10-10'],
[400, '2019-10-11'],
[650, '2019-10-12'],
[500, '2019-10-13'],
[250, '2019-10-14'],
[300, '2019-10-15'],
[450, '2019-10-16'],
[300, '2019-10-17'],
[100, '2019-10-18']
]
}
]
};
Result:
See on Imgur

Change Graph Series Fillcolor in highcharts

AS shown in image, i want to change Fill color by point (referring project state in my case so),
visual for my chart
code i have used so far to achieve this is below,
$(function () {
$('#ao-projectssummry-chart').highcharts({
type: "spline",
title: null,
borderRadius : null,
xAxis: {
categories: ['May2016', 'June2016', 'July2016', 'August2016', 'september2016', 'November2016'],
opposite: true
//type: 'datetime',
//min: Date.UTC(2011, 4, 31),
//max: Date.UTC(2012, 11, 6)
},
yAxis: {
min: 0,
max: 5,
title : null
},
plotOptions: {
series: {
lineWidth: 20,
borderRadius: null,
radius: 0
},
marker: {
radius : 0
}
},
credits : {
enabled : false
},
legend: {
enabled : false
},
series: [{
name: "Project 1",
data: [1, 1, {
y: 1,
marker: {
symbol: 'url(https://www.highcharts.com/samples/graphics/sun.png)',
overlapping: true
}
}, {
y: 1,
marker: {
symbol: 'url(https://www.highcharts.com/samples/graphics/sun.png)'
}
}, {
y: 1,
marker: {
symbol: 'url(https://www.highcharts.com/samples/graphics/sun.png)'
}
}
]
},
{
name: "Project 2",
data: [2, {
y: 2,
marker: {
symbol: 'url(https://www.highcharts.com/samples/graphics/sun.png)',
overlapping : true
}
}, 2, 2, 2, {
y:2,
marker: {
symbol: 'url(https://www.highcharts.com/samples/graphics/sun.png)',
overlapping: true
}
},
]
}]
});
});
so, how can i change the plotoption color by point? also how can i achieve background lines shown in the picture?
Any help would be appreciated! thanks in advance.
Ok, so it seems the question is different than what I read it as the first time. Rather than changing the color of the point markers, you want to change the color of the segments between markers.
Here is an approach that achieves what you are asking for, using the columnrange series type instead of a line. This allows more flexibility and control.
The idea:
First, set the type, and invert the chart (columnrange is a vertical series type; to make it horizontal, invert the chart - the x axis is now the vertical axis, and the y axis is now the horizontal axis):
chart: {
type: "columnrange",
inverted: true
}
Update the axis settings accordingly (swap x for y).
Set your data with an x value, a low value (starting point), and a high value (end point).
Set the color to whatever you want:
data: [{
x: 1,
low: Date.UTC(2016,3,15),
high: Date.UTC(2016,4,21),
color: 'rgb(0,156,255)'
},{
x: 3,
low: Date.UTC(2016,2,7),
high: Date.UTC(2016,6,15),
color: "rgb(204,0,0)"
}]
To place the markers, add a separate series, either line or scatter (I use line, with a lineWidth: 0, because scatter series use a different tooltip model, and are not as easy to integrate with other series, if the tooltip is important to you. But otherwise, both work the same).
Marker series:
{
name: 'Markers',
type: 'line',
data: [
{
x: 1,
y: Date.UTC(2016,2,15),
marker: {
fillColor:"#9CCB00"
}
}
Example:
https://jsfiddle.net/jlbriggs/x7c3t81n/
Output:
You need to specify that in the data array directly:
Example code:
data: [5,4,3,2,5,6,7,9, {y:6, marker: { enabled: true, radius: 10, fillColor: 'red'}},3,2,5,6,7]
Anything that you can specify in the plotOptions that affects the data point, you can specify in this way for a specific data point.
Any point for which you don't specify anything, follows the default options, or the options specified in the plotOptions.
Fiddle:
http://jsfiddle.net/jlbriggs/3d3fuhbb/126/
Output:

Double column Highcharts with drilldown

I am using Highcharts for generating a two column bar graph. Means for each day I am showing the number of downloads and number of signups. Now I need to have a drilldown, which shows up the hourly data. The Highcharts docs is showing an example for Signle column by specifying the y value. But as I am showing stached bar, I have two y values for the same date. The code I am using is as follows :
series: [{
name : 'Signups,
color : '#0066FF',
data : <?=$series_1?>, //data in JSON format from PHP
drilldown: true
}, {
name : 'Downloads',
color : '#E81531',
data : <?=$series_2?>, //data in JSON format from PHP
drilldown: true
}],
Example for you for drilldown with two series, with stacking: 'normal': http://jsfiddle.net/6zYmJ/10/
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Basic drilldown'
},
xAxis: {
type: 'category'
},
legend: {
enabled: false
},
plotOptions: {
series: {
stacking: 'normal',
borderWidth: 0,
dataLabels: {
enabled: true,
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Animals',
y: 5,
drilldown: 'animals'
}, {
name: 'Fruits',
y: 2,
drilldown: 'fruits'
}, {
name: 'Cars',
y: 4,
drilldown: 'cars'
}]
}, {
name: 'Things2',
colorByPoint: true,
data: [{
name: 'Animals2',
y: 5,
drilldown: 'animals2'
}, {
name: 'Fruits2',
y: 2,
drilldown: 'fruits2'
}, {
name: 'Cars2',
y: 4,
drilldown: 'cars2'
}]
}],
drilldown: {
series: [{
id: 'animals',
data: [
['Cats', 4],
['Dogs', 2],
['Cows', 1],
['Sheep', 2],
['Pigs', 1]
]
}, {
id: 'fruits',
data: [
['Apples', 4],
['Oranges', 2]
]
}, {
id: 'cars',
data: [
['Toyota', 4],
['Opel', 2],
['Volkswagen', 2]
]
},{
id: 'animals2',
data: [
['Cats', 4],
['Dogs', 2],
['Cows', 1],
['Sheep', 2],
['Pigs', 1]
]
}, {
id: 'fruits2',
data: [
['Apples', 4],
['Oranges', 2]
]
}, {
id: 'cars2',
data: [
['Toyota', 4],
['Opel', 2],
['Volkswagen', 2]
]
}]
}
})
Adding to Pawel Response-
Just replace in plotOptions with this value
column: {
pointPadding: 0.2,
borderWidth: 0
}
,