How can I draw an additional horizontal grid line with a specific value in Google Bar chart (Not average value) - charts

How can I draw an additional horizontal grid line with a specific value in Google Bar chart. The line I want to draw is not the average. It is a specific value.
What I am getting
What I need
How can I do this?
EDIT
This my data model:
var data = google.visualization.arrayToDataTable([
["Month", "Points", { role: "style" }, "TARGET GOAL"],
["Apr-19", 17, "#c4c4c4", 25],
["May-19", 32, "#c4c4c4", 25],
["Jun-19", 20, "#c4c4c4", 25],
["Jul-19", 22, "#c4c4c4", 25],
["Aug-19", 27, "#c4c4c4", 25],
["Sep-19", 26, "#c4c4c4", 25],
["Oct-19", 18, "#008600", 25],
["Nov-19", 18, "#008600", 25],
["Dec-19", 18, "#008600", 25],
]);
And in options object I have this:
seriesType: 'bars',
series:{
3: {
type: 'line'
}
}
Since 25 is the value I want to be rendered as a line and it is in the 4th position.
And finally
var chart = new google.visualization.ComboChart(document.getElementById("container_id"));
Am I missing something?
EDIT-2 Complete script:
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart_ebcg_unitary);
function drawChart_ebcg_unitary() {
var data = google.visualization.arrayToDataTable([
["Month", "Points", { role: "style" }, "TARGET GOAL"],
["Apr-19", 17, "#c4c4c4", 25],
["May-19", 32, "#c4c4c4", 25],
["Jun-19", 20, "#c4c4c4", 25],
["Jul-19", 22, "#c4c4c4", 25],
["Aug-19", 27, "#c4c4c4", 25],
["Sep-19", 26, "#c4c4c4", 25],
["Oct-19", 18, "#008600", 25],
["Nov-19", 18, "#008600", 25],
["Dec-19", 18, "#008600", 25],
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
},
2]);
var options = {
chartArea: {
left: 50,
width: "90%",
height: 250
},
title: "",
width: '100%',
height: 350,
bar: {groupWidth: "90%"},
legend: {position: "none"},
seriesType: 'bars',
series:{
1: {
type: 'line'
}
},
vAxis: {
minValue: 0,
title: 'SALES UNITS'
},
hAxis: {
title: 'MONTH'
},
annotations: {
textStyle: {
fontName: 'Arial, sans-serif',
color: '#000000',
fontSize: 12,
bold: true
},
alwaysOutside: true
}
};
var chart = new google.visualization.ComboChart(document.getElementById("ecbg_unitary"));
chart.draw(view, options);
}
jQuery(window).resize(function () {
drawChart_ebcg_unitary();
});
EDIT 3: Average line
How can I make the average line (please see screenshot) value (25) to appear only once, i.e at the end of the line rather than showing it on every month's column. This needs to look similar as in the screenshot under (What I need) section. Please advise.

use a ComboChart, which allows you to draw series of different types.
in the options, set the main seriesType.
then use the series option, to change the type of a specific series...
{
seriesType: 'bars',
series: {
1: {
type: 'line'
}
}
}
see following working snippet...
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart_ebcg_unitary);
function drawChart_ebcg_unitary() {
var data = google.visualization.arrayToDataTable([
["Month", "Points", { role: "style" }, "TARGET GOAL"],
["Apr-19", 17, "#c4c4c4", 25],
["May-19", 32, "#c4c4c4", 25],
["Jun-19", 20, "#c4c4c4", 25],
["Jul-19", 22, "#c4c4c4", 25],
["Aug-19", 27, "#c4c4c4", 25],
["Sep-19", 26, "#c4c4c4", 25],
["Oct-19", 18, "#008600", 25],
["Nov-19", 18, "#008600", 25],
["Dec-19", 18, "#008600", 25],
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
},
2, 3]);
var options = {
chartArea: {
left: 50,
width: "90%",
height: 250
},
title: "",
width: '100%',
height: 350,
bar: {groupWidth: "90%"},
legend: {position: "none"},
seriesType: 'bars',
series:{
1: {
type: 'line'
}
},
vAxis: {
minValue: 0,
title: 'SALES UNITS'
},
hAxis: {
title: 'MONTH'
},
annotations: {
textStyle: {
fontName: 'Arial, sans-serif',
color: '#000000',
fontSize: 12,
bold: true
},
alwaysOutside: true
}
};
var chart = new google.visualization.ComboChart(document.getElementById("ecbg_unitary"));
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="ecbg_unitary"></div>
EDIT
to display the annotation for the average only once,
use your own calculation for the annotation,
and only return a value if the row index equals the last row...
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
},
2, 3, {
calc: function(dt, row) {
var annotation = null;
if (row === (dt.getNumberOfRows() - 1)) {
annotation = dt.getFormattedValue(row, 3);
}
return annotation;
},
type: 'string',
role: 'annotation'
}
]);

