Skip to content

Instantly share code, notes, and snippets.

@holyjak
Created May 5, 2013 20:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save holyjak/5522060 to your computer and use it in GitHub Desktop.
Save holyjak/5522060 to your computer and use it in GitHub Desktop.
Intention Hidden In Implementation And Misty Edge of Validity - why does this function do what it does and under what assumptions does it operate? REFACTORED. See http://wondersofcode.wordpress.com/2013/05/05/intention-hidden-in-implementation-and-misty-edge-of-validity/
// Set seriesData.previous to hold data series of the previous period
// so that we may compute deltas (e.g. +10%).
// We also ensure that all the series, previous and current, have the same
// number of data points, adding fake ones if necessary, so that the delta-computation
// code <tbd:add reference> doesn't blow up. There may be some data missing
// at the end of a period, for example because months have different numbers of days.
// The fake elements and also any other undefined values will default to [0,0], which
// should be OK with all (line,area,..) graphs and tables.
// E.x.: seriesData.series[0].data = [ [1,"12%"],[2,"22%"],..,[31,"18%"] ],
// the previous month had only 30 days so we add a fake element for day 31;
// See the class Series for more information.
augmentSeriesWithPreviousValues:function (seriesData, previousSeriesData) {
var series = seriesData.series;
seriesData.previous = [];
var previousSeries = previousSeriesData.series;
... // checks, computing maxRows, maxColumns, previousCategories
// that maps category name to series index (id)
var matcher = new SeriesMatcher(seriesData, previousCategories); // a helper
// The current and previous series must have data for the same unit (e.g. day 15 if period=month),
// only at the end of the period there may be missing entries (shorter month etc.)
assertMatchingDaysInCurrentAndPrevious(series, previousSeries);
for (var seriesId = 0; seriesId < series.length; seriesId++) {
var previousSeriesId = matcher.previousSeriesIdFor(seriesId)
for (var rowId = 0; rowId < maxRows; rowId++) {
for (var columnId = 1; columnId < maxColumns; columnId++) {
createDataPointIfMissing(series, seriesId, rowId);
replaceNaNWithDefaultOf(0, series, seriesId, rowId, columnId);
createDataPointIfMissing(seriesData.previous, seriesId, rowId);
copyPreviousValueIfDefined(seriesData.previous[seriesId], previousSeries[previousSeriesId], rowId, columnId);
replaceNaNWithDefaultOf(0, seriesData.previous, seriesId, rowId, columnId);
}
}
}
}
// Make sure the 3D array series has the element [seriesId][rowId];
// it's assumed that [seriesId-1][rowId-1] exist, unless 0.
function createDataPointIfMissing(series, seriesId, rowId) {
var array = series;
[seriesId, rowId].forEach(function(idx){
if (!array[idx]) {
array[idx] = [];
}
array = array[idx];
});
return series;
}
// If x or y coordinate of the data point series[seriesId][rowId] is undefined,
// set it to the given default value
function replaceNaNWithDefaultOf(default, series, seriesId, rowId, columnId) {
var value = series[seriesId][rowId][columnId];
if (isNaN(value)) {
series[seriesId][rowId][columnId] = default;
}
}
// Copy the given data point's coordinate from source (if defined) to target
function copyPreviousValueIfDefined(target, source, rowId, columnId) {
if (source && source[rowId] && source[rowId][columnId]) {
target[rowId][columnId] = source[rowId][columnId];
}
}
... // implementation of other helper functions, such as assertNoMissing, not shown
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment