Related
Well, I am using a LineChart with Angular 4 and I make sure to change labels according to window size like the following:
#HostListener('window:resize', ['$event']) onResize(event) {
if (event.target['innerWidth'] < 420) {
this.stockAnalysisService.getOptionsY()['hAxis']['format'] = 'MMM';
} else if (event.target['innerWidth'] < 760) {
this.stockAnalysisService.getOptionsY()['hAxis']['format'] = 'MM. yy\'';
} else { this.stockAnalysisService.getOptionsY()['hAxis']['format'] = 'MMM d, yyyy'; }
this.drawBasic();
}
This is just basic Angular syntax to detect resize or window and change the hAxis labels accordingly.
My question is, if I want a custom label where I present months on the labels and the months are presented with values of DAY OF THE MONTH and ONLY the first day of the month will have an addition of text to it like the following image:
RED: days of the month (jumps 5 days each time but not relevant)
BLACK: first indication of the month (Should not be NOV 10, but NOV 1, not relevant)
Any idea?
to have one or more labels different from than rest,
will need to use option --> hAxis.ticks
this means you will need to build an array of the labels that should be displayed
using object notation, for each tick you can provide
the value of the tick (v:)
and the formatted value of the tick (f:)
{v: dateValue, f: displayValue}
the value (v:) should be the same type as the x-axis, in this case --> 'date'
the formatted value (f:) should be --> 'string'
if you don't use object notation, and just provide a date for the tick,
the label will be displayed according to --> hAxis.format
so, for the dates that should have the month prefix,
use object notation, for the rest, just provide the date
see following working snippet for an example...
google.charts.load('current', {
packages: ['controls', 'corechart', 'table']
}).then(function () {
var data = new google.visualization.DataTable();
data.addColumn('date', 'x');
data.addColumn('number', 'y0');
data.addRows([
[new Date(2017, 7, 1), 2],
[new Date(2017, 7, 2), 3],
[new Date(2017, 7, 4), 1],
[new Date(2017, 7, 8), 5],
[new Date(2017, 7, 16), 6],
[new Date(2017, 7, 20), 7],
[new Date(2017, 7, 24), 1],
[new Date(2017, 7, 26), 2],
[new Date(2017, 7, 27), 3],
[new Date(2017, 8, 1), 2],
[new Date(2017, 8, 2), 3],
[new Date(2017, 8, 4), 9],
[new Date(2017, 8, 8), 5],
[new Date(2017, 8, 16), 6],
[new Date(2017, 8, 20), 7],
[new Date(2017, 8, 24), 1],
[new Date(2017, 8, 26), 2],
[new Date(2017, 8, 27), 3]
]);
var oneDay = (1000 * 60 * 60 * 24);
var dateRange = data.getColumnRange(0);
var formatMonth = new google.visualization.DateFormat({
pattern: 'MMM dd'
});
// build ticks
var ticksX = [];
for (var i = dateRange.min.getTime(); i <= dateRange.max.getTime(); i = i + oneDay) {
var rowDate = new Date(i);
if (rowDate.getDate() === 1) {
// add first day of month
ticksX.push({
v: rowDate,
f: formatMonth.formatValue(rowDate)
});
} else if (((i - dateRange.min.getTime()) % 7) === 0) {
// add date every seven days
ticksX.push(rowDate);
}
}
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
chart.draw(data, {
chartArea: {
bottom: 36,
left: 48,
right: 12,
top: 12,
width: '100%',
height: '100%'
},
hAxis: {
format: 'dd',
ticks: ticksX
},
width: 800
});
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I have a Google sheet that look like this:
Date Sales
31/03/2017 1000
30/06/2017 2000
30/09/2017 1500
31/12/2017 2500
31/03/2018 4000
If I import this using .arrayToDataTable in Google charts and set the type of column 0 to 'date' or 'string' - it doesn't like it, because the date is only a formatted number i.e 43190 = 31/3/2018. so the type has to be 'number' which then only displays the underlying number on the chart and not the date
I can loop through each of the row values and I've tried changing them with this
function formatDate(date) {
var d = new Date((date - 25569)*86400*1000),
locale = "en-us",
month = d.toLocaleString(locale, { month: "short" });
var formattedDate = d.getDay() + "/" + month + "/" + d.getFullYear();
return formattedDate
}
this converts the number to a date string - so with an input of, say, 43190 it returns 31/Mar/2018 but I still can't change the column type to 'date'
I could output the dates as strings but they don't sort in chronological order but alphabetical - I want them chronological.
can anybody show me where I'm going wrong?
EDIT:
If I change the function to
function formatDate(date) {
var d = new Date((date - 25569)*86400*1000)
return d
}
this now sets the column values to the full date object
but I get an error a saying "Value Sun Jun 30 2013 01:00:00 GMT+0100 (GMT Summer Time) does not match type number in column index 0"
Now this must be referring to the datatable column zero, which in the original table, is a date number. I've tried adding:
data.setColumnProperty(0, 'type' , 'date')
but seem to get the same error.
perhaps I'm not changing the type at the correct point in the code.
to clarify: I'm getting the original values from a range in the google sheet then converting that range to a datatable using .arrayToDataTable. So I'm not sure I can define the column type at the point of making the datatable hence the separate attempt with:
data.setColumnProperty(0, 'type' , 'date')
You have to supply the complete date object in the date-type column.
Good documentation about dates can be found here
https://developers.google.com/chart/interactive/docs/datesandtimes#axesgridlinesticks
An example of dates and sales could be
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Sales');
data.addRows([
[new Date(2015, 0, 1), 5], [new Date(2015, 0, 2), 7], [new Date(2015, 0, 3), 3],
[new Date(2015, 0, 4), 1], [new Date(2015, 0, 5), 3], [new Date(2015, 0, 6), 4],
[new Date(2015, 0, 7), 3], [new Date(2015, 0, 8), 4], [new Date(2015, 0, 9), 2],
[new Date(2015, 0, 10), 5], [new Date(2015, 0, 11), 8], [new Date(2015, 0, 12), 6],
[new Date(2015, 0, 13), 3], [new Date(2015, 0, 14), 3], [new Date(2015, 0, 15), 5],
[new Date(2015, 0, 16), 7], [new Date(2015, 0, 17), 6], [new Date(2015, 0, 18), 6],
[new Date(2015, 0, 19), 3], [new Date(2015, 0, 20), 1], [new Date(2015, 0, 21), 2],
[new Date(2015, 0, 22), 4], [new Date(2015, 0, 23), 6], [new Date(2015, 0, 24), 5],
[new Date(2015, 0, 25), 9], [new Date(2015, 0, 26), 4], [new Date(2015, 0, 27), 9],
[new Date(2015, 0, 28), 8], [new Date(2015, 0, 29), 6], [new Date(2015, 0, 30), 4],
[new Date(2015, 0, 31), 6], [new Date(2015, 1, 1), 7], [new Date(2015, 1, 2), 9]
]);
You could than add the following to options to format your date
hAxis: {
format: 'MM/dd/yyyy'
}
I have a DATAS.TXT file automatically filled-in with TIME and TEMPERATURE datas.
TIME is already formatted as per Google Charts requirements:
new Date(Year, Month, Day, Hours, Minutes)
TIME datas and TEMPERATURES datas are separated by a SPACE character and each line terminates with \r.
The DATAS.TXT file shows something like this:
new Date(2017, 01, 01, 05, 15) 20.5
new Date(2017, 01, 01, 18, 50) 21.7
new Date(2017, 01, 19, 12, 35) 22.4
etc ...
From this DATA file I would like to generate a Google Chart like this example:
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type='text/javascript'>
google.load('visualization', '1', {'packages':['annotatedtimeline']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Date');
data.addColumn('number', 'Temperatures');
data.addRows([
[new Date(2001, 0, 1, 0), 0.0],
[new Date(2001, 0, 1, 1), 4.8],
[new Date(2001, 0, 1, 2), 4.6],
[new Date(2001, 0, 1, 3), 2.6],
[new Date(2001, 0, 1, 4), 3.6],
// ...
// Rest of year data here...
// ...
[new Date(2001, 11, 31, 20), 9.4],
[new Date(2001, 11, 31, 21), 7.0],
[new Date(2001, 11, 31, 22), 8.5],
[new Date(2001, 11, 31, 23), 2.2]
]);
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(data, {displayAnnotations: true});
}
</script>
My question is, how can I fill-in data.addRows([ ... ] contents with the datas issued from my DATAS.TXT file?
I need a function that could pick-up TIMES, detect the space character insertion, pick-up the associated TEMPERATURE data and detect the \r character.
I'm not confortable with PHP, any help will be highly appreciated.
I have a timeline chart. When I have only 3 columns (row label, start date, end date) in my timeline and color it, everything works perfectly. However, I added a another column (bar label) to my timeline, and now the coloring is all messed up. Does anyone know how to fix this issue? If it isn't, would this issue be considered a bug.
Sample code snippet on jsfiddle demonstrating the issue:
https://jsfiddle.net/9egybsro/
Looking at my hard-coded color array:
var color = ['#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#868686',
'#FF9900',
'#FF9900'
]
All bars except the 3rd to last bar should be colored orange. The 3rd to last bar should be colored grey. As shown when the run button is hit, all the bars are colored orange.
by default, the colors follow the bar labels
set timeline.colorByRowLabel to use the row labels / position of colors array
timeline: {
colorByRowLabel: true
}
otherwise, use a distinct bar label...
var barLabel = [];
for (var i = 0; i < startDate.length; ++i) {
barLabel.push("potato" + i);
}
see following working snippet...
google.charts.load('current', {
'packages': ['timeline']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById("timeline");
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({
type: 'string',
id: 'account_name'
});
dataTable.addColumn({
type: 'string',
id: 'bar_label'
});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
var name = ['Russ Hanneman',
'Gavin Belson',
'Jack Barker',
'Peter Gregory',
'Jian Yang',
'Richard Hendrix',
'Dinesh Chugtai',
'Bertram Gilfoyle',
'Erlich Bachman',
'Monica Hall',
'Nelson Bighetti',
'Aaron Anderson',
'Donald \'OJ\' Dunn'
]
var startDate = [new Date(2016, 0, 2),
new Date(2015, 5, 1),
new Date(2015, 11, 31),
new Date(2014, 0, 1),
new Date(2016, 6, 16),
new Date(2016, 9, 12),
new Date(2017, 5, 20),
new Date(2019, 0, 1),
new Date(2015, 0, 1),
new Date(2016, 9, 21),
new Date(2015, 8, 1),
new Date(2017, 6, 4),
new Date(2015, 6, 17)
]
var endDate = [new Date(2025, 6, 25),
new Date(2016, 11, 17),
new Date(2016, 2, 4),
new Date(2018, 6, 16),
new Date(2017, 11, 25),
new Date(2020, 2, 3),
new Date(2019, 6, 13),
new Date(2019, 9, 16),
new Date(2018, 9, 23),
new Date(2019, 7, 12),
new Date(2019, 2, 17),
new Date(2022, 3, 1),
new Date(2021, 0, 21)
]
var barLabel = [];
for (var i = 0; i < startDate.length; ++i) {
barLabel.push("potato");
}
var color = ['#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#FF9900',
'#868686',
'#FF9900',
'#FF9900'
]
heightVal = 50 * name.length;
if (heightVal > 500) {
heightVal = 500;
}
document.getElementById("timeline").style = "height: " + heightVal.toString() + "px;";
var accounts = [];
for (i = 0; i < endDate.length; i++) {
accounts.push([name[i], barLabel[i], startDate[i], endDate[i]]);
}
var options = {
colors: color,
timeline: {
colorByRowLabel: true
}
};
dataTable.addRows(accounts);
chart.draw(dataTable, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<p id="demo"></p>
<div id="timeline" style="height: 240px;"></div>
Solved it. colorByRowLabel needs to be set to true. I believe that the value of the bar label will be used as a metric for coloring if it's set to false rather than the index of that row relative to the array of colors.
I have to use classic Google Line Chart because the Material version doesn't support the curved lines yet, but I like curves. Unfortunately though it seems that only Material chart displays the datum stems (I'm not sure if I describe that properly, but I mean those dots which represent the data points on the line), and only when you hover over a line (anywhere along the line).
Here is a screenshot, to the left is a Google Material Chart and I'm hovering over the line, to the right is a chartjs chart, shows the studs even without hovering over anything.
Google Line Chart JSFiddle where you can see how the Material and the Classic Google Charts behave: https://jsfiddle.net/csabatoth/yyhLwkaf/
var classicOptions = {
title: 'Foo',
width: 900,
height: 500,
theme: 'material',
curveType: 'function'
// TODO
};
When in Material mode, you have to hover over a line to cause the data studs to appear. Classic charts is even worse in this respect: you have to "follow" the line until you hit a data point, and that's when it is only revealed.
What I desire is something like that (see the first visible line chart):
http://www.chartjs.org/docs/#line-chart-introduction
The data studs are visible regardless you hover over the line or not. I cannot seem to find out which is the proper option for that.
I think you are looking for pointSize
google.charts.load('current', {'packages':['line', 'corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var button = document.getElementById('change-chart');
var chartDiv = document.getElementById('chart_div');
var data = new google.visualization.DataTable();
data.addColumn('date', 'Month');
data.addColumn('number', "Average Temperature");
data.addColumn('number', "Average Hours of Daylight");
data.addRows([
[new Date(2014, 0), -.5, 5.7],
[new Date(2014, 1), .4, 8.7],
[new Date(2014, 2), .5, 12],
[new Date(2014, 3), 2.9, 15.3],
[new Date(2014, 4), 6.3, 18.6],
[new Date(2014, 5), 9, 20.9],
[new Date(2014, 6), 10.6, 19.8],
[new Date(2014, 7), 10.3, 16.6],
[new Date(2014, 8), 7.4, 13.3],
[new Date(2014, 9), 4.4, 9.9],
[new Date(2014, 10), 1.1, 6.6],
[new Date(2014, 11), -.2, 4.5]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, 2]);
var materialOptions = {
chart: {
title: 'Average Temperatures and Daylight in Iceland Throughout the Year'
},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: {axis: 'Temps'},
1: {axis: 'Daylight'}
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Temps: {label: 'Temps (Celsius)'},
Daylight: {label: 'Daylight'}
}
}
};
var classicOptions = {
curveType: 'function',
pointSize: 10,
title: 'Average Temperatures and Daylight in Iceland Throughout the Year',
width: 900,
height: 500,
// Gives each series an axis that matches the vAxes number below.
series: {
0: {targetAxisIndex: 0},
1: {targetAxisIndex: 1}
},
vAxes: {
// Adds titles to each axis.
0: {title: 'Temps (Celsius)'},
1: {title: 'Daylight'}
},
hAxis: {
ticks: [
new Date(2014, 0), new Date(2014, 1), new Date(2014, 2), new Date(2014, 3),
new Date(2014, 4), new Date(2014, 5), new Date(2014, 6), new Date(2014, 7),
new Date(2014, 8), new Date(2014, 9), new Date(2014, 10), new Date(2014, 11)
]
},
vAxis: {
viewWindow: {
max: 30
}
}
};
function drawMaterialChart() {
var materialChart = new google.charts.Line(chartDiv);
materialChart.draw(view, materialOptions);
button.innerText = 'Change to Classic';
button.onclick = drawClassicChart;
}
function drawClassicChart() {
var classicChart = new google.visualization.LineChart(chartDiv);
classicChart.draw(view, classicOptions);
button.innerText = 'Change to Material';
button.onclick = drawMaterialChart;
}
drawClassicChart();
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<button id="change-chart">Change to Material</button>
<br><br>
<div id="chart_div"></div>