Related

ECharts - Getting a single splitLine to render in a stacked bar chart

Trying to get a single split line to render on a stacked bar graph.
Here's the code:
options = {
tooltip: {
trigger: 'item',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['Graph 1', 'Graph 2']
},
grid: {
left: '7%',
right: '5%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: [40, 41, 42, 43, 44],
axisLabel: {
interval: 1
},
splitLine: {
show: true,
interval: function (param) {
//return param === 1; //what I'm trying to get it to do
return param > 0 && param < 2; //this doesn't work
//return param > 0; //this works, but adds a split line to everything above 1 as well, not what I want. vice versa (param < 2) also works, but again not what I want
},
lineStyle: {
type: 'dashed',
width: 2,
color: '#767676'
}
}
}
],
yAxis: [
{
type: 'value',
name: 'Y',
nameLocation: 'middle',
nameTextStyle: {
padding: [0, 0, 8, 0],
color: '#767676',
fontSize: 14
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false
}
}
],
series: [
{
name: 'Graph 1',
type: 'bar',
barWidth: 20,
stack: 'Graph',
itemStyle: {
color: '#db0011'
},
data: [8000, 10000, 12000, 16000, 20000]
},
{
name: 'Graph 2',
type: 'bar',
barWidth: 20,
barGap: '-100%',
stack: 'Graph',
itemStyle: {
color: '#00a69d'
},
data: [4000, 5000, 6000, 8000, 10000]
}
]
};
As per the above code,
param > 0 works but will add a split line to everything beyond 1 (1 and 2)
likewise, param < 2 will add a split line to everything before 2 (0 and 1)
param > 0 and param < 2 doesn't work (no split line appears)
setting a fixed number causes a split line to appear at the end of the graph as well, despite not being in the right interval (e.g. if my items went from 40 - 80 and I set an interval of 7, then the split line would appear before 47, 54, 61, 68, 75 and on 40 and 80)
How do I get a single split line to appear?
I've also seen Echarts how do you add dashed vertical line in between specific bars on bar chart?, however I don't have enough knowledge on how to modify this to work with a stacked bar chart.
How I want it to look like:
The way I ended up resolving this is:
var option = {
tooltip: {
trigger: 'item',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['Graph 1', 'Graph 2']
},
grid: {
left: '7%',
right: '5%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: [40, '', 41, '', 42, '', 43, '', 44],
axisLabel: {
interval: 1
},
splitLine: {
show: false
}
}
],
yAxis: [
{
type: 'value',
name: 'Y',
nameLocation: 'middle',
nameTextStyle: {
padding: [0, 0, 8, 0],
color: '#767676',
fontSize: 14
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false
}
}
],
series: [
{
name: 'Graph 1',
type: 'bar',
barWidth: 20,
stack: 'Graph',
data: [8000, 0, 10000, 0, 12000, 0, 16000, 0, 20000],
markLine: {
silent: true,
symbol: 'none',
label: {
show: false
},
data: [
{
name: "Test",
xAxis: 2.5,
lineStyle: {
color: '#767676',
width: 2,
type: 'dashed'
}
},
]
}
},
{
name: 'Graph 2',
type: 'bar',
barWidth: 20,
barGap: '-100%',
stack: 'Graph',
data: [4000, 0, 5000, 0, 6000, 0, 8000, 0, 10000]
}
]
};
A few things to note:
Add a bunch of empty string entries for your labels (x-axis). As can be seen above, data is [40, '', 41, '', 42, '', 43, '', 44] instead of [40, 41, 42, 43, 44].
Add zeroes in your graph series relative to where you inserted empty string labels in your x-axis data above (e.g. 4000, 0, 5000, 0, 6000, 0, 8000, 0, 10000). Do this for each graph you have.
In any of the graphs, insert the above markLine syntax I added to Graph 1. You will need to adjust the value of xAxis until you get the middle point.
Demo: https://jsfiddle.net/k9hgj5zb/1/
Credits to this link: Draw horizontal target line using EChart.JS

