Use d3 modules to reduce build size

This switches the codebase to use only specific d3 (version 4) modules
rather than the entire d3 (v3) package, resulting in a decent shrink
in build size (~75KB reduction).

Change-Id: I9f6a5d039d6340cc28115337bdfb891d15af7057
This commit is contained in:
Tim Buckley 2016-05-20 16:13:20 -06:00
parent 28caae17d6
commit 965e723004
7 changed files with 72 additions and 53 deletions

View File

@ -2,9 +2,12 @@
var directivesModule = require('./_index.js'); var directivesModule = require('./_index.js');
var d3Ease = require('d3-ease');
var d3Interpolate = require('d3-interpolate');
var d3Scale = require('d3-scale');
var arrayUtil = require('../util/array-util'); var arrayUtil = require('../util/array-util');
var parseDstat = require('../util/dstat-parse'); var parseDstat = require('../util/dstat-parse');
var d3 = require('d3');
var getDstatLanes = function(data, mins, maxes) { var getDstatLanes = function(data, mins, maxes) {
if (!data || !data.length) { if (!data || !data.length) {
@ -16,14 +19,14 @@ var getDstatLanes = function(data, mins, maxes) {
if ('total_cpu_usage_usr' in row && 'total_cpu_usage_sys' in row) { if ('total_cpu_usage_usr' in row && 'total_cpu_usage_sys' in row) {
lanes.push([{ lanes.push([{
scale: d3.scale.linear().domain([0, 100]), scale: d3Scale.scaleLinear().domain([0, 100]),
value: function(d) { value: function(d) {
return d.total_cpu_usage_wai; return d.total_cpu_usage_wai;
}, },
color: "rgba(224, 188, 188, 1)", color: "rgba(224, 188, 188, 1)",
text: "CPU wait" text: "CPU wait"
}, { }, {
scale: d3.scale.linear().domain([0, 100]), scale: d3Scale.scaleLinear().domain([0, 100]),
value: function(d) { value: function(d) {
return d.total_cpu_usage_usr + d.total_cpu_usage_sys; return d.total_cpu_usage_usr + d.total_cpu_usage_sys;
}, },
@ -34,7 +37,7 @@ var getDstatLanes = function(data, mins, maxes) {
if ('memory_usage_used' in row) { if ('memory_usage_used' in row) {
lanes.push([{ lanes.push([{
scale: d3.scale.linear().domain([0, maxes.memory_usage_used]), scale: d3Scale.scaleLinear().domain([0, maxes.memory_usage_used]),
value: function(d) { return d.memory_usage_used; }, value: function(d) { return d.memory_usage_used; },
color: "rgba(102, 140, 178, 0.75)", color: "rgba(102, 140, 178, 0.75)",
text: "Memory" text: "Memory"
@ -43,12 +46,12 @@ var getDstatLanes = function(data, mins, maxes) {
if ('net_total_recv' in row && 'net_total_send' in row) { if ('net_total_recv' in row && 'net_total_send' in row) {
lanes.push([{ lanes.push([{
scale: d3.scale.linear().domain([0, maxes.net_total_recv]), scale: d3Scale.scaleLinear().domain([0, maxes.net_total_recv]),
value: function(d) { return d.net_total_recv; }, value: function(d) { return d.net_total_recv; },
color: "rgba(224, 188, 188, 1)", color: "rgba(224, 188, 188, 1)",
text: "Net Down" text: "Net Down"
}, { }, {
scale: d3.scale.linear().domain([0, maxes.net_total_send]), scale: d3Scale.scaleLinear().domain([0, maxes.net_total_send]),
value: function(d) { return d.net_total_send; }, value: function(d) { return d.net_total_send; },
color: "rgba(102, 140, 178, 0.75)", color: "rgba(102, 140, 178, 0.75)",
text: "Net Up", text: "Net Up",
@ -58,13 +61,13 @@ var getDstatLanes = function(data, mins, maxes) {
if ('dsk_total_read' in row && 'dsk_total_writ' in row) { if ('dsk_total_read' in row && 'dsk_total_writ' in row) {
lanes.push([{ lanes.push([{
scale: d3.scale.linear().domain([0, maxes.dsk_total_read]), scale: d3Scale.scaleLinear().domain([0, maxes.dsk_total_read]),
value: function(d) { return d.dsk_total_read; }, value: function(d) { return d.dsk_total_read; },
color: "rgba(224, 188, 188, 1)", color: "rgba(224, 188, 188, 1)",
text: "Disk Read", text: "Disk Read",
type: "line" type: "line"
}, { }, {
scale: d3.scale.linear().domain([0, maxes.dsk_total_writ]), scale: d3Scale.scaleLinear().domain([0, maxes.dsk_total_writ]),
value: function(d) { return d.dsk_total_writ; }, value: function(d) { return d.dsk_total_writ; },
color: "rgba(102, 140, 178, 0.75)", color: "rgba(102, 140, 178, 0.75)",
text: "Disk Write", text: "Disk Write",
@ -87,12 +90,12 @@ function timelineDstat($document, $window) {
// axes and dstat-global variables // axes and dstat-global variables
var absolute = timelineController.axes.absolute; var absolute = timelineController.axes.absolute;
var xSelected = timelineController.axes.selection; var xSelected = timelineController.axes.selection;
var y = d3.scale.linear(); var y = d3Scale.scaleLinear();
// animation variables // animation variables
var currentViewExtents = null; var currentViewExtents = null;
var viewInterpolator = null; var viewInterpolator = null;
var easeOutCubic = d3.ease('cubic-out'); var easeOutCubic = d3Ease.easeCubicOut;
var easeStartTimestamp = null; var easeStartTimestamp = null;
var easeDuration = 500; var easeDuration = 500;
@ -406,7 +409,7 @@ function timelineDstat($document, $window) {
if (currentViewExtents) { if (currentViewExtents) {
// if we know where the view is already, try to animate the transition // if we know where the view is already, try to animate the transition
viewInterpolator = d3.interpolate( viewInterpolator = d3Interpolate.interpolateArray(
currentViewExtents, currentViewExtents,
timelineController.viewExtents); timelineController.viewExtents);
easeStartTimestamp = performance.now(); easeStartTimestamp = performance.now();
@ -426,7 +429,7 @@ function timelineDstat($document, $window) {
if (currentViewExtents) { if (currentViewExtents) {
// if we know where the view is already, try to animate the transition // if we know where the view is already, try to animate the transition
viewInterpolator = d3.interpolate( viewInterpolator = d3Interpolate.interpolateArray(
currentViewExtents, currentViewExtents,
timelineController.viewExtents); timelineController.viewExtents);
easeStartTimestamp = performance.now(); easeStartTimestamp = performance.now();

View File

@ -2,7 +2,7 @@
var directivesModule = require('./_index.js'); var directivesModule = require('./_index.js');
var d3 = require('d3'); var d3Scale = require('d3-scale');
function timelineOverview($document, $window) { function timelineOverview($document, $window) {
var link = function(scope, el, attrs, timelineController) { var link = function(scope, el, attrs, timelineController) {
@ -14,7 +14,7 @@ function timelineOverview($document, $window) {
// scales and extents // scales and extents
var x = timelineController.axes.x; var x = timelineController.axes.x;
var y = d3.scale.linear(); var y = d3Scale.scaleLinear();
var brushExtent = [0, 0]; var brushExtent = [0, 0];
var handleSize = 3; var handleSize = 3;
@ -81,7 +81,7 @@ function timelineOverview($document, $window) {
} }
var size = viewEnd - viewStart; var size = viewEnd - viewStart;
var currentMid = viewStart.getTime() + (size / 2); var currentMid = (+viewStart) + (size / 2);
var targetMid = item.startDate.getTime() + (item.endDate - item.startDate) / 2; var targetMid = item.startDate.getTime() + (item.endDate - item.startDate) / 2;
var targetStart, targetEnd; var targetStart, targetEnd;

View File

@ -3,7 +3,10 @@
var directivesModule = require('./_index.js'); var directivesModule = require('./_index.js');
var arrayUtil = require('../util/array-util'); var arrayUtil = require('../util/array-util');
var d3 = require('d3'); var d3Ease = require('d3-ease');
var d3Interpolate = require('d3-interpolate');
var d3Scale = require('d3-scale');
var d3TimeFormat = require('d3-time-format');
/** /**
* @ngInject * @ngInject
@ -17,16 +20,16 @@ function timelineViewport($document, $window) {
var loaded = false; var loaded = false;
// axes and timeline-global variables // axes and timeline-global variables
var y = d3.scale.linear(); var y = d3Scale.scaleLinear();
var absolute = timelineController.axes.absolute; var absolute = timelineController.axes.absolute;
var xSelected = timelineController.axes.selection; var xSelected = timelineController.axes.selection;
var cursorTimeFormat = d3.time.format('%X'); var cursorTimeFormat = d3TimeFormat.timeFormat('%X');
var tickFormat = timelineController.axes.x.tickFormat(); var tickFormat = timelineController.axes.x.tickFormat();
// animation variables // animation variables
var currentViewExtents = null; var currentViewExtents = null;
var viewInterpolator = null; var viewInterpolator = null;
var easeOutCubic = d3.ease('cubic-out'); var easeOutCubic = d3Ease.easeCubicOut;
var easeStartTimestamp = null; var easeStartTimestamp = null;
var easeDuration = 500; var easeDuration = 500;
@ -361,7 +364,7 @@ function timelineViewport($document, $window) {
// make a scale for the position of this region, but shrink it slightly so // make a scale for the position of this region, but shrink it slightly so
// no labels overlap region boundaries and get cut off // no labels overlap region boundaries and get cut off
var tickScale = d3.time.scale().domain([ var tickScale = d3Scale.scaleTime().domain([
absolute.invert(region.x + 10), absolute.invert(region.x + 10),
absolute.invert(region.x + region.width - 10) absolute.invert(region.x + region.width - 10)
]); ]);
@ -613,7 +616,7 @@ function timelineViewport($document, $window) {
if (currentViewExtents) { if (currentViewExtents) {
// if we know where the view is already, try to animate the transition // if we know where the view is already, try to animate the transition
viewInterpolator = d3.interpolate( viewInterpolator = d3Interpolate.interpolateArray(
currentViewExtents, currentViewExtents,
timelineController.viewExtents); timelineController.viewExtents);
easeStartTimestamp = performance.now(); easeStartTimestamp = performance.now();
@ -633,7 +636,7 @@ function timelineViewport($document, $window) {
if (currentViewExtents) { if (currentViewExtents) {
// if we know where the view is already, try to animate the transition // if we know where the view is already, try to animate the transition
viewInterpolator = d3.interpolate( viewInterpolator = d3Interpolate.interpolateArray(
currentViewExtents, currentViewExtents,
timelineController.viewExtents); timelineController.viewExtents);
easeStartTimestamp = performance.now(); easeStartTimestamp = performance.now();

View File

@ -4,7 +4,10 @@ var directivesModule = require('./_index.js');
var arrayUtil = require('../util/array-util'); var arrayUtil = require('../util/array-util');
var parseDstat = require('../util/dstat-parse'); var parseDstat = require('../util/dstat-parse');
var d3 = require('d3');
var d3Array = require('d3-array');
var d3Collection = require('d3-collection');
var d3Scale = require('d3-scale');
var statusColorMap = { var statusColorMap = {
'success': 'LightGreen', 'success': 'LightGreen',
@ -60,14 +63,14 @@ function timeline($window, $log, datasetService, progressService) {
* The primary axis mapping date to on-screen x. The lower time bound maps * The primary axis mapping date to on-screen x. The lower time bound maps
* to x=0, while the upper time bound maps to x=width. * to x=0, while the upper time bound maps to x=width.
*/ */
x: d3.time.scale(), x: d3Scale.scaleTime(),
/** /**
* The selection axis, mapping date to on-screen x, depending on the size * The selection axis, mapping date to on-screen x, depending on the size
* and position of the user selection. `selection(viewExtents[0]) = 0`, * and position of the user selection. `selection(viewExtents[0]) = 0`,
* while `selection(viewExtents[1]) = width` * while `selection(viewExtents[1]) = width`
*/ */
selection: d3.scale.linear(), selection: d3Scale.scaleLinear(),
/** /**
* The absolute x axis mapping date to virtual x, depending only on the * The absolute x axis mapping date to virtual x, depending only on the
@ -76,7 +79,7 @@ function timeline($window, $log, datasetService, progressService) {
* be the total width at the current scale, spanning as many * be the total width at the current scale, spanning as many
* viewport-widths as necessary. * viewport-widths as necessary.
*/ */
absolute: d3.scale.linear() absolute: d3Scale.scaleLinear()
}; };
self.selectionName = null; self.selectionName = null;
@ -88,12 +91,12 @@ function timeline($window, $log, datasetService, progressService) {
self.animateCallbacks = []; self.animateCallbacks = [];
self.setViewExtents = function(extents) { self.setViewExtents = function(extents) {
if (angular.isNumber(extents[0])) { if (extents[0] instanceof Date) {
extents[0] = new Date(extents[0]); extents[0] = +extents[0];
} }
if (angular.isNumber(extents[1])) { if (extents[1] instanceof Date) {
extents[1] = new Date(extents[1]); extents[1] = +extents[1];
} }
var oldSize = self.viewExtents[1] - self.viewExtents[0]; var oldSize = self.viewExtents[1] - self.viewExtents[0];
@ -357,9 +360,9 @@ function timeline($window, $log, datasetService, progressService) {
self.timeExtents = [ minStart, maxEnd ]; self.timeExtents = [ minStart, maxEnd ];
self.data = d3.nest() self.data = d3Collection.nest()
.key(function(d) { return d.worker; }) .key(function(d) { return d.worker; })
.sortKeys(d3.ascending) .sortKeys(d3Array.ascending)
.entries(raw.filter(function(d) { return d.duration > 0; })); .entries(raw.filter(function(d) { return d.duration > 0; }));
self.axes.x.domain(self.timeExtents); self.axes.x.domain(self.timeExtents);
@ -444,18 +447,16 @@ function timeline($window, $log, datasetService, progressService) {
scope.$on('windowResize', updateWidth); scope.$on('windowResize', updateWidth);
updateWidth(); updateWidth();
d3.select(window) $window.addEventListener('keydown', function(evt) {
.on("keydown", function() { if (evt.keyCode === 37) {
var code = d3.event.keyCode;
if (code === 37) {
ctrl.selectPreviousItem(); ctrl.selectPreviousItem();
} }
if (code === 39) { if (evt.keyCode === 39) {
ctrl.selectNextItem(); ctrl.selectNextItem();
} }
scope.$apply(); scope.$apply();
}); });
}; };
return { return {

View File

@ -1,12 +1,16 @@
'use strict'; 'use strict';
var d3 = require('d3');
var filtersModule = require('./_index.js'); var filtersModule = require('./_index.js');
var secondsToTime = function(seconds) { var format = function(value) {
var format = d3.format('02d'); if (value < 10) {
return '0' + value;
} else {
return value.toString();
}
};
var secondsToTime = function(seconds) {
var hours = Math.floor(seconds / 60 / 60); var hours = Math.floor(seconds / 60 / 60);
seconds = seconds - (hours * 60 * 60); seconds = seconds - (hours * 60 * 60);

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var d3 = require("d3"); var timeFormat = require('d3-time-format');
var dsv = require('d3-dsv');
var fillArrayRight = function(array) { var fillArrayRight = function(array) {
@ -37,9 +38,9 @@ var parseDstat = function(data, year) {
// assume UTC - may not necessarily be the case? // assume UTC - may not necessarily be the case?
// dstat doesn't include the year in its logs, so we'll need to copy it // dstat doesn't include the year in its logs, so we'll need to copy it
// from the subunit logs // from the subunit logs
var dateFormat = d3.time.format.utc("%d-%m %H:%M:%S"); var dateFormat = timeFormat.utcParse('%d-%m %H:%M:%S');
var parsed = d3.csv.parseRows(data, function(row, i) { var parsed = dsv.csvParseRows(data, function(row, i) {
if (i === 0) { if (i === 0) {
if (row.length !== 1 || if (row.length !== 1 ||
!row[0].startsWith('Dstat') || !row[0].startsWith('Dstat') ||
@ -64,8 +65,8 @@ var parseDstat = function(data, year) {
var name = names[col]; var name = names[col];
var value = row[col]; var value = row[col];
if (value && name) { if (value && name) {
if (name === "system_time") { if (name === 'system_time') {
value = dateFormat.parse(value); value = dateFormat(value);
value.setFullYear(1900 + year); value.setFullYear(1900 + year);
} else { } else {
value = parseFloat(value); value = parseFloat(value);

View File

@ -19,7 +19,14 @@
"bulk-require": "^0.2.1", "bulk-require": "^0.2.1",
"bulkify": "1.1.1", "bulkify": "1.1.1",
"codemirror": "5.14.2", "codemirror": "5.14.2",
"d3": "^3.5.6", "d3-array": "^0.7.1",
"d3-collection": "^0.2.0",
"d3-dsv": "^0.3.2",
"d3-ease": "^0.7.0",
"d3-interpolate": "^0.7.0",
"d3-request": "^0.4.6",
"d3-scale": "^0.7.0",
"d3-time-format": "^0.3.2",
"del": "2.2.0", "del": "2.2.0",
"eslint": "~1.10.3", "eslint": "~1.10.3",
"eslint-config-openstack": "1.2.4", "eslint-config-openstack": "1.2.4",