Skip to content

Commit 7fef7b1

Browse files
committed
Massage the data going into download graph
Google graphs does not treat 0-values in a stacked area-graph very well. The default behavior for something like the crates.io download graph is to draw many lines right over the top of eachother, meaning that a recently released version will have its lines drawn over the top of the the other versions. This can be fixed by passing google graphs a dataset with nulls instead of zeros for areas where the line shouldn't be drawn. This is an implementation of an algorithm that detects sequences of zeros and removes all the zeroes in the middle of the sequence, replacing them with null. For example [1, 2, 0, 0, 0, 0, 5, 10, 0, 0, 0, 3, 0, 0] will become (spaces indicate null) [1, 2, 0, , , 0, 5, 10, 0, , 0, 3, 0, 0] Leaving the boundary 0s makes the graph look more continuous. See the PR for before/after photos.
1 parent 65eefe1 commit 7fef7b1

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

app/components/download-graph.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,53 @@ export default Ember.Component.extend({
2020

2121
let data = this.get('data');
2222

23+
let datapoints_count = (data[1] || []).length - 1;
24+
25+
// "on" is an array of booleans where each
26+
// element in the array says whether or not the
27+
// corresponding line in the data is being drawn or not.
28+
//
29+
// Each line starts as not being drawn, and can pick up and
30+
// be stopped arbitrarily many times before the graph is complete.
31+
let on = [];
32+
for (let i = 0; i < datapoints_count; i++) {
33+
on.push(false);
34+
}
35+
36+
// Start at 1 because the 0th entry in the array
37+
// is an array of version numbers
38+
for (let i = 1; i < data.length; i++) {
39+
for (let k = 0; k < datapoints_count; k++) {
40+
// k + 1 because the first entry in the array is the date
41+
let value = data[i][k + 1];
42+
43+
// If we are "off" and are looking at a zero
44+
// replace the data at this point with `null`.
45+
//
46+
// Null tells google.visualization to stop drawing
47+
// the line altogether.
48+
if (!on[k] && value === 0) {
49+
data[i][k + 1] = null;
50+
51+
// If we are off and the value is not zero, we
52+
// need to turn back on. (keep the value the same though)
53+
} else if (!on[k] && value !== 0) {
54+
on[k] = true;
55+
56+
// We previously wrote a null into data[i - 1][k + 1],
57+
// so to make the graph look pretty, we'll switch it back
58+
// to the zero that it was before.
59+
if (i > 1) {
60+
data[i - 1][k + 1] = 0;
61+
}
62+
// If we are on and the value is zero, turn off
63+
// but keep the zero in the array
64+
} else if (on[k] && value === 0) {
65+
on[k] = false;
66+
}
67+
}
68+
}
69+
2370
if (!data || !window.google || !window.googleChartsLoaded) {
2471
this.$().hide();
2572
return;

0 commit comments

Comments
 (0)