Column stacked chart by groups - google-visualization

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.

Related

Getting the ID of the Max record in an aggregate

Take these models:
class Rocket(Model):
...
class Flight(Model):
rocket = ForeignKey(Rocket)
start_time = DateTimeField(...)
If I want to get start times of the latest flight for every rocket, that is simple:
>>> Flight.objects.values('rocket').annotate(max_start_time=Max('start_time'))
<QuerySet [
{'rocket': 3, 'max_start_time': datetime.datetime(2019, 6, 13, 6, 58, 46, 299013, tzinfo=<UTC>)},
{'rocket': 4, 'max_start_time': datetime.datetime(2019, 6, 13, 6, 59, 12, 759964, tzinfo=<UTC>)},
...]>
But what if instead of max_start_time I wanted to select IDs of those same Flights?
In other words, I want to get the ID of the latest Flight for every rocket.
What database backend are you using? If your database backend has support for DISTINCT ON this is most easily accomplished by:
Flight.objects.order_by("rocket", "-start_time").distinct("rocket").values("id", "rocket")

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?

Control two google charts at once with one control filter - possible?

I am trying to add two types of charts into one dashboard and filter them by country, like so:
the initial values shown should be for Europe, done via
'state': {'selectedValues': ['Europe']}
Chart 1 is a pie chart and should show the split between two variables within Europe and each country for let's say 2012, like so:
['Country', 'Speciality', 'Amount'],
['Europe', 'XYZ', 20441],
['Europe', 'ABC', 5355],
['Austria', 'XYZ', 477],
['Austria', 'ABC', 153],
['BeNeLux', 'XYZ', 1512],
['BeNeLux', 'ABC', 298],
['France', 'XYZ', 3080],
['France', 'ABC', 792],
and so on
Chart 2 should refer to the same two variables, but adding quarters, i.e. Q1, Q2, Q3 and Q4. Ideally I would like to have this as a 100% stacked column chart. Columns being Q1 Q2 Q3 Q4.
Question is: How do I add both charts into the dashboard and have the control filter both charts if I select for example France?
Thanks
Binding the filter to two charts is easy, as the documentation says:
// One-to-many binding where 'ageSelector' drives two charts.
dashboard.bind(agePicker, [ageVsSalaryScatterPlot, ageBarChart]);
This will mean that if you select 'Europe' it will change the filter for both charts. From your question it seems you may be a bit unclear on how to actually set this up (since your data isn't formatted correctly).
You will need 5 things:
DataTable containing information for all charts (so if you want quarter information, it needs to be in the DataTable as well
Dashboard object to contain the charts and controls
ChartWrapper object for the pie chart.
ChartWrapper object for the stacked column chart
ControlWrapper object for the selector
DataTable
Currently you have your data with only 3 columns:
['Country', 'Speciality', 'Amount'],
['Europe', 'XYZ', 20441],
['Europe', 'ABC', 5355],
['Austria', 'XYZ', 477],
['Austria', 'ABC', 153],
['BeNeLux', 'XYZ', 1512],
['BeNeLux', 'ABC', 298],
['France', 'XYZ', 3080],
['France', 'ABC', 792],
Since you also want quarters, you need to add that information as well.
['Country', 'Speciality', 'Amount', 'Q1', 'Q2', 'Q3', 'Q4'],
['Europe', 'XYZ', 20441, 1, 2, 3, 4],
['Europe', 'ABC', 5355, 1, 2, 3, 4],
['Austria', 'XYZ', 477, 1, 2, 3, 4],
['Austria', 'ABC', 153, 1, 2, 3, 4],
['BeNeLux', 'XYZ', 1512, 1, 2, 3, 4],
['BeNeLux', 'ABC', 298, 1, 2, 3, 4],
['France', 'XYZ', 3080, 1, 2, 3, 4],
['France', 'ABC', 792, 1, 2, 3, 4],
Dashboard Object
A dashboard object points to a <div> element that contains the other <div> elements for the charts and controls. So in your case, something like:
Then you create the dashboard using code like this:
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
ChartWrappers
So you have two charts, and you need to create two separate wrappers. A wrapper basically gives all the details on what that chart will need to be created:
Where on the page it goes (the <div>)
Where it will take its data from
What type of chart / options it will use
The piechart only uses columns 0, 1, 2, so you set the 'view' property of the object to limit the data to those columns.
Do the same with the stackedcolumnchart, using columns 0, 1, 3, 4, 5, 6.
Both charts need to take data from the same DataTable though, otherwise filtering one chart won't affect the other (the filter will apply to the DataTable, so if you have two of them, you can only change one at a time).
ControlWrapper
Like the ChartWrapper, you need to create a ControlWrapper object that has all the details about the Control you use.
Once you have all your objects set up, you can draw the dashboard and bind the control to the two charts with the code at the top of this answer.
References
If you're still confused, play around with Google Playground for Dashboards to get an idea of how it works.

Show time of day on Google annotated time line chart

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}}
);
}