Simplest annotated line chart - google-visualization

this was originally asked on Google groups but since I received no replies, I'm asking here on SO.
I am plotting basic data like temperature, various counts and such with date time and I like to append a third column as a further description.
E.g.
time, value, description
time, value, description
time, value, description
So I am looking at the simplest way of plotting that, as full screen as possible, as minimally (least LOC) as possible.
So far with https://jsfiddle.net/kaihendry/q1mczqc1/2/ I have not figured how to show the description (is it a infobox/selection? not sure on terminology), which in my example is the kernel version, when I click a point.
Furthermore I don't understand why on the right of the graph there are these null value labels:
http://s.natalian.org/2015-06-16/1434449447_1054x1058.png
And any tips to make http://s.natalian.org/2015-06-16/foo.html scale to fill the whole screen? I especially want to make it usable on my iPhone.

I have not figured how to show the description (is it a infobox/selection? not sure on terminology)
In web development, this is called a tooltip. In Google charts, you can add a tooltip by replacing the commented line with the following one :
//data.addColumn('string', 'kernel');
data.addColumn({type: 'string', role: 'tooltip'});
So, the 3rd column will not be handled as a data series, but as a tooltip.
Furthermore I don't understand why on the right of the graph there are these null value labels
The null values are shown, because (as previously stated), you have inserted 2 series of data ('Date' and 'kernel'). If you make the replacement mentioned before, the null values will be replaced
And any tips to make .. scale to fill the whole screen ?
You can add the following option to configure the dimensions of the chart :
var options = {
chartArea: {width: '80%', height: '80%'}
};
Furthermore, since the version of line charts you are using are slightly obsolete, you shoud replace
var chart = new google.charts.Line(document.getElementById('linechart_material'));
with
var chart = new google.visualization.LineChart(document.getElementById('linechart_material'));
In the following jsfiddle, you can find a final working version
(with some more fixes, like horizontal axis range and legend positioning).

If I understand right you want to add third column as a description for each point.
If you add 3rd column like this
data.addColumn('string', 'kernel');
Google chart takes this as another series and because the data are string it can't draw the series and shows null.
You can add 3rd column as a tooltip.
data.addColumn({type: 'string', role: 'tooltip'});
But for tooltip to work you need to change the line chart to visualization line chart
var chart = new google.visualization.LineChart(document.getElementById('linechart_material'));
To make chart fill the screen you can change the div style.
<div id="linechart_material" style="height:100%;"></div>

Related

How to convert a decimal into it's time equivalent as part of a function?

