Related
Is it possible to create a chart like the one below using google charts?
I have no idea how to go about this, so I decided to try using candlesticks chart.
with this basic starter code:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(candleChart);
/*CANDEL CHART*/
function candleChart() {
var data = google.visualization.arrayToDataTable([
['Jan', 20, 28, 38, 45],
['Feb', 31, 38, 55, 66],
['Mar', 50, 55, 77, 80],
['Apr', 77, 77, 66, 50],
['May', 68, 66, 22, 15],
['jun', 68, 66, 22, 15],
['Jul', 68, 66, 22, 15],
['Aug', 68, 66, 22, 15],
['Sep', 68, 66, 22, 15],
['Oct', 68, 66, 22, 15],
['Nov', 68, 66, 22, 15],
['Dec', 68, 66, 22, 15]
// Treat first row as data as well.
], true);
var options = {
legend:'none'
};
var chart = new google.visualization.CandlestickChart(document.getElementById('candle_chart'));
chart.draw(data, options);
}
But this is not what I want, I don't know where to start and I couldn't find any documentation on how to make it like the chart in the image.
The vertical line needs 0 as the center like in the image with positive numbers increasing below it and positive numbers increasing above it.
The bottom blue bar would be total number of competitors that did not get accepted. The green bar being total of competitors that did get accepted.
the line will represent where the user placed in that number.
Please help I have no clue where to begin. Thank you in advance!
use a ComboChart with 3 series / y-axis columns.
for the first two series use stacked columns. the first being the negative values, the second positive.
isStacked: true,
seriesType: 'bars',
for the third, change the series type to line.
series: {
2: {
type: 'line'
}
},
data should look similar to following.
['x', 'y0', 'y1', 'y2'],
['Jan', -125, 100, -10],
['Feb', -100, 125, 5],
['Mar', -200, 415, 205],
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'y0', 'y1', 'y2'],
['Jan', -125, 100, -10],
['Feb', -100, 125, 5],
['Mar', -200, 415, 205],
['Apr', -375, 180, -190],
['May', -180, 240, 100],
['Jun', -160, 100, -205],
['Jul', -125, 80, -12],
['Aug', -175, 110, -25],
['Sep', -100, 220, 150],
['Oct', -110, 390, 240],
['05 Nov', -10, 25, 30],
])
var options = {
chartArea: {
height: '100%',
width: '100%',
top: 16,
right: 16,
bottom: 60,
left: 60
},
colors: ['#03a9f4', '#cddc39', '#616161'],
hAxis: {
title: 'FY 18'
},
height: '100%',
isStacked: true,
legend: {
position: 'none'
},
pointSize: 6,
series: {
2: {
type: 'line'
}
},
seriesType: 'bars',
vAxis: {
ticks: [
{v: -400, f: '400'},
{v: -200, f: '200'},
0,
200,
400
],
title: 'Amount'
},
width: '100%'
}
var chart = new google.visualization.ComboChart(document.getElementById('chart'))
chart.draw(data, options)
});
#chart {
height: 320px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
It's this:
var options = {vAxis: { ticks: [-80,-40,0,40,80] }}
Read through the documentation! Every page on the google charts site lists all the configuration options for that chart type: super useful stuff.
Working JS fiddle cribbed from a gcharts example here.
Hi all I am trying to plot stacked bar using canvasJS for following nested list:
pepidstat=[[[2016, 61, 'Feb'], [2011, 367, 'Feb'], [2013, 83, 'Feb'], [2014, 89, 'Feb'], [2015, 106, 'Feb']], [[2016, 43, 'Jan'], [2011, 128, 'Jan'], [2013, 150, 'Jan'], [2014, 74, 'Jan'], [2015, 121, 'Jan']]]
And my workable javascript is:
<script type="text/javascript">
window.onload = function () {
var chartbar = new CanvasJS.Chart("chartContainerBar",
{
title:{
text: "Yearly Growth of Total Peptides"
},
animationEnabled: true,
axisX: {
interval: 1,
labelFontSize: 10,
lineThickness: 0
},
data:pepiddata
});
chartbar.render();
chartbar={};
}
var pepidstatlist = {{ pepidstat|safe }};
var pepiddata = [];var pepiddataSeries = { type: "stackedBar",showInLegend: "true" };
var pepidname= [];
var pepiddataPoints = [];
for (pi = 0; pi < pepidstatlist.length;pi++) {
piname = pepidstatlist[pi][0][2];
for (pj = 0; pj < pepidstatlist[pi].length;pj++) {
pidx=pepidstatlist[pi][pj][0];
pidy=pepidstatlist[pi][pj][1];
pepiddataPoints.push({
x:pidx,
y: pidy,
label: pidx,
name:piname,
toolTipContent: "{name}-{label}:{y}",
});
}
pepiddataSeries.name = piname; // here I want pass each month name
}
pepiddataSeries.dataPoints = pepiddataPoints;
pepiddata.push(pepiddataSeries);
</script>
This script is working perfectly except I can't assign each month name in data series. Can you please suggest where do I need to modify my script?
Thanks
You are just creating a single dataSeries. Create two dataSeries and push it to data. And everything else just works fine.
pepidstat=[[[2011, 61, 'Feb'], [2012, 367, 'Feb'], [2013, 83, 'Feb'], [2014, 89, 'Feb'], [2015, 106, 'Feb']], [[2011, 43, 'Jan'], [2012, 128, 'Jan'], [2013, 150, 'Jan'], [2014, 74, 'Jan'], [2015, 121, 'Jan']]]
var pepidstatlist = pepidstat;
var pepiddata = [];
var pepidname= [];
for (pi = 0; pi < pepidstatlist.length;pi++) {
piname = pepidstatlist[pi][0][2]; //month
var pepiddataPoints = [];
for (pj = 0; pj < pepidstatlist[pi].length;pj++) {
pidx=pepidstatlist[pi][pj][0]; //Year
pidy=pepidstatlist[pi][pj][1]; //value
pepiddataPoints.push({
x:pidx,
y: pidy,
label: pidx,
name:piname,
toolTipContent: "{name}-{label}:{y}",
});
}
var pepiddataSeries = { type: "stackedBar", showInLegend: "true" };
pepiddataSeries.name = piname; // here I want pass each month name
pepiddataSeries.dataPoints = pepiddataPoints;
pepiddata.push(pepiddataSeries);
}
var chartbar = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Yearly Growth of Total Peptides"
},
animationEnabled: true,
axisX: {
interval: 1,
labelFontSize: 10,
lineThickness: 0
},
data: pepiddata,
});
chartbar.render();
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<br/><!-- Just so that JSFiddle's Result label doesn't overlap the Chart -->
<div id="chartContainer" style="height: 360px; width: 100%;"></div>
Tips: Sort your array based on year value inside your array.
I have situation where i have to combine bar and line chart I have the below data please check if have any solution of this:
$(document).ready(function () {
var s1 = [ 59, 175, 148, 213, 19, 213, 144, 64, 229, 89, 59, 363, 5, 71, 31];//bar chart
var s2 = [66, 220, 87, 59, 15, 227, 134, 46, 139, 30, 18, 71, 2, 17, 2];
//bar chart
var line1= [98.81, 98.90, 99.00, 99.17, 99.35, 99.36, 99.46, 99.56, 99.71, 99.82, 99.87, 99.89, 99.92, 99.95,99.98];//data for line chart
var line2 = [ 99.52, 99.52, 99.52, 99.52, 99.52,99.52,99.52,99.52, 99.52, 99.52, 99.52, 99.52, 99.52, 99.52];//data for line chart
var ticks = ['Rakhine', 'Ayeyarwady', 'Magway', 'Bago', 'Kayah', 'Sagaing', 'Shan', 'Kachin', 'Yangon', 'Mon', 'Kayin', 'Mandalay',
'Chin', 'Tanintharyi', 'Naypyitaw' ];
//now i need to combine bar and line with the same plot
plot2 = $.jqplot('chart2', [s1, s2], {
seriesDefaults: {
renderer: $.jqplot.BarRenderer,show: true,
pointLabels: { show: true }
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
}
}
});
});
Description:
Ive been doing some research on stackoverflow however I cant seem to pinpoint my problem. This code worked for a little bit but it stopped working almost as fast. I am trying to get 3 google charts to show up on one page. Is there something wrong with the code?
Here it is below
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {
'packages': ['line', 'corechart']
});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
var chart0 = document.getElementById('curve_chart0');
var data0 = new google.visualization.DataTable();
data0.addColumn('string', '');
data0.addColumn('number', 'Altitude');
data0.addColumn('number', 'Speed');
data0.addRows([
['05:22:57', 6519, 0],
['05:24:00', 6519, 0],
['05:24:57', 6519, 0],
['05:25:57', 6519, 0],
['05:26:57', 6519, 0],
['05:27:58', 6519, 0],
['05:28:57', 6519, 0],
['05:29:58', 6519, 0],
['05:30:58', 6519, 0],
['05:31:58', 6519, 11],
['05:32:58', 6519, 0],
['05:33:58', 6519, 11]
]);
var options0 = {
chart: {
},
legend: {
position: 'none'
},
series: {
// Gives each series an axis name that matches the Y-axis below.
0: {
axis: 'Altitude'
},
1: {
axis: 'Speed'
}
},
width: 400,
height: 150,
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Altitude: {
label: 'Altitude'
},
Speed: {
label: 'Speed'
}
}
}
};
chart0 = new google.charts.Line(document.getElementById('curve_chart0'));
chart0.draw(data0, options0);
var chart1 = document.getElementById('curve_chart1');
var data1 = new google.visualization.DataTable();
data1.addColumn('string', '');
data1.addColumn('number', 'Altitude');
data1.addColumn('number', 'Speed');
data1.addRows([
['05:39:58', 116, 0],
['05:40:58', 116, 0],
['05:41:58', 116, 0],
['05:42:58', 116, 0],
['05:43:58', 116, 0],
['05:44:59', 116, 1],
['05:45:59', 116, 0],
['05:46:59', 116, 0],
['05:47:59', 116, 0],
['05:48:59', 116, 33],
['05:49:59', 116, 19],
['05:50:59', 116, 21],
['05:51:59', 116, 7],
['05:52:59', 116, 85],
['05:53:59', 3019, 196]
]);
var options1 = {
chart: {
},
legend: {
position: 'none'
},
series: {
// Gives each series an axis name that matches the Y-axis below.
0: {
axis: 'Altitude'
},
1: {
axis: 'Speed'
}
},
width: 400,
height: 150,
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Altitude: {
label: 'Altitude'
},
Speed: {
label: 'Speed'
}
}
}
};
chart1 = new google.charts.Line(document.getElementById('curve_chart1'));
chart1.draw(data1, options1);
var chart2 = document.getElementById('curve_chart2');
var data2 = new google.visualization.DataTable();
data2.addColumn('string', '');
data2.addColumn('number', 'Altitude');
data2.addColumn('number', 'Speed');
data2.addRows([
['23:58:54', 30, 0],
['23:59:54', 30, 0],
['00:00:54', 30, 1],
['00:01:54', 30, 1],
['00:02:54', 30, 0],
['00:03:54', 30, 0],
['00:04:54', 30, 0],
['00:05:54', 30, 13],
['00:06:54', 30, 17],
['00:07:54', 30, 21],
['00:08:54', 30, 5],
['00:09:55', 316, 178],
['00:10:55', 3770, 209],
['00:11:55', 6308, 241]
]);
var options2 = {
chart: {
},
legend: {
position: 'none'
},
series: {
// Gives each series an axis name that matches the Y-axis below.
0: {
axis: 'Altitude'
},
1: {
axis: 'Speed'
}
},
width: 400,
height: 150,
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Altitude: {
label: 'Altitude'
},
Speed: {
label: 'Speed'
}
}
}
};
chart2 = new google.charts.Line(document.getElementById('curve_chart2'));
chart2.draw(data2, options2);
}
</script>
</head>
<body>
<!--Divs that will hold the charts-->
<div id="curve_chart0"></div>
<div id="curve_chart1"></div>
<div id="curve_chart2"></div>
</body>
</html>
The following displays as you want though it uses the classical charts.
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.0', {
'packages': ['line', 'corechart']
});
google.setOnLoadCallback(drawChart);
function graph(div,data)
{
var data0 = new google.visualization.DataTable();
data0.addColumn('string', '');
data0.addColumn('number', 'Altitude');
data0.addColumn('number', 'Speed');
data0.addRows(data);
var options = {
chart: {
},
legend: {
position: 'none'
},
series: {
// Gives each series an axis name that matches the Y-axis below.
0: {targetAxisIndex: 0},
1: {targetAxisIndex: 1}
},
width: 400,
height: 150,
vAxes: {
// Adds labels to each axis; they don't have to match the axis names.
0: {title: 'Altitude'},
1: {title: 'Speed'}
}
};
var chart0 = new google.visualization.LineChart(document.getElementById(div));
chart0.draw(data0, options);
}
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
graph('curve_chart0',[
['05:22:57', 6519, 0],
['05:24:00', 6519, 0],
['05:24:57', 6519, 0],
['05:25:57', 6519, 0],
['05:26:57', 6519, 0],
['05:27:58', 6519, 0],
['05:28:57', 6519, 0],
['05:29:58', 6519, 0],
['05:30:58', 6519, 0],
['05:31:58', 6519, 11],
['05:32:58', 6519, 0],
['05:33:58', 6519, 11]
]);
graph('curve_chart1',[
['05:39:58', 116, 0],
['05:40:58', 116, 0],
['05:41:58', 116, 0],
['05:42:58', 116, 0],
['05:43:58', 116, 0],
['05:44:59', 116, 1],
['05:45:59', 116, 0],
['05:46:59', 116, 0],
['05:47:59', 116, 0],
['05:48:59', 116, 33],
['05:49:59', 116, 19],
['05:50:59', 116, 21],
['05:51:59', 116, 7],
['05:52:59', 116, 85],
['05:53:59', 3019, 196]
]);
graph('curve_chart2',[
['23:58:54', 30, 0],
['23:59:54', 30, 0],
['00:00:54', 30, 1],
['00:01:54', 30, 1],
['00:02:54', 30, 0],
['00:03:54', 30, 0],
['00:04:54', 30, 0],
['00:05:54', 30, 13],
['00:06:54', 30, 17],
['00:07:54', 30, 21],
['00:08:54', 30, 5],
['00:09:55', 316, 178],
['00:10:55', 3770, 209],
['00:11:55', 6308, 241]
]);
}
</script>
</head>
<body>
<!--Divs that will hold the charts-->
<div id="curve_chart0"></div>
<div id="curve_chart1"></div>
<div id="curve_chart2"></div>
</body>
</html>
Try this it works:-
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.0', { packages: ['line'] });
google.setOnLoadCallback(drawCharts);
function drawPageViews(chartReady) {
var data = new google.visualization.DataTable();
var div2 = document.getElementById("div2");
var labels = ['m', 'n', 'o', 'p', 'q', 'r', 's'];
data.addColumn('string', 'Day');
data.addColumn('number', 'PageViews');
var rows = new Array();
for (var i = 0; i < labels.length; i++) {
rows.push([labels[i], getRandomInt(0, 100)]);
}
data.addRows(rows);
var options = {
chart: {
title: 'Page views'
},
width: 900,
height: 500
};
var chart = new google.charts.Line(document.getElementById('div2'));
if(typeof chartReady !== 'undefined') google.visualization.events.addOneTimeListener(chart, 'ready', chartReady);
chart.draw(data, options);
}
function drawEventViews(chartReady) {
var data = new google.visualization.DataTable();
var div1 = document.getElementById("div1");
var labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
data.addColumn('string', 'Day');
data.addColumn('number', 'EventViews');
var rows = new Array();
for (var i = 0; i < labels.length; i++) {
rows.push([labels[i], getRandomInt(0, 100)]);
}
data.addRows(rows);
var options = {
chart: {
title: 'Event views'
},
width: 500,
height: 500
};
var chart = new google.charts.Line(document.getElementById('div1'));
if(typeof chartReady !== 'undefined') google.visualization.events.addOneTimeListener(chart, 'ready', chartReady);
chart.draw(data, options);
}
function drawCharts() {
drawPageViews(function(){
drawEventViews();
});
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
</head>
<body>
<div id="div2"></div>
<div id="div1"></div>
</body>
</html>
Is there a way to add another line to the bar in the BoxPlot chart which will represent the Mean (Average)? This will look like the Median line which is automatically drawn for you in the below Fiddle
http://jsfiddle.net/tLucL6mq/3/
Fiddle code:
$('#container').highcharts({
chart: {
type: 'boxplot',
inverted: true
},
title: {
text: 'Sample Base Salary Range'
},
legend: {
enabled: false
},
xAxis: {
categories: ['4', '3', '2', '1', '0'],
title: {
text: 'Job Level'
}
},
yAxis: {
title: {
text: 'Base Salary'
}
},
plotOptions: {
boxplot: {
fillColor: '#F0F0E0',
lineWidth: 2,
medianColor: '#0C5DA5',
medianWidth: 3
}
},
series: [{
name: "Observation Data",
data: [
['0', 68, 75, 79, 82, 84, 89], //level 4 - category 0
['1', 53, 63, 68, 72, 75, 79], //level 3 - category 1
['2', 47, 52, 59, 64, 67, 68], //level 2 - category 2
['3', 35, 37, 39, 42, 46, 51], //level 1 - category 3
['4', 32, 33, 34, 38, 40, 45] //level 0 - category 4
],
tooltip: {
headerFormat: '<b>{point.series.name}</b><br/><em>Job Level: {point.x}</em><br/>',
pointFormat: '- Max: {point.high}<br/>' +
'- Q3: {point.q3}<br/>' +
'- Median: {point.median}<br/>' +
'- Q1: {point.q1}<br/>' +
'- Min: {point.low}<br/>'
}
}, {
name: "Outlier Data",
color: Highcharts.getOptions().colors[0],
type: 'scatter',
data: [ // x, y positions where 0 is the first category
[0, 74],
[1, 67],
[4, 40],
[4, 48]
],
marker: {
fillColor: 'yellow',
lineWidth: 2,
lineColor: '#0C5DA5'
},
tooltip: {
headerFormat: '<b>{point.series.name}</b><br/><em>Job Level: {point.x}</em><br/>',
pointFormat: 'Base Salary: {point.y}'
}
}]
});
I'm not seeing in the docs how to do this... Is this possible at all?
Also, in the example, when you hover any part of the boxplot, the tooltip pops up. Is there a way to show the tooltip when you hover the Median or one of the Quartiles so that it only shows that data point's info?
I'm thinking it would be similar to how the tooltip for the scatter series shows data for individual points.
Edit:
I finally got my head around the syntax to pass in point objects instead of the array of values for each data set. After getting that object syntax correct, I added a new property for mean and included that value in the tooltip.
http://jsfiddle.net/tLucL6mq/4/
series: [{
name: "Observation Data",
data: [
{x: '0', low: 68, q1: 75, median: 79, q3: 82, high: 84, mean: 77.6}, //level 4 - category 0
{x: '1', low: 53, q1: 63, median: 68, q3: 72, high: 75, mean: 66.2}, //level 3 - category 1
{x: '2', low: 47, q1: 52, median: 59, q3: 64, high: 67, mean: 57.8}, //level 2 - category 2
{x: '3', low: 35, q1: 37, median: 39, q3: 42, high: 46, mean: 39.8}, //level 1 - category 3
{x: '4', low: 32, q1: 33, median: 34, q3: 38, high: 40, mean: 35.4} //level 0 - category 4
],
tooltip: {
headerFormat: '<b>{point.series.name}</b><br/><em>Job Level: {point.x}</em><br/>',
pointFormat: '- Min: {point.low}<br/>' +
'- Q1: {point.q1}<br/>' +
'- Median: {point.median}<br/>' +
'- Q3: {point.q3}<br/>' +
'- Max: {point.high}<br/>' +
'- Mean: {point.mean}<br/>'
}
}
This is almost what I wanted, but ideally, I would like to see the mean line displayed on the box for each data set just like the median line is.
In general, it's not supported to add such line, but it's Highcharts, so you can extend default functions: http://jsfiddle.net/tLucL6mq/5/ ;)
Simple snippet:
(function (H) {
// when changing point format for boxplot, values will calculate automatically
H.seriesTypes.boxplot.prototype.pointArrayMap = ['low', 'q1', 'median', 'q3', 'high', 'mean'];
H.seriesTypes.boxplot.prototype.toYData = function (point) {
return [point.low, point.q1, point.median, point.q3, point.high, point.mean];
};
// draw lines after default drawPoints is called:
H.wrap(H.seriesTypes.boxplot.prototype, 'drawPoints', function (p) {
p.call(this);
var chart = this.chart,
r = chart.renderer,
xAxis = this.xAxis,
yAxis = this.yAxis,
x, y;
// for each point, draw line:
H.each(this.points, function (p, i) {
x = p.shapeArgs.x;
y = p.meanPlot;
if (p.meanPlotX) {
// update existing path:
p.meanPlotX.attr({
d: ['M', x, y, 'L', x + p.shapeArgs.width, y]
});
} else {
// create mean-line for the first time
p.meanPlotX = r.path(['M', x, y, 'L', x + p.shapeArgs.width, y]).attr({
stroke: 'black',
'stroke-width': 2
}).add(p.series.group);
}
});
});
})(Highcharts)
Extra:
It will work with your previous format [x, y1, y2, y3, y4, y5, y6] because of the first two methods (pointArrayMap and toYData), of course in case y6=mean: http://jsfiddle.net/tLucL6mq/7/