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

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>

Related

Where in options to define a name for the name of the X axis from such a dataset

The chartjs documentation provides an example in which it is unclear where to define a name for the X-axis. For the Y-axes, everything is clear, and where to determine the name for the X-axis name from such a data set in the same way?
const data = [{x: 'Jan', net: 100, cogs: 50, gm: 50}, {x: 'Feb', net: 120, cogs: 55, gm: 75}];
const cfg = {
type: 'bar',
data: {
labels: ['Jan', 'Feb'],
datasets: [{
label: 'Net sales',
data: data,
parsing: {
yAxisKey: 'net'
}
}, {
label: 'Cost of goods sold',
data: data,
parsing: {
yAxisKey: 'cogs'
}
}, {
label: 'Gross margin',
data: data,
parsing: {
yAxisKey: 'gm'
}
}]
},
};

Apache echarts scatter: assign label to each point

I am building an echarts scatter graph that contains 6 points. I would like to manually assign a label to each point, like I did with the label of X and Y axis.
Is there a way to achieve this? I searched in Apache Echarts docs but I did not find any useful setting for assigning a label to "data" values.
Here is the source code of my graph:
option = {
xAxis: {
data: ['Low', 'Med', 'High'],
name: "Value",
},
yAxis: {
min: '5',
name: "Score",
},
series: [
{
type: 'scatter',
symbolSize: 20,
data: [
[2,9.8],
[1,8.8],
[2,5.9],
[1,9.8],
[1,10.0],
[3,9.8],
[2,10.0],
[1,9.8],
[2,5.9],
[1,9.8]
],
label: {
show: true,
position: 'right',
color: "black",
fontSize: 16,
},
}
],
grid:{
show: true,
backgroundColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgb(255, 102, 102)'
},
{
offset: 1,
color: 'rgb(153, 255, 153)'
}])
},
};
You could specify the labels as an additional value in the data array:
data: [
[ 2, 9.8, "label1" ],
[ 1, 8.8, "label2" ],
...
Then use a formatter function in your label definition, to select the third element of the data array as the label:
label: {
...
formatter: function(d) {
return d.data[2];
}
I also found this solution, working as well as Chris one:
series: [
{
type: 'scatter',
symbolSize: 15,
data: [
{value: [2,9.8] , name: 'value1'},
{value: [1,8.8] , name: 'value2'},
{value: [2,5.9] , name: 'value3'},
],
label: {
show: true,
position: 'right',
formatter: params => params.name,
color: "black",
fontSize: 16,
},

ECharts bar chart backed by dataset; tooltip with several values

I'd like to show bar chart with categories on x-axis (say months), multiple series and each bar element containing multiple data points (value shown on y-axis, the rest in tooltip).
It's relatively easy to do it using series.data:
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
}
},
xAxis: {
type: 'category'
},
yAxis: {
type: 'value'
},
series: [
{
name: 'Series A',
type: 'bar',
label: {
show: true
},
data: [
['Jul', 320, 2],
['June', 119, 4]],
encode: {
tooltip: [0,1,2]
}
}
,
{
name: 'Series B',
type: 'bar',
label: {
show: true
},
data: [
['Jul', 420, 3],
['June', 123, 5]],
encode: {
tooltip: [0,1,2]
}
}
]
};
I'm wondering how it can be refactored best to use dataset? I have two ideas, I wonder what are pros & cons.. Maybe there is other, cleaner way to express it.
Ideally instead of one big array I'd prefer to have array of objects so dimensions are named.
Solution: One dataset, shifting indices
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
}
},
legend: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category'
//, data: ['Jul', 'June']
},
yAxis: {
type: 'value'
},
dataset: {
source: [
['Jul', 320, 2, 420, 3],
['June', 119, 4, 123, 5]]
},
series: [
{
name: 'Series A',
type: 'bar',
label: {
show: true
},
encode: {
y: 1,
tooltip: [0,1,2]
}
}
,
{
name: 'Series B',
type: 'bar',
label: {
show: true
},
encode: {
y: 3,
tooltip: [0,3,4]
}
}
]
};
With named dimensions it would look like:
dataset: {
source: [
[month:'Jul', SeriesA_dim1: 320, SeriesA_dim2: 2, SeriesB_dim1: 420, SeriesB_dim2: 3],
[month:'Jun', SeriesA_dim1: 119, SeriesA_dim2: 4, SeriesB_dim1: 123 SeriesB_dim2: 5],
},
....
encode: {
y: 'SeriesB_dim1',
tooltip: ['month','SeriesB_dim1','SeriesB_dim2']
}
Solution 2: Multiple datasets
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
}
},
legend: {},
xAxis: {
type: 'category'
},
yAxis: {
type: 'value'
},
dataset: [{
source: [
['Jul', 320, 2],
['June', 119, 4]]
},
{
source: [
['Jul', 420, 3],
['June', 123, 5]]
}],
series: [
{
name: 'Series A',
type: 'bar',
label: {
show: true
},
// data: [
// ['Jul', 320, 2],
// ['June', 119, 4]],
encode: {
tooltip: [0,1,2]
}
}
,
{
name: 'Series B',
type: 'bar',
label: {
show: true
},
// data: [
// ['Jul', 420, 3],
// ['June', 123, 5]],
datasetIndex: 1,
encode: {
tooltip: [0,1,2]
}
}
]
};
With named dimensions it would look like:
dataset: [{
source: [
[month:'Jul', dim1: 320, dim2: 2],
[month:'June', dim1: 119, dim2: 4]]
},
{
source: [
[month:'Jul', dim1: 420, dim2: 3],
[month:'June', dim1: 123, dim2: 5]]
}],
....
encode: {
y: 'dim1', // the default would be likely working as well
tooltip: ['month','dim1','dim2']
}

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>

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?