assign $scope.chart.options based on conditional check - javascript - javascript

I am working on google chart API.I am working on timeline chart. I want to assign the colors of the bar inside the timeline chart based on the conditional check.
Below is the condition:
var firstWord = value.detail.trim().split(' ')[0];
if(firstWord === 'monthly'){ $scope.chart.options.colors[0]='yellow';}
if(firstWord === 'daily') { $scope.chart.options.colors[0]='green';}
How to assign the colors in the $scope.chart.options dynamically at runtime based on conditional check.
complete js code:
app.controller('MyController', ['$rootScope', '$scope',function ($scope, MyService) {
$scope.chart = {};
$scope.chart.type = "Timeline";
$scope.chart.cssStyle = "height:80%; width:100%;";
$scope.chart.options = {
timeline: {
barLabelStyle: { fontSize: 14 ,bold:true}
},
// colors:['#7EAE5A','#0E77B4'],
};
$scope.chart.data = {
"cols": [
{id: "status", label: "Status", type: "string"},
{id: "detail", label: "Detail", type: "string"},
{id:"tooltip", role:"tooltip", type:"string"},
{id: "startDate", label: "startDate", type: "date"},
{id: "endDate", label: "endDate", type: "date"}
]
};
//getting the response data
MyService.getResponseData().then(
function (response) {
$scope.myResponse = response;
$scope.chart.data.rows = {};
angular.forEach($scope.myResponse, function (value, key) {
var firstWord = value.detail.trim().split(' ')[0];
if(firstWord === 'monthly'){ $scope.chart.options.colors[0]='yellow';}
if(firstWord === 'daily') { $scope.chart.options.colors[0]='green';}
var cData = {
c: [{v: i}, {v: value.detail },
{v: "tooltip"},{v: value.startDate}, {v: value.endDate}]
};
weekRows.push(cData);i++;
});
$scope.chart.data.rows = weekRows;
}
},

you can use a DataView to dynamically change the color
using a calculated column with the 'style' role
see following working snippet...
google.charts.load('current', {
packages:['timeline']
}).then(function () {
var chart;
var dataTable;
var options;
dataTable = google.visualization.arrayToDataTable([
['100', 'daily_HourlyMay', new Date(2018, 5, 1), new Date(2018, 5, 1) ],
['101', 'yearly_hourlyMarch113', new Date(2018, 3, 27), new Date(2018, 3, 27) ],
['102', 'monthly_hourlyFeb', new Date(2018, 2, 23), new Date(2018, 2, 30) ],
['103', 'daily_HourlyApril', new Date(2018, 4, 11), new Date(2018, 4, 18) ],
['104', 'daily_HourlyMarch224', new Date(2018, 3, 16), new Date(2018, 3, 27) ],
['105', 'monthly_HourlySept', new Date(2018, 6, 5), new Date(2018, 6, 18) ],
['106', 'yearly_sometext shown here', new Date(2018, 1, 12), new Date(2018, 1, 30) ],
['107', 'monthly_HourlySept', new Date(2018, 8, 5), new Date(2018, 8, 18) ],
['108', 'yearly_sometext shown here', new Date(2018, 9, 12), new Date(2018, 9, 30) ],
['109', 'daily_text1 data', new Date(2018, 7, 5), new Date(2018, 7, 18)
]], true);
dataView = new google.visualization.DataView(dataTable);
dataView.setColumns([0, 1, {
calc: function (dt, row) {
var color;
var firstWord = dt.getValue(row, 1).trim().split('_')[0];
switch (firstWord) {
case 'monthly':
color = 'yellow';
break;
case 'daily':
color = 'green';
break;
case 'yearly':
color = 'blue';
break;
default:
color = 'black';
}
return color;
},
role: 'style',
type: 'string',
}, 2, 3]);
options = {timeline: {showRowLabels: false}};
chart = new google.visualization.Timeline(document.getElementById('chart_div'));
chart.draw(dataView, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
UPDATE
in angular, set the view in app.js...
chart1.view = {columns: [0, 1, {
calc: function (dt, row) {
var color;
var firstWord = dt.getValue(row, 1).trim().split('_')[0];
switch (firstWord) {
case 'monthly':
color = 'yellow';
break;
case 'daily':
color = 'green';
break;
case 'yearly':
color = 'blue';
break;
default:
color = 'black';
}
return color;
},
role: 'style',
type: 'string',
}, 2, 3]};

Related

Stepped Area Google charts wrong visualization

I'm using Google charts Stepped Area in my project, I have 2 data columns (datetime,state).
The problem is when the change in time is dynamic and not fixed the chart gets abnormal like this example, however when the data points are in fixed time change, the chart is drawn correctly for example in this code the points are one every 100 milliseconds.
Example 1 data
['Date', 'State'],
[new Date(1534078983500), 3],
[new Date(1534078983880), 1],
[new Date(1534080441460), 3],
[new Date(1534080441840), 1],
[new Date(1534080533960), 3],
[new Date(1534080534330), 1]
Example 2 data
['Date', 'State'],
[new Date(1534078983100), 3],
[new Date(1534078983200), 1],
[new Date(1534078983300), 3],
[new Date(1534078983400), 1],
[new Date(1534078983500), 3],
[new Date(1534078983600), 1]
according to the Data Format for the SteppedAreaChart,
the Data Type for the x-axis should be --> 'string'
although it may work with dates, the results may be inconsistent
instead, use the DateFormat class to convert the date to a timestamp string
see following working snippet...
here, a DataView is used to create a calculated column for the timestamp...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Date', 'State'],
[new Date(1534078983500), 3],
[new Date(1534078983880), 1],
[new Date(1534080441460), 3],
[new Date(1534080441840), 1],
[new Date(1534080533960), 3],
[new Date(1534080534330), 1]
]);
var formatTime = new google.visualization.DateFormat({
pattern: 'HH:ss.SSSS a'
});
var view = new google.visualization.DataView(data);
view.setColumns([{
calc: function (dt, row) {
return formatTime.formatValue(dt.getValue(row, 0));
},
label: data.getColumnLabel(0),
type: 'string'
}, 1]);
var options = {
title: 'The decline of \'The 39 Steps\'',
vAxis: {
title: 'Accumulated Rating',
ticks: [{ v: 0, f: '' }, { v: 1, f: 'Close' }, { v: 2, f: 'CLG/OPG' }, { v: 3, f: 'Open' }, { v: 4, f: '' }]
}
};
var chart = new google.visualization.SteppedAreaChart(document.getElementById('chart_div'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
if you need to use the explorer option,
you can use a number instead of a string
use the formatted value to display the actual dates,
and build custom ticks for the x-axis using the same approach...
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Date', 'State'],
[new Date(1534078983500), 3],
[new Date(1534078983880), 1],
[new Date(1534080441460), 3],
[new Date(1534080441840), 1],
[new Date(1534080533960), 3],
[new Date(1534080534330), 1]
]);
var formatTime = new google.visualization.DateFormat({
pattern: 'HH:ss.SSSS a'
});
var view = new google.visualization.DataView(data);
view.setColumns([{
calc: function (dt, row) {
return {
v: row,
f: formatTime.formatValue(dt.getValue(row, 0))
};
},
label: data.getColumnLabel(0),
type: 'number'
}, 1]);
var xTicks = [];
for (var i = 0; i < view.getNumberOfRows(); i++) {
addTick(i);
}
function addTick(i) {
xTicks.push({
v: view.getValue(i, 0),
f: view.getFormattedValue(i, 0)
});
}
var options = {
explorer: {},
hAxis: {
ticks: xTicks
},
title: 'The decline of \'The 39 Steps\'',
vAxis: {
title: 'Accumulated Rating',
ticks: [{ v: 0, f: '' }, { v: 1, f: 'Close' }, { v: 2, f: 'CLG/OPG' }, { v: 3, f: 'Open' }, { v: 4, f: '' }]
}
};
var chart = new google.visualization.SteppedAreaChart(document.getElementById('chart_div'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google visualization set column dock

I am struggling with google charts. I want bars to be displayed from bottom, rather than from top. Currently they are "hanging" like on the image below:
I don't see proper setting in docs, if it is there, please correct me. This is the code responsible for handling the display:
function parseInterval(value) {
var result = new Date(1,1,1);
result.setMilliseconds(value*1000);
return result;
}
(function($) {
$(document).ready(function(){
var loading = $('#loading');
$.getJSON("/api/v1/users", function(result) {
var dropdown = $("#user_id");
$.each(result, function(item) {
dropdown.append($("<option />").val(this.user_id).text(this.name));
});
dropdown.show();
loading.hide();
});
$('#user_id').change(function(){
var selected_user = $("#user_id").val();
var chart_div = $('#chart_div');
if(selected_user) {
loading.show();
chart_div.hide();
$.getJSON("/api/v1/mean_time_month/"+selected_user, function(result) {
$.each(result, function(index, value) {
value[1] = parseInterval(value[1]);
});
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('datetime', 'Mean time (h:m:s)');
data.addRows(result);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Mean presence time',
minValue: new Date(1, 1, 1, 0, 0)
},
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
chart_div.show();
loading.hide();
var chart = new google.visualization.ColumnChart(chart_div[0]);
chart.draw(data, options);
});
}
});
});
})(jQuery);
try using option vAxis.direction...
The direction in which the values along the vertical axis grow. Specify -1 to reverse the order of the values.
vAxis: {
direction: -1
}
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('datetime', 'Mean time (h:m:s)');
data.addRows([
['Jan', new Date(1, 1, 1, 8, 16, 13)],
['Feb', new Date(1, 1, 1, 9, 24, 45)],
['Mar', new Date(1, 1, 1, 7, 36, 56)],
['Apr', new Date(1, 1, 1, 4, 20, 42)],
['May', new Date(1, 1, 1, 6, 51, 16)]
]);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
direction: -1,
title: 'Mean presence time',
minValue: new Date(1, 1, 1, 0, 0)
}
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
but i think the real problem lies within the data
notice the y-axis values the chart displays in the example above,
the order doesn't seem right, as well as the range (10am - 12am)
it appears you're only interested in the time values
as such, recommend using 'timeofday' vs. 'datetime'
(see --> working with timeofday)
The DataTable 'timeofday' column data type takes an array of either 3 or 4 numbers, representing hours, minutes, seconds, and optionally milliseconds, respectively. Using timeofday is different than using date and datetime in that the values are not specific to a date, whereas date and datetime always specify a date.
For example, the time 8:30am would be: [8, 30, 0, 0], with the 4th value being optional ([8, 30, 0] would output the same 'timeofday' value).
see following working snippet for example using 'timeofday'...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('timeofday', 'Mean time (h:m:s)');
data.addRows([
['Jan', [8, 16, 13]],
['Feb', [9, 24, 45]],
['Mar', [7, 36, 56]],
['Apr', [4, 20, 42]],
['May', [6, 51, 16]]
]);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Mean presence time',
minValue: [0, 0, 0]
}
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Error Date type (Google visualization)

This is my code for displaying the chart
$scope.course_chart = function(response){
var data2 = new google.visualization.DataTable();
data2.addColumn('date', 'pv_date');
data2.addColumn('string', 'pageviews');
_.each(response.result.rows, function(item){
var formattedDate = item[0].slice(0, 4) + ", " + item[0].slice(4, 6) + ", " + item[0].slice(6, 8);
var date_format = new Date(formattedDate);
date_format = $filter('date')(date_format);
data2.addRow([
date_format,
item[1]
]);
});
var chart = new google.visualization.AreaChart(document.querySelector('#course_chart'));
chart.draw(data2, options2);
};
google.load('visualization', '1', {packages:['corechart'], callback: $scope.course_chart});
My date_format value is Sep 27, 2016
what is the requirement output for this data type "date" in google visualization?
if you have column with data type: 'date'
then you must pass a date object --> new Date()
you can use any of the javascript date contructors
such as...
new Date(2016, 8, 26)
remember in javascript, months are zero based (8 = Sept)
or...
new Date('09/26/2016')
this creates the date from a string and does not set the format when displayed
adding rows to the data table...
data2.addColumn('date', 'pv_date');
data2.addRow(new Date(2016, 8, 26));
if you already have the date formatted, you can use object notation when adding rows
(v = value, f = formatted value)...
data2.addRow({
v: new Date(2016, 8, 26)
f: 'Sep 26, 2016'
});
you can also use the DateFormat provided by google
data2.addRow(new Date(2016, 8, 26));
var formatDate = new google.visualization.DateFormat({
pattern: 'MMM d, yyyy'
});
formatDate.format(data2, 0);
finally, you can provide raw dates and let the axis format the dates
i.e. hAxis.format: 'MMM d, yyyy'...
here are a few examples using each scenario...
1. use hAxis.format
google.charts.load('current', {
callback: function () {
var data2 = new google.visualization.DataTable();
data2.addColumn('date', 'pv_date');
data2.addColumn('number', 'pageviews');
data2.addRows([
[new Date(2016, 8, 26), 100],
[new Date(2016, 8, 27), 101]
]);
var options = {
hAxis: {
format: 'MMM d, yyyy'
}
};
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data2, options);
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
2. use DateFormat
google.charts.load('current', {
callback: function () {
var data2 = new google.visualization.DataTable();
data2.addColumn('date', 'pv_date');
data2.addColumn('number', 'pageviews');
data2.addRows([
[new Date(2016, 8, 26), 100],
[new Date(2016, 8, 27), 101]
]);
var formatDate = new google.visualization.DateFormat({
pattern: 'MMM d, yyyy'
});
formatDate.format(data2, 0);
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data2);
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
3. use Object notation {v: , f:}
google.charts.load('current', {
callback: function () {
var data2 = new google.visualization.DataTable();
data2.addColumn('date', 'pv_date');
data2.addColumn('number', 'pageviews');
data2.addRows([
[{v: new Date(2016, 8, 26), f: 'Sep 26, 2016'}, 100],
[{v: new Date(2016, 8, 27), f: 'Sep 27, 2016'}, 101]
]);
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data2);
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
also, for AreaChart, the columns after the first should be of type: 'number' -- not 'string'

Dual y axes in Google charts

I am trying to use dual y axes with Google charts.I understand the basics and how it works.
On one y axis, I want BMI values and on other Weight Values.
I am taking out data from SQL database. However, BMI and Weight are itself values in a column called ReadingName.
So, if I use the query,
select * from table where ReadingName = 'BMI' or ReadingName = Weight
I get the result set which is serialized into JSON and then forwarded to render charts which again would be retrieved using column Name only.
Now, to have observation values for BMI on one yaxis and Weight on other, as per the example on GoogleCharts website, I need to have them as columns.
But I have them only as different values of same column called ReadingType.Is there a work around possible ?
This is how it should look like :
Unfortunately, you'll have to massage the data into a format it understands. The DataTable class provides lots of methods for populating but here is an example:
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Start with long data
var rawData = [
[new Date(2014, 8, 1), "Weight", 140],
[new Date(2014, 8, 1), "BMI", 5],
[new Date(2014, 8, 15), "Weight", 130],
[new Date(2014, 8, 15), "BMI", 4],
[new Date(2014, 9, 1), "Weight", 120],
[new Date(2014, 9, 1), "BMI", 3],
[new Date(2014, 9, 15), "Weight", 120],
[new Date(2014, 9, 15), "BMI", 3]
];
// Create a wide table from the long data
var data = new google.visualization.DataTable();
data.addColumn("date", "Date");
data.addColumn("number", "BMI");
data.addColumn("number", "Weight");
var lastDate = null;
var currentRow = null;
for (var i=0; i < rawData.length; i++) {
var date=rawData[i][0];
var col=rawData[i][1];
var value=rawData[i][2];
if (lastDate == null) {
// First pass
currentRow = [date, null, null];
}
else if (lastDate != date) {
data.addRow(currentRow);
currentRow = [date, null, null];
}
if (col=="BMI") currentRow[1] = value;
else if (col=="Weight") currentRow[2] = value;
lastDate = date;
}
if (currentRow != null) data.addRow(currentRow);
var options = {
title: 'Wight & BMI',
vAxes: [{
title: "Weight",
minValue: 0
}, {
title: "BMI",
minValue: 0
}],
series: {
0: { targetAxisIndex:0 },
1: { targetAxisIndex:1 }
},
interpolateNulls: true
}
var chart = new google.visualization.LineChart(document.getElementById("chart"));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart" style="width: 900px; height: 300px;"></div>

How do I get more specific duration using Google Charts Timeline?

So, I'm using the following code to create a timeline from Google charts.
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['timeline']}]}"></script>
<script type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById("example1");
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: "string", id: "RowName" });
dataTable.addColumn({ type: "string", id: "Label" });
dataTable.addColumn({ type: "date", id: "Start" });
dataTable.addColumn({ type: "date", id: "End" });
dataTable.addRows([
["Row1", "Step 1", new Date(2013, 11, 4, 2, 45, 0), new Date(2013, 11, 4, 4, 5, 15)],
["Row1", "Step 2", new Date(2013, 11, 4, 4, 5, 15), new Date(2013, 11, 7, 8, 34, 55)],
["Row1", "Step 3", new Date(2013, 11, 7, 8, 34, 55), new Date(2013, 11, 12, 11, 28, 49)],
["Row1", "Step 4", new Date(2013, 11, 12, 11, 28, 49), new Date(2013, 11, 14, 9, 27, 17)]
]);
var options = {
timeline: {
groupByRowLabel: true,
showRowLabels: true
}
};
chart.draw(dataTable, options);
}
</script>
<div id="example1" style="width: 900px; height: 180px;"></div>
I would like to get more detailed with the mouse over popup Duration. If you look at Step 1, it just says Duration: 1 day. But, if you look at the code, it was only an hour 20 minutes and 15 seconds. Is there any way to get this to show?
Link of code running: http://jsfiddle.net/ifandelse/FdFM3/
It's correct what user asgallant said. But still you can get some information.
Add one element after you chart div:
<div id="example1" style="width: 900px; height: 180px;"></div>
<div id='duration'></div>
Add event listener before call to draw chart:
google.visualization.events.addListener(chart, 'onmouseover', function (obj) {
var startDate = dataTable.getValue(obj.row, 2);
var endDate = dataTable.getValue(obj.row, 3);
var timeDiff = Math.abs(startDate.getTime() - endDate.getTime());
var diffDays = (timeDiff / (1000 * 3600 * 24));
var durationEl = document.getElementById('duration');
durationEl.innerHTML = 'Duration: ' + diffDays.toFixed(4);
});
chart.draw(dataTable, options);
You will get now for the 1st step 0.0557. This solution is little ugly but at least you get an idea. You can even calculate hours if you want and do some styling.
See example at jsBin.

Categories