Show all values in stacked area charts at given time - google-visualization
Amazon did a great job with the monitoring in OpsWorks (see screenshot). You can point at any time in any of the area charts and see all values for all charts at that time.
Is it possible to achieve something similar with the Google Visualisation API?
I also have multiple (stacked) area charts and it's a pain to point at each datapoint to get the exact value. Some of them are overlapping or very close together.
You can't trigger the tooltips in all of the charts at the same time, but if you disable the built-in tooltips, you can achieve something similar by building out your tooltips in HTML and populating them manually in a "onmouseover" event handler:
function mouseOverHandler (e) {
// use e.row, e.column to find data and populate your tooltips
}
function mouseOutHandler (e) {
// clear the tooltips
}
google.visualization.events.addListener(chart1, 'onmouseover', mouseOverHandler);
google.visualization.events.addListener(chart1, 'onmouseout', mouseOutHandler);
google.visualization.events.addListener(chart2, 'onmouseover', mouseOverHandler);
google.visualization.events.addListener(chart2, 'onmouseout', mouseOutHandler);
// etc...
In your stacked area chart (assuming you do not replace the tooltips with a custom solution), you can set the focusTarget option to 'category' to make all values at a given x-axis value show up in the tooltip (works only within one chart, not across charts).
You can also cheat by putting all three charts in the same chart element with a little trickery (and some limitations). For instance, you can make the chart like this:
Here is the code for that (dummy data):
function drawVisualization() {
// Some raw data (not necessarily accurate)
var data = new google.visualization.DataTable();
data.addColumn('number', 'time');
data.addColumn('number', 'used');
data.addColumn('number', 'cached');
data.addColumn('number', 'free');
data.addColumn('number', 'user');
data.addColumn('number', 'system');
data.addColumn('number', 'io wait');
data.addColumn('number', '1 min');
data.addColumn('number', '5 min');
data.addColumn('number', '15 min');
data.addRows([
[1, {v:0.1, f:'10%'},{v:0.55, f:'45%'},{v:1, f:'45%'},{v:1.01, f:'0.15 GiB'},{v:1.83, f:'12.45 GiB'},{v:1.18, f:'2.7 GiB'},{v:2.28166561658701, f:'28.2%'},{v:2.38024858239246, f:'38.0%'},{v:2.42249842488051, f:'42.2%'}],
[2, {v:0.2, f:'20%'},{v:0.6, f:'40%'},{v:1, f:'40%'},{v:1.54, f:'8.1 GiB'},{v:1.47, f:'7.05 GiB'},{v:1.77, f:'11.55 GiB'},{v:2.53503269167234, f:'53.5%'},{v:2.74904576834128, f:'74.9%'},{v:2.4119751725877, f:'41.2%'}],
[3, {v:0.3, f:'30%'},{v:0.65, f:'35%'},{v:1, f:'35%'},{v:1.13, f:'1.95 GiB'},{v:1.15, f:'2.25 GiB'},{v:1.75, f:'11.25 GiB'},{v:2.73464579773048, f:'73.5%'},{v:2.85218912536736, f:'85.2%'},{v:2.80811037750353, f:'80.8%'}],
[4, {v:0.4, f:'40%'},{v:0.7, f:'30%'},{v:1, f:'30%'},{v:1.27, f:'4.05 GiB'},{v:1.86, f:'12.9 GiB'},{v:1.1, f:'1.5 GiB'},{v:2.86045009159487, f:'86.0%'},{v:2.92068159800651, f:'92.1%'},{v:2.54208355770477, f:'54.2%'}],
[5, {v:0.5, f:'50%'},{v:0.75, f:'25%'},{v:1, f:'25%'},{v:1.23, f:'3.45 GiB'},{v:1.12, f:'1.8 GiB'},{v:1.88, f:'13.2 GiB'},{v:2.89980619585711, f:'90.0%'},{v:2.8728120099814, f:'87.3%'},{v:2.75583720451997, f:'75.6%'}],
[6, {v:0.6, f:'60%'},{v:0.8, f:'20%'},{v:1, f:'20%'},{v:1.5, f:'7.5 GiB'},{v:1.78, f:'11.7 GiB'},{v:1.26, f:'3.9 GiB'},{v:2.84876005903125, f:'84.9%'},{v:2.66203284604438, f:'66.2%'},{v:2.63657004427344, f:'63.7%'}],
[7, {v:0.7, f:'70%'},{v:0.85, f:'15%'},{v:1, f:'15%'},{v:1.91, f:'13.65 GiB'},{v:1.26, f:'3.9 GiB'},{v:1.69, f:'10.35 GiB'},{v:2.71244021344925, f:'71.2%'},{v:2.78368423479417, f:'78.4%'},{v:2.69819140918026, f:'69.8%'}],
[8, {v:0.8, f:'80%'},{v:0.9, f:'10%'},{v:1, f:'10%'},{v:1.48, f:'7.2 GiB'},{v:1.51, f:'7.65 GiB'},{v:1.41, f:'6.15 GiB'},{v:2.50454251895529, f:'50.5%'},{v:2.59031474717769, f:'59.0%'},{v:2.33299806251049, f:'33.3%'}],
[9, {v:0.9, f:'90%'},{v:0.95, f:'5%'},{v:1, f:'5%'},{v:1.18, f:'2.7 GiB'},{v:1.53, f:'7.95 GiB'},{v:1.97, f:'14.55 GiB'},{v:2.24595415946281, f:'24.6%'},{v:2.24103507627355, f:'24.1%'},{v:2.22381828511115, f:'22.4%'}],
[10, {v:1, f:'100%'},{v:1, f:'0%'},{v:1, f:'0%'},{v:1.66, f:'9.9 GiB'},{v:1.61, f:'9.15 GiB'},{v:1.2, f:'3 GiB'},{v:2.1229770797314, f:'12.3%'},{v:2.13527478770454, f:'13.5%'},{v:2.14757249567768, f:'14.8%'}],
]);
// Create and draw the visualization.
var ac = new google.visualization.AreaChart(document.getElementById('visualization'));
ac.draw(data, {
title : 'Monthly Coffee Production by Country',
isStacked: false,
width: 600,
height: 400,
areaOpacity: 0.0,
focusTarget: 'category',
series: { 0: {areaOpacity: 0.5}, 1: {areaOpacity: 0.5}, 2: {areaOpacity: 0.5} },
vAxis: { ticks: [{v:0, f:""}, {v:0.5, f:"7.5 GiB"}, {v:1, f:"15.0 GiB"}, {v:1.5, f:"50%"}, {v:2, f:"100%"}, {v:2.5, f:"50%"}, {v:3, f:"100%"}, ] }
});
}
Basically, I put all 3 series on the same chart by putting them all as percentages of 1/3rd of the chart. So the first series is from 0-1, the second from 1-2, and the third from 2-3. I then used liberal quantities of {v:, f:} notation to make them look like different numbers (for the GiB particularly), and used the ticks option to make the axis look like it has 3 scales. Finally, I set focusTarget: 'category' so all lines get selected when you mouseover any of them.
You can format colors and even add dummy series to add thicker black lines between the series if you want to make them look more 'distinct'. You can also do some tricky stuff with dummy series and white areas and 100% opacity to potentially add background colors to higher areas. But the general concept is as outlined above, depending on what you are going for, it could work too.
Related
Set Fixed axis values
I had some code that set my V axis scale from 0 - 4. However I deleted it and now I cannot remember how I got it working again. See below for my chart code, and the code I think I used before. This is what I think I used before... vAxis: { viewWindowMode:'explicit', viewWindow: { max:100, min:99.8 } } Below is my chart // Create a line chart, passing some options var LineChart = new google.visualization.ChartWrapper({ 'chartType': 'LineChart', 'containerId': 'chart_div', 'options': { //'width': 300, 'height': 300, 'legend': 'top', 'backgroundColor': '#eeeeee', 'colors': [ '#8ea23f'], 'pointSize': 5, 'title': 'Selected Site and Species abundance over time' }, 'view':{'columns':[0,2]}, });
There you go: 'vAxis': {'title': 'Something Here', 'minValue': 0, 'maxValue': 4},
There are two approaches to take, depending on what you need. The first one (shown by Tom's answer) sets alternative min and max values for the data set sent to the chart, eg. the chart interprets the maximum data value is must accommodate as MAX(vAxis.maxValue, data set max value). If the data set goes outside the bounds of vAxis.minValue/maxValue, those options will essentially be ignored. Also, the chart's actual axis range is only based on the min/max values - the values displayed will include the min/max, but might go beyond the min/max in order to produce clean intervals between axis labels. If you need to explicitly limit the axis to a specific range, where your min and max values are the absolute limits you want displayed, then you use the vAxis.viewWindow.min/max options.
Google Chart Customization
I want following Google Chart (Column Chart) to show its first label on horizontal axis. Also I want each column to have same width; first and last column need a change. How is it possible? var chartDataRaw = [{ "month": "201211", "articles": 41467 }, { "month": "201212", "articles": 31820 }, { "month": "201301", "articles": 43817 }, { "month": "201302", "articles": 42773 }, { "month": "201303", "articles": 38695 }, { "month": "201304", "articles": 41257 }]; var dataTable = new google.visualization.DataTable(); dataTable.addColumn('date', 'Month'); dataTable.addColumn('number', 'Articles'); var i = 1; //chartDataRaw is array of objects, requested from server. looped through jquery each to fill dataTable $.each(chartDataRaw, function () { var year = this.month.substring(0, 4); var month = this.month.substring(4); var dataItem = [new Date(year, month), this.articles]; dataTable.addRow(dataItem); }); var options = { title: 'Company Coverage', hAxis: { title: 'Last Six Months', titleTextStyle: { color: 'red' }, format: 'MMM, yyyy', fontSize: '8px' }, vAxis: { textPosition: 'none' }, trendlines: { 0: { color: 'black', lineWidth: 3, opacity: 0.4 } }, legend: 'none' }; var monthYearFormatter = new google.visualization.DateFormat({ pattern: "MMM, yyyy" }); monthYearFormatter.format(dataTable, 0); //change date format to render on chart var chart = new google.visualization.ColumnChart(document.getElementById('chart_div')); chart.draw(dataTable, options); http://jsfiddle.net/YyYsN/2/ Edit: Added chart data
Executive Summary You are committing several mortal sins: You are not defining dates right You have no y axis values distorting your data You are using columns to describe a continuous series You are predicting based on only 6 data points You are not defining dates right Look at the value for January 2013. It says 31,820 articles. The issue is your data says there were 43,817 articles in January. What the heck is going on? Javascript Date Objects use month values from 0-11, not 1-12. That means when you convert the dates, you need to change your function. Old: var dataItem = [new Date(year, month), this.articles]; New: var dataItem = [new Date(year, month - 1), this.articles]; You have no y axis values distorting your data Compare the second bar to the third bar. What is the ratio between the two? It looks like the second bar is around .5 gridlines, and the third bar is around 3.5 gridlines. That is a 700% increase in articles! Only if you look at the data, it's actually going from 31,820 to 43,817, and increase of only 37%. Bar charts should always start from zero, otherwise you get incredibly distorted perspective of the data, especially when there are no labels to boot. Old: vAxis: { textPosition: 'none', }, New: vAxis: { textPosition: 'none', minValue: 0 }, You are using columns to describe a continuous series Columns show discrete items. If I want to poll how many kids in a class like dogs, cats, and iguanas, a column chart is great since it allows me to compare the popularity (height) across unrelated categories (horizontal). Columns are okay for showing sales per month (or articles per month), but by making them columns you are implying that the columns should be compared as individual items, not as a progressing series. If you want to show that these data items are connected (as implied by the trendline) it would make much more sense to show an area chart. (Ideally, the area chart would show articles over the last 30 days, and have daily data, rather than a monthly compilation since months are arbitrary cutoffs, and things like weekends and holidays probably have a significant impact on your data which further distorts what you're trying to show). Old var chart = new google.visualization.ColumnChart(document.getElementById('chart_div')); New var chart = new google.visualization.AreaChart(document.getElementById('chart_div')); You are predicting based on only 6 data point Six points does not a trend make. Your data's highest value is the second point, yet you are showing the trend increasing over time. Perhaps the trendline suggests an upward trend (since the later values are higher than the first value), but as soon as you move 1 month forward you will have a descending trendline (barring a massive increase in articles). This makes no rational sense. 5 months of data are the same. How can changing 1 month of a 6-month series change the direction of the trendline? Forecasting is iffy-enough as it is (see the Black Swan theory), but doing it on a minimal 6-month series likely isn't the best. This means the trendline should probably be removed altogether since it not only doesn't convey useful information, it potentially conveys incorrect information. Summary That said, if you just want your left and right columns not to be cut off, you can change the following code: Old hAxis: { title: 'Last Six Months', titleTextStyle: { color: 'red' }, format: 'MMM, yyyy', fontSize: '8px', }, New hAxis: { title: 'Last Six Months', titleTextStyle: { color: 'red' }, format: 'MMM, yyyy', fontSize: '8px', minValue: new Date(2012,9), maxValue: new Date(2013,4) },
fixed it myself by changing corechart visualization version to 1.1 google.load("visualization", "1.1", {packages:["corechart"]});
Google Charts - Line chart like in Google Adsense
does someone has a cool example of 2 vAxis line Chart like this from Google adnsese, where you can add and remove values to display in the chart? I have already done the 2 vAxis chart and display many values, but now I would like to add and remove some of them and rebuild the chart.
I haven't seen the AdSense Chart, but I will try to answer. To add or remove data points or lines from a chart you can manipulate the DataTable (or create a new one) and then call 'draw' again on the chart. here is an example with animation: var data = google.visualization.arrayToDataTable([ ['x','Domain', 'Line 1', 'Line 2'], ['A', 1, 1, 0.5], ['B', 2, 0.5, 1] ]); // Use transition animation var opts = {animation: { duration: 1000, easing: 'out' }} var chart = new google.visualization.LineChart(document.getElementById('visualization')); chart.draw(data, opts); // remove a data line (column) data.removeColumn(3); chart.draw(data, opts); // add a new data point (row) data.addRow(['C',4,1,0.5]); chart.draw(data, opts);
What I use the following data format with area chart in Google Chart tools?
I have been using Area Chart for one of my project. I want the area chart to show full grid lines, and come to find out that it will only show if you have number or date data on major axis. Well I want year on major axis. But putting year as number, display that with number format. Something like this... 2005 displays 2005.00 . I have found out by going through documentation that data can be passed in this format - {v:2005, f:'2005'}. But this is not working when I pass the value in this format using google.visualization.arrayToDataTable(). json data I was trying to pass on has format something like this - [["Years", "sales"],[{v:2005, f:'2005'}, 52450],[{v:2006, f:'2006'}, 63457]] But the chart is not coming up... :(
If you want to use the {v:2005,f:'2005'} trick, you can't use ArrayToDataTable, you need to define the DataTable somewhat differently. You can see a similar problem here: Not Working DataTable: var data = google.visualization.arrayToDataTable([ ['Category', 'Amount'], ['Food', {v:5595.819984, f:'5.595,82'}], ['Home', {v:1890.530002, f:'1.890,53'}], ['Mail', {v:8.380000, f:'8,38'}], ['Train', {v:564.899998, f:'564,90'}], ['Photo', {v:959.119995, f:'959,12'}], ['Lego', {v:428.760004, f:'428,76'}], Working DataTable: var data = google.visualization.DataTable(); data.addColumn('string', 'Category'); data.addColumn('number', 'Amount'); data.addRows([ ['Food', {v:5595.819984, f:'5.595,82'}], ['Home', {v:1890.530002, f:'1.890,53'}], ['Mail', {v:8.380000, f:'8,38'}], ['Train', {v:564.899998, f:'564,90'}], ['Photo', {v:959.119995, f:'959,12'}], ['Lego', {v:428.760004, f:'428,76'}], ]);
put labels on top of inside bar in google interactive bar chart
I have created a bar chart using google Column Chart, now I have only integer values in my datatable but google divide acis with float values, is there a way to force chart mark only integers? is there any way to show value labels on top or inside bar chart? I found some way for image chart, but I whould like to keep chart interactive
There is no direct solution to this as yet because annotations are not supported in column chart. But let me share a work around for this: You can create a combo chart with two series having same data (as that of your column chart) along with the annotation column. Set the type of the first series to bars and that of the other series to line. Finally, specify visibleInLegend, lineWidth, and pointSize properties of the second series to false and 0s respectively. var data = new google.visualization.DataTable(); data.addColumn({ type: 'string', label: 'Labels' }); data.addColumn({ type: 'number', label: 'Bar Series' }); data.addColumn({ type: 'number', label: 'Line Series' }); data.addColumn({ type: 'string', role: 'annotation' }); data.addRows([['Label1', 10, 10, '10'], ['Label1', 20, 20, '20'], ['Label1', 40, 40, '40'], ['Label1', 5, 5, '5'], ['Label1', 30, 30, '30'], ]); var barchart = new google.visualization.ComboChart(document.getElementById('bar_element')); var options = {series: [{ type: 'bars' }, { type: 'line', lineWidth: 0, visibleInLegend:false, pointSize: 0}]}; barchart.draw(data, options);
For your first problem you can use gridlines property, take a look at this post to see how you can use it. For the second question I don't really understand. When you go on a bar with your mouse, the popup with values isn't already displayed on the top of the bar?