I'm running into an issue when trying to compare data across two sheets to find discrepancies - specifically when it comes to comparing start and end times.
Right now, the "IF" statement in my screenshot is executing perfectly, except when a time is involved - it's reading those cells as decimals instead (but only sometimes).
I've tried formatting these cells (on the raw data AND on this "Discrepancies" report sheet) so that they are displayed as a "HH:MM am/pm" time, but the sheet is still comparing the decimal values.
Is there anything that I can add to this function to account for a compared value being a time instead of text, and having that text be compared for any discrepancies? I cannot add or change anything to the raw data sheets, the only thing I can edit is the formula seen in the screenshot I provided.
See the highlighted cells in my screenshot - this is the issue I keep running into. As you can see, there are SOME cells (the non-highlighted ones) that are executing as intended, but I'm unsure why this isn't the case for the whole spreadsheet when I've formatted everything the same way using the exact same formula across the whole sheet.
For example, the values in cell N2 is "8:00 AM" on both sheets, so the formula should just display "8:00 AM" in that cell (and NOT be highlighted) since there is no discrepancy in the cells between both sheets it's comparing. But instead, it's showing both times as a decimal with the slightest difference between them and is suggesting a difference where there technically isn't (or shouldn't be) one.
Please help!
Screenshot of original spreadsheet for reference
---EDIT (added the below):
Here is a view-only version of a SAMPLE SHEET that displays the issue I'm having:
https://docs.google.com/spreadsheets/d/1BdSQGsCajB3kOnYxzM3sl-0o3iTvR3ABdHpnzYRXjpA/edit?usp=sharing
On the sample sheet, the only cells that are performing as intended are C2, E2, G2, I2, K2, K6, or any cells that contain text like "Closed". Any of the other cells that have a time in both raw data tabs appears to be pulling the serial numbers for those times instead of correctly formatting it into "HH:mm AM/PM".
A quick tour of how the SAMPLE SHEET is set up:
User enters raw data into the "MicrositeRawData" and "SalesforceRawData" tabs.
Data is pulled from the "SalesforceRawData" tab into the "CleanedUpSalesforceData" tab using a QUERY that matches the UNIQUE ID's from the "MicrositeRawData" sheet, so that it essentially creates a tab that's in the same order and accounts for any extraneous data between the tabs (keep in mind this is a sample sheet and that the original sheet I'm using includes a lot more data which causes a mismatch of rows between the sheets which makes the QUERY necessary).
The "DISCREPANCIES" tab then compares the data between the "MicrositeRawData" and "CleanedUpSalesforceData" tabs. If the data is the same, it simply copies the data from the "MicrositeRawData" cell. But if the data is NOT the same, it lists the values from both sheets and is conditionally formatted to highlight those cells in yellow.
If there is data on the "MicrositeRawData" tab that is NOT included on the "SalesforceRawData" tab, the "DISCREPANCIES" tab will notate that and highlight the "A" cell in pink instead of yellow (as demonstrated in "A5").
try in B2:
=IF(MicrositeRawData!B2=CleanedUpSalesforceData!B2, MicrositeRawData!B2,
"MICROSITE: "&TEXT(MicrositeRawData!B2, "h:mm AM/PM")&CHAR(10)&
"SALESFORCE: "&TEXT(CleanedUpSalesforceData!B2, "h:mm AM/PM"))
update
delete all formulae from range B2:O10 and use this in B2:
=ARRAYFORMULA(IF(TO_TEXT(MicrositeRawData!B2:O10)=
TO_TEXT(CleanedUpSalesforceData!B2:O10), MicrositeRawData!B2:O10,
"MICROSITE: "&TEXT(IF(MicrositeRawData!B2:O10="",
"", MicrositeRawData!B2:O10), "h:mm AM/PM")&CHAR(10)&
"SALESFORCE: "&TEXT(IF(CleanedUpSalesforceData!B2:O10="",
"", CleanedUpSalesforceData!B2:O10), "h:mm AM/PM")))

Ticks callback not displaying strings containing decimal

I'm trying to display a formatted string for thousands and million amounts for only certain ticks on a horizantal stacked bar chart.
See line 18 (which works): https://stackblitz.com/edit/angular-sl5pqg
If the line is changed to const actualAmount = 12500000;, I am expecting "$12.5M" to be displayed on the first tick point I want to display but it's coming up blank.
Could someone kindly let me know what I'm doing wrong?
Many thanks!
Ben
Your code looks fine but you need to define ticks.autoSkip: false:
ticks: {
...
autoSkip: false,
Please have a look at the amended StackBlitz
If autoSkip is true (default), Chart.js automatically calculates
how many labels can be shown and hides labels accordingly. Labels will
be rotated up to maxRotation before skipping any. Turn autoSkip
off to show all labels no matter what.

How to limit number of displayed points in chart.js?

I have too many points on x-axis in my chart. I would like to limit maximum of displayed points to 100. But at the same time still displaying same chart. Exactly same chart - but with fewer points.
screenshot of my chart with too many points
I have no idea how to do it in PHP at server side so I was thinking if there is any solution on client side in chart.js?
It's your responsibility to give chart.js the points it should display. You have to limit the arrays with the labels and the data to 100 datapoints. Use every second data or so. Just do it in plain JavaScript. There's no function in chart.js for that.
For large datasets, chart.js does offer a data decimation plugin that automatically decimates data at the start of the chart lifecycle, reducing the number of data points drawn.
According to chart.js docs, to use the decimation plugin, the following requirements must be met:
The dataset must have an indexAxis of 'x' The dataset must be a line
The X axis for the dataset must be either a 'linear' or 'time' type axis
Data must not need parsing, i.e. parsing must be false
The dataset object must be mutable. The plugin stores the original data
as dataset._data and then defines a new data property on the dataset.
Your chart options should look something like this:
options: {
parsing: false,
plugins: {
decimation: {
enabled: false,
algorithm: 'min-max',
},
},
scales: {
x: {
type: 'time',
ticks: {
source: 'auto',
autoSkip: true,
}
}
}
Remember also that if you disable parsing the data you pass should be in the right format for the type of chart you chose, so epoch timestamps in this case. More info here.
Finally, you can find a working example here.

ChartJS Tooltip displaying data from same dataset

Currently working on a chart that displays upwards ~1000 datapoints at any given moment between 2-3 datasets.
The only thing is that each of the points has a different timestamp (x-value).
Our goal is that upon hovering on one data point, it also brings the closest data point from the other datasets as well. We were able to achieve that with:
options={{
tooltips: {
mode: 'x'
}
}}
I understand that there is a default pointHitRadius and that seems to be the reason why multiple values of the same dataset are appearing in the same tooltip.
I made a simple test case: TEST
I increased the pointBorderRadius and it seems to include 1-5 points at a time.
Is there a way to only include data from each dataset ONCE?
The closest thing I found (before having to extend functionality), is that there is a filter function available.
However, from what I can see, it looks like it only returns one instance from each dataset. Which wouldn't be too helpful.
Anyone run into this issue?

How to get any y value for specified x in chart.js?

This example is very skewed, but it shows my point well enough. The blue line has a large gap (so a bunch of extrapolated data) for the first ~2 weeks of Nov. I want to hover over point on the red line, and get the corresponding data for the blue line. I've found scale.getValueForPixel(value) but that only gets data for the exact point in the scale. I haven't been able to find a corresponding function for whatever the line is.
Is there any way for me to get the extrapolated data from any point on a line?
A simple to way to get this done is binding the canvas for onClick event, and use the following code, also here is a working fiddle -> http://jsfiddle.net/Lzo5g01n/4/
document.getElementById("myChart").addEventListener("click", function(e) {
var element = myChart.getElementAtEvent(e)[0];
if (element) {
alert(myChart.config.data.datasets[element._datasetIndex].data[element._index]);
}
});