I have a multidimensional array structured like this: [[year,month,day,value],[year2,month2,day2,value2],[year3,month3,day3,value3]...]. Each value is an integer number. I would like to build an Highcharts Histogram chart: in the xAxis there are the YEARS, in the yAxis the MONTHS. Now, in the columns i would like to have the sum of the VALUES for that year (example: column 2009 with the sum of all values that have 2009 as year). In the markers, i would like to have them
distributed according to the month of that year (example: in column 2009, markers with month 1 at the left, and with month 12 at the right of that column, and also for other columns).
Is it possible to do with this type of chart? Thanks a lot.
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/histogram-bellcurve.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
var data = [[2014,1,10,3],[2014,2,3,9],[2013,12,4,7],[2012,3,6,7],[2009,8,5,9],[2010,11,31,5],[2016,1,1,3],[2011,12,13,9],[2016,2,14,7],[2017,5,29,6],[2008,8,15,4],[2013,11,31,5]];
Highcharts.setOptions({
colors: ['green', 'blue', 'yellow', 'orange', 'red', 'violet', 'pink', 'brown', 'black']
});
$(function () {
Highcharts.chart('prova',{
title: {
text: 'Distribuzione articoli'
},
xAxis: [{
title: { text: 'Anno' },
min: 2009,
max: 2017,
type: 'category'
}, {
title: { text: 'Mese' },
opposite: true,
}],
yAxis: [{
title: { text: 'Giorno' },
min: 0,
max: 12,
labels: {
step: 1,
}
}, {
title: { text: 'Sequenza temporale' },
opposite: true,
}],
series: [{
name: 'Sequenza temporale',
type: 'histogram',
xAxis: 1,
yAxis: 1,
baseSeries: 's1',
zIndex: -1
}, {
name: 'Articoli',
type: 'scatter',
data: data,
id: 's1',
marker: {
radius: 1.5
}
}]
})
})
})
</script>
<div id="prova" height="400px" width="800px"></div>
Related
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>
Noticed that dataZoom in echarts only display series for the first category rather than a total across all categories.
For example, consider a cluster bar chart that contains 3 categories (2015,2016,2017). DataZoom displays trend for the 2015 by default rather than total across 2015,2016 and 2017. Any recommendations on how to improve the display as it might be misleading to the end user?
option = {
legend: {},
tooltip: {},
dataset: {
source: [
['product', '2015', '2016', '2017'],
['Matcha Latte', 43.3, 185.8, 93.7],
['Milk Tea', 83.1, 73.4, 55.1],
['Cheese Cocoa', 86.4, 65.2, 82.5],
['Walnut Brownie', 72.4, 53.9, 39.1]
]
},
xAxis: {type: 'category'},
yAxis: {},
// Declare several bar series, each will be mapped
// to a column of dataset.source by default.
dataZoom: [
{
show: true,
type: 'slider',
start: 0,
end: 100,
filterMode: 'filter'
},
{
type: 'inside',
start: 0,
end: 100
},
{
show: false,
yAxisIndex: 0,
filterMode: 'empty',
width: 30,
height: '80%',
showDataShadow: false,
left: '93%'
}
],
series: [
{type: 'bar'},
{type: 'bar'},
{type: 'bar'}
]
};
Thanks,
Dee
Could you explain «DataZoom displays trend for the 2015 by default»? I tried to find the troubles and just pasted you code to editor. It's look as was expected — DataZoom show all clusters, what's wrong?
var myChart = echarts.init(document.getElementById('main'));
var option = {
legend: {},
tooltip: {},
dataset: {
source: [
['product', '2015', '2016', '2017'],
['Matcha Latte', 43.3, 185.8, 93.7],
['Milk Tea', 83.1, 73.4, 55.1],
['Cheese Cocoa', 86.4, 65.2, 82.5],
['Walnut Brownie', 72.4, 53.9, 39.1]
]
},
xAxis: {type: 'category'},
yAxis: {},
// Declare several bar series, each will be mapped
// to a column of dataset.source by default.
dataZoom: [
{
show: true,
type: 'slider',
start: 0,
end: 100,
filterMode: 'filter'
},
{
type: 'inside',
start: 0,
end: 100
},
{
show: false,
yAxisIndex: 0,
filterMode: 'empty',
width: 30,
height: '80%',
showDataShadow: false,
left: '93%'
}
],
series: [
{type: 'bar'},
{type: 'bar'},
{type: 'bar'}
]
};
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>
I'm creating a stacked bar graph and need to show the label inside the stack. But Few of the label's are getting overlapped. for reference image
Can you please help me how to avoid overlapping using google charts ?
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<script type="text/javascript">
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawStacked);
function drawStacked() {
var data = new google.visualization.arrayToDataTable([['Time Period','XYZ',{ role: 'annotation'},'ABC',{ role: 'annotation'},{ role: 'annotation'},'Average'],
['Aug', 3754,'3754', 2089,'2089','5,843',4000],
['Sept', 900,'900', 200,'200', '100',4000],
['Oct', 2000,'2000', 4900,'4900', '6000',4000],
['Nov', 1700,'1700', 2200,'2200', '3900',4000],
['Dec', 2400,'2400', 2089,'2200', '4600',4000]
]);
var options = {
title: 'Overview of the Tickets',
isStacked: true,
orientation: 'horizontal',
hAxis: {
title: 'Time Period',
annotations: {}
},
vAxis: {
title: 'Number of Tickets'
},
seriesType: 'bars',
series: {2: {type: 'line'}}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
</html>
Regards,
Srikanth
first, it appears you have an extra annotation column in your data,
that doesn't appear to belong to a specific column
copied from question above...
var data = new google.visualization.arrayToDataTable([
[
'Time Period',
'XYZ',
{role: 'annotation'},
'ABC',
{role: 'annotation'},
{role: 'annotation'}, // <-- extra annotation?
'Average'
],
[
'Aug',
3754,
'3754',
2089,
'2089',
'5,843', // <-- extra annotation?
4000
],
...
]);
this could be part of the reason it's so cluttered
regardless, use the annotations configuration option for adjustments
the config option can be used for the entire chart, or just for a specific series
var options = {
// entire chart
annotations: {
textStyle: {
fontSize: 10
}
},
series: {
0: {
// series 0
annotations: {
stem: {
length: 0
},
},
},
1: {
// series 1
annotations: {
stem: {
length: 16
}
},
},
}
...
};
specifically, you can use a combination of annotations.textStyle.fontSize and annotations.stem.length to prevent overlapping
see following working snippet...
annotations.textStyle.fontSize is reduced for the entire chart
this allows the first annotation on the second column to fit within the bar
annotations.stem.length is set to zero (0) on the first series,
and 16 on the second...
(the extra annotation from the question has been removed)
google.charts.load('current', {
callback: drawStacked,
packages: ['corechart']
});
function drawStacked() {
var data = new google.visualization.arrayToDataTable([
['Time Period', 'XYZ', {role: 'annotation'}, 'ABC', {role: 'annotation'}, 'Average'],
['Aug', 3754, '3754', 2089, '2089', 4000],
['Sept', 900, '900', 200, '200', 4000],
['Oct', 2000, '2000', 4900, '4900', 4000],
['Nov', 1700, '1700', 2200, '2200', 4000],
['Dec', 2400, '2400', 2089, '2200', 4000]
]);
var options = {
annotations: {
textStyle: {
fontSize: 10
}
},
series: {
0: {
annotations: {
stem: {
length: 0
},
},
},
1: {
annotations: {
stem: {
length: 16
}
},
},
2: {
type: 'line'
}
},
hAxis: {
title: 'Time Period'
},
isStacked: true,
seriesType: 'bars',
title: 'Overview of the Tickets',
vAxis: {
title: 'Number of Tickets'
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
since the third annotation is needed as the total of the other two stacks,
recommend adding the series value for the total, in addition to the annotation column
and setting the total series type to 'line'
this will place the total annotation above the rest, for sure
so long as there is enough room on the chart to display the annotation above the bars
to ensure enough room above bars, find the max vAxis value, and add a value that will create enough room for the annotation
then set that value as vAxis.viewWindow.max
you can turn off the line and point, and hide the total series from the legend if needed
in my experience, it takes quite a bit of manipulation to get a complex google chart to display nicely
see the following working snippet, which incorporates the third, 'total', annotation...
google.charts.load('current', {
callback: drawStacked,
packages: ['corechart']
});
function drawStacked() {
var data = new google.visualization.arrayToDataTable([
['Time Period', 'XYZ', {role: 'annotation'}, 'ABC', {role: 'annotation'}, 'TOTAL', {role: 'annotation'}, 'Average'],
['Aug', 3754, '3,754', 2089, '2,089', 5843, '5,843', 4000],
['Sept', 900, '900', 200, '200', 1100, '1,100', 4000],
['Oct', 2000, '2,000', 4900, '4,900', 6900, '6,900', 4000],
['Nov', 1700, '1,700', 2200, '2,200', 3900, '3,900', 4000],
['Dec', 2400, '2,400', 2089, '2,089', 4489, '4,489', 4000]
]);
// find max for all columns to set top vAxis number
var maxVaxis = 0;
for (var i = 1; i < data.getNumberOfColumns(); i++) {
if (data.getColumnType(i) === 'number') {
maxVaxis = Math.max(maxVaxis, data.getColumnRange(i).max);
}
}
var options = {
annotations: {
textStyle: {
fontSize: 10
}
},
series: {
0: {
annotations: {
stem: {
length: 0
},
}
},
1: {
annotations: {
stem: {
length: 2
}
}
},
2: {
annotations: {
stem: {
color: 'transparent',
length: 16
}
},
color: 'black',
lineWidth: 0,
pointShape: 'square',
pointSize: 0,
type: 'line',
visibleInLegend: false
},
3: {
type: 'line'
}
},
hAxis: {
title: 'Time Period'
},
isStacked: true,
seriesType: 'bars',
title: 'Overview of the Tickets',
vAxis: {
title: 'Number of Tickets',
viewWindow: {
max: maxVaxis + 2000
}
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I think it happens because there's not enough vertical space for the labels.
Try this:
Save the highest value of the graph (let's call it maxNumber)
In the "options" set vAxis maxValue to be maxNumber plus a little more.
I have 4 horizontal lines in my graph so I wrote:
var options = {
title: chartTitle,
....... //Your options
vAxis: {
//Add more space in order to make sure the annotations are not overlapping
maxValue: maxNumber + maxNumber/4,
},
I am using Highcharts, but my question is in general. I want to know which chart is a perfect match to show change in values between 2 dates.
E.g The lending rate e.g
29-Aug : 21.2
30-Aug : 21.3
The change is 0.1 million.
Which chart type should i choose to show this little difference clearly noticeable .?
If you're comparing two dates/values, I would recommend using a bar chart. (If you're comparing values over months or years, I would suggest using a line or area chart.) You can better emphasize the difference between the two lending rate values by specifying the minimum, maximum, and step scale values so that the 0.1 million difference can be clearly illustrated. See the below demo:
var myConfig = {
type: 'bar',
title: {
text: 'Lending Rate',
fontFamily: 'Georgia'
},
utc: true,
timezone: 0,
scaleX: {
transform: {
type: 'date',
all: '%M %d, %Y'
},
step: 86400000,
item: {
fontSize: 10
}
},
scaleY: {
values: '21.1:21.4:0.1',
format: '%vM',
decimals: 1,
item: {
fontSize: 10
},
guide: {
lineStyle: 'dotted'
}
},
plot: {
barWidth: '50%',
borderWidth: 1,
borderColor: 'gray',
backgroundColor: '#99ccff',
valueBox: {
text: '%v million',
fontSize: 12,
fontColor: 'gray',
fontWeight: 'normal'
},
tooltip: {
text: '%v million'
}
},
series: [
{
values: [
[1472428800000, 21.2],
[1472515200000, 21.3],
]
}
]
};
zingchart.render({
id : 'myChart',
data : myConfig,
height: 400,
width: 600
});
<script src= "https://cdn.zingchart.com/zingchart.min.js"></script>
<div id='myChart'></div>
For more on scale customization and formatting, see this X/Y-Axis Scales Tutorial. The value boxes and tooltips can also be used to provide further information about the node values.
Hope that helps. I'm a member of the ZingChart team, and happy to answer further questions.
A simple bar chart with data labels to indicate the respective values would be helpful to show users there is a very small change in value.
See the code snippet below. I modified one of the basic Highcharts demos for a bar chart with your example values.
I hope this is helpful for you!
$(function () {
$('#container').highcharts({
chart: { type: 'bar' },
title: { text: 'Sample Chart' },
xAxis: {
categories: ['29-Aug','30-Aug'],
title: { text: null }
},
yAxis: { min: 0 },
tooltip: { valueSuffix: ' million' },
plotOptions: {
bar: {
dataLabels: {
crop: false,
overflow: 'none',
enabled: true,
style: { fontSize: '18px' }
}
}
},
legend: { enabled: false },
credits: { enabled: false },
series: [{
name: 'Sample Series',
data: [21.2,21.3]
}]
});
});
<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/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 450px; height: 250px; margin: 0 auto"></div>
I'm using HighCharts to display charts on my site.
What I'd like to achieve is just a line chart with (zoomable) Date-Time X-Axis and numbers in Y-Axis.
But the result is messed up:
I load data by an ajax call, create an array and use chart.series[0].setData(chartData); to set the chart's data. Below is a sample for chartData:
[[1343071800000, 17], [1343158200000, 171], [1343244600000, 291], [1343075400000, 18],
[1343161800000, 74], [1343248200000, 293], [1343165400000, 183], [1343251800000, 296]]
Also, I use DotNetHighCharts since I'm using ASP.NET MVC 3, but the generated javascript to create the chart is as follows:
chart = new Highcharts.Chart({
chart: { renderTo:'chart_container' },
legend: { align: 'left', borderWidth: 0, floating: true, layout: 'horizontal', verticalAlign: 'top', y: 20 },
plotOptions: { series: { cursor: 'pointer', marker: { lineWidth: 1 }, point: { events: { click: function() { alert(Highcharts.dateFormat('%A, %b %e, %Y', this.x) +': '+ this.y +' visits'); } } } } },
subtitle: { text: 'Source: Google Analytics' },
title: { text: 'Daily visits at www.highcharts.com' },
tooltip: { crosshairs: true, shared: true },
xAxis: { gridLineWidth: 1, labels: { align: 'left', x: 3, y: -3 }, tickInterval: 604800000, tickWidth: 0, type: 'datetime' },
yAxis: [{ labels: { align: 'left', x: 3, y: 16, formatter: function() { return Highcharts.numberFormat(this.value, 0); } }, showFirstLabel: false, title: { text: '' } }, { gridLineWidth: 0, labels: { align: 'right', x: -3, y: 16, formatter: function() { return Highcharts.numberFormat(this.value, 0); } }, linkedTo: 0, opposite: true, showFirstLabel: false, title: { text: '' } }],
series: [{ name: 'All visits' }]
Your dataset is not in chronological order. So the charting system is joining all the points as best it can.
For time-based series it is always best to sort your time from earliest to latest.