echarts: bar chart start at value? - echarts

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>

Related

Multiple bars with same category name show differently based on array of arrays or array of objects

I noticed that using
option = {
xAxis: {
type: 'category',
},
yAxis: {
type: 'value'
},
series: [ {
type: 'bar',
data: [
{ name: 'Sun', value: 50 },
{ name: 'Sun', value: 80 },
{ name: 'Mon', value: 100 }
]
}]
}
There are two bars with category as 'Sun'. But if I use
option = {
xAxis: {
type: 'category',
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar',
data: [
['Sun',50],
['Sun',80],
['Mon',100]
]
}]
}
I see only one bar for 'Sun' with both data elements overlapping. Why does it work with array of objects differently? Also, if instead of using inline data, if I use dataset, then both array of arrays and array of objects behave the same where there is only one bar with overlap.
The reason I am looking for clarity on this is, I have a visualMap with a different attribute for color which makes the data repeat. I am trying to figure out if I need to create separate series or use the same series.
In general is bad idea to naming data points the same name. Strange that the data in the first case did not merge... If you need make the group then in the Echarts it's named stack. For the stack you can use the same name and it will be joined into one group.
VisualMap usually the global option and affects all series but you can limit with seriesIndex.
var myChart = echarts.init(document.getElementById('main'));
var option = {
xAxis: {
data: ["Cat1", "Cat2", "Cat3", "Cat4", "Cat5", "Cat6"]
},
visualMap: {
type: 'continuous',
range: [0, 70],
seriesIndex: 2,
color: ['green', 'blue', 'red'],
},
yAxis: {},
series: [{
name: 'Series1',
stack: 'group1',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
color: 'lightgray'
}, {
name: 'Series2',
stack: 'group1',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
color: 'gray'
}, {
name: 'Series3',
stack: 'group2',
type: 'bar',
data: [50, 20, 70, 10, 60, 40],
}]
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.9.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;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

Is there a way to specify the y-axis crossing point?

In the example below the y-axis crosses at 1, rather than 0. Is there a way to achieve this in echarts?
It seems to me, literally, you can't do this with basic bar chart because it will break the coordinate system and result will be anything but not a bar chart.
If you need only visual like on attached picture then you can hide xAxis and draw its surrogate with markLine but you will have the troubles with bar positioning (that will fix with stack and transparent bars, see below).
If you need real chart with responsive, zoomable and other opts then in the Echarts you can use custom series for build own chart type (see example).
Example how to make picture like attached:
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {},
xAxis: {
data: ['Category-1', 'Category-2', 'Category-3', 'Category-4'],
show: true,
axisLine: {
show: true,
lineStyle: {
opacity: 0
}
},
axisTick: {
show: false,
}
},
yAxis: {
max: 4,
min: -1
},
series: [{
name: 'Series-1',
type: 'bar',
stack: 'group',
data: [1, 1, -3],
color: 'rgba(0,0,0, 0)',
}, {
name: 'Series-2',
type: 'bar',
stack: 'group',
data: [{
value: 1,
itemStyle: {
color: 'red'
}
}, {
value: 2,
itemStyle: {
color: 'green'
}
}, {
value: 1,
itemStyle: {
color: 'orange'
}
}],
markLine: {
symbol: "none",
data: [{
silent: false,
yAxis: 1,
lineStyle: {
color: "#000",
width: 1,
type: "solid"
}
}, ],
label: {
show: false,
}
},
}]
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>
P.S. If this not a secret, why you need it?

Vertical stacked bar chart with chart.js

Excellent and free library from chart.js. I'm transferring my charts from Google charts to chart.js, because I can use them offline and it seems more responsive to window's changes of size. Furthermore I realised that my viewers in China could not see my Google charts because Google services are blocked in China.
I've been reading the documentation regarding stacked vertical bar charts, but I can't figure out, how to make a chart like this. In all examples I saw for stacked bar charts, the number of items is the same for each bar.
Can I make only two vertical stacked datasets? It's because the right bar has more items than the left one. Or do I need n datasets, being n the number of items, of the bar which has more items?
Code
I want to group one dataset per (stacked) bar, but I can't.
var ctx = document.getElementById("barChart").getContext('2d');
var labels = ["standing costs", "running costs"];
var dataset = [
{
type: 'bar',
label: ["cost1", "cost2", "cost3", "cost4"],
data: [1, 2, 1, 3],
stack: "standing costs",
backgroundColor: [
'navy',
'blue',
'aqua',
'teal'
]
},
{
type: 'bar',
label: ["cost5", "cost6", "cost7", "cost8"],
data: [5, 1, 3, 0],
stack: "running costs",
backgroundColor: [
'green',
'lime',
'yellow',
'white'
]
}
];
var options = {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
};
var content = {
type: 'bar',
data: {
labels: labels,
datasets: dataset
},
options
};
new Chart(ctx, content);
#import url("https://cdnjs.cloudflare.com/ajax/libs/colors/1.0/colors.min.css");
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.0/Chart.bundle.min.js"></script>
<canvas id="barChart"></canvas>
Quick Solution :
Vertical Stacked Bar Chart
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Standing costs', 'Running costs'], // responsible for how many bars are gonna show on the chart
// create 12 datasets, since we have 12 items
// data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')
// put 0, if there is no data for the particular bar
datasets: [{
label: 'Washing and cleaning',
data: [0, 8],
backgroundColor: '#22aa99'
}, {
label: 'Traffic tickets',
data: [0, 2],
backgroundColor: '#994499'
}, {
label: 'Tolls',
data: [0, 1],
backgroundColor: '#316395'
}, {
label: 'Parking',
data: [5, 2],
backgroundColor: '#b82e2e'
}, {
label: 'Car tax',
data: [0, 1],
backgroundColor: '#66aa00'
}, {
label: 'Repairs and improvements',
data: [0, 2],
backgroundColor: '#dd4477'
}, {
label: 'Maintenance',
data: [6, 1],
backgroundColor: '#0099c6'
}, {
label: 'Inspection',
data: [0, 2],
backgroundColor: '#990099'
}, {
label: 'Loan interest',
data: [0, 3],
backgroundColor: '#109618'
}, {
label: 'Depreciation of the vehicle',
data: [0, 2],
backgroundColor: '#109618'
}, {
label: 'Fuel',
data: [0, 1],
backgroundColor: '#dc3912'
}, {
label: 'Insurance and Breakdown cover',
data: [4, 0],
backgroundColor: '#3366cc'
}]
},
options: {
responsive: false,
legend: {
position: 'right' // place legend on the right side of chart
},
scales: {
xAxes: [{
stacked: true // this should be set to make the bars stacked
}],
yAxes: [{
stacked: true // this also..
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" width="700"></canvas>
apology for not giving explanation.
updated for v3
<div style="height: 500px">
<canvas id="chart_1" ></canvas>
</div>
<script>
chart = new Chart(document.getElementById('chart_1').getContext('2d'), {
type: 'bar',
data: {
labels: ["One", "Two", "Three"],
datasets: [{
label: 'Blue',
data: [100, 110, 120],
backgroundColor: 'blue',
},
{
label: 'Red',
data: [30, 20, 10],
backgroundColor: 'red',
},
]
},
options: {
plugins: {
title: {
display: true,
text: 'Example',
font: {
size: 14
}
},
},
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
});
</script>

Highcharts, graphing precipitation types, volumes and intensity over time

I have an automatic weather station that collects four different types of data for precipitation:
On/Off for precipitation event
total volume over time period in mm
intensity mm/hour and
precipitation type
i.e.:
0 No precipitation
40 Precipitation present
51 Light drizzle
52 Moderate drizzle
53 Heavy drizzle
Stacked bars can manage volume by precipitation type over time.
I would like to graph intensity by type by time. I think changing marker colours based on type is an answer to this. Is there a better solution please?
One suggestion based on your requirements could be a combination bar and line chart, using dual axes (as Grzegorz BlachliƄski mentioned).
As you noted, stacked bars would be helpful for showing comparative volume of each precipitation type. You could then overlay lines to show the intensity of each type over time.
I would suggest choosing colors that the user can easily relate to each precipitation type, especially between the two chart types.
Here's a rough draft I coded based on one of the demo charts from the Highcharts website:
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Precipitation'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: [{
min: 0,
title: {
text: 'Preipitation volume (mm)'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},{
min: 0,
title: {
text: 'Preipitation intensity (mm/hr)'
},
opposite: true
}],
legend: {
//align: 'bottom',
//x: -30,
//verticalAlign: 'bottom',
//y: 25,
//floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
series: [{
name: 'rain',
data: [5, 3, 4, 7, 2],
color: '#b3b3ff'
}, {
name: 'sleet',
data: [2, 2, 3, 2, 1],
color: '#d9b3ff'
}, {
name: 'snow',
data: [3, 4, 4, 2, 5],
color: '#c2c2f0'
},{
name: 'rain intensity',
data: [5, 3, 4, 7, 2],
color: 'blue',
type: 'line',
yAxis: 1
}, {
name: 'sleet intensity',
data: [2, 2, 3, 2, 1],
color: 'purple',
type: 'line',
yAxis: 1
}, {
name: 'snow intensity',
data: [3, 4, 4, 2, 5],
color: 'indigo',
type: 'line',
yAxis: 1
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
If you like, you're also welcome to work from this code at the fiddle I created here: http://jsfiddle.net/brightmatrix/kbk53n43/
I hope this is helpful for you.