function identity(x) { return x; } function property(/*arguments*/) { var properties = Array.prototype.slice.call(arguments); return function (x) { var result = x, i; for (i = 0; i < properties.length; i++) { result = result[properties[i]]; } return result; }; } function add(a, b) { return a + b; } function extentUnion(extents) { return extents.reduce(function(prev, next) { return [Math.min(prev[0], next[0]), Math.max(prev[1], next[1])]; }, [Infinity, -Infinity]); } function key(x) { if (x.key === void(0)) { if (x instanceof Array) return JSON.stringify(x.slice(0, 2)); else return x; } else { return x.key; } } function constant(c) { return function () { return c; }; } function tuple(/*arguments*/) { var functions = Array.prototype.slice.call(arguments); return function (x) { return functions.map(function (elem, i, funs) { return funs[i](x) }); }; } function comp(/*arguments*/) { var functions = Array.prototype.slice.call(arguments); return function (/*arguments*/) { var result = functions[functions.length - 1].apply(null, arguments), i; for (i = functions.length - 2; i >= 0; i--) { result = functions[i].call(null, result); } return result; } } var d3u = { repeat: tuple(identity), descend: identity, bind: function bind(rootSelection, element, dataFlow, classes, mixins) { if(mixins) { if(typeof mixins !== 'function') { mixins = function() {return mixins;} } } else { mixins = function() {return [];} } var classesToClassAttr = function (classNames) { return classNames.join(' '); }, classesToCssSelector = function (classNames) { return (['']).concat(classNames).join(' .') }, cssClasses = classesToCssSelector(classes), binding = rootSelection.selectAll(cssClasses).data(dataFlow, key); binding.entered = binding.enter().append(element); binding.entered.attr('class', function(d, i) { var classesWithMixins = classes.concat(mixins(d,i)); return classesToClassAttr(classesWithMixins); }); return binding; }, translateSVG: function translateSVG(funX, funY) { return function (d, i) { return 'translate(' + funX(d, i) + ',' + funY(d, i) + ')'; }; }, scaleSVG: function scaleSVG(funX, funY) { return function (d, i) { return 'scale(' + funX(d, i) + ',' + funY(d, i) + ')'; }; }, tableBind: function tableBind(root, columnClass, cellClass) { var columnBinding = d3u.bind(root, 'g', d3u.repeat, [columnClass]); var cellBinding = d3u.bind(columnBinding, 'g', d3u.descend, [cellClass]); return { column: columnBinding, cell: cellBinding } }, formatWithPrefix: function formatWithPrefix(value) { var absv = Math.abs(value); if (absv > 1000000) return d3.format(absv < 9950000 ? ",.1f" : ",.0f")(value / 1000000) + 'M'; else if (absv > 1000) return d3.format(absv < 9950 ? ",.1f" : ",.0f")(value / 1000) + 'k'; else return d3.format(",.0f")(value); }, pointMarker: function(selection) { selection.each(function(d) { d3u.bind(selection, 'circle', d3u.repeat, ['metrics-dropdown-probe']).attr({r: '3px', fill: 'red'}); }); }, parseMatrix: function parseMatrix(cssString) { return cssString.replace(/^\w*\(/, '').replace(')', '').split(/\s*,\s*/); }, scaleMaker: function scaleMaker(domainMin, domainMax, rangeMin, rangeMax) { var rangeExtent = rangeMax - rangeMin, domainExtent = domainMax - domainMin, slope = rangeExtent / domainExtent, a = slope, b = rangeMin - slope * domainMin; return function scaleMakerInner(n) { return a * n + b; } } };