How to put vertical lines on google chart scatter

How I can make vertical lines on a scatter google chart?
I need to put the red line vertically:
here is my current code:
//making array with data
var dataArray = [];
dataArray.push(["", "", { role: 'annotation' }, "", ""]);
projects.forEach(function(item, index){
dataArray.push([parseFloat(item["bottomData"]), parseFloat((item["leftData"])), index+1, 10, 15]);
});
var data = google.visualization.arrayToDataTable(dataArray);
//define ticks
var rangeX = data.getColumnRange(0);
var ticksX = [];
for (var i = (Math.floor(rangeX.min / 5) * 5); i <= (Math.ceil(rangeX.max / 5) * 5); i = i + 5) {
ticksX.push(i);
}
var rangeY = data.getColumnRange(1);
var ticksY = [];
for (var i =(Math.floor(rangeY.min/5) * 5); i <= Math.ceil(rangeY.max/5) * 5; i=i+5) {
ticksY.push(i);
}
//define options
var options = {
series: {
1: {
lineWidth: 2,
pointSize: 0,
color: 'green'
},
2: {
lineWidth: 2,
pointSize: 0,
color: 'red'
},
},
colors:['002060'],
vAxis: {
ticks: ticksY,
},
hAxis: {
ticks: ticksX,
},
};
//print chart
var chart = new google.visualization.ScatterChart(document.getElementById("chartDiv"));
chart.draw(data, options);
I also tried using multiple axes putting some with direction=-1 or orientation=vertical but it doesn't work
in order to mix line series with scatter,
you will need to use a ComboChart
and to get vertical lines,
you will need to add multiple rows with the same x axis value,
with values for the min and max y axis values.
in the options, set the seriesType to 'scatter'
and change the series type to 'line'
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'y0', {role: 'annotation', type: 'number'}],
[26, 1, 1],
[33, 5, 2],
[36, 1, 3],
[38, 6, 4],
[58, 1, 5]
]);
var ticksX = [25, 30, 35, 40, 45, 50, 55, 60];
var ticksY = [0, 5, 10, 15, 20, 25];
data.addColumn('number', 'y1');
data.addColumn('number', 'y2');
//red line (vertical)
ticksY.forEach(function (value) {
data.addRow([40, null, null, null, value]);
});
//green line (horizontal)
ticksX.forEach(function (value) {
data.addRow([value, null, null, 10, null]);
});
data.sort([{column: 0}]);
var options = {
interpolateNulls: true,
seriesType: 'scatter',
series: {
1: {
color: 'green',
type: 'line'
},
2: {
color: 'red',
type: 'line'
},
},
colors:['002060'],
vAxis: {
ticks: ticksY
},
hAxis: {
ticks: ticksX
},
};
var chart = new google.visualization.ComboChart(document.getElementById("chartDiv"));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chartDiv"></div>

Highchart - xAxis weekly date can start given day?

