Show time of day on Google annotated time line chart - google-visualization

I am trying to use the Google charts api to create line charts that have datetimes on the x axis and values on the other. Generally these will only be for a 48 hour period, so I really need to show the times of day on the x axis as well as the days.
Does anyone know how to achieve this please?
Alternatively can anyone suggest another Javascript chart api that would allow this please?

The AnnotatedTimeline charts are old and outdated; you can replicate 95% of the functionality using a LineChart with "annotation" and "annotationText" column roles and a ChartRangeFilter. The LineCharts support using datetimes.

I'm using morris.js on a temperature time series.
Would like to see other suggestions.

#asgallant is right. A sample of what it would look like can but seen in Google Code Playground and pasting this script:
function drawVisualization() {
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Time');
data.addColumn('number', 'Count');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn({type: 'string', role: 'annotationText'});
data.addRows([
[new Date(2013, 0, 31, 19, 30), 1, 'A', 'Event 1'],
[new Date(2013, 1, 2, 20, 30), 2, 'B', 'No event'],
[new Date(2013, 1, 7, 18, 30), 2.5, 'C', 'No event'],
]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {curveType: "function",
width: 500, height: 400,
vAxis: {maxValue: 10}}
);
}

Related

Google Charts Filter/Control chart based on hidden value

I have a scattor plot with the following data:
[ 'HDD', 'Oil Consumption']
['100','1000']
['50','500']
['10,'100']
Say each data point is taken from a specific date:
[ 'HDD', 'Oil Consumption', 'Date']
['100','1000','1 January 2015']
['50','500', '1 February 2015']
['10,'100', '1 March 2015']
How can I add a filter (DateRangeFilter preferably) to filter based on the date column, even though the date column isn't really apart of the scatter plot.
You do this with ChartWrapper, ControlWrapper and a Dashboard.
Here is the documentation related to this from Google.
Basically, you instead of initiating a chart with new google.visualization.ScatterChart(document.getElementById('yourId')) you use something called ChartWrapper (which is, in my opinion, an easier and more readable way of doing this).
Then you create a ControlWrapper (a wrapper for your control (date range filter) element).
Lastly you bind your ControlWrapper to your ChartWrapper via your Dashboard.
Your data could be like:
var data = google.visualization.arrayToDataTable([
['Age', 'Weight', 'Date'],
[ 8, 12, new Date(2015, 10, 1)],
[ 4, 5.5, new Date(2015, 10, 2)],
[ 11, 14, new Date(2015, 10, 3)],
[ 4, 5, new Date(2015, 10, 4)],
[ 3, 3.5, new Date(2015, 10, 5)],
[ 6.5, 7, new Date(2015, 10, 6)]
]);
A ChartWrapper could look like this:
var scatterWrap = new google.visualization.ChartWrapper({
chartType:'ScatterChart',
containerId:'chart_div',
dataTable:data,
view:{
columns:[0, 1] // This makes sure your ScatterChart won't try to use the third column for visualization, that would result in an error.
}
});
and a ControlWrapper like this
var dateRangeWrap = new google.visualization.ControlWrapper({
controlType:'DateRangeFilter',
containerId:'dateRange',
options:{
filterColumnIndex:2
}
});
Finally initializing and binding to your Dashboard:
var googleDashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
googleDashboard.bind(dateRangeWrap, scatterWrap);
googleDashboard.draw(data);
This would all end in this Fiddle. (Note that you need to load controls instead of corechart in your google.load).

Scatter chart: distinct color for similar Y value

For example, let's take this configuration and data:
var data = new google.visualization.DataTable();
data.addColumn('number', 'Age');
data.addColumn('number', 'Weight');
data.addRows([
[ 8, 12, 'Female'],
[ 4, 5.5, 'Unknown'],
[ 11, 14, 'Female'],
[ 4, 5, 'Male'],
[ 3, 3.5, 'Female'],
[ 6.5, 7, 'Male']
]);
What options or column role should I use in order to:
have the 'Male', 'Female', and 'Unknown' dots in distinct colors?
display the three colors + strings in the legend?
I already managed to achieve [1] with some pre-processing and using "style", but I thought there would be a simpler solution for such a relatively trivial case. Could it be that I missed some point in the documentation?

Show all values in stacked area charts at given time

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.

Column stacked chart by groups

I have a column chart that shows power consumption in current and previous years. Now this consumption comes from different sources, so I would like to chart these values in multiple columns that show stacked values.
I am using google chart, but setting the isStacked parameter to true in the options array just stacks every single value for a specific row. What I want to do achieve is something like this:
That is, rows with multiple stacked columns. Is this even possible with Google Chart API?
This is doable with a kludge:
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['Country', 'Cars', 'Trucks'],
['', null, null],
['US', 15, 15],
['Canada', 17, 17],
['Europe', 13, 13],
['Mexico', 16, 16],
['Asia', 20, 20],
['', null, null],
['US', 15, 15],
['Canada', 17, 17],
['Europe', 13, 13],
['Mexico', 16, 16],
['Asia', 20, 20],
['', null, null],
['US', 15, 15],
['Canada', 17, 17],
['Europe', 13, 13],
['Mexico', 16, 16],
['Asia', 20, 20],
['', null, null],
['US', 15, 15],
['Canada', 17, 17],
['Europe', 13, 13],
['Mexico', 16, 16],
['Asia', 20, 20],
['', null, null],
]);
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data,
{isStacked:true, width:800, hAxis: {showTextEvery:1, slantedText:true}}
);
}
This is probably not a great way of doing this. Basically, you are trying to make a single chart show too much information and would be far better off splitting up your data in to multiple charts. For instance, you can use domain roles, or you can just use a line chart to be able to compare the difference between trucks and cars (which you can't currently do because of the different baselines). You can also compare different countries on just cars or trucks as a standard column chart (not stacked). You can use chart interaction to allow users to pick what data they want to see. It looks like you are trying to recreate an existing Excel chart which isn't interactive with an interactive technology, so the best thing is likely to rethink how it should be used given the ability to interact due to the shift in technology.

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?