I have a very basic 'line' weekly date graphic. I just need the date on x-axis to start the on given day of my first point. I have specified pointStart: Date.UTC(2018, 09, 25) but it showing different week in a different month? How can I display week from given date in x-axis?
$('#container').highcharts({
chart: {
type: 'line'
},
credits : {
enabled : false
},
title: {
text: false
},
xAxis: {
tickInterval: 7 * 24 * 3600 * 1000,
type: 'datetime',
startOnTick: true,
startOfWeek: 0,
labels: {
format: '{value:%d/%m/%Y}',
rotation: -45,
y: 30,
align: 'center'
}
},
yAxis: {
min: 0,
title: {
text: 'HH'
}
},
plotOptions: {
series: {
pointStart: Date.UTC(2018, 09, 25),
pointInterval: 7 * 24 * 3600 * 1000
}
},
series: [
{
name: 'Curva Tardía',
data: [18, 27, 36, 36, 10]
}, {
name: 'Curva Temprana',
data: [9, 18, 27, 27, 90]
},{
name: 'Curva Real',
data: [0, 36, 45, 89, 100]
}
]
});
Easy to make mistake, in Date.UTC, month is a 0 based index, which means initializing the function with 09 means it is setting month to October and not September.
By setting Date.UTC(2018, 08, 25) you will get the date you expect to be there:
$('#container').highcharts({
chart: {
type: 'line'
},
credits : {
enabled : false
},
title: {
text: false
},
xAxis: {
tickInterval: 7 * 24 * 3600 * 1000,
type: 'datetime',
startOnTick: true,
startOfWeek: 0,
labels: {
format: '{value:%d/%m/%Y}',
rotation: -45,
y: 30,
align: 'center'
}
},
yAxis: {
min: 0,
title: {
text: 'HH'
}
},
plotOptions: {
series: {
pointStart: Date.UTC(2018, 08, 25),
pointInterval: 7 * 24 * 3600 * 1000
}
},
series: [
{
name: 'Curva Tardía',
data: [18, 27, 36, 36, 10]
}, {
name: 'Curva Temprana',
data: [9, 18, 27, 27, 90]
},{
name: 'Curva Real',
data: [0, 36, 45, 89, 100]
}
]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
You need to use startOfWeek option:
xAxis: {
startOfWeek: 4
}
Live demo: http://jsfiddle.net/BlackLabel/nL4vuz5f/
API: https://api.highcharts.com/highcharts/xAxis.startOfWeek

Hide column and its annotation value in Google column chart

I've got a column google chart where I have four bars for each month. In the view set, in order to put the values on the top of each bar, I added an annotation for each one as following:
view.setColumns([0, 1,
{
id:"col1",
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" }, 2,
{
id:"col1",
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3,
{
id:"col1",
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}, 4,
{
id:"col1",
calc: "stringify",
sourceColumn: 4,
type: "string",
role: "annotation"
}
]);
I also added four buttons, for each column, to hide them. When I use the function hideColumns, it receives an array of indexes to identify the columns I want to hide. However, when I click on the button to hide the column, its annotation value keeps displayed on the chart and goes to a neighbor column. How do I hide the column and the annotation at the same time avoiding this? I tried assigning an id to the object column (annotation) and use it in the hideColumns function, but the function only receives an array of indexes.
This is the piece of code to hide the column number 1:
var hideAtv = document.getElementById("hideAtividades");
hideAtv.onclick = function()
{
view.hideColumns([1]);
chart.draw(view, options);
}
Thanks in advance
the annotation column should always follow the series column in the data table...
so if you want to hide column 1, also hide column 2...
var hideAtv = document.getElementById("hideAtividades");
hideAtv.onclick = function()
{
view.hideColumns([1, 2]);
chart.draw(view, options);
}
EDIT
when using DataView.hideColumns, the column references are for the data table
so it must not handle hiding calculated columns, e.g. annotation columns here
as such, instead of using hideColumns, use setColumns as used initially,
just without the column to be hidden
you can get the column definitions back by using DataView.getViewColumns
then check if the column should be visible...
if (columnDef.hasOwnProperty('sourceColumn')) {
if (columnDef.sourceColumn !== 1) {
viewColumns.push(columnDef);
}
} else if (columnDef !== 1) {
viewColumns.push(columnDef);
}
view.setColumns(viewColumns);
see following working snippet, here the same function is used to hide columns,
based on the button's value attribute
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['x', 'y0', 'y1', 'y2', 'y3'],
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
]);
var view = new google.visualization.DataView(data);
var columns = [0, 1,
{
id:"col1",
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2,
{
id:"col1",
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3,
{
id:"col1",
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}, 4,
{
id:"col1",
calc: "stringify",
sourceColumn: 4,
type: "string",
role: "annotation"
}
];
view.setColumns(columns);
var options = {
chartArea: {
top: 12,
left: 32,
bottom: 60,
right: 8,
height: '100%',
width: '100%'
},
height: 496,
legend: {
position: 'bottom'
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view, options);
document.getElementById('hideSeries1').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries2').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries3').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries4').addEventListener('click', hideColumn, false);
document.getElementById('resetSeries').addEventListener('click', resetSeries, false);
function hideColumn(e) {
var hideColumn = parseInt(e.target.value);
var viewColumns = [];
view.getViewColumns().forEach(function (columnDef) {
if (columnDef.hasOwnProperty('sourceColumn')) {
if (columnDef.sourceColumn !== hideColumn) {
viewColumns.push(columnDef);
}
} else if (columnDef !== hideColumn) {
viewColumns.push(columnDef);
}
});
view.setColumns(viewColumns);
chart.draw(view, options);
}
function resetSeries(e) {
view.setColumns(columns);
chart.draw(view, options);
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<button id="hideSeries1" value="1">Hide Series 1</button>
<button id="hideSeries2" value="2">Hide Series 2</button>
<button id="hideSeries3" value="3">Hide Series 3</button>
<button id="hideSeries4" value="4">Hide Series 4</button>
<button id="resetSeries">Reset All Series</button>
note: the above snippet keeps previously hidden buttons hidden, by using...
view.getViewColumns().forEach
to allow only one column to be hidden at a time, use...
columns.forEach
see following snippet for the latter...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['x', 'y0', 'y1', 'y2', 'y3'],
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
]);
var view = new google.visualization.DataView(data);
var columns = [0, 1,
{
id:"col1",
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2,
{
id:"col1",
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3,
{
id:"col1",
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}, 4,
{
id:"col1",
calc: "stringify",
sourceColumn: 4,
type: "string",
role: "annotation"
}
];
view.setColumns(columns);
var options = {
chartArea: {
top: 12,
left: 32,
bottom: 60,
right: 8,
height: '100%',
width: '100%'
},
height: 496,
legend: {
position: 'bottom'
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view, options);
document.getElementById('hideSeries1').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries2').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries3').addEventListener('click', hideColumn, false);
document.getElementById('hideSeries4').addEventListener('click', hideColumn, false);
document.getElementById('resetSeries').addEventListener('click', resetSeries, false);
function hideColumn(e) {
var hideColumn = parseInt(e.target.value);
var viewColumns = [];
columns.forEach(function (columnDef) {
if (columnDef.hasOwnProperty('sourceColumn')) {
if (columnDef.sourceColumn !== hideColumn) {
viewColumns.push(columnDef);
}
} else if (columnDef !== hideColumn) {
viewColumns.push(columnDef);
}
});
view.setColumns(viewColumns);
chart.draw(view, options);
}
function resetSeries(e) {
view.setColumns(columns);
chart.draw(view, options);
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<button id="hideSeries1" value="1">Hide Series 1</button>
<button id="hideSeries2" value="2">Hide Series 2</button>
<button id="hideSeries3" value="3">Hide Series 3</button>
<button id="hideSeries4" value="4">Hide Series 4</button>
<button id="resetSeries">Reset All Series</button>

Visualization Combo Chart dual axis chart

im working on a report, where i need to populate a graph with dual axis, can someone help me out to find how can i impelment that, here is the sample chart that i need.
i im trying to use https://developers.google.com/chart/interactive/docs/gallery/combochart but looking this will not work for me.
Thanks.
This should get you started...
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
["Week Ending","Actual FT", "Recommended FTE", "Other Tickets", "Router Tickets"],
["7/1", 1800, 1900, 19, 22],
["7/8", 1800, 1900, 20, 23],
["7/15", 1800, 1900, 20, 23],
["7/22", 1800, 1900, 19, 22],
// ..
["9/29", 1800, 1900, 29, 30]
]);
var options2 = {
vAxes: [{
minValue: 1200,
maxValue: 2500
}, {
minValue: 17,
maxValue: 30
}],
curveType: 'function',
hAxis: {
title: "week ending"
},
series: {
0: {
type: "bars",
targetAxisIndex: 0,
color: "blue"
},
1: {
type: "bars",
targetAxisIndex: 0,
color: "green"
},
2: {
type: "line",
targetAxisIndex: 1,
color: "red"
},
3: {
type: "line",
targetAxisIndex: 1,
color: "cyan"
}
}
};
var chart = new google.visualization.LineChart(document.getElementById("chart"));
chart.draw(data, options2);
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart" style="width: 900px; height: 300px;"></div>