From 709e812dbdc7b2e8546a9ec00f906bc1e2e96c7d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 20 Jul 2015 17:13:36 -0700 Subject: [PATCH 001/117] [autorangeSmooth] added the smooth endpoint --- plottable.d.ts | 3 +++ plottable.js | 9 +++++++++ src/plots/xyPlot.ts | 13 +++++++++++++ 3 files changed, 25 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index cabbad8a85..89b74bc8ad 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2590,6 +2590,7 @@ declare module Plottable { class XYPlot extends Plot { protected static _X_KEY: string; protected static _Y_KEY: string; + _autorangeSmooth: boolean; /** * An XYPlot is a Plot that displays data along two primary directions, X and Y. * @@ -2672,6 +2673,8 @@ declare module Plottable { * @returns {XYPlot} The calling XYPlot. */ autorangeMode(autorangeMode: string): XYPlot; + autorangeSmooth(): boolean; + autorangeSmooth(autorangeSmooth: boolean): XYPlot; computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number): XYPlot; /** * Adjusts the domains of both X and Y scales to show all data. diff --git a/plottable.js b/plottable.js index db629a9323..2d23829b9c 100644 --- a/plottable.js +++ b/plottable.js @@ -6692,6 +6692,8 @@ var Plottable; _super.call(this); this._autoAdjustXScaleDomain = false; this._autoAdjustYScaleDomain = false; + // TODO: private + this._autorangeSmooth = false; this._deferredRendering = false; this._cachedDomainX = [null, null]; this._cachedDomainY = [null, null]; @@ -6861,6 +6863,13 @@ var Plottable; } return this; }; + XYPlot.prototype.autorangeSmooth = function (autorangeSmooth) { + if (autorangeSmooth == null) { + return this._autorangeSmooth; + } + this._autorangeSmooth = autorangeSmooth; + return this; + }; XYPlot.prototype.computeLayout = function (origin, availableWidth, availableHeight) { _super.prototype.computeLayout.call(this, origin, availableWidth, availableHeight); var xBinding = this.x(); diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index 0beef6de09..fad2379dc2 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -9,6 +9,9 @@ export class XYPlot extends Plot { private _adjustYDomainOnChangeFromXCallback: ScaleCallback>; private _adjustXDomainOnChangeFromYCallback: ScaleCallback>; + // TODO: private + public _autorangeSmooth = false; + private _deferredRendering = false; private _cachedDomainX: X[] = [null, null]; private _cachedDomainY: Y[] = [null, null]; @@ -284,6 +287,16 @@ export class XYPlot extends Plot { return this; } + public autorangeSmooth(): boolean; + public autorangeSmooth(autorangeSmooth: boolean): XYPlot; + public autorangeSmooth(autorangeSmooth?: boolean): any { + if (autorangeSmooth == null) { + return this._autorangeSmooth; + } + this._autorangeSmooth = autorangeSmooth; + return this; + } + public computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number) { super.computeLayout(origin, availableWidth, availableHeight); var xBinding = this.x(); From 77fb491a7f3a0455855220a0299168bff752c0e3 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 20 Jul 2015 20:10:08 -0700 Subject: [PATCH 002/117] [autorangeSmooth] Hacked first attempt --- plottable.js | 58 ++++++++++++++++++++++++++++++++-- src/plots/plot.ts | 80 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 4 deletions(-) diff --git a/plottable.js b/plottable.js index 2d23829b9c..b3f4adf708 100644 --- a/plottable.js +++ b/plottable.js @@ -6168,17 +6168,71 @@ var Plottable; extents.set(key, this.datasets().map(function (dataset) { return _this._computeExtent(dataset, accScaleBinding, filter); })); }; Plot.prototype._computeExtent = function (dataset, accScaleBinding, filter) { + var _this = this; var accessor = accScaleBinding.accessor; var scale = accScaleBinding.scale; if (scale == null) { return []; } var data = dataset.data(); + // if (filter != null) { + // data = data.filter((d, i) => filter(d, i, dataset)); + // } + var filteredData = []; + var justAdded = false; + var lastValue; if (filter != null) { - data = data.filter(function (d, i) { return filter(d, i, dataset); }); + data.forEach(function (d, i) { + if (filter(d, i, dataset)) { + if (!justAdded && lastValue != null) { + if (_this.x && _this.x().scale && _this.y && _this.y().scale) { + var xScale = _this.x().scale; + var yScale = _this.y().scale; + var leftPoint = xScale.domain()[0]; + var befX = lastValue.x; + var aftX = d.x; + var x1 = leftPoint - befX; + var x2 = aftX - befX; + var y2 = d.y - lastValue.y; + var y1 = x1 * y2 / x2; + filteredData.push({ + x: befX + x1, + y: lastValue.y + y1 + }); + } + } + filteredData.push(d); + justAdded = true; + } + else { + if (justAdded) { + if (_this.x && _this.x().scale && _this.y && _this.y().scale) { + var xScale = _this.x().scale; + var yScale = _this.y().scale; + var rightPoint = xScale.domain()[1]; + var befX = lastValue.x; + var aftX = d.x; + var x1 = rightPoint - befX; + var x2 = aftX - befX; + var y2 = d.y - lastValue.y; + var y1 = x1 * y2 / x2; + filteredData.push({ + x: befX + x1, + y: lastValue.y + y1 + }); + } + } + justAdded = false; + } + lastValue = d; + }); + } + else { + filteredData = data; } var appliedAccessor = function (d, i) { return accessor(d, i, dataset); }; - var mappedData = data.map(appliedAccessor); + var mappedData = filteredData.map(appliedAccessor); + // var mappedData = data.map(appliedAccessor); return scale.extentOfValues(mappedData); }; /** diff --git a/src/plots/plot.ts b/src/plots/plot.ts index f35f98c4ce..7459326c4e 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -299,6 +299,9 @@ export class Plot extends Component { extents.set(key, this.datasets().map((dataset) => this._computeExtent(dataset, accScaleBinding, filter))); } + private _temp1: any; + private _temp2: any; + private _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { var accessor = accScaleBinding.accessor; var scale = accScaleBinding.scale; @@ -308,11 +311,84 @@ export class Plot extends Component { } var data = dataset.data(); + // if (filter != null) { + // data = data.filter((d, i) => filter(d, i, dataset)); + // } + + var filteredData: any[] = []; + + var justAdded = false; + var lastValue: any; + if (filter != null) { - data = data.filter((d, i) => filter(d, i, dataset)); + data.forEach((d, i) => { + if (filter(d, i, dataset)) { + if (!justAdded && lastValue != null) { + + if (this.x && this.x().scale && this.y && this.y().scale) { + + var xScale = this.x().scale; + var yScale = this.y().scale; + + var leftPoint = xScale.domain()[0]; + var befX = lastValue.x; + var aftX = d.x; + + var x1 = leftPoint - befX; + var x2 = aftX - befX; + var y2 = d.y - lastValue.y; + + var y1 = x1 * y2 / x2; + + filteredData.push({ + x: befX + x1, + y: lastValue.y + y1 + }); + } + + // filteredData.push(lastValue); + } + filteredData.push(d); + justAdded = true; + } else { + if (justAdded) { + + if (this.x && this.x().scale && this.y && this.y().scale) { + + var xScale = this.x().scale; + var yScale = this.y().scale; + + var rightPoint = xScale.domain()[1]; + var befX = lastValue.x; + var aftX = d.x; + + var x1 = rightPoint - befX; + var x2 = aftX - befX; + var y2 = d.y - lastValue.y; + + var y1 = x1 * y2 / x2; + + filteredData.push({ + x: befX + x1, + y: lastValue.y + y1 + }); + } + + // filteredData.push(d); + } + justAdded = false; + } + + lastValue = d; + }); + } else { + filteredData = data; } + + var appliedAccessor = (d: any, i: number) => accessor(d, i, dataset); - var mappedData = data.map(appliedAccessor); + var mappedData = filteredData.map(appliedAccessor); + // var mappedData = data.map(appliedAccessor); return scale.extentOfValues(mappedData); } From 7e5fccca74a73f1c1fb2577a469ab428f2a8d987 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 21 Jul 2015 14:58:19 -0700 Subject: [PATCH 003/117] [autorangeSmooth] Removed unused variables --- src/plots/plot.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 7459326c4e..d3fdf95932 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -299,9 +299,6 @@ export class Plot extends Component { extents.set(key, this.datasets().map((dataset) => this._computeExtent(dataset, accScaleBinding, filter))); } - private _temp1: any; - private _temp2: any; - private _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { var accessor = accScaleBinding.accessor; var scale = accScaleBinding.scale; From ab6d929b625a16c74f22fb434b4117dbde958d58 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 22 Jul 2015 12:14:02 -0700 Subject: [PATCH 004/117] [autorangeSmooth] Fixed compilation issues --- plottable.js | 14 ++++++++------ src/plots/plot.ts | 16 ++++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/plottable.js b/plottable.js index 9b2170075b..3dc29b3918 100644 --- a/plottable.js +++ b/plottable.js @@ -6261,9 +6261,10 @@ var Plottable; data.forEach(function (d, i) { if (filter(d, i, dataset)) { if (!justAdded && lastValue != null) { - if (_this.x && _this.x().scale && _this.y && _this.y().scale) { - var xScale = _this.x().scale; - var yScale = _this.y().scale; + var self = _this; + if (self.x && self.x().scale && self.y && self.y().scale) { + var xScale = self.x().scale; + var yScale = self.y().scale; var leftPoint = xScale.domain()[0]; var befX = lastValue.x; var aftX = d.x; @@ -6282,9 +6283,10 @@ var Plottable; } else { if (justAdded) { - if (_this.x && _this.x().scale && _this.y && _this.y().scale) { - var xScale = _this.x().scale; - var yScale = _this.y().scale; + var self = _this; + if (self.x && self.x().scale && self.y && self.y().scale) { + var xScale = self.x().scale; + var yScale = self.y().scale; var rightPoint = xScale.domain()[1]; var befX = lastValue.x; var aftX = d.x; diff --git a/src/plots/plot.ts b/src/plots/plot.ts index d3fdf95932..a4e0bb2df3 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -322,10 +322,12 @@ export class Plot extends Component { if (filter(d, i, dataset)) { if (!justAdded && lastValue != null) { - if (this.x && this.x().scale && this.y && this.y().scale) { + var self = this; - var xScale = this.x().scale; - var yScale = this.y().scale; + if (self.x && self.x().scale && self.y && self.y().scale) { + + var xScale = self.x().scale; + var yScale = self.y().scale; var leftPoint = xScale.domain()[0]; var befX = lastValue.x; @@ -350,10 +352,12 @@ export class Plot extends Component { } else { if (justAdded) { - if (this.x && this.x().scale && this.y && this.y().scale) { + var self = this; + + if (self.x && self.x().scale && self.y && self.y().scale) { - var xScale = this.x().scale; - var yScale = this.y().scale; + var xScale = self.x().scale; + var yScale = self.y().scale; var rightPoint = xScale.domain()[1]; var befX = lastValue.x; From 0f55a380be44e4304be66aa3cfaf4c41dcf11185 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 22 Jul 2015 15:53:27 -0700 Subject: [PATCH 005/117] autorangeSmooth POC --- plottable.js | 132 ++++++++++++++++++++++++-------------- src/plots/plot.ts | 157 ++++++++++++++++++++++++++++++---------------- 2 files changed, 186 insertions(+), 103 deletions(-) diff --git a/plottable.js b/plottable.js index 3dc29b3918..485c4f3e4d 100644 --- a/plottable.js +++ b/plottable.js @@ -6244,70 +6244,106 @@ var Plottable; extents.set(key, this.datasets().map(function (dataset) { return _this._computeExtent(dataset, accScaleBinding, filter); })); }; Plot.prototype._computeExtent = function (dataset, accScaleBinding, filter) { - var _this = this; var accessor = accScaleBinding.accessor; var scale = accScaleBinding.scale; if (scale == null) { return []; } var data = dataset.data(); - // if (filter != null) { - // data = data.filter((d, i) => filter(d, i, dataset)); - // } var filteredData = []; + ; + if (filter != null) { + filteredData = data.filter(function (d, i) { return filter(d, i, dataset); }); + } var justAdded = false; var lastValue; - if (filter != null) { + var self = this; + if (self.x && self.x().scale && self.y && self.y().scale) { + var westOfLeft; + var westOfRight; + var left = self.x().scale.domain()[0]; + var right = self.x().scale.domain()[1]; + var lastValue; data.forEach(function (d, i) { - if (filter(d, i, dataset)) { - if (!justAdded && lastValue != null) { - var self = _this; - if (self.x && self.x().scale && self.y && self.y().scale) { - var xScale = self.x().scale; - var yScale = self.y().scale; - var leftPoint = xScale.domain()[0]; - var befX = lastValue.x; - var aftX = d.x; - var x1 = leftPoint - befX; - var x2 = aftX - befX; - var y2 = d.y - lastValue.y; - var y1 = x1 * y2 / x2; - filteredData.push({ - x: befX + x1, - y: lastValue.y + y1 - }); - } + if (lastValue) { + // console.log(lastValue.x, d.x); + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + var x1 = left - lastValue.x; + var x2 = d.x - lastValue.x; + var y2 = d.y - lastValue.y; + var y1 = x1 * y2 / x2; + filteredData.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); } - filteredData.push(d); - justAdded = true; - } - else { - if (justAdded) { - var self = _this; - if (self.x && self.x().scale && self.y && self.y().scale) { - var xScale = self.x().scale; - var yScale = self.y().scale; - var rightPoint = xScale.domain()[1]; - var befX = lastValue.x; - var aftX = d.x; - var x1 = rightPoint - befX; - var x2 = aftX - befX; - var y2 = d.y - lastValue.y; - var y1 = x1 * y2 / x2; - filteredData.push({ - x: befX + x1, - y: lastValue.y + y1 - }); - } + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + var x1 = right - lastValue.x; + var x2 = d.x - lastValue.x; + var y2 = d.y - lastValue.y; + var y1 = x1 * y2 / x2; + filteredData.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); } - justAdded = false; } + westOfLeft = d.x < left; + westOfRight = d.x < right; lastValue = d; }); } - else { - filteredData = data; - } + // if (filter != null) { + // data.forEach((d, i) => { + // if (filter(d, i, dataset)) { + // if (!justAdded && lastValue != null) { + // var self = this; + // if (self.x && self.x().scale && self.y && self.y().scale) { + // var xScale = self.x().scale; + // var yScale = self.y().scale; + // var leftPoint = xScale.domain()[0]; + // var befX = lastValue.x; + // var aftX = d.x; + // var x1 = leftPoint - befX; + // var x2 = aftX - befX; + // var y2 = d.y - lastValue.y; + // var y1 = x1 * y2 / x2; + // filteredData.push({ + // x: befX + x1, + // y: lastValue.y + y1 + // }); + // } + // // filteredData.push(lastValue); + // } + // filteredData.push(d); + // justAdded = true; + // } else { + // if (justAdded) { + // var self = this; + // if (self.x && self.x().scale && self.y && self.y().scale) { + // var xScale = self.x().scale; + // var yScale = self.y().scale; + // var rightPoint = xScale.domain()[1]; + // var befX = lastValue.x; + // var aftX = d.x; + // var x1 = rightPoint - befX; + // var x2 = aftX - befX; + // var y2 = d.y - lastValue.y; + // var y1 = x1 * y2 / x2; + // filteredData.push({ + // x: befX + x1, + // y: lastValue.y + y1 + // }); + // } + // // filteredData.push(d); + // } + // justAdded = false; + // } + // lastValue = d; + // }); + // } else { + // filteredData = data; + // } var appliedAccessor = function (d, i) { return accessor(d, i, dataset); }; var mappedData = filteredData.map(appliedAccessor); // var mappedData = data.map(appliedAccessor); diff --git a/src/plots/plot.ts b/src/plots/plot.ts index a4e0bb2df3..ef3aa9528d 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -308,83 +308,130 @@ export class Plot extends Component { } var data = dataset.data(); - // if (filter != null) { - // data = data.filter((d, i) => filter(d, i, dataset)); - // } - - var filteredData: any[] = []; + var filteredData: any[] = [];; + if (filter != null) { + filteredData = data.filter((d, i) => filter(d, i, dataset)); + } var justAdded = false; var lastValue: any; - if (filter != null) { - data.forEach((d, i) => { - if (filter(d, i, dataset)) { - if (!justAdded && lastValue != null) { - var self = this; + var self = this; + if (self.x && self.x().scale && self.y && self.y().scale) { + var westOfLeft: boolean; + var westOfRight: boolean; + var left = self.x().scale.domain()[0]; + var right = self.x().scale.domain()[1]; - if (self.x && self.x().scale && self.y && self.y().scale) { + var lastValue: any; + data.forEach((d, i) => { - var xScale = self.x().scale; - var yScale = self.y().scale; + if (lastValue) { - var leftPoint = xScale.domain()[0]; - var befX = lastValue.x; - var aftX = d.x; + // console.log(lastValue.x, d.x); + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - var x1 = leftPoint - befX; - var x2 = aftX - befX; - var y2 = d.y - lastValue.y; + var x1 = left - lastValue.x; + var x2 = d.x - lastValue.x; + var y2 = d.y - lastValue.y; + var y1 = x1 * y2 / x2; - var y1 = x1 * y2 / x2; + filteredData.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } - filteredData.push({ - x: befX + x1, - y: lastValue.y + y1 - }); - } + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + var x1 = right - lastValue.x; + var x2 = d.x - lastValue.x; + var y2 = d.y - lastValue.y; + var y1 = x1 * y2 / x2; - // filteredData.push(lastValue); + filteredData.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); } - filteredData.push(d); - justAdded = true; - } else { - if (justAdded) { - var self = this; + } - if (self.x && self.x().scale && self.y && self.y().scale) { + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; - var xScale = self.x().scale; - var yScale = self.y().scale; + }); + } - var rightPoint = xScale.domain()[1]; - var befX = lastValue.x; - var aftX = d.x; + // if (filter != null) { + // data.forEach((d, i) => { + // if (filter(d, i, dataset)) { + // if (!justAdded && lastValue != null) { - var x1 = rightPoint - befX; - var x2 = aftX - befX; - var y2 = d.y - lastValue.y; + // var self = this; - var y1 = x1 * y2 / x2; + // if (self.x && self.x().scale && self.y && self.y().scale) { - filteredData.push({ - x: befX + x1, - y: lastValue.y + y1 - }); - } + // var xScale = self.x().scale; + // var yScale = self.y().scale; - // filteredData.push(d); - } - justAdded = false; - } + // var leftPoint = xScale.domain()[0]; + // var befX = lastValue.x; + // var aftX = d.x; - lastValue = d; - }); - } else { - filteredData = data; - } + // var x1 = leftPoint - befX; + // var x2 = aftX - befX; + // var y2 = d.y - lastValue.y; + + // var y1 = x1 * y2 / x2; + + // filteredData.push({ + // x: befX + x1, + // y: lastValue.y + y1 + // }); + // } + + // // filteredData.push(lastValue); + // } + // filteredData.push(d); + // justAdded = true; + // } else { + // if (justAdded) { + + // var self = this; + + // if (self.x && self.x().scale && self.y && self.y().scale) { + + // var xScale = self.x().scale; + // var yScale = self.y().scale; + + // var rightPoint = xScale.domain()[1]; + // var befX = lastValue.x; + // var aftX = d.x; + + // var x1 = rightPoint - befX; + // var x2 = aftX - befX; + // var y2 = d.y - lastValue.y; + + // var y1 = x1 * y2 / x2; + + // filteredData.push({ + // x: befX + x1, + // y: lastValue.y + y1 + // }); + // } + + // // filteredData.push(d); + // } + // justAdded = false; + // } + + // lastValue = d; + // }); + // } else { + // filteredData = data; + // } var appliedAccessor = (d: any, i: number) => accessor(d, i, dataset); From a2c2bbd4f2513990a009b9d2b60af5c51a88df17 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 22 Jul 2015 16:16:58 -0700 Subject: [PATCH 006/117] [autorangeSmoot] Better code --- plottable.js | 76 ++++++---------------------------- src/plots/plot.ts | 101 ++++++---------------------------------------- 2 files changed, 25 insertions(+), 152 deletions(-) diff --git a/plottable.js b/plottable.js index 485c4f3e4d..31e39e0704 100644 --- a/plottable.js +++ b/plottable.js @@ -6251,12 +6251,9 @@ var Plottable; } var data = dataset.data(); var filteredData = []; - ; if (filter != null) { filteredData = data.filter(function (d, i) { return filter(d, i, dataset); }); } - var justAdded = false; - var lastValue; var self = this; if (self.x && self.x().scale && self.y && self.y().scale) { var westOfLeft; @@ -6265,23 +6262,26 @@ var Plottable; var right = self.x().scale.domain()[1]; var lastValue; data.forEach(function (d, i) { + var x1; + var x2; + var y1; + var y2; if (lastValue) { - // console.log(lastValue.x, d.x); if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - var x1 = left - lastValue.x; - var x2 = d.x - lastValue.x; - var y2 = d.y - lastValue.y; - var y1 = x1 * y2 / x2; + x1 = left - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; filteredData.push({ x: lastValue.x + x1, y: lastValue.y + y1 }); } if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - var x1 = right - lastValue.x; - var x2 = d.x - lastValue.x; - var y2 = d.y - lastValue.y; - var y1 = x1 * y2 / x2; + x1 = right - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; filteredData.push({ x: lastValue.x + x1, y: lastValue.y + y1 @@ -6293,60 +6293,8 @@ var Plottable; lastValue = d; }); } - // if (filter != null) { - // data.forEach((d, i) => { - // if (filter(d, i, dataset)) { - // if (!justAdded && lastValue != null) { - // var self = this; - // if (self.x && self.x().scale && self.y && self.y().scale) { - // var xScale = self.x().scale; - // var yScale = self.y().scale; - // var leftPoint = xScale.domain()[0]; - // var befX = lastValue.x; - // var aftX = d.x; - // var x1 = leftPoint - befX; - // var x2 = aftX - befX; - // var y2 = d.y - lastValue.y; - // var y1 = x1 * y2 / x2; - // filteredData.push({ - // x: befX + x1, - // y: lastValue.y + y1 - // }); - // } - // // filteredData.push(lastValue); - // } - // filteredData.push(d); - // justAdded = true; - // } else { - // if (justAdded) { - // var self = this; - // if (self.x && self.x().scale && self.y && self.y().scale) { - // var xScale = self.x().scale; - // var yScale = self.y().scale; - // var rightPoint = xScale.domain()[1]; - // var befX = lastValue.x; - // var aftX = d.x; - // var x1 = rightPoint - befX; - // var x2 = aftX - befX; - // var y2 = d.y - lastValue.y; - // var y1 = x1 * y2 / x2; - // filteredData.push({ - // x: befX + x1, - // y: lastValue.y + y1 - // }); - // } - // // filteredData.push(d); - // } - // justAdded = false; - // } - // lastValue = d; - // }); - // } else { - // filteredData = data; - // } var appliedAccessor = function (d, i) { return accessor(d, i, dataset); }; var mappedData = filteredData.map(appliedAccessor); - // var mappedData = data.map(appliedAccessor); return scale.extentOfValues(mappedData); }; /** diff --git a/src/plots/plot.ts b/src/plots/plot.ts index ef3aa9528d..dfb91eebaf 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -308,15 +308,11 @@ export class Plot extends Component { } var data = dataset.data(); - var filteredData: any[] = [];; + var filteredData: any[] = []; if (filter != null) { filteredData = data.filter((d, i) => filter(d, i, dataset)); } - var justAdded = false; - var lastValue: any; - - var self = this; if (self.x && self.x().scale && self.y && self.y().scale) { var westOfLeft: boolean; @@ -326,16 +322,17 @@ export class Plot extends Component { var lastValue: any; data.forEach((d, i) => { - + var x1: any; + var x2: any; + var y1: any; + var y2: any; if (lastValue) { - - // console.log(lastValue.x, d.x); if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - var x1 = left - lastValue.x; - var x2 = d.x - lastValue.x; - var y2 = d.y - lastValue.y; - var y1 = x1 * y2 / x2; + x1 = left - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; filteredData.push({ x: lastValue.x + x1, @@ -344,17 +341,16 @@ export class Plot extends Component { } if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - var x1 = right - lastValue.x; - var x2 = d.x - lastValue.x; - var y2 = d.y - lastValue.y; - var y1 = x1 * y2 / x2; + x1 = right - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; filteredData.push({ x: lastValue.x + x1, y: lastValue.y + y1 }); } - } westOfLeft = d.x < left; @@ -364,79 +360,8 @@ export class Plot extends Component { }); } - // if (filter != null) { - // data.forEach((d, i) => { - // if (filter(d, i, dataset)) { - // if (!justAdded && lastValue != null) { - - // var self = this; - - // if (self.x && self.x().scale && self.y && self.y().scale) { - - // var xScale = self.x().scale; - // var yScale = self.y().scale; - - // var leftPoint = xScale.domain()[0]; - // var befX = lastValue.x; - // var aftX = d.x; - - // var x1 = leftPoint - befX; - // var x2 = aftX - befX; - // var y2 = d.y - lastValue.y; - - // var y1 = x1 * y2 / x2; - - // filteredData.push({ - // x: befX + x1, - // y: lastValue.y + y1 - // }); - // } - - // // filteredData.push(lastValue); - // } - // filteredData.push(d); - // justAdded = true; - // } else { - // if (justAdded) { - - // var self = this; - - // if (self.x && self.x().scale && self.y && self.y().scale) { - - // var xScale = self.x().scale; - // var yScale = self.y().scale; - - // var rightPoint = xScale.domain()[1]; - // var befX = lastValue.x; - // var aftX = d.x; - - // var x1 = rightPoint - befX; - // var x2 = aftX - befX; - // var y2 = d.y - lastValue.y; - - // var y1 = x1 * y2 / x2; - - // filteredData.push({ - // x: befX + x1, - // y: lastValue.y + y1 - // }); - // } - - // // filteredData.push(d); - // } - // justAdded = false; - // } - - // lastValue = d; - // }); - // } else { - // filteredData = data; - // } - - var appliedAccessor = (d: any, i: number) => accessor(d, i, dataset); var mappedData = filteredData.map(appliedAccessor); - // var mappedData = data.map(appliedAccessor); return scale.extentOfValues(mappedData); } From 4e4992885eaf5dea4600d21ce386542796a5a618 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 10:03:49 -0700 Subject: [PATCH 007/117] [autorangeSmooth] Moved the autorange to its place --- plottable.js | 125 ++++++++++++++++++++++++++++++-------------- src/plots/plot.ts | 92 ++++++++++++++++---------------- src/plots/xyPlot.ts | 69 ++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 85 deletions(-) diff --git a/plottable.js b/plottable.js index 31e39e0704..5366d88121 100644 --- a/plottable.js +++ b/plottable.js @@ -6254,45 +6254,45 @@ var Plottable; if (filter != null) { filteredData = data.filter(function (d, i) { return filter(d, i, dataset); }); } - var self = this; - if (self.x && self.x().scale && self.y && self.y().scale) { - var westOfLeft; - var westOfRight; - var left = self.x().scale.domain()[0]; - var right = self.x().scale.domain()[1]; - var lastValue; - data.forEach(function (d, i) { - var x1; - var x2; - var y1; - var y2; - if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - x1 = left - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - filteredData.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - filteredData.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - } - westOfLeft = d.x < left; - westOfRight = d.x < right; - lastValue = d; - }); - } + // var self = this; + // if (self.x && self.x().scale && self.y && self.y().scale) { + // var westOfLeft: boolean; + // var westOfRight: boolean; + // var left = self.x().scale.domain()[0]; + // var right = self.x().scale.domain()[1]; + // var lastValue: any; + // data.forEach((d, i) => { + // var x1: any; + // var x2: any; + // var y1: any; + // var y2: any; + // if (lastValue) { + // if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + // x1 = left - lastValue.x; + // x2 = d.x - lastValue.x; + // y2 = d.y - lastValue.y; + // y1 = x1 * y2 / x2; + // filteredData.push({ + // x: lastValue.x + x1, + // y: lastValue.y + y1 + // }); + // } + // if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + // x1 = right - lastValue.x; + // x2 = d.x - lastValue.x; + // y2 = d.y - lastValue.y; + // y1 = x1 * y2 / x2; + // filteredData.push({ + // x: lastValue.x + x1, + // y: lastValue.y + y1 + // }); + // } + // } + // westOfLeft = d.x < left; + // westOfRight = d.x < right; + // lastValue = d; + // }); + // } var appliedAccessor = function (d, i) { return accessor(d, i, dataset); }; var mappedData = filteredData.map(appliedAccessor); return scale.extentOfValues(mappedData); @@ -7050,6 +7050,53 @@ var Plottable; return; } if (this._autoAdjustYScaleDomain) { + if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + if (this._yDomainChangeIncludedValues) { + this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + var data = this.datasets()[0].data(); + var includedValues = []; + var westOfLeft; + var westOfRight; + var left = this.x().scale.domain()[0]; + var right = this.x().scale.domain()[1]; + var lastValue; + data.forEach(function (d, i) { + var x1; + var x2; + var y1; + var y2; + if (lastValue) { + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + x1 = left - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + x1 = right - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + } + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; + }); + includedValues = includedValues.map(function (d) { return d.y; }); + console.log(includedValues); + this._yDomainChangeIncludedValues = function () { return includedValues; }; + this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + } this._updateYExtentsAndAutodomain(); } }; diff --git a/src/plots/plot.ts b/src/plots/plot.ts index dfb91eebaf..14b86a0a38 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -313,52 +313,52 @@ export class Plot extends Component { filteredData = data.filter((d, i) => filter(d, i, dataset)); } - var self = this; - if (self.x && self.x().scale && self.y && self.y().scale) { - var westOfLeft: boolean; - var westOfRight: boolean; - var left = self.x().scale.domain()[0]; - var right = self.x().scale.domain()[1]; - - var lastValue: any; - data.forEach((d, i) => { - var x1: any; - var x2: any; - var y1: any; - var y2: any; - if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - - x1 = left - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - - filteredData.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - - filteredData.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - } - - westOfLeft = d.x < left; - westOfRight = d.x < right; - lastValue = d; - - }); - } + // var self = this; + // if (self.x && self.x().scale && self.y && self.y().scale) { + // var westOfLeft: boolean; + // var westOfRight: boolean; + // var left = self.x().scale.domain()[0]; + // var right = self.x().scale.domain()[1]; + + // var lastValue: any; + // data.forEach((d, i) => { + // var x1: any; + // var x2: any; + // var y1: any; + // var y2: any; + // if (lastValue) { + // if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + + // x1 = left - lastValue.x; + // x2 = d.x - lastValue.x; + // y2 = d.y - lastValue.y; + // y1 = x1 * y2 / x2; + + // filteredData.push({ + // x: lastValue.x + x1, + // y: lastValue.y + y1 + // }); + // } + + // if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + // x1 = right - lastValue.x; + // x2 = d.x - lastValue.x; + // y2 = d.y - lastValue.y; + // y1 = x1 * y2 / x2; + + // filteredData.push({ + // x: lastValue.x + x1, + // y: lastValue.y + y1 + // }); + // } + // } + + // westOfLeft = d.x < left; + // westOfRight = d.x < right; + // lastValue = d; + + // }); + // } var appliedAccessor = (d: any, i: number) => accessor(d, i, dataset); var mappedData = filteredData.map(appliedAccessor); diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index fad2379dc2..2593929e15 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -344,9 +344,78 @@ export class XYPlot extends Plot { return this; } + + private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; + private _adjustYDomainOnChangeFromX() { if (!this._projectorsReady()) { return; } + if (this._autoAdjustYScaleDomain) { + + if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + + if (this._yDomainChangeIncludedValues) { + this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + + var data = this.datasets()[0].data(); + + var includedValues: any[] = []; + + var westOfLeft: boolean; + var westOfRight: boolean; + var left = this.x().scale.domain()[0]; + var right = this.x().scale.domain()[1]; + + var lastValue: any; + data.forEach((d, i) => { + var x1: any; + var x2: any; + var y1: any; + var y2: any; + if (lastValue) { + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + + x1 = left - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + x1 = right - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + } + + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; + }); + + includedValues = includedValues.map((d) => d.y); + + console.log(includedValues); + + + this._yDomainChangeIncludedValues = () => includedValues; + this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + + + } + this._updateYExtentsAndAutodomain(); } } From c3d9f00300d928d4287d6dcd41d753219ed57741 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 10:15:21 -0700 Subject: [PATCH 008/117] [autorangeSmoot] Extracted the code into its own method --- plottable.js | 97 +++++++++++++++++++------------------ src/plots/xyPlot.ts | 113 +++++++++++++++++++++++--------------------- 2 files changed, 109 insertions(+), 101 deletions(-) diff --git a/plottable.js b/plottable.js index 5366d88121..d9cafb41c8 100644 --- a/plottable.js +++ b/plottable.js @@ -7050,56 +7050,59 @@ var Plottable; return; } if (this._autoAdjustYScaleDomain) { - if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - if (this._yDomainChangeIncludedValues) { - this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); - } - var data = this.datasets()[0].data(); - var includedValues = []; - var westOfLeft; - var westOfRight; - var left = this.x().scale.domain()[0]; - var right = this.x().scale.domain()[1]; - var lastValue; - data.forEach(function (d, i) { - var x1; - var x2; - var y1; - var y2; - if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - x1 = left - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - } - westOfLeft = d.x < left; - westOfRight = d.x < right; - lastValue = d; - }); - includedValues = includedValues.map(function (d) { return d.y; }); - console.log(includedValues); - this._yDomainChangeIncludedValues = function () { return includedValues; }; - this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); - } + this._ownMethod(); this._updateYExtentsAndAutodomain(); } }; + XYPlot.prototype._ownMethod = function () { + if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + if (this._yDomainChangeIncludedValues) { + this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + var data = this.datasets()[0].data(); + var includedValues = []; + var westOfLeft; + var westOfRight; + var left = this.x().scale.domain()[0]; + var right = this.x().scale.domain()[1]; + var lastValue; + data.forEach(function (d, i) { + var x1; + var x2; + var y1; + var y2; + if (lastValue) { + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + x1 = left - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + x1 = right - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + } + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; + }); + includedValues = includedValues.map(function (d) { return d.y; }); + console.log(includedValues); + this._yDomainChangeIncludedValues = function () { return includedValues; }; + this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + }; XYPlot.prototype._adjustXDomainOnChangeFromY = function () { if (!this._projectorsReady()) { return; diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index 2593929e15..897d20dbc6 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -351,74 +351,79 @@ export class XYPlot extends Plot { if (!this._projectorsReady()) { return; } if (this._autoAdjustYScaleDomain) { + this._ownMethod(); - if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + this._updateYExtentsAndAutodomain(); + } + } - if (this._yDomainChangeIncludedValues) { - this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); - } + private _ownMethod() { + if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - var data = this.datasets()[0].data(); - - var includedValues: any[] = []; - - var westOfLeft: boolean; - var westOfRight: boolean; - var left = this.x().scale.domain()[0]; - var right = this.x().scale.domain()[1]; - - var lastValue: any; - data.forEach((d, i) => { - var x1: any; - var x2: any; - var y1: any; - var y2: any; - if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - - x1 = left - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } + if (this._yDomainChangeIncludedValues) { + this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + + var data = this.datasets()[0].data(); + + var includedValues: any[] = []; + + var westOfLeft: boolean; + var westOfRight: boolean; + var left = this.x().scale.domain()[0]; + var right = this.x().scale.domain()[1]; + + var lastValue: any; + data.forEach((d, i) => { + var x1: any; + var x2: any; + var y1: any; + var y2: any; + if (lastValue) { + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + + x1 = left - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); } - westOfLeft = d.x < left; - westOfRight = d.x < right; - lastValue = d; - }); + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + x1 = right - lastValue.x; + x2 = d.x - lastValue.x; + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; - includedValues = includedValues.map((d) => d.y); + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + } - console.log(includedValues); + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; + }); + includedValues = includedValues.map((d) => d.y); - this._yDomainChangeIncludedValues = () => includedValues; - this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + console.log(includedValues); - } + this._yDomainChangeIncludedValues = () => includedValues; + this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + - this._updateYExtentsAndAutodomain(); } } + + private _adjustXDomainOnChangeFromY() { if (!this._projectorsReady()) { return; } if (this._autoAdjustXScaleDomain) { From 53c0f1d3af1f1b6b59f4307d1fa283277aa05ecb Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 13:52:58 -0700 Subject: [PATCH 009/117] [autorangeSmooth] Moved everything to the line plot --- plottable.d.ts | 1 + plottable.js | 111 +++++++++++++++++++++++------------------- src/plots/linePlot.ts | 82 +++++++++++++++++++++++++++++++ src/plots/xyPlot.ts | 72 --------------------------- 4 files changed, 144 insertions(+), 122 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 89b74bc8ad..f88ba8f8e2 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2981,6 +2981,7 @@ declare module Plottable { */ constructor(); protected _createDrawer(dataset: Dataset): Drawer; + protected _updateExtentsForProperty(property: string): void; protected _getResetYFunction(): (d: any, i: number, dataset: Dataset) => number; protected _generateDrawSteps(): Drawers.DrawStep[]; protected _generateAttrToProjector(): { diff --git a/plottable.js b/plottable.js index d9cafb41c8..71dd04ae91 100644 --- a/plottable.js +++ b/plottable.js @@ -7050,59 +7050,9 @@ var Plottable; return; } if (this._autoAdjustYScaleDomain) { - this._ownMethod(); this._updateYExtentsAndAutodomain(); } }; - XYPlot.prototype._ownMethod = function () { - if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - if (this._yDomainChangeIncludedValues) { - this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); - } - var data = this.datasets()[0].data(); - var includedValues = []; - var westOfLeft; - var westOfRight; - var left = this.x().scale.domain()[0]; - var right = this.x().scale.domain()[1]; - var lastValue; - data.forEach(function (d, i) { - var x1; - var x2; - var y1; - var y2; - if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - x1 = left - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - } - westOfLeft = d.x < left; - westOfRight = d.x < right; - lastValue = d; - }); - includedValues = includedValues.map(function (d) { return d.y; }); - console.log(includedValues); - this._yDomainChangeIncludedValues = function () { return includedValues; }; - this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); - } - }; XYPlot.prototype._adjustXDomainOnChangeFromY = function () { if (!this._projectorsReady()) { return; @@ -8015,6 +7965,67 @@ var Plottable; Line.prototype._createDrawer = function (dataset) { return new Plottable.Drawers.Line(dataset); }; + Line.prototype._updateExtentsForProperty = function (property) { + if (property === "y") { + this._ownMethod(); + } + _super.prototype._updateExtentsForProperty.call(this, property); + }; + Line.prototype._ownMethod = function () { + if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + var changedScale = this.y().scale; + var changedAccessor = this.y().accessor; + var adjustingScale = this.x().scale; + var adjustingAccessor = this.x().accessor; + if (this._yDomainChangeIncludedValues) { + changedScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + var includedValues = []; + this.datasets().forEach(function (dataset) { + var data = dataset.data(); + var westOfLeft; + var westOfRight; + var left = adjustingScale.domain()[0]; + var right = adjustingScale.domain()[1]; + var lastValue; + data.forEach(function (d, i) { + var x1; + var x2; + var y1; + var y2; + if (lastValue) { + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + x1 = left - adjustingAccessor(lastValue, i - 1, dataset); + x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); + y2 = changedAccessor(d, i, dataset) - changedAccessor(lastValue, i - 1, dataset); + y1 = x1 * y2 / x2; + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + x1 = right - adjustingAccessor(lastValue, i - 1, dataset); + x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + } + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; + }); + }); + includedValues = includedValues.map(function (d) { return d.y; }); + console.log(includedValues); + this._yDomainChangeIncludedValues = function () { return includedValues; }; + changedScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + }; Line.prototype._getResetYFunction = function () { // gets the y-value generator for the animation start point var yDomain = this.y().scale.domain(); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index bb73e257c1..5d0e1211c7 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -25,6 +25,88 @@ export module Plots { return new Plottable.Drawers.Line(dataset); } + protected _updateExtentsForProperty(property: string) { + + if (property === "y") { + this._ownMethod(); + } + super._updateExtentsForProperty(property); + } + + + private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; + + private _ownMethod() { + if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + + var changedScale = this.y().scale; + var changedAccessor = this.y().accessor; + + var adjustingScale = this.x().scale; + var adjustingAccessor = this.x().accessor; + + if (this._yDomainChangeIncludedValues) { + changedScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + + var includedValues: any[] = []; + this.datasets().forEach((dataset) => { + + var data = dataset.data(); + + var westOfLeft: boolean; + var westOfRight: boolean; + var left = adjustingScale.domain()[0]; + var right = adjustingScale.domain()[1]; + + var lastValue: any; + data.forEach((d, i) => { + var x1: any; + var x2: any; + var y1: any; + var y2: any; + if (lastValue) { + if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + + x1 = left - adjustingAccessor(lastValue, i - 1, dataset); + x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); + y2 = changedAccessor(d, i, dataset) - changedAccessor(lastValue, i - 1, dataset); + y1 = x1 * y2 / x2; + + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + + if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { + x1 = right - adjustingAccessor(lastValue, i - 1, dataset); + x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); + y2 = d.y - lastValue.y; + y1 = x1 * y2 / x2; + + includedValues.push({ + x: lastValue.x + x1, + y: lastValue.y + y1 + }); + } + } + + westOfLeft = d.x < left; + westOfRight = d.x < right; + lastValue = d; + }); + }); + + includedValues = includedValues.map((d) => d.y); + + console.log(includedValues); + + this._yDomainChangeIncludedValues = () => includedValues; + changedScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + } + protected _getResetYFunction() { // gets the y-value generator for the animation start point var yDomain = this.y().scale.domain(); diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index 897d20dbc6..29ae96d6c9 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -344,86 +344,14 @@ export class XYPlot extends Plot { return this; } - - private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; - private _adjustYDomainOnChangeFromX() { if (!this._projectorsReady()) { return; } if (this._autoAdjustYScaleDomain) { - this._ownMethod(); - this._updateYExtentsAndAutodomain(); } } - private _ownMethod() { - if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - - if (this._yDomainChangeIncludedValues) { - this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); - } - - var data = this.datasets()[0].data(); - - var includedValues: any[] = []; - - var westOfLeft: boolean; - var westOfRight: boolean; - var left = this.x().scale.domain()[0]; - var right = this.x().scale.domain()[1]; - - var lastValue: any; - data.forEach((d, i) => { - var x1: any; - var x2: any; - var y1: any; - var y2: any; - if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - - x1 = left - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - lastValue.x; - x2 = d.x - lastValue.x; - y2 = d.y - lastValue.y; - y1 = x1 * y2 / x2; - - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); - } - } - - westOfLeft = d.x < left; - westOfRight = d.x < right; - lastValue = d; - }); - - includedValues = includedValues.map((d) => d.y); - - console.log(includedValues); - - - this._yDomainChangeIncludedValues = () => includedValues; - this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); - - - } - } - - private _adjustXDomainOnChangeFromY() { if (!this._projectorsReady()) { return; } if (this._autoAdjustXScaleDomain) { From ea95d062606c37ea7252e4aec56f812d795b6f86 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 14:06:24 -0700 Subject: [PATCH 010/117] [autorangeSmooth] Preparing to leave data space --- plottable.js | 29 ++++++++++++++++------------- src/plots/linePlot.ts | 31 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/plottable.js b/plottable.js index 71dd04ae91..530bb214cd 100644 --- a/plottable.js +++ b/plottable.js @@ -7973,20 +7973,20 @@ var Plottable; }; Line.prototype._ownMethod = function () { if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - var changedScale = this.y().scale; - var changedAccessor = this.y().accessor; - var adjustingScale = this.x().scale; - var adjustingAccessor = this.x().accessor; + var yScale = this.y().scale; + var yAccessor = this.y().accessor; + var xScale = this.x().scale; + var xAccessor = this.x().accessor; if (this._yDomainChangeIncludedValues) { - changedScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + yScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } var includedValues = []; this.datasets().forEach(function (dataset) { var data = dataset.data(); var westOfLeft; var westOfRight; - var left = adjustingScale.domain()[0]; - var right = adjustingScale.domain()[1]; + var left = xScale.domain()[0]; + var right = xScale.domain()[1]; var lastValue; data.forEach(function (d, i) { var x1; @@ -7995,9 +7995,9 @@ var Plottable; var y2; if (lastValue) { if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - x1 = left - adjustingAccessor(lastValue, i - 1, dataset); - x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); - y2 = changedAccessor(d, i, dataset) - changedAccessor(lastValue, i - 1, dataset); + x1 = left - xAccessor(lastValue, i - 1, dataset); + x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); + y2 = yAccessor(d, i, dataset) - yAccessor(lastValue, i - 1, dataset); y1 = x1 * y2 / x2; includedValues.push({ x: lastValue.x + x1, @@ -8005,8 +8005,8 @@ var Plottable; }); } if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - adjustingAccessor(lastValue, i - 1, dataset); - x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); + x1 = right - xAccessor(lastValue, i - 1, dataset); + x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); y2 = d.y - lastValue.y; y1 = x1 * y2 / x2; includedValues.push({ @@ -8023,9 +8023,12 @@ var Plottable; includedValues = includedValues.map(function (d) { return d.y; }); console.log(includedValues); this._yDomainChangeIncludedValues = function () { return includedValues; }; - changedScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } }; + Line.prototype._endOfDomainValues = function () { + return []; + }; Line.prototype._getResetYFunction = function () { // gets the y-value generator for the animation start point var yDomain = this.y().scale.domain(); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 5d0e1211c7..310468438d 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -26,7 +26,6 @@ export module Plots { } protected _updateExtentsForProperty(property: string) { - if (property === "y") { this._ownMethod(); } @@ -39,14 +38,14 @@ export module Plots { private _ownMethod() { if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - var changedScale = this.y().scale; - var changedAccessor = this.y().accessor; + var yScale = this.y().scale; + var yAccessor = this.y().accessor; - var adjustingScale = this.x().scale; - var adjustingAccessor = this.x().accessor; + var xScale = >this.x().scale; + var xAccessor = this.x().accessor; if (this._yDomainChangeIncludedValues) { - changedScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + yScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } var includedValues: any[] = []; @@ -56,8 +55,8 @@ export module Plots { var westOfLeft: boolean; var westOfRight: boolean; - var left = adjustingScale.domain()[0]; - var right = adjustingScale.domain()[1]; + var left = xScale.domain()[0]; + var right = xScale.domain()[1]; var lastValue: any; data.forEach((d, i) => { @@ -68,9 +67,9 @@ export module Plots { if (lastValue) { if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - x1 = left - adjustingAccessor(lastValue, i - 1, dataset); - x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); - y2 = changedAccessor(d, i, dataset) - changedAccessor(lastValue, i - 1, dataset); + x1 = left - xAccessor(lastValue, i - 1, dataset); + x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); + y2 = yAccessor(d, i, dataset) - yAccessor(lastValue, i - 1, dataset); y1 = x1 * y2 / x2; includedValues.push({ @@ -80,8 +79,8 @@ export module Plots { } if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - adjustingAccessor(lastValue, i - 1, dataset); - x2 = adjustingAccessor(d, i, dataset) - adjustingAccessor(lastValue, i - 1, dataset); + x1 = right - xAccessor(lastValue, i - 1, dataset); + x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); y2 = d.y - lastValue.y; y1 = x1 * y2 / x2; @@ -103,10 +102,14 @@ export module Plots { console.log(includedValues); this._yDomainChangeIncludedValues = () => includedValues; - changedScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } } + private _endOfDomainValues(): X|number[][] { + return []; + } + protected _getResetYFunction() { // gets the y-value generator for the animation start point var yDomain = this.y().scale.domain(); From 09577fc442af3502876e7a0188a8c826831f19ef Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 14:43:31 -0700 Subject: [PATCH 011/117] [autorangeSmooth] Moved to pixel space --- plottable.js | 37 ++++++++++++++++--------------------- src/plots/linePlot.ts | 40 ++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 43 deletions(-) diff --git a/plottable.js b/plottable.js index 530bb214cd..245baf2f4e 100644 --- a/plottable.js +++ b/plottable.js @@ -7985,8 +7985,8 @@ var Plottable; var data = dataset.data(); var westOfLeft; var westOfRight; - var left = xScale.domain()[0]; - var right = xScale.domain()[1]; + var left = xScale.scale(xScale.domain()[0]); + var right = xScale.scale(xScale.domain()[1]); var lastValue; data.forEach(function (d, i) { var x1; @@ -7994,33 +7994,28 @@ var Plottable; var y1; var y2; if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - x1 = left - xAccessor(lastValue, i - 1, dataset); - x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); - y2 = yAccessor(d, i, dataset) - yAccessor(lastValue, i - 1, dataset); + if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { + x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); } - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - xAccessor(lastValue, i - 1, dataset); - x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); - y2 = d.y - lastValue.y; + if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { + console.log(1); + x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); } } - westOfLeft = d.x < left; - westOfRight = d.x < right; + westOfLeft = xScale.scale(d.x) < left; + westOfRight = xScale.scale(d.x) < right; lastValue = d; }); }); - includedValues = includedValues.map(function (d) { return d.y; }); + // includedValues = includedValues.map((d) => d.y); console.log(includedValues); this._yDomainChangeIncludedValues = function () { return includedValues; }; yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 310468438d..704ca222e6 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -38,7 +38,7 @@ export module Plots { private _ownMethod() { if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - var yScale = this.y().scale; + var yScale = >this.y().scale; var yAccessor = this.y().accessor; var xScale = >this.x().scale; @@ -55,8 +55,8 @@ export module Plots { var westOfLeft: boolean; var westOfRight: boolean; - var left = xScale.domain()[0]; - var right = xScale.domain()[1]; + var left = xScale.scale(xScale.domain()[0]); + var right = xScale.scale(xScale.domain()[1]); var lastValue: any; data.forEach((d, i) => { @@ -65,39 +65,35 @@ export module Plots { var y1: any; var y2: any; if (lastValue) { - if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { + if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { - x1 = left - xAccessor(lastValue, i - 1, dataset); - x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); - y2 = yAccessor(d, i, dataset) - yAccessor(lastValue, i - 1, dataset); + x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) } - if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - x1 = right - xAccessor(lastValue, i - 1, dataset); - x2 = xAccessor(d, i, dataset) - xAccessor(lastValue, i - 1, dataset); - y2 = d.y - lastValue.y; + if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { + console.log(1); + + x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); y1 = x1 * y2 / x2; - includedValues.push({ - x: lastValue.x + x1, - y: lastValue.y + y1 - }); + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) } } - westOfLeft = d.x < left; - westOfRight = d.x < right; + westOfLeft = xScale.scale(d.x) < left; + westOfRight = xScale.scale(d.x) < right; lastValue = d; }); }); - includedValues = includedValues.map((d) => d.y); + // includedValues = includedValues.map((d) => d.y); console.log(includedValues); From b8f85fe29e5801095ebd0191efab3e94c7e1a74d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 15:59:04 -0700 Subject: [PATCH 012/117] [autorangeSmooth] Nicer for loop --- plottable.js | 53 ++++++++++++++++++------------------ src/plots/linePlot.ts | 63 +++++++++++++++++++++---------------------- 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/plottable.js b/plottable.js index 245baf2f4e..f9011c9806 100644 --- a/plottable.js +++ b/plottable.js @@ -7988,35 +7988,34 @@ var Plottable; var left = xScale.scale(xScale.domain()[0]); var right = xScale.scale(xScale.domain()[1]); var lastValue; - data.forEach(function (d, i) { - var x1; - var x2; - var y1; - var y2; - if (lastValue) { - if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { - x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); - y1 = x1 * y2 / x2; - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); - } - if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { - console.log(1); - x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); - y1 = x1 * y2 / x2; - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); - } + var d; + var x1; + var x2; + var y1; + var y2; + for (var i = 1; i < data.length; i++) { + d = data[i]; + lastValue = data[i - 1]; + westOfLeft = xScale.scale(lastValue.x) < left; + westOfRight = xScale.scale(lastValue.x) < right; + if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { + x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); + y1 = x1 * y2 / x2; + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); } - westOfLeft = xScale.scale(d.x) < left; - westOfRight = xScale.scale(d.x) < right; - lastValue = d; - }); + if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { + console.log(1); + x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); + y1 = x1 * y2 / x2; + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); + } + } + ; }); - // includedValues = includedValues.map((d) => d.y); - console.log(includedValues); this._yDomainChangeIncludedValues = function () { return includedValues; }; yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 704ca222e6..5f5ff66a5c 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -59,43 +59,40 @@ export module Plots { var right = xScale.scale(xScale.domain()[1]); var lastValue: any; - data.forEach((d, i) => { - var x1: any; - var x2: any; - var y1: any; - var y2: any; - if (lastValue) { - if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { - - x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); - y1 = x1 * y2 / x2; - - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) - } - - if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { - console.log(1); - - x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); - y1 = x1 * y2 / x2; - - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) - } + var d: any; + var x1: any; + var x2: any; + var y1: any; + var y2: any; + for (var i = 1; i < data.length; i++) { + d = data[i]; + lastValue = data[i - 1]; + westOfLeft = xScale.scale(lastValue.x) < left; + westOfRight = xScale.scale(lastValue.x) < right; + + if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { + + x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); + y1 = x1 * y2 / x2; + + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) } - westOfLeft = xScale.scale(d.x) < left; - westOfRight = xScale.scale(d.x) < right; - lastValue = d; - }); - }); + if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { + console.log(1); + + x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); + y1 = x1 * y2 / x2; - // includedValues = includedValues.map((d) => d.y); + includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) + } - console.log(includedValues); + }; + }); this._yDomainChangeIncludedValues = () => includedValues; yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); From b5e773d2bb58294931281ec64cbcc1cb97e3052d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:22:50 -0700 Subject: [PATCH 013/117] [autorangeSmooth] Method extraction --- plottable.js | 93 +++++++++++++++++++---------------- src/plots/linePlot.ts | 112 +++++++++++++++++++++++------------------- 2 files changed, 112 insertions(+), 93 deletions(-) diff --git a/plottable.js b/plottable.js index f9011c9806..5bd4d5b901 100644 --- a/plottable.js +++ b/plottable.js @@ -7973,53 +7973,62 @@ var Plottable; }; Line.prototype._ownMethod = function () { if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - var yScale = this.y().scale; - var yAccessor = this.y().accessor; - var xScale = this.x().scale; - var xAccessor = this.x().accessor; if (this._yDomainChangeIncludedValues) { - yScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } - var includedValues = []; - this.datasets().forEach(function (dataset) { - var data = dataset.data(); - var westOfLeft; - var westOfRight; - var left = xScale.scale(xScale.domain()[0]); - var right = xScale.scale(xScale.domain()[1]); - var lastValue; - var d; - var x1; - var x2; - var y1; - var y2; - for (var i = 1; i < data.length; i++) { - d = data[i]; - lastValue = data[i - 1]; - westOfLeft = xScale.scale(lastValue.x) < left; - westOfRight = xScale.scale(lastValue.x) < right; - if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { - x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); - y1 = x1 * y2 / x2; - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); - } - if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { - console.log(1); - x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); - y1 = x1 * y2 / x2; - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); - } - } - ; - }); + var edgeIntersectionPoints = this._getEdgeIntersectionPoitns(); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]); this._yDomainChangeIncludedValues = function () { return includedValues; }; - yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } }; + Line.prototype._getEdgeIntersectionPoitns = function () { + if (!(this.x().scale instanceof Plottable.QuantitativeScale)) { + return [[], []]; + } + var yScale = this.y().scale; + var yAccessor = this.y().accessor; + var xScale = this.x().scale; + var xAccessor = this.x().accessor; + var includedValues = [[], []]; + var left = xScale.scale(xScale.domain()[0]); + var right = xScale.scale(xScale.domain()[1]); + this.datasets().forEach(function (dataset) { + var data = dataset.data(); + var westOfLeft; + var westOfRight; + var lastValue; + var d; + var x1; + var x2; + var y1; + var y2; + for (var i = 1; i < data.length; i++) { + d = data[i]; + lastValue = data[i - 1]; + westOfLeft = xScale.scale(lastValue.x) < left; + westOfRight = xScale.scale(lastValue.x) < right; + // If values crossed left edge + if (xScale.scale(lastValue.x) < left && xScale.scale(d.x) >= left) { + x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); + y1 = x1 * y2 / x2; + includedValues[0].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); + } + // If values crossed right edge + if (xScale.scale(lastValue.x) < right && xScale.scale(d.x) >= right) { + x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); + y1 = x1 * y2 / x2; + includedValues[1].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); + } + } + ; + }); + return includedValues; + }; Line.prototype._endOfDomainValues = function () { return []; }; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 5f5ff66a5c..132d1d6a35 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -38,65 +38,75 @@ export module Plots { private _ownMethod() { if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { - var yScale = >this.y().scale; - var yAccessor = this.y().accessor; - - var xScale = >this.x().scale; - var xAccessor = this.x().accessor; - if (this._yDomainChangeIncludedValues) { - yScale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); + this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } - var includedValues: any[] = []; - this.datasets().forEach((dataset) => { - - var data = dataset.data(); - - var westOfLeft: boolean; - var westOfRight: boolean; - var left = xScale.scale(xScale.domain()[0]); - var right = xScale.scale(xScale.domain()[1]); - - var lastValue: any; - var d: any; - var x1: any; - var x2: any; - var y1: any; - var y2: any; - for (var i = 1; i < data.length; i++) { - d = data[i]; - lastValue = data[i - 1]; - westOfLeft = xScale.scale(lastValue.x) < left; - westOfRight = xScale.scale(lastValue.x) < right; - - if ((westOfLeft === true && xScale.scale(d.x) >= left) !== (westOfLeft === false && xScale.scale(d.x) < left)) { - - x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); - y1 = x1 * y2 / x2; - - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) - } + var edgeIntersectionPoints = this._getEdgeIntersectionPoitns(); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) - if ((westOfRight && xScale.scale(d.x) >= right) !== (!westOfRight && xScale.scale(d.x) < right)) { - console.log(1); + this._yDomainChangeIncludedValues = () => includedValues; + this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); + } + } - x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); - y1 = x1 * y2 / x2; + private _getEdgeIntersectionPoitns(): number[][] { - includedValues.push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) - } + if (!(this.x().scale instanceof QuantitativeScale)) { + return [[], []]; + } - }; - }); + var yScale = >this.y().scale; + var yAccessor = this.y().accessor; + + var xScale = >this.x().scale; + var xAccessor = this.x().accessor; + + var includedValues: number[][] = [[], []]; + var left = xScale.scale(xScale.domain()[0]); + var right = xScale.scale(xScale.domain()[1]); + this.datasets().forEach((dataset) => { + + var data = dataset.data(); + + var westOfLeft: boolean; + var westOfRight: boolean; + + var lastValue: any; + var d: any; + var x1: any; + var x2: any; + var y1: any; + var y2: any; + for (var i = 1; i < data.length; i++) { + d = data[i]; + lastValue = data[i - 1]; + westOfLeft = xScale.scale(lastValue.x) < left; + westOfRight = xScale.scale(lastValue.x) < right; + + // If values crossed left edge + if (xScale.scale(lastValue.x) < left && xScale.scale(d.x) >= left) { + x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); + y1 = x1 * y2 / x2; + + includedValues[0].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) + } + + // If values crossed right edge + if (xScale.scale(lastValue.x) < right && xScale.scale(d.x) >= right) { + x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); + y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); + y1 = x1 * y2 / x2; + + includedValues[1].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) + } + }; + }); - this._yDomainChangeIncludedValues = () => includedValues; - yScale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); - } + return includedValues; } private _endOfDomainValues(): X|number[][] { From 4dd112f5188bc40052f6cf7fb1455cac39b94892 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:41:12 -0700 Subject: [PATCH 014/117] [autorangeSmooth] Better namings part 1 --- plottable.js | 4 ++++ src/plots/linePlot.ts | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/plottable.js b/plottable.js index 5bd4d5b901..fe4252b035 100644 --- a/plottable.js +++ b/plottable.js @@ -8004,6 +8004,10 @@ var Plottable; var y1; var y2; for (var i = 1; i < data.length; i++) { + var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); + var currX = xScale.scale(xAccessor(data[i], i, dataset)); + var prevY = yScale.scale(yAccessor(data[i - 1], i - 1, dataset)); + var currY = yScale.scale(yAccessor(data[i], i, dataset)); d = data[i]; lastValue = data[i - 1]; westOfLeft = xScale.scale(lastValue.x) < left; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 132d1d6a35..aa002d5a33 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -79,6 +79,13 @@ export module Plots { var y1: any; var y2: any; for (var i = 1; i < data.length; i++) { + + var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); + var currX = xScale.scale(xAccessor(data[i], i, dataset)); + + var prevY = yScale.scale(yAccessor(data[i - 1], i - 1, dataset)); + var currY = yScale.scale(yAccessor(data[i], i, dataset)); + d = data[i]; lastValue = data[i - 1]; westOfLeft = xScale.scale(lastValue.x) < left; From 28daf07c9b427ffc7cf51b1d129998859eb3c4a6 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:42:55 -0700 Subject: [PATCH 015/117] [autorangeSmooth] Better namings part 2 --- plottable.js | 16 ++++++---------- src/plots/linePlot.ts | 18 ++++++------------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/plottable.js b/plottable.js index fe4252b035..48e3e7b4fa 100644 --- a/plottable.js +++ b/plottable.js @@ -7995,8 +7995,6 @@ var Plottable; var right = xScale.scale(xScale.domain()[1]); this.datasets().forEach(function (dataset) { var data = dataset.data(); - var westOfLeft; - var westOfRight; var lastValue; var d; var x1; @@ -8010,21 +8008,19 @@ var Plottable; var currY = yScale.scale(yAccessor(data[i], i, dataset)); d = data[i]; lastValue = data[i - 1]; - westOfLeft = xScale.scale(lastValue.x) < left; - westOfRight = xScale.scale(lastValue.x) < right; // If values crossed left edge if (xScale.scale(lastValue.x) < left && xScale.scale(d.x) >= left) { - x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); + x1 = left - prevX; + x2 = currX - prevX; + y2 = currY - prevY; y1 = x1 * y2 / x2; includedValues[0].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); } // If values crossed right edge if (xScale.scale(lastValue.x) < right && xScale.scale(d.x) >= right) { - x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); + x1 = right - prevX; + x2 = currX - prevX; + y2 = currY - prevY; y1 = x1 * y2 / x2; includedValues[1].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index aa002d5a33..384fe6fde2 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -69,9 +69,6 @@ export module Plots { var data = dataset.data(); - var westOfLeft: boolean; - var westOfRight: boolean; - var lastValue: any; var d: any; var x1: any; @@ -79,7 +76,6 @@ export module Plots { var y1: any; var y2: any; for (var i = 1; i < data.length; i++) { - var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); var currX = xScale.scale(xAccessor(data[i], i, dataset)); @@ -88,14 +84,12 @@ export module Plots { d = data[i]; lastValue = data[i - 1]; - westOfLeft = xScale.scale(lastValue.x) < left; - westOfRight = xScale.scale(lastValue.x) < right; // If values crossed left edge if (xScale.scale(lastValue.x) < left && xScale.scale(d.x) >= left) { - x1 = left - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(yAccessor(d, i, dataset)) - yScale.scale(yAccessor(lastValue, i - 1, dataset)); + x1 = left - prevX; + x2 = currX - prevX; + y2 = currY - prevY; y1 = x1 * y2 / x2; includedValues[0].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) @@ -103,9 +97,9 @@ export module Plots { // If values crossed right edge if (xScale.scale(lastValue.x) < right && xScale.scale(d.x) >= right) { - x1 = right - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - x2 = xScale.scale(xAccessor(d, i, dataset)) - xScale.scale(xAccessor(lastValue, i - 1, dataset)); - y2 = yScale.scale(d.y) - yScale.scale(lastValue.y); + x1 = right - prevX; + x2 = currX - prevX; + y2 = currY - prevY; y1 = x1 * y2 / x2; includedValues[1].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) From ffbd451f11c5fbda7a021f594c9a45e5acbeaf0a Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:48:59 -0700 Subject: [PATCH 016/117] [autorangeSmooth] Better namings part 3 --- plottable.js | 25 +++++++++---------------- src/plots/linePlot.ts | 28 ++++++++++------------------ 2 files changed, 19 insertions(+), 34 deletions(-) diff --git a/plottable.js b/plottable.js index 48e3e7b4fa..d4d710caa9 100644 --- a/plottable.js +++ b/plottable.js @@ -7976,13 +7976,13 @@ var Plottable; if (this._yDomainChangeIncludedValues) { this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } - var edgeIntersectionPoints = this._getEdgeIntersectionPoitns(); + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]); this._yDomainChangeIncludedValues = function () { return includedValues; }; this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } }; - Line.prototype._getEdgeIntersectionPoitns = function () { + Line.prototype._getEdgeIntersectionPoints = function () { if (!(this.x().scale instanceof Plottable.QuantitativeScale)) { return [[], []]; } @@ -7990,44 +7990,37 @@ var Plottable; var yAccessor = this.y().accessor; var xScale = this.x().scale; var xAccessor = this.x().accessor; - var includedValues = [[], []]; + var intersectionPoints = [[], []]; var left = xScale.scale(xScale.domain()[0]); var right = xScale.scale(xScale.domain()[1]); this.datasets().forEach(function (dataset) { var data = dataset.data(); - var lastValue; - var d; - var x1; - var x2; - var y1; - var y2; + var x1, x2, y1, y2; for (var i = 1; i < data.length; i++) { var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); var currX = xScale.scale(xAccessor(data[i], i, dataset)); var prevY = yScale.scale(yAccessor(data[i - 1], i - 1, dataset)); var currY = yScale.scale(yAccessor(data[i], i, dataset)); - d = data[i]; - lastValue = data[i - 1]; // If values crossed left edge - if (xScale.scale(lastValue.x) < left && xScale.scale(d.x) >= left) { + if (prevX < left && left <= currX) { x1 = left - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - includedValues[0].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); + intersectionPoints[0].push(yScale.invert(prevY + y1)); } // If values crossed right edge - if (xScale.scale(lastValue.x) < right && xScale.scale(d.x) >= right) { + if (prevX < right && right <= currX) { x1 = right - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - includedValues[1].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)); + intersectionPoints[1].push(yScale.invert(prevY + y1)); } } ; }); - return includedValues; + return intersectionPoints; }; Line.prototype._endOfDomainValues = function () { return []; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 384fe6fde2..d71f877368 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -42,7 +42,7 @@ export module Plots { this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } - var edgeIntersectionPoints = this._getEdgeIntersectionPoitns(); + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) this._yDomainChangeIncludedValues = () => includedValues; @@ -50,7 +50,7 @@ export module Plots { } } - private _getEdgeIntersectionPoitns(): number[][] { + private _getEdgeIntersectionPoints(): number[][] { if (!(this.x().scale instanceof QuantitativeScale)) { return [[], []]; @@ -59,22 +59,17 @@ export module Plots { var yScale = >this.y().scale; var yAccessor = this.y().accessor; - var xScale = >this.x().scale; + var xScale = this.x().scale; var xAccessor = this.x().accessor; - var includedValues: number[][] = [[], []]; + var intersectionPoints: number[][] = [[], []]; var left = xScale.scale(xScale.domain()[0]); var right = xScale.scale(xScale.domain()[1]); this.datasets().forEach((dataset) => { var data = dataset.data(); - var lastValue: any; - var d: any; - var x1: any; - var x2: any; - var y1: any; - var y2: any; + var x1: any, x2: any, y1: any, y2: any; for (var i = 1; i < data.length; i++) { var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); var currX = xScale.scale(xAccessor(data[i], i, dataset)); @@ -82,32 +77,29 @@ export module Plots { var prevY = yScale.scale(yAccessor(data[i - 1], i - 1, dataset)); var currY = yScale.scale(yAccessor(data[i], i, dataset)); - d = data[i]; - lastValue = data[i - 1]; - // If values crossed left edge - if (xScale.scale(lastValue.x) < left && xScale.scale(d.x) >= left) { + if (prevX < left && left <= currX) { x1 = left - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - includedValues[0].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) + intersectionPoints[0].push(yScale.invert(prevY + y1)); } // If values crossed right edge - if (xScale.scale(lastValue.x) < right && xScale.scale(d.x) >= right) { + if (prevX < right && right <= currX) { x1 = right - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - includedValues[1].push(yScale.invert(yScale.scale(yAccessor(lastValue, i - 1, dataset)) + y1)) + intersectionPoints[1].push(yScale.invert(prevY + y1)); } }; }); - return includedValues; + return intersectionPoints; } private _endOfDomainValues(): X|number[][] { From 863a230ad363437370b1432c18e7d4ef13b514fa Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:50:27 -0700 Subject: [PATCH 017/117] [autorangeSmooth] Removed extra method --- plottable.js | 3 --- src/plots/linePlot.ts | 4 ---- 2 files changed, 7 deletions(-) diff --git a/plottable.js b/plottable.js index d4d710caa9..5672a4d7a6 100644 --- a/plottable.js +++ b/plottable.js @@ -8022,9 +8022,6 @@ var Plottable; }); return intersectionPoints; }; - Line.prototype._endOfDomainValues = function () { - return []; - }; Line.prototype._getResetYFunction = function () { // gets the y-value generator for the animation start point var yDomain = this.y().scale.domain(); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index d71f877368..1735f046e9 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -102,10 +102,6 @@ export module Plots { return intersectionPoints; } - private _endOfDomainValues(): X|number[][] { - return []; - } - protected _getResetYFunction() { // gets the y-value generator for the animation start point var yDomain = this.y().scale.domain(); From 1a811e6ee56c65fc6f5d91ed3ef4e1509b3e7517 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:55:07 -0700 Subject: [PATCH 018/117] [autorangeSmooth] Deleted extra variables --- plottable.js | 11 ++++++----- src/plots/linePlot.ts | 13 +++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/plottable.js b/plottable.js index 5672a4d7a6..dd1898f3b8 100644 --- a/plottable.js +++ b/plottable.js @@ -7972,7 +7972,7 @@ var Plottable; _super.prototype._updateExtentsForProperty.call(this, property); }; Line.prototype._ownMethod = function () { - if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + if (this.x && this.x().scale && this.y && this.y().scale) { if (this._yDomainChangeIncludedValues) { this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } @@ -7983,6 +7983,7 @@ var Plottable; } }; Line.prototype._getEdgeIntersectionPoints = function () { + var _this = this; if (!(this.x().scale instanceof Plottable.QuantitativeScale)) { return [[], []]; } @@ -7997,10 +7998,10 @@ var Plottable; var data = dataset.data(); var x1, x2, y1, y2; for (var i = 1; i < data.length; i++) { - var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); - var currX = xScale.scale(xAccessor(data[i], i, dataset)); - var prevY = yScale.scale(yAccessor(data[i - 1], i - 1, dataset)); - var currY = yScale.scale(yAccessor(data[i], i, dataset)); + var prevX = currX || xScale.scale(_this.x().accessor(data[i - 1], i - 1, dataset)); + var prevY = currY || yScale.scale(_this.y().accessor(data[i - 1], i - 1, dataset)); + var currX = xScale.scale(_this.x().accessor(data[i], i, dataset)); + var currY = yScale.scale(_this.y().accessor(data[i], i, dataset)); // If values crossed left edge if (prevX < left && left <= currX) { x1 = left - prevX; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 1735f046e9..a16a82385a 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -36,7 +36,7 @@ export module Plots { private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; private _ownMethod() { - if (this.x && this.x().scale && this.y && this.y().scale && this.datasets().length > 0) { + if (this.x && this.x().scale && this.y && this.y().scale) { if (this._yDomainChangeIncludedValues) { this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); @@ -57,10 +57,7 @@ export module Plots { } var yScale = >this.y().scale; - var yAccessor = this.y().accessor; - var xScale = this.x().scale; - var xAccessor = this.x().accessor; var intersectionPoints: number[][] = [[], []]; var left = xScale.scale(xScale.domain()[0]); @@ -71,11 +68,11 @@ export module Plots { var x1: any, x2: any, y1: any, y2: any; for (var i = 1; i < data.length; i++) { - var prevX = xScale.scale(xAccessor(data[i - 1], i - 1, dataset)); - var currX = xScale.scale(xAccessor(data[i], i, dataset)); + var prevX = currX || xScale.scale(this.x().accessor(data[i - 1], i - 1, dataset)); + var prevY = currY || yScale.scale(this.y().accessor(data[i - 1], i - 1, dataset)); - var prevY = yScale.scale(yAccessor(data[i - 1], i - 1, dataset)); - var currY = yScale.scale(yAccessor(data[i], i, dataset)); + var currX = xScale.scale(this.x().accessor(data[i], i, dataset)); + var currY = yScale.scale(this.y().accessor(data[i], i, dataset)); // If values crossed left edge if (prevX < left && left <= currX) { From 74d4958f33254d4a698fada3df61537a0faa5370 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 16:55:48 -0700 Subject: [PATCH 019/117] [autorangeSmooth] Uncommitted plottable.js --- plottable.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/plottable.js b/plottable.js index dd1898f3b8..8c80024be2 100644 --- a/plottable.js +++ b/plottable.js @@ -7988,9 +7988,7 @@ var Plottable; return [[], []]; } var yScale = this.y().scale; - var yAccessor = this.y().accessor; var xScale = this.x().scale; - var xAccessor = this.x().accessor; var intersectionPoints = [[], []]; var left = xScale.scale(xScale.domain()[0]); var right = xScale.scale(xScale.domain()[1]); From 979102f68b18a3bb99c259dec9513c8b93de6ddd Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 17:07:45 -0700 Subject: [PATCH 020/117] [autorangeSmooth] Fixed typing --- plottable.js | 14 ++++++++++---- src/plots/linePlot.ts | 22 ++++++++++++++-------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/plottable.js b/plottable.js index 8c80024be2..96cf954eb0 100644 --- a/plottable.js +++ b/plottable.js @@ -7977,14 +7977,14 @@ var Plottable; this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); this._yDomainChangeIncludedValues = function () { return includedValues; }; this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } }; Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; - if (!(this.x().scale instanceof Plottable.QuantitativeScale)) { + if (!(this.y().scale instanceof Plottable.QuantitativeScale)) { return [[], []]; } var yScale = this.y().scale; @@ -8006,7 +8006,10 @@ var Plottable; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[0].push(yScale.invert(prevY + y1)); + intersectionPoints[0].push({ + x: left, + y: yScale.invert(prevY + y1) + }); } // If values crossed right edge if (prevX < right && right <= currX) { @@ -8014,7 +8017,10 @@ var Plottable; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[1].push(yScale.invert(prevY + y1)); + intersectionPoints[1].push({ + x: right, + y: yScale.invert(prevY + y1) + }); } } ; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index a16a82385a..1e272572d1 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -33,7 +33,7 @@ export module Plots { } - private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; + private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; private _ownMethod() { if (this.x && this.x().scale && this.y && this.y().scale) { @@ -43,30 +43,30 @@ export module Plots { } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); this._yDomainChangeIncludedValues = () => includedValues; this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } } - private _getEdgeIntersectionPoints(): number[][] { + private _getEdgeIntersectionPoints(): Point[][] { - if (!(this.x().scale instanceof QuantitativeScale)) { + if (!(this.y().scale instanceof QuantitativeScale)) { return [[], []]; } var yScale = >this.y().scale; var xScale = this.x().scale; - var intersectionPoints: number[][] = [[], []]; + var intersectionPoints: Point[][] = [[], []]; var left = xScale.scale(xScale.domain()[0]); var right = xScale.scale(xScale.domain()[1]); this.datasets().forEach((dataset) => { var data = dataset.data(); - var x1: any, x2: any, y1: any, y2: any; + var x1: number, x2: number, y1: number, y2: number; for (var i = 1; i < data.length; i++) { var prevX = currX || xScale.scale(this.x().accessor(data[i - 1], i - 1, dataset)); var prevY = currY || yScale.scale(this.y().accessor(data[i - 1], i - 1, dataset)); @@ -81,7 +81,10 @@ export module Plots { y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[0].push(yScale.invert(prevY + y1)); + intersectionPoints[0].push({ + x: left, + y: yScale.invert(prevY + y1) + }); } // If values crossed right edge @@ -91,7 +94,10 @@ export module Plots { y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[1].push(yScale.invert(prevY + y1)); + intersectionPoints[1].push({ + x: right, + y: yScale.invert(prevY + y1) + }); } }; }); From d30b6f8f8f59b46e988f0a7149dd418c9af522bf Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 17:15:58 -0700 Subject: [PATCH 021/117] [autorangeSmooth] renamed the _ownMethod --- plottable.js | 20 ++++++++++---------- src/plots/linePlot.ts | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/plottable.js b/plottable.js index 96cf954eb0..b217fdfe52 100644 --- a/plottable.js +++ b/plottable.js @@ -7967,11 +7967,11 @@ var Plottable; }; Line.prototype._updateExtentsForProperty = function (property) { if (property === "y") { - this._ownMethod(); + this._addIntersectionPoints(); } _super.prototype._updateExtentsForProperty.call(this, property); }; - Line.prototype._ownMethod = function () { + Line.prototype._addIntersectionPoints = function () { if (this.x && this.x().scale && this.y && this.y().scale) { if (this._yDomainChangeIncludedValues) { this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); @@ -7990,8 +7990,8 @@ var Plottable; var yScale = this.y().scale; var xScale = this.x().scale; var intersectionPoints = [[], []]; - var left = xScale.scale(xScale.domain()[0]); - var right = xScale.scale(xScale.domain()[1]); + var leftX = xScale.scale(xScale.domain()[0]); + var rightX = xScale.scale(xScale.domain()[1]); this.datasets().forEach(function (dataset) { var data = dataset.data(); var x1, x2, y1, y2; @@ -8001,24 +8001,24 @@ var Plottable; var currX = xScale.scale(_this.x().accessor(data[i], i, dataset)); var currY = yScale.scale(_this.y().accessor(data[i], i, dataset)); // If values crossed left edge - if (prevX < left && left <= currX) { - x1 = left - prevX; + if (prevX < leftX && leftX <= currX) { + x1 = leftX - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; intersectionPoints[0].push({ - x: left, + x: leftX, y: yScale.invert(prevY + y1) }); } // If values crossed right edge - if (prevX < right && right <= currX) { - x1 = right - prevX; + if (prevX < rightX && rightX <= currX) { + x1 = rightX - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; intersectionPoints[1].push({ - x: right, + x: rightX, y: yScale.invert(prevY + y1) }); } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 1e272572d1..d3968dba04 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -27,7 +27,7 @@ export module Plots { protected _updateExtentsForProperty(property: string) { if (property === "y") { - this._ownMethod(); + this._addIntersectionPoints(); } super._updateExtentsForProperty(property); } @@ -35,7 +35,7 @@ export module Plots { private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; - private _ownMethod() { + private _addIntersectionPoints() { if (this.x && this.x().scale && this.y && this.y().scale) { if (this._yDomainChangeIncludedValues) { @@ -60,8 +60,8 @@ export module Plots { var xScale = this.x().scale; var intersectionPoints: Point[][] = [[], []]; - var left = xScale.scale(xScale.domain()[0]); - var right = xScale.scale(xScale.domain()[1]); + var leftX = xScale.scale(xScale.domain()[0]); + var rightX = xScale.scale(xScale.domain()[1]); this.datasets().forEach((dataset) => { var data = dataset.data(); @@ -75,27 +75,27 @@ export module Plots { var currY = yScale.scale(this.y().accessor(data[i], i, dataset)); // If values crossed left edge - if (prevX < left && left <= currX) { - x1 = left - prevX; + if (prevX < leftX && leftX <= currX) { + x1 = leftX - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; intersectionPoints[0].push({ - x: left, + x: leftX, y: yScale.invert(prevY + y1) }); } // If values crossed right edge - if (prevX < right && right <= currX) { - x1 = right - prevX; + if (prevX < rightX && rightX <= currX) { + x1 = rightX - prevX; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; intersectionPoints[1].push({ - x: right, + x: rightX, y: yScale.invert(prevY + y1) }); } From ac5d0d38ea4811e87a27b8c097f05f9dad59ef45 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 17:22:25 -0700 Subject: [PATCH 022/117] [autorangeSmooth] new approach --- plottable.d.ts | 2 ++ plottable.js | 56 +++++++++++++------------------------------ src/plots/linePlot.ts | 27 ++++++++++++++++++++- src/plots/plot.ts | 50 +------------------------------------- 4 files changed, 45 insertions(+), 90 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index f88ba8f8e2..4a417b4fe3 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2420,6 +2420,7 @@ declare module Plottable { protected _updateExtents(): void; protected _updateExtentsForProperty(property: string): void; protected _filterForProperty(property: string): Accessor; + protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[]; /** * Override in subclass to add special extents, such as included values */ @@ -2982,6 +2983,7 @@ declare module Plottable { constructor(); protected _createDrawer(dataset: Dataset): Drawer; protected _updateExtentsForProperty(property: string): void; + protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[]; protected _getResetYFunction(): (d: any, i: number, dataset: Dataset) => number; protected _generateDrawSteps(): Drawers.DrawStep[]; protected _generateAttrToProjector(): { diff --git a/plottable.js b/plottable.js index b217fdfe52..cea5b8c2dc 100644 --- a/plottable.js +++ b/plottable.js @@ -6254,45 +6254,6 @@ var Plottable; if (filter != null) { filteredData = data.filter(function (d, i) { return filter(d, i, dataset); }); } - // var self = this; - // if (self.x && self.x().scale && self.y && self.y().scale) { - // var westOfLeft: boolean; - // var westOfRight: boolean; - // var left = self.x().scale.domain()[0]; - // var right = self.x().scale.domain()[1]; - // var lastValue: any; - // data.forEach((d, i) => { - // var x1: any; - // var x2: any; - // var y1: any; - // var y2: any; - // if (lastValue) { - // if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - // x1 = left - lastValue.x; - // x2 = d.x - lastValue.x; - // y2 = d.y - lastValue.y; - // y1 = x1 * y2 / x2; - // filteredData.push({ - // x: lastValue.x + x1, - // y: lastValue.y + y1 - // }); - // } - // if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - // x1 = right - lastValue.x; - // x2 = d.x - lastValue.x; - // y2 = d.y - lastValue.y; - // y1 = x1 * y2 / x2; - // filteredData.push({ - // x: lastValue.x + x1, - // y: lastValue.y + y1 - // }); - // } - // } - // westOfLeft = d.x < left; - // westOfRight = d.x < right; - // lastValue = d; - // }); - // } var appliedAccessor = function (d, i) { return accessor(d, i, dataset); }; var mappedData = filteredData.map(appliedAccessor); return scale.extentOfValues(mappedData); @@ -7967,7 +7928,6 @@ var Plottable; }; Line.prototype._updateExtentsForProperty = function (property) { if (property === "y") { - this._addIntersectionPoints(); } _super.prototype._updateExtentsForProperty.call(this, property); }; @@ -7982,6 +7942,22 @@ var Plottable; this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); } }; + Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { + var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); + if (this.x && this.x().scale && this.y && this.y().scale) { + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); + var maxIncludedValue = Math.max.apply(this, includedValues); + var minIncludedValue = Math.min.apply(this, includedValues); + if (minIncludedValue < extent[0]) { + extent[0] = minIncludedValue; + } + if (maxIncludedValue > extent[1]) { + extent[1] = maxIncludedValue; + } + } + return extent; + }; Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; if (!(this.y().scale instanceof Plottable.QuantitativeScale)) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index d3968dba04..14b9a53813 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -27,7 +27,7 @@ export module Plots { protected _updateExtentsForProperty(property: string) { if (property === "y") { - this._addIntersectionPoints(); + // this._addIntersectionPoints(); } super._updateExtentsForProperty(property); } @@ -50,6 +50,31 @@ export module Plots { } } + protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { + + var extent = super._computeExtent(dataset, accScaleBinding, filter); + + if (this.x && this.x().scale && this.y && this.y().scale) { + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + + var maxIncludedValue = Math.max.apply(this, includedValues); + var minIncludedValue = Math.min.apply(this, includedValues); + + if (minIncludedValue < extent[0]) { + extent[0] = minIncludedValue; + } + + if (maxIncludedValue > extent[1]) { + extent[1] = maxIncludedValue; + } + } + + + return extent; + + } + private _getEdgeIntersectionPoints(): Point[][] { if (!(this.y().scale instanceof QuantitativeScale)) { diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 14b86a0a38..17fd4b8335 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -299,7 +299,7 @@ export class Plot extends Component { extents.set(key, this.datasets().map((dataset) => this._computeExtent(dataset, accScaleBinding, filter))); } - private _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { + protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { var accessor = accScaleBinding.accessor; var scale = accScaleBinding.scale; @@ -312,54 +312,6 @@ export class Plot extends Component { if (filter != null) { filteredData = data.filter((d, i) => filter(d, i, dataset)); } - - // var self = this; - // if (self.x && self.x().scale && self.y && self.y().scale) { - // var westOfLeft: boolean; - // var westOfRight: boolean; - // var left = self.x().scale.domain()[0]; - // var right = self.x().scale.domain()[1]; - - // var lastValue: any; - // data.forEach((d, i) => { - // var x1: any; - // var x2: any; - // var y1: any; - // var y2: any; - // if (lastValue) { - // if ((westOfLeft === true && d.x >= left) !== (westOfLeft === false && d.x < left)) { - - // x1 = left - lastValue.x; - // x2 = d.x - lastValue.x; - // y2 = d.y - lastValue.y; - // y1 = x1 * y2 / x2; - - // filteredData.push({ - // x: lastValue.x + x1, - // y: lastValue.y + y1 - // }); - // } - - // if ((westOfRight && d.x >= right) !== (!westOfRight && d.x < right)) { - // x1 = right - lastValue.x; - // x2 = d.x - lastValue.x; - // y2 = d.y - lastValue.y; - // y1 = x1 * y2 / x2; - - // filteredData.push({ - // x: lastValue.x + x1, - // y: lastValue.y + y1 - // }); - // } - // } - - // westOfLeft = d.x < left; - // westOfRight = d.x < right; - // lastValue = d; - - // }); - // } - var appliedAccessor = (d: any, i: number) => accessor(d, i, dataset); var mappedData = filteredData.map(appliedAccessor); From 99731388100260845842a64f395caa930983fc0f Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 19:12:01 -0700 Subject: [PATCH 023/117] [autorangeSmooth] Finished adding the feature as an opt-in --- plottable.d.ts | 6 ++---- plottable.js | 38 ++++++++++++-------------------------- src/plots/linePlot.ts | 42 +++++++++++++++++------------------------- src/plots/xyPlot.ts | 13 ------------- 4 files changed, 31 insertions(+), 68 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 4a417b4fe3..064d0571ee 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2591,7 +2591,6 @@ declare module Plottable { class XYPlot extends Plot { protected static _X_KEY: string; protected static _Y_KEY: string; - _autorangeSmooth: boolean; /** * An XYPlot is a Plot that displays data along two primary directions, X and Y. * @@ -2674,8 +2673,6 @@ declare module Plottable { * @returns {XYPlot} The calling XYPlot. */ autorangeMode(autorangeMode: string): XYPlot; - autorangeSmooth(): boolean; - autorangeSmooth(autorangeSmooth: boolean): XYPlot; computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number): XYPlot; /** * Adjusts the domains of both X and Y scales to show all data. @@ -2981,8 +2978,9 @@ declare module Plottable { * @constructor */ constructor(); + autorangeSmooth(): boolean; + autorangeSmooth(autorangeSmooth: boolean): Plots.Line; protected _createDrawer(dataset: Dataset): Drawer; - protected _updateExtentsForProperty(property: string): void; protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[]; protected _getResetYFunction(): (d: any, i: number, dataset: Dataset) => number; protected _generateDrawSteps(): Drawers.DrawStep[]; diff --git a/plottable.js b/plottable.js index cea5b8c2dc..1792eacfd1 100644 --- a/plottable.js +++ b/plottable.js @@ -6779,8 +6779,6 @@ var Plottable; _super.call(this); this._autoAdjustXScaleDomain = false; this._autoAdjustYScaleDomain = false; - // TODO: private - this._autorangeSmooth = false; this._deferredRendering = false; this._cachedDomainX = [null, null]; this._cachedDomainY = [null, null]; @@ -6955,13 +6953,6 @@ var Plottable; } return this; }; - XYPlot.prototype.autorangeSmooth = function (autorangeSmooth) { - if (autorangeSmooth == null) { - return this._autorangeSmooth; - } - this._autorangeSmooth = autorangeSmooth; - return this; - }; XYPlot.prototype.computeLayout = function (origin, availableWidth, availableHeight) { _super.prototype.computeLayout.call(this, origin, availableWidth, availableHeight); var xBinding = this.x(); @@ -7914,6 +7905,7 @@ var Plottable; */ function Line() { _super.call(this); + this._autorangeSmooth = false; this.addClass("line-plot"); var animator = new Plottable.Animators.Easing(); animator.stepDuration(Plottable.Plot._ANIMATION_MAX_DURATION); @@ -7923,32 +7915,26 @@ var Plottable; this.attr("stroke", new Plottable.Scales.Color().range()[0]); this.attr("stroke-width", "2px"); } - Line.prototype._createDrawer = function (dataset) { - return new Plottable.Drawers.Line(dataset); - }; - Line.prototype._updateExtentsForProperty = function (property) { - if (property === "y") { + Line.prototype.autorangeSmooth = function (autorangeSmooth) { + if (autorangeSmooth == null) { + return this._autorangeSmooth; } - _super.prototype._updateExtentsForProperty.call(this, property); + this._autorangeSmooth = autorangeSmooth; + return this; }; - Line.prototype._addIntersectionPoints = function () { - if (this.x && this.x().scale && this.y && this.y().scale) { - if (this._yDomainChangeIncludedValues) { - this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); - } - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); - this._yDomainChangeIncludedValues = function () { return includedValues; }; - this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); - } + Line.prototype._createDrawer = function (dataset) { + return new Plottable.Drawers.Line(dataset); }; Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); - if (this.x && this.x().scale && this.y && this.y().scale) { + if (this._autorangeSmooth && this.x && this.x().scale && this.y && this.y().scale) { var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); + if (extent.length === 0) { + extent = [minIncludedValue, maxIncludedValue]; + } if (minIncludedValue < extent[0]) { extent[0] = minIncludedValue; } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 14b9a53813..6214e23414 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -4,6 +4,8 @@ module Plottable { export module Plots { export class Line extends XYPlot { + private _autorangeSmooth = false; + /** * A Line Plot draws line segments starting from the first data point to the next. * @@ -21,46 +23,36 @@ export module Plots { this.attr("stroke-width", "2px"); } - protected _createDrawer(dataset: Dataset): Drawer { - return new Plottable.Drawers.Line(dataset); - } - - protected _updateExtentsForProperty(property: string) { - if (property === "y") { - // this._addIntersectionPoints(); + public autorangeSmooth(): boolean; + public autorangeSmooth(autorangeSmooth: boolean): Plots.Line; + public autorangeSmooth(autorangeSmooth?: boolean): any { + if (autorangeSmooth == null) { + return this._autorangeSmooth; } - super._updateExtentsForProperty(property); + this._autorangeSmooth = autorangeSmooth; + return this; } - - private _yDomainChangeIncludedValues: Scales.IncludedValuesProvider; - - private _addIntersectionPoints() { - if (this.x && this.x().scale && this.y && this.y().scale) { - - if (this._yDomainChangeIncludedValues) { - this.y().scale.removeIncludedValuesProvider(this._yDomainChangeIncludedValues); - } - - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); - - this._yDomainChangeIncludedValues = () => includedValues; - this.y().scale.addIncludedValuesProvider(this._yDomainChangeIncludedValues); - } + protected _createDrawer(dataset: Dataset): Drawer { + return new Plottable.Drawers.Line(dataset); } protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { var extent = super._computeExtent(dataset, accScaleBinding, filter); - if (this.x && this.x().scale && this.y && this.y().scale) { + if (this._autorangeSmooth && this.x && this.x().scale && this.y && this.y().scale) { + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); + if (extent.length === 0) { + extent = [minIncludedValue, maxIncludedValue]; + } + if (minIncludedValue < extent[0]) { extent[0] = minIncludedValue; } diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index 29ae96d6c9..3112c2acfc 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -9,9 +9,6 @@ export class XYPlot extends Plot { private _adjustYDomainOnChangeFromXCallback: ScaleCallback>; private _adjustXDomainOnChangeFromYCallback: ScaleCallback>; - // TODO: private - public _autorangeSmooth = false; - private _deferredRendering = false; private _cachedDomainX: X[] = [null, null]; private _cachedDomainY: Y[] = [null, null]; @@ -287,16 +284,6 @@ export class XYPlot extends Plot { return this; } - public autorangeSmooth(): boolean; - public autorangeSmooth(autorangeSmooth: boolean): XYPlot; - public autorangeSmooth(autorangeSmooth?: boolean): any { - if (autorangeSmooth == null) { - return this._autorangeSmooth; - } - this._autorangeSmooth = autorangeSmooth; - return this; - } - public computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number) { super.computeLayout(origin, availableWidth, availableHeight); var xBinding = this.x(); From b9afcc50124e5999024a5684889b35f7a81bc8cc Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 19:13:30 -0700 Subject: [PATCH 024/117] [autorangeSmooth] Deleted extra additions --- plottable.js | 5 ++--- src/plots/plot.ts | 5 ++--- src/plots/xyPlot.ts | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/plottable.js b/plottable.js index 1792eacfd1..8829738c0e 100644 --- a/plottable.js +++ b/plottable.js @@ -6250,12 +6250,11 @@ var Plottable; return []; } var data = dataset.data(); - var filteredData = []; if (filter != null) { - filteredData = data.filter(function (d, i) { return filter(d, i, dataset); }); + data = data.filter(function (d, i) { return filter(d, i, dataset); }); } var appliedAccessor = function (d, i) { return accessor(d, i, dataset); }; - var mappedData = filteredData.map(appliedAccessor); + var mappedData = data.map(appliedAccessor); return scale.extentOfValues(mappedData); }; /** diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 17fd4b8335..157571f3ed 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -308,12 +308,11 @@ export class Plot extends Component { } var data = dataset.data(); - var filteredData: any[] = []; if (filter != null) { - filteredData = data.filter((d, i) => filter(d, i, dataset)); + data = data.filter((d, i) => filter(d, i, dataset)); } var appliedAccessor = (d: any, i: number) => accessor(d, i, dataset); - var mappedData = filteredData.map(appliedAccessor); + var mappedData = data.map(appliedAccessor); return scale.extentOfValues(mappedData); } diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index 3112c2acfc..dd920d7fcb 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -333,7 +333,6 @@ export class XYPlot extends Plot { private _adjustYDomainOnChangeFromX() { if (!this._projectorsReady()) { return; } - if (this._autoAdjustYScaleDomain) { this._updateYExtentsAndAutodomain(); } From eb67655a4eb64138512aa88bbb3b6f7d8cb97b24 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 19:16:35 -0700 Subject: [PATCH 025/117] [autorangeSmooth] TSLint --- plottable.js | 9 +++++---- src/plots/linePlot.ts | 12 +++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/plottable.js b/plottable.js index 8829738c0e..9afeb509d1 100644 --- a/plottable.js +++ b/plottable.js @@ -7956,11 +7956,12 @@ var Plottable; this.datasets().forEach(function (dataset) { var data = dataset.data(); var x1, x2, y1, y2; + var prevX, prevY, currX, currY; for (var i = 1; i < data.length; i++) { - var prevX = currX || xScale.scale(_this.x().accessor(data[i - 1], i - 1, dataset)); - var prevY = currY || yScale.scale(_this.y().accessor(data[i - 1], i - 1, dataset)); - var currX = xScale.scale(_this.x().accessor(data[i], i, dataset)); - var currY = yScale.scale(_this.y().accessor(data[i], i, dataset)); + prevX = currX || xScale.scale(_this.x().accessor(data[i - 1], i - 1, dataset)); + prevY = currY || yScale.scale(_this.y().accessor(data[i - 1], i - 1, dataset)); + currX = xScale.scale(_this.x().accessor(data[i], i, dataset)); + currY = yScale.scale(_this.y().accessor(data[i], i, dataset)); // If values crossed left edge if (prevX < leftX && leftX <= currX) { x1 = leftX - prevX; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 6214e23414..273302507c 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -61,10 +61,7 @@ export module Plots { extent[1] = maxIncludedValue; } } - - return extent; - } private _getEdgeIntersectionPoints(): Point[][] { @@ -84,12 +81,13 @@ export module Plots { var data = dataset.data(); var x1: number, x2: number, y1: number, y2: number; + var prevX: number, prevY: number, currX: number, currY: number; for (var i = 1; i < data.length; i++) { - var prevX = currX || xScale.scale(this.x().accessor(data[i - 1], i - 1, dataset)); - var prevY = currY || yScale.scale(this.y().accessor(data[i - 1], i - 1, dataset)); + prevX = currX || xScale.scale(this.x().accessor(data[i - 1], i - 1, dataset)); + prevY = currY || yScale.scale(this.y().accessor(data[i - 1], i - 1, dataset)); - var currX = xScale.scale(this.x().accessor(data[i], i, dataset)); - var currY = yScale.scale(this.y().accessor(data[i], i, dataset)); + currX = xScale.scale(this.x().accessor(data[i], i, dataset)); + currY = yScale.scale(this.y().accessor(data[i], i, dataset)); // If values crossed left edge if (prevX < leftX && leftX <= currX) { From f9d2e2ee14d3427bd569b7954d39f4470e956ddb Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 19:20:42 -0700 Subject: [PATCH 026/117] [autorangeSmooth] Fixed gruntfile --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index bc9b862fbe..f1ddaa5bd4 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,7 +17,7 @@ module.exports = function(grunt) { } }, test: { - src: ["test/*.ts", "typings/**/*.d.ts", "build/plottable.d.ts"], + src: ["test/**/*.ts", "typings/**/*.d.ts", "build/plottable.d.ts"], outDir: "build/test/", options: { target: "es5", From 7ce6ef9dd794942acedce72d77486858097a4a4c Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 23 Jul 2015 20:00:00 -0700 Subject: [PATCH 027/117] [autorangeSmooth] Written failing tests --- plottable.js | 5 ++- src/plots/linePlot.ts | 6 ++- test/plots/linePlotTests.ts | 76 +++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index 9afeb509d1..b6008c0d8b 100644 --- a/plottable.js +++ b/plottable.js @@ -7919,6 +7919,8 @@ var Plottable; return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + this._updateExtentsForProperty("y"); + this._updateExtentsForProperty("x"); return this; }; Line.prototype._createDrawer = function (dataset) { @@ -7926,7 +7928,7 @@ var Plottable; }; Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); - if (this._autorangeSmooth && this.x && this.x().scale && this.y && this.y().scale) { + if (this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale) { var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); var maxIncludedValue = Math.max.apply(this, includedValues); @@ -7941,6 +7943,7 @@ var Plottable; extent[1] = maxIncludedValue; } } + console.log(extent); return extent; }; Line.prototype._getEdgeIntersectionPoints = function () { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 273302507c..4998ccae26 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -30,6 +30,8 @@ export module Plots { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + this._updateExtentsForProperty("y"); + this._updateExtentsForProperty("x"); return this; } @@ -41,7 +43,7 @@ export module Plots { var extent = super._computeExtent(dataset, accScaleBinding, filter); - if (this._autorangeSmooth && this.x && this.x().scale && this.y && this.y().scale) { + if (this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale) { var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); @@ -61,6 +63,8 @@ export module Plots { extent[1] = maxIncludedValue; } } + console.log(extent); + return extent; } diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index cb1f31b32d..73c321062c 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -330,4 +330,80 @@ describe("Plots", () => { svg.remove(); }); }); + + describe("smooth autoranging", () => { + it("smooth autoranging works", () => { + + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); + + var data = [ + {"x":0.0, "y":-1}, + {"x":1.8, "y":-2}, + ] + + var line = new Plottable.Plots.Line() + .x(function(d) { return d.x; }, xScale) + .y(function(d) { return d.y; }, yScale) + .addDataset(new Plottable.Dataset(data)) + .autorangeMode("y") + + xScale.padProportion(0); + yScale.padProportion(0); + line.renderTo(svg); + + assert.deepEqual(yScale.domain(), [0, 1], + "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); + + line.autorangeSmooth(true); + line.render(); + assert.deepEqual(yScale.domain(), [0, 1], + "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); + + line.autorangeSmooth(false); + assert.deepEqual(yScale.domain(), [0, 1], + "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); + + svg.remove(); + + }); + + it("autoDomaining works", () => { + + + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + + xScale.domain([-0.1, 0.2]); + + var data = [ + {"x":0.0, "y":-1}, + {"x":1.8, "y":-2}, + ] + + var line = new Plottable.Plots.Line() + .x(function(d) { return d.x; }, xScale) + .y(function(d) { return d.y; }, yScale) + .addDataset(new Plottable.Dataset(data)) + .autorangeMode("y") + + line.renderTo(svg); + + line.autorangeSmooth(true); + xScale.autoDomain(); + assert.deepEqual(xScale.domain(), [-0.2, 2], + "autoDomain works even when autoranging is done smoothly"); + + line.autorangeSmooth(false); + assert.deepEqual(xScale.domain(), [-0.2, 2], + "autoDomain works when smooth autoranging is disabled back"); + + svg.remove(); + }); + }); }); From 4325bb6bc9a921cf7b38dc751b8aa1a11e31b63a Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Fri, 24 Jul 2015 12:25:02 -0700 Subject: [PATCH 028/117] [autorangeSmooth] tslint --- plottable.js | 1 - src/plots/linePlot.ts | 2 -- test/plots/linePlotTests.ts | 37 ++++++++++++++++++------------------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/plottable.js b/plottable.js index b6008c0d8b..259dedcfcd 100644 --- a/plottable.js +++ b/plottable.js @@ -7943,7 +7943,6 @@ var Plottable; extent[1] = maxIncludedValue; } } - console.log(extent); return extent; }; Line.prototype._getEdgeIntersectionPoints = function () { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 4998ccae26..af27ee687d 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -63,8 +63,6 @@ export module Plots { extent[1] = maxIncludedValue; } } - console.log(extent); - return extent; } diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 73c321062c..426b9ce34c 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -341,15 +341,15 @@ describe("Plots", () => { xScale.domain([0.1, 1.1]); var data = [ - {"x":0.0, "y":-1}, - {"x":1.8, "y":-2}, - ] + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2}, + ]; - var line = new Plottable.Plots.Line() - .x(function(d) { return d.x; }, xScale) - .y(function(d) { return d.y; }, yScale) - .addDataset(new Plottable.Dataset(data)) - .autorangeMode("y") + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); xScale.padProportion(0); yScale.padProportion(0); @@ -360,6 +360,7 @@ describe("Plots", () => { line.autorangeSmooth(true); line.render(); + // This is actually incorrect, but I don't know exact value to put in assert.deepEqual(yScale.domain(), [0, 1], "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); @@ -372,8 +373,6 @@ describe("Plots", () => { }); it("autoDomaining works", () => { - - var svg = TestMethods.generateSVG(500, 500); var xScale = new Plottable.Scales.Linear(); @@ -382,15 +381,15 @@ describe("Plots", () => { xScale.domain([-0.1, 0.2]); var data = [ - {"x":0.0, "y":-1}, - {"x":1.8, "y":-2}, - ] - - var line = new Plottable.Plots.Line() - .x(function(d) { return d.x; }, xScale) - .y(function(d) { return d.y; }, yScale) - .addDataset(new Plottable.Dataset(data)) - .autorangeMode("y") + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2}, + ]; + + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); line.renderTo(svg); From 1ac0377b4c517b49fe93224b2aa99fcf3c9b4d10 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 28 Jul 2015 15:02:01 -0700 Subject: [PATCH 029/117] [autorangeSmooth] TDD: caught edge cases in failing tests --- plottable.js | 2 - src/plots/linePlot.ts | 2 - test/plots/linePlotTests.ts | 140 ++++++++++++++++++++++-------------- 3 files changed, 87 insertions(+), 57 deletions(-) diff --git a/plottable.js b/plottable.js index 259dedcfcd..4fd704b262 100644 --- a/plottable.js +++ b/plottable.js @@ -7919,8 +7919,6 @@ var Plottable; return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; - this._updateExtentsForProperty("y"); - this._updateExtentsForProperty("x"); return this; }; Line.prototype._createDrawer = function (dataset) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index af27ee687d..d159736d94 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -30,8 +30,6 @@ export module Plots { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; - this._updateExtentsForProperty("y"); - this._updateExtentsForProperty("x"); return this; } diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 426b9ce34c..45b189218b 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -331,78 +331,112 @@ describe("Plots", () => { }); }); - describe("smooth autoranging", () => { - it("smooth autoranging works", () => { + describe("Line Plot", () => { + describe("smooth autoranging", () => { + it("smooth autoranging works", () => { - var svg = TestMethods.generateSVG(500, 500); + var svg = TestMethods.generateSVG(500, 500); - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); - xScale.domain([0.1, 1.1]); + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); - var data = [ - {"x": 0.0, "y": -1}, - {"x": 1.8, "y": -2}, - ]; + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2}, + ]; - var line = new Plottable.Plots.Line(); - line.x(function(d) { return d.x; }, xScale); - line.y(function(d) { return d.y; }, yScale); - line.addDataset(new Plottable.Dataset(data)); - line.autorangeMode("y"); + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); - xScale.padProportion(0); - yScale.padProportion(0); - line.renderTo(svg); + xScale.padProportion(0); + yScale.padProportion(0); + line.renderTo(svg); - assert.deepEqual(yScale.domain(), [0, 1], - "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); + assert.deepEqual(yScale.domain(), [0, 1], "when there are no visible points in the view, the y-scale domain defaults to [0, 1]"); - line.autorangeSmooth(true); - line.render(); - // This is actually incorrect, but I don't know exact value to put in - assert.deepEqual(yScale.domain(), [0, 1], - "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); + line.autorangeSmooth(true); + assert.closeTo(yScale.domain()[0], -1.61, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.05, 0.001, "Smooth autoranging forces the domain to include the line (right)"); - line.autorangeSmooth(false); - assert.deepEqual(yScale.domain(), [0, 1], - "When there are no visible points in the view, the y-scale domain defaults to [0, 1]"); + line.autorangeSmooth(false); + assert.deepEqual(yScale.domain(), [0, 1], "Resetting the smooth autorange works"); - svg.remove(); + xScale.domain([data[0].x, data[1].x]); + assert.deepEqual(yScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge poitns (no smooth)"); - }); + line.autorangeSmooth(true); + assert.deepEqual(yScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); - it("autoDomaining works", () => { - var svg = TestMethods.generateSVG(500, 500); + svg.remove(); - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); + }); - xScale.domain([-0.1, 0.2]); + it("autoDomaining works with smooth autoranging (before rendering)", () => { + var svg = TestMethods.generateSVG(500, 500); - var data = [ - {"x": 0.0, "y": -1}, - {"x": 1.8, "y": -2}, - ]; + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); - var line = new Plottable.Plots.Line(); - line.x(function(d) { return d.x; }, xScale); - line.y(function(d) { return d.y; }, yScale); - line.addDataset(new Plottable.Dataset(data)); - line.autorangeMode("y"); + xScale.domain([-0.1, 0.2]); - line.renderTo(svg); + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2}, + ]; - line.autorangeSmooth(true); - xScale.autoDomain(); - assert.deepEqual(xScale.domain(), [-0.2, 2], - "autoDomain works even when autoranging is done smoothly"); + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); - line.autorangeSmooth(false); - assert.deepEqual(xScale.domain(), [-0.2, 2], - "autoDomain works when smooth autoranging is disabled back"); + line.autorangeSmooth(true); + xScale.autoDomain(); + line.renderTo(svg); - svg.remove(); + assert.deepEqual(xScale.domain(), [-0.2, 2], "autoDomain works even when autoranging is done smoothly"); + + line.autorangeSmooth(false); + assert.deepEqual(xScale.domain(), [-0.2, 2], "autoDomain works when smooth autoranging is disabled back"); + + svg.remove(); + }); + + it("autoDomaining works with smooth autoranging (after rendering)", () => { + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + + xScale.domain([-0.1, 0.2]); + + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2}, + ]; + + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); + + line.renderTo(svg); + + line.autorangeSmooth(true); + xScale.autoDomain(); + + assert.deepEqual(xScale.domain(), [-0.2, 2], "autoDomain works even when autoranging is done smoothly"); + + line.autorangeSmooth(false); + assert.deepEqual(xScale.domain(), [-0.2, 2], "autoDomain works when smooth autoranging is disabled back"); + + svg.remove(); + }); }); }); }); From 980628692427dcf6931ab12ca65c0ea9de6104c7 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 28 Jul 2015 16:41:28 -0700 Subject: [PATCH 030/117] [autorangeSmooth] one edge case remaining --- plottable.js | 30 ++++++++++++++++-------------- src/plots/linePlot.ts | 31 +++++++++++++++++-------------- test/plots/linePlotTests.ts | 4 ++-- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/plottable.js b/plottable.js index 4fd704b262..1729877caf 100644 --- a/plottable.js +++ b/plottable.js @@ -7919,6 +7919,7 @@ var Plottable; return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + this.autorangeMode(this.autorangeMode()); return this; }; Line.prototype._createDrawer = function (dataset) { @@ -7926,20 +7927,21 @@ var Plottable; }; Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); - if (this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale) { - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); - var maxIncludedValue = Math.max.apply(this, includedValues); - var minIncludedValue = Math.min.apply(this, includedValues); - if (extent.length === 0) { - extent = [minIncludedValue, maxIncludedValue]; - } - if (minIncludedValue < extent[0]) { - extent[0] = minIncludedValue; - } - if (maxIncludedValue > extent[1]) { - extent[1] = maxIncludedValue; - } + if (!(this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale)) { + return extent; + } + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); + var maxIncludedValue = Math.max.apply(this, includedValues); + var minIncludedValue = Math.min.apply(this, includedValues); + if (extent.length === 0) { + extent = [minIncludedValue, maxIncludedValue]; + } + if (minIncludedValue < extent[0]) { + extent[0] = minIncludedValue; + } + if (maxIncludedValue > extent[1]) { + extent[1] = maxIncludedValue; } return extent; }; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index d159736d94..2c67f137e8 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -30,6 +30,7 @@ export module Plots { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + this.autorangeMode(this.autorangeMode()); return this; } @@ -41,26 +42,28 @@ export module Plots { var extent = super._computeExtent(dataset, accScaleBinding, filter); - if (this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale) { + if (!(this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale)) { + return extent; + } - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); - var maxIncludedValue = Math.max.apply(this, includedValues); - var minIncludedValue = Math.min.apply(this, includedValues); + var maxIncludedValue = Math.max.apply(this, includedValues); + var minIncludedValue = Math.min.apply(this, includedValues); - if (extent.length === 0) { - extent = [minIncludedValue, maxIncludedValue]; - } + if (extent.length === 0) { + extent = [minIncludedValue, maxIncludedValue]; + } - if (minIncludedValue < extent[0]) { - extent[0] = minIncludedValue; - } + if (minIncludedValue < extent[0]) { + extent[0] = minIncludedValue; + } - if (maxIncludedValue > extent[1]) { - extent[1] = maxIncludedValue; - } + if (maxIncludedValue > extent[1]) { + extent[1] = maxIncludedValue; } + return extent; } diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 45b189218b..d59d422445 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -359,8 +359,8 @@ describe("Plots", () => { assert.deepEqual(yScale.domain(), [0, 1], "when there are no visible points in the view, the y-scale domain defaults to [0, 1]"); line.autorangeSmooth(true); - assert.closeTo(yScale.domain()[0], -1.61, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.05, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.05555, 0.001, "Smooth autoranging forces the domain to include the line (right)"); line.autorangeSmooth(false); assert.deepEqual(yScale.domain(), [0, 1], "Resetting the smooth autorange works"); From bd8edd1277c7b456a930803822441e8c2f395ea3 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 29 Jul 2015 12:34:28 -0700 Subject: [PATCH 031/117] [autorangeSmooth] Fixed all bugs --- plottable.js | 2 +- src/plots/linePlot.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index 1729877caf..cec551e11a 100644 --- a/plottable.js +++ b/plottable.js @@ -7927,7 +7927,7 @@ var Plottable; }; Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); - if (!(this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale)) { + if (!(this._autorangeSmooth && this.y() && this.y().scale && accScaleBinding === this.y())) { return extent; } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 2c67f137e8..19821e4de1 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -42,7 +42,7 @@ export module Plots { var extent = super._computeExtent(dataset, accScaleBinding, filter); - if (!(this._autorangeSmooth && this.x() && this.x().scale && this.y() && this.y().scale)) { + if (!(this._autorangeSmooth && this.y() && this.y().scale && accScaleBinding === this.y())) { return extent; } From 65fd35b2fa57fc46d10a8f66d0dfe1b6003dce37 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 29 Jul 2015 12:45:49 -0700 Subject: [PATCH 032/117] [autorangeSmooth] UnUpdated plottable.d.ts --- plottable.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plottable.d.ts b/plottable.d.ts index 224de2c0ac..9fff280f93 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -1913,7 +1913,7 @@ declare module Plottable { * Additionally, very abnormal fonts may not approximate reasonably. * * @param {boolean} The new text width approximation setting. - * @returns {Plottable.Axes.Numeric} The calling Plottable.Axes.Numeric. + * @returns {Axes.Numeric} The calling Axes.Numeric. */ usesTextWidthApproximation(enable: boolean): Axes.Numeric; } From 3cb4c1c978576c854aa72816a6e7806f015e443d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Fri, 31 Jul 2015 11:43:51 -0700 Subject: [PATCH 033/117] [autorangeSmooth] nice domain enabled --- plottable.d.ts | 5 +++++ plottable.js | 22 +++++++++++++++++++++- src/plots/linePlot.ts | 16 ++++++++++++++++ src/scales/quantitativeScale.ts | 17 ++++++++++++++++- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 9fff280f93..4e4471c213 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -869,6 +869,8 @@ declare module Plottable { * @returns {QuantitativeScale} The calling QuantitativeScale. */ padProportion(padProportion: number): QuantitativeScale; + niceDomain(): boolean; + niceDomain(niceDomainEnabled: boolean): QuantitativeScale; protected _expandSingleValueDomain(singleValueDomain: D[]): D[]; /** * Computes the domain value corresponding to a supplied range value. @@ -3005,6 +3007,9 @@ declare module Plottable { * @constructor */ constructor(); + y(): Plots.AccessorScaleBinding; + y(y: number | Accessor): Plots.Line; + y(y: number | Accessor, yScale: Scale): Plots.Line; autorangeSmooth(): boolean; autorangeSmooth(autorangeSmooth: boolean): Plots.Line; protected _createDrawer(dataset: Dataset): Drawer; diff --git a/plottable.js b/plottable.js index e10e2ebc64..470e778da9 100644 --- a/plottable.js +++ b/plottable.js @@ -1556,6 +1556,7 @@ var Plottable; _super.call(this); this._tickGenerator = function (scale) { return scale.defaultTicks(); }; this._padProportion = 0.05; + this._niceDomainEnabled = true; this._paddingExceptionsProviders = new Plottable.Utils.Set(); } QuantitativeScale.prototype.autoDomain = function () { @@ -1667,7 +1668,17 @@ var Plottable; }); var newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); var newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); - return this._niceDomain([newMin, newMax]); + if (this._niceDomainEnabled) { + return this._niceDomain([newMin, newMax]); + } + return ([newMin, newMax]); + }; + QuantitativeScale.prototype.niceDomain = function (niceDomainEnabled) { + if (niceDomainEnabled == null) { + return this._niceDomainEnabled; + } + this._niceDomainEnabled = niceDomainEnabled; + return this; }; QuantitativeScale.prototype._expandSingleValueDomain = function (singleValueDomain) { return singleValueDomain; @@ -7975,11 +7986,20 @@ var Plottable; this.attr("stroke", new Plottable.Scales.Color().range()[0]); this.attr("stroke-width", "2px"); } + Line.prototype.y = function (y, yScale) { + if (yScale instanceof Plottable.QuantitativeScale) { + yScale.niceDomain(!this._autorangeSmooth); + } + return _super.prototype.y.call(this, y, yScale); + }; Line.prototype.autorangeSmooth = function (autorangeSmooth) { if (autorangeSmooth == null) { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { + this.y().scale.niceDomain(!autorangeSmooth); + } this.autorangeMode(this.autorangeMode()); return this; }; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 19821e4de1..b516fa979e 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -23,6 +23,16 @@ export module Plots { this.attr("stroke-width", "2px"); } + public y(): Plots.AccessorScaleBinding; + public y(y: number | Accessor): Plots.Line; + public y(y: number | Accessor, yScale: Scale): Plots.Line; + public y(y?: number | Accessor | number | Accessor, yScale?: Scale): any { + if (yScale instanceof QuantitativeScale) { + (>yScale).niceDomain(!this._autorangeSmooth); + } + return super.y(y, yScale); + } + public autorangeSmooth(): boolean; public autorangeSmooth(autorangeSmooth: boolean): Plots.Line; public autorangeSmooth(autorangeSmooth?: boolean): any { @@ -30,6 +40,11 @@ export module Plots { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + + if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { + (>this.y().scale).niceDomain(!autorangeSmooth); + } + this.autorangeMode(this.autorangeMode()); return this; } @@ -213,6 +228,7 @@ export module Plots { this.datasets().forEach((dataset) => dataToDraw.set(dataset, [dataset.data()])); return dataToDraw; } + } } } diff --git a/src/scales/quantitativeScale.ts b/src/scales/quantitativeScale.ts index 0ed2c6b279..22a735bfe3 100644 --- a/src/scales/quantitativeScale.ts +++ b/src/scales/quantitativeScale.ts @@ -8,6 +8,7 @@ export class QuantitativeScale extends Scale { private _paddingExceptionsProviders: Utils.Set>; private _domainMin: D; private _domainMax: D; + private _niceDomainEnabled = true; /** * A QuantitativeScale is a Scale that maps number-like values to numbers. @@ -152,7 +153,21 @@ export class QuantitativeScale extends Scale { }); var newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); var newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); - return this._niceDomain([newMin, newMax]); + if (this._niceDomainEnabled) { + return this._niceDomain([newMin, newMax]); + } + return ([newMin, newMax]); + } + + public niceDomain(): boolean; + public niceDomain(niceDomainEnabled: boolean): QuantitativeScale; + public niceDomain(niceDomainEnabled?: boolean): any { + if (niceDomainEnabled == null) { + return this._niceDomainEnabled; + } + + this._niceDomainEnabled = niceDomainEnabled; + return this; } protected _expandSingleValueDomain(singleValueDomain: D[]): D[] { From 8ddcf12de4bc6ba437ec0ee124633190296f5083 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Fri, 31 Jul 2015 11:55:19 -0700 Subject: [PATCH 034/117] [autorangeSmooth] Written failing test --- plottable.d.ts | 6 ++++++ src/scales/quantitativeScale.ts | 6 ++++++ test/scales/linearScaleTests.ts | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index 4e4471c213..8f55c8f218 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -869,7 +869,13 @@ declare module Plottable { * @returns {QuantitativeScale} The calling QuantitativeScale. */ padProportion(padProportion: number): QuantitativeScale; + /** + * Gets whether or not the scale will have a nice domain. + */ niceDomain(): boolean; + /** + * Sets whether or not the scale will have a nice domain. + */ niceDomain(niceDomainEnabled: boolean): QuantitativeScale; protected _expandSingleValueDomain(singleValueDomain: D[]): D[]; /** diff --git a/src/scales/quantitativeScale.ts b/src/scales/quantitativeScale.ts index 22a735bfe3..4777551deb 100644 --- a/src/scales/quantitativeScale.ts +++ b/src/scales/quantitativeScale.ts @@ -159,7 +159,13 @@ export class QuantitativeScale extends Scale { return ([newMin, newMax]); } + /** + * Gets whether or not the scale will have a nice domain. + */ public niceDomain(): boolean; + /** + * Sets whether or not the scale will have a nice domain. + */ public niceDomain(niceDomainEnabled: boolean): QuantitativeScale; public niceDomain(niceDomainEnabled?: boolean): any { if (niceDomainEnabled == null) { diff --git a/test/scales/linearScaleTests.ts b/test/scales/linearScaleTests.ts index 0d951847d3..bd8ec6e182 100644 --- a/test/scales/linearScaleTests.ts +++ b/test/scales/linearScaleTests.ts @@ -120,6 +120,29 @@ describe("Scales", () => { assert.deepEqual(scale.domain(), [-1, 5], "Regular domains still accepted"); }); + describe("nice domain", () => { + it("nice domain setter and getter", () => { + var scale = new Plottable.Scales.Linear(); + + assert.strictEqual(scale.niceDomain(), true, "scales make their domain nice by default"); + assert.strictEqual(scale.niceDomain(false), scale, "setting disabling nice domain returns the scale"); + assert.strictEqual(scale.niceDomain(), false, "the domain is no longer nice"); + }); + + it("nice domain works", () => { + var scale = new Plottable.Scales.Linear(); + scale.addIncludedValuesProvider(function() { + return [1.123123123, 3.123123123]; + }); + + assert.deepEqual(scale.domain(), [1, 3.2], "nice domain works"); + scale.niceDomain(false); + assert.deepEqual(scale.domain(), [1.073123123, 3.173123123], "nice domain can be deactivated"); + scale.niceDomain(true); + assert.deepEqual(scale.domain(), [1, 3.2], "nice domain can be activated back"); + }); + }) + it("custom tick generator", () => { var scale = new Plottable.Scales.Linear(); scale.domain([0, 10]); From 3e0f98b2b4f4e88d9291a079d098e718313ed8d8 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Fri, 31 Jul 2015 12:07:30 -0700 Subject: [PATCH 035/117] [autorangeSmooth] fixed the test --- plottable.js | 1 + src/scales/quantitativeScale.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/plottable.js b/plottable.js index 470e778da9..e7b776feae 100644 --- a/plottable.js +++ b/plottable.js @@ -1678,6 +1678,7 @@ var Plottable; return this._niceDomainEnabled; } this._niceDomainEnabled = niceDomainEnabled; + this._autoDomainIfAutomaticMode(); return this; }; QuantitativeScale.prototype._expandSingleValueDomain = function (singleValueDomain) { diff --git a/src/scales/quantitativeScale.ts b/src/scales/quantitativeScale.ts index 4777551deb..ba37d3eeff 100644 --- a/src/scales/quantitativeScale.ts +++ b/src/scales/quantitativeScale.ts @@ -173,6 +173,7 @@ export class QuantitativeScale extends Scale { } this._niceDomainEnabled = niceDomainEnabled; + this._autoDomainIfAutomaticMode(); return this; } From 57eca57fc9bd3dc1803697c16d2daf888943d05a Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Fri, 31 Jul 2015 12:09:01 -0700 Subject: [PATCH 036/117] [autorangeSmooth] tslint --- test/scales/linearScaleTests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/scales/linearScaleTests.ts b/test/scales/linearScaleTests.ts index bd8ec6e182..d9eecc0eed 100644 --- a/test/scales/linearScaleTests.ts +++ b/test/scales/linearScaleTests.ts @@ -141,7 +141,7 @@ describe("Scales", () => { scale.niceDomain(true); assert.deepEqual(scale.domain(), [1, 3.2], "nice domain can be activated back"); }); - }) + }); it("custom tick generator", () => { var scale = new Plottable.Scales.Linear(); From 3fa4d478526f8ffe2cebb4177af2d3cd51c35abf Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 4 Aug 2015 12:50:35 -0700 Subject: [PATCH 037/117] [autorangeSmooth] niceDomain -> snapsDomain --- plottable.d.ts | 8 ++++---- plottable.js | 16 ++++++++-------- src/plots/linePlot.ts | 4 ++-- src/scales/quantitativeScale.ts | 20 ++++++++++---------- test/scales/linearScaleTests.ts | 10 +++++----- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 8f55c8f218..e31698f8cf 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -870,13 +870,13 @@ declare module Plottable { */ padProportion(padProportion: number): QuantitativeScale; /** - * Gets whether or not the scale will have a nice domain. + * Gets whether or not the scale snaps its domain to nice values. */ - niceDomain(): boolean; + snapsDomain(): boolean; /** - * Sets whether or not the scale will have a nice domain. + * Sets whether or not the scale snaps its domain to nice values. */ - niceDomain(niceDomainEnabled: boolean): QuantitativeScale; + snapsDomain(snapsDomain: boolean): QuantitativeScale; protected _expandSingleValueDomain(singleValueDomain: D[]): D[]; /** * Computes the domain value corresponding to a supplied range value. diff --git a/plottable.js b/plottable.js index e7b776feae..6067805c55 100644 --- a/plottable.js +++ b/plottable.js @@ -1556,7 +1556,7 @@ var Plottable; _super.call(this); this._tickGenerator = function (scale) { return scale.defaultTicks(); }; this._padProportion = 0.05; - this._niceDomainEnabled = true; + this._snapsDomain = true; this._paddingExceptionsProviders = new Plottable.Utils.Set(); } QuantitativeScale.prototype.autoDomain = function () { @@ -1668,16 +1668,16 @@ var Plottable; }); var newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); var newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); - if (this._niceDomainEnabled) { + if (this._snapsDomain) { return this._niceDomain([newMin, newMax]); } return ([newMin, newMax]); }; - QuantitativeScale.prototype.niceDomain = function (niceDomainEnabled) { - if (niceDomainEnabled == null) { - return this._niceDomainEnabled; + QuantitativeScale.prototype.snapsDomain = function (snapsDomain) { + if (snapsDomain == null) { + return this._snapsDomain; } - this._niceDomainEnabled = niceDomainEnabled; + this._snapsDomain = snapsDomain; this._autoDomainIfAutomaticMode(); return this; }; @@ -7989,7 +7989,7 @@ var Plottable; } Line.prototype.y = function (y, yScale) { if (yScale instanceof Plottable.QuantitativeScale) { - yScale.niceDomain(!this._autorangeSmooth); + yScale.snapsDomain(!this._autorangeSmooth); } return _super.prototype.y.call(this, y, yScale); }; @@ -7999,7 +7999,7 @@ var Plottable; } this._autorangeSmooth = autorangeSmooth; if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { - this.y().scale.niceDomain(!autorangeSmooth); + this.y().scale.snapsDomain(!autorangeSmooth); } this.autorangeMode(this.autorangeMode()); return this; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index b516fa979e..d2001755be 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -28,7 +28,7 @@ export module Plots { public y(y: number | Accessor, yScale: Scale): Plots.Line; public y(y?: number | Accessor | number | Accessor, yScale?: Scale): any { if (yScale instanceof QuantitativeScale) { - (>yScale).niceDomain(!this._autorangeSmooth); + (>yScale).snapsDomain(!this._autorangeSmooth); } return super.y(y, yScale); } @@ -42,7 +42,7 @@ export module Plots { this._autorangeSmooth = autorangeSmooth; if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { - (>this.y().scale).niceDomain(!autorangeSmooth); + (>this.y().scale).snapsDomain(!autorangeSmooth); } this.autorangeMode(this.autorangeMode()); diff --git a/src/scales/quantitativeScale.ts b/src/scales/quantitativeScale.ts index ba37d3eeff..30b4a85e45 100644 --- a/src/scales/quantitativeScale.ts +++ b/src/scales/quantitativeScale.ts @@ -8,7 +8,7 @@ export class QuantitativeScale extends Scale { private _paddingExceptionsProviders: Utils.Set>; private _domainMin: D; private _domainMax: D; - private _niceDomainEnabled = true; + private _snapsDomain = true; /** * A QuantitativeScale is a Scale that maps number-like values to numbers. @@ -153,26 +153,26 @@ export class QuantitativeScale extends Scale { }); var newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); var newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); - if (this._niceDomainEnabled) { + if (this._snapsDomain) { return this._niceDomain([newMin, newMax]); } return ([newMin, newMax]); } /** - * Gets whether or not the scale will have a nice domain. + * Gets whether or not the scale snaps its domain to nice values. */ - public niceDomain(): boolean; + public snapsDomain(): boolean; /** - * Sets whether or not the scale will have a nice domain. + * Sets whether or not the scale snaps its domain to nice values. */ - public niceDomain(niceDomainEnabled: boolean): QuantitativeScale; - public niceDomain(niceDomainEnabled?: boolean): any { - if (niceDomainEnabled == null) { - return this._niceDomainEnabled; + public snapsDomain(snapsDomain: boolean): QuantitativeScale; + public snapsDomain(snapsDomain?: boolean): any { + if (snapsDomain == null) { + return this._snapsDomain; } - this._niceDomainEnabled = niceDomainEnabled; + this._snapsDomain = snapsDomain; this._autoDomainIfAutomaticMode(); return this; } diff --git a/test/scales/linearScaleTests.ts b/test/scales/linearScaleTests.ts index d9eecc0eed..97fae01da6 100644 --- a/test/scales/linearScaleTests.ts +++ b/test/scales/linearScaleTests.ts @@ -124,9 +124,9 @@ describe("Scales", () => { it("nice domain setter and getter", () => { var scale = new Plottable.Scales.Linear(); - assert.strictEqual(scale.niceDomain(), true, "scales make their domain nice by default"); - assert.strictEqual(scale.niceDomain(false), scale, "setting disabling nice domain returns the scale"); - assert.strictEqual(scale.niceDomain(), false, "the domain is no longer nice"); + assert.strictEqual(scale.snapsDomain(), true, "scales make their domain nice by default"); + assert.strictEqual(scale.snapsDomain(false), scale, "setting disabling nice domain returns the scale"); + assert.strictEqual(scale.snapsDomain(), false, "the domain is no longer nice"); }); it("nice domain works", () => { @@ -136,9 +136,9 @@ describe("Scales", () => { }); assert.deepEqual(scale.domain(), [1, 3.2], "nice domain works"); - scale.niceDomain(false); + scale.snapsDomain(false); assert.deepEqual(scale.domain(), [1.073123123, 3.173123123], "nice domain can be deactivated"); - scale.niceDomain(true); + scale.snapsDomain(true); assert.deepEqual(scale.domain(), [1, 3.2], "nice domain can be activated back"); }); }); From edf21de44f9e76e69c7ead7f3c561ddff54e7369 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 4 Aug 2015 12:56:05 -0700 Subject: [PATCH 038/117] [autorangeSmooth] TSDoc --- plottable.d.ts | 9 +++++++++ src/plots/linePlot.ts | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index e31698f8cf..0a67a0a3ef 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3016,7 +3016,16 @@ declare module Plottable { y(): Plots.AccessorScaleBinding; y(y: number | Accessor): Plots.Line; y(y: number | Accessor, yScale: Scale): Plots.Line; + /** + * Gets whether or not the autoranging is done smoothly. + */ autorangeSmooth(): boolean; + /** + * Sets whether or not the autorange is done smoothly. + * + * Smooth autoranging is done by making sure lines always exit on the left / right side of the plot + * and deactivating the nice domain feature on the scales + */ autorangeSmooth(autorangeSmooth: boolean): Plots.Line; protected _createDrawer(dataset: Dataset): Drawer; protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[]; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index d2001755be..5ce4bc36f4 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -33,7 +33,16 @@ export module Plots { return super.y(y, yScale); } + /** + * Gets whether or not the autoranging is done smoothly. + */ public autorangeSmooth(): boolean; + /** + * Sets whether or not the autorange is done smoothly. + * + * Smooth autoranging is done by making sure lines always exit on the left / right side of the plot + * and deactivating the nice domain feature on the scales + */ public autorangeSmooth(autorangeSmooth: boolean): Plots.Line; public autorangeSmooth(autorangeSmooth?: boolean): any { if (autorangeSmooth == null) { From 7138337583f98a3da2aea56ffa5c6d13076e55d2 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 14:55:11 -0700 Subject: [PATCH 039/117] [autorangeSmooth] bumped version number --- plottable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index d8ded30cbe..ea1b3ddc76 100644 --- a/plottable.js +++ b/plottable.js @@ -1,5 +1,5 @@ /*! -Plottable 1.5.2 (https://github.com/palantir/plottable) +Plottable 1.6.1 (https://github.com/palantir/plottable) Copyright 2014-2015 Palantir Technologies Licensed under MIT (https://github.com/palantir/plottable/blob/master/LICENSE) */ @@ -900,7 +900,7 @@ var Plottable; /// var Plottable; (function (Plottable) { - Plottable.version = "1.5.2"; + Plottable.version = "1.6.1"; })(Plottable || (Plottable = {})); /// From 7004143ce4dab12948618a770aea8f67d8579488 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 20:29:58 -0700 Subject: [PATCH 040/117] [autorangeSmooth] remodelled the asserts --- plottable.js | 11 ++++++++++- src/plots/linePlot.ts | 14 +++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index ea1b3ddc76..019f2a0030 100644 --- a/plottable.js +++ b/plottable.js @@ -8170,7 +8170,16 @@ var Plottable; }; Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); - if (!(this._autorangeSmooth && this.y() && this.y().scale && accScaleBinding === this.y())) { + if (!this._autorangeSmooth) { + return extent; + } + if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { + return extent; + } + if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { + return extent; + } + if (!(accScaleBinding.scale)) { return extent; } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 62c16943d0..085b028e8f 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -102,7 +102,19 @@ export module Plots { var extent = super._computeExtent(dataset, accScaleBinding, filter); - if (!(this._autorangeSmooth && this.y() && this.y().scale && accScaleBinding === this.y())) { + if (!this._autorangeSmooth) { + return extent; + } + + if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { + return extent; + } + + if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { + return extent; + } + + if (!(accScaleBinding.scale)) { return extent; } From ed0da4192064e55889b263d78a47c37c13964fe7 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 21:00:13 -0700 Subject: [PATCH 041/117] [autorangeSmooth] checkpoint the idea with up down points included as well --- plottable.js | 22 +++++++++++++++------- src/plots/linePlot.ts | 29 +++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/plottable.js b/plottable.js index 019f2a0030..d4fd505145 100644 --- a/plottable.js +++ b/plottable.js @@ -8179,11 +8179,15 @@ var Plottable; if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { return extent; } + if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { + return extent; + } if (!(accScaleBinding.scale)) { return extent; } - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); + var direction = this.autorangeMode(); + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(direction); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point[direction]; }); var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); if (extent.length === 0) { @@ -8197,16 +8201,18 @@ var Plottable; } return extent; }; - Line.prototype._getEdgeIntersectionPoints = function () { + Line.prototype._getEdgeIntersectionPoints = function (direction) { var _this = this; - if (!(this.y().scale instanceof Plottable.QuantitativeScale)) { - return [[], []]; + if (!(this.y().scale instanceof Plottable.QuantitativeScale && this.x().scale instanceof Plottable.QuantitativeScale)) { + return [[], [], [], []]; } var yScale = this.y().scale; var xScale = this.x().scale; var intersectionPoints = [[], []]; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); + var downY = yScale.scale(yScale.domain()[0]); + var upY = yScale.scale(yScale.domain()[1]); this.datasets().forEach(function (dataset) { var data = dataset.data(); var x1, x2, y1, y2; @@ -8217,7 +8223,7 @@ var Plottable; currX = xScale.scale(_this.x().accessor(data[i], i, dataset)); currY = yScale.scale(_this.y().accessor(data[i], i, dataset)); // If values crossed left edge - if (prevX < leftX && leftX <= currX) { + if ((prevX < leftX) === (leftX <= currX)) { x1 = leftX - prevX; x2 = currX - prevX; y2 = currY - prevY; @@ -8228,7 +8234,7 @@ var Plottable; }); } // If values crossed right edge - if (prevX < rightX && rightX <= currX) { + if ((prevX < rightX) === (rightX <= currX)) { x1 = rightX - prevX; x2 = currX - prevX; y2 = currY - prevY; @@ -8241,6 +8247,8 @@ var Plottable; } ; }); + intersectionPoints.push([]); + intersectionPoints.push([]); return intersectionPoints; }; Line.prototype._getResetYFunction = function () { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 085b028e8f..05e1194295 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -114,12 +114,18 @@ export module Plots { return extent; } + if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { + return extent; + } + if (!(accScaleBinding.scale)) { return extent; } - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + var direction = this.autorangeMode(); + + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(direction); + var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point: any) => point[direction]); var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); @@ -139,10 +145,10 @@ export module Plots { return extent; } - private _getEdgeIntersectionPoints(): Point[][] { + private _getEdgeIntersectionPoints(direction: string): Point[][] { - if (!(this.y().scale instanceof QuantitativeScale)) { - return [[], []]; + if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { + return [[], [], [], []]; } var yScale = >this.y().scale; @@ -151,8 +157,10 @@ export module Plots { var intersectionPoints: Point[][] = [[], []]; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); - this.datasets().forEach((dataset) => { + var downY = yScale.scale(yScale.domain()[0]); + var upY = yScale.scale(yScale.domain()[1]); + this.datasets().forEach((dataset) => { var data = dataset.data(); var x1: number, x2: number, y1: number, y2: number; @@ -165,7 +173,7 @@ export module Plots { currY = yScale.scale(this.y().accessor(data[i], i, dataset)); // If values crossed left edge - if (prevX < leftX && leftX <= currX) { + if ((prevX < leftX) === (leftX <= currX)) { x1 = leftX - prevX; x2 = currX - prevX; y2 = currY - prevY; @@ -178,7 +186,7 @@ export module Plots { } // If values crossed right edge - if (prevX < rightX && rightX <= currX) { + if ((prevX < rightX) === (rightX <= currX)) { x1 = rightX - prevX; x2 = currX - prevX; y2 = currY - prevY; @@ -189,9 +197,14 @@ export module Plots { y: yScale.invert(prevY + y1) }); } + + // If values crossed upper edge }; }); + intersectionPoints.push([]); + intersectionPoints.push([]); + return intersectionPoints; } From 8ed993602c1f751568a2806e1aa3caf230b7158d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 21:39:13 -0700 Subject: [PATCH 042/117] [autorangeSmooth] checkpoint added points of intersection for the top and bottom edges --- plottable.js | 35 +++++++++++++++++++++++++++++------ src/plots/linePlot.ts | 42 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/plottable.js b/plottable.js index d4fd505145..50c9cda160 100644 --- a/plottable.js +++ b/plottable.js @@ -8186,8 +8186,11 @@ var Plottable; return extent; } var direction = this.autorangeMode(); - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(direction); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point[direction]; }); + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + var includedValues = direction === "y" ? + edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) : + edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]); + includedValues = includedValues.map(function (point) { return point[direction]; }); var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); if (extent.length === 0) { @@ -8201,14 +8204,14 @@ var Plottable; } return extent; }; - Line.prototype._getEdgeIntersectionPoints = function (direction) { + Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; if (!(this.y().scale instanceof Plottable.QuantitativeScale && this.x().scale instanceof Plottable.QuantitativeScale)) { return [[], [], [], []]; } var yScale = this.y().scale; var xScale = this.x().scale; - var intersectionPoints = [[], []]; + var intersectionPoints = [[], [], [], []]; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); var downY = yScale.scale(yScale.domain()[0]); @@ -8244,11 +8247,31 @@ var Plottable; y: yScale.invert(prevY + y1) }); } + // If values crossed upper edge + if ((prevY < upY) === (upY <= currY)) { + x2 = currX - prevX; + y1 = upY - prevY; + y2 = currY - prevY; + x1 = y1 * x2 / y2; + intersectionPoints[2].push({ + x: xScale.invert(prevX + x1), + y: upY + }); + } + // If values crossed lower edge + if ((prevY < downY) === (downY <= currY)) { + x2 = currX - prevX; + y1 = downY - prevY; + y2 = currY - prevY; + x1 = y1 * x2 / y2; + intersectionPoints[3].push({ + x: xScale.invert(prevX + x1), + y: downY + }); + } } ; }); - intersectionPoints.push([]); - intersectionPoints.push([]); return intersectionPoints; }; Line.prototype._getResetYFunction = function () { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 05e1194295..425fb1d040 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -106,6 +106,7 @@ export module Plots { return extent; } + if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { return extent; } @@ -122,10 +123,14 @@ export module Plots { return extent; } + var direction = this.autorangeMode(); - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(direction); - var includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point: any) => point[direction]); + var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + var includedValues = direction === "y" ? + edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) : + edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]); + includedValues = includedValues.map((point: any) => point[direction]); var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); @@ -145,16 +150,16 @@ export module Plots { return extent; } - private _getEdgeIntersectionPoints(direction: string): Point[][] { + private _getEdgeIntersectionPoints(): Point[][] { if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { return [[], [], [], []]; } var yScale = >this.y().scale; - var xScale = this.x().scale; + var xScale = >this.x().scale; - var intersectionPoints: Point[][] = [[], []]; + var intersectionPoints: Point[][] = [[], [], [], []]; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); var downY = yScale.scale(yScale.domain()[0]); @@ -199,12 +204,33 @@ export module Plots { } // If values crossed upper edge + if ((prevY < upY) === (upY <= currY)) { + x2 = currX - prevX; + y1 = upY - prevY; + y2 = currY - prevY; + x1 = y1 * x2 / y2; + + intersectionPoints[2].push({ + x: xScale.invert(prevX + x1), + y: upY + }); + } + + // If values crossed lower edge + if ((prevY < downY) === (downY <= currY)) { + x2 = currX - prevX; + y1 = downY - prevY; + y2 = currY - prevY; + x1 = y1 * x2 / y2; + + intersectionPoints[3].push({ + x: xScale.invert(prevX + x1), + y: downY + }); + } }; }); - intersectionPoints.push([]); - intersectionPoints.push([]); - return intersectionPoints; } From 66669573d6fbb3b53fa481accf5c35882eccb840 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 21:45:42 -0700 Subject: [PATCH 043/117] [autorangeSmooth] prettified the code a bit --- plottable.js | 12 +++++++----- src/plots/linePlot.ts | 15 ++++++--------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/plottable.js b/plottable.js index 50c9cda160..cfdb646ce9 100644 --- a/plottable.js +++ b/plottable.js @@ -8185,12 +8185,14 @@ var Plottable; if (!(accScaleBinding.scale)) { return extent; } - var direction = this.autorangeMode(); var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = direction === "y" ? - edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) : - edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]); - includedValues = includedValues.map(function (point) { return point[direction]; }); + var includedValues; + if (this.autorangeMode() === "y") { + includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); + } + else { + includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map(function (point) { return point.x; }); + } var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); if (extent.length === 0) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 425fb1d040..19f7b1b4d1 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -99,7 +99,6 @@ export module Plots { } protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { - var extent = super._computeExtent(dataset, accScaleBinding, filter); if (!this._autorangeSmooth) { @@ -123,14 +122,13 @@ export module Plots { return extent; } - - var direction = this.autorangeMode(); - var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - var includedValues = direction === "y" ? - edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]) : - edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]); - includedValues = includedValues.map((point: any) => point[direction]); + var includedValues: number[]; + if (this.autorangeMode() === "y") { + includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + } else { // === "x" + includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map((point) => point.x); + } var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); @@ -151,7 +149,6 @@ export module Plots { } private _getEdgeIntersectionPoints(): Point[][] { - if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { return [[], [], [], []]; } From 3ec578d0b0867ce630109ad4e8071da6dbc32ab6 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 21:56:03 -0700 Subject: [PATCH 044/117] [autorangeSmooth] code works now but there is a type issue --- plottable.d.ts | 7 +++++-- plottable.js | 9 +++++++++ src/plots/linePlot.ts | 20 +++++++++++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 9f8d9940c9..9cf15cdb73 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3095,9 +3095,12 @@ declare module Plottable { * @constructor */ constructor(); + x(): Plots.AccessorScaleBinding; + x(x: number | Accessor): Line; + x(x: X | Accessor, xScale: Scale): Line; y(): Plots.AccessorScaleBinding; - y(y: number | Accessor): Plots.Line; - y(y: number | Accessor, yScale: Scale): Plots.Line; + y(y: number | Accessor): Line; + y(y: number | Accessor, yScale: Scale): Line; /** * Gets whether or not the autoranging is done smoothly. */ diff --git a/plottable.js b/plottable.js index cfdb646ce9..4c335d1c93 100644 --- a/plottable.js +++ b/plottable.js @@ -8140,6 +8140,12 @@ var Plottable; this.attr("stroke", new Plottable.Scales.Color().range()[0]); this.attr("stroke-width", "2px"); } + Line.prototype.x = function (x, xScale) { + if (xScale instanceof Plottable.QuantitativeScale) { + xScale.snapsDomain(!this._autorangeSmooth); + } + return _super.prototype.x.call(this, x, xScale); + }; Line.prototype.y = function (y, yScale) { if (yScale instanceof Plottable.QuantitativeScale) { yScale.snapsDomain(!this._autorangeSmooth); @@ -8151,6 +8157,9 @@ var Plottable; return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + if (this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { + this.x().scale.snapsDomain(!autorangeSmooth); + } if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { this.y().scale.snapsDomain(!autorangeSmooth); } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 19f7b1b4d1..93022b57aa 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -24,9 +24,19 @@ export module Plots { this.attr("stroke-width", "2px"); } + public x(): Plots.AccessorScaleBinding; + public x(x: number | Accessor): Line; + public x(x: X | Accessor, xScale: Scale): Line; + public x(x?: number | Accessor | X | Accessor, xScale?: Scale): any { + if (xScale instanceof QuantitativeScale) { + (>xScale).snapsDomain(!this._autorangeSmooth); + } + return super.x(x, xScale); + } + public y(): Plots.AccessorScaleBinding; - public y(y: number | Accessor): Plots.Line; - public y(y: number | Accessor, yScale: Scale): Plots.Line; + public y(y: number | Accessor): Line; + public y(y: number | Accessor, yScale: Scale): Line; public y(y?: number | Accessor | number | Accessor, yScale?: Scale): any { if (yScale instanceof QuantitativeScale) { (>yScale).snapsDomain(!this._autorangeSmooth); @@ -51,6 +61,10 @@ export module Plots { } this._autorangeSmooth = autorangeSmooth; + if (this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { + (>this.x().scale).snapsDomain(!autorangeSmooth); + } + if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { (>this.y().scale).snapsDomain(!autorangeSmooth); } @@ -154,7 +168,7 @@ export module Plots { } var yScale = >this.y().scale; - var xScale = >this.x().scale; + var xScale = >this.x().scale; var intersectionPoints: Point[][] = [[], [], [], []]; var leftX = xScale.scale(xScale.domain()[0]); From c19c4bfaa5e27b055f36e919d08b664cdefb4004 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 22:03:20 -0700 Subject: [PATCH 045/117] [autorangeSmooth] fixed type errors --- plottable.js | 7 ++++++- src/plots/linePlot.ts | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/plottable.js b/plottable.js index 4c335d1c93..035c86c48c 100644 --- a/plottable.js +++ b/plottable.js @@ -8144,7 +8144,12 @@ var Plottable; if (xScale instanceof Plottable.QuantitativeScale) { xScale.snapsDomain(!this._autorangeSmooth); } - return _super.prototype.x.call(this, x, xScale); + if (xScale == null) { + return _super.prototype.x.call(this, x); + } + else { + return _super.prototype.x.call(this, x, xScale); + } }; Line.prototype.y = function (y, yScale) { if (yScale instanceof Plottable.QuantitativeScale) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 93022b57aa..3bf33b0c2a 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -31,7 +31,13 @@ export module Plots { if (xScale instanceof QuantitativeScale) { (>xScale).snapsDomain(!this._autorangeSmooth); } - return super.x(x, xScale); + + if (xScale == null) { + return super.x(>x); + } else { + return super.x(>x, xScale); + } + } public y(): Plots.AccessorScaleBinding; @@ -168,7 +174,7 @@ export module Plots { } var yScale = >this.y().scale; - var xScale = >this.x().scale; + var xScale = >this.x().scale; var intersectionPoints: Point[][] = [[], [], [], []]; var leftX = xScale.scale(xScale.domain()[0]); From b6cc351c8f8098b248ce1324871e347ab4564554 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 22:04:17 -0700 Subject: [PATCH 046/117] [autorangeSmooth] removed extra arguments from the y() --- src/plots/linePlot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 3bf33b0c2a..3d32dd7cb4 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -43,7 +43,7 @@ export module Plots { public y(): Plots.AccessorScaleBinding; public y(y: number | Accessor): Line; public y(y: number | Accessor, yScale: Scale): Line; - public y(y?: number | Accessor | number | Accessor, yScale?: Scale): any { + public y(y?: number | Accessor, yScale?: Scale): any { if (yScale instanceof QuantitativeScale) { (>yScale).snapsDomain(!this._autorangeSmooth); } From 89d857edd4a03e19dc3db5a57e5f317d2682a75a Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 22:11:41 -0700 Subject: [PATCH 047/117] [autorangeSmooth] tslint --- src/plots/linePlot.ts | 1 - src/plots/xyPlot.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 3d32dd7cb4..821087ee9d 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -125,7 +125,6 @@ export module Plots { return extent; } - if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { return extent; } diff --git a/src/plots/xyPlot.ts b/src/plots/xyPlot.ts index dd920d7fcb..0beef6de09 100644 --- a/src/plots/xyPlot.ts +++ b/src/plots/xyPlot.ts @@ -337,7 +337,6 @@ export class XYPlot extends Plot { this._updateYExtentsAndAutodomain(); } } - private _adjustXDomainOnChangeFromY() { if (!this._projectorsReady()) { return; } if (this._autoAdjustXScaleDomain) { From b4c6679c80e1ca2f5f919ef4e59f52f1090e5287 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 22:27:19 -0700 Subject: [PATCH 048/117] [autorangeSmooth] amended test comments for domain --- test/scales/linearScaleTests.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/scales/linearScaleTests.ts b/test/scales/linearScaleTests.ts index c3cca9d808..eccf39e0a7 100644 --- a/test/scales/linearScaleTests.ts +++ b/test/scales/linearScaleTests.ts @@ -118,26 +118,26 @@ describe("Scales", () => { assert.deepEqual(scale.domain(), [-1, 5], "Regular domains still accepted"); }); - describe("nice domain", () => { - it("nice domain setter and getter", () => { + describe("domain snapping", () => { + it("domain snapping setter and getter", () => { var scale = new Plottable.Scales.Linear(); - assert.strictEqual(scale.snapsDomain(), true, "scales make their domain nice by default"); - assert.strictEqual(scale.snapsDomain(false), scale, "setting disabling nice domain returns the scale"); - assert.strictEqual(scale.snapsDomain(), false, "the domain is no longer nice"); + assert.strictEqual(scale.snapsDomain(), true, "scales make their domain snap by default"); + assert.strictEqual(scale.snapsDomain(false), scale, "setting disabling domain snapping returns the scale"); + assert.strictEqual(scale.snapsDomain(), false, "the domain is no longer snaps"); }); - it("nice domain works", () => { + it("domain snapping works", () => { var scale = new Plottable.Scales.Linear(); scale.addIncludedValuesProvider(function() { return [1.123123123, 3.123123123]; }); - assert.deepEqual(scale.domain(), [1, 3.2], "nice domain works"); + assert.deepEqual(scale.domain(), [1, 3.2], "domain snapping works"); scale.snapsDomain(false); - assert.deepEqual(scale.domain(), [1.073123123, 3.173123123], "nice domain can be deactivated"); + assert.deepEqual(scale.domain(), [1.073123123, 3.173123123], "domain snapping can be deactivated"); scale.snapsDomain(true); - assert.deepEqual(scale.domain(), [1, 3.2], "nice domain can be activated back"); + assert.deepEqual(scale.domain(), [1, 3.2], "domain snapping can be activated back"); }); }); From 2fffbfa9337953dd0a56f0f64213b7092725792d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 11 Aug 2015 22:42:39 -0700 Subject: [PATCH 049/117] [autorangeSmooth] new test --- test/plots/linePlotTests.ts | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 71fb3ef79f..6d4cedc1af 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -482,6 +482,49 @@ describe("Plots", () => { svg.remove(); }); + + // it("smooth autoranging works for vertical lines", () => { + // var svg = TestMethods.generateSVG(500, 500); + + // var xScale = new Plottable.Scales.Linear(); + // var yScale = new Plottable.Scales.Linear(); + // yScale.domain([0.1, 1.1]); + + // var data = [ + // {"x": 0.0, "y": -1}, + // {"x": 1.8, "y": -2}, + // ]; + + // var line = new Plottable.Plots.Line(); + // line.x(function(d) { return d.x; }, xScale); + // line.y(function(d) { return d.y; }, yScale); + // line.addDataset(new Plottable.Dataset(data)); + // line.autorangeMode("x"); + + // xScale.padProportion(0); + // yScale.padProportion(0); + // line.renderTo(svg); + + // assert.deepEqual(xScale.domain(), [0, 1], "when there are no visible points in the view, the x-scale domain defaults to [0, 1]"); + + // line.autorangeSmooth(true); + // assert.closeTo(xScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); + // assert.closeTo(xScale.domain()[1], -1.05555, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + + // line.autorangeSmooth(false); + // assert.deepEqual(xScale.domain(), [0, 1], "Resetting the smooth autorange works"); + + // xScale.domain([data[0].x, data[1].x]); + // assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge poitns (no smooth)"); + + // line.autorangeSmooth(true); + // assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); + + // svg.remove(); + + // }); + + }); }); }); From 8e52a26846a13e58498c5a8627b34e61ca06ec48 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Mon, 10 Aug 2015 17:37:33 -0700 Subject: [PATCH 050/117] add label() and enabledLabel() for Rectangle plot --- plottable.d.ts | 25 +++++++++ plottable.js | 64 ++++++++++++++++++++++ src/plots/rectanglePlot.ts | 94 ++++++++++++++++++++++++++++++++ test/plots/rectanglePlotTests.ts | 74 +++++++++++++++++++++++++ 4 files changed, 257 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index 165ebe21c2..9de278e2a3 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2896,12 +2896,37 @@ declare module Plottable { * @returns {PlotEntity[]} */ entitiesIn(xRange: Range, yRange: Range): PlotEntity[]; + /** + * Gets the Accessor for label. + */ + label(): AccessorScaleBinding; + /** + * Sets label to the result of an Accessor. + * + * @param {Accessor} label + * @returns {Plots.Rectangle} The calling Rectangle Plot. + */ + label(label: Accessor): Plots.Rectangle; + /** + * Get whether rectangle labels are enabled. + * + * @returns {boolean} Whether rectangles should display labels or not. + */ + labelsEnabled(): boolean; + /** + * Sets whether labels are enabled. + * + * @param {boolean} labelsEnabled + * @returns {Rectangle} The calling Rectangle Plot. + */ + labelsEnabled(enabled: boolean): Plots.Rectangle; protected _propertyProjectors(): AttributeToProjector; protected _pixelPoint(datum: any, index: number, dataset: Dataset): { x: any; y: any; }; protected _getDataToDraw(): Utils.Map; + protected _additionalPaint(time: number): void; } } } diff --git a/plottable.js b/plottable.js index c06755ccf1..8406bae1cd 100644 --- a/plottable.js +++ b/plottable.js @@ -7258,6 +7258,7 @@ var Plottable; */ function Rectangle() { _super.call(this); + this._labelsEnabled = false; this.animator("rectangles", new Plottable.Animators.Null()); this.addClass("rectangle-plot"); } @@ -7439,6 +7440,24 @@ var Plottable; }); return intersected; }; + Rectangle.prototype.label = function (label) { + if (label === undefined) { + return this._propertyBindings.get(Rectangle._LABEL_KEY); + } + this._bindProperty(Rectangle._LABEL_KEY, label, null); + this.render(); + return this; + }; + Rectangle.prototype.labelsEnabled = function (enabled) { + if (enabled === undefined) { + return this._labelsEnabled; + } + else { + this._labelsEnabled = enabled; + this.render(); + return this; + } + }; Rectangle.prototype._propertyProjectors = function () { var attrToProjector = _super.prototype._propertyProjectors.call(this); if (this.x2() != null) { @@ -7488,8 +7507,53 @@ var Plottable; }); return dataToDraw; }; + Rectangle.prototype._additionalPaint = function (time) { + var _this = this; + this._renderArea.select(".label-area").remove(); + if (this._labelsEnabled && this.label() != null) { + Plottable.Utils.Window.setTimeout(function () { return _this._drawLabels(); }, time); + } + }; + Rectangle.prototype._drawLabels = function () { + var _this = this; + var dataToDraw = this._getDataToDraw(); + this.datasets().forEach(function (dataset) { return _this._drawLabel(dataToDraw.get(dataset), dataset); }); + }; + Rectangle.prototype._drawLabel = function (data, dataset) { + var _this = this; + var attrToProjector = this._generateAttrToProjector(); + var labelArea = this._renderArea.append("g").classed("label-area", true); + var measurer = new SVGTypewriter.Measurers.Measurer(labelArea); + var writer = new SVGTypewriter.Writers.Writer(measurer); + data.forEach(function (datum, datumIndex) { + var label = "" + _this.label().accessor(datum, datumIndex, dataset); + var measurement = measurer.measure(label); + var x = attrToProjector["x"](datum, datumIndex, dataset); + var y = attrToProjector["y"](datum, datumIndex, dataset); + var width = attrToProjector["width"](datum, datumIndex, dataset); + var height = attrToProjector["height"](datum, datumIndex, dataset); + if (measurement.height <= height && measurement.width <= width) { + var horizontalOffset = (width - measurement.width) / 2; + var verticalOffset = (height - measurement.height) / 2; + x += horizontalOffset; + y += verticalOffset; + var color = attrToProjector["fill"] == null ? "black" : attrToProjector["fill"](datum, datumIndex, dataset); + var dark = Plottable.Utils.Color.contrast("white", color) * 1.6 < Plottable.Utils.Color.contrast("black", color); + var g = labelArea.append("g").attr("transform", "translate(" + x + "," + y + ")"); + var className = dark ? "dark-label" : "light-label"; + g.classed(className, true); + writer.write(label, measurement.width, measurement.height, { + selection: g, + xAlign: "center", + yAlign: "center", + textRotation: 0 + }); + } + }); + }; Rectangle._X2_KEY = "x2"; Rectangle._Y2_KEY = "y2"; + Rectangle._LABEL_KEY = "label"; return Rectangle; })(Plottable.XYPlot); Plots.Rectangle = Rectangle; diff --git a/src/plots/rectanglePlot.ts b/src/plots/rectanglePlot.ts index 96dc9a21f9..f642b1946e 100644 --- a/src/plots/rectanglePlot.ts +++ b/src/plots/rectanglePlot.ts @@ -5,6 +5,8 @@ export module Plots { export class Rectangle extends XYPlot { private static _X2_KEY = "x2"; private static _Y2_KEY = "y2"; + private static _LABEL_KEY = "label"; + private _labelsEnabled = false; /** * A Rectangle Plot displays rectangles based on the data. @@ -303,6 +305,50 @@ export module Plots { return intersected; } + /** + * Gets the Accessor for label. + */ + public label(): AccessorScaleBinding; + /** + * Sets label to the result of an Accessor. + * + * @param {Accessor} label + * @returns {Plots.Rectangle} The calling Rectangle Plot. + */ + public label(label: Accessor): Plots.Rectangle; + public label(label?: Accessor): any { + if (label === undefined) { + return this._propertyBindings.get(Rectangle._LABEL_KEY); + } + + this._bindProperty(Rectangle._LABEL_KEY, label, null); + this.render(); + return this; + } + + /** + * Get whether rectangle labels are enabled. + * + * @returns {boolean} Whether rectangles should display labels or not. + */ + public labelsEnabled(): boolean; + /** + * Sets whether labels are enabled. + * + * @param {boolean} labelsEnabled + * @returns {Rectangle} The calling Rectangle Plot. + */ + public labelsEnabled(enabled: boolean): Plots.Rectangle; + public labelsEnabled(enabled?: boolean): any { + if (enabled === undefined) { + return this._labelsEnabled; + } else { + this._labelsEnabled = enabled; + this.render(); + return this; + } + } + protected _propertyProjectors(): AttributeToProjector { let attrToProjector = super._propertyProjectors(); if (this.x2() != null) { @@ -354,6 +400,54 @@ export module Plots { }); return dataToDraw; } + + protected _additionalPaint(time: number) { + this._renderArea.select(".label-area").remove(); + if (this._labelsEnabled && this.label() != null) { + Utils.Window.setTimeout(() => this._drawLabels(), time); + } + } + + private _drawLabels() { + let dataToDraw = this._getDataToDraw(); + this.datasets().forEach((dataset) => this._drawLabel(dataToDraw.get(dataset), dataset)); + } + + private _drawLabel(data: any[], dataset: Dataset) { + let attrToProjector = this._generateAttrToProjector(); + let labelArea = this._renderArea.append("g").classed("label-area", true); + let measurer = new SVGTypewriter.Measurers.Measurer(labelArea); + let writer = new SVGTypewriter.Writers.Writer(measurer); + data.forEach((datum, datumIndex) => { + let label = "" + this.label().accessor(datum, datumIndex, dataset); + let measurement = measurer.measure(label); + + let x = attrToProjector["x"](datum, datumIndex, dataset); + let y = attrToProjector["y"](datum, datumIndex, dataset); + let width = attrToProjector["width"](datum, datumIndex, dataset); + let height = attrToProjector["height"](datum, datumIndex, dataset); + + if (measurement.height <= height && measurement.width <= width) { + let horizontalOffset = (width - measurement.width) / 2; + let verticalOffset = (height - measurement.height) / 2; + x += horizontalOffset; + y += verticalOffset; + + let color = attrToProjector["fill"] == null ? "black" : attrToProjector["fill"](datum, datumIndex, dataset); + let dark = Utils.Color.contrast("white", color) * 1.6 < Utils.Color.contrast("black", color); + let g = labelArea.append("g").attr("transform", "translate(" + x + "," + y + ")"); + let className = dark ? "dark-label" : "light-label"; + g.classed(className, true); + + writer.write(label, measurement.width, measurement.height, { + selection: g, + xAlign: "center", + yAlign: "center", + textRotation: 0 + }); + } + }); + } } } } diff --git a/test/plots/rectanglePlotTests.ts b/test/plots/rectanglePlotTests.ts index 3288111fb9..e6d6fae945 100644 --- a/test/plots/rectanglePlotTests.ts +++ b/test/plots/rectanglePlotTests.ts @@ -441,6 +441,80 @@ describe("Plots", () => { svg.remove(); }); + + }); + + describe("Rectangle Plot With Labels", () => { + let svg: d3.Selection; + let rectanglePlot: Plottable.Plots.Rectangle; + let DATA: [any]; + let dataset: Plottable.Dataset; + beforeEach(() => { + let xScale = new Plottable.Scales.Linear(); + let yScale = new Plottable.Scales.Linear(); + svg = TestMethods.generateSVG(SVG_WIDTH / 2, SVG_HEIGHT); + rectanglePlot = new Plottable.Plots.Rectangle(); + DATA = [ + { x: 0, y: 0, x2: 1, y2: 1, val: 1 }, + { x: 0, y: 1, x2: 1, y2: 2, val: 2 } + ]; + dataset = new Plottable.Dataset(DATA); + rectanglePlot.addDataset(dataset); + rectanglePlot.x((d: any) => d.x, xScale) + .y((d: any) => d.y, yScale) + .x2((d: any) => d.x2) + .y2((d: any) => d.y2) + .label((d: any) => d.val) + .renderTo(svg); + }); + + it("rectangle labels disabled by default", () => { + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 0, "by default, no labels are drawn"); + svg.remove(); + }); + + it("rectangle labels render properly", () => { + rectanglePlot.labelsEnabled(true); + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 2, "all labels are drawn"); + texts.forEach((text, i) => { + assert.strictEqual(text, DATA[i].val + "", "label is drawn correctly"); + }); + svg.remove(); + }); + + it("rectangle labels hide if rectangle is too skinny", () => { + rectanglePlot.labelsEnabled(true); + rectanglePlot.label((d: any, i: number) => d.val + ( i !== 0 ? "a really really really long string" : "" )); + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 1, "the second label is too long to be drawn"); + assert.strictEqual(texts[0], "1"); + svg.remove(); + }); + + it("rectangle labels hide if rectangle is too short", () => { + rectanglePlot.labelsEnabled(true); + svg.remove(); + svg = TestMethods.generateSVG(SVG_WIDTH / 2, 30); + rectanglePlot.label((d: any) => d.val); + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 0, "labels are not drawn when rectangles are too short"); + svg.remove(); + }); + + it("rectangle labels are updated on dataset change", () => { + rectanglePlot.labelsEnabled(true); + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 2, "all labels are drawn"); + + let data2 = [{ x: 0, y: 0, x2: 1, y2: 1, val: 5 }]; + dataset.data(data2); + texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 1, "new label is drawn"); + assert.strictEqual(texts[0], "5"); + svg.remove(); + }); }); }); }); From c866e72ef4af34fe72866995a325b05e70b6200f Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Mon, 10 Aug 2015 21:27:14 -0700 Subject: [PATCH 051/117] minor changes --- plottable.js | 8 ++++---- src/plots/barPlot.ts | 2 +- src/plots/piePlot.ts | 2 +- src/plots/rectanglePlot.ts | 4 ++-- test/plots/rectanglePlotTests.ts | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plottable.js b/plottable.js index 8406bae1cd..20e5a80f32 100644 --- a/plottable.js +++ b/plottable.js @@ -6759,7 +6759,7 @@ var Plottable; return this; }; Pie.prototype.labelsEnabled = function (enabled) { - if (enabled === undefined) { + if (enabled == null) { return this._labelsEnabled; } else { @@ -7441,7 +7441,7 @@ var Plottable; return intersected; }; Rectangle.prototype.label = function (label) { - if (label === undefined) { + if (label == null) { return this._propertyBindings.get(Rectangle._LABEL_KEY); } this._bindProperty(Rectangle._LABEL_KEY, label, null); @@ -7449,7 +7449,7 @@ var Plottable; return this; }; Rectangle.prototype.labelsEnabled = function (enabled) { - if (enabled === undefined) { + if (enabled == null) { return this._labelsEnabled; } else { @@ -7814,7 +7814,7 @@ var Plottable; return this; }; Bar.prototype.labelsEnabled = function (enabled) { - if (enabled === undefined) { + if (enabled == null) { return this._labelsEnabled; } else { diff --git a/src/plots/barPlot.ts b/src/plots/barPlot.ts index 1744ce9456..2e6712bf58 100644 --- a/src/plots/barPlot.ts +++ b/src/plots/barPlot.ts @@ -181,7 +181,7 @@ export module Plots { */ public labelsEnabled(enabled: boolean): Bar; public labelsEnabled(enabled?: boolean): any { - if (enabled === undefined) { + if (enabled == null) { return this._labelsEnabled; } else { this._labelsEnabled = enabled; diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 8a7105e9d3..6522ce259a 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -173,7 +173,7 @@ export module Plots { */ public labelsEnabled(enabled: boolean): Pie; public labelsEnabled(enabled?: boolean): any { - if (enabled === undefined) { + if (enabled == null) { return this._labelsEnabled; } else { this._labelsEnabled = enabled; diff --git a/src/plots/rectanglePlot.ts b/src/plots/rectanglePlot.ts index f642b1946e..83cc19af3c 100644 --- a/src/plots/rectanglePlot.ts +++ b/src/plots/rectanglePlot.ts @@ -317,7 +317,7 @@ export module Plots { */ public label(label: Accessor): Plots.Rectangle; public label(label?: Accessor): any { - if (label === undefined) { + if (label == null) { return this._propertyBindings.get(Rectangle._LABEL_KEY); } @@ -340,7 +340,7 @@ export module Plots { */ public labelsEnabled(enabled: boolean): Plots.Rectangle; public labelsEnabled(enabled?: boolean): any { - if (enabled === undefined) { + if (enabled == null) { return this._labelsEnabled; } else { this._labelsEnabled = enabled; diff --git a/test/plots/rectanglePlotTests.ts b/test/plots/rectanglePlotTests.ts index e6d6fae945..363eeaff62 100644 --- a/test/plots/rectanglePlotTests.ts +++ b/test/plots/rectanglePlotTests.ts @@ -445,15 +445,15 @@ describe("Plots", () => { }); describe("Rectangle Plot With Labels", () => { - let svg: d3.Selection; - let rectanglePlot: Plottable.Plots.Rectangle; + let svg: d3.Selection; + let rectanglePlot: Plottable.Plots.Rectangle; let DATA: [any]; let dataset: Plottable.Dataset; beforeEach(() => { let xScale = new Plottable.Scales.Linear(); let yScale = new Plottable.Scales.Linear(); svg = TestMethods.generateSVG(SVG_WIDTH / 2, SVG_HEIGHT); - rectanglePlot = new Plottable.Plots.Rectangle(); + rectanglePlot = new Plottable.Plots.Rectangle(); DATA = [ { x: 0, y: 0, x2: 1, y2: 1, val: 1 }, { x: 0, y: 1, x2: 1, y2: 2, val: 2 } From 003f472087af52c9e87fbe8f1df5b87a716a4979 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Wed, 12 Aug 2015 12:08:23 -0700 Subject: [PATCH 052/117] update per comments --- plottable.d.ts | 2 +- plottable.js | 12 ++++++------ src/plots/barPlot.ts | 2 +- src/plots/piePlot.ts | 2 +- src/plots/rectanglePlot.ts | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 9de278e2a3..30a9108d1d 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2899,7 +2899,7 @@ declare module Plottable { /** * Gets the Accessor for label. */ - label(): AccessorScaleBinding; + label(): Accessor; /** * Sets label to the result of an Accessor. * diff --git a/plottable.js b/plottable.js index 20e5a80f32..f08d2a7000 100644 --- a/plottable.js +++ b/plottable.js @@ -6759,7 +6759,7 @@ var Plottable; return this; }; Pie.prototype.labelsEnabled = function (enabled) { - if (enabled == null) { + if (enabled === undefined) { return this._labelsEnabled; } else { @@ -7259,6 +7259,7 @@ var Plottable; function Rectangle() { _super.call(this); this._labelsEnabled = false; + this._label = null; this.animator("rectangles", new Plottable.Animators.Null()); this.addClass("rectangle-plot"); } @@ -7442,9 +7443,9 @@ var Plottable; }; Rectangle.prototype.label = function (label) { if (label == null) { - return this._propertyBindings.get(Rectangle._LABEL_KEY); + return this._label; } - this._bindProperty(Rectangle._LABEL_KEY, label, null); + this._label = label; this.render(); return this; }; @@ -7526,7 +7527,7 @@ var Plottable; var measurer = new SVGTypewriter.Measurers.Measurer(labelArea); var writer = new SVGTypewriter.Writers.Writer(measurer); data.forEach(function (datum, datumIndex) { - var label = "" + _this.label().accessor(datum, datumIndex, dataset); + var label = "" + _this.label()(datum, datumIndex, dataset); var measurement = measurer.measure(label); var x = attrToProjector["x"](datum, datumIndex, dataset); var y = attrToProjector["y"](datum, datumIndex, dataset); @@ -7553,7 +7554,6 @@ var Plottable; }; Rectangle._X2_KEY = "x2"; Rectangle._Y2_KEY = "y2"; - Rectangle._LABEL_KEY = "label"; return Rectangle; })(Plottable.XYPlot); Plots.Rectangle = Rectangle; @@ -7814,7 +7814,7 @@ var Plottable; return this; }; Bar.prototype.labelsEnabled = function (enabled) { - if (enabled == null) { + if (enabled === undefined) { return this._labelsEnabled; } else { diff --git a/src/plots/barPlot.ts b/src/plots/barPlot.ts index 2e6712bf58..1744ce9456 100644 --- a/src/plots/barPlot.ts +++ b/src/plots/barPlot.ts @@ -181,7 +181,7 @@ export module Plots { */ public labelsEnabled(enabled: boolean): Bar; public labelsEnabled(enabled?: boolean): any { - if (enabled == null) { + if (enabled === undefined) { return this._labelsEnabled; } else { this._labelsEnabled = enabled; diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 6522ce259a..8a7105e9d3 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -173,7 +173,7 @@ export module Plots { */ public labelsEnabled(enabled: boolean): Pie; public labelsEnabled(enabled?: boolean): any { - if (enabled == null) { + if (enabled === undefined) { return this._labelsEnabled; } else { this._labelsEnabled = enabled; diff --git a/src/plots/rectanglePlot.ts b/src/plots/rectanglePlot.ts index 83cc19af3c..b656a728cc 100644 --- a/src/plots/rectanglePlot.ts +++ b/src/plots/rectanglePlot.ts @@ -5,8 +5,8 @@ export module Plots { export class Rectangle extends XYPlot { private static _X2_KEY = "x2"; private static _Y2_KEY = "y2"; - private static _LABEL_KEY = "label"; private _labelsEnabled = false; + private _label: Accessor = null; /** * A Rectangle Plot displays rectangles based on the data. @@ -308,7 +308,7 @@ export module Plots { /** * Gets the Accessor for label. */ - public label(): AccessorScaleBinding; + public label(): Accessor; /** * Sets label to the result of an Accessor. * @@ -318,10 +318,10 @@ export module Plots { public label(label: Accessor): Plots.Rectangle; public label(label?: Accessor): any { if (label == null) { - return this._propertyBindings.get(Rectangle._LABEL_KEY); + return this._label; } - this._bindProperty(Rectangle._LABEL_KEY, label, null); + this._label = label; this.render(); return this; } @@ -419,7 +419,7 @@ export module Plots { let measurer = new SVGTypewriter.Measurers.Measurer(labelArea); let writer = new SVGTypewriter.Writers.Writer(measurer); data.forEach((datum, datumIndex) => { - let label = "" + this.label().accessor(datum, datumIndex, dataset); + let label = "" + this.label()(datum, datumIndex, dataset); let measurement = measurer.measure(label); let x = attrToProjector["x"](datum, datumIndex, dataset); From f9ceb35180353059af1470deb57a0ce2fe15cdb2 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:12:29 -0700 Subject: [PATCH 053/117] [autorangeSmooth] implemented the autorange feature properly --- plottable.d.ts | 2 ++ plottable.js | 23 +++++++++++++++++------ src/plots/linePlot.ts | 23 +++++++++++++++++++---- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 9cf15cdb73..9768257c00 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3101,6 +3101,8 @@ declare module Plottable { y(): Plots.AccessorScaleBinding; y(y: number | Accessor): Line; y(y: number | Accessor, yScale: Scale): Line; + autorangeMode(): string; + autorangeMode(autorangeMode: string): Line; /** * Gets whether or not the autoranging is done smoothly. */ diff --git a/plottable.js b/plottable.js index 035c86c48c..62a5a3905c 100644 --- a/plottable.js +++ b/plottable.js @@ -1,5 +1,5 @@ /*! -Plottable 1.6.1 (https://github.com/palantir/plottable) +Plottable 1.5.2 (https://github.com/palantir/plottable) Copyright 2014-2015 Palantir Technologies Licensed under MIT (https://github.com/palantir/plottable/blob/master/LICENSE) */ @@ -900,7 +900,7 @@ var Plottable; /// var Plottable; (function (Plottable) { - Plottable.version = "1.6.1"; + Plottable.version = "1.5.2"; })(Plottable || (Plottable = {})); /// @@ -8141,7 +8141,7 @@ var Plottable; this.attr("stroke-width", "2px"); } Line.prototype.x = function (x, xScale) { - if (xScale instanceof Plottable.QuantitativeScale) { + if (xScale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "x") { xScale.snapsDomain(!this._autorangeSmooth); } if (xScale == null) { @@ -8152,20 +8152,31 @@ var Plottable; } }; Line.prototype.y = function (y, yScale) { - if (yScale instanceof Plottable.QuantitativeScale) { + if (yScale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "y") { yScale.snapsDomain(!this._autorangeSmooth); } return _super.prototype.y.call(this, y, yScale); }; + Line.prototype.autorangeMode = function (autorangeMode) { + if (this.autorangeSmooth() && autorangeMode === "x" || autorangeMode === "y") { + if (this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "x") { + this.x().scale.snapsDomain(!this.autorangeSmooth()); + } + if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "y") { + this.y().scale.snapsDomain(!this.autorangeSmooth()); + } + } + return _super.prototype.autorangeMode.call(this, autorangeMode); + }; Line.prototype.autorangeSmooth = function (autorangeSmooth) { if (autorangeSmooth == null) { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; - if (this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { + if (this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "x") { this.x().scale.snapsDomain(!autorangeSmooth); } - if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { + if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "y") { this.y().scale.snapsDomain(!autorangeSmooth); } this.autorangeMode(this.autorangeMode()); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 821087ee9d..8a54724cda 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -28,7 +28,7 @@ export module Plots { public x(x: number | Accessor): Line; public x(x: X | Accessor, xScale: Scale): Line; public x(x?: number | Accessor | X | Accessor, xScale?: Scale): any { - if (xScale instanceof QuantitativeScale) { + if (xScale instanceof QuantitativeScale && this.autorangeMode() === "x") { (>xScale).snapsDomain(!this._autorangeSmooth); } @@ -44,12 +44,27 @@ export module Plots { public y(y: number | Accessor): Line; public y(y: number | Accessor, yScale: Scale): Line; public y(y?: number | Accessor, yScale?: Scale): any { - if (yScale instanceof QuantitativeScale) { + if (yScale instanceof QuantitativeScale && this.autorangeMode() === "y") { (>yScale).snapsDomain(!this._autorangeSmooth); } return super.y(y, yScale); } + public autorangeMode(): string; + public autorangeMode(autorangeMode: string): Line; + public autorangeMode(autorangeMode?: string): any { + if (this.autorangeSmooth() && autorangeMode === "x" || autorangeMode === "y") { + if (this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale && this.autorangeMode() === "x") { + (>this.x().scale).snapsDomain(!this.autorangeSmooth()); + } + + if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale && this.autorangeMode() === "y") { + (>this.y().scale).snapsDomain(!this.autorangeSmooth()); + } + } + return super.autorangeMode(autorangeMode); + } + /** * Gets whether or not the autoranging is done smoothly. */ @@ -67,11 +82,11 @@ export module Plots { } this._autorangeSmooth = autorangeSmooth; - if (this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { + if (this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale && this.autorangeMode() === "x") { (>this.x().scale).snapsDomain(!autorangeSmooth); } - if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { + if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale && this.autorangeMode() === "y") { (>this.y().scale).snapsDomain(!autorangeSmooth); } From 63d24e54a2d05c6a2a326223e229dccb7c545d22 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:20:09 -0700 Subject: [PATCH 054/117] [autorangeSmooth] Fixed all tests --- test/plots/linePlotTests.ts | 66 ++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 6d4cedc1af..d3f31171ed 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -388,7 +388,7 @@ describe("Plots", () => { var data = [ {"x": 0.0, "y": -1}, - {"x": 1.8, "y": -2}, + {"x": 1.8, "y": -2} ]; var line = new Plottable.Plots.Line(); @@ -430,7 +430,7 @@ describe("Plots", () => { var data = [ {"x": 0.0, "y": -1}, - {"x": 1.8, "y": -2}, + {"x": 1.8, "y": -2} ]; var line = new Plottable.Plots.Line(); @@ -461,7 +461,7 @@ describe("Plots", () => { var data = [ {"x": 0.0, "y": -1}, - {"x": 1.8, "y": -2}, + {"x": 1.8, "y": -2} ]; var line = new Plottable.Plots.Line(); @@ -483,47 +483,45 @@ describe("Plots", () => { svg.remove(); }); - // it("smooth autoranging works for vertical lines", () => { - // var svg = TestMethods.generateSVG(500, 500); - - // var xScale = new Plottable.Scales.Linear(); - // var yScale = new Plottable.Scales.Linear(); - // yScale.domain([0.1, 1.1]); - - // var data = [ - // {"x": 0.0, "y": -1}, - // {"x": 1.8, "y": -2}, - // ]; + it("smooth autoranging works for vertical lines", () => { + var svg = TestMethods.generateSVG(500, 500); - // var line = new Plottable.Plots.Line(); - // line.x(function(d) { return d.x; }, xScale); - // line.y(function(d) { return d.y; }, yScale); - // line.addDataset(new Plottable.Dataset(data)); - // line.autorangeMode("x"); + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + yScale.domain([0.1, 1.1]); - // xScale.padProportion(0); - // yScale.padProportion(0); - // line.renderTo(svg); + var data = [ + {"x": -2, "y": 1.8}, + {"x": -1, "y": 0.0} + ]; - // assert.deepEqual(xScale.domain(), [0, 1], "when there are no visible points in the view, the x-scale domain defaults to [0, 1]"); + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("x"); - // line.autorangeSmooth(true); - // assert.closeTo(xScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); - // assert.closeTo(xScale.domain()[1], -1.05555, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + xScale.padProportion(0); + yScale.padProportion(0); + line.renderTo(svg); - // line.autorangeSmooth(false); - // assert.deepEqual(xScale.domain(), [0, 1], "Resetting the smooth autorange works"); + assert.deepEqual(xScale.domain(), [0, 1], "when there are no visible points in the view, the x-scale domain defaults to [0, 1]"); - // xScale.domain([data[0].x, data[1].x]); - // assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge poitns (no smooth)"); + line.autorangeSmooth(true); + assert.closeTo(xScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(xScale.domain()[1], -1.05555, 0.001, "smooth autoranging forces the domain to include the line (right)"); - // line.autorangeSmooth(true); - // assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); + line.autorangeSmooth(false); + assert.deepEqual(xScale.domain(), [0, 1], "resetting the smooth autorange works"); - // svg.remove(); + yScale.domain([data[0].y, data[1].y]); + assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge poitns (no smooth)"); - // }); + line.autorangeSmooth(true); + assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); + svg.remove(); + }); }); }); From 1a58c86c10758d9f5f90fc6ef286cee9b27dc1c7 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:24:38 -0700 Subject: [PATCH 055/117] [autorangeSmooth] fixed bug where autorangemode called before autorange smooth was not snapping the domain --- plottable.js | 4 ++-- src/plots/linePlot.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plottable.js b/plottable.js index 62a5a3905c..6519f216f1 100644 --- a/plottable.js +++ b/plottable.js @@ -8159,10 +8159,10 @@ var Plottable; }; Line.prototype.autorangeMode = function (autorangeMode) { if (this.autorangeSmooth() && autorangeMode === "x" || autorangeMode === "y") { - if (this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "x") { + if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { this.x().scale.snapsDomain(!this.autorangeSmooth()); } - if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "y") { + if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { this.y().scale.snapsDomain(!this.autorangeSmooth()); } } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 8a54724cda..9a42b233a3 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -54,11 +54,11 @@ export module Plots { public autorangeMode(autorangeMode: string): Line; public autorangeMode(autorangeMode?: string): any { if (this.autorangeSmooth() && autorangeMode === "x" || autorangeMode === "y") { - if (this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale && this.autorangeMode() === "x") { + if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { (>this.x().scale).snapsDomain(!this.autorangeSmooth()); } - if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale && this.autorangeMode() === "y") { + if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { (>this.y().scale).snapsDomain(!this.autorangeSmooth()); } } From e26bd9f8dce4779f725ecd95690e8ec152178f6a Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:28:28 -0700 Subject: [PATCH 056/117] [autorangeSmooth] written testcase for the previous scenario --- test/plots/linePlotTests.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index d3f31171ed..be18a346d9 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -417,7 +417,35 @@ describe("Plots", () => { assert.deepEqual(yScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); svg.remove(); + }); + + it("smooth autoranging works (called before accessors)", () => { + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2} + ]; + + var line = new Plottable.Plots.Line(); + line.autorangeSmooth(true); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); + + xScale.padProportion(0); + yScale.padProportion(0); + line.renderTo(svg); + + assert.closeTo(yScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.05555, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + + svg.remove(); }); it("autoDomaining works with smooth autoranging (before rendering)", () => { From 37fd46ac48b8827c073f31bf5171ef155e6bf335 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Wed, 12 Aug 2015 16:30:10 -0700 Subject: [PATCH 057/117] minor changes --- plottable.d.ts | 10 ++++++---- src/plots/rectanglePlot.ts | 10 ++++++---- test/plots/rectanglePlotTests.ts | 6 +++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 30a9108d1d..04b3e795a7 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2897,20 +2897,22 @@ declare module Plottable { */ entitiesIn(xRange: Range, yRange: Range): PlotEntity[]; /** - * Gets the Accessor for label. + * Gets the accessor for labels. + * + * @returns {Accessor} */ label(): Accessor; /** - * Sets label to the result of an Accessor. + * Sets the text of labels to the result of an Accessor. * * @param {Accessor} label * @returns {Plots.Rectangle} The calling Rectangle Plot. */ label(label: Accessor): Plots.Rectangle; /** - * Get whether rectangle labels are enabled. + * Gets whether labels are enabled. * - * @returns {boolean} Whether rectangles should display labels or not. + * @returns {boolean} */ labelsEnabled(): boolean; /** diff --git a/src/plots/rectanglePlot.ts b/src/plots/rectanglePlot.ts index b656a728cc..1d0dd82f3d 100644 --- a/src/plots/rectanglePlot.ts +++ b/src/plots/rectanglePlot.ts @@ -306,11 +306,13 @@ export module Plots { } /** - * Gets the Accessor for label. + * Gets the accessor for labels. + * + * @returns {Accessor} */ public label(): Accessor; /** - * Sets label to the result of an Accessor. + * Sets the text of labels to the result of an Accessor. * * @param {Accessor} label * @returns {Plots.Rectangle} The calling Rectangle Plot. @@ -327,9 +329,9 @@ export module Plots { } /** - * Get whether rectangle labels are enabled. + * Gets whether labels are enabled. * - * @returns {boolean} Whether rectangles should display labels or not. + * @returns {boolean} */ public labelsEnabled(): boolean; /** diff --git a/test/plots/rectanglePlotTests.ts b/test/plots/rectanglePlotTests.ts index 363eeaff62..8beb258656 100644 --- a/test/plots/rectanglePlotTests.ts +++ b/test/plots/rectanglePlotTests.ts @@ -455,8 +455,8 @@ describe("Plots", () => { svg = TestMethods.generateSVG(SVG_WIDTH / 2, SVG_HEIGHT); rectanglePlot = new Plottable.Plots.Rectangle(); DATA = [ - { x: 0, y: 0, x2: 1, y2: 1, val: 1 }, - { x: 0, y: 1, x2: 1, y2: 2, val: 2 } + { x: 0, y: 0, x2: 1, y2: 1, val: "1" }, + { x: 0, y: 1, x2: 1, y2: 2, val: "2" } ]; dataset = new Plottable.Dataset(DATA); rectanglePlot.addDataset(dataset); @@ -479,7 +479,7 @@ describe("Plots", () => { let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); assert.lengthOf(texts, 2, "all labels are drawn"); texts.forEach((text, i) => { - assert.strictEqual(text, DATA[i].val + "", "label is drawn correctly"); + assert.strictEqual(text, DATA[i].val, "label is drawn correctly"); }); svg.remove(); }); From 9c578a5424f0613b8d867be251c5123f0a06cd47 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:34:43 -0700 Subject: [PATCH 058/117] [autorangeSmooth] written proper test now without the padding proportion edge case --- test/plots/linePlotTests.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index be18a346d9..9c962d3fac 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -432,18 +432,16 @@ describe("Plots", () => { ]; var line = new Plottable.Plots.Line(); - line.autorangeSmooth(true); line.x(function(d) { return d.x; }, xScale); line.y(function(d) { return d.y; }, yScale); line.addDataset(new Plottable.Dataset(data)); line.autorangeMode("y"); + line.autorangeSmooth(true); - xScale.padProportion(0); - yScale.padProportion(0); line.renderTo(svg); - assert.closeTo(yScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.05555, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); svg.remove(); }); From 732f391929f9ba3ee9f4434609cc1e739d830fa3 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:37:47 -0700 Subject: [PATCH 059/117] [autorangeSmooth] tested all cases of autorangeSmooth calls --- test/plots/linePlotTests.ts | 108 ++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 9c962d3fac..3908d49acf 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -431,15 +431,123 @@ describe("Plots", () => { {"x": 1.8, "y": -2} ]; + var line = new Plottable.Plots.Line(); + line.autorangeSmooth(true); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); + + line.renderTo(svg); + + assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + + svg.remove(); + }); + + it("smooth autoranging works (called before before autorangeMode)", () => { + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); + + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2} + ]; + + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeSmooth(true); + line.autorangeMode("y"); + + line.renderTo(svg); + + assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + + svg.remove(); + }); + + it("smooth autoranging works (called before before rendering)", () => { + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); + + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2} + ]; + var line = new Plottable.Plots.Line(); line.x(function(d) { return d.x; }, xScale); line.y(function(d) { return d.y; }, yScale); line.addDataset(new Plottable.Dataset(data)); line.autorangeMode("y"); + + line.autorangeSmooth(true); + line.renderTo(svg); + + assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + + svg.remove(); + }); + + it("smooth autoranging works (called before after rendering)", () => { + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); + + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2} + ]; + + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); + line.autorangeMode("y"); + + line.renderTo(svg); + line.autorangeSmooth(true); + assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + + svg.remove(); + }); + + it("smooth autoranging works (called before after rendering, before autorangeMode)", () => { + var svg = TestMethods.generateSVG(500, 500); + + var xScale = new Plottable.Scales.Linear(); + var yScale = new Plottable.Scales.Linear(); + xScale.domain([0.1, 1.1]); + + var data = [ + {"x": 0.0, "y": -1}, + {"x": 1.8, "y": -2} + ]; + + var line = new Plottable.Plots.Line(); + line.x(function(d) { return d.x; }, xScale); + line.y(function(d) { return d.y; }, yScale); + line.addDataset(new Plottable.Dataset(data)); line.renderTo(svg); + line.autorangeSmooth(true); + line.autorangeMode("y"); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); From 218067705a2bc233cba4a203b3d3f3dcfefb0ea5 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Wed, 12 Aug 2015 16:51:49 -0700 Subject: [PATCH 060/117] [autorangeSmooth] Refactored the tests --- test/plots/linePlotTests.ts | 70 ++++++++----------------------------- 1 file changed, 14 insertions(+), 56 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 3908d49acf..55346b83be 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -378,12 +378,22 @@ describe("Plots", () => { describe("Line Plot", () => { describe("smooth autoranging", () => { - it("smooth autoranging works", () => { - var svg = TestMethods.generateSVG(500, 500); + var svg: d3.Selection; + var xScale: Plottable.Scales.Linear; + var yScale: Plottable.Scales.Linear; - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); + beforeEach(() => { + svg = TestMethods.generateSVG(500, 500); + xScale = new Plottable.Scales.Linear(); + yScale = new Plottable.Scales.Linear(); + }); + + afterEach(() => { + svg.remove(); + }); + + it("smooth autoranging works", () => { xScale.domain([0.1, 1.1]); var data = [ @@ -415,15 +425,9 @@ describe("Plots", () => { line.autorangeSmooth(true); assert.deepEqual(yScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); - - svg.remove(); }); it("smooth autoranging works (called before accessors)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); xScale.domain([0.1, 1.1]); var data = [ @@ -442,15 +446,9 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); - - svg.remove(); }); it("smooth autoranging works (called before before autorangeMode)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); xScale.domain([0.1, 1.1]); var data = [ @@ -469,15 +467,9 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); - - svg.remove(); }); it("smooth autoranging works (called before before rendering)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); xScale.domain([0.1, 1.1]); var data = [ @@ -496,15 +488,9 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); - - svg.remove(); }); it("smooth autoranging works (called before after rendering)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); xScale.domain([0.1, 1.1]); var data = [ @@ -523,15 +509,9 @@ describe("Plots", () => { line.autorangeSmooth(true); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); - - svg.remove(); }); it("smooth autoranging works (called before after rendering, before autorangeMode)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); xScale.domain([0.1, 1.1]); var data = [ @@ -550,16 +530,9 @@ describe("Plots", () => { line.autorangeMode("y"); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); - - svg.remove(); }); it("autoDomaining works with smooth autoranging (before rendering)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); - xScale.domain([-0.1, 0.2]); var data = [ @@ -581,16 +554,9 @@ describe("Plots", () => { line.autorangeSmooth(false); assert.deepEqual(xScale.domain(), [-0.2, 2], "autoDomain works when smooth autoranging is disabled back"); - - svg.remove(); }); it("autoDomaining works with smooth autoranging (after rendering)", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); - xScale.domain([-0.1, 0.2]); var data = [ @@ -613,15 +579,9 @@ describe("Plots", () => { line.autorangeSmooth(false); assert.deepEqual(xScale.domain(), [-0.2, 2], "autoDomain works when smooth autoranging is disabled back"); - - svg.remove(); }); it("smooth autoranging works for vertical lines", () => { - var svg = TestMethods.generateSVG(500, 500); - - var xScale = new Plottable.Scales.Linear(); - var yScale = new Plottable.Scales.Linear(); yScale.domain([0.1, 1.1]); var data = [ @@ -653,8 +613,6 @@ describe("Plots", () => { line.autorangeSmooth(true); assert.deepEqual(xScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge points (smooth)"); - - svg.remove(); }); }); From 34d6641363cc9f8c14c6a7ee36de91f517dba249 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 13:36:50 -0700 Subject: [PATCH 061/117] [autorangeSmooth] New version of implementing this inside the _extentsForProperty so we don't have to expose anything new --- plottable.d.ts | 2 +- plottable.js | 82 +++++++++++++++++++++++++----------- src/plots/linePlot.ts | 96 ++++++++++++++++++++++++++++++++----------- 3 files changed, 132 insertions(+), 48 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 9768257c00..1f6d00f5b7 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3141,7 +3141,7 @@ declare module Plottable { interpolator(interpolator: "cardinal-closed"): Line; interpolator(interpolator: "monotone"): Line; protected _createDrawer(dataset: Dataset): Drawer; - protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[]; + protected _extentsForProperty(property: string): any[]; protected _getResetYFunction(): (d: any, i: number, dataset: Dataset) => number; protected _generateDrawSteps(): Drawers.DrawStep[]; protected _generateAttrToProjector(): { diff --git a/plottable.js b/plottable.js index 6519f216f1..953f304d10 100644 --- a/plottable.js +++ b/plottable.js @@ -8193,22 +8193,17 @@ var Plottable; Line.prototype._createDrawer = function (dataset) { return new Plottable.Drawers.Line(dataset); }; - Line.prototype._computeExtent = function (dataset, accScaleBinding, filter) { - var extent = _super.prototype._computeExtent.call(this, dataset, accScaleBinding, filter); + Line.prototype._extentsForProperty = function (property) { + // return super._extentsForProperty(property); + var extents = _super.prototype._extentsForProperty.call(this, property); if (!this._autorangeSmooth) { - return extent; - } - if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { - return extent; + return extents; } - if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { - return extent; + if (this.autorangeMode() !== property) { + return extents; } if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { - return extent; - } - if (!(accScaleBinding.scale)) { - return extent; + return extents; } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues; @@ -8220,17 +8215,58 @@ var Plottable; } var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); - if (extent.length === 0) { - extent = [minIncludedValue, maxIncludedValue]; - } - if (minIncludedValue < extent[0]) { - extent[0] = minIncludedValue; - } - if (maxIncludedValue > extent[1]) { - extent[1] = maxIncludedValue; - } - return extent; - }; + extents.forEach(function (extent) { + // When no end-points are in the viewport + if (extent.length === 0) { + extent = [minIncludedValue, maxIncludedValue]; + } + if (minIncludedValue < extent[0]) { + extent[0] = minIncludedValue; + } + if (maxIncludedValue > extent[1]) { + extent[1] = maxIncludedValue; + } + }); + return extents; + }; + // protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { + // var extent = super._computeExtent(dataset, accScaleBinding, filter); + // if (!this._autorangeSmooth) { + // return extent; + // } + // if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { + // return extent; + // } + // if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { + // return extent; + // } + // if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { + // return extent; + // } + // if (!(accScaleBinding.scale)) { + // return extent; + // } + // var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + // var includedValues: number[]; + // if (this.autorangeMode() === "y") { + // includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + // } else { // === "x" + // includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map((point) => point.x); + // } + // var maxIncludedValue = Math.max.apply(this, includedValues); + // var minIncludedValue = Math.min.apply(this, includedValues); + // // Generally when no points are in the viewport (only lines crossing) + // if (extent.length === 0) { + // extent = [minIncludedValue, maxIncludedValue]; + // } + // if (minIncludedValue < extent[0]) { + // extent[0] = minIncludedValue; + // } + // if (maxIncludedValue > extent[1]) { + // extent[1] = maxIncludedValue; + // } + // return extent; + // } Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; if (!(this.y().scale instanceof Plottable.QuantitativeScale && this.x().scale instanceof Plottable.QuantitativeScale)) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 9a42b233a3..0886134e9d 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -133,27 +133,21 @@ export module Plots { return new Plottable.Drawers.Line(dataset); } - protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { - var extent = super._computeExtent(dataset, accScaleBinding, filter); + protected _extentsForProperty(property: string) { + // return super._extentsForProperty(property); - if (!this._autorangeSmooth) { - return extent; - } + var extents = super._extentsForProperty(property); - if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { - return extent; + if (!this._autorangeSmooth) { + return extents; } - if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { - return extent; + if (this.autorangeMode() !== property) { + return extents; } if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { - return extent; - } - - if (!(accScaleBinding.scale)) { - return extent; + return extents; } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); @@ -167,21 +161,75 @@ export module Plots { var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); - if (extent.length === 0) { - extent = [minIncludedValue, maxIncludedValue]; - } + extents.forEach((extent) => { + // When no end-points are in the viewport + if (extent.length === 0) { + extent = [minIncludedValue, maxIncludedValue]; + } - if (minIncludedValue < extent[0]) { - extent[0] = minIncludedValue; - } + if (minIncludedValue < extent[0]) { + extent[0] = minIncludedValue; + } - if (maxIncludedValue > extent[1]) { - extent[1] = maxIncludedValue; - } + if (maxIncludedValue > extent[1]) { + extent[1] = maxIncludedValue; + } + }); + + return extents; - return extent; } + // protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { + // var extent = super._computeExtent(dataset, accScaleBinding, filter); + + // if (!this._autorangeSmooth) { + // return extent; + // } + + // if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { + // return extent; + // } + + // if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { + // return extent; + // } + + // if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { + // return extent; + // } + + // if (!(accScaleBinding.scale)) { + // return extent; + // } + + // var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + // var includedValues: number[]; + // if (this.autorangeMode() === "y") { + // includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + // } else { // === "x" + // includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map((point) => point.x); + // } + + // var maxIncludedValue = Math.max.apply(this, includedValues); + // var minIncludedValue = Math.min.apply(this, includedValues); + + // // Generally when no points are in the viewport (only lines crossing) + // if (extent.length === 0) { + // extent = [minIncludedValue, maxIncludedValue]; + // } + + // if (minIncludedValue < extent[0]) { + // extent[0] = minIncludedValue; + // } + + // if (maxIncludedValue > extent[1]) { + // extent[1] = maxIncludedValue; + // } + + // return extent; + // } + private _getEdgeIntersectionPoints(): Point[][] { if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { return [[], [], [], []]; From 8a579d27725a158c447119fec6b8fb5dd294640c Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 13:47:41 -0700 Subject: [PATCH 062/117] [autorangeSmooth] implemented the _extentsForProperty properly --- plottable.js | 51 +++----------------------------- src/plots/linePlot.ts | 67 +++---------------------------------------- 2 files changed, 8 insertions(+), 110 deletions(-) diff --git a/plottable.js b/plottable.js index 953f304d10..ca6dfc0876 100644 --- a/plottable.js +++ b/plottable.js @@ -8194,7 +8194,6 @@ var Plottable; return new Plottable.Drawers.Line(dataset); }; Line.prototype._extentsForProperty = function (property) { - // return super._extentsForProperty(property); var extents = _super.prototype._extentsForProperty.call(this, property); if (!this._autorangeSmooth) { return extents; @@ -8206,6 +8205,7 @@ var Plottable; return extents; } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + console.log(edgeIntersectionPoints); var includedValues; if (this.autorangeMode() === "y") { includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); @@ -8215,58 +8215,15 @@ var Plottable; } var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); - extents.forEach(function (extent) { + extents = extents.map(function (extent) { // When no end-points are in the viewport if (extent.length === 0) { - extent = [minIncludedValue, maxIncludedValue]; - } - if (minIncludedValue < extent[0]) { - extent[0] = minIncludedValue; - } - if (maxIncludedValue > extent[1]) { - extent[1] = maxIncludedValue; + return [minIncludedValue, maxIncludedValue]; } + return [Math.min(minIncludedValue, extent[0]), Math.max(maxIncludedValue, extent[1])]; }); return extents; }; - // protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { - // var extent = super._computeExtent(dataset, accScaleBinding, filter); - // if (!this._autorangeSmooth) { - // return extent; - // } - // if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { - // return extent; - // } - // if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { - // return extent; - // } - // if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { - // return extent; - // } - // if (!(accScaleBinding.scale)) { - // return extent; - // } - // var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - // var includedValues: number[]; - // if (this.autorangeMode() === "y") { - // includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); - // } else { // === "x" - // includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map((point) => point.x); - // } - // var maxIncludedValue = Math.max.apply(this, includedValues); - // var minIncludedValue = Math.min.apply(this, includedValues); - // // Generally when no points are in the viewport (only lines crossing) - // if (extent.length === 0) { - // extent = [minIncludedValue, maxIncludedValue]; - // } - // if (minIncludedValue < extent[0]) { - // extent[0] = minIncludedValue; - // } - // if (maxIncludedValue > extent[1]) { - // extent[1] = maxIncludedValue; - // } - // return extent; - // } Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; if (!(this.y().scale instanceof Plottable.QuantitativeScale && this.x().scale instanceof Plottable.QuantitativeScale)) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 0886134e9d..be305491ef 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -134,8 +134,6 @@ export module Plots { } protected _extentsForProperty(property: string) { - // return super._extentsForProperty(property); - var extents = super._extentsForProperty(property); if (!this._autorangeSmooth) { @@ -151,6 +149,7 @@ export module Plots { } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); + console.log(edgeIntersectionPoints); var includedValues: number[]; if (this.autorangeMode() === "y") { includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); @@ -161,75 +160,17 @@ export module Plots { var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); - extents.forEach((extent) => { + extents = extents.map((extent) => { // When no end-points are in the viewport if (extent.length === 0) { - extent = [minIncludedValue, maxIncludedValue]; - } - - if (minIncludedValue < extent[0]) { - extent[0] = minIncludedValue; - } - - if (maxIncludedValue > extent[1]) { - extent[1] = maxIncludedValue; + return [minIncludedValue, maxIncludedValue]; } + return [Math.min(minIncludedValue, extent[0]), Math.max(maxIncludedValue, extent[1])]; }); return extents; - } - // protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { - // var extent = super._computeExtent(dataset, accScaleBinding, filter); - - // if (!this._autorangeSmooth) { - // return extent; - // } - - // if (this.autorangeMode() === "x" && accScaleBinding !== this.x()) { - // return extent; - // } - - // if (this.autorangeMode() === "y" && accScaleBinding !== this.y()) { - // return extent; - // } - - // if (this.autorangeMode() !== "x" && this.autorangeMode() !== "y") { - // return extent; - // } - - // if (!(accScaleBinding.scale)) { - // return extent; - // } - - // var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - // var includedValues: number[]; - // if (this.autorangeMode() === "y") { - // includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); - // } else { // === "x" - // includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map((point) => point.x); - // } - - // var maxIncludedValue = Math.max.apply(this, includedValues); - // var minIncludedValue = Math.min.apply(this, includedValues); - - // // Generally when no points are in the viewport (only lines crossing) - // if (extent.length === 0) { - // extent = [minIncludedValue, maxIncludedValue]; - // } - - // if (minIncludedValue < extent[0]) { - // extent[0] = minIncludedValue; - // } - - // if (maxIncludedValue > extent[1]) { - // extent[1] = maxIncludedValue; - // } - - // return extent; - // } - private _getEdgeIntersectionPoints(): Point[][] { if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { return [[], [], [], []]; From b8944eaf876db9fab05a282b75120b070340bcbb Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 13:49:37 -0700 Subject: [PATCH 063/117] [autorangeSmooth] tslint and privatized _computeExtent --- plottable.d.ts | 1 - plottable.js | 1 - src/plots/linePlot.ts | 1 - src/plots/plot.ts | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 1f6d00f5b7..7508301f69 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2519,7 +2519,6 @@ declare module Plottable { protected _updateExtents(): void; protected _updateExtentsForProperty(property: string): void; protected _filterForProperty(property: string): Accessor; - protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[]; /** * Override in subclass to add special extents, such as included values */ diff --git a/plottable.js b/plottable.js index ca6dfc0876..f2c2e6c493 100644 --- a/plottable.js +++ b/plottable.js @@ -8205,7 +8205,6 @@ var Plottable; return extents; } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - console.log(edgeIntersectionPoints); var includedValues; if (this.autorangeMode() === "y") { includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index be305491ef..583ca7beb9 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -149,7 +149,6 @@ export module Plots { } var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); - console.log(edgeIntersectionPoints); var includedValues: number[]; if (this.autorangeMode() === "y") { includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 157571f3ed..f35f98c4ce 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -299,7 +299,7 @@ export class Plot extends Component { extents.set(key, this.datasets().map((dataset) => this._computeExtent(dataset, accScaleBinding, filter))); } - protected _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { + private _computeExtent(dataset: Dataset, accScaleBinding: Plots.AccessorScaleBinding, filter: Accessor): any[] { var accessor = accScaleBinding.accessor; var scale = accScaleBinding.scale; From be710a0fdb4bea646e8454993ebd386145e6fd06 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Thu, 13 Aug 2015 12:57:16 -0700 Subject: [PATCH 064/117] add entitiesAt() for scatter plot --- plottable.d.ts | 7 ++++ plottable.js | 20 +++++++++++ src/plots/scatterPlot.ts | 21 +++++++++++ test/plots/scatterPlotTests.ts | 65 ++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index 165ebe21c2..0d634e4684 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2969,6 +2969,13 @@ declare module Plottable { * @returns {PlotEntity[]} */ entitiesIn(xRange: Range, yRange: Range): PlotEntity[]; + /** + * Gets the Entities at a particular Point. + * + * @param {Point} p + * @returns {PlotEntity[]} + */ + entitiesAt(p: Point): PlotEntity[]; } } } diff --git a/plottable.js b/plottable.js index f498cb5fcd..0007556df7 100644 --- a/plottable.js +++ b/plottable.js @@ -7620,6 +7620,26 @@ var Plottable; return dataXRange.min <= x && x <= dataXRange.max && dataYRange.min <= y && y <= dataYRange.max; }); }; + /** + * Gets the Entities at a particular Point. + * + * @param {Point} p + * @returns {PlotEntity[]} + */ + Scatter.prototype.entitiesAt = function (p) { + var xProjector = Plottable.Plot._scaledAccessor(this.x()); + var yProjector = Plottable.Plot._scaledAccessor(this.y()); + var sizeProjector = Plottable.Plot._scaledAccessor(this.size()); + return this.entities().filter(function (entity) { + var datum = entity.datum; + var index = entity.index; + var dataset = entity.dataset; + var x = xProjector(datum, index, dataset); + var y = yProjector(datum, index, dataset); + var size = sizeProjector(datum, index, dataset); + return x - size / 2 <= p.x && p.x <= x + size / 2 && y - size / 2 <= p.y && p.y <= y + size / 2; + }); + }; Scatter._SIZE_KEY = "size"; Scatter._SYMBOL_KEY = "symbol"; return Scatter; diff --git a/src/plots/scatterPlot.ts b/src/plots/scatterPlot.ts index 85a92f692e..9ea0cd9fe8 100644 --- a/src/plots/scatterPlot.ts +++ b/src/plots/scatterPlot.ts @@ -180,6 +180,27 @@ export module Plots { return dataXRange.min <= x && x <= dataXRange.max && dataYRange.min <= y && y <= dataYRange.max; }); } + + /** + * Gets the Entities at a particular Point. + * + * @param {Point} p + * @returns {PlotEntity[]} + */ + public entitiesAt(p: Point) { + let xProjector = Plot._scaledAccessor(this.x()); + let yProjector = Plot._scaledAccessor(this.y()); + let sizeProjector = Plot._scaledAccessor(this.size()); + return this.entities().filter((entity) => { + let datum = entity.datum; + let index = entity.index; + let dataset = entity.dataset; + let x = xProjector(datum, index, dataset); + let y = yProjector(datum, index, dataset); + let size = sizeProjector(datum, index, dataset); + return x - size / 2 <= p.x && p.x <= x + size / 2 && y - size / 2 <= p.y && p.y <= y + size / 2; + }); + } } } } diff --git a/test/plots/scatterPlotTests.ts b/test/plots/scatterPlotTests.ts index d081f8f309..29ab60240f 100644 --- a/test/plots/scatterPlotTests.ts +++ b/test/plots/scatterPlotTests.ts @@ -214,6 +214,71 @@ describe("Plots", () => { svg.remove(); }); + it("can retrieve entities centered at a given point", () => { + let svg = TestMethods.generateSVG(400, 400); + let xScale = new Plottable.Scales.Linear(); + let yScale = new Plottable.Scales.Linear(); + + let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 1, y: 1}]); + let dataset2 = new Plottable.Dataset([{x: 1, y: 2}, {x: 3, y: 4}]); + let plot = new Plottable.Plots.Scatter(); + plot.x((d: any) => d.x, xScale) + .y((d: any) => d.y, yScale) + .addDataset(dataset) + .addDataset(dataset2); + plot.renderTo(svg); + + let entities = plot.entitiesAt({ x: xScale.scale(1), y: yScale.scale(1) }); + assert.lengthOf(entities, 1, "only one entity has been retrieved"); + assert.deepEqual(entities[0].datum, {x: 1, y: 1}, "correct datum has been retrieved"); + + svg.remove(); + }); + + it("determines whether an entity contains a given point by its size", () => { + let svg = TestMethods.generateSVG(400, 400); + let xScale = new Plottable.Scales.Linear(); + let yScale = new Plottable.Scales.Linear(); + + let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 1, y: 1}]); + let dataset2 = new Plottable.Dataset([{x: 1, y: 2}, {x: 3, y: 4}]); + let plot = new Plottable.Plots.Scatter(); + plot.size(10) + .x((d: any) => d.x, xScale) + .y((d: any) => d.y, yScale) + .addDataset(dataset) + .addDataset(dataset2); + plot.renderTo(svg); + + let entities = plot.entitiesAt({ x: xScale.scale(1) + 5, y: yScale.scale(2) - 5}); + assert.lengthOf(entities, 1, "only one entity has been retrieved"); + assert.deepEqual(entities[0].datum, {x: 1, y: 2}, "correct datum has been retrieved"); + + plot.size(6); + entities = plot.entitiesAt({ x: xScale.scale(1) + 5, y: yScale.scale(2) - 5}); + assert.lengthOf(entities, 0, "none of the entities is retrieved"); + svg.remove(); + }); + + it("returns an empty array when no entities contain a given point", () => { + let svg = TestMethods.generateSVG(400, 400); + let xScale = new Plottable.Scales.Linear(); + let yScale = new Plottable.Scales.Linear(); + + let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 1, y: 1}]); + let dataset2 = new Plottable.Dataset([{x: 1, y: 2}, {x: 3, y: 4}]); + let plot = new Plottable.Plots.Scatter(); + plot.x((d: any) => d.x, xScale) + .y((d: any) => d.y, yScale) + .addDataset(dataset) + .addDataset(dataset2); + plot.renderTo(svg); + + let entities = plot.entitiesAt({ x: xScale.scale(3), y: yScale.scale(3)}); + assert.lengthOf(entities, 0, "none of the entities is retrieved"); + svg.remove(); + }); + it("correctly handles NaN and undefined x and y values", () => { let svg = TestMethods.generateSVG(400, 400); let data = [ From 2c75134cf575cafc6d9882be74c4c581d217b724 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 14:06:44 -0700 Subject: [PATCH 065/117] [autorangeSmooth] Created type instead of array of points to aid readability --- plottable.js | 26 ++++++++++++++++++-------- src/plots/linePlot.ts | 35 ++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/plottable.js b/plottable.js index f2c2e6c493..3be41fd258 100644 --- a/plottable.js +++ b/plottable.js @@ -8207,10 +8207,10 @@ var Plottable; var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues; if (this.autorangeMode() === "y") { - includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map(function (point) { return point.y; }); + includedValues = edgeIntersectionPoints.left.concat(edgeIntersectionPoints.right).map(function (point) { return point.y; }); } else { - includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map(function (point) { return point.x; }); + includedValues = edgeIntersectionPoints.top.concat(edgeIntersectionPoints.bottom).map(function (point) { return point.x; }); } var maxIncludedValue = Math.max.apply(this, includedValues); var minIncludedValue = Math.min.apply(this, includedValues); @@ -8226,11 +8226,21 @@ var Plottable; Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; if (!(this.y().scale instanceof Plottable.QuantitativeScale && this.x().scale instanceof Plottable.QuantitativeScale)) { - return [[], [], [], []]; + return { + top: [], + bottom: [], + left: [], + right: [] + }; } var yScale = this.y().scale; var xScale = this.x().scale; - var intersectionPoints = [[], [], [], []]; + var intersectionPoints = { + top: [], + bottom: [], + left: [], + right: [] + }; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); var downY = yScale.scale(yScale.domain()[0]); @@ -8250,7 +8260,7 @@ var Plottable; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[0].push({ + intersectionPoints.left.push({ x: leftX, y: yScale.invert(prevY + y1) }); @@ -8261,7 +8271,7 @@ var Plottable; x2 = currX - prevX; y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[1].push({ + intersectionPoints.right.push({ x: rightX, y: yScale.invert(prevY + y1) }); @@ -8272,7 +8282,7 @@ var Plottable; y1 = upY - prevY; y2 = currY - prevY; x1 = y1 * x2 / y2; - intersectionPoints[2].push({ + intersectionPoints.top.push({ x: xScale.invert(prevX + x1), y: upY }); @@ -8283,7 +8293,7 @@ var Plottable; y1 = downY - prevY; y2 = currY - prevY; x1 = y1 * x2 / y2; - intersectionPoints[3].push({ + intersectionPoints.bottom.push({ x: xScale.invert(prevX + x1), y: downY }); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 583ca7beb9..c6174a700d 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -2,6 +2,13 @@ module Plottable { export module Plots { + type EdgeIntersection = { + left: Point[], + right: Point[], + top: Point[], + bottom: Point[] + }; + export class Line extends XYPlot { private _interpolator: string | ((points: Array<[number, number]>) => string) = "linear"; @@ -151,9 +158,9 @@ export module Plots { var edgeIntersectionPoints = this._getEdgeIntersectionPoints(); var includedValues: number[]; if (this.autorangeMode() === "y") { - includedValues = edgeIntersectionPoints[0].concat(edgeIntersectionPoints[1]).map((point) => point.y); + includedValues = edgeIntersectionPoints.left.concat(edgeIntersectionPoints.right).map((point) => point.y); } else { // === "x" - includedValues = edgeIntersectionPoints[2].concat(edgeIntersectionPoints[3]).map((point) => point.x); + includedValues = edgeIntersectionPoints.top.concat(edgeIntersectionPoints.bottom).map((point) => point.x); } var maxIncludedValue = Math.max.apply(this, includedValues); @@ -170,15 +177,25 @@ export module Plots { return extents; } - private _getEdgeIntersectionPoints(): Point[][] { + private _getEdgeIntersectionPoints(): EdgeIntersection { if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { - return [[], [], [], []]; + return { + top: [], + bottom: [], + left: [], + right: [] + }; } var yScale = >this.y().scale; var xScale = >this.x().scale; - var intersectionPoints: Point[][] = [[], [], [], []]; + var intersectionPoints: EdgeIntersection = { + top: [], + bottom: [], + left: [], + right: [] + }; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); var downY = yScale.scale(yScale.domain()[0]); @@ -203,7 +220,7 @@ export module Plots { y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[0].push({ + intersectionPoints.left.push({ x: leftX, y: yScale.invert(prevY + y1) }); @@ -216,7 +233,7 @@ export module Plots { y2 = currY - prevY; y1 = x1 * y2 / x2; - intersectionPoints[1].push({ + intersectionPoints.right.push({ x: rightX, y: yScale.invert(prevY + y1) }); @@ -229,7 +246,7 @@ export module Plots { y2 = currY - prevY; x1 = y1 * x2 / y2; - intersectionPoints[2].push({ + intersectionPoints.top.push({ x: xScale.invert(prevX + x1), y: upY }); @@ -242,7 +259,7 @@ export module Plots { y2 = currY - prevY; x1 = y1 * x2 / y2; - intersectionPoints[3].push({ + intersectionPoints.bottom.push({ x: xScale.invert(prevX + x1), y: downY }); From a97a4635a8944981f773eab50356df3601837f40 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 14:08:42 -0700 Subject: [PATCH 066/117] [autorangeSmooth] rearranged the if statement --- plottable.js | 4 ++-- src/plots/linePlot.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plottable.js b/plottable.js index 3be41fd258..a2b07dc89f 100644 --- a/plottable.js +++ b/plottable.js @@ -8173,10 +8173,10 @@ var Plottable; return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; - if (this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "x") { + if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { this.x().scale.snapsDomain(!autorangeSmooth); } - if (this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "y") { + if (this.autorangeMode() === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { this.y().scale.snapsDomain(!autorangeSmooth); } this.autorangeMode(this.autorangeMode()); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index c6174a700d..4d019b8555 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -89,11 +89,11 @@ export module Plots { } this._autorangeSmooth = autorangeSmooth; - if (this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale && this.autorangeMode() === "x") { + if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { (>this.x().scale).snapsDomain(!autorangeSmooth); } - if (this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale && this.autorangeMode() === "y") { + if (this.autorangeMode() === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { (>this.y().scale).snapsDomain(!autorangeSmooth); } From ebeac98f7beee0e4552c2ca0266b39ac90da90b3 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 14:15:30 -0700 Subject: [PATCH 067/117] [autorangeSmooth] renamed up/down to top/botom --- plottable.js | 16 ++++++++-------- src/plots/linePlot.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plottable.js b/plottable.js index 33cbf327b1..fa583f2e56 100644 --- a/plottable.js +++ b/plottable.js @@ -8331,8 +8331,8 @@ var Plottable; }; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); - var downY = yScale.scale(yScale.domain()[0]); - var upY = yScale.scale(yScale.domain()[1]); + var bottomY = yScale.scale(yScale.domain()[0]); + var topY = yScale.scale(yScale.domain()[1]); this.datasets().forEach(function (dataset) { var data = dataset.data(); var x1, x2, y1, y2; @@ -8365,25 +8365,25 @@ var Plottable; }); } // If values crossed upper edge - if ((prevY < upY) === (upY <= currY)) { + if ((prevY < topY) === (topY <= currY)) { x2 = currX - prevX; - y1 = upY - prevY; + y1 = topY - prevY; y2 = currY - prevY; x1 = y1 * x2 / y2; intersectionPoints.top.push({ x: xScale.invert(prevX + x1), - y: upY + y: topY }); } // If values crossed lower edge - if ((prevY < downY) === (downY <= currY)) { + if ((prevY < bottomY) === (bottomY <= currY)) { x2 = currX - prevX; - y1 = downY - prevY; + y1 = bottomY - prevY; y2 = currY - prevY; x1 = y1 * x2 / y2; intersectionPoints.bottom.push({ x: xScale.invert(prevX + x1), - y: downY + y: bottomY }); } } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index a181d4db7b..0cf33b1149 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -198,8 +198,8 @@ export module Plots { }; let leftX = xScale.scale(xScale.domain()[0]); let rightX = xScale.scale(xScale.domain()[1]); - let downY = yScale.scale(yScale.domain()[0]); - let upY = yScale.scale(yScale.domain()[1]); + let bottomY = yScale.scale(yScale.domain()[0]); + let topY = yScale.scale(yScale.domain()[1]); this.datasets().forEach((dataset) => { let data = dataset.data(); @@ -240,28 +240,28 @@ export module Plots { } // If values crossed upper edge - if ((prevY < upY) === (upY <= currY)) { + if ((prevY < topY) === (topY <= currY)) { x2 = currX - prevX; - y1 = upY - prevY; + y1 = topY - prevY; y2 = currY - prevY; x1 = y1 * x2 / y2; intersectionPoints.top.push({ x: xScale.invert(prevX + x1), - y: upY + y: topY }); } // If values crossed lower edge - if ((prevY < downY) === (downY <= currY)) { + if ((prevY < bottomY) === (bottomY <= currY)) { x2 = currX - prevX; - y1 = downY - prevY; + y1 = bottomY - prevY; y2 = currY - prevY; x1 = y1 * x2 / y2; intersectionPoints.bottom.push({ x: xScale.invert(prevX + x1), - y: downY + y: bottomY }); } }; From 3799b19085dbdf83d9715f4e8f8faa108d27516f Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 14:18:34 -0700 Subject: [PATCH 068/117] [autorangeSmooth] tslint --- test/scales/linearScaleTests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/scales/linearScaleTests.ts b/test/scales/linearScaleTests.ts index e64919587f..ef2947baba 100644 --- a/test/scales/linearScaleTests.ts +++ b/test/scales/linearScaleTests.ts @@ -120,7 +120,7 @@ describe("Scales", () => { describe("domain snapping", () => { it("domain snapping setter and getter", () => { - var scale = new Plottable.Scales.Linear(); + let scale = new Plottable.Scales.Linear(); assert.strictEqual(scale.snapsDomain(), true, "scales make their domain snap by default"); assert.strictEqual(scale.snapsDomain(false), scale, "setting disabling domain snapping returns the scale"); @@ -128,7 +128,7 @@ describe("Scales", () => { }); it("domain snapping works", () => { - var scale = new Plottable.Scales.Linear(); + let scale = new Plottable.Scales.Linear(); scale.addIncludedValuesProvider(function() { return [1.123123123, 3.123123123]; }); From ee00c9f5be79363d9f89ef4781e3914374087c04 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Thu, 13 Aug 2015 15:26:13 -0700 Subject: [PATCH 069/117] unit test --- test/plots/scatterPlotTests.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/plots/scatterPlotTests.ts b/test/plots/scatterPlotTests.ts index 29ab60240f..22c902e1fc 100644 --- a/test/plots/scatterPlotTests.ts +++ b/test/plots/scatterPlotTests.ts @@ -220,12 +220,10 @@ describe("Plots", () => { let yScale = new Plottable.Scales.Linear(); let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 1, y: 1}]); - let dataset2 = new Plottable.Dataset([{x: 1, y: 2}, {x: 3, y: 4}]); let plot = new Plottable.Plots.Scatter(); plot.x((d: any) => d.x, xScale) .y((d: any) => d.y, yScale) - .addDataset(dataset) - .addDataset(dataset2); + .addDataset(dataset); plot.renderTo(svg); let entities = plot.entitiesAt({ x: xScale.scale(1), y: yScale.scale(1) }); @@ -241,21 +239,19 @@ describe("Plots", () => { let yScale = new Plottable.Scales.Linear(); let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 1, y: 1}]); - let dataset2 = new Plottable.Dataset([{x: 1, y: 2}, {x: 3, y: 4}]); let plot = new Plottable.Plots.Scatter(); plot.size(10) .x((d: any) => d.x, xScale) .y((d: any) => d.y, yScale) - .addDataset(dataset) - .addDataset(dataset2); + .addDataset(dataset); plot.renderTo(svg); - let entities = plot.entitiesAt({ x: xScale.scale(1) + 5, y: yScale.scale(2) - 5}); + let entities = plot.entitiesAt({ x: xScale.scale(1) + 5, y: yScale.scale(1) - 5}); assert.lengthOf(entities, 1, "only one entity has been retrieved"); - assert.deepEqual(entities[0].datum, {x: 1, y: 2}, "correct datum has been retrieved"); + assert.deepEqual(entities[0].datum, {x: 1, y: 1}, "correct datum has been retrieved"); plot.size(6); - entities = plot.entitiesAt({ x: xScale.scale(1) + 5, y: yScale.scale(2) - 5}); + entities = plot.entitiesAt({ x: xScale.scale(1) + 5, y: yScale.scale(1) - 5}); assert.lengthOf(entities, 0, "none of the entities is retrieved"); svg.remove(); }); @@ -265,17 +261,21 @@ describe("Plots", () => { let xScale = new Plottable.Scales.Linear(); let yScale = new Plottable.Scales.Linear(); - let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 1, y: 1}]); - let dataset2 = new Plottable.Dataset([{x: 1, y: 2}, {x: 3, y: 4}]); + let dataset = new Plottable.Dataset([{x: 0, y: 0}, {x: 200, y: 200}]); + let dataset2 = new Plottable.Dataset([{x: 0, y: 1}, {x: 1, y: 0}]); let plot = new Plottable.Plots.Scatter(); + plot.x((d: any) => d.x, xScale) .y((d: any) => d.y, yScale) .addDataset(dataset) .addDataset(dataset2); plot.renderTo(svg); - let entities = plot.entitiesAt({ x: xScale.scale(3), y: yScale.scale(3)}); - assert.lengthOf(entities, 0, "none of the entities is retrieved"); + let entities = plot.entitiesAt({ x: xScale.scale(0.5), y: yScale.scale(0.5)}); + assert.lengthOf(entities, 3, "all 3 entities containing the point have been retrieved"); + assert.deepEqual(entities[0].datum, {x: 0, y: 0}, "correct datum has been retrieved"); + assert.deepEqual(entities[1].datum, {x: 0, y: 1}, "correct datum has been retrieved"); + assert.deepEqual(entities[2].datum, {x: 1, y: 0}, "correct datum has been retrieved"); svg.remove(); }); From 1a07676b370f9c7578c1c99b75ebadfb0f152843 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 16:49:36 -0700 Subject: [PATCH 070/117] [autorangeSmooth] CR part 1 --- plottable.js | 11 +---------- src/plots/linePlot.ts | 13 +------------ 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/plottable.js b/plottable.js index fa583f2e56..685826b9c5 100644 --- a/plottable.js +++ b/plottable.js @@ -8300,16 +8300,7 @@ var Plottable; else { includedValues = edgeIntersectionPoints.top.concat(edgeIntersectionPoints.bottom).map(function (point) { return point.x; }); } - var maxIncludedValue = Math.max.apply(this, includedValues); - var minIncludedValue = Math.min.apply(this, includedValues); - extents = extents.map(function (extent) { - // When no end-points are in the viewport - if (extent.length === 0) { - return [minIncludedValue, maxIncludedValue]; - } - return [Math.min(minIncludedValue, extent[0]), Math.max(maxIncludedValue, extent[1])]; - }); - return extents; + return extents.map(function (extent) { return d3.extent(d3.merge([extent, includedValues])); }); }; Line.prototype._getEdgeIntersectionPoints = function () { var _this = this; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 0cf33b1149..7c9a0640a4 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -163,18 +163,7 @@ export module Plots { includedValues = edgeIntersectionPoints.top.concat(edgeIntersectionPoints.bottom).map((point) => point.x); } - let maxIncludedValue = Math.max.apply(this, includedValues); - let minIncludedValue = Math.min.apply(this, includedValues); - - extents = extents.map((extent) => { - // When no end-points are in the viewport - if (extent.length === 0) { - return [minIncludedValue, maxIncludedValue]; - } - return [Math.min(minIncludedValue, extent[0]), Math.max(maxIncludedValue, extent[1])]; - }); - - return extents; + return extents.map((extent: [number, number]) => d3.extent(d3.merge([extent, includedValues]))); } private _getEdgeIntersectionPoints(): EdgeIntersection { From 0269cfc889b0f13b79a7bf958b8e978332149a94 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 16:58:15 -0700 Subject: [PATCH 071/117] [autorangeSmooth] correct order of fields in the EdgeIntersection --- plottable.js | 12 ++++++------ src/plots/linePlot.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plottable.js b/plottable.js index 685826b9c5..4bdb212fc2 100644 --- a/plottable.js +++ b/plottable.js @@ -8306,19 +8306,19 @@ var Plottable; var _this = this; if (!(this.y().scale instanceof Plottable.QuantitativeScale && this.x().scale instanceof Plottable.QuantitativeScale)) { return { - top: [], - bottom: [], left: [], - right: [] + right: [], + top: [], + bottom: [] }; } var yScale = this.y().scale; var xScale = this.x().scale; var intersectionPoints = { - top: [], - bottom: [], left: [], - right: [] + right: [], + top: [], + bottom: [] }; var leftX = xScale.scale(xScale.domain()[0]); var rightX = xScale.scale(xScale.domain()[1]); diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 7c9a0640a4..b8cdba7778 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -169,10 +169,10 @@ export module Plots { private _getEdgeIntersectionPoints(): EdgeIntersection { if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { return { - top: [], - bottom: [], left: [], - right: [] + right: [], + top: [], + bottom: [] }; } @@ -180,10 +180,10 @@ export module Plots { let xScale = >this.x().scale; let intersectionPoints: EdgeIntersection = { - top: [], - bottom: [], left: [], - right: [] + right: [], + top: [], + bottom: [] }; let leftX = xScale.scale(xScale.domain()[0]); let rightX = xScale.scale(xScale.domain()[1]); From d080d70a2b7bde2d47e4ea3524660763d74c4a6f Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 16:58:34 -0700 Subject: [PATCH 072/117] [autorangeSmooth] pluralized EdgeIntersections --- src/plots/linePlot.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index b8cdba7778..1416e1f497 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -2,7 +2,7 @@ module Plottable { export module Plots { - type EdgeIntersection = { + type EdgeIntersections = { left: Point[], right: Point[], top: Point[], @@ -166,7 +166,7 @@ export module Plots { return extents.map((extent: [number, number]) => d3.extent(d3.merge([extent, includedValues]))); } - private _getEdgeIntersectionPoints(): EdgeIntersection { + private _getEdgeIntersectionPoints(): EdgeIntersections { if (!(this.y().scale instanceof QuantitativeScale && this.x().scale instanceof QuantitativeScale)) { return { left: [], @@ -179,7 +179,7 @@ export module Plots { let yScale = >this.y().scale; let xScale = >this.x().scale; - let intersectionPoints: EdgeIntersection = { + let intersectionPoints: EdgeIntersections = { left: [], right: [], top: [], From 020cfc4725c548981eb3f328f884d88bb6a4be84 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:17:04 -0700 Subject: [PATCH 073/117] [autorangeSmooth] removed redundant if statement in autorangeMode --- plottable.js | 12 +++++------- src/plots/linePlot.ts | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/plottable.js b/plottable.js index 4bdb212fc2..dcdd3147b4 100644 --- a/plottable.js +++ b/plottable.js @@ -8246,13 +8246,11 @@ var Plottable; return _super.prototype.y.call(this, y, yScale); }; Line.prototype.autorangeMode = function (autorangeMode) { - if (this.autorangeSmooth() && autorangeMode === "x" || autorangeMode === "y") { - if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { - this.x().scale.snapsDomain(!this.autorangeSmooth()); - } - if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { - this.y().scale.snapsDomain(!this.autorangeSmooth()); - } + if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { + this.x().scale.snapsDomain(!this.autorangeSmooth()); + } + if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { + this.y().scale.snapsDomain(!this.autorangeSmooth()); } return _super.prototype.autorangeMode.call(this, autorangeMode); }; diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 1416e1f497..792b04b8db 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -60,14 +60,12 @@ export module Plots { public autorangeMode(): string; public autorangeMode(autorangeMode: string): Line; public autorangeMode(autorangeMode?: string): any { - if (this.autorangeSmooth() && autorangeMode === "x" || autorangeMode === "y") { - if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { - (>this.x().scale).snapsDomain(!this.autorangeSmooth()); - } + if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { + (>this.x().scale).snapsDomain(!this.autorangeSmooth()); + } - if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { - (>this.y().scale).snapsDomain(!this.autorangeSmooth()); - } + if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { + (>this.y().scale).snapsDomain(!this.autorangeSmooth()); } return super.autorangeMode(autorangeMode); } From 77ef2370ca94ca4a24816a98fc69db07c11dbd72 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:28:34 -0700 Subject: [PATCH 074/117] [autorangeSmooth] Made the method extraction work --- plottable.d.ts | 1 + plottable.js | 20 ++++++++++---------- src/plots/linePlot.ts | 22 +++++++++++----------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 86c695b67c..2405590515 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3145,6 +3145,7 @@ declare module Plottable { * and deactivating the nice domain feature on the scales */ autorangeSmooth(autorangeSmooth: boolean): Plots.Line; + _setScaleSnappingForAutorangeSmooth(): void; /** * Gets the interpolation function associated with the plot. * diff --git a/plottable.js b/plottable.js index dcdd3147b4..9c436ce39b 100644 --- a/plottable.js +++ b/plottable.js @@ -8246,27 +8246,27 @@ var Plottable; return _super.prototype.y.call(this, y, yScale); }; Line.prototype.autorangeMode = function (autorangeMode) { - if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { - this.x().scale.snapsDomain(!this.autorangeSmooth()); - } - if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { - this.y().scale.snapsDomain(!this.autorangeSmooth()); + var ret = _super.prototype.autorangeMode.call(this, autorangeMode); + if (autorangeMode != null) { + this._setScaleSnappingForAutorangeSmooth(); } - return _super.prototype.autorangeMode.call(this, autorangeMode); + return ret; }; Line.prototype.autorangeSmooth = function (autorangeSmooth) { if (autorangeSmooth == null) { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + this._setScaleSnappingForAutorangeSmooth(); + return this; + }; + Line.prototype._setScaleSnappingForAutorangeSmooth = function () { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { - this.x().scale.snapsDomain(!autorangeSmooth); + this.x().scale.snapsDomain(!this.autorangeSmooth()); } if (this.autorangeMode() === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { - this.y().scale.snapsDomain(!autorangeSmooth); + this.y().scale.snapsDomain(!this.autorangeSmooth()); } - this.autorangeMode(this.autorangeMode()); - return this; }; Line.prototype.interpolator = function (interpolator) { if (interpolator == null) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 792b04b8db..51c9beea41 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -60,14 +60,13 @@ export module Plots { public autorangeMode(): string; public autorangeMode(autorangeMode: string): Line; public autorangeMode(autorangeMode?: string): any { - if (autorangeMode === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { - (>this.x().scale).snapsDomain(!this.autorangeSmooth()); - } + let ret = super.autorangeMode(autorangeMode); - if (autorangeMode === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { - (>this.y().scale).snapsDomain(!this.autorangeSmooth()); + if (autorangeMode != null) { + this._setScaleSnappingForAutorangeSmooth(); } - return super.autorangeMode(autorangeMode); + + return ret; } /** @@ -86,17 +85,18 @@ export module Plots { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; + this._setScaleSnappingForAutorangeSmooth(); + return this; + } + public _setScaleSnappingForAutorangeSmooth() { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { - (>this.x().scale).snapsDomain(!autorangeSmooth); + (>this.x().scale).snapsDomain(!this.autorangeSmooth()); } if (this.autorangeMode() === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { - (>this.y().scale).snapsDomain(!autorangeSmooth); + (>this.y().scale).snapsDomain(!this.autorangeSmooth()); } - - this.autorangeMode(this.autorangeMode()); - return this; } /** From f447594c626284d983e1a5bb2ccc64f320aa636e Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:31:57 -0700 Subject: [PATCH 075/117] [autorangeSmooth] fixed bug and privatized the setScaleSnapping method --- plottable.d.ts | 1 - plottable.js | 9 +++++---- src/plots/linePlot.ts | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 2405590515..86c695b67c 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3145,7 +3145,6 @@ declare module Plottable { * and deactivating the nice domain feature on the scales */ autorangeSmooth(autorangeSmooth: boolean): Plots.Line; - _setScaleSnappingForAutorangeSmooth(): void; /** * Gets the interpolation function associated with the plot. * diff --git a/plottable.js b/plottable.js index 9c436ce39b..0374d0f024 100644 --- a/plottable.js +++ b/plottable.js @@ -8246,11 +8246,12 @@ var Plottable; return _super.prototype.y.call(this, y, yScale); }; Line.prototype.autorangeMode = function (autorangeMode) { - var ret = _super.prototype.autorangeMode.call(this, autorangeMode); - if (autorangeMode != null) { - this._setScaleSnappingForAutorangeSmooth(); + if (autorangeMode == null) { + return _super.prototype.autorangeMode.call(this); } - return ret; + _super.prototype.autorangeMode.call(this, autorangeMode); + this._setScaleSnappingForAutorangeSmooth(); + return this; }; Line.prototype.autorangeSmooth = function (autorangeSmooth) { if (autorangeSmooth == null) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 51c9beea41..fa4a117b46 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -60,13 +60,13 @@ export module Plots { public autorangeMode(): string; public autorangeMode(autorangeMode: string): Line; public autorangeMode(autorangeMode?: string): any { - let ret = super.autorangeMode(autorangeMode); - - if (autorangeMode != null) { - this._setScaleSnappingForAutorangeSmooth(); + if (autorangeMode == null) { + return super.autorangeMode(); } - return ret; + super.autorangeMode(autorangeMode); + this._setScaleSnappingForAutorangeSmooth(); + return this; } /** @@ -89,7 +89,7 @@ export module Plots { return this; } - public _setScaleSnappingForAutorangeSmooth() { + private _setScaleSnappingForAutorangeSmooth() { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { (>this.x().scale).snapsDomain(!this.autorangeSmooth()); } From 48548b61e28a25ec05e96d8a8bfd3ad92178c7bf Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:32:22 -0700 Subject: [PATCH 076/117] [autorangeSmooth] Simplified setScaleSnapping() method name --- plottable.js | 6 +++--- src/plots/linePlot.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plottable.js b/plottable.js index 0374d0f024..0e61c0c609 100644 --- a/plottable.js +++ b/plottable.js @@ -8250,7 +8250,7 @@ var Plottable; return _super.prototype.autorangeMode.call(this); } _super.prototype.autorangeMode.call(this, autorangeMode); - this._setScaleSnappingForAutorangeSmooth(); + this._setScaleSnapping(); return this; }; Line.prototype.autorangeSmooth = function (autorangeSmooth) { @@ -8258,10 +8258,10 @@ var Plottable; return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; - this._setScaleSnappingForAutorangeSmooth(); + this._setScaleSnapping(); return this; }; - Line.prototype._setScaleSnappingForAutorangeSmooth = function () { + Line.prototype._setScaleSnapping = function () { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { this.x().scale.snapsDomain(!this.autorangeSmooth()); } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index fa4a117b46..a51d0c4648 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -65,7 +65,7 @@ export module Plots { } super.autorangeMode(autorangeMode); - this._setScaleSnappingForAutorangeSmooth(); + this._setScaleSnapping(); return this; } @@ -85,11 +85,11 @@ export module Plots { return this._autorangeSmooth; } this._autorangeSmooth = autorangeSmooth; - this._setScaleSnappingForAutorangeSmooth(); + this._setScaleSnapping(); return this; } - private _setScaleSnappingForAutorangeSmooth() { + private _setScaleSnapping() { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { (>this.x().scale).snapsDomain(!this.autorangeSmooth()); } From 797bdb971cf5a3e8924e7c3ceff13b0080aeaf7d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:40:34 -0700 Subject: [PATCH 077/117] [autorangeSmooth] extracted the _setScaleSnapping from the accessors as well --- plottable.js | 21 ++++++++++++--------- src/plots/linePlot.ts | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/plottable.js b/plottable.js index 0e61c0c609..c8c3d4c132 100644 --- a/plottable.js +++ b/plottable.js @@ -8229,21 +8229,24 @@ var Plottable; this.attr("stroke-width", "2px"); } Line.prototype.x = function (x, xScale) { - if (xScale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "x") { - xScale.snapsDomain(!this._autorangeSmooth); - } - if (xScale == null) { - return _super.prototype.x.call(this, x); + if (x == null) { + return _super.prototype.x.call(this); } else { - return _super.prototype.x.call(this, x, xScale); + _super.prototype.x.call(this, x, xScale); + this._setScaleSnapping(); + return this; } }; Line.prototype.y = function (y, yScale) { - if (yScale instanceof Plottable.QuantitativeScale && this.autorangeMode() === "y") { - yScale.snapsDomain(!this._autorangeSmooth); + if (y == null) { + return _super.prototype.y.call(this); + } + else { + _super.prototype.y.call(this, y, yScale); + this._setScaleSnapping(); + return this; } - return _super.prototype.y.call(this, y, yScale); }; Line.prototype.autorangeMode = function (autorangeMode) { if (autorangeMode == null) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index a51d0c4648..7e6dc0898d 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -35,26 +35,26 @@ export module Plots { public x(x: number | Accessor): Line; public x(x: X | Accessor, xScale: Scale): Line; public x(x?: number | Accessor | X | Accessor, xScale?: Scale): any { - if (xScale instanceof QuantitativeScale && this.autorangeMode() === "x") { - (>xScale).snapsDomain(!this._autorangeSmooth); - } - - if (xScale == null) { - return super.x(>x); + if (x == null) { + return super.x(); } else { - return super.x(>x, xScale); + super.x(>x, xScale); + this._setScaleSnapping(); + return this; } - } public y(): Plots.AccessorScaleBinding; public y(y: number | Accessor): Line; public y(y: number | Accessor, yScale: Scale): Line; public y(y?: number | Accessor, yScale?: Scale): any { - if (yScale instanceof QuantitativeScale && this.autorangeMode() === "y") { - (>yScale).snapsDomain(!this._autorangeSmooth); + if (y == null) { + return super.y(); + } else { + super.y(y, yScale); + this._setScaleSnapping(); + return this; } - return super.y(y, yScale); } public autorangeMode(): string; From 4fa2ffc2307ff3b9198a826a80272b51fac0dbf3 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:42:13 -0700 Subject: [PATCH 078/117] [autorangeSmooth] correct signature for the x accessor on line plot --- plottable.js | 7 ++++++- src/plots/linePlot.ts | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index c8c3d4c132..53f19866d4 100644 --- a/plottable.js +++ b/plottable.js @@ -8233,7 +8233,12 @@ var Plottable; return _super.prototype.x.call(this); } else { - _super.prototype.x.call(this, x, xScale); + if (xScale == null) { + _super.prototype.x.call(this, x); + } + else { + _super.prototype.x.call(this, x, xScale); + } this._setScaleSnapping(); return this; } diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index 7e6dc0898d..a564efa0f0 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -38,7 +38,11 @@ export module Plots { if (x == null) { return super.x(); } else { - super.x(>x, xScale); + if (xScale == null) { + super.x(>x); + } else { + super.x(< X | Accessor>x, xScale); + } this._setScaleSnapping(); return this; } From 5d5acbe6ba8d66db2dc6e085e3341b939632af30 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:43:05 -0700 Subject: [PATCH 079/117] [autorangeSmooth] whitespace --- src/plots/linePlot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index a564efa0f0..e92219b512 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -41,7 +41,7 @@ export module Plots { if (xScale == null) { super.x(>x); } else { - super.x(< X | Accessor>x, xScale); + super.x(>x, xScale); } this._setScaleSnapping(); return this; From 2bf11047ff98eb594339841f4eae5bd7c9c5137c Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 13 Aug 2015 17:46:59 -0700 Subject: [PATCH 080/117] [autorangeSmooth] assert messages for the tests un capitalized now --- test/plots/linePlotTests.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index adcb3c88ee..6f4c497f2b 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -415,10 +415,10 @@ describe("Plots", () => { line.autorangeSmooth(true); assert.closeTo(yScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.05555, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[1], -1.05555, 0.001, "smooth autoranging forces the domain to include the line (right)"); line.autorangeSmooth(false); - assert.deepEqual(yScale.domain(), [0, 1], "Resetting the smooth autorange works"); + assert.deepEqual(yScale.domain(), [0, 1], "resetting the smooth autorange works"); xScale.domain([data[0].x, data[1].x]); assert.deepEqual(yScale.domain(), [-2, -1], "no changes for autoranging smooth with same edge poitns (no smooth)"); @@ -445,7 +445,7 @@ describe("Plots", () => { line.renderTo(svg); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before before autorangeMode)", () => { @@ -466,7 +466,7 @@ describe("Plots", () => { line.renderTo(svg); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before before rendering)", () => { @@ -487,7 +487,7 @@ describe("Plots", () => { line.renderTo(svg); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before after rendering)", () => { @@ -508,7 +508,7 @@ describe("Plots", () => { line.autorangeSmooth(true); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before after rendering, before autorangeMode)", () => { @@ -529,7 +529,7 @@ describe("Plots", () => { line.autorangeSmooth(true); line.autorangeMode("y"); assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "Smooth autoranging forces the domain to include the line (right)"); + assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("autoDomaining works with smooth autoranging (before rendering)", () => { From 208092a4991e4b0f2435cc8f9eb75158469e5ff4 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Fri, 14 Aug 2015 13:12:56 -0700 Subject: [PATCH 081/117] unit test name --- test/plots/scatterPlotTests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/plots/scatterPlotTests.ts b/test/plots/scatterPlotTests.ts index 22c902e1fc..747795f062 100644 --- a/test/plots/scatterPlotTests.ts +++ b/test/plots/scatterPlotTests.ts @@ -256,7 +256,7 @@ describe("Plots", () => { svg.remove(); }); - it("returns an empty array when no entities contain a given point", () => { + it("returns all entities containing a given point across all datasets", () => { let svg = TestMethods.generateSVG(400, 400); let xScale = new Plottable.Scales.Linear(); let yScale = new Plottable.Scales.Linear(); From 5d269e85b7751728a591e66db1153ffbac052eca Mon Sep 17 00:00:00 2001 From: Brandon Luong Date: Sun, 16 Aug 2015 01:53:33 -0700 Subject: [PATCH 082/117] timeAxis includes the margin in its height --- plottable.js | 5 +++-- src/axes/timeAxis.ts | 5 +++-- test/axes/timeAxisTests.ts | 12 ++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/plottable.js b/plottable.js index 7891b43ebb..d8757316a5 100644 --- a/plottable.js +++ b/plottable.js @@ -4063,9 +4063,10 @@ var Plottable; // Makes sure that the size it requires is a multiple of tier sizes, such that // we have no leftover tiers var size = _super.prototype._sizeFromOffer.call(this, availableWidth, availableHeight); - size.height = this._tierHeights.reduce(function (prevValue, currValue, index, arr) { + var tierHeights = this._tierHeights.reduce(function (prevValue, currValue, index, arr) { return (prevValue + currValue > size.height) ? prevValue : (prevValue + currValue); }); + size.height = Math.min(size.height, tierHeights + this.margin()); return size; }; Time.prototype._setup = function () { @@ -4222,7 +4223,7 @@ var Plottable; }; Time.prototype._hideOverflowingTiers = function () { var _this = this; - var availableHeight = this.height(); + var availableHeight = this.height() - this.margin(); var usedHeight = 0; this.content() .selectAll("." + Time.TIME_AXIS_TIER_CLASS) diff --git a/src/axes/timeAxis.ts b/src/axes/timeAxis.ts index 8871f05a9c..fa4e8f718d 100644 --- a/src/axes/timeAxis.ts +++ b/src/axes/timeAxis.ts @@ -309,9 +309,10 @@ export module Axes { // we have no leftover tiers let size = super._sizeFromOffer(availableWidth, availableHeight); - size.height = this._tierHeights.reduce((prevValue, currValue, index, arr) => { + let tierHeights = this._tierHeights.reduce((prevValue, currValue, index, arr) => { return (prevValue + currValue > size.height) ? prevValue : (prevValue + currValue); }); + size.height = Math.min(size.height, tierHeights + this.margin()); return size; } @@ -491,7 +492,7 @@ export module Axes { } private _hideOverflowingTiers() { - let availableHeight = this.height(); + let availableHeight = this.height() - this.margin(); let usedHeight = 0; this.content() diff --git a/test/axes/timeAxisTests.ts b/test/axes/timeAxisTests.ts index 167a657efe..ebba482039 100644 --- a/test/axes/timeAxisTests.ts +++ b/test/axes/timeAxisTests.ts @@ -231,6 +231,7 @@ describe("TimeAxis", () => { let xScale = new Plottable.Scales.Time(); xScale.domain([new Date("2013-03-23 12:00"), new Date("2013-04-03 0:00")]); let xAxis = new Plottable.Axes.Time(xScale, "bottom"); + xAxis.margin(0); let tiersToCreate = 15; let configuration = Array.apply(null, Array(tiersToCreate)).map(() => { @@ -281,4 +282,15 @@ describe("TimeAxis", () => { }); + it("height includes margin, label padding, and tick length", () => { + let svg = TestMethods.generateSVG(400, 400); + let xScale = new Plottable.Scales.Time(); + let xAxis = new Plottable.Axes.Time(xScale, "bottom"); + xAxis.margin(100); + xAxis.renderTo(svg); + let minimumHeight = xAxis.tickLabelPadding() + xAxis.margin() + xAxis.innerTickLength(); + assert.operator(xAxis.height(), ">=", minimumHeight, "height includes all relevant pieces"); + svg.remove(); + }); + }); From a46efdc46774eb39b5b95ecaa9b5ccabdf283fc9 Mon Sep 17 00:00:00 2001 From: Brandon Luong Date: Mon, 17 Aug 2015 13:54:25 -0700 Subject: [PATCH 083/117] revert availableHeight calculation --- plottable.js | 2 +- src/axes/timeAxis.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index d8757316a5..3a79bf14b2 100644 --- a/plottable.js +++ b/plottable.js @@ -4223,7 +4223,7 @@ var Plottable; }; Time.prototype._hideOverflowingTiers = function () { var _this = this; - var availableHeight = this.height() - this.margin(); + var availableHeight = this.height(); var usedHeight = 0; this.content() .selectAll("." + Time.TIME_AXIS_TIER_CLASS) diff --git a/src/axes/timeAxis.ts b/src/axes/timeAxis.ts index fa4e8f718d..1c3b66fdd3 100644 --- a/src/axes/timeAxis.ts +++ b/src/axes/timeAxis.ts @@ -492,7 +492,7 @@ export module Axes { } private _hideOverflowingTiers() { - let availableHeight = this.height() - this.margin(); + let availableHeight = this.height(); let usedHeight = 0; this.content() From e9ea4c5f2c55273267cda06fe699889da7680a9f Mon Sep 17 00:00:00 2001 From: Brandon Luong Date: Mon, 17 Aug 2015 14:10:35 -0700 Subject: [PATCH 084/117] modify test to be specific to anchor + computeLayout --- test/axes/timeAxisTests.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/axes/timeAxisTests.ts b/test/axes/timeAxisTests.ts index ebba482039..dc181480b7 100644 --- a/test/axes/timeAxisTests.ts +++ b/test/axes/timeAxisTests.ts @@ -287,7 +287,8 @@ describe("TimeAxis", () => { let xScale = new Plottable.Scales.Time(); let xAxis = new Plottable.Axes.Time(xScale, "bottom"); xAxis.margin(100); - xAxis.renderTo(svg); + xAxis.anchor(svg); + xAxis.computeLayout({ x: 0, y: 0}, 400, 400); let minimumHeight = xAxis.tickLabelPadding() + xAxis.margin() + xAxis.innerTickLength(); assert.operator(xAxis.height(), ">=", minimumHeight, "height includes all relevant pieces"); svg.remove(); From d4a8f04362965160dc41228459a946c2afc2b479 Mon Sep 17 00:00:00 2001 From: Brandon Luong Date: Mon, 17 Aug 2015 14:14:22 -0700 Subject: [PATCH 085/117] change test name --- test/axes/timeAxisTests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/axes/timeAxisTests.ts b/test/axes/timeAxisTests.ts index dc181480b7..29c58b14f0 100644 --- a/test/axes/timeAxisTests.ts +++ b/test/axes/timeAxisTests.ts @@ -282,7 +282,7 @@ describe("TimeAxis", () => { }); - it("height includes margin, label padding, and tick length", () => { + it("occupied space includes margin, label padding, and tick length", () => { let svg = TestMethods.generateSVG(400, 400); let xScale = new Plottable.Scales.Time(); let xAxis = new Plottable.Axes.Time(xScale, "bottom"); From 7f8e1056aca8e41fa051437110f1c07330dbd1c9 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Fri, 31 Jul 2015 18:19:46 -0700 Subject: [PATCH 086/117] draw stroke with an additional path for pie plot --- plottable.d.ts | 6 ++++- plottable.js | 49 ++++++++++++++++++++++++++++++++++++-- src/drawers/arcDrawer.ts | 10 ++++++-- src/plots/piePlot.ts | 41 +++++++++++++++++++++++++++++++ test/plots/piePlotTests.ts | 41 ++++++++++++++++++++++++------- 5 files changed, 133 insertions(+), 14 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index a0e29f5500..33288ec847 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -1323,7 +1323,8 @@ declare module Plottable { declare module Plottable { module Drawers { class Arc extends Drawer { - constructor(dataset: Dataset); + constructor(dataset: Dataset, isOutline?: boolean); + protected _applyDefaultAttributes(selection: d3.Selection): void; } } } @@ -2648,9 +2649,12 @@ declare module Plottable { * @constructor */ constructor(); + protected _setup(): void; computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number): Pie; addDataset(dataset: Dataset): Pie; + protected _removeDatasetNodes(dataset: Dataset): void; removeDataset(dataset: Dataset): Pie; + selections(datasets?: Dataset[]): d3.Selection; protected _onDatasetUpdate(): void; protected _createDrawer(dataset: Dataset): Drawers.Arc; entities(datasets?: Dataset[]): PlotEntity[]; diff --git a/plottable.js b/plottable.js index 195e7bcc4c..7bbc47fdbd 100644 --- a/plottable.js +++ b/plottable.js @@ -2854,11 +2854,17 @@ var Plottable; (function (Drawers) { var Arc = (function (_super) { __extends(Arc, _super); - function Arc(dataset) { + function Arc(dataset, isOutline) { + if (isOutline === void 0) { isOutline = false; } _super.call(this, dataset); - this._className = "arc"; + this._className = "arc " + (isOutline ? "outline" : "fill"); this._svgElementName = "path"; + this._isOutline = isOutline; } + Arc.prototype._applyDefaultAttributes = function (selection) { + _super.prototype._applyDefaultAttributes.call(this, selection); + selection.style(this._isOutline ? "fill" : "stroke", "none"); + }; return Arc; })(Plottable.Drawer); Drawers.Arc = Arc; @@ -6827,7 +6833,13 @@ var Plottable; this.outerRadius(function () { return Math.min(_this.width(), _this.height()) / 2; }); this.addClass("pie-plot"); this.attr("fill", function (d, i) { return String(i); }, new Plottable.Scales.Color()); + this._strokeDrawers = new Plottable.Utils.Map(); } + Pie.prototype._setup = function () { + var _this = this; + _super.prototype._setup.call(this); + this._strokeDrawers.forEach(function (d) { return d.renderArea(_this._renderArea.append("g")); }); + }; Pie.prototype.computeLayout = function (origin, availableWidth, availableHeight) { _super.prototype.computeLayout.call(this, origin, availableWidth, availableHeight); this._renderArea.attr("transform", "translate(" + this.width() / 2 + "," + this.height() / 2 + ")"); @@ -6846,15 +6858,39 @@ var Plottable; return this; } this._updatePieAngles(); + var strokeDrawer = new Plottable.Drawers.Arc(dataset, true); + if (this._isSetup) { + strokeDrawer.renderArea(this._renderArea.append("g")); + } + this._strokeDrawers.set(dataset, strokeDrawer); _super.prototype.addDataset.call(this, dataset); return this; }; + Pie.prototype._removeDatasetNodes = function (dataset) { + _super.prototype._removeDatasetNodes.call(this, dataset); + this._strokeDrawers.get(dataset).remove(); + }; Pie.prototype.removeDataset = function (dataset) { _super.prototype.removeDataset.call(this, dataset); this._startAngles = []; this._endAngles = []; return this; }; + Pie.prototype.selections = function (datasets) { + var _this = this; + if (datasets === void 0) { datasets = this.datasets(); } + var allSelections = _super.prototype.selections.call(this, datasets)[0]; + datasets.forEach(function (dataset) { + var drawer = _this._strokeDrawers.get(dataset); + if (drawer == null) { + return; + } + drawer.renderArea().selectAll(drawer.selector()).each(function () { + allSelections.push(this); + }); + }); + return d3.selectAll(allSelections); + }; Pie.prototype._onDatasetUpdate = function () { this._updatePieAngles(); _super.prototype._onDatasetUpdate.call(this); @@ -6869,6 +6905,8 @@ var Plottable; entities.forEach(function (entity) { entity.position.x += _this.width() / 2; entity.position.y += _this.height() / 2; + var stroke = _this._strokeDrawers.get(entity.dataset).selectionForIndex(entity.index); + entity.selection[0].push(stroke[0][0]); }); return entities; }; @@ -6990,6 +7028,13 @@ var Plottable; if (this._labelsEnabled) { Plottable.Utils.Window.setTimeout(function () { return _this._drawLabels(); }, time); } + var drawSteps = this._generateStrokeDrawSteps(); + var dataToDraw = this._getDataToDraw(); + this.datasets().forEach(function (dataset) { return _this._strokeDrawers.get(dataset).draw(dataToDraw.get(dataset), drawSteps); }); + }; + Pie.prototype._generateStrokeDrawSteps = function () { + var attrToProjector = this._generateAttrToProjector(); + return [{ attrToProjector: attrToProjector, animator: new Plottable.Animators.Null() }]; }; Pie.prototype._sliceIndexForPoint = function (p) { var pointRadius = Math.sqrt(Math.pow(p.x, 2) + Math.pow(p.y, 2)); diff --git a/src/drawers/arcDrawer.ts b/src/drawers/arcDrawer.ts index 1f7def9c47..1a4ca357f3 100644 --- a/src/drawers/arcDrawer.ts +++ b/src/drawers/arcDrawer.ts @@ -3,13 +3,19 @@ module Plottable { export module Drawers { export class Arc extends Drawer { + private _isOutline: boolean; - constructor(dataset: Dataset) { + constructor(dataset: Dataset, isOutline = false) { super(dataset); - this._className = "arc"; + this._className = "arc " + (isOutline ? "outline" : "fill"); this._svgElementName = "path"; + this._isOutline = isOutline; } + protected _applyDefaultAttributes(selection: d3.Selection) { + super._applyDefaultAttributes(selection); + selection.style(this._isOutline ? "fill" : "stroke", "none"); + } } } } diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 6522ce259a..a735a0b63a 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -11,6 +11,7 @@ export module Plots { private _endAngles: number[]; private _labelFormatter: Formatter = Formatters.identity(); private _labelsEnabled = false; + private _strokeDrawers: Utils.Map; /** * @constructor @@ -21,6 +22,13 @@ export module Plots { this.outerRadius(() => Math.min(this.width(), this.height()) / 2); this.addClass("pie-plot"); this.attr("fill", (d, i) => String(i), new Scales.Color()); + + this._strokeDrawers = new Utils.Map(); + } + + protected _setup() { + super._setup(); + this._strokeDrawers.forEach((d) => d.renderArea(this._renderArea.append("g"))); } public computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number) { @@ -42,10 +50,20 @@ export module Plots { return this; } this._updatePieAngles(); + var strokeDrawer = new Drawers.Arc(dataset, true); + if (this._isSetup) { + strokeDrawer.renderArea(this._renderArea.append("g")); + } + this._strokeDrawers.set(dataset, strokeDrawer); super.addDataset(dataset); return this; } + protected _removeDatasetNodes(dataset: Dataset) { + super._removeDatasetNodes(dataset); + this._strokeDrawers.get(dataset).remove(); + } + public removeDataset(dataset: Dataset) { super.removeDataset(dataset); this._startAngles = []; @@ -53,6 +71,18 @@ export module Plots { return this; } + public selections(datasets = this.datasets()) { + var allSelections = super.selections(datasets)[0]; + datasets.forEach((dataset) => { + var drawer = this._strokeDrawers.get(dataset); + if (drawer == null) { return; } + drawer.renderArea().selectAll(drawer.selector()).each(function() { + allSelections.push(this); + }); + }); + return d3.selectAll(allSelections); + } + protected _onDatasetUpdate() { this._updatePieAngles(); super._onDatasetUpdate(); @@ -67,6 +97,8 @@ export module Plots { entities.forEach((entity) => { entity.position.x += this.width() / 2; entity.position.y += this.height() / 2; + var stroke = this._strokeDrawers.get(entity.dataset).selectionForIndex(entity.index); + entity.selection[0].push(stroke[0][0]); }); return entities; } @@ -274,6 +306,15 @@ export module Plots { if (this._labelsEnabled) { Utils.Window.setTimeout(() => this._drawLabels(), time); } + + var drawSteps = this._generateStrokeDrawSteps(); + var dataToDraw = this._getDataToDraw(); + this.datasets().forEach((dataset) => this._strokeDrawers.get(dataset).draw(dataToDraw.get(dataset), drawSteps)); + } + + private _generateStrokeDrawSteps() { + var attrToProjector = this._generateAttrToProjector(); + return [{attrToProjector: attrToProjector, animator: new Animators.Null()}]; } private _sliceIndexForPoint(p: Point) { diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index 15a8055344..27382a1e41 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -13,6 +13,29 @@ describe("Plots", () => { svg.remove(); }); + it("each slice consists of a fill path and a stroke path", () => { + var svg = TestMethods.generateSVG(500, 500); + var piePlot = new Plottable.Plots.Pie(); + piePlot.sectorValue((d) => d.value); + var data = [ + { value: 1 }, + { value: 1 } + ]; + var dataset = new Plottable.Dataset(data); + piePlot.addDataset(dataset); + piePlot.renderTo(svg); + var renderArea = ( piePlot)._renderArea; + var arcPaths = renderArea.selectAll(".arc"); + var arcFillPaths = renderArea.selectAll(".arc.fill"); + var arcOutlinePaths = renderArea.selectAll(".arc.outline"); + assert.strictEqual(arcPaths.size(), 4, "2 paths per datum"); + assert.strictEqual(arcFillPaths.size(), 2, "1 fill path per datum"); + assert.strictEqual(arcOutlinePaths.size(), 2, "1 outline path1 per datum"); + assert.strictEqual(arcFillPaths.style("stroke"), "none", "fill paths have no stroke"); + assert.strictEqual(arcOutlinePaths.style("fill"), "none", "outline paths have no fill"); + svg.remove(); + }); + it("updates slices when data changes", () => { let svg = TestMethods.generateSVG(500, 500); let piePlot = new Plottable.Plots.Pie(); @@ -28,7 +51,7 @@ describe("Plots", () => { piePlot.renderTo(svg); let fourSlicePathStrings: String[] = []; piePlot.content().selectAll("path").each(function() { fourSlicePathStrings.push(d3.select(this).attr("d")); }); - assert.lengthOf(fourSlicePathStrings, fourSliceData.length, "one path per datum"); + assert.lengthOf(fourSlicePathStrings, fourSliceData.length * 2, "2 paths per datum"); let twoSliceData = [ { value: 1 }, @@ -37,7 +60,7 @@ describe("Plots", () => { dataset.data(twoSliceData); let twoSlicePathStrings: String[] = []; piePlot.content().selectAll("path").each(function() { twoSlicePathStrings.push(d3.select(this).attr("d")); }); - assert.lengthOf(twoSlicePathStrings, twoSliceData.length, "one path per datum"); + assert.lengthOf(twoSlicePathStrings, twoSliceData.length * 2, "2 paths per datum"); twoSlicePathStrings.forEach((pathString, index) => { assert.notStrictEqual(pathString, fourSlicePathStrings[index], "slices were updated when data changed"); @@ -241,7 +264,7 @@ describe("Plots", () => { }); it("sectors divided evenly", () => { - let arcPaths = renderArea.selectAll(".arc"); + let arcPaths = renderArea.selectAll(".arc.fill"); assert.lengthOf(arcPaths[0], 2, "only has two sectors"); let arcPath0 = d3.select(arcPaths[0][0]); let pathPoints0 = TestMethods.normalizePath(arcPath0.attr("d")).split(/[A-Z]/).slice(1, 4); @@ -278,7 +301,7 @@ describe("Plots", () => { it("project value onto different attribute", () => { piePlot.sectorValue((d) => d.value2); - let arcPaths = renderArea.selectAll(".arc"); + let arcPaths = renderArea.selectAll(".arc.fill"); assert.lengthOf(arcPaths[0], 2, "only has two sectors"); let arcPath0 = d3.select(arcPaths[0][0]); let pathPoints0 = TestMethods.normalizePath(arcPath0.attr("d")).split(/[A-Z]/).slice(1, 4); @@ -308,7 +331,7 @@ describe("Plots", () => { it("innerRadius", () => { piePlot.innerRadius(5); - let arcPaths = renderArea.selectAll(".arc"); + let arcPaths = renderArea.selectAll(".arc.fill"); assert.lengthOf(arcPaths[0], 2, "only has two sectors"); let pathPoints0 = TestMethods.normalizePath(d3.select(arcPaths[0][0]).attr("d")).split(/[A-Z]/).slice(1, 5); @@ -329,7 +352,7 @@ describe("Plots", () => { it("outerRadius", () => { piePlot.outerRadius(() => 150); - let arcPaths = renderArea.selectAll(".arc"); + let arcPaths = renderArea.selectAll(".arc.fill"); assert.lengthOf(arcPaths[0], 2, "only has two sectors"); let pathPoints0 = TestMethods.normalizePath(d3.select(arcPaths[0][0]).attr("d")).split(/[A-Z]/).slice(1, 5); @@ -351,14 +374,14 @@ describe("Plots", () => { describe("selections", () => { it("retrieves all dataset selections with no args", () => { let allSectors = piePlot.selections(); - assert.strictEqual(allSectors.size(), 2, "all sectors retrieved"); + assert.strictEqual(allSectors.size(), 2 * 2, "all sectors retrieved"); svg.remove(); }); it("retrieves correct selections", () => { let allSectors = piePlot.selections([simpleDataset]); - assert.strictEqual(allSectors.size(), 2, "all sectors retrieved"); + assert.strictEqual(allSectors.size(), 2 * 2, "all sectors retrieved"); assert.includeMembers(allSectors.data(), simpleData, "dataset data in selection data"); svg.remove(); @@ -485,7 +508,7 @@ describe("Plots", () => { plot.renderTo(svg); - let elementsDrawnSel = ( plot)._element.selectAll(".arc"); + let elementsDrawnSel = ( plot)._element.selectAll(".arc.fill"); assert.strictEqual(elementsDrawnSel.size(), 4, "There should be exactly 4 slices in the pie chart, representing the valid values"); From 6e01be41b4d5707b6be12e6773496e1c912825f6 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Mon, 3 Aug 2015 17:43:47 -0700 Subject: [PATCH 087/117] use ArcOutline drawer --- plottable.d.ts | 6 +++++- plottable.js | 24 ++++++++++++++++++------ src/drawers/arcDrawer.ts | 22 +++++++++++++++++----- src/plots/piePlot.ts | 6 +++--- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 33288ec847..c6b8cbab52 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -1323,7 +1323,11 @@ declare module Plottable { declare module Plottable { module Drawers { class Arc extends Drawer { - constructor(dataset: Dataset, isOutline?: boolean); + constructor(dataset: Dataset); + protected _applyDefaultAttributes(selection: d3.Selection): void; + } + class ArcOutline extends Drawer { + constructor(dataset: Dataset); protected _applyDefaultAttributes(selection: d3.Selection): void; } } diff --git a/plottable.js b/plottable.js index 7bbc47fdbd..86faa449b0 100644 --- a/plottable.js +++ b/plottable.js @@ -2854,20 +2854,32 @@ var Plottable; (function (Drawers) { var Arc = (function (_super) { __extends(Arc, _super); - function Arc(dataset, isOutline) { - if (isOutline === void 0) { isOutline = false; } + function Arc(dataset) { _super.call(this, dataset); - this._className = "arc " + (isOutline ? "outline" : "fill"); + this._className = "arc fill"; this._svgElementName = "path"; - this._isOutline = isOutline; } Arc.prototype._applyDefaultAttributes = function (selection) { _super.prototype._applyDefaultAttributes.call(this, selection); - selection.style(this._isOutline ? "fill" : "stroke", "none"); + selection.style("stroke", "none"); }; return Arc; })(Plottable.Drawer); Drawers.Arc = Arc; + var ArcOutline = (function (_super) { + __extends(ArcOutline, _super); + function ArcOutline(dataset) { + _super.call(this, dataset); + this._className = "arc outline"; + this._svgElementName = "path"; + } + ArcOutline.prototype._applyDefaultAttributes = function (selection) { + _super.prototype._applyDefaultAttributes.call(this, selection); + selection.style("fill", "none"); + }; + return ArcOutline; + })(Plottable.Drawer); + Drawers.ArcOutline = ArcOutline; })(Drawers = Plottable.Drawers || (Plottable.Drawers = {})); })(Plottable || (Plottable = {})); @@ -6858,7 +6870,7 @@ var Plottable; return this; } this._updatePieAngles(); - var strokeDrawer = new Plottable.Drawers.Arc(dataset, true); + var strokeDrawer = new Plottable.Drawers.ArcOutline(dataset); if (this._isSetup) { strokeDrawer.renderArea(this._renderArea.append("g")); } diff --git a/src/drawers/arcDrawer.ts b/src/drawers/arcDrawer.ts index 1a4ca357f3..58e32b503b 100644 --- a/src/drawers/arcDrawer.ts +++ b/src/drawers/arcDrawer.ts @@ -3,18 +3,30 @@ module Plottable { export module Drawers { export class Arc extends Drawer { - private _isOutline: boolean; - constructor(dataset: Dataset, isOutline = false) { + constructor(dataset: Dataset) { super(dataset); - this._className = "arc " + (isOutline ? "outline" : "fill"); + this._className = "arc fill"; this._svgElementName = "path"; - this._isOutline = isOutline; } protected _applyDefaultAttributes(selection: d3.Selection) { super._applyDefaultAttributes(selection); - selection.style(this._isOutline ? "fill" : "stroke", "none"); + selection.style("stroke", "none"); + } + } + + export class ArcOutline extends Drawer { + + constructor(dataset: Dataset) { + super(dataset); + this._className = "arc outline"; + this._svgElementName = "path"; + } + + protected _applyDefaultAttributes(selection: d3.Selection) { + super._applyDefaultAttributes(selection); + selection.style("fill", "none"); } } } diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index a735a0b63a..412e59b4b0 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -11,7 +11,7 @@ export module Plots { private _endAngles: number[]; private _labelFormatter: Formatter = Formatters.identity(); private _labelsEnabled = false; - private _strokeDrawers: Utils.Map; + private _strokeDrawers: Utils.Map; /** * @constructor @@ -23,7 +23,7 @@ export module Plots { this.addClass("pie-plot"); this.attr("fill", (d, i) => String(i), new Scales.Color()); - this._strokeDrawers = new Utils.Map(); + this._strokeDrawers = new Utils.Map(); } protected _setup() { @@ -50,7 +50,7 @@ export module Plots { return this; } this._updatePieAngles(); - var strokeDrawer = new Drawers.Arc(dataset, true); + var strokeDrawer = new Drawers.ArcOutline(dataset); if (this._isSetup) { strokeDrawer.renderArea(this._renderArea.append("g")); } From 97f93a3516a0516722e3f7bcd324469e9c31cfda Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Tue, 4 Aug 2015 14:43:58 -0700 Subject: [PATCH 088/117] move ArcOutline to a separate file --- plottable.d.ts | 6 ++++++ plottable.js | 14 ++++++++++++++ src/drawers/arcDrawer.ts | 14 -------------- src/drawers/arcOutlineDrawer.ts | 20 ++++++++++++++++++++ src/reference.ts | 1 + 5 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/drawers/arcOutlineDrawer.ts diff --git a/plottable.d.ts b/plottable.d.ts index c6b8cbab52..743794385f 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -1326,6 +1326,12 @@ declare module Plottable { constructor(dataset: Dataset); protected _applyDefaultAttributes(selection: d3.Selection): void; } + } +} + + +declare module Plottable { + module Drawers { class ArcOutline extends Drawer { constructor(dataset: Dataset); protected _applyDefaultAttributes(selection: d3.Selection): void; diff --git a/plottable.js b/plottable.js index 86faa449b0..6d6179ab7c 100644 --- a/plottable.js +++ b/plottable.js @@ -2866,6 +2866,20 @@ var Plottable; return Arc; })(Plottable.Drawer); Drawers.Arc = Arc; + })(Drawers = Plottable.Drawers || (Plottable.Drawers = {})); +})(Plottable || (Plottable = {})); + +/// +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var Plottable; +(function (Plottable) { + var Drawers; + (function (Drawers) { var ArcOutline = (function (_super) { __extends(ArcOutline, _super); function ArcOutline(dataset) { diff --git a/src/drawers/arcDrawer.ts b/src/drawers/arcDrawer.ts index 58e32b503b..48f6865f29 100644 --- a/src/drawers/arcDrawer.ts +++ b/src/drawers/arcDrawer.ts @@ -15,19 +15,5 @@ export module Drawers { selection.style("stroke", "none"); } } - - export class ArcOutline extends Drawer { - - constructor(dataset: Dataset) { - super(dataset); - this._className = "arc outline"; - this._svgElementName = "path"; - } - - protected _applyDefaultAttributes(selection: d3.Selection) { - super._applyDefaultAttributes(selection); - selection.style("fill", "none"); - } - } } } diff --git a/src/drawers/arcOutlineDrawer.ts b/src/drawers/arcOutlineDrawer.ts new file mode 100644 index 0000000000..1e3d3af07c --- /dev/null +++ b/src/drawers/arcOutlineDrawer.ts @@ -0,0 +1,20 @@ +/// + +module Plottable { +export module Drawers { + + export class ArcOutline extends Drawer { + + constructor(dataset: Dataset) { + super(dataset); + this._className = "arc outline"; + this._svgElementName = "path"; + } + + protected _applyDefaultAttributes(selection: d3.Selection) { + super._applyDefaultAttributes(selection); + selection.style("fill", "none"); + } + } +} +} diff --git a/src/reference.ts b/src/reference.ts index ba5ebf9a65..647f38b5f2 100644 --- a/src/reference.ts +++ b/src/reference.ts @@ -38,6 +38,7 @@ /// /// /// +/// /// /// From b8ba35629e2b115e4ee15676268ef0c25d389632 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Mon, 17 Aug 2015 15:26:08 -0700 Subject: [PATCH 089/117] change var to let; set stroke-linejoin to round --- plottable.js | 1 + src/drawers/arcOutlineDrawer.ts | 1 + src/plots/piePlot.ts | 14 +++++++------- test/plots/piePlotTests.ts | 16 ++++++++-------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/plottable.js b/plottable.js index 6d6179ab7c..1705ca456f 100644 --- a/plottable.js +++ b/plottable.js @@ -2890,6 +2890,7 @@ var Plottable; ArcOutline.prototype._applyDefaultAttributes = function (selection) { _super.prototype._applyDefaultAttributes.call(this, selection); selection.style("fill", "none"); + selection.style("stroke-linejoin", "round"); }; return ArcOutline; })(Plottable.Drawer); diff --git a/src/drawers/arcOutlineDrawer.ts b/src/drawers/arcOutlineDrawer.ts index 1e3d3af07c..199d78cdec 100644 --- a/src/drawers/arcOutlineDrawer.ts +++ b/src/drawers/arcOutlineDrawer.ts @@ -14,6 +14,7 @@ export module Drawers { protected _applyDefaultAttributes(selection: d3.Selection) { super._applyDefaultAttributes(selection); selection.style("fill", "none"); + selection.style("stroke-linejoin", "round"); } } } diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 412e59b4b0..b9a37de59a 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -50,7 +50,7 @@ export module Plots { return this; } this._updatePieAngles(); - var strokeDrawer = new Drawers.ArcOutline(dataset); + let strokeDrawer = new Drawers.ArcOutline(dataset); if (this._isSetup) { strokeDrawer.renderArea(this._renderArea.append("g")); } @@ -72,9 +72,9 @@ export module Plots { } public selections(datasets = this.datasets()) { - var allSelections = super.selections(datasets)[0]; + let allSelections = super.selections(datasets)[0]; datasets.forEach((dataset) => { - var drawer = this._strokeDrawers.get(dataset); + let drawer = this._strokeDrawers.get(dataset); if (drawer == null) { return; } drawer.renderArea().selectAll(drawer.selector()).each(function() { allSelections.push(this); @@ -97,7 +97,7 @@ export module Plots { entities.forEach((entity) => { entity.position.x += this.width() / 2; entity.position.y += this.height() / 2; - var stroke = this._strokeDrawers.get(entity.dataset).selectionForIndex(entity.index); + let stroke = this._strokeDrawers.get(entity.dataset).selectionForIndex(entity.index); entity.selection[0].push(stroke[0][0]); }); return entities; @@ -307,13 +307,13 @@ export module Plots { Utils.Window.setTimeout(() => this._drawLabels(), time); } - var drawSteps = this._generateStrokeDrawSteps(); - var dataToDraw = this._getDataToDraw(); + let drawSteps = this._generateStrokeDrawSteps(); + let dataToDraw = this._getDataToDraw(); this.datasets().forEach((dataset) => this._strokeDrawers.get(dataset).draw(dataToDraw.get(dataset), drawSteps)); } private _generateStrokeDrawSteps() { - var attrToProjector = this._generateAttrToProjector(); + let attrToProjector = this._generateAttrToProjector(); return [{attrToProjector: attrToProjector, animator: new Animators.Null()}]; } diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index 27382a1e41..ba00c07709 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -14,20 +14,20 @@ describe("Plots", () => { }); it("each slice consists of a fill path and a stroke path", () => { - var svg = TestMethods.generateSVG(500, 500); - var piePlot = new Plottable.Plots.Pie(); + let svg = TestMethods.generateSVG(500, 500); + let piePlot = new Plottable.Plots.Pie(); piePlot.sectorValue((d) => d.value); - var data = [ + let data = [ { value: 1 }, { value: 1 } ]; - var dataset = new Plottable.Dataset(data); + let dataset = new Plottable.Dataset(data); piePlot.addDataset(dataset); piePlot.renderTo(svg); - var renderArea = ( piePlot)._renderArea; - var arcPaths = renderArea.selectAll(".arc"); - var arcFillPaths = renderArea.selectAll(".arc.fill"); - var arcOutlinePaths = renderArea.selectAll(".arc.outline"); + let renderArea = ( piePlot)._renderArea; + let arcPaths = renderArea.selectAll(".arc"); + let arcFillPaths = renderArea.selectAll(".arc.fill"); + let arcOutlinePaths = renderArea.selectAll(".arc.outline"); assert.strictEqual(arcPaths.size(), 4, "2 paths per datum"); assert.strictEqual(arcFillPaths.size(), 2, "1 fill path per datum"); assert.strictEqual(arcOutlinePaths.size(), 2, "1 outline path1 per datum"); From c428e6e6edad936dfc97a7f73aa1ecc5d3428068 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 17 Aug 2015 16:42:14 -0700 Subject: [PATCH 090/117] [autorangeSmooth] Remvoed magic numbers from first test --- test/plots/linePlotTests.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 6f4c497f2b..d821086e06 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -414,8 +414,21 @@ describe("Plots", () => { assert.deepEqual(yScale.domain(), [0, 1], "when there are no visible points in the view, the y-scale domain defaults to [0, 1]"); line.autorangeSmooth(true); - assert.closeTo(yScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.05555, 0.001, "smooth autoranging forces the domain to include the line (right)"); + + let base = data[0].y; + let x1 = xScale.domain()[1] - data[0].x; + let x2 = data[1].x - data[0].x; + let y2 = data[1].y - data[0].y; + let expectedBottom = base + y2 * x1 / x2; + + base = data[0].y; + x1 = xScale.domain()[0] - data[0].x; + x2 = data[1].x - data[0].x; + y2 = data[1].y - data[0].y; + let expectedTop = base + y2 * x1 / x2; + + assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); line.autorangeSmooth(false); assert.deepEqual(yScale.domain(), [0, 1], "resetting the smooth autorange works"); From ee5c097ee9a68aa107baef7a8b81a306f147a0f1 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 17 Aug 2015 17:26:35 -0700 Subject: [PATCH 091/117] [autorangeSmooth] Added calculated values for the small tests instead of magic numbers --- src/scales/quantitativeScale.ts | 1 + test/plots/linePlotTests.ts | 83 ++++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/scales/quantitativeScale.ts b/src/scales/quantitativeScale.ts index ca921fd7b1..cccb7f0379 100644 --- a/src/scales/quantitativeScale.ts +++ b/src/scales/quantitativeScale.ts @@ -153,6 +153,7 @@ export class QuantitativeScale extends Scale { }); let newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); let newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); + if (this._snapsDomain) { return this._niceDomain([newMin, newMax]); } diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index d821086e06..acd1a7fa31 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -457,8 +457,20 @@ describe("Plots", () => { line.renderTo(svg); - assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); + let base = data[0].y; + let x1 = (xScale.domain()[1] - data[0].x) - (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + let x2 = data[1].x - data[0].x; + let y2 = data[1].y - data[0].y; + let expectedTop = base + y2 * x1 / x2; + + base = data[0].y; + x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + x2 = data[1].x - data[0].x; + y2 = data[1].y - data[0].y; + let expectedBottom = base + y2 * x1 / x2; + + assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before before autorangeMode)", () => { @@ -478,8 +490,20 @@ describe("Plots", () => { line.renderTo(svg); - assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); + let base = data[0].y; + let x1 = (xScale.domain()[1] - data[0].x) - (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + let x2 = data[1].x - data[0].x; + let y2 = data[1].y - data[0].y; + let expectedTop = base + y2 * x1 / x2; + + base = data[0].y; + x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + x2 = data[1].x - data[0].x; + y2 = data[1].y - data[0].y; + let expectedBottom = base + y2 * x1 / x2; + + assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before before rendering)", () => { @@ -499,8 +523,20 @@ describe("Plots", () => { line.autorangeSmooth(true); line.renderTo(svg); - assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); + let base = data[0].y; + let x1 = (xScale.domain()[1] - data[0].x) - (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + let x2 = data[1].x - data[0].x; + let y2 = data[1].y - data[0].y; + let expectedTop = base + y2 * x1 / x2; + + base = data[0].y; + x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + x2 = data[1].x - data[0].x; + y2 = data[1].y - data[0].y; + let expectedBottom = base + y2 * x1 / x2; + + assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before after rendering)", () => { @@ -518,10 +554,22 @@ describe("Plots", () => { line.autorangeMode("y"); line.renderTo(svg); - line.autorangeSmooth(true); - assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); + + let base = data[0].y; + let x1 = (xScale.domain()[1] - data[0].x) - (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + let x2 = data[1].x - data[0].x; + let y2 = data[1].y - data[0].y; + let expectedTop = base + y2 * x1 / x2; + + base = data[0].y; + x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + x2 = data[1].x - data[0].x; + y2 = data[1].y - data[0].y; + let expectedBottom = base + y2 * x1 / x2; + + assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("smooth autoranging works (called before after rendering, before autorangeMode)", () => { @@ -541,8 +589,21 @@ describe("Plots", () => { line.autorangeSmooth(true); line.autorangeMode("y"); - assert.closeTo(yScale.domain()[0], -1.625, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(yScale.domain()[1], -1.041, 0.001, "smooth autoranging forces the domain to include the line (right)"); + + let base = data[0].y; + let x1 = (xScale.domain()[1] - data[0].x) - (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + let x2 = data[1].x - data[0].x; + let y2 = data[1].y - data[0].y; + let expectedTop = base + y2 * x1 / x2; + + base = data[0].y; + x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); + x2 = data[1].x - data[0].x; + y2 = data[1].y - data[0].y; + let expectedBottom = base + y2 * x1 / x2; + + assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); it("autoDomaining works with smooth autoranging (before rendering)", () => { From 5ee17f860cb7a19342886337e131672db9fe200d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 17 Aug 2015 17:51:27 -0700 Subject: [PATCH 092/117] [autorangeSmooth] added Calculated Values isntead of magic numbers for last test as well --- test/plots/linePlotTests.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index acd1a7fa31..a63f48f187 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -676,8 +676,21 @@ describe("Plots", () => { assert.deepEqual(xScale.domain(), [0, 1], "when there are no visible points in the view, the x-scale domain defaults to [0, 1]"); line.autorangeSmooth(true); - assert.closeTo(xScale.domain()[0], -1.61111, 0.001, "smooth autoranging forces the domain to include the line (left)"); - assert.closeTo(xScale.domain()[1], -1.05555, 0.001, "smooth autoranging forces the domain to include the line (right)"); + + let base = data[0].x; + let x1 = (yScale.domain()[1] - data[0].y); + let x2 = data[1].y - data[0].y; + let y2 = data[1].x - data[0].x; + let expectedTop = base + y2 * x1 / x2; + + base = data[0].x; + x1 = (yScale.domain()[0] - data[0].y); + x2 = data[1].y - data[0].y; + y2 = data[1].x - data[0].x; + let expectedBottom = base + y2 * x1 / x2; + + assert.closeTo(xScale.domain()[0], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (left)"); + assert.closeTo(xScale.domain()[1], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (right)"); line.autorangeSmooth(false); assert.deepEqual(xScale.domain(), [0, 1], "resetting the smooth autorange works"); From 415d8afa153b02c5f01e0294230d051ac01b403d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 17 Aug 2015 17:52:22 -0700 Subject: [PATCH 093/117] [autorangeSmooth] Deleted redundant lines --- test/plots/linePlotTests.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index a63f48f187..2322465e71 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -421,10 +421,7 @@ describe("Plots", () => { let y2 = data[1].y - data[0].y; let expectedBottom = base + y2 * x1 / x2; - base = data[0].y; x1 = xScale.domain()[0] - data[0].x; - x2 = data[1].x - data[0].x; - y2 = data[1].y - data[0].y; let expectedTop = base + y2 * x1 / x2; assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); @@ -463,10 +460,7 @@ describe("Plots", () => { let y2 = data[1].y - data[0].y; let expectedTop = base + y2 * x1 / x2; - base = data[0].y; x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); - x2 = data[1].x - data[0].x; - y2 = data[1].y - data[0].y; let expectedBottom = base + y2 * x1 / x2; assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); @@ -496,10 +490,7 @@ describe("Plots", () => { let y2 = data[1].y - data[0].y; let expectedTop = base + y2 * x1 / x2; - base = data[0].y; x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); - x2 = data[1].x - data[0].x; - y2 = data[1].y - data[0].y; let expectedBottom = base + y2 * x1 / x2; assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); @@ -529,10 +520,7 @@ describe("Plots", () => { let y2 = data[1].y - data[0].y; let expectedTop = base + y2 * x1 / x2; - base = data[0].y; x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); - x2 = data[1].x - data[0].x; - y2 = data[1].y - data[0].y; let expectedBottom = base + y2 * x1 / x2; assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); @@ -562,10 +550,7 @@ describe("Plots", () => { let y2 = data[1].y - data[0].y; let expectedTop = base + y2 * x1 / x2; - base = data[0].y; x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); - x2 = data[1].x - data[0].x; - y2 = data[1].y - data[0].y; let expectedBottom = base + y2 * x1 / x2; assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); @@ -596,10 +581,7 @@ describe("Plots", () => { let y2 = data[1].y - data[0].y; let expectedTop = base + y2 * x1 / x2; - base = data[0].y; x1 = (xScale.domain()[0] - data[0].x) + (xScale.domain()[1] - xScale.domain()[0]) * (1 + yScale.padProportion() / 2); - x2 = data[1].x - data[0].x; - y2 = data[1].y - data[0].y; let expectedBottom = base + y2 * x1 / x2; assert.closeTo(yScale.domain()[0], expectedBottom, 0.001, "smooth autoranging forces the domain to include the line (left)"); @@ -683,10 +665,7 @@ describe("Plots", () => { let y2 = data[1].x - data[0].x; let expectedTop = base + y2 * x1 / x2; - base = data[0].x; x1 = (yScale.domain()[0] - data[0].y); - x2 = data[1].y - data[0].y; - y2 = data[1].x - data[0].x; let expectedBottom = base + y2 * x1 / x2; assert.closeTo(xScale.domain()[0], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (left)"); From 9243ca9bcc1151ea34b39bc2a654ecf56c7d1d35 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Mon, 17 Aug 2015 17:58:11 -0700 Subject: [PATCH 094/117] [autorangeSmooth] snapsDomain -> snappingDomainEnabled --- plottable.d.ts | 4 ++-- plottable.js | 16 ++++++++-------- src/plots/linePlot.ts | 4 ++-- src/scales/quantitativeScale.ts | 16 ++++++++-------- test/scales/linearScaleTests.ts | 10 +++++----- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 86c695b67c..5e55649ed9 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -889,11 +889,11 @@ declare module Plottable { /** * Gets whether or not the scale snaps its domain to nice values. */ - snapsDomain(): boolean; + snappingDomainEnabled(): boolean; /** * Sets whether or not the scale snaps its domain to nice values. */ - snapsDomain(snapsDomain: boolean): QuantitativeScale; + snappingDomainEnabled(snappingDomainEnabled: boolean): QuantitativeScale; protected _expandSingleValueDomain(singleValueDomain: D[]): D[]; /** * Computes the domain value corresponding to a supplied range value. diff --git a/plottable.js b/plottable.js index 53f19866d4..fcc18445dc 100644 --- a/plottable.js +++ b/plottable.js @@ -1613,7 +1613,7 @@ var Plottable; _super.call(this); this._tickGenerator = function (scale) { return scale.defaultTicks(); }; this._padProportion = 0.05; - this._snapsDomain = true; + this._snappingDomainEnabled = true; this._paddingExceptionsProviders = new Plottable.Utils.Set(); } QuantitativeScale.prototype.autoDomain = function () { @@ -1725,16 +1725,16 @@ var Plottable; }); var newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); var newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); - if (this._snapsDomain) { + if (this._snappingDomainEnabled) { return this._niceDomain([newMin, newMax]); } return ([newMin, newMax]); }; - QuantitativeScale.prototype.snapsDomain = function (snapsDomain) { - if (snapsDomain == null) { - return this._snapsDomain; + QuantitativeScale.prototype.snappingDomainEnabled = function (snappingDomainEnabled) { + if (snappingDomainEnabled == null) { + return this._snappingDomainEnabled; } - this._snapsDomain = snapsDomain; + this._snappingDomainEnabled = snappingDomainEnabled; this._autoDomainIfAutomaticMode(); return this; }; @@ -8271,10 +8271,10 @@ var Plottable; }; Line.prototype._setScaleSnapping = function () { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof Plottable.QuantitativeScale) { - this.x().scale.snapsDomain(!this.autorangeSmooth()); + this.x().scale.snappingDomainEnabled(!this.autorangeSmooth()); } if (this.autorangeMode() === "y" && this.y() && this.y().scale && this.y().scale instanceof Plottable.QuantitativeScale) { - this.y().scale.snapsDomain(!this.autorangeSmooth()); + this.y().scale.snappingDomainEnabled(!this.autorangeSmooth()); } }; Line.prototype.interpolator = function (interpolator) { diff --git a/src/plots/linePlot.ts b/src/plots/linePlot.ts index e92219b512..3e0f37575b 100644 --- a/src/plots/linePlot.ts +++ b/src/plots/linePlot.ts @@ -95,11 +95,11 @@ export module Plots { private _setScaleSnapping() { if (this.autorangeMode() === "x" && this.x() && this.x().scale && this.x().scale instanceof QuantitativeScale) { - (>this.x().scale).snapsDomain(!this.autorangeSmooth()); + (>this.x().scale).snappingDomainEnabled(!this.autorangeSmooth()); } if (this.autorangeMode() === "y" && this.y() && this.y().scale && this.y().scale instanceof QuantitativeScale) { - (>this.y().scale).snapsDomain(!this.autorangeSmooth()); + (>this.y().scale).snappingDomainEnabled(!this.autorangeSmooth()); } } diff --git a/src/scales/quantitativeScale.ts b/src/scales/quantitativeScale.ts index cccb7f0379..8e06c18da5 100644 --- a/src/scales/quantitativeScale.ts +++ b/src/scales/quantitativeScale.ts @@ -8,7 +8,7 @@ export class QuantitativeScale extends Scale { private _paddingExceptionsProviders: Utils.Set>; private _domainMin: D; private _domainMax: D; - private _snapsDomain = true; + private _snappingDomainEnabled = true; /** * A QuantitativeScale is a Scale that maps number-like values to numbers. @@ -154,7 +154,7 @@ export class QuantitativeScale extends Scale { let newMin = minExistsInExceptions ? min : this.invert(this.scale(min) - (this.scale(max) - this.scale(min)) * p); let newMax = maxExistsInExceptions ? max : this.invert(this.scale(max) + (this.scale(max) - this.scale(min)) * p); - if (this._snapsDomain) { + if (this._snappingDomainEnabled) { return this._niceDomain([newMin, newMax]); } return ([newMin, newMax]); @@ -163,17 +163,17 @@ export class QuantitativeScale extends Scale { /** * Gets whether or not the scale snaps its domain to nice values. */ - public snapsDomain(): boolean; + public snappingDomainEnabled(): boolean; /** * Sets whether or not the scale snaps its domain to nice values. */ - public snapsDomain(snapsDomain: boolean): QuantitativeScale; - public snapsDomain(snapsDomain?: boolean): any { - if (snapsDomain == null) { - return this._snapsDomain; + public snappingDomainEnabled(snappingDomainEnabled: boolean): QuantitativeScale; + public snappingDomainEnabled(snappingDomainEnabled?: boolean): any { + if (snappingDomainEnabled == null) { + return this._snappingDomainEnabled; } - this._snapsDomain = snapsDomain; + this._snappingDomainEnabled = snappingDomainEnabled; this._autoDomainIfAutomaticMode(); return this; } diff --git a/test/scales/linearScaleTests.ts b/test/scales/linearScaleTests.ts index ef2947baba..9b05c77e98 100644 --- a/test/scales/linearScaleTests.ts +++ b/test/scales/linearScaleTests.ts @@ -122,9 +122,9 @@ describe("Scales", () => { it("domain snapping setter and getter", () => { let scale = new Plottable.Scales.Linear(); - assert.strictEqual(scale.snapsDomain(), true, "scales make their domain snap by default"); - assert.strictEqual(scale.snapsDomain(false), scale, "setting disabling domain snapping returns the scale"); - assert.strictEqual(scale.snapsDomain(), false, "the domain is no longer snaps"); + assert.strictEqual(scale.snappingDomainEnabled(), true, "scales make their domain snap by default"); + assert.strictEqual(scale.snappingDomainEnabled(false), scale, "setting disabling domain snapping returns the scale"); + assert.strictEqual(scale.snappingDomainEnabled(), false, "the domain is no longer snaps"); }); it("domain snapping works", () => { @@ -134,9 +134,9 @@ describe("Scales", () => { }); assert.deepEqual(scale.domain(), [1, 3.2], "domain snapping works"); - scale.snapsDomain(false); + scale.snappingDomainEnabled(false); assert.deepEqual(scale.domain(), [1.073123123, 3.173123123], "domain snapping can be deactivated"); - scale.snapsDomain(true); + scale.snappingDomainEnabled(true); assert.deepEqual(scale.domain(), [1, 3.2], "domain snapping can be activated back"); }); }); From 431fc4356ca607e9d68970af3599264c9d6cd47f Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Tue, 18 Aug 2015 11:17:14 -0700 Subject: [PATCH 095/117] unit tests --- plottable.css | 4 ++++ plottable.js | 1 - src/drawers/arcOutlineDrawer.ts | 1 - test/plots/piePlotTests.ts | 29 +++++++++++++++++++++++++++-- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/plottable.css b/plottable.css index fe8daab4a5..1fbf7d10fe 100644 --- a/plottable.css +++ b/plottable.css @@ -182,3 +182,7 @@ svg.plottable { stroke: #CCC; stroke-width: 1px; } + +.plottable .pie-plot .arc.outline { + stroke-linejoin: round; +} \ No newline at end of file diff --git a/plottable.js b/plottable.js index 1705ca456f..6d6179ab7c 100644 --- a/plottable.js +++ b/plottable.js @@ -2890,7 +2890,6 @@ var Plottable; ArcOutline.prototype._applyDefaultAttributes = function (selection) { _super.prototype._applyDefaultAttributes.call(this, selection); selection.style("fill", "none"); - selection.style("stroke-linejoin", "round"); }; return ArcOutline; })(Plottable.Drawer); diff --git a/src/drawers/arcOutlineDrawer.ts b/src/drawers/arcOutlineDrawer.ts index 199d78cdec..1e3d3af07c 100644 --- a/src/drawers/arcOutlineDrawer.ts +++ b/src/drawers/arcOutlineDrawer.ts @@ -14,7 +14,6 @@ export module Drawers { protected _applyDefaultAttributes(selection: d3.Selection) { super._applyDefaultAttributes(selection); selection.style("fill", "none"); - selection.style("stroke-linejoin", "round"); } } } diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index ba00c07709..ba606d2cc3 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -30,12 +30,34 @@ describe("Plots", () => { let arcOutlinePaths = renderArea.selectAll(".arc.outline"); assert.strictEqual(arcPaths.size(), 4, "2 paths per datum"); assert.strictEqual(arcFillPaths.size(), 2, "1 fill path per datum"); - assert.strictEqual(arcOutlinePaths.size(), 2, "1 outline path1 per datum"); + assert.strictEqual(arcOutlinePaths.size(), 2, "1 outline path per datum"); assert.strictEqual(arcFillPaths.style("stroke"), "none", "fill paths have no stroke"); assert.strictEqual(arcOutlinePaths.style("fill"), "none", "outline paths have no fill"); svg.remove(); }); + it("each entity selection consists of a fill path and a stroke path", () => { + let svg = TestMethods.generateSVG(500, 500); + let piePlot = new Plottable.Plots.Pie(); + piePlot.sectorValue((d) => d.value); + let data = [ + { value: 1 }, + { value: 1 } + ]; + let dataset = new Plottable.Dataset(data); + piePlot.addDataset(dataset); + piePlot.renderTo(svg); + + let entities = piePlot.entities(); + entities.forEach((entity) => { + assert.strictEqual(entity.selection.size(), 2, "each entity selection has 2 paths"); + assert.lengthOf(entity.selection.filter("fill"), 1, "each entity selection has 1 fill path"); + assert.lengthOf(entity.selection.filter("outline"), 1, "each entity selection has 1 stroke path"); + }); + + svg.remove(); + }); + it("updates slices when data changes", () => { let svg = TestMethods.generateSVG(500, 500); let piePlot = new Plottable.Plots.Pie(); @@ -375,13 +397,16 @@ describe("Plots", () => { it("retrieves all dataset selections with no args", () => { let allSectors = piePlot.selections(); assert.strictEqual(allSectors.size(), 2 * 2, "all sectors retrieved"); - + assert.strictEqual(allSectors.filter(".fill").size(), 2, "each sector has a fill path"); + assert.strictEqual(allSectors.filter(".outline").size(), 2, "each sector has an outline path"); svg.remove(); }); it("retrieves correct selections", () => { let allSectors = piePlot.selections([simpleDataset]); assert.strictEqual(allSectors.size(), 2 * 2, "all sectors retrieved"); + assert.strictEqual(allSectors.filter(".fill").size(), 2, "each sector has a fill path"); + assert.strictEqual(allSectors.filter(".outline").size(), 2, "each sector has an outline path"); assert.includeMembers(allSectors.data(), simpleData, "dataset data in selection data"); svg.remove(); From 27c3b285a465d106b9b25ce1a0ee9a79320b035e Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 11:52:15 -0700 Subject: [PATCH 096/117] [datasetPerf] Failing tests but faster updates --- plottable.d.ts | 16 ++++++----- plottable.js | 63 ++++++++++++++++++++++++----------------- src/plots/plot.ts | 72 +++++++++++++++++++++++++++++------------------ 3 files changed, 90 insertions(+), 61 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index a0e29f5500..3314082ffa 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2521,13 +2521,6 @@ declare module Plottable { anchor(selection: d3.Selection): Plot; protected _setup(): void; destroy(): void; - /** - * Adds a Dataset to the Plot. - * - * @param {Dataset} dataset - * @returns {Plot} The calling Plot. - */ - addDataset(dataset: Dataset): Plot; protected _createNodesForDataset(dataset: Dataset): Drawer; protected _createDrawer(dataset: Dataset): Drawer; protected _getAnimator(key: string): Animator; @@ -2592,6 +2585,14 @@ declare module Plottable { * @returns {Plot} The calling Plot. */ animator(animatorKey: string, animator: Animator): Plot; + /** + * Adds a Dataset to the Plot. + * + * @param {Dataset} dataset + * @returns {Plot} The calling Plot. + */ + addDataset(dataset: Dataset): void; + _addDataset(dataset: Dataset, withUpdate: boolean): Plot; /** * Removes a Dataset from the Plot. * @@ -2599,6 +2600,7 @@ declare module Plottable { * @returns {Plot} The calling Plot. */ removeDataset(dataset: Dataset): Plot; + _removeDataset(dataset: Dataset, withUpdate: boolean): Plot; protected _removeDatasetNodes(dataset: Dataset): void; datasets(): Dataset[]; datasets(datasets: Dataset[]): Plot; diff --git a/plottable.js b/plottable.js index 1bcf1cf90b..aa0ce90bb7 100644 --- a/plottable.js +++ b/plottable.js @@ -6415,26 +6415,6 @@ var Plottable; this._scales().forEach(function (scale) { return scale.offUpdate(_this._renderCallback); }); this.datasets().forEach(function (dataset) { return _this.removeDataset(dataset); }); }; - /** - * Adds a Dataset to the Plot. - * - * @param {Dataset} dataset - * @returns {Plot} The calling Plot. - */ - Plot.prototype.addDataset = function (dataset) { - if (this.datasets().indexOf(dataset) > -1) { - this.removeDataset(dataset); - } - ; - var drawer = this._createDrawer(dataset); - this._datasetToDrawer.set(dataset, drawer); - if (this._isSetup) { - this._createNodesForDataset(dataset); - } - dataset.onUpdate(this._onDatasetUpdateCallback); - this._onDatasetUpdate(); - return this; - }; Plot.prototype._createNodesForDataset = function (dataset) { var drawer = this._datasetToDrawer.get(dataset); drawer.renderArea(this._renderArea.append("g")); @@ -6618,6 +6598,30 @@ var Plottable; return this; } }; + /** + * Adds a Dataset to the Plot. + * + * @param {Dataset} dataset + * @returns {Plot} The calling Plot. + */ + Plot.prototype.addDataset = function (dataset) { + this._addDataset(dataset, true); + }; + Plot.prototype._addDataset = function (dataset, withUpdate) { + // if (this.datasets().indexOf(dataset) > -1) { + this._removeDataset(dataset, false); + // }; + var drawer = this._createDrawer(dataset); + this._datasetToDrawer.set(dataset, drawer); + if (this._isSetup) { + this._createNodesForDataset(dataset); + } + dataset.onUpdate(this._onDatasetUpdateCallback); + if (withUpdate) { + this._onDatasetUpdate(); + } + return this; + }; /** * Removes a Dataset from the Plot. * @@ -6625,10 +6629,16 @@ var Plottable; * @returns {Plot} The calling Plot. */ Plot.prototype.removeDataset = function (dataset) { - if (this.datasets().indexOf(dataset) > -1) { - this._removeDatasetNodes(dataset); - dataset.offUpdate(this._onDatasetUpdateCallback); - this._datasetToDrawer.delete(dataset); + return this._removeDataset(dataset, true); + }; + Plot.prototype._removeDataset = function (dataset, withUpdate) { + if (this.datasets().indexOf(dataset) === -1) { + return this; + } + this._removeDatasetNodes(dataset); + dataset.offUpdate(this._onDatasetUpdateCallback); + this._datasetToDrawer.delete(dataset); + if (withUpdate) { this._onDatasetUpdate(); } return this; @@ -6644,8 +6654,9 @@ var Plottable; if (datasets == null) { return currentDatasets; } - currentDatasets.forEach(function (dataset) { return _this.removeDataset(dataset); }); - datasets.forEach(function (dataset) { return _this.addDataset(dataset); }); + currentDatasets.forEach(function (dataset) { return _this._removeDataset(dataset, false); }); + datasets.forEach(function (dataset) { return _this._addDataset(dataset, false); }); + this._onDatasetUpdate(); return this; }; Plot.prototype._getDrawersInOrder = function () { diff --git a/src/plots/plot.ts b/src/plots/plot.ts index adb3933587..bfe617fadb 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -96,28 +96,6 @@ export class Plot extends Component { this.datasets().forEach((dataset) => this.removeDataset(dataset)); } - /** - * Adds a Dataset to the Plot. - * - * @param {Dataset} dataset - * @returns {Plot} The calling Plot. - */ - public addDataset(dataset: Dataset) { - if (this.datasets().indexOf(dataset) > -1) { - this.removeDataset(dataset); - }; - let drawer = this._createDrawer(dataset); - this._datasetToDrawer.set(dataset, drawer); - - if (this._isSetup) { - this._createNodesForDataset(dataset); - } - - dataset.onUpdate(this._onDatasetUpdateCallback); - this._onDatasetUpdate(); - return this; - } - protected _createNodesForDataset(dataset: Dataset) { let drawer = this._datasetToDrawer.get(dataset); drawer.renderArea(this._renderArea.append("g")); @@ -373,6 +351,34 @@ export class Plot extends Component { } } + /** + * Adds a Dataset to the Plot. + * + * @param {Dataset} dataset + * @returns {Plot} The calling Plot. + */ + public addDataset(dataset: Dataset) { + this._addDataset(dataset, true); + } + + public _addDataset(dataset: Dataset, withUpdate: boolean) { + // if (this.datasets().indexOf(dataset) > -1) { + this._removeDataset(dataset, false); + // }; + let drawer = this._createDrawer(dataset); + this._datasetToDrawer.set(dataset, drawer); + + if (this._isSetup) { + this._createNodesForDataset(dataset); + } + + dataset.onUpdate(this._onDatasetUpdateCallback); + if (withUpdate) { + this._onDatasetUpdate(); + } + return this; + } + /** * Removes a Dataset from the Plot. * @@ -380,10 +386,18 @@ export class Plot extends Component { * @returns {Plot} The calling Plot. */ public removeDataset(dataset: Dataset): Plot { - if (this.datasets().indexOf(dataset) > -1) { - this._removeDatasetNodes(dataset); - dataset.offUpdate(this._onDatasetUpdateCallback); - this._datasetToDrawer.delete(dataset); + return this._removeDataset(dataset, true); + } + + public _removeDataset(dataset: Dataset, withUpdate: boolean) { + if (this.datasets().indexOf(dataset) === -1) { + return this; + } + + this._removeDatasetNodes(dataset); + dataset.offUpdate(this._onDatasetUpdateCallback); + this._datasetToDrawer.delete(dataset); + if (withUpdate) { this._onDatasetUpdate(); } return this; @@ -402,8 +416,10 @@ export class Plot extends Component { if (datasets == null) { return currentDatasets; } - currentDatasets.forEach((dataset) => this.removeDataset(dataset)); - datasets.forEach((dataset) => this.addDataset(dataset)); + + currentDatasets.forEach((dataset) => this._removeDataset(dataset, false)); + datasets.forEach((dataset) => this._addDataset(dataset, false)); + this._onDatasetUpdate(); return this; } From b16cfa4597675b36d9f2c9fca1c29c8f7abf8fa2 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 12:34:24 -0700 Subject: [PATCH 097/117] [datasetPerf] fixed tests --- plottable.d.ts | 2 +- plottable.js | 2 +- src/plots/plot.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 3314082ffa..80aceda04b 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2591,7 +2591,7 @@ declare module Plottable { * @param {Dataset} dataset * @returns {Plot} The calling Plot. */ - addDataset(dataset: Dataset): void; + addDataset(dataset: Dataset): Plot; _addDataset(dataset: Dataset, withUpdate: boolean): Plot; /** * Removes a Dataset from the Plot. diff --git a/plottable.js b/plottable.js index aa0ce90bb7..5e4d854f98 100644 --- a/plottable.js +++ b/plottable.js @@ -6605,7 +6605,7 @@ var Plottable; * @returns {Plot} The calling Plot. */ Plot.prototype.addDataset = function (dataset) { - this._addDataset(dataset, true); + return this._addDataset(dataset, true); }; Plot.prototype._addDataset = function (dataset, withUpdate) { // if (this.datasets().indexOf(dataset) > -1) { diff --git a/src/plots/plot.ts b/src/plots/plot.ts index bfe617fadb..57fccc84e6 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -358,7 +358,7 @@ export class Plot extends Component { * @returns {Plot} The calling Plot. */ public addDataset(dataset: Dataset) { - this._addDataset(dataset, true); + return this._addDataset(dataset, true); } public _addDataset(dataset: Dataset, withUpdate: boolean) { From 62f1c157c5fec662f4e1fb6ff3ae87395afe76f5 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Tue, 18 Aug 2015 12:28:12 -0700 Subject: [PATCH 098/117] hide labels that are cut off by edges or other rectangles --- plottable.js | 41 +++++++++++++++++++++------ src/plots/rectanglePlot.ts | 47 +++++++++++++++++++++++++------ test/plots/rectanglePlotTests.ts | 48 ++++++++++++++++++++++++++++++-- 3 files changed, 116 insertions(+), 20 deletions(-) diff --git a/plottable.js b/plottable.js index f08d2a7000..37962055a5 100644 --- a/plottable.js +++ b/plottable.js @@ -7419,10 +7419,7 @@ var Plottable; } return this._entitiesIntersecting(dataXRange, dataYRange); }; - Rectangle.prototype._entityBBox = function (entity, attrToProjector) { - var datum = entity.datum; - var index = entity.index; - var dataset = entity.dataset; + Rectangle.prototype._entityBBox = function (datum, index, dataset, attrToProjector) { return { x: attrToProjector["x"](datum, index, dataset), y: attrToProjector["y"](datum, index, dataset), @@ -7435,7 +7432,7 @@ var Plottable; var intersected = []; var attrToProjector = this._generateAttrToProjector(); this.entities().forEach(function (entity) { - if (Plottable.Utils.DOM.intersectsBBox(xValOrRange, yValOrRange, _this._entityBBox(entity, attrToProjector))) { + if (Plottable.Utils.DOM.intersectsBBox(xValOrRange, yValOrRange, _this._entityBBox(entity.datum, entity.index, entity.dataset, attrToProjector))) { intersected.push(entity); } }); @@ -7510,7 +7507,7 @@ var Plottable; }; Rectangle.prototype._additionalPaint = function (time) { var _this = this; - this._renderArea.select(".label-area").remove(); + this._renderArea.selectAll(".label-area").remove(); if (this._labelsEnabled && this.label() != null) { Plottable.Utils.Window.setTimeout(function () { return _this._drawLabels(); }, time); } @@ -7518,14 +7515,21 @@ var Plottable; Rectangle.prototype._drawLabels = function () { var _this = this; var dataToDraw = this._getDataToDraw(); - this.datasets().forEach(function (dataset) { return _this._drawLabel(dataToDraw.get(dataset), dataset); }); + this.datasets().forEach(function (dataset, i) { return _this._drawLabel(dataToDraw, dataset, i); }); }; - Rectangle.prototype._drawLabel = function (data, dataset) { + Rectangle.prototype._drawLabel = function (dataToDraw, dataset, datasetIndex) { var _this = this; var attrToProjector = this._generateAttrToProjector(); var labelArea = this._renderArea.append("g").classed("label-area", true); var measurer = new SVGTypewriter.Measurers.Measurer(labelArea); var writer = new SVGTypewriter.Writers.Writer(measurer); + var xRange = this.x().scale.range(); + var yRange = this.y().scale.range(); + var xMin = Math.min.apply(null, xRange); + var xMax = Math.max.apply(null, xRange); + var yMin = Math.min.apply(null, yRange); + var yMax = Math.max.apply(null, yRange); + var data = dataToDraw.get(dataset); data.forEach(function (datum, datumIndex) { var label = "" + _this.label()(datum, datumIndex, dataset); var measurement = measurer.measure(label); @@ -7538,6 +7542,14 @@ var Plottable; var verticalOffset = (height - measurement.height) / 2; x += horizontalOffset; y += verticalOffset; + var xLabelRange = { min: x, max: x + measurement.width }; + var yLabelRange = { min: y, max: y + measurement.height }; + if (xLabelRange.min < xMin || xLabelRange.max > xMax || yLabelRange.min < yMin || yLabelRange.max > yMax) { + return; + } + if (_this._overlayLabel(xLabelRange, yLabelRange, datumIndex, datasetIndex, dataToDraw)) { + return; + } var color = attrToProjector["fill"] == null ? "black" : attrToProjector["fill"](datum, datumIndex, dataset); var dark = Plottable.Utils.Color.contrast("white", color) * 1.6 < Plottable.Utils.Color.contrast("black", color); var g = labelArea.append("g").attr("transform", "translate(" + x + "," + y + ")"); @@ -7552,6 +7564,19 @@ var Plottable; } }); }; + Rectangle.prototype._overlayLabel = function (labelXRange, labelYRange, datumIndex, datasetIndex, dataToDraw) { + var attrToProjector = this._generateAttrToProjector(); + for (var i = datasetIndex; i < this.datasets().length; i++) { + var dataset = this.datasets()[i]; + var data = dataToDraw.get(dataset); + for (var j = (i === datasetIndex ? datumIndex + 1 : 0); j < data.length; j++) { + if (Plottable.Utils.DOM.intersectsBBox(labelXRange, labelYRange, this._entityBBox(data[j], j, dataset, attrToProjector))) { + return true; + } + } + } + return false; + }; Rectangle._X2_KEY = "x2"; Rectangle._Y2_KEY = "y2"; return Rectangle; diff --git a/src/plots/rectanglePlot.ts b/src/plots/rectanglePlot.ts index 1d0dd82f3d..f4e9d2c949 100644 --- a/src/plots/rectanglePlot.ts +++ b/src/plots/rectanglePlot.ts @@ -282,10 +282,7 @@ export module Plots { return this._entitiesIntersecting(dataXRange, dataYRange); } - private _entityBBox(entity: PlotEntity, attrToProjector: AttributeToProjector): SVGRect { - let datum = entity.datum; - let index = entity.index; - let dataset = entity.dataset; + private _entityBBox(datum: any, index: number, dataset: Plottable.Dataset, attrToProjector: AttributeToProjector): SVGRect { return { x: attrToProjector["x"](datum, index, dataset), y: attrToProjector["y"](datum, index, dataset), @@ -298,7 +295,8 @@ export module Plots { let intersected: PlotEntity[] = []; let attrToProjector = this._generateAttrToProjector(); this.entities().forEach((entity) => { - if (Utils.DOM.intersectsBBox(xValOrRange, yValOrRange, this._entityBBox(entity, attrToProjector))) { + if (Utils.DOM.intersectsBBox(xValOrRange, yValOrRange, + this._entityBBox(entity.datum, entity.index, entity.dataset, attrToProjector))) { intersected.push(entity); } }); @@ -404,7 +402,7 @@ export module Plots { } protected _additionalPaint(time: number) { - this._renderArea.select(".label-area").remove(); + this._renderArea.selectAll(".label-area").remove(); if (this._labelsEnabled && this.label() != null) { Utils.Window.setTimeout(() => this._drawLabels(), time); } @@ -412,14 +410,21 @@ export module Plots { private _drawLabels() { let dataToDraw = this._getDataToDraw(); - this.datasets().forEach((dataset) => this._drawLabel(dataToDraw.get(dataset), dataset)); + this.datasets().forEach((dataset, i) => this._drawLabel(dataToDraw, dataset, i)); } - private _drawLabel(data: any[], dataset: Dataset) { + private _drawLabel(dataToDraw: Utils.Map, dataset: Dataset, datasetIndex: number) { let attrToProjector = this._generateAttrToProjector(); let labelArea = this._renderArea.append("g").classed("label-area", true); let measurer = new SVGTypewriter.Measurers.Measurer(labelArea); let writer = new SVGTypewriter.Writers.Writer(measurer); + let xRange = this.x().scale.range(); + let yRange = this.y().scale.range(); + let xMin = Math.min.apply(null, xRange); + let xMax = Math.max.apply(null, xRange); + let yMin = Math.min.apply(null, yRange); + let yMax = Math.max.apply(null, yRange); + let data = dataToDraw.get(dataset); data.forEach((datum, datumIndex) => { let label = "" + this.label()(datum, datumIndex, dataset); let measurement = measurer.measure(label); @@ -428,13 +433,22 @@ export module Plots { let y = attrToProjector["y"](datum, datumIndex, dataset); let width = attrToProjector["width"](datum, datumIndex, dataset); let height = attrToProjector["height"](datum, datumIndex, dataset); - if (measurement.height <= height && measurement.width <= width) { + let horizontalOffset = (width - measurement.width) / 2; let verticalOffset = (height - measurement.height) / 2; x += horizontalOffset; y += verticalOffset; + let xLabelRange = { min: x, max: x + measurement.width }; + let yLabelRange = { min : y, max: y + measurement.height }; + if (xLabelRange.min < xMin || xLabelRange.max > xMax || yLabelRange.min < yMin || yLabelRange.max > yMax) { + return; + } + if (this._overlayLabel(xLabelRange, yLabelRange, datumIndex, datasetIndex, dataToDraw)) { + return; + } + let color = attrToProjector["fill"] == null ? "black" : attrToProjector["fill"](datum, datumIndex, dataset); let dark = Utils.Color.contrast("white", color) * 1.6 < Utils.Color.contrast("black", color); let g = labelArea.append("g").attr("transform", "translate(" + x + "," + y + ")"); @@ -450,6 +464,21 @@ export module Plots { } }); } + + private _overlayLabel(labelXRange: Range, labelYRange: Range, datumIndex: number, datasetIndex: number, + dataToDraw: Utils.Map) { + let attrToProjector = this._generateAttrToProjector(); + for (let i = datasetIndex; i < this.datasets().length; i ++ ) { + let dataset = this.datasets()[i]; + let data = dataToDraw.get(dataset); + for (let j = (i === datasetIndex ? datumIndex + 1 : 0); j < data.length ; j ++ ) { + if (Utils.DOM.intersectsBBox(labelXRange, labelYRange, this._entityBBox(data[j], j, dataset, attrToProjector))) { + return true; + } + } + } + return false; + } } } } diff --git a/test/plots/rectanglePlotTests.ts b/test/plots/rectanglePlotTests.ts index 8beb258656..abeae9971d 100644 --- a/test/plots/rectanglePlotTests.ts +++ b/test/plots/rectanglePlotTests.ts @@ -449,9 +449,11 @@ describe("Plots", () => { let rectanglePlot: Plottable.Plots.Rectangle; let DATA: [any]; let dataset: Plottable.Dataset; + let xScale: Plottable.Scales.Linear; + let yScale: Plottable.Scales.Linear; beforeEach(() => { - let xScale = new Plottable.Scales.Linear(); - let yScale = new Plottable.Scales.Linear(); + xScale = new Plottable.Scales.Linear(); + yScale = new Plottable.Scales.Linear(); svg = TestMethods.generateSVG(SVG_WIDTH / 2, SVG_HEIGHT); rectanglePlot = new Plottable.Plots.Rectangle(); DATA = [ @@ -508,13 +510,53 @@ describe("Plots", () => { let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); assert.lengthOf(texts, 2, "all labels are drawn"); - let data2 = [{ x: 0, y: 0, x2: 1, y2: 1, val: 5 }]; + let data2 = [{ x: 0, y: 0, x2: 1, y2: 1, val: "5" }]; dataset.data(data2); texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); assert.lengthOf(texts, 1, "new label is drawn"); assert.strictEqual(texts[0], "5"); svg.remove(); }); + + it("labels cut off by edges are not shown", () => { + rectanglePlot.labelsEnabled(true); + let data = [ + { x: 2, y: 2, x2: 3, y2: 3, val: "center" }, + { x: 0.5, y: 2, x2: 1.5, y2: 3, val: "left" }, + { x: 3.5, y: 2, x2: 4.5, y2: 3, val: "right" }, + { x: 2, y: 3.5, x2: 3, y2: 4.5, val: "top" }, + { x: 2, y: 0.5, x2: 3, y2: 1.5, val: "bottom" }]; + dataset.data(data); + xScale.domain([1, 4]); + yScale.domain([1, 4]); + + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 1, "only one label is drawn"); + assert.strictEqual(texts[0], "center"); + svg.remove(); + }); + + it("labels cut off by other rectangels are not shown", () => { + rectanglePlot.labelsEnabled(true); + let data = [ + { x: 0, y: 0, x2: 2, y2: 2, val: "bottom" }, + { x: 1, y: 1, x2: 3, y2: 3, val: "middle" }]; + let data2 = [ + { x: 2, y: 2, x2: 4, y2: 4, val: "top" }, + { x: 4, y: 4, x2: 6, y2: 6, val: "other" }]; + dataset.data(data); + let texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 1, "1 label is drawn"); + assert.strictEqual(texts[0], "middle"); + + rectanglePlot.addDataset(new Plottable.Dataset(data2)); + + texts = svg.selectAll("text")[0].map((n: any) => d3.select(n).text()); + assert.lengthOf(texts, 2, "2 labels are drawn"); + assert.strictEqual(texts[0], "top"); + assert.strictEqual(texts[1], "other"); + svg.remove(); + }); }); }); }); From f29b508105921f67d7a6f51fdf4cb93c8e9f4cae Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 12:37:13 -0700 Subject: [PATCH 099/117] [datasetPerf] Removed debug comments --- plottable.d.ts | 2 -- plottable.js | 10 ++++------ src/plots/plot.ts | 12 +++++------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 80aceda04b..0a8086a2a2 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2592,7 +2592,6 @@ declare module Plottable { * @returns {Plot} The calling Plot. */ addDataset(dataset: Dataset): Plot; - _addDataset(dataset: Dataset, withUpdate: boolean): Plot; /** * Removes a Dataset from the Plot. * @@ -2600,7 +2599,6 @@ declare module Plottable { * @returns {Plot} The calling Plot. */ removeDataset(dataset: Dataset): Plot; - _removeDataset(dataset: Dataset, withUpdate: boolean): Plot; protected _removeDatasetNodes(dataset: Dataset): void; datasets(): Dataset[]; datasets(datasets: Dataset[]): Plot; diff --git a/plottable.js b/plottable.js index 5e4d854f98..2bb490abdd 100644 --- a/plottable.js +++ b/plottable.js @@ -6607,17 +6607,15 @@ var Plottable; Plot.prototype.addDataset = function (dataset) { return this._addDataset(dataset, true); }; - Plot.prototype._addDataset = function (dataset, withUpdate) { - // if (this.datasets().indexOf(dataset) > -1) { + Plot.prototype._addDataset = function (dataset, dispatchUpdate) { this._removeDataset(dataset, false); - // }; var drawer = this._createDrawer(dataset); this._datasetToDrawer.set(dataset, drawer); if (this._isSetup) { this._createNodesForDataset(dataset); } dataset.onUpdate(this._onDatasetUpdateCallback); - if (withUpdate) { + if (dispatchUpdate) { this._onDatasetUpdate(); } return this; @@ -6631,14 +6629,14 @@ var Plottable; Plot.prototype.removeDataset = function (dataset) { return this._removeDataset(dataset, true); }; - Plot.prototype._removeDataset = function (dataset, withUpdate) { + Plot.prototype._removeDataset = function (dataset, dispatchUpdate) { if (this.datasets().indexOf(dataset) === -1) { return this; } this._removeDatasetNodes(dataset); dataset.offUpdate(this._onDatasetUpdateCallback); this._datasetToDrawer.delete(dataset); - if (withUpdate) { + if (dispatchUpdate) { this._onDatasetUpdate(); } return this; diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 57fccc84e6..a259bc80a0 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -361,10 +361,8 @@ export class Plot extends Component { return this._addDataset(dataset, true); } - public _addDataset(dataset: Dataset, withUpdate: boolean) { - // if (this.datasets().indexOf(dataset) > -1) { - this._removeDataset(dataset, false); - // }; + private _addDataset(dataset: Dataset, dispatchUpdate: boolean) { + this._removeDataset(dataset, false); let drawer = this._createDrawer(dataset); this._datasetToDrawer.set(dataset, drawer); @@ -373,7 +371,7 @@ export class Plot extends Component { } dataset.onUpdate(this._onDatasetUpdateCallback); - if (withUpdate) { + if (dispatchUpdate) { this._onDatasetUpdate(); } return this; @@ -389,7 +387,7 @@ export class Plot extends Component { return this._removeDataset(dataset, true); } - public _removeDataset(dataset: Dataset, withUpdate: boolean) { + private _removeDataset(dataset: Dataset, dispatchUpdate: boolean) { if (this.datasets().indexOf(dataset) === -1) { return this; } @@ -397,7 +395,7 @@ export class Plot extends Component { this._removeDatasetNodes(dataset); dataset.offUpdate(this._onDatasetUpdateCallback); this._datasetToDrawer.delete(dataset); - if (withUpdate) { + if (dispatchUpdate) { this._onDatasetUpdate(); } return this; From 61318b558409081e408dc08dd13f8dc2f19199f7 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 12:40:19 -0700 Subject: [PATCH 100/117] [datasetPerf] perfImprovement on destroy() as well --- plottable.js | 3 ++- src/plots/plot.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plottable.js b/plottable.js index 2bb490abdd..5c7e442120 100644 --- a/plottable.js +++ b/plottable.js @@ -6413,7 +6413,8 @@ var Plottable; var _this = this; _super.prototype.destroy.call(this); this._scales().forEach(function (scale) { return scale.offUpdate(_this._renderCallback); }); - this.datasets().forEach(function (dataset) { return _this.removeDataset(dataset); }); + this.datasets().forEach(function (dataset) { return _this._removeDataset(dataset, false); }); + this._onDatasetUpdate(); }; Plot.prototype._createNodesForDataset = function (dataset) { var drawer = this._datasetToDrawer.get(dataset); diff --git a/src/plots/plot.ts b/src/plots/plot.ts index a259bc80a0..2c551cd6c8 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -93,7 +93,8 @@ export class Plot extends Component { public destroy() { super.destroy(); this._scales().forEach((scale) => scale.offUpdate(this._renderCallback)); - this.datasets().forEach((dataset) => this.removeDataset(dataset)); + this.datasets().forEach((dataset) => this._removeDataset(dataset, false)); + this._onDatasetUpdate(); } protected _createNodesForDataset(dataset: Dataset) { From 5463a3143b5668f96f473688aa17ebd7d8388414 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 12:49:56 -0700 Subject: [PATCH 101/117] [autorangeSmooth] Amended test names --- test/plots/linePlotTests.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/plots/linePlotTests.ts b/test/plots/linePlotTests.ts index 2322465e71..e8ec8cf311 100644 --- a/test/plots/linePlotTests.ts +++ b/test/plots/linePlotTests.ts @@ -467,7 +467,7 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); - it("smooth autoranging works (called before before autorangeMode)", () => { + it("smooth autoranging works (called before autorangeMode)", () => { xScale.domain([0.1, 1.1]); let data = [ @@ -497,7 +497,7 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); - it("smooth autoranging works (called before before rendering)", () => { + it("smooth autoranging works (called before rendering)", () => { xScale.domain([0.1, 1.1]); let data = [ @@ -527,7 +527,7 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); - it("smooth autoranging works (called before after rendering)", () => { + it("smooth autoranging works (called after rendering)", () => { xScale.domain([0.1, 1.1]); let data = [ @@ -557,7 +557,7 @@ describe("Plots", () => { assert.closeTo(yScale.domain()[1], expectedTop, 0.001, "smooth autoranging forces the domain to include the line (right)"); }); - it("smooth autoranging works (called before after rendering, before autorangeMode)", () => { + it("smooth autoranging works (called after rendering, before autorangeMode)", () => { xScale.domain([0.1, 1.1]); let data = [ From 2bb78706bd248fe2a56a8eb2faa58ebfbc965d5a Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Tue, 18 Aug 2015 14:33:02 -0700 Subject: [PATCH 102/117] minor changes/ doc update --- plottable.d.ts | 1 + plottable.js | 5 +++-- src/plots/rectanglePlot.ts | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 04b3e795a7..297d736a5f 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2917,6 +2917,7 @@ declare module Plottable { labelsEnabled(): boolean; /** * Sets whether labels are enabled. + * Labels too big to be contained in the rectangle, cut off by edges, or blocked by other rectangles will not be shown. * * @param {boolean} labelsEnabled * @returns {Rectangle} The calling Rectangle Plot. diff --git a/plottable.js b/plottable.js index 37962055a5..8c09924524 100644 --- a/plottable.js +++ b/plottable.js @@ -7566,8 +7566,9 @@ var Plottable; }; Rectangle.prototype._overlayLabel = function (labelXRange, labelYRange, datumIndex, datasetIndex, dataToDraw) { var attrToProjector = this._generateAttrToProjector(); - for (var i = datasetIndex; i < this.datasets().length; i++) { - var dataset = this.datasets()[i]; + var datasets = this.datasets(); + for (var i = datasetIndex; i < datasets.length; i++) { + var dataset = datasets[i]; var data = dataToDraw.get(dataset); for (var j = (i === datasetIndex ? datumIndex + 1 : 0); j < data.length; j++) { if (Plottable.Utils.DOM.intersectsBBox(labelXRange, labelYRange, this._entityBBox(data[j], j, dataset, attrToProjector))) { diff --git a/src/plots/rectanglePlot.ts b/src/plots/rectanglePlot.ts index f4e9d2c949..c931170318 100644 --- a/src/plots/rectanglePlot.ts +++ b/src/plots/rectanglePlot.ts @@ -334,6 +334,7 @@ export module Plots { public labelsEnabled(): boolean; /** * Sets whether labels are enabled. + * Labels too big to be contained in the rectangle, cut off by edges, or blocked by other rectangles will not be shown. * * @param {boolean} labelsEnabled * @returns {Rectangle} The calling Rectangle Plot. @@ -468,8 +469,9 @@ export module Plots { private _overlayLabel(labelXRange: Range, labelYRange: Range, datumIndex: number, datasetIndex: number, dataToDraw: Utils.Map) { let attrToProjector = this._generateAttrToProjector(); - for (let i = datasetIndex; i < this.datasets().length; i ++ ) { - let dataset = this.datasets()[i]; + let datasets = this.datasets(); + for (let i = datasetIndex; i < datasets.length; i ++ ) { + let dataset = datasets[i]; let data = dataToDraw.get(dataset); for (let j = (i === datasetIndex ? datumIndex + 1 : 0); j < data.length ; j ++ ) { if (Utils.DOM.intersectsBBox(labelXRange, labelYRange, this._entityBBox(data[j], j, dataset, attrToProjector))) { From 67cacd48a4627853f495b5f8e9a9c7fe2cd3a97a Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 16:29:09 -0700 Subject: [PATCH 103/117] [datasetPerf] CR --- plottable.js | 26 ++++++++++++-------------- src/plots/plot.ts | 26 ++++++++++++-------------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/plottable.js b/plottable.js index 5c7e442120..53dea26a3b 100644 --- a/plottable.js +++ b/plottable.js @@ -6413,7 +6413,7 @@ var Plottable; var _this = this; _super.prototype.destroy.call(this); this._scales().forEach(function (scale) { return scale.offUpdate(_this._renderCallback); }); - this.datasets().forEach(function (dataset) { return _this._removeDataset(dataset, false); }); + this.datasets().forEach(function (dataset) { return _this._removeDataset(dataset); }); this._onDatasetUpdate(); }; Plot.prototype._createNodesForDataset = function (dataset) { @@ -6606,19 +6606,18 @@ var Plottable; * @returns {Plot} The calling Plot. */ Plot.prototype.addDataset = function (dataset) { - return this._addDataset(dataset, true); + this._addDataset(dataset); + this._onDatasetUpdate(); + return this; }; - Plot.prototype._addDataset = function (dataset, dispatchUpdate) { - this._removeDataset(dataset, false); + Plot.prototype._addDataset = function (dataset) { + this._removeDataset(dataset); var drawer = this._createDrawer(dataset); this._datasetToDrawer.set(dataset, drawer); if (this._isSetup) { this._createNodesForDataset(dataset); } dataset.onUpdate(this._onDatasetUpdateCallback); - if (dispatchUpdate) { - this._onDatasetUpdate(); - } return this; }; /** @@ -6628,18 +6627,17 @@ var Plottable; * @returns {Plot} The calling Plot. */ Plot.prototype.removeDataset = function (dataset) { - return this._removeDataset(dataset, true); + this._removeDataset(dataset); + this._onDatasetUpdate(); + return this; }; - Plot.prototype._removeDataset = function (dataset, dispatchUpdate) { + Plot.prototype._removeDataset = function (dataset) { if (this.datasets().indexOf(dataset) === -1) { return this; } this._removeDatasetNodes(dataset); dataset.offUpdate(this._onDatasetUpdateCallback); this._datasetToDrawer.delete(dataset); - if (dispatchUpdate) { - this._onDatasetUpdate(); - } return this; }; Plot.prototype._removeDatasetNodes = function (dataset) { @@ -6653,8 +6651,8 @@ var Plottable; if (datasets == null) { return currentDatasets; } - currentDatasets.forEach(function (dataset) { return _this._removeDataset(dataset, false); }); - datasets.forEach(function (dataset) { return _this._addDataset(dataset, false); }); + currentDatasets.forEach(function (dataset) { return _this._removeDataset(dataset); }); + datasets.forEach(function (dataset) { return _this._addDataset(dataset); }); this._onDatasetUpdate(); return this; }; diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 2c551cd6c8..42bb4bcb4c 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -93,7 +93,7 @@ export class Plot extends Component { public destroy() { super.destroy(); this._scales().forEach((scale) => scale.offUpdate(this._renderCallback)); - this.datasets().forEach((dataset) => this._removeDataset(dataset, false)); + this.datasets().forEach((dataset) => this._removeDataset(dataset)); this._onDatasetUpdate(); } @@ -359,11 +359,13 @@ export class Plot extends Component { * @returns {Plot} The calling Plot. */ public addDataset(dataset: Dataset) { - return this._addDataset(dataset, true); + this._addDataset(dataset); + this._onDatasetUpdate(); + return this; } - private _addDataset(dataset: Dataset, dispatchUpdate: boolean) { - this._removeDataset(dataset, false); + private _addDataset(dataset: Dataset) { + this._removeDataset(dataset); let drawer = this._createDrawer(dataset); this._datasetToDrawer.set(dataset, drawer); @@ -372,9 +374,6 @@ export class Plot extends Component { } dataset.onUpdate(this._onDatasetUpdateCallback); - if (dispatchUpdate) { - this._onDatasetUpdate(); - } return this; } @@ -385,10 +384,12 @@ export class Plot extends Component { * @returns {Plot} The calling Plot. */ public removeDataset(dataset: Dataset): Plot { - return this._removeDataset(dataset, true); + this._removeDataset(dataset); + this._onDatasetUpdate() + return this; } - private _removeDataset(dataset: Dataset, dispatchUpdate: boolean) { + private _removeDataset(dataset: Dataset) { if (this.datasets().indexOf(dataset) === -1) { return this; } @@ -396,9 +397,6 @@ export class Plot extends Component { this._removeDatasetNodes(dataset); dataset.offUpdate(this._onDatasetUpdateCallback); this._datasetToDrawer.delete(dataset); - if (dispatchUpdate) { - this._onDatasetUpdate(); - } return this; } @@ -416,8 +414,8 @@ export class Plot extends Component { return currentDatasets; } - currentDatasets.forEach((dataset) => this._removeDataset(dataset, false)); - datasets.forEach((dataset) => this._addDataset(dataset, false)); + currentDatasets.forEach((dataset) => this._removeDataset(dataset)); + datasets.forEach((dataset) => this._addDataset(dataset)); this._onDatasetUpdate(); return this; } From 77388898fd7376f7b16c4104e9d8975a7be9edc2 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 16:31:06 -0700 Subject: [PATCH 104/117] [datasetPerf] tslint --- src/plots/plot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 42bb4bcb4c..20fb4af191 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -385,7 +385,7 @@ export class Plot extends Component { */ public removeDataset(dataset: Dataset): Plot { this._removeDataset(dataset); - this._onDatasetUpdate() + this._onDatasetUpdate(); return this; } From 938831e4ef155e503948a54e26ee00dac4320ac3 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Tue, 18 Aug 2015 16:35:37 -0700 Subject: [PATCH 105/117] unit test --- test/plots/piePlotTests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index ba606d2cc3..d322992142 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -51,8 +51,8 @@ describe("Plots", () => { let entities = piePlot.entities(); entities.forEach((entity) => { assert.strictEqual(entity.selection.size(), 2, "each entity selection has 2 paths"); - assert.lengthOf(entity.selection.filter("fill"), 1, "each entity selection has 1 fill path"); - assert.lengthOf(entity.selection.filter("outline"), 1, "each entity selection has 1 stroke path"); + assert.strictEqual(entity.selection.filter(".fill").size(), 1, "each entity selection has 1 fill path"); + assert.strictEqual(entity.selection.filter(".outline").size(), 1, "each entity selection has 1 stroke path"); }); svg.remove(); From cd50481c8cfcb4e0eb1166ea4c7d02b946b6982f Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Tue, 18 Aug 2015 16:58:43 -0700 Subject: [PATCH 106/117] [datasetPerf] destroy 1 line shorter --- plottable.js | 3 +-- src/plots/plot.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plottable.js b/plottable.js index 53dea26a3b..3586930a69 100644 --- a/plottable.js +++ b/plottable.js @@ -6413,8 +6413,7 @@ var Plottable; var _this = this; _super.prototype.destroy.call(this); this._scales().forEach(function (scale) { return scale.offUpdate(_this._renderCallback); }); - this.datasets().forEach(function (dataset) { return _this._removeDataset(dataset); }); - this._onDatasetUpdate(); + this.datasets([]); }; Plot.prototype._createNodesForDataset = function (dataset) { var drawer = this._datasetToDrawer.get(dataset); diff --git a/src/plots/plot.ts b/src/plots/plot.ts index 20fb4af191..f3cea6a111 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -93,8 +93,7 @@ export class Plot extends Component { public destroy() { super.destroy(); this._scales().forEach((scale) => scale.offUpdate(this._renderCallback)); - this.datasets().forEach((dataset) => this._removeDataset(dataset)); - this._onDatasetUpdate(); + this.datasets([]); } protected _createNodesForDataset(dataset: Dataset) { From d6a420414993b9f2ad892cc46cf94c8fc96c3a5c Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 12:09:41 -0700 Subject: [PATCH 107/117] [datasetPerf] Fixed Area Plot bug --- plottable.d.ts | 3 ++- plottable.js | 4 ++-- src/plots/areaPlot.ts | 4 ++-- src/plots/plot.ts | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 0a8086a2a2..dc4e6cb530 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2592,6 +2592,7 @@ declare module Plottable { * @returns {Plot} The calling Plot. */ addDataset(dataset: Dataset): Plot; + protected _addDataset(dataset: Dataset): Plot; /** * Removes a Dataset from the Plot. * @@ -3262,7 +3263,7 @@ declare module Plottable { */ y0(y0: number | Accessor): Area; protected _onDatasetUpdate(): void; - addDataset(dataset: Dataset): Area; + protected _addDataset(dataset: Dataset): Area; protected _removeDatasetNodes(dataset: Dataset): void; protected _additionalPaint(): void; protected _createDrawer(dataset: Dataset): Drawers.Area; diff --git a/plottable.js b/plottable.js index 3586930a69..7812d56bfa 100644 --- a/plottable.js +++ b/plottable.js @@ -8549,13 +8549,13 @@ var Plottable; _super.prototype._onDatasetUpdate.call(this); this._updateYScale(); }; - Area.prototype.addDataset = function (dataset) { + Area.prototype._addDataset = function (dataset) { var lineDrawer = new Plottable.Drawers.Line(dataset); if (this._isSetup) { lineDrawer.renderArea(this._renderArea.append("g")); } this._lineDrawers.set(dataset, lineDrawer); - _super.prototype.addDataset.call(this, dataset); + _super.prototype._addDataset.call(this, dataset); return this; }; Area.prototype._removeDatasetNodes = function (dataset) { diff --git a/src/plots/areaPlot.ts b/src/plots/areaPlot.ts index 37a5be8fd4..131e271e0e 100644 --- a/src/plots/areaPlot.ts +++ b/src/plots/areaPlot.ts @@ -80,13 +80,13 @@ export module Plots { this._updateYScale(); } - public addDataset(dataset: Dataset) { + protected _addDataset(dataset: Dataset) { let lineDrawer = new Drawers.Line(dataset); if (this._isSetup) { lineDrawer.renderArea(this._renderArea.append("g")); } this._lineDrawers.set(dataset, lineDrawer); - super.addDataset(dataset); + super._addDataset(dataset); return this; } diff --git a/src/plots/plot.ts b/src/plots/plot.ts index f3cea6a111..a1533e18d9 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -363,7 +363,7 @@ export class Plot extends Component { return this; } - private _addDataset(dataset: Dataset) { + protected _addDataset(dataset: Dataset) { this._removeDataset(dataset); let drawer = this._createDrawer(dataset); this._datasetToDrawer.set(dataset, drawer); From f67168a4b0d365e0b748b404266f3679cff74346 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 12:15:54 -0700 Subject: [PATCH 108/117] [datasetPerf] Fixed the dataset add/remove for all plots --- plottable.d.ts | 7 +++++-- plottable.js | 19 ++++++++++++++----- src/plots/barPlot.ts | 13 ++++++++++++- src/plots/piePlot.ts | 8 ++++---- src/plots/plot.ts | 2 +- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index dc4e6cb530..d51ea67aa3 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2600,6 +2600,7 @@ declare module Plottable { * @returns {Plot} The calling Plot. */ removeDataset(dataset: Dataset): Plot; + protected _removeDataset(dataset: Dataset): Plot; protected _removeDatasetNodes(dataset: Dataset): void; datasets(): Dataset[]; datasets(datasets: Dataset[]): Plot; @@ -2650,8 +2651,8 @@ declare module Plottable { */ constructor(); computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number): Pie; - addDataset(dataset: Dataset): Pie; - removeDataset(dataset: Dataset): Pie; + protected _addDataset(dataset: Dataset): Pie; + protected _removeDataset(dataset: Dataset): Pie; protected _onDatasetUpdate(): void; protected _createDrawer(dataset: Dataset): Drawers.Arc; entities(datasets?: Dataset[]): PlotEntity[]; @@ -3090,7 +3091,9 @@ declare module Plottable { */ baselineValue(value: X | Y): Bar; addDataset(dataset: Dataset): Bar; + protected _addDataset(dataset: Dataset): Bar; removeDataset(dataset: Dataset): Bar; + _removeDataset(dataset: Dataset): Bar; /** * Get whether bar labels are enabled. * diff --git a/plottable.js b/plottable.js index 7812d56bfa..485b76d9b7 100644 --- a/plottable.js +++ b/plottable.js @@ -6848,17 +6848,17 @@ var Plottable; } return this; }; - Pie.prototype.addDataset = function (dataset) { + Pie.prototype._addDataset = function (dataset) { if (this.datasets().length === 1) { Plottable.Utils.Window.warn("Only one dataset is supported in Pie plots"); return this; } this._updatePieAngles(); - _super.prototype.addDataset.call(this, dataset); + _super.prototype._addDataset.call(this, dataset); return this; }; - Pie.prototype.removeDataset = function (dataset) { - _super.prototype.removeDataset.call(this, dataset); + Pie.prototype._removeDataset = function (dataset) { + _super.prototype._removeDataset.call(this, dataset); this._startAngles = []; this._endAngles = []; return this; @@ -7905,17 +7905,26 @@ var Plottable; return this; }; Bar.prototype.addDataset = function (dataset) { - dataset.onUpdate(this._updateBarPixelWidthCallback); _super.prototype.addDataset.call(this, dataset); this._updateBarPixelWidth(); return this; }; + Bar.prototype._addDataset = function (dataset) { + dataset.onUpdate(this._updateBarPixelWidthCallback); + _super.prototype._addDataset.call(this, dataset); + return this; + }; Bar.prototype.removeDataset = function (dataset) { dataset.offUpdate(this._updateBarPixelWidthCallback); _super.prototype.removeDataset.call(this, dataset); this._updateBarPixelWidth(); return this; }; + Bar.prototype._removeDataset = function (dataset) { + dataset.offUpdate(this._updateBarPixelWidthCallback); + _super.prototype._removeDataset.call(this, dataset); + return this; + }; Bar.prototype.labelsEnabled = function (enabled) { if (enabled == null) { return this._labelsEnabled; diff --git a/src/plots/barPlot.ts b/src/plots/barPlot.ts index 2e6712bf58..884444d18c 100644 --- a/src/plots/barPlot.ts +++ b/src/plots/barPlot.ts @@ -154,12 +154,17 @@ export module Plots { } public addDataset(dataset: Dataset) { - dataset.onUpdate(this._updateBarPixelWidthCallback); super.addDataset(dataset); this._updateBarPixelWidth(); return this; } + protected _addDataset(dataset: Dataset) { + dataset.onUpdate(this._updateBarPixelWidthCallback); + super._addDataset(dataset); + return this; + } + public removeDataset(dataset: Dataset) { dataset.offUpdate(this._updateBarPixelWidthCallback); super.removeDataset(dataset); @@ -167,6 +172,12 @@ export module Plots { return this; } + public _removeDataset(dataset: Dataset) { + dataset.offUpdate(this._updateBarPixelWidthCallback); + super._removeDataset(dataset); + return this; + } + /** * Get whether bar labels are enabled. * diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 6522ce259a..07d734f907 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -36,18 +36,18 @@ export module Plots { return this; } - public addDataset(dataset: Dataset) { + protected _addDataset(dataset: Dataset) { if (this.datasets().length === 1) { Utils.Window.warn("Only one dataset is supported in Pie plots"); return this; } this._updatePieAngles(); - super.addDataset(dataset); + super._addDataset(dataset); return this; } - public removeDataset(dataset: Dataset) { - super.removeDataset(dataset); + protected _removeDataset(dataset: Dataset) { + super._removeDataset(dataset); this._startAngles = []; this._endAngles = []; return this; diff --git a/src/plots/plot.ts b/src/plots/plot.ts index a1533e18d9..ecf6fb5163 100644 --- a/src/plots/plot.ts +++ b/src/plots/plot.ts @@ -388,7 +388,7 @@ export class Plot extends Component { return this; } - private _removeDataset(dataset: Dataset) { + protected _removeDataset(dataset: Dataset) { if (this.datasets().indexOf(dataset) === -1) { return this; } From c9c9ad2cda67de67d27ae6e9713f94ffede6071b Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 12:18:44 -0700 Subject: [PATCH 109/117] [datasetPerf] compilation issues on tests and forgotten protected --- plottable.d.ts | 2 +- src/plots/barPlot.ts | 2 +- test/plots/piePlotTests.ts | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index d51ea67aa3..d74aa854fd 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3093,7 +3093,7 @@ declare module Plottable { addDataset(dataset: Dataset): Bar; protected _addDataset(dataset: Dataset): Bar; removeDataset(dataset: Dataset): Bar; - _removeDataset(dataset: Dataset): Bar; + protected _removeDataset(dataset: Dataset): Bar; /** * Get whether bar labels are enabled. * diff --git a/src/plots/barPlot.ts b/src/plots/barPlot.ts index 884444d18c..a31e39ce6d 100644 --- a/src/plots/barPlot.ts +++ b/src/plots/barPlot.ts @@ -172,7 +172,7 @@ export module Plots { return this; } - public _removeDataset(dataset: Dataset) { + protected _removeDataset(dataset: Dataset) { dataset.offUpdate(this._updateBarPixelWidthCallback); super._removeDataset(dataset); return this; diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index 15a8055344..6122aa58ce 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -187,7 +187,8 @@ describe("Plots", () => { { value: 5000 }, { value: 5000 }]; let dataset = new Plottable.Dataset(data); - piePlot.addDataset(dataset).outerRadius(500); + piePlot.addDataset(dataset) + piePlot.outerRadius(500); piePlot.renderTo(svg); let texts = svg.selectAll("text"); From 35a8353acaf440d954bce7bfcd2a31ff7ffc66f6 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 12:22:03 -0700 Subject: [PATCH 110/117] [datasetPerf] tslint --- test/plots/piePlotTests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index 6122aa58ce..7bc772d9f5 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -187,7 +187,7 @@ describe("Plots", () => { { value: 5000 }, { value: 5000 }]; let dataset = new Plottable.Dataset(data); - piePlot.addDataset(dataset) + piePlot.addDataset(dataset); piePlot.outerRadius(500); piePlot.renderTo(svg); From c71e6afd9d12bccc2de575cd873060b4c9cca63d Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Wed, 19 Aug 2015 14:45:35 -0700 Subject: [PATCH 111/117] skip negative values in pie plot --- plottable.js | 10 +++++----- src/plots/piePlot.ts | 10 +++++----- test/plots/piePlotTests.ts | 22 +++++++--------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/plottable.js b/plottable.js index 31e7d32eaf..dbc9d7e454 100644 --- a/plottable.js +++ b/plottable.js @@ -7028,11 +7028,8 @@ var Plottable; } var sectorValueAccessor = Plottable.Plot._scaledAccessor(this.sectorValue()); var dataset = this.datasets()[0]; - var data = dataset.data().filter(function (d, i) { return Plottable.Utils.Math.isValidNumber(sectorValueAccessor(d, i, dataset)); }); + var data = this._getDataToDraw().get(dataset); var pie = d3.layout.pie().sort(null).value(function (d, i) { return sectorValueAccessor(d, i, dataset); })(data); - if (pie.some(function (slice) { return slice.value < 0; })) { - Plottable.Utils.Window.warn("Negative values will not render correctly in a Pie Plot."); - } this._startAngles = pie.map(function (slice) { return slice.startAngle; }); this._endAngles = pie.map(function (slice) { return slice.endAngle; }); }; @@ -7044,7 +7041,10 @@ var Plottable; var sectorValueAccessor = Plottable.Plot._scaledAccessor(this.sectorValue()); var ds = this.datasets()[0]; var data = dataToDraw.get(ds); - var filteredData = data.filter(function (d, i) { return Plottable.Utils.Math.isValidNumber(sectorValueAccessor(d, i, ds)); }); + var filteredData = data.filter(function (d, i) { + var value = sectorValueAccessor(d, i, ds); + return Plottable.Utils.Math.isValidNumber(value) && value >= 0; + }); dataToDraw.set(ds, filteredData); return dataToDraw; }; diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index b9a37de59a..8d0b9346d6 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -266,11 +266,8 @@ export module Plots { if (this.datasets().length === 0) { return; } let sectorValueAccessor = Plot._scaledAccessor(this.sectorValue()); let dataset = this.datasets()[0]; - let data = dataset.data().filter((d, i) => Plottable.Utils.Math.isValidNumber(sectorValueAccessor(d, i, dataset))); + let data = this._getDataToDraw().get(dataset); let pie = d3.layout.pie().sort(null).value((d, i) => sectorValueAccessor(d, i, dataset))(data); - if (pie.some((slice) => slice.value < 0)) { - Utils.Window.warn("Negative values will not render correctly in a Pie Plot."); - } this._startAngles = pie.map((slice) => slice.startAngle); this._endAngles = pie.map((slice) => slice.endAngle); } @@ -281,7 +278,10 @@ export module Plots { let sectorValueAccessor = Plot._scaledAccessor(this.sectorValue()); let ds = this.datasets()[0]; let data = dataToDraw.get(ds); - let filteredData = data.filter((d, i) => Plottable.Utils.Math.isValidNumber(sectorValueAccessor(d, i, ds))); + let filteredData = data.filter((d, i) => { + let value = sectorValueAccessor(d, i, ds); + return Plottable.Utils.Math.isValidNumber(value) && value >= 0; + }); dataToDraw.set(ds, filteredData); return dataToDraw; } diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index d322992142..8c84b6054e 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -497,24 +497,11 @@ describe("Plots", () => { assert.strictEqual(arcPath1.attr("fill"), "#aec7e8", "second sector filled appropriately"); svg.remove(); }); - - }); - - it("throws warnings on negative data", () => { - let message: String; - let oldWarn = Plottable.Utils.Window.warn; - Plottable.Utils.Window.warn = (warn) => message = warn; - piePlot.removeDataset(simpleDataset); - let negativeDataset = new Plottable.Dataset([{value: -5}, {value: 15}]); - piePlot.addDataset(negativeDataset); - assert.strictEqual(message, "Negative values will not render correctly in a Pie Plot."); - Plottable.Utils.Window.warn = oldWarn; - svg.remove(); }); }); describe("fail safe tests", () => { - it("undefined, NaN and non-numeric strings not be represented in a Pie Chart", () => { + it("undefined, NaN, non-numeric strings, and negative number not be represented in a Pie Chart", () => { let svg = TestMethods.generateSVG(); let data1 = [ @@ -525,6 +512,7 @@ describe("Plots", () => { { v: 1 }, { v: "Bad String" }, { v: 1 }, + { v: -100 }, ]; let plot = new Plottable.Plots.Pie(); @@ -537,9 +525,13 @@ describe("Plots", () => { assert.strictEqual(elementsDrawnSel.size(), 4, "There should be exactly 4 slices in the pie chart, representing the valid values"); + for (let i = 0 ; i < 4 ; i ++ ) { + let startAngle = ( plot)._startAngles[i]; + let endAngle = ( plot)._endAngles[i]; + assert.closeTo(endAngle - startAngle, Math.PI / 2, 0.001, "each slice is a quarter of the pie"); + } svg.remove(); - }); }); }); From 13ff4f1ce2226891d59c92ebd5e787a513f36c02 Mon Sep 17 00:00:00 2001 From: Zoe Tsai Date: Wed, 19 Aug 2015 19:31:00 -0700 Subject: [PATCH 112/117] fix a bug where entities() include invalid data --- plottable.d.ts | 1 + plottable.js | 18 ++++++++++++------ src/plots/piePlot.ts | 20 ++++++++++++++------ test/plots/piePlotTests.ts | 2 ++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index 6df1741e5b..93a43b3c2d 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2763,6 +2763,7 @@ declare module Plottable { entitiesAt(queryPoint: Point): PlotEntity[]; protected _propertyProjectors(): AttributeToProjector; protected _getDataToDraw(): Utils.Map; + protected static _isValidData(value: any): boolean; protected _pixelPoint(datum: any, index: number, dataset: Dataset): { x: number; y: number; diff --git a/plottable.js b/plottable.js index dbc9d7e454..0e0f6e721f 100644 --- a/plottable.js +++ b/plottable.js @@ -7041,21 +7041,27 @@ var Plottable; var sectorValueAccessor = Plottable.Plot._scaledAccessor(this.sectorValue()); var ds = this.datasets()[0]; var data = dataToDraw.get(ds); - var filteredData = data.filter(function (d, i) { - var value = sectorValueAccessor(d, i, ds); - return Plottable.Utils.Math.isValidNumber(value) && value >= 0; - }); + var filteredData = data.filter(function (d, i) { return Pie._isValidData(sectorValueAccessor(d, i, ds)); }); dataToDraw.set(ds, filteredData); return dataToDraw; }; + Pie._isValidData = function (value) { + return Plottable.Utils.Math.isValidNumber(value) && value >= 0; + }; Pie.prototype._pixelPoint = function (datum, index, dataset) { + var scaledValueAccessor = Plottable.Plot._scaledAccessor(this.sectorValue()); + if (!Pie._isValidData(scaledValueAccessor(datum, index, dataset))) { + return { x: NaN, y: NaN }; + } var innerRadius = Plottable.Plot._scaledAccessor(this.innerRadius())(datum, index, dataset); var outerRadius = Plottable.Plot._scaledAccessor(this.outerRadius())(datum, index, dataset); var avgRadius = (innerRadius + outerRadius) / 2; - var scaledValueAccessor = Plottable.Plot._scaledAccessor(this.sectorValue()); var pie = d3.layout.pie() .sort(null) - .value(function (d, i) { return scaledValueAccessor(d, i, dataset); })(dataset.data()); + .value(function (d, i) { + var value = scaledValueAccessor(d, i, dataset); + return Pie._isValidData(value) ? value : 0; + })(dataset.data()); var startAngle = pie[index].startAngle; var endAngle = pie[index].endAngle; var avgAngle = (startAngle + endAngle) / 2; diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 8d0b9346d6..c02c64f0de 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -278,23 +278,31 @@ export module Plots { let sectorValueAccessor = Plot._scaledAccessor(this.sectorValue()); let ds = this.datasets()[0]; let data = dataToDraw.get(ds); - let filteredData = data.filter((d, i) => { - let value = sectorValueAccessor(d, i, ds); - return Plottable.Utils.Math.isValidNumber(value) && value >= 0; - }); + let filteredData = data.filter((d, i) => Pie._isValidData(sectorValueAccessor(d, i, ds))); dataToDraw.set(ds, filteredData); return dataToDraw; } + protected static _isValidData(value: any) { + return Plottable.Utils.Math.isValidNumber(value) && value >= 0; + } + protected _pixelPoint(datum: any, index: number, dataset: Dataset) { + let scaledValueAccessor = Plot._scaledAccessor(this.sectorValue()); + if (!Pie._isValidData(scaledValueAccessor(datum, index, dataset))) { + return { x: NaN, y: NaN}; + } + let innerRadius = Plot._scaledAccessor(this.innerRadius())(datum, index, dataset); let outerRadius = Plot._scaledAccessor(this.outerRadius())(datum, index, dataset); let avgRadius = (innerRadius + outerRadius) / 2; - let scaledValueAccessor = Plot._scaledAccessor(this.sectorValue()); let pie = d3.layout.pie() .sort(null) - .value((d: any, i: number) => scaledValueAccessor(d, i, dataset))(dataset.data()); + .value((d: any, i: number) => { + let value = scaledValueAccessor(d, i, dataset); + return Pie._isValidData(value) ? value : 0; + })(dataset.data()); let startAngle = pie[index].startAngle; let endAngle = pie[index].endAngle; let avgAngle = (startAngle + endAngle) / 2; diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index 8c84b6054e..7fc5ba5fad 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -525,6 +525,8 @@ describe("Plots", () => { assert.strictEqual(elementsDrawnSel.size(), 4, "There should be exactly 4 slices in the pie chart, representing the valid values"); + assert.lengthOf(plot.entities(), 4, "there should be exactly 4 entities, representing the valid values"); + for (let i = 0 ; i < 4 ; i ++ ) { let startAngle = ( plot)._startAngles[i]; let endAngle = ( plot)._endAngles[i]; From f408a92e90bbb4d8ff3fce6364471dfd812cf026 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 14:35:41 -0700 Subject: [PATCH 113/117] [datasetPerf] fixed bug of not updating the width of the bar in bar plot --- plottable.d.ts | 2 ++ plottable.js | 8 ++++++++ src/plots/barPlot.ts | 12 ++++++++++++ 3 files changed, 22 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index ac29a55edf..ca15504fde 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3144,6 +3144,8 @@ declare module Plottable { protected _addDataset(dataset: Dataset): Bar; removeDataset(dataset: Dataset): Bar; protected _removeDataset(dataset: Dataset): Bar; + datasets(): Dataset[]; + datasets(datasets: Dataset[]): Plot; /** * Get whether bar labels are enabled. * diff --git a/plottable.js b/plottable.js index d7b5b7d51b..404185ca4d 100644 --- a/plottable.js +++ b/plottable.js @@ -8098,6 +8098,14 @@ var Plottable; _super.prototype._removeDataset.call(this, dataset); return this; }; + Bar.prototype.datasets = function (datasets) { + if (datasets == null) { + return _super.prototype.datasets.call(this); + } + _super.prototype.datasets.call(this, datasets); + this._updateBarPixelWidth(); + return this; + }; Bar.prototype.labelsEnabled = function (enabled) { if (enabled == null) { return this._labelsEnabled; diff --git a/src/plots/barPlot.ts b/src/plots/barPlot.ts index a31e39ce6d..d5745c9e5a 100644 --- a/src/plots/barPlot.ts +++ b/src/plots/barPlot.ts @@ -178,6 +178,18 @@ export module Plots { return this; } + public datasets(): Dataset[]; + public datasets(datasets: Dataset[]): Plot; + public datasets(datasets?: Dataset[]): any { + if (datasets == null) { + return super.datasets(); + } + + super.datasets(datasets); + this._updateBarPixelWidth(); + return this; + } + /** * Get whether bar labels are enabled. * From c5b7c0be8bb7f1bf42e8ec5cfff6ae9f5af071af Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 14:42:51 -0700 Subject: [PATCH 114/117] [datasetPerf] added extra test --- test/plots/plotTests.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/plots/plotTests.ts b/test/plots/plotTests.ts index b345eccabd..bf5c6ba063 100644 --- a/test/plots/plotTests.ts +++ b/test/plots/plotTests.ts @@ -82,6 +82,9 @@ describe("Plots", () => { plot.removeDataset(dataset1); assert.deepEqual(plot.datasets(), [dataset2, dataset3], "removing a Dataset leaves the remainder in the same order"); + + plot.datasets([]); + assert.deepEqual(plot.datasets(), [], "the datasets() call first removes all the datasets"); }); it("Updates its projectors when the Dataset is changed", () => { From 89a92cb5711ffa01522a9cb0d5061da821725850 Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 16:46:59 -0700 Subject: [PATCH 115/117] [datasetPerf] no more API breaking changes for Typescript users --- plottable.d.ts | 13 +++---------- plottable.js | 40 ++++++++++++-------------------------- src/plots/areaPlot.ts | 5 +++++ src/plots/piePlot.ts | 10 ++++++++++ test/plots/piePlotTests.ts | 3 +-- 5 files changed, 31 insertions(+), 40 deletions(-) diff --git a/plottable.d.ts b/plottable.d.ts index ca15504fde..ce038af2bb 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -1338,16 +1338,6 @@ declare module Plottable { } -declare module Plottable { - module Drawers { - class ArcOutline extends Drawer { - constructor(dataset: Dataset); - protected _applyDefaultAttributes(selection: d3.Selection): void; - } - } -} - - declare module Plottable { module Drawers { class Symbol extends Drawer { @@ -2671,7 +2661,9 @@ declare module Plottable { constructor(); protected _setup(): void; computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number): Pie; + addDataset(dataset: Dataset): Pie; protected _addDataset(dataset: Dataset): Pie; + removeDataset(dataset: Dataset): Pie; protected _removeDatasetNodes(dataset: Dataset): void; protected _removeDataset(dataset: Dataset): Pie; selections(datasets?: Dataset[]): d3.Selection; @@ -3338,6 +3330,7 @@ declare module Plottable { */ y0(y0: number | Accessor): Area; protected _onDatasetUpdate(): void; + addDataset(dataset: Dataset): Area; protected _addDataset(dataset: Dataset): Area; protected _removeDatasetNodes(dataset: Dataset): void; protected _additionalPaint(): void; diff --git a/plottable.js b/plottable.js index 404185ca4d..0cb0a224ea 100644 --- a/plottable.js +++ b/plottable.js @@ -2881,34 +2881,6 @@ var Plottable; })(Drawers = Plottable.Drawers || (Plottable.Drawers = {})); })(Plottable || (Plottable = {})); -/// -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - __.prototype = b.prototype; - d.prototype = new __(); -}; -var Plottable; -(function (Plottable) { - var Drawers; - (function (Drawers) { - var ArcOutline = (function (_super) { - __extends(ArcOutline, _super); - function ArcOutline(dataset) { - _super.call(this, dataset); - this._className = "arc outline"; - this._svgElementName = "path"; - } - ArcOutline.prototype._applyDefaultAttributes = function (selection) { - _super.prototype._applyDefaultAttributes.call(this, selection); - selection.style("fill", "none"); - }; - return ArcOutline; - })(Plottable.Drawer); - Drawers.ArcOutline = ArcOutline; - })(Drawers = Plottable.Drawers || (Plottable.Drawers = {})); -})(Plottable || (Plottable = {})); - /// var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -6898,6 +6870,10 @@ var Plottable; } return this; }; + Pie.prototype.addDataset = function (dataset) { + _super.prototype.addDataset.call(this, dataset); + return this; + }; Pie.prototype._addDataset = function (dataset) { if (this.datasets().length === 1) { Plottable.Utils.Window.warn("Only one dataset is supported in Pie plots"); @@ -6912,6 +6888,10 @@ var Plottable; _super.prototype._addDataset.call(this, dataset); return this; }; + Pie.prototype.removeDataset = function (dataset) { + _super.prototype.removeDataset.call(this, dataset); + return this; + }; Pie.prototype._removeDatasetNodes = function (dataset) { _super.prototype._removeDatasetNodes.call(this, dataset); this._strokeDrawers.get(dataset).remove(); @@ -8890,6 +8870,10 @@ var Plottable; _super.prototype._onDatasetUpdate.call(this); this._updateYScale(); }; + Area.prototype.addDataset = function (dataset) { + _super.prototype.addDataset.call(this, dataset); + return this; + }; Area.prototype._addDataset = function (dataset) { var lineDrawer = new Plottable.Drawers.Line(dataset); if (this._isSetup) { diff --git a/src/plots/areaPlot.ts b/src/plots/areaPlot.ts index 131e271e0e..b4e1b51be1 100644 --- a/src/plots/areaPlot.ts +++ b/src/plots/areaPlot.ts @@ -80,6 +80,11 @@ export module Plots { this._updateYScale(); } + public addDataset(dataset: Dataset) { + super.addDataset(dataset); + return this; + } + protected _addDataset(dataset: Dataset) { let lineDrawer = new Drawers.Line(dataset); if (this._isSetup) { diff --git a/src/plots/piePlot.ts b/src/plots/piePlot.ts index 33fcd00021..5df5224feb 100644 --- a/src/plots/piePlot.ts +++ b/src/plots/piePlot.ts @@ -44,6 +44,11 @@ export module Plots { return this; } + public addDataset(dataset: Dataset) { + super.addDataset(dataset); + return this; + } + protected _addDataset(dataset: Dataset) { if (this.datasets().length === 1) { Utils.Window.warn("Only one dataset is supported in Pie plots"); @@ -59,6 +64,11 @@ export module Plots { return this; } + public removeDataset(dataset: Dataset) { + super.removeDataset(dataset); + return this; + } + protected _removeDatasetNodes(dataset: Dataset) { super._removeDatasetNodes(dataset); this._strokeDrawers.get(dataset).remove(); diff --git a/test/plots/piePlotTests.ts b/test/plots/piePlotTests.ts index a1faf714cf..d322992142 100644 --- a/test/plots/piePlotTests.ts +++ b/test/plots/piePlotTests.ts @@ -232,8 +232,7 @@ describe("Plots", () => { { value: 5000 }, { value: 5000 }]; let dataset = new Plottable.Dataset(data); - piePlot.addDataset(dataset); - piePlot.outerRadius(500); + piePlot.addDataset(dataset).outerRadius(500); piePlot.renderTo(svg); let texts = svg.selectAll("text"); From 8f438eda0e0c8e3b69b8db24b242c96b81eda06d Mon Sep 17 00:00:00 2001 From: Andrei Cioara Date: Thu, 20 Aug 2015 16:48:15 -0700 Subject: [PATCH 116/117] [datasetPerf] added compiled files --- plottable.d.ts | 10 ++++++++++ plottable.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/plottable.d.ts b/plottable.d.ts index c202097e22..42dfd14d3d 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -1338,6 +1338,16 @@ declare module Plottable { } +declare module Plottable { + module Drawers { + class ArcOutline extends Drawer { + constructor(dataset: Dataset); + protected _applyDefaultAttributes(selection: d3.Selection): void; + } + } +} + + declare module Plottable { module Drawers { class Symbol extends Drawer { diff --git a/plottable.js b/plottable.js index f3e83b94a4..0a4204f220 100644 --- a/plottable.js +++ b/plottable.js @@ -2881,6 +2881,34 @@ var Plottable; })(Drawers = Plottable.Drawers || (Plottable.Drawers = {})); })(Plottable || (Plottable = {})); +/// +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var Plottable; +(function (Plottable) { + var Drawers; + (function (Drawers) { + var ArcOutline = (function (_super) { + __extends(ArcOutline, _super); + function ArcOutline(dataset) { + _super.call(this, dataset); + this._className = "arc outline"; + this._svgElementName = "path"; + } + ArcOutline.prototype._applyDefaultAttributes = function (selection) { + _super.prototype._applyDefaultAttributes.call(this, selection); + selection.style("fill", "none"); + }; + return ArcOutline; + })(Plottable.Drawer); + Drawers.ArcOutline = ArcOutline; + })(Drawers = Plottable.Drawers || (Plottable.Drawers = {})); +})(Plottable || (Plottable = {})); + /// var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; From 829dfec185b51e14d994c8b1e6abd2add1b8c42f Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Fri, 21 Aug 2015 11:33:50 -0700 Subject: [PATCH 117/117] Release version 1.8.0 --- bower.json | 2 +- package.json | 2 +- plottable.js | 4 ++-- plottable.min.js | 15 ++++++++------- plottable.zip | Bin 208473 -> 213851 bytes 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bower.json b/bower.json index b8f11913f3..26d4dd2ef2 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "plottable", "description": "A modular charting library built on D3", - "version": "1.7.0", + "version": "1.8.0", "main": ["plottable.js", "plottable.css"], "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 0a120032ca..739ce501f7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "plottable.js", "description": "A modular charting library built on D3", - "version": "1.7.0", + "version": "1.8.0", "license": "MIT", "repository": { "type": "git", diff --git a/plottable.js b/plottable.js index 0a4204f220..b014ad712d 100644 --- a/plottable.js +++ b/plottable.js @@ -1,5 +1,5 @@ /*! -Plottable 1.7.0 (https://github.com/palantir/plottable) +Plottable 1.8.0 (https://github.com/palantir/plottable) Copyright 2014-2015 Palantir Technologies Licensed under MIT (https://github.com/palantir/plottable/blob/master/LICENSE) */ @@ -901,7 +901,7 @@ var Plottable; /// var Plottable; (function (Plottable) { - Plottable.version = "1.7.0"; + Plottable.version = "1.8.0"; })(Plottable || (Plottable = {})); /// diff --git a/plottable.min.js b/plottable.min.js index aebd3cc029..0bb8781a9f 100644 --- a/plottable.min.js +++ b/plottable.min.js @@ -1,7 +1,8 @@ -!function(a,b){if("object"==typeof exports)module.exports=b(require,exports,module);else if("function"==typeof define&&define.amd)define(["require","exports","module"],b);else{var c=function(b){return a[b]},d=a,e={exports:d};a.Plottable=b(c,d,e)}}(this,function(){var a;!function(a){var b;!function(b){var c;!function(b){function c(a,b,c){return k.min(b,c)<=a&&a<=k.max(b,c)}function d(a,b,c){return k.min(k.max(b,a),c)}function e(a,b,c){var d="function"==typeof b?b:null,e=null==d?b:c,f=null==d?d3.max(a):d3.max(a,d);return void 0!==f?f:e}function f(a,b,c){var d="function"==typeof b?b:null,e=null==d?b:c,f=null==d?d3.min(a):d3.min(a,d);return void 0!==f?f:e}function g(a){return a!==a}function h(b){return"number"==typeof b&&!a.Utils.Math.isNaN(b)&&isFinite(b)}function i(a,b,c){if(void 0===c&&(c=1),0===c)throw new Error("step cannot be 0");for(var d=k.max(k.ceil((b-a)/c),0),e=[],f=0;d>f;++f)e[f]=a+c*f;return e}function j(a,b){return k.pow(b.y-a.y,2)+k.pow(b.x-a.x,2)}var k=window.Math;b.inRange=c,b.clamp=d,b.max=e,b.min=f,b.isNaN=g,b.isValidNumber=h,b.range=i,b.distanceSquared=j}(c=b.Math||(b.Math={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function b(){"function"==typeof window.Map?this._es6Map=new window.Map:this._keyValuePairs=[]}return b.prototype.set=function(b,c){if(a.Math.isNaN(b))throw new Error("NaN may not be used as a key to the Map");if(null!=this._es6Map)return this._es6Map.set(b,c),this;for(var d=0;db.right?!1:a.bottomb.bottom?!1:!0}function h(a,b){return n.floor(b.left)<=n.ceil(a.left)&&n.floor(b.top)<=n.ceil(a.top)&&n.floor(a.right)<=n.ceil(b.right)&&n.floor(a.bottom)<=n.ceil(b.bottom)}function i(a){var b=a.ownerSVGElement;return null!=b?b:"svg"===a.nodeName.toLowerCase()?a:null}function j(){return"plottableClipPath"+ ++o}function k(a,b,c,d){void 0===d&&(d=.5);var e=l(a),f=l(b);return c.x+c.width>=e.min-d&&c.x<=e.max+d&&c.y+c.height>=f.min-d&&c.y<=f.max+d}function l(a){if("number"==typeof a){var b=a;return{min:b,max:b}}var c=a;if(c instanceof Object&&"min"in c&&"max"in c)return c;throw new Error("input '"+a+"' can't be parsed as an Range")}function m(a,b){var c=a.getPropertyValue(b),d=parseFloat(c);return d||0}var n=window.Math;a.elementBBox=b,a.SCREEN_REFRESH_RATE_MILLISECONDS=1e3/60,a.requestAnimationFramePolyfill=c,a.elementWidth=d,a.elementHeight=e,a.translate=f,a.clientRectsOverlap=g,a.clientRectInside=h,a.boundingSVG=i;var o=0;a.generateUniqueClipPathId=j,a.intersectsBBox=k}(b=a.DOM||(a.DOM={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b;!function(a){function b(a,b){var c=e(a)+.05,d=e(b)+.05;return c>d?c/d:d/c}function c(a,b){var c=d3.hsl(a).brighter(b);return c.rgb().toString()}function d(a,b){a.classed(b,!0);var c=a.style("background-color");if("transparent"===c)return null;var d=/\((.+)\)/.exec(c)[1].split(",").map(function(a){var b=+a,c=b.toString(16);return 16>b?"0"+c:c});if(4===d.length&&"00"===d[3])return null;var e="#"+d.join("");return a.classed(b,!1),e}function e(a){var b=d3.rgb(a),c=function(a){return a/=255,.03928>=a?a/12.92:f.pow((a+.055)/1.055,2.4)},d=c(b.r),e=c(b.g),g=c(b.b);return.2126*d+.7152*e+.0722*g}var f=window.Math;a.contrast=b,a.lightenColor=c,a.colorTest=d}(b=a.Color||(a.Color={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b;!function(a){function b(a,b){if(a.length!==b.length)throw new Error("attempted to add arrays of unequal length");return a.map(function(c,d){return a[d]+b[d]})}function c(a){var b=d3.set(),c=[];return a.forEach(function(a){b.has(String(a))||(b.add(String(a)),c.push(a))}),c}function d(a){return f.prototype.concat.apply([],a)}function e(a,b){for(var c=[],d=0;b>d;d++)c[d]="function"==typeof a?a(d):a;return c}var f=window.Array;a.add=b,a.uniq=c,a.flatten=d,a.createFilledArray=e}(b=a.Array||(a.Array={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.apply(this,arguments)}return b(c,a),c.prototype.callCallbacks=function(){for(var a=this,b=[],c=0;c=0?f:g;m.has(k)?(j=m.get(k),m.set(k,j+l)):(j=0,m.set(k,l)),i.set(k,{value:l,offset:j})}),h.set(b,i)}),h}function d(b,c,d){var g=[];b.forEach(function(a,b){b.data().forEach(function(f,h){if(null==d||d(f,h,b)){var i=a.get(e(c(f,h,b)));g.push(i.value+i.offset)}})});var h=a.Math.max(g,0),i=a.Math.min(g,0);return[f.min(i,0),f.max(0,h)]}function e(a){return String(a)}var f=window.Math;b.stack=c,b.stackedExtent=d,b.normalizeKey=e}(b=a.Stacking||(a.Stacking={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(b){var c;!function(c){function d(b){a.Configs.SHOW_WARNINGS&&null!=window.console&&(null!=window.console.warn?console.warn(b):null!=window.console.log&&console.log(b))}function e(a,b){for(var c=[],d=2;da&&(b="-"+b)),b}}function d(a){return void 0===a&&(a=3),m(a),function(b){return b.toFixed(a)}}function e(a){return void 0===a&&(a=3),m(a),function(b){if("number"==typeof b){var c=Math.pow(10,a);return String(Math.round(b*c)/c)}return String(b)}}function f(){return function(a){return String(a)}}function g(a){void 0===a&&(a=0);var c=b.fixed(a);return function(a){var b=100*a,d=a.toString(),e=Math.pow(10,d.length-(d.indexOf(".")+1));return b=parseInt((b*e).toString(),10)/e,c(b)+"%"}}function h(a){return void 0===a&&(a=3),m(a),function(b){return d3.format("."+a+"s")(b)}}function i(a){void 0===a&&(a=3),m(a);var b="KMBTQ",c=d3.format("."+a+"e"),d=d3.format("."+a+"f"),e=Math.pow(10,3*(b.length+1)),f=Math.pow(10,-a);return function(a){var g=Math.abs(a);if((f>g||g>=e)&&0!==g)return c(a);for(var h=-1;g>=Math.pow(1e3,h+2)&&h0&&"1000"===i.substr(0,4)||0>a&&"-1000"===i.substr(0,5))&&(hd;d++)if(b[d].filter(c))return d3.time.format(b[d].format)(c)}}function k(a){return d3.time.format(a)}function l(b,c,d){return void 0===b&&(b=0),void 0===c&&(c=a.MILLISECONDS_IN_ONE_DAY),void 0===d&&(d=""),a.Utils.Window.deprecated("relativeDate()","1.3","Not safe for use with time zones."),function(a){var e=Math.round((a.valueOf()-b)/c);return e.toString()+d}}function m(a){if(0>a||a>20)throw new RangeError("Formatter precision must be between 0 and 20");if(a!==Math.floor(a))throw new RangeError("Formatter precision must be an integer")}b.currency=c,b.fixed=d,b.general=e,b.identity=f,b.percentage=g,b.siSuffix=h,b.shortScale=i,b.multiTime=j,b.time=k,b.relativeDate=l}(b=a.Formatters||(a.Formatters={}))}(a||(a={}));var a;!function(a){var b;!function(a){function b(){return function(a){return d3.svg.symbol().type("circle").size(Math.PI*Math.pow(a/2,2))(null)}}function c(){return function(a){return d3.svg.symbol().type("square").size(Math.pow(a,2))(null)}}function d(){return function(a){return d3.svg.symbol().type("cross").size(5/9*Math.pow(a,2))(null)}}function e(){return function(a){return d3.svg.symbol().type("diamond").size(Math.tan(Math.PI/6)*Math.pow(a,2)/2)(null)}}function f(){return function(a){return d3.svg.symbol().type("triangle-up").size(Math.sqrt(3)*Math.pow(a/2,2))(null)}}function g(){return function(a){return d3.svg.symbol().type("triangle-down").size(Math.sqrt(3)*Math.pow(a/2,2))(null)}}a.circle=b,a.square=c,a.cross=d,a.diamond=e,a.triangleUp=f,a.triangleDown=g}(b=a.SymbolFactories||(a.SymbolFactories={}))}(a||(a={}));var a;!function(a){var b=function(){function b(){this._autoDomainAutomatically=!0,this._domainModificationInProgress=!1,this._callbacks=new a.Utils.CallbackSet,this._includedValuesProviders=new a.Utils.Set}return b.prototype.extentOfValues=function(){return[]},b.prototype._getAllIncludedValues=function(){var a=this,b=[];return this._includedValuesProviders.forEach(function(c){var d=c(a);b=b.concat(d)}),b},b.prototype._getExtent=function(){return[]},b.prototype.onUpdate=function(a){return this._callbacks.add(a),this},b.prototype.offUpdate=function(a){return this._callbacks["delete"](a),this},b.prototype._dispatchUpdate=function(){this._callbacks.callCallbacks(this)},b.prototype.autoDomain=function(){return this._autoDomainAutomatically=!0,this._setDomain(this._getExtent()),this},b.prototype._autoDomainIfAutomaticMode=function(){this._autoDomainAutomatically&&this.autoDomain()},b.prototype.scale=function(){throw new Error("Subclasses should override scale")},b.prototype.domain=function(a){return null==a?this._getDomain():(this._autoDomainAutomatically=!1,this._setDomain(a),this)},b.prototype._getDomain=function(){throw new Error("Subclasses should override _getDomain")},b.prototype._setDomain=function(a){this._domainModificationInProgress||(this._domainModificationInProgress=!0,this._setBackingScaleDomain(a),this._dispatchUpdate(),this._domainModificationInProgress=!1)},b.prototype._setBackingScaleDomain=function(){throw new Error("Subclasses should override _setBackingDomain")},b.prototype.range=function(a){return null==a?this._getRange():(this._setRange(a),this)},b.prototype._getRange=function(){throw new Error("Subclasses should override _getRange")},b.prototype._setRange=function(){throw new Error("Subclasses should override _setRange")},b.prototype.addIncludedValuesProvider=function(a){return this._includedValuesProviders.add(a),this._autoDomainIfAutomaticMode(),this},b.prototype.removeIncludedValuesProvider=function(a){return this._includedValuesProviders["delete"](a),this._autoDomainIfAutomaticMode(),this},b}();a.Scale=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c=function(c){function d(){c.call(this),this._tickGenerator=function(a){return a.defaultTicks()},this._padProportion=.05,this._paddingExceptionsProviders=new a.Utils.Set}return b(d,c),d.prototype.autoDomain=function(){return this._domainMin=null,this._domainMax=null,c.prototype.autoDomain.call(this),this},d.prototype._autoDomainIfAutomaticMode=function(){if(null!=this._domainMin&&null!=this._domainMax)return void this._setDomain([this._domainMin,this._domainMax]);var a=this._getExtent();if(null!=this._domainMin){var b=a[1];return this._domainMin>=b&&(b=this._expandSingleValueDomain([this._domainMin,this._domainMin])[1]),void this._setDomain([this._domainMin,b])}if(null!=this._domainMax){var d=a[0];return this._domainMax<=d&&(d=this._expandSingleValueDomain([this._domainMax,this._domainMax])[0]),void this._setDomain([d,this._domainMax])}c.prototype._autoDomainIfAutomaticMode.call(this)},d.prototype._getExtent=function(){var b=this._getAllIncludedValues(),c=this._defaultExtent();if(0!==b.length){var d=[a.Utils.Math.min(b,c[0]),a.Utils.Math.max(b,c[1])];c=this._padDomain(d)}return null!=this._domainMin&&(c[0]=this._domainMin),null!=this._domainMax&&(c[1]=this._domainMax),c},d.prototype.addPaddingExceptionsProvider=function(a){return this._paddingExceptionsProviders.add(a),this._autoDomainIfAutomaticMode(),this},d.prototype.removePaddingExceptionsProvider=function(a){return this._paddingExceptionsProviders["delete"](a),this._autoDomainIfAutomaticMode(),this},d.prototype.padProportion=function(a){if(null==a)return this._padProportion;if(0>a)throw new Error("padProportion must be non-negative");return this._padProportion=a,this._autoDomainIfAutomaticMode(),this},d.prototype._padDomain=function(a){var b=this;if(a[0].valueOf()===a[1].valueOf())return this._expandSingleValueDomain(a);if(0===this._padProportion)return a;var c=this._padProportion/2,d=a[0],e=a[1],f=!1,g=!1;this._paddingExceptionsProviders.forEach(function(a){var c=a(b);c.forEach(function(a){a.valueOf()===d.valueOf()&&(f=!0),a.valueOf()===e.valueOf()&&(g=!0)})});var h=f?d:this.invert(this.scale(d)-(this.scale(e)-this.scale(d))*c),i=g?e:this.invert(this.scale(e)+(this.scale(e)-this.scale(d))*c);return this._niceDomain([h,i])},d.prototype._expandSingleValueDomain=function(a){return a},d.prototype.invert=function(){throw new Error("Subclasses should override invert")},d.prototype.domain=function(a){return null!=a&&(this._domainMin=a[0],this._domainMax=a[1]),c.prototype.domain.call(this,a)},d.prototype.domainMin=function(a){return null==a?this.domain()[0]:(this._domainMin=a,this._autoDomainIfAutomaticMode(),this)},d.prototype.domainMax=function(a){return null==a?this.domain()[1]:(this._domainMax=a,this._autoDomainIfAutomaticMode(),this)},d.prototype.extentOfValues=function(b){var c=d3.extent(b.filter(function(b){return a.Utils.Math.isValidNumber(+b)}));return null==c[0]||null==c[1]?[]:c},d.prototype._setDomain=function(b){var d=function(b){return a.Utils.Math.isNaN(b)||1/0===b||b===-1/0};return d(b[0])||d(b[1])?void a.Utils.Window.warn("Warning: QuantitativeScales cannot take NaN or Infinity as a domain value. Ignoring."):void c.prototype._setDomain.call(this,b)},d.prototype.defaultTicks=function(){throw new Error("Subclasses should override _getDefaultTicks")},d.prototype.ticks=function(){return this._tickGenerator(this)},d.prototype._niceDomain=function(){throw new Error("Subclasses should override _niceDomain")},d.prototype._defaultExtent=function(){throw new Error("Subclasses should override _defaultExtent")},d.prototype.tickGenerator=function(a){return null==a?this._tickGenerator:(this._tickGenerator=a,this)},d._DEFAULT_NUM_TICKS=10,d}(a.Scale);a.QuantitativeScale=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function d(){a.call(this),this._d3Scale=d3.scale.linear()}return b(d,a),d.prototype._defaultExtent=function(){return[0,1]},d.prototype._expandSingleValueDomain=function(a){return a[0]===a[1]?[a[0]-1,a[1]+1]:a},d.prototype.scale=function(a){return this._d3Scale(a)},d.prototype._getDomain=function(){return this._d3Scale.domain()},d.prototype._setBackingScaleDomain=function(a){this._d3Scale.domain(a)},d.prototype._getRange=function(){return this._d3Scale.range()},d.prototype._setRange=function(a){this._d3Scale.range(a)},d.prototype.invert=function(a){return this._d3Scale.invert(a)},d.prototype.defaultTicks=function(){return this._d3Scale.ticks(c.Linear._DEFAULT_NUM_TICKS)},d.prototype._niceDomain=function(a,b){return this._d3Scale.copy().domain(a).nice(b).domain()},d}(a.QuantitativeScale);c.Linear=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(a){if(void 0===a&&(a=10),d.call(this),this._d3Scale=d3.scale.linear(),this._base=a,this._pivot=this._base,this._setDomain(this._defaultExtent()),1>=a)throw new Error("ModifiedLogScale: The base must be > 1")}return b(e,d),e.prototype._adjustedLog=function(a){var b=0>a?-1:1;return a*=b,aa?-1:1;return a*=b,a=Math.pow(this._base,a),a=b&&c>=a}),n=m.sort(function(a,b){return a-b});return n},e.prototype._howManyTicks=function(b,d){var e=this._adjustedLog(a.Utils.Math.min(this._untransformedDomain,0)),f=this._adjustedLog(a.Utils.Math.max(this._untransformedDomain,0)),g=this._adjustedLog(b),h=this._adjustedLog(d),i=(h-g)/(f-e),j=Math.ceil(i*c.ModifiedLog._DEFAULT_NUM_TICKS);return j},e.prototype._niceDomain=function(a){return a},e.prototype._defaultExtent=function(){return[0,this._base]},e.prototype._expandSingleValueDomain=function(a){if(a[0]===a[1]){var b=a[0];return b>0?[b/this._base,b*this._base]:0===b?[-this._base,this._base]:[b*this._base,b/this._base]}return a},e.prototype._getRange=function(){return this._d3Scale.range()},e.prototype._setRange=function(a){this._d3Scale.range(a)},e.prototype.defaultTicks=function(){return this._d3Scale.ticks(c.ModifiedLog._DEFAULT_NUM_TICKS)},e}(a.QuantitativeScale);c.ModifiedLog=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){c.call(this),this._range=[0,1],this._d3Scale=d3.scale.ordinal();var a=.3;this._innerPadding=d._convertToPlottableInnerPadding(a),this._outerPadding=d._convertToPlottableOuterPadding(.5,a)}return b(d,c),d.prototype.extentOfValues=function(b){return a.Utils.Array.uniq(b)},d.prototype._getExtent=function(){return a.Utils.Array.uniq(this._getAllIncludedValues())},d.prototype.domain=function(a){return c.prototype.domain.call(this,a)},d.prototype._setDomain=function(a){c.prototype._setDomain.call(this,a),this.range(this.range())},d.prototype.range=function(a){if(null==a)return this._range;this._range=a;var b=1-1/(1+this.innerPadding()),c=this.outerPadding()/(1+this.innerPadding());return this._d3Scale.rangeBands(a,b,c),this},d._convertToPlottableInnerPadding=function(a){return 1/(1-a)-1},d._convertToPlottableOuterPadding=function(a,b){return a/(1-b)},d.prototype.rangeBand=function(){return this._d3Scale.rangeBand()},d.prototype.stepWidth=function(){return this.rangeBand()*(1+this.innerPadding())},d.prototype.innerPadding=function(a){return null==a?this._innerPadding:(this._innerPadding=a,this.range(this.range()),this._dispatchUpdate(),this)},d.prototype.outerPadding=function(a){return null==a?this._outerPadding:(this._outerPadding=a,this.range(this.range()),this._dispatchUpdate(),this)},d.prototype.scale=function(a){return this._d3Scale(a)+this.rangeBand()/2},d.prototype._getDomain=function(){return this._d3Scale.domain()},d.prototype._setBackingScaleDomain=function(a){this._d3Scale.domain(a)},d.prototype._getRange=function(){return this._d3Scale.range()},d.prototype._setRange=function(a){this._d3Scale.range(a)},d}(a.Scale);c.Category=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(a){c.call(this);var b;switch(a){case null:case void 0:null==d._plottableColorCache&&(d._plottableColorCache=d._getPlottableColors()),b=d3.scale.ordinal().range(d._plottableColorCache);break;case"Category10":case"category10":case"10":b=d3.scale.category10();break;case"Category20":case"category20":case"20":b=d3.scale.category20();break;case"Category20b":case"category20b":case"20b":b=d3.scale.category20b();break;case"Category20c":case"category20c":case"20c":b=d3.scale.category20c();break;default:throw new Error("Unsupported ColorScale type")}this._d3Scale=b}return b(d,c),d.prototype.extentOfValues=function(b){return a.Utils.Array.uniq(b)},d.prototype._getExtent=function(){return a.Utils.Array.uniq(this._getAllIncludedValues())},d.invalidateColorCache=function(){d._plottableColorCache=null},d._getPlottableColors=function(){for(var b,c=[],d=d3.select("body").append("plottable-color-tester"),e=a.Utils.Color.colorTest(d,""),f=0;null!==(b=a.Utils.Color.colorTest(d,"plottable-colors-"+f))&&f0&&this._setDomain([a.Utils.Math.min(b,0),a.Utils.Math.max(b,0)]),this},d.prototype.scale=function(a){return this._d3Scale(a)},d.prototype._getDomain=function(){return this._d3Scale.domain()},d.prototype._setBackingScaleDomain=function(a){this._d3Scale.domain(a)},d.prototype._getRange=function(){return this._colorRange},d.prototype._setRange=function(a){this._colorRange=a,this._resetScale()},d.REDS=["#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"],d.BLUES=["#FFFFFF","#CCFFFF","#A5FFFD","#85F7FB","#6ED3EF","#55A7E0","#417FD0","#2545D3","#0B02E1"],d.POSNEG=["#0B02E1","#2545D3","#417FD0","#55A7E0","#6ED3EF","#85F7FB","#A5FFFD","#CCFFFF","#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"],d}(a.Scale);c.InterpolatedColor=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a;!function(a){var b;!function(b){var c;!function(b){function c(b){if(0>=b)throw new Error("interval must be positive number");return function(c){var d=c.domain(),e=Math.min(d[0],d[1]),f=Math.max(d[0],d[1]),g=Math.ceil(e/b)*b,h=Math.floor((f-g)/b)+1,i=e%b===0?[]:[e],j=a.Utils.Math.range(0,h).map(function(a){return g+a*b}),k=f%b===0?[]:[f];return i.concat(j).concat(k)}}function d(){return function(a){var b=a.defaultTicks();return b.filter(function(a,c){return a%1===0||0===c||c===b.length-1})}}b.intervalTickGenerator=c,b.integerTickGenerator=d}(c=b.TickGenerators||(b.TickGenerators={}))}(b=a.Scales||(a.Scales={}))}(a||(a={}));var a;!function(a){var b=function(){function b(a){this._cachedSelectionValid=!1,this._dataset=a}return b.prototype.renderArea=function(a){return null==a?this._renderArea:(this._renderArea=a,this._cachedSelectionValid=!1,this)},b.prototype.remove=function(){null!=this.renderArea()&&this.renderArea().remove()},b.prototype._bindSelectionData=function(a){var b=this.selection().data(a);b.enter().append(this._svgElementName),b.exit().remove(),this._applyDefaultAttributes(b)},b.prototype._applyDefaultAttributes=function(a){null!=this._className&&a.classed(this._className,!0)},b.prototype._drawStep=function(a){var b=this.selection(),c=["fill","stroke"];c.forEach(function(c){null!=a.attrToAppliedProjector[c]&&b.attr(c,a.attrToAppliedProjector[c])}),a.animator.animate(b,a.attrToAppliedProjector),null!=this._className&&this.selection().classed(this._className,!0)},b.prototype._appliedProjectors=function(a){var b=this,c={};return Object.keys(a).forEach(function(d){c[d]=function(c,e){return a[d](c,e,b._dataset)}}),c},b.prototype.totalDrawTime=function(a,b){var c=0;return b.forEach(function(b){c+=b.animator.totalTime(a.length)}),c},b.prototype.draw=function(b,c){var d=this,e=c.map(function(a){var b=d._appliedProjectors(a.attrToProjector);return{attrToAppliedProjector:b,animator:a.animator}});this._bindSelectionData(b),this._cachedSelectionValid=!1;var f=0;return e.forEach(function(c){a.Utils.Window.setTimeout(function(){return d._drawStep(c)},f),f+=c.animator.totalTime(b.length)}),this},b.prototype.selection=function(){return this._cachedSelectionValid||(this._cachedSelection=this.renderArea().selectAll(this.selector()),this._cachedSelectionValid=!0),this._cachedSelection},b.prototype.selector=function(){return this._svgElementName},b.prototype.selectionForIndex=function(a){return d3.select(this.selection()[0][a])},b}();a.Drawer=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="line",this._svgElementName="path"}return b(c,a),c.prototype._applyDefaultAttributes=function(b){a.prototype._applyDefaultAttributes.call(this,b),b.style("fill","none")},c.prototype.selectionForIndex=function(){return d3.select(this.selection()[0][0])},c}(a.Drawer);c.Line=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="area",this._svgElementName="path"}return b(c,a),c.prototype._applyDefaultAttributes=function(b){a.prototype._applyDefaultAttributes.call(this,b),b.style("stroke","none")},c.prototype.selectionForIndex=function(){return d3.select(this.selection()[0][0])},c}(a.Drawer);c.Area=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._svgElementName="rect"}return b(c,a),c}(a.Drawer);c.Rectangle=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="arc",this._svgElementName="path"}return b(c,a),c}(a.Drawer);c.Arc=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._svgElementName="path",this._className="symbol"}return b(c,a),c}(a.Drawer);c.Symbol=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._svgElementName="line"}return b(c,a),c}(a.Drawer);c.Segment=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function a(){}return a.TOP="top",a.BOTTOM="bottom",a.LEFT="left",a.RIGHT="right",a.CENTER="center",a}();a.Alignment=b}(b=a.Components||(a.Components={}));var c=function(){function b(){this._clipPathEnabled=!1,this._origin={x:0,y:0},this._xAlignment="left",this._yAlignment="top",this._isSetup=!1,this._isAnchored=!1,this._boxes=[],this._isTopLevelComponent=!1,this._cssClasses=new a.Utils.Set,this._destroyed=!1,this._onAnchorCallbacks=new a.Utils.CallbackSet,this._onDetachCallbacks=new a.Utils.CallbackSet,this._cssClasses.add("component")}return b.prototype.anchor=function(a){if(this._destroyed)throw new Error("Can't reuse destroy()-ed Components!");return"svg"===a.node().nodeName.toLowerCase()&&(this._rootSVG=a,this._rootSVG.classed("plottable",!0),this._rootSVG.style("overflow","visible"),this._isTopLevelComponent=!0),null!=this._element?a.node().appendChild(this._element.node()):(this._element=a.append("g"),this._setup()),this._isAnchored=!0,this._onAnchorCallbacks.callCallbacks(this),this},b.prototype.onAnchor=function(a){return this._isAnchored&&a(this),this._onAnchorCallbacks.add(a),this},b.prototype.offAnchor=function(a){return this._onAnchorCallbacks["delete"](a),this},b.prototype._setup=function(){var b=this;this._isSetup||(this._cssClasses.forEach(function(a){b._element.classed(a,!0)}),this._cssClasses=new a.Utils.Set,this._backgroundContainer=this._element.append("g").classed("background-container",!0),this._addBox("background-fill",this._backgroundContainer),this._content=this._element.append("g").classed("content",!0),this._foregroundContainer=this._element.append("g").classed("foreground-container",!0),this._boxContainer=this._element.append("g").classed("box-container",!0),this._clipPathEnabled&&this._generateClipPath(),this._boundingBox=this._addBox("bounding-box"),this._isSetup=!0)},b.prototype.requestedSpace=function(){return{minWidth:0,minHeight:0}},b.prototype.computeLayout=function(c,d,e){var f=this;if(null==c||null==d||null==e){if(null==this._element)throw new Error("anchor() must be called before computeLayout()");if(!this._isTopLevelComponent)throw new Error("null arguments cannot be passed to computeLayout() on a non-root node");c={x:0,y:0},null==this._rootSVG.attr("width")&&this._rootSVG.attr("width","100%"),null==this._rootSVG.attr("height")&&this._rootSVG.attr("height","100%");var g=this._rootSVG.node();d=a.Utils.DOM.elementWidth(g),e=a.Utils.DOM.elementHeight(g)}var h=this._sizeFromOffer(d,e);this._width=h.width,this._height=h.height;var i=b._xAlignToProportion[this._xAlignment],j=b._yAlignToProportion[this._yAlignment];return this._origin={x:c.x+(d-this.width())*i,y:c.y+(e-this.height())*j},this._element.attr("transform","translate("+this._origin.x+","+this._origin.y+")"),this._boxes.forEach(function(a){return a.attr("width",f.width()).attr("height",f.height())}),this},b.prototype._sizeFromOffer=function(a,b){var c=this.requestedSpace(a,b);return{width:this.fixedWidth()?Math.min(a,c.minWidth):a,height:this.fixedHeight()?Math.min(b,c.minHeight):b}},b.prototype.render=function(){return this._isAnchored&&this._isSetup&&this.width()>=0&&this.height()>=0&&a.RenderController.registerToRender(this),this},b.prototype._scheduleComputeLayout=function(){this._isAnchored&&this._isSetup&&a.RenderController.registerToComputeLayout(this)},b.prototype.renderImmediately=function(){return this},b.prototype.redraw=function(){return this._isAnchored&&this._isSetup&&(this._isTopLevelComponent?this._scheduleComputeLayout():this.parent().redraw()),this},b.prototype.renderTo=function(b){if(this.detach(),null!=b){var c;if(c="string"==typeof b?d3.select(b):b,!c.node()||"svg"!==c.node().nodeName.toLowerCase())throw new Error("Plottable requires a valid SVG to renderTo");this.anchor(c)}if(null==this._element)throw new Error("If a Component has never been rendered before, then renderTo must be given a node to render to, or a d3.Selection, or a selector string");return this.computeLayout(),this.render(),a.RenderController.flush(),this},b.prototype.xAlignment=function(a){if(null==a)return this._xAlignment;if(a=a.toLowerCase(),null==b._xAlignToProportion[a])throw new Error("Unsupported alignment: "+a);return this._xAlignment=a,this.redraw(),this},b.prototype.yAlignment=function(a){if(null==a)return this._yAlignment;if(a=a.toLowerCase(),null==b._yAlignToProportion[a])throw new Error("Unsupported alignment: "+a);return this._yAlignment=a,this.redraw(),this},b.prototype._addBox=function(a,b){if(null==this._element)throw new Error("Adding boxes before anchoring is currently disallowed");b=null==b?this._boxContainer:b;var c=b.append("rect");return null!=a&&c.classed(a,!0),this._boxes.push(c),null!=this.width()&&null!=this.height()&&c.attr("width",this.width()).attr("height",this.height()),c},b.prototype._generateClipPath=function(){var b=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;b=b.split("#")[0];var c=a.Utils.DOM.generateUniqueClipPathId();this._element.attr("clip-path",'url("'+b+"#"+c+'")');var d=this._boxContainer.append("clipPath").attr("id",c);this._addBox("clip-rect",d)},b.prototype.hasClass=function(a){return null==a?!1:null==this._element?this._cssClasses.has(a):this._element.classed(a)},b.prototype.addClass=function(a){return null==a?this:(null==this._element?this._cssClasses.add(a):this._element.classed(a,!0),this)},b.prototype.removeClass=function(a){return null==a?this:(null==this._element?this._cssClasses["delete"](a):this._element.classed(a,!1),this)},b.prototype.fixedWidth=function(){return!1},b.prototype.fixedHeight=function(){return!1},b.prototype.detach=function(){return this.parent(null),this._isAnchored&&this._element.remove(),this._isAnchored=!1,this._onDetachCallbacks.callCallbacks(this),this},b.prototype.onDetach=function(a){return this._onDetachCallbacks.add(a),this},b.prototype.offDetach=function(a){return this._onDetachCallbacks["delete"](a),this},b.prototype.parent=function(a){if(void 0===a)return this._parent;if(null!==a&&!a.has(this))throw new Error("Passed invalid parent");return this._parent=a,this},b.prototype.destroy=function(){this._destroyed=!0,this.detach()},b.prototype.width=function(){return this._width},b.prototype.height=function(){return this._height},b.prototype.origin=function(){return{x:this._origin.x,y:this._origin.y}},b.prototype.originToSVG=function(){for(var a=this.origin(),b=this.parent();null!=b;){var c=b.origin();a.x+=c.x,a.y+=c.y,b=b.parent()}return a},b.prototype.foreground=function(){return this._foregroundContainer},b.prototype.content=function(){return this._content},b.prototype.background=function(){return this._backgroundContainer},b._xAlignToProportion={left:0,center:.5,right:1},b._yAlignToProportion={top:0,center:.5,bottom:1},b}();a.Component=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c=function(a){function c(){var b=this;a.call(this),this._detachCallback=function(a){return b.remove(a)}}return b(c,a),c.prototype.anchor=function(b){var c=this;return a.prototype.anchor.call(this,b),this._forEach(function(a){return a.anchor(c.content())}),this},c.prototype.render=function(){return this._forEach(function(a){return a.render()}),this},c.prototype.has=function(){throw new Error("has() is not implemented on ComponentContainer")},c.prototype._adoptAndAnchor=function(a){a.parent(this),a.onDetach(this._detachCallback),this._isAnchored&&a.anchor(this.content())},c.prototype.remove=function(a){return this.has(a)&&(a.offDetach(this._detachCallback),this._remove(a),a.detach(),this.redraw()),this},c.prototype._remove=function(){return!1},c.prototype._forEach=function(){throw new Error("_forEach() is not implemented on ComponentContainer")},c.prototype.destroy=function(){a.prototype.destroy.call(this),this._forEach(function(a){return a.destroy()})},c}(a.Component);a.ComponentContainer=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(a){var b=this;void 0===a&&(a=[]),c.call(this),this._components=[],this.addClass("component-group"),a.forEach(function(a){return b.append(a)})}return b(d,c),d.prototype._forEach=function(a){this.components().forEach(a)},d.prototype.has=function(a){return this._components.indexOf(a)>=0},d.prototype.requestedSpace=function(b,c){var d=this._components.map(function(a){return a.requestedSpace(b,c)});return{minWidth:a.Utils.Math.max(d,function(a){return a.minWidth},0),minHeight:a.Utils.Math.max(d,function(a){return a.minHeight},0)}},d.prototype.computeLayout=function(a,b,d){var e=this;return c.prototype.computeLayout.call(this,a,b,d),this._forEach(function(a){a.computeLayout({x:0,y:0},e.width(),e.height())}),this},d.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}},d.prototype.fixedWidth=function(){return this._components.every(function(a){return a.fixedWidth()})},d.prototype.fixedHeight=function(){return this._components.every(function(a){return a.fixedHeight()})},d.prototype.components=function(){return this._components.slice()},d.prototype.append=function(a){return null==a||this.has(a)||(a.detach(),this._components.push(a),this._adoptAndAnchor(a),this.redraw()),this},d.prototype._remove=function(a){var b=this._components.indexOf(a);return b>=0?(this._components.splice(b,1),!0):!1},d}(a.ComponentContainer);c.Group=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c=function(c){function d(b,d){var e=this;if(c.call(this),this._endTickLength=5,this._innerTickLength=5,this._tickLabelPadding=10,this._margin=15,this._showEndTickLabels=!1,null==b||null==d)throw new Error("Axis requires a scale and orientation");this._scale=b,this.orientation(d),this._setDefaultAlignment(),this.addClass("axis"),this.addClass(this._isHorizontal()?"x-axis":"y-axis"),this.formatter(a.Formatters.identity()),this._rescaleCallback=function(){return e._rescale()},this._scale.onUpdate(this._rescaleCallback)}return b(d,c),d.prototype.destroy=function(){c.prototype.destroy.call(this),this._scale.offUpdate(this._rescaleCallback)},d.prototype._isHorizontal=function(){return"top"===this._orientation||"bottom"===this._orientation},d.prototype._computeWidth=function(){return this._computedWidth=this._maxLabelTickLength(),this._computedWidth},d.prototype._computeHeight=function(){return this._computedHeight=this._maxLabelTickLength(),this._computedHeight},d.prototype.requestedSpace=function(){var a=0,b=0;return this._isHorizontal()?(null==this._computedHeight&&this._computeHeight(),b=this._computedHeight+this._margin):(null==this._computedWidth&&this._computeWidth(),a=this._computedWidth+this._margin),{minWidth:a,minHeight:b}},d.prototype.fixedHeight=function(){return this._isHorizontal()},d.prototype.fixedWidth=function(){return!this._isHorizontal()},d.prototype._rescale=function(){this.render()},d.prototype.computeLayout=function(a,b,d){return c.prototype.computeLayout.call(this,a,b,d),this._scale.range(this._isHorizontal()?[0,this.width()]:[this.height(),0]),this},d.prototype._setup=function(){c.prototype._setup.call(this),this._tickMarkContainer=this.content().append("g").classed(d.TICK_MARK_CLASS+"-container",!0),this._tickLabelContainer=this.content().append("g").classed(d.TICK_LABEL_CLASS+"-container",!0),this._baseline=this.content().append("line").classed("baseline",!0)},d.prototype._getTickValues=function(){return[]},d.prototype.renderImmediately=function(){var a=this._getTickValues(),b=this._tickMarkContainer.selectAll("."+d.TICK_MARK_CLASS).data(a);return b.enter().append("line").classed(d.TICK_MARK_CLASS,!0),b.attr(this._generateTickMarkAttrHash()),d3.select(b[0][0]).classed(d.END_TICK_MARK_CLASS,!0).attr(this._generateTickMarkAttrHash(!0)),d3.select(b[0][a.length-1]).classed(d.END_TICK_MARK_CLASS,!0).attr(this._generateTickMarkAttrHash(!0)),b.exit().remove(),this._baseline.attr(this._generateBaselineAttrHash()),this},d.prototype._generateBaselineAttrHash=function(){var a={x1:0,y1:0,x2:0,y2:0};switch(this._orientation){case"bottom":a.x2=this.width();break;case"top":a.x2=this.width(),a.y1=this.height(),a.y2=this.height();break;case"left":a.x1=this.width(),a.x2=this.width(),a.y2=this.height();break;case"right":a.y2=this.height()}return a},d.prototype._generateTickMarkAttrHash=function(a){var b=this;void 0===a&&(a=!1);var c={x1:0,y1:0,x2:0,y2:0},d=function(a){return b._scale.scale(a)};this._isHorizontal()?(c.x1=d,c.x2=d):(c.y1=d,c.y2=d);var e=a?this._endTickLength:this._innerTickLength;switch(this._orientation){case"bottom":c.y2=e;break;case"top":c.y1=this.height(),c.y2=this.height()-e;break;case"left":c.x1=this.width(),c.x2=this.width()-e;break;case"right":c.x2=e}return c},d.prototype.redraw=function(){return this._computedWidth=null,this._computedHeight=null,c.prototype.redraw.call(this)},d.prototype._setDefaultAlignment=function(){switch(this._orientation){case"bottom":this.yAlignment("top");break;case"top":this.yAlignment("bottom");break;case"left":this.xAlignment("right");break;case"right":this.xAlignment("left")}},d.prototype.formatter=function(a){return null==a?this._formatter:(this._formatter=a,this.redraw(),this)},d.prototype.tickLength=function(b){return a.Utils.Window.deprecated("tickLength()","v1.3.0","Replaced by innerTickLength()"),this.innerTickLength(b)},d.prototype.innerTickLength=function(a){if(null==a)return this._innerTickLength;if(0>a)throw new Error("inner tick length must be positive");return this._innerTickLength=a,this.redraw(),this},d.prototype.endTickLength=function(a){if(null==a)return this._endTickLength;if(0>a)throw new Error("end tick length must be positive");return this._endTickLength=a,this.redraw(),this},d.prototype._maxLabelTickLength=function(){return this.showEndTickLabels()?Math.max(this.innerTickLength(),this.endTickLength()):this.innerTickLength()},d.prototype.tickLabelPadding=function(a){if(null==a)return this._tickLabelPadding;if(0>a)throw new Error("tick label padding must be positive");return this._tickLabelPadding=a,this.redraw(),this},d.prototype.margin=function(a){if(null==a)return this._margin;if(0>a)throw new Error("margin size must be positive");return this._margin=a,this.redraw(),this},d.prototype.orientation=function(a){if(null==a)return this._orientation;var b=a.toLowerCase();if("top"!==b&&"bottom"!==b&&"left"!==b&&"right"!==b)throw new Error("unsupported orientation");return this._orientation=b,this.redraw(),this},d.prototype.showEndTickLabels=function(a){return null==a?this._showEndTickLabels:(this._showEndTickLabels=a,this.render(),this)},d.END_TICK_MARK_CLASS="end-tick-mark",d.TICK_MARK_CLASS="tick-mark",d.TICK_LABEL_CLASS="tick-label",d}(a.Component);a.Axis=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(a){a.second="second",a.minute="minute",a.hour="hour",a.day="day",a.week="week",a.month="month",a.year="year"}(d=a.TimeInterval||(a.TimeInterval={}));var e;!function(e){var f=function(e){function f(a,b){e.call(this,a,b),this._tierLabelPositions=[],this.addClass("time-axis"),this.tickLabelPadding(5),this.axisConfigurations(f._DEFAULT_TIME_AXIS_CONFIGURATIONS)}return b(f,e),f.prototype.tierLabelPositions=function(a){if(null==a)return this._tierLabelPositions;if(!a.every(function(a){return"between"===a.toLowerCase()||"center"===a.toLowerCase()}))throw new Error("Unsupported position for tier labels");return this._tierLabelPositions=a,this.redraw(),this},f.prototype.axisConfigurations=function(b){if(null==b)return this._possibleTimeAxisConfigurations;this._possibleTimeAxisConfigurations=b,this._numTiers=a.Utils.Math.max(this._possibleTimeAxisConfigurations.map(function(a){return a.length}),0),this._isAnchored&&this._setupDomElements();for(var c=this.tierLabelPositions(),d=[],e=0;ed&&a.every(function(a){return b._checkTimeAxisTierConfigurationWidth(a)})&&(c=d)}),c===this._possibleTimeAxisConfigurations.length&&(a.Utils.Window.warn("zoomed out too far: could not find suitable interval to display labels"),--c),c},f.prototype.orientation=function(a){if(a&&("right"===a.toLowerCase()||"left"===a.toLowerCase()))throw new Error(a+" is not a supported orientation for TimeAxis - only horizontal orientations are supported");return e.prototype.orientation.call(this,a)},f.prototype._computeHeight=function(){var a=this._measurer.measure().height;this._tierHeights=[];for(var b=0;bthis._scale.domain()[1])return this.width();var f=Math.abs(this._scale.scale(e)-this._scale.scale(c));return f},f.prototype._maxWidthForInterval=function(a){return this._measurer.measure(a.formatter(f._LONG_DATE)).width},f.prototype._checkTimeAxisTierConfigurationWidth=function(a){var b=this._maxWidthForInterval(a)+2*this.tickLabelPadding();return Math.min(this._getIntervalLength(a),this.width())>=b},f.prototype._sizeFromOffer=function(a,b){var c=e.prototype._sizeFromOffer.call(this,a,b);return c.height=this._tierHeights.reduce(function(a,b){return a+b>c.height?a:a+b}),c},f.prototype._setup=function(){e.prototype._setup.call(this),this._setupDomElements()},f.prototype._setupDomElements=function(){this.content().selectAll("."+f.TIME_AXIS_TIER_CLASS).remove(),this._tierLabelContainers=[],this._tierMarkContainers=[],this._tierBaselines=[],this._tickLabelContainer.remove(),this._baseline.remove();for(var b=0;b=f.length||g.push(new Date((f[b+1].valueOf()-f[b].valueOf())/2+f[b].valueOf()))}):g=f;var h=b.selectAll("."+a.Axis.TICK_LABEL_CLASS).data(g,function(a){return String(a.valueOf())}),i=h.enter().append("g").classed(a.Axis.TICK_LABEL_CLASS,!0);i.append("text");var j="center"===this._tierLabelPositions[d]||1===c.step?0:this.tickLabelPadding(),k="bottom"===this.orientation()?d3.sum(this._tierHeights.slice(0,d+1))-this.tickLabelPadding():this.height()-d3.sum(this._tierHeights.slice(0,d))-this.tickLabelPadding(),l=h.selectAll("text");l.size()>0&&a.Utils.DOM.translate(l,j,k),h.exit().remove(),h.attr("transform",function(a){return"translate("+e._scale.scale(a)+",0)"});var m="center"===this._tierLabelPositions[d]||1===c.step?"middle":"start";h.selectAll("text").text(c.formatter).style("text-anchor",m)},f.prototype._renderTickMarks=function(b,c){var d=this._tierMarkContainers[c].selectAll("."+a.Axis.TICK_MARK_CLASS).data(b);d.enter().append("line").classed(a.Axis.TICK_MARK_CLASS,!0);var e=this._generateTickMarkAttrHash(),f=this._tierHeights.slice(0,c).reduce(function(a,b){return a+b},0);"bottom"===this.orientation()?(e.y1=f,e.y2=f+("center"===this._tierLabelPositions[c]?this.innerTickLength():this._tierHeights[c])):(e.y1=this.height()-f,e.y2=this.height()-(f+("center"===this._tierLabelPositions[c]?this.innerTickLength():this._tierHeights[c]))),d.attr(e),"bottom"===this.orientation()?(e.y1=f,e.y2=f+this._tierHeights[c]):(e.y1=this.height()-f,e.y2=this.height()-(f+this._tierHeights[c])),d3.select(d[0][0]).attr(e),d3.select(d[0][0]).classed(a.Axis.END_TICK_MARK_CLASS,!0),d3.select(d[0][d.size()-1]).classed(a.Axis.END_TICK_MARK_CLASS,!0),d.exit().remove()},f.prototype._renderLabellessTickMarks=function(b){var c=this._tickMarkContainer.selectAll("."+a.Axis.TICK_MARK_CLASS).data(b);c.enter().append("line").classed(a.Axis.TICK_MARK_CLASS,!0);var d=this._generateTickMarkAttrHash();d.y2="bottom"===this.orientation()?this.tickLabelPadding():this.height()-this.tickLabelPadding(),c.attr(d),c.exit().remove()},f.prototype._generateLabellessTicks=function(){return this._mostPreciseConfigIndex<1?[]:this._getTickIntervalValues(this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex-1][0])},f.prototype.renderImmediately=function(){var a=this;this._mostPreciseConfigIndex=this._getMostPreciseConfigurationIndex();var b=this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex];this._cleanTiers(),b.forEach(function(b,c){return a._renderTierLabels(a._tierLabelContainers[c],b,c)});for(var c=b.map(function(b){return a._getTickValuesForConfiguration(b)}),d=0,e=0;e=i&&(g=this._generateLabellessTicks()),this._renderLabellessTickMarks(g),this._hideOverflowingTiers();for(var e=0;e=c?"inherit":"hidden"})},f.prototype._hideOverlappingAndCutOffLabels=function(b){var c,d=this,e=this._boundingBox.node().getBoundingClientRect(),f=function(a){return Math.floor(e.left)<=Math.ceil(a.left)&&Math.floor(e.top)<=Math.ceil(a.top)&&Math.floor(a.right)<=Math.ceil(e.left+d.width())&&Math.floor(a.bottom)<=Math.ceil(e.top+d.height())},g=this._tierMarkContainers[b].selectAll("."+a.Axis.TICK_MARK_CLASS).filter(function(){var a=d3.select(this).style("visibility");return"visible"===a||"inherit"===a}),h=g[0].map(function(a){return a.getBoundingClientRect()}),i=this._tierLabelContainers[b].selectAll("."+a.Axis.TICK_LABEL_CLASS).filter(function(){var a=d3.select(this).style("visibility");return"visible"===a||"inherit"===a});i.each(function(b,d){var e=this.getBoundingClientRect(),g=d3.select(this),i=h[d],j=h[d+1];!f(e)||null!=c&&a.Utils.DOM.clientRectsOverlap(e,c)||i.right>e.left||j.left=b[1]?b[0]:b[1];return c===b[0]?a.ticks().filter(function(a){return a>=c&&d>=a}):a.ticks().filter(function(a){return a>=c&&d>=a}).reverse()},e.prototype._rescale=function(){if(this._isSetup){if(!this._isHorizontal()){var a=this._computeWidth();if(a>this.width()||a=f.left)return!1}else if(e.top-c<=f.bottom)return!1}return!0},e}(a.Axis);d.Numeric=e}(d=a.Axes||(a.Axes={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(a,b){d.call(this,a,b),this._tickLabelAngle=0,this.addClass("category-axis")}return b(e,d),e.prototype._setup=function(){d.prototype._setup.call(this),this._measurer=new c.Measurers.CacheCharacterMeasurer(this._tickLabelContainer),this._wrapper=new c.Wrappers.SingleLineWrapper,this._writer=new c.Writers.Writer(this._measurer,this._wrapper)},e.prototype._rescale=function(){return this.redraw()},e.prototype.requestedSpace=function(a,b){var c=this._isHorizontal()?0:this._maxLabelTickLength()+this.tickLabelPadding()+this.margin(),d=this._isHorizontal()?this._maxLabelTickLength()+this.tickLabelPadding()+this.margin():0;if(0===this._scale.domain().length)return{minWidth:0,minHeight:0};var e=this._scale,f=this._measureTicks(a,b,e,e.domain());return{minWidth:f.usedWidth+c,minHeight:f.usedHeight+d}},e.prototype._getTickValues=function(){return this._scale.domain()},e.prototype.tickLabelAngle=function(a){if(null==a)return this._tickLabelAngle;if(0!==a&&90!==a&&-90!==a)throw new Error("Angle "+a+" not supported; only 0, 90, and -90 are valid values");return this._tickLabelAngle=a,this.redraw(),this},e.prototype._drawTicks=function(a,b,c,d){var e,f,g=this;switch(this.tickLabelAngle()){case 0:e={left:"right",right:"left",top:"center",bottom:"center"},f={left:"center",right:"center",top:"bottom",bottom:"top"};break;case 90:e={left:"center",right:"center",top:"right",bottom:"left"},f={left:"top",right:"bottom",top:"center",bottom:"center"};break;case-90:e={left:"center",right:"center",top:"left",bottom:"right"},f={left:"bottom",right:"top",top:"center",bottom:"center"}}d.each(function(d){var h=c.stepWidth(),i=g._isHorizontal()?h:a-g._maxLabelTickLength()-g.tickLabelPadding(),j=g._isHorizontal()?b-g._maxLabelTickLength()-g.tickLabelPadding():h,k={selection:d3.select(this),xAlign:e[g.orientation()],yAlign:f[g.orientation()],textRotation:g.tickLabelAngle()};g._writer.write(g.formatter()(d),i,j,k)})},e.prototype._measureTicks=function(b,d,e,f){var g=this,h=this._isHorizontal()?b:d,i=2*e.outerPadding(),j=(f.length-1)*e.innerPadding(),k=h/(i+j+f.length),l=k*(1+e.innerPadding()),m=f.map(function(a){var c=b-g._maxLabelTickLength()-g.tickLabelPadding();g._isHorizontal()&&(c=l,0!==g._tickLabelAngle&&(c=d-g._maxLabelTickLength()-g.tickLabelPadding()),c=Math.max(c,0));var e=l;return g._isHorizontal()&&(e=d-g._maxLabelTickLength()-g.tickLabelPadding(),0!==g._tickLabelAngle&&(e=b-g._maxLabelTickLength()-g.tickLabelPadding()),e=Math.max(e,0)),g._wrapper.wrap(g.formatter()(a),g._measurer,c,e)}),n=this._isHorizontal()&&0===this._tickLabelAngle?d3.sum:a.Utils.Math.max,o=this._isHorizontal()&&0===this._tickLabelAngle?a.Utils.Math.max:d3.sum,p=m.every(function(a){return!c.Utils.StringMethods.isNotEmptyString(a.truncatedText)&&1===a.noLines}),q=n(m,function(a){return g._measurer.measure(a.wrappedText).width},0),r=o(m,function(a){return g._measurer.measure(a.wrappedText).height},0);if(0!==this._tickLabelAngle){var s=r;r=q,q=s}return{textFits:p,usedWidth:q,usedHeight:r}},e.prototype.renderImmediately=function(){var b=this;d.prototype.renderImmediately.call(this);var c=this._scale,e=this._tickLabelContainer.selectAll("."+a.Axis.TICK_LABEL_CLASS).data(this._scale.domain(),function(a){return a}),f=function(a){var d=c.stepWidth()-c.rangeBand(),e=c.scale(a)-c.rangeBand()/2-d/2,f=b._isHorizontal()?e:0,g=b._isHorizontal()?0:e;return"translate("+f+","+g+")"};e.enter().append("g").classed(a.Axis.TICK_LABEL_CLASS,!0),e.exit().remove(),e.attr("transform",f),e.text(""),this._drawTicks(this.width(),this.height(),c,e);var g="right"===this.orientation()?this._maxLabelTickLength()+this.tickLabelPadding():0,h="bottom"===this.orientation()?this._maxLabelTickLength()+this.tickLabelPadding():0;return a.Utils.DOM.translate(this._tickLabelContainer,g,h),this},e.prototype.computeLayout=function(a,b,c){return this._measurer.reset(),d.prototype.computeLayout.call(this,a,b,c)},e}(a.Axis);d.Category=e}(d=a.Axes||(a.Axes={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(a){function d(b,c){void 0===b&&(b=""),void 0===c&&(c=0),a.call(this),this.addClass("label"),this.text(b),this.angle(c),this.xAlignment("center").yAlignment("center"),this._padding=0}return b(d,a),d.prototype.requestedSpace=function(){var a=this._measurer.measure(this._text),b=(0===this.angle()?a.width:a.height)+2*this.padding(),c=(0===this.angle()?a.height:a.width)+2*this.padding();return{minWidth:b,minHeight:c}},d.prototype._setup=function(){a.prototype._setup.call(this),this._textContainer=this.content().append("g"),this._measurer=new c.Measurers.Measurer(this._textContainer),this._wrapper=new c.Wrappers.Wrapper,this._writer=new c.Writers.Writer(this._measurer,this._wrapper),this.text(this._text)},d.prototype.text=function(a){if(null==a)return this._text;if("string"!=typeof a)throw new Error("Label.text() only takes strings as input");return this._text=a,this.redraw(),this},d.prototype.angle=function(a){if(null==a)return this._angle;if(a%=360,a>180?a-=360:-180>a&&(a+=360),-90!==a&&0!==a&&90!==a)throw new Error(a+" is not a valid angle for Label");return this._angle=a,this.redraw(),this},d.prototype.padding=function(a){if(null==a)return this._padding;if(a=+a,0>a)throw new Error(a+" is not a valid padding value. Cannot be less than 0.");return this._padding=a,this.redraw(),this},d.prototype.fixedWidth=function(){return!0},d.prototype.fixedHeight=function(){return!0},d.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this),this._textContainer.selectAll("g").remove();var b=this._measurer.measure(this._text),c=Math.max(Math.min((this.height()-b.height)/2,this.padding()),0),d=Math.max(Math.min((this.width()-b.width)/2,this.padding()),0);this._textContainer.attr("transform","translate("+d+","+c+")");var e=this.width()-2*d,f=this.height()-2*c,g={selection:this._textContainer,xAlign:this.xAlignment(),yAlign:this.yAlignment(),textRotation:this.angle()};return this._writer.write(this._text,e,f,g),this},d}(a.Component);d.Label=e;var f=function(a){function c(b,d){a.call(this,b,d),this.addClass(c.TITLE_LABEL_CLASS)}return b(c,a),c.TITLE_LABEL_CLASS="title-label",c}(e);d.TitleLabel=f;var g=function(a){function c(b,d){a.call(this,b,d),this.addClass(c.AXIS_LABEL_CLASS)}return b(c,a),c.AXIS_LABEL_CLASS="axis-label",c}(e);d.AxisLabel=g}(d=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(b){var c=this;if(d.call(this),this._padding=5,this.addClass("legend"),this.maxEntriesPerRow(1),null==b)throw new Error("Legend requires a colorScale");this._colorScale=b,this._redrawCallback=function(){return c.redraw()},this._colorScale.onUpdate(this._redrawCallback),this.xAlignment("right").yAlignment("top"),this.comparator(function(a,b){return c._colorScale.domain().indexOf(a)-c._colorScale.domain().indexOf(b)}),this._symbolFactoryAccessor=function(){return a.SymbolFactories.circle()},this._symbolOpacityAccessor=function(){return 1}}return b(e,d),e.prototype._setup=function(){d.prototype._setup.call(this);var a=this.content().append("g").classed(e.LEGEND_ROW_CLASS,!0),b=a.append("g").classed(e.LEGEND_ENTRY_CLASS,!0);b.append("text"),this._measurer=new c.Measurers.Measurer(a),this._wrapper=(new c.Wrappers.Wrapper).maxLines(1),this._writer=new c.Writers.Writer(this._measurer,this._wrapper).addTitleElement(!0)},e.prototype.maxEntriesPerRow=function(a){return null==a?this._maxEntriesPerRow:(this._maxEntriesPerRow=a,this.redraw(),this)},e.prototype.comparator=function(a){return null==a?this._comparator:(this._comparator=a,this.redraw(),this)},e.prototype.colorScale=function(a){return null!=a?(this._colorScale.offUpdate(this._redrawCallback),this._colorScale=a,this._colorScale.onUpdate(this._redrawCallback),this.redraw(),this):this._colorScale},e.prototype.destroy=function(){d.prototype.destroy.call(this),this._colorScale.offUpdate(this._redrawCallback)},e.prototype._calculateLayoutInfo=function(a,b){var c=this,d=this._measurer.measure().height,e=Math.max(0,a-this._padding),f=this._colorScale.domain().slice();f.sort(this.comparator());var g=d3.map(),h=d3.map();f.forEach(function(a){var b=d+c._measurer.measure(a).width+c._padding,f=Math.min(b,e);g.set(a,f),h.set(a,b)});var i=this._packRows(e,f,g),j=Math.floor((b-2*this._padding)/d);return j!==j&&(j=0),{textHeight:d,entryLengths:g,untruncatedEntryLengths:h,rows:i,numRowsToDraw:Math.max(Math.min(j,i.length),0)}},e.prototype.requestedSpace=function(b,c){var d=this._calculateLayoutInfo(b,c),e=d.rows.map(function(a){return d3.sum(a,function(a){return d.untruncatedEntryLengths.get(a)})}),f=a.Utils.Math.max(e,0);return{minWidth:this._padding+f,minHeight:d.rows.length*d.textHeight+2*this._padding}},e.prototype._packRows=function(a,b,c){var d=this,e=[],f=[],g=a;return b.forEach(function(b){var h=c.get(b);(h>g||f.length===d._maxEntriesPerRow)&&(e.push(f),f=[],g=a),f.push(b),g-=h}),0!==f.length&&e.push(f),e},e.prototype.entitiesAt=function(a){if(!this._isSetup)return[];var b=[],c=this._calculateLayoutInfo(this.width(),this.height()),d=this._padding,f=this;return this.content().selectAll("g."+e.LEGEND_ROW_CLASS).each(function(g,h){var i=h*c.textHeight+d,j=(h+1)*c.textHeight+d,k=(i+j)/2,l=d,m=d;d3.select(this).selectAll("g."+e.LEGEND_ENTRY_CLASS).each(function(d){m+=c.entryLengths.get(d);var e=l+c.textHeight/2;if(m>=a.x&&l<=a.x&&j>=a.y&&i<=a.y){var g=d3.select(this),h=g.datum();b.push({datum:h,position:{x:e,y:k},selection:g,component:f})}l+=c.entryLengths.get(d)})}),b},e.prototype.renderImmediately=function(){var a=this;d.prototype.renderImmediately.call(this);var b=this._calculateLayoutInfo(this.width(),this.height()),c=b.rows.slice(0,b.numRowsToDraw),f=this.content().selectAll("g."+e.LEGEND_ROW_CLASS).data(c);f.enter().append("g").classed(e.LEGEND_ROW_CLASS,!0),f.exit().remove(),f.attr("transform",function(c,d){return"translate(0, "+(d*b.textHeight+a._padding)+")"});var g=f.selectAll("g."+e.LEGEND_ENTRY_CLASS).data(function(a){return a}),h=g.enter().append("g").classed(e.LEGEND_ENTRY_CLASS,!0);h.append("path"),h.append("g").classed("text-container",!0),g.exit().remove();var i=this._padding;f.each(function(){var a=i,c=d3.select(this).selectAll("g."+e.LEGEND_ENTRY_CLASS);c.attr("transform",function(c){var d="translate("+a+", 0)";return a+=b.entryLengths.get(c),d})}),g.select("path").attr("d",function(c,d,e){return a.symbol()(c,e)(.6*b.textHeight)}).attr("transform","translate("+b.textHeight/2+","+b.textHeight/2+")").attr("fill",function(b){return a._colorScale.scale(b)}).attr("opacity",function(b,c,d){return a.symbolOpacity()(b,d)}).classed(e.LEGEND_SYMBOL_CLASS,!0);var j=this._padding,k=g.select("g.text-container");k.text(""),k.append("title").text(function(a){return a});var l=this;return k.attr("transform","translate("+b.textHeight+", 0)").each(function(a){var c=d3.select(this),d=b.entryLengths.get(a)-b.textHeight-j,e={selection:c,xAlign:"left",yAlign:"top",textRotation:0};l._writer.write(a,d,l.height(),e)}),this},e.prototype.symbol=function(a){return null==a?this._symbolFactoryAccessor:(this._symbolFactoryAccessor=a,this.render(),this)},e.prototype.symbolOpacity=function(a){return null==a?this._symbolOpacityAccessor:(this._symbolOpacityAccessor="number"==typeof a?function(){return a}:a,this.render(),this)},e.prototype.fixedWidth=function(){return!0},e.prototype.fixedHeight=function(){return!0},e.LEGEND_ROW_CLASS="legend-row",e.LEGEND_ENTRY_CLASS="legend-entry",e.LEGEND_SYMBOL_CLASS="legend-symbol",e}(a.Component);d.Legend=e}(d=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(b){var c=this;if(d.call(this),this._padding=5,this._numSwatches=10,null==b)throw new Error("InterpolatedColorLegend requires a interpolatedColorScale");this._scale=b,this._redrawCallback=function(){return c.redraw()},this._scale.onUpdate(this._redrawCallback),this._formatter=a.Formatters.general(),this._orientation="horizontal",this.addClass("legend"),this.addClass("interpolated-color-legend")}return b(e,d),e.prototype.destroy=function(){d.prototype.destroy.call(this),this._scale.offUpdate(this._redrawCallback)},e.prototype.formatter=function(a){return void 0===a?this._formatter:(this._formatter=a,this.redraw(),this)},e._ensureOrientation=function(a){if(a=a.toLowerCase(),"horizontal"===a||"left"===a||"right"===a)return a;throw new Error('"'+a+'" is not a valid orientation for InterpolatedColorLegend')},e.prototype.orientation=function(a){return null==a?this._orientation:(this._orientation=e._ensureOrientation(a),this.redraw(),this)},e.prototype.fixedWidth=function(){return!0},e.prototype.fixedHeight=function(){return!0},e.prototype._generateTicks=function(){for(var a=this._scale.domain(),b=(a[1]-a[0])/this._numSwatches,c=[],d=0;d<=this._numSwatches;d++)c.push(a[0]+b*d);return c},e.prototype._setup=function(){d.prototype._setup.call(this),this._swatchContainer=this.content().append("g").classed("swatch-container",!0),this._swatchBoundingBox=this.content().append("rect").classed("swatch-bounding-box",!0),this._lowerLabel=this.content().append("g").classed(e.LEGEND_LABEL_CLASS,!0),this._upperLabel=this.content().append("g").classed(e.LEGEND_LABEL_CLASS,!0),this._measurer=new c.Measurers.Measurer(this.content()),this._wrapper=new c.Wrappers.Wrapper,this._writer=new c.Writers.Writer(this._measurer,this._wrapper)},e.prototype.requestedSpace=function(){var b,c,d=this,e=this._measurer.measure().height,f=this._generateTicks(),g=f.length,h=this._scale.domain(),i=h.map(function(a){return d._measurer.measure(d._formatter(a)).width});if(this._isVertical()){var j=a.Utils.Math.max(i,0);c=this._padding+e+this._padding+j+this._padding,b=this._padding+g*e+this._padding}else b=this._padding+e+this._padding,c=this._padding+i[0]+this._padding+g*e+this._padding+i[1]+this._padding;return{minWidth:c,minHeight:b}},e.prototype._isVertical=function(){return"horizontal"!==this._orientation},e.prototype.renderImmediately=function(){var a=this;d.prototype.renderImmediately.call(this);var b,c,e,f,g=this._scale.domain(),h=this._formatter(g[0]),i=this._measurer.measure(h).width,j=this._formatter(g[1]),k=this._measurer.measure(j).width,l=this._generateTicks(),m=l.length,n=this._padding,o={x:0,y:0},p={x:0,y:0},q={selection:this._lowerLabel,xAlign:"center",yAlign:"center",textRotation:0},r={selection:this._upperLabel,xAlign:"center",yAlign:"center",textRotation:0},s={x:0,y:n,width:0,height:0};if(this._isVertical()){var t=Math.max(i,k);b=Math.max(this.width()-3*n-t,0),c=Math.max((this.height()-2*n)/m,0),f=function(a,b){return n+(m-(b+1))*c},r.yAlign="top",o.y=n,q.yAlign="bottom",p.y=-n,"left"===this._orientation?(e=function(){return n+t+n},r.xAlign="right",o.x=-(n+b+n),q.xAlign="right",p.x=-(n+b+n)):(e=function(){return n},r.xAlign="left",o.x=n+b+n,q.xAlign="left",p.x=n+b+n),s.width=b,s.height=m*c}else b=Math.max((this.width()-4*n-i-k)/m,0),c=Math.max(this.height()-2*n,0),e=function(a,c){return n+i+n+c*b},f=function(){return n},r.xAlign="right",o.x=-n,q.xAlign="left",p.x=n,s.width=m*b,s.height=c;s.x=e(null,0),this._upperLabel.text(""),this._writer.write(j,this.width(),this.height(),r);var u="translate("+o.x+", "+o.y+")";this._upperLabel.attr("transform",u),this._lowerLabel.text(""),this._writer.write(h,this.width(),this.height(),q);var v="translate("+p.x+", "+p.y+")";this._lowerLabel.attr("transform",v),this._swatchBoundingBox.attr(s);var w=this._swatchContainer.selectAll("rect.swatch").data(l);return w.enter().append("rect").classed("swatch",!0),w.exit().remove(),w.attr({fill:function(b){return a._scale.scale(b)},width:b,height:c,x:e,y:f}),this},e.LEGEND_LABEL_CLASS="legend-label",e}(a.Component);d.InterpolatedColorLegend=e}(d=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(b,d){var e=this;if(null!=b&&!a.QuantitativeScale.prototype.isPrototypeOf(b))throw new Error("xScale needs to inherit from Scale.QuantitativeScale");if(null!=d&&!a.QuantitativeScale.prototype.isPrototypeOf(d))throw new Error("yScale needs to inherit from Scale.QuantitativeScale");c.call(this),this.addClass("gridlines"),this._xScale=b,this._yScale=d,this._renderCallback=function(){return e.render()},this._xScale&&this._xScale.onUpdate(this._renderCallback),this._yScale&&this._yScale.onUpdate(this._renderCallback)}return b(d,c),d.prototype.destroy=function(){return c.prototype.destroy.call(this),this._xScale&&this._xScale.offUpdate(this._renderCallback),this._yScale&&this._yScale.offUpdate(this._renderCallback),this},d.prototype._setup=function(){c.prototype._setup.call(this),this._xLinesContainer=this.content().append("g").classed("x-gridlines",!0),this._yLinesContainer=this.content().append("g").classed("y-gridlines",!0)},d.prototype.renderImmediately=function(){return c.prototype.renderImmediately.call(this),this._redrawXLines(),this._redrawYLines(),this},d.prototype.computeLayout=function(a,b,d){return c.prototype.computeLayout.call(this,a,b,d),null!=this._xScale&&this._xScale.range([0,this.width()]),null!=this._yScale&&this._yScale.range([this.height(),0]),this},d.prototype._redrawXLines=function(){var a=this;if(this._xScale){var b=this._xScale.ticks(),c=function(b){return a._xScale.scale(b)},d=this._xLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",c).attr("y1",0).attr("x2",c).attr("y2",this.height()).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},d.prototype._redrawYLines=function(){var a=this;if(this._yScale){var b=this._yScale.ticks(),c=function(b){return a._yScale.scale(b)},d=this._yLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",0).attr("y1",c).attr("x2",this.width()).attr("y2",c).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},d}(a.Component);c.Gridlines=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(a){var b=this;void 0===a&&(a=[]),c.call(this),this._rowPadding=0,this._columnPadding=0,this._rows=[],this._rowWeights=[],this._columnWeights=[],this._nRows=0,this._nCols=0,this._calculatedLayout=null,this.addClass("table"),a.forEach(function(a,c){a.forEach(function(a,d){null!=a&&b.add(a,c,d)})})}return b(d,c),d.prototype._forEach=function(a){for(var b=0;b0&&f!==z,E=g>0&&g!==A;if(!D&&!E)break;if(w>5)break}return f=m-d3.sum(h.guaranteedWidths),g=n-d3.sum(h.guaranteedHeights),s=d._calcProportionalSpace(p,f),t=d._calcProportionalSpace(o,g),{colProportionalSpace:s,rowProportionalSpace:t,guaranteedWidths:h.guaranteedWidths,guaranteedHeights:h.guaranteedHeights,wantsWidth:i,wantsHeight:j}},d.prototype._determineGuarantees=function(b,c,d){void 0===d&&(d=!1);var e=a.Utils.Array.createFilledArray(0,this._nCols),f=a.Utils.Array.createFilledArray(0,this._nRows),g=a.Utils.Array.createFilledArray(!1,this._nCols),h=a.Utils.Array.createFilledArray(!1,this._nRows);return this._rows.forEach(function(a,i){a.forEach(function(a,j){var k;k=null!=a?a.requestedSpace(b[j],c[i]):{minWidth:0,minHeight:0};var l=d?Math.min(k.minWidth,b[j]):k.minWidth;e[j]=Math.max(e[j],l);var m=d?Math.min(k.minHeight,c[i]):k.minHeight;f[i]=Math.max(f[i],m);var n=k.minWidth>b[j];g[j]=g[j]||n;var o=k.minHeight>c[i];h[i]=h[i]||o})}),{guaranteedWidths:e,guaranteedHeights:f,wantsWidthArr:g,wantsHeightArr:h}},d.prototype.requestedSpace=function(a,b){return this._calculatedLayout=this._iterateLayout(a,b),{minWidth:d3.sum(this._calculatedLayout.guaranteedWidths),minHeight:d3.sum(this._calculatedLayout.guaranteedHeights)}},d.prototype.computeLayout=function(b,d,e){var f=this;c.prototype.computeLayout.call(this,b,d,e);var g=d3.sum(this._calculatedLayout.guaranteedWidths),h=d3.sum(this._calculatedLayout.guaranteedHeights),i=this._calculatedLayout;(g>this.width()||h>this.height())&&(i=this._iterateLayout(this.width(),this.height(),!0));var j=0,k=a.Utils.Array.add(i.rowProportionalSpace,i.guaranteedHeights),l=a.Utils.Array.add(i.colProportionalSpace,i.guaranteedWidths);return this._rows.forEach(function(a,b){var c=0;a.forEach(function(a,d){null!=a&&a.computeLayout({x:c,y:j},l[d],k[b]),c+=l[d]+f._columnPadding}),j+=k[b]+f._rowPadding}),this},d.prototype.rowPadding=function(a){return null==a?this._rowPadding:(this._rowPadding=a,this.redraw(),this)},d.prototype.columnPadding=function(a){return null==a?this._columnPadding:(this._columnPadding=a,this.redraw(),this)},d.prototype.rowWeight=function(a,b){return null==b?this._rowWeights[a]:(this._rowWeights[a]=b,this.redraw(),this)},d.prototype.columnWeight=function(a,b){return null==b?this._columnWeights[a]:(this._columnWeights[a]=b,this.redraw(),this)},d.prototype.fixedWidth=function(){var a=d3.transpose(this._rows);return d._fixedSpace(a,function(a){return null==a||a.fixedWidth()})},d.prototype.fixedHeight=function(){return d._fixedSpace(this._rows,function(a){return null==a||a.fixedHeight()})},d.prototype._padTableToSize=function(a,b){for(var c=0;a>c;c++){void 0===this._rows[c]&&(this._rows[c]=[],this._rowWeights[c]=null);for(var d=0;b>d;d++)void 0===this._rows[c][d]&&(this._rows[c][d]=null)}for(var d=0;b>d;d++)void 0===this._columnWeights[d]&&(this._columnWeights[d]=null)},d._calcComponentWeights=function(a,b,c){return a.map(function(a,d){if(null!=a)return a;var e=b[d].map(c),f=e.reduce(function(a,b){return a&&b},!0);return f?0:1})},d._calcProportionalSpace=function(b,c){var d=d3.sum(b);return 0===d?a.Utils.Array.createFilledArray(0,b.length):b.map(function(a){return c*a/d})},d._fixedSpace=function(a,b){var c=function(a){return a.reduce(function(a,b){return a&&b},!0)},d=function(a){return c(a.map(b))};return c(a.map(d))},d}(a.ComponentContainer);c.Table=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(){var b=this;a.call(this),this._boxVisible=!1,this._boxBounds={topLeft:{x:0,y:0},bottomRight:{x:0,y:0}},this.addClass("selection-box-layer"),this._adjustBoundsCallback=function(){b.bounds({topLeft:{x:b._xScale?b._xScale.scale(b._boxLeftDataValue):b._boxBounds.topLeft.x,y:b._yScale?b._yScale.scale(b._boxTopDataValue):b._boxBounds.topLeft.y},bottomRight:{x:b._xScale?b._xScale.scale(b._boxRightDataValue):b._boxBounds.bottomRight.x,y:b._yScale?b._yScale.scale(b._boxBottomDataValue):b._boxBounds.bottomRight.y}})}}return b(c,a),c.prototype._setup=function(){a.prototype._setup.call(this),this._box=this.content().append("g").classed("selection-box",!0).remove(),this._boxArea=this._box.append("rect").classed("selection-area",!0)},c.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}},c.prototype.bounds=function(a){return null==a?this._boxBounds:(this._setBounds(a),this.render(),this) -},c.prototype._setBounds=function(a){var b={x:Math.min(a.topLeft.x,a.bottomRight.x),y:Math.min(a.topLeft.y,a.bottomRight.y)},c={x:Math.max(a.topLeft.x,a.bottomRight.x),y:Math.max(a.topLeft.y,a.bottomRight.y)};this._boxBounds={topLeft:b,bottomRight:c},this._bindBoxDataValues()},c.prototype.renderImmediately=function(){if(this._boxVisible){var a=this._boxBounds.topLeft.y,b=this._boxBounds.bottomRight.y,c=this._boxBounds.topLeft.x,d=this._boxBounds.bottomRight.x;this._boxArea.attr({x:c,y:a,width:d-c,height:b-a}),this.content().node().appendChild(this._box.node())}else this._box.remove();return this},c.prototype.boxVisible=function(a){return null==a?this._boxVisible:(this._boxVisible=a,this.render(),this)},c.prototype.fixedWidth=function(){return!0},c.prototype.fixedHeight=function(){return!0},c.prototype.xScale=function(a){return null==a?this._xScale:(null!=this._xScale&&this._xScale.offUpdate(this._adjustBoundsCallback),this._xScale=a,this._xScale.onUpdate(this._adjustBoundsCallback),this._bindBoxDataValues(),this)},c.prototype.yScale=function(a){return null==a?this._yScale:(null!=this._yScale&&this._yScale.offUpdate(this._adjustBoundsCallback),this._yScale=a,this._yScale.onUpdate(this._adjustBoundsCallback),this._bindBoxDataValues(),this)},c.prototype.xExtent=function(){return[this._boxLeftDataValue,this._boxRightDataValue]},c.prototype.yExtent=function(){return[this._boxTopDataValue,this._boxBottomDataValue]},c.prototype._bindBoxDataValues=function(){this._boxLeftDataValue=this._xScale?this._xScale.invert(this._boxBounds.topLeft.x):null,this._boxTopDataValue=this._yScale?this._yScale.invert(this._boxBounds.topLeft.y):null,this._boxRightDataValue=this._xScale?this._xScale.invert(this._boxBounds.bottomRight.x):null,this._boxBottomDataValue=this._yScale?this._yScale.invert(this._boxBounds.bottomRight.y):null},c.prototype.destroy=function(){a.prototype.destroy.call(this),null!=this._xScale&&this.xScale().offUpdate(this._adjustBoundsCallback),null!=this._yScale&&this.yScale().offUpdate(this._adjustBoundsCallback)},c}(a.Component);c.SelectionBoxLayer=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d;!function(a){a[a.VALUE=0]="VALUE",a[a.PIXEL=1]="PIXEL"}(d||(d={}));var e=function(c){function e(a){var b=this;if(c.call(this),this._mode=d.VALUE,a!==e.ORIENTATION_VERTICAL&&a!==e.ORIENTATION_HORIZONTAL)throw new Error(a+" is not a valid orientation for GuideLineLayer");this._orientation=a,this._clipPathEnabled=!0,this.addClass("guide-line-layer"),this._scaleUpdateCallback=function(){b._syncPixelPositionAndValue(),b.render()}}return b(e,c),e.prototype._setup=function(){c.prototype._setup.call(this),this._guideLine=this.content().append("line").classed("guide-line",!0)},e.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}},e.prototype._isVertical=function(){return this._orientation===e.ORIENTATION_VERTICAL},e.prototype.fixedWidth=function(){return!0},e.prototype.fixedHeight=function(){return!0},e.prototype.computeLayout=function(a,b,d){return c.prototype.computeLayout.call(this,a,b,d),null!=this.scale()&&this.scale().range(this._isVertical()?[0,this.width()]:[this.height(),0]),this},e.prototype.renderImmediately=function(){return c.prototype.renderImmediately.call(this),this._syncPixelPositionAndValue(),this._guideLine.attr({x1:this._isVertical()?this.pixelPosition():0,y1:this._isVertical()?0:this.pixelPosition(),x2:this._isVertical()?this.pixelPosition():this.width(),y2:this._isVertical()?this.height():this.pixelPosition()}),this},e.prototype._syncPixelPositionAndValue=function(){null!=this.scale()&&(this._mode===d.VALUE&&null!=this.value()?this._pixelPosition=this.scale().scale(this.value()):this._mode===d.PIXEL&&null!=this.pixelPosition()&&(this._value=this.scale().invert(this.pixelPosition())))},e.prototype.scale=function(a){if(null==a)return this._scale;var b=this._scale;return null!=b&&b.offUpdate(this._scaleUpdateCallback),this._scale=a,this._scale.onUpdate(this._scaleUpdateCallback),this._syncPixelPositionAndValue(),this.redraw(),this},e.prototype.value=function(a){return null==a?this._value:(this._value=a,this._mode=d.VALUE,this._syncPixelPositionAndValue(),this.render(),this)},e.prototype.pixelPosition=function(b){if(null==b)return this._pixelPosition;if(!a.Utils.Math.isValidNumber(b))throw new Error("pixelPosition must be a finite number");return this._pixelPosition=b,this._mode=d.PIXEL,this._syncPixelPositionAndValue(),this.render(),this},e.prototype.destroy=function(){c.prototype.destroy.call(this),null!=this.scale()&&this.scale().offUpdate(this._scaleUpdateCallback)},e.ORIENTATION_VERTICAL="vertical",e.ORIENTATION_HORIZONTAL="horizontal",e}(a.Component);c.GuideLineLayer=e}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var b;!function(a){a.MAIN="main",a.RESET="reset"}(b=a.Animator||(a.Animator={}))}(c=a.Plots||(a.Plots={}));var d=function(d){function e(){var b=this;d.call(this),this._dataChanged=!1,this._animate=!1,this._animators={},this._clipPathEnabled=!0,this.addClass("plot"),this._datasetToDrawer=new a.Utils.Map,this._attrBindings=d3.map(),this._attrExtents=d3.map(),this._includedValuesProvider=function(a){return b._includedValuesForScale(a)},this._renderCallback=function(){return b.render()},this._onDatasetUpdateCallback=function(){return b._onDatasetUpdate()},this._propertyBindings=d3.map(),this._propertyExtents=d3.map();var f=(new a.Animators.Easing).maxTotalDuration(e._ANIMATION_MAX_DURATION);this.animator(c.Animator.MAIN,f),this.animator(c.Animator.RESET,new a.Animators.Null)}return b(e,d),e.prototype.anchor=function(a){return d.prototype.anchor.call(this,a),this._dataChanged=!0,this._updateExtents(),this},e.prototype._setup=function(){var a=this;d.prototype._setup.call(this),this._renderArea=this.content().append("g").classed("render-area",!0),this.datasets().forEach(function(b){return a._createNodesForDataset(b)})},e.prototype.destroy=function(){var a=this;d.prototype.destroy.call(this),this._scales().forEach(function(b){return b.offUpdate(a._renderCallback)}),this.datasets().forEach(function(b){return a.removeDataset(b)})},e.prototype.addDataset=function(a){this.datasets().indexOf(a)>-1&&this.removeDataset(a);var b=this._createDrawer(a);return this._datasetToDrawer.set(a,b),this._isSetup&&this._createNodesForDataset(a),a.onUpdate(this._onDatasetUpdateCallback),this._onDatasetUpdate(),this},e.prototype._createNodesForDataset=function(a){var b=this._datasetToDrawer.get(a);return b.renderArea(this._renderArea.append("g")),b},e.prototype._createDrawer=function(b){return new a.Drawer(b)},e.prototype._getAnimator=function(b){return this._animateOnNextRender()?this._animators[b]||new a.Animators.Null:new a.Animators.Null},e.prototype._onDatasetUpdate=function(){this._updateExtents(),this._dataChanged=!0,this.render()},e.prototype.attr=function(a,b,c){return null==b?this._attrBindings.get(a):(this._bindAttr(a,b,c),this.render(),this)},e.prototype._bindProperty=function(a,b,c){this._bind(a,b,c,this._propertyBindings,this._propertyExtents),this._updateExtentsForProperty(a)},e.prototype._bindAttr=function(a,b,c){this._bind(a,b,c,this._attrBindings,this._attrExtents),this._updateExtentsForAttr(a)},e.prototype._bind=function(a,b,c,d){var e=d.get(a),f=null!=e?e.scale:null;null!=f&&this._uninstallScaleForKey(f,a),null!=c&&this._installScaleForKey(c,a),d.set(a,{accessor:d3.functor(b),scale:c})},e.prototype._generateAttrToProjector=function(){var a={};this._attrBindings.forEach(function(b,c){var d=c.accessor,e=c.scale,f=e?function(a,b,c){return e.scale(d(a,b,c))}:d;a[b]=f});var b=this._propertyProjectors();return Object.keys(b).forEach(function(c){null==a[c]&&(a[c]=b[c])}),a},e.prototype.renderImmediately=function(){return this._isAnchored&&(this._paint(),this._dataChanged=!1),this},e.prototype.animated=function(a){return null==a?this._animate:(this._animate=a,this)},e.prototype.detach=function(){return d.prototype.detach.call(this),this._updateExtents(),this},e.prototype._scales=function(){var a=[];return this._attrBindings.forEach(function(b,c){var d=c.scale;null!=d&&-1===a.indexOf(d)&&a.push(d)}),this._propertyBindings.forEach(function(b,c){var d=c.scale;null!=d&&-1===a.indexOf(d)&&a.push(d)}),a},e.prototype._updateExtents=function(){var a=this;this._attrBindings.forEach(function(b){return a._updateExtentsForAttr(b)}),this._propertyExtents.forEach(function(b){return a._updateExtentsForProperty(b)}),this._scales().forEach(function(b){return b.addIncludedValuesProvider(a._includedValuesProvider)})},e.prototype._updateExtentsForAttr=function(a){this._updateExtentsForKey(a,this._attrBindings,this._attrExtents,null)},e.prototype._updateExtentsForProperty=function(a){this._updateExtentsForKey(a,this._propertyBindings,this._propertyExtents,this._filterForProperty(a))},e.prototype._filterForProperty=function(){return null},e.prototype._updateExtentsForKey=function(a,b,c,d){var e=this,f=b.get(a);null!=f&&null!=f.accessor&&c.set(a,this.datasets().map(function(a){return e._computeExtent(a,f,d)}))},e.prototype._computeExtent=function(a,b,c){var d=b.accessor,e=b.scale;if(null==e)return[];var f=a.data();null!=c&&(f=f.filter(function(b,d){return c(b,d,a)}));var g=function(b,c){return d(b,c,a)},h=f.map(g);return e.extentOfValues(h)},e.prototype._extentsForProperty=function(a){return this._propertyExtents.get(a)},e.prototype._includedValuesForScale=function(a){var b=this;if(!this._isAnchored)return[];var c=[];return this._attrBindings.forEach(function(d,e){if(e.scale===a){var f=b._attrExtents.get(d);null!=f&&(c=c.concat(d3.merge(f)))}}),this._propertyBindings.forEach(function(d,e){if(e.scale===a){var f=b._extentsForProperty(d);null!=f&&(c=c.concat(d3.merge(f)))}}),c},e.prototype.animator=function(a,b){return void 0===b?this._animators[a]:(this._animators[a]=b,this)},e.prototype.removeDataset=function(a){return this.datasets().indexOf(a)>-1&&(this._removeDatasetNodes(a),a.offUpdate(this._onDatasetUpdateCallback),this._datasetToDrawer["delete"](a),this._onDatasetUpdate()),this},e.prototype._removeDatasetNodes=function(a){var b=this._datasetToDrawer.get(a);b.remove()},e.prototype.datasets=function(a){var b=this,c=[];return this._datasetToDrawer.forEach(function(a,b){return c.push(b)}),null==a?c:(c.forEach(function(a){return b.removeDataset(a)}),a.forEach(function(a){return b.addDataset(a)}),this)},e.prototype._getDrawersInOrder=function(){var a=this;return this.datasets().map(function(b){return a._datasetToDrawer.get(b)})},e.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new a.Animators.Null}]},e.prototype._additionalPaint=function(){},e.prototype._getDataToDraw=function(){var b=new a.Utils.Map;return this.datasets().forEach(function(a){return b.set(a,a.data())}),b},e.prototype._paint=function(){var b=this._generateDrawSteps(),c=this._getDataToDraw(),d=this._getDrawersInOrder();this.datasets().forEach(function(a,e){return d[e].draw(c.get(a),b)});var e=this.datasets().map(function(a,e){return d[e].totalDrawTime(c.get(a),b)}),f=a.Utils.Math.max(e,0);this._additionalPaint(f)},e.prototype.selections=function(a){var b=this;void 0===a&&(a=this.datasets());var c=[];return a.forEach(function(a){var d=b._datasetToDrawer.get(a);null!=d&&d.renderArea().selectAll(d.selector()).each(function(){c.push(this)})}),d3.selectAll(c)},e.prototype.entities=function(a){var b=this;return void 0===a&&(a=this.datasets()),this._lightweightEntities(a).map(function(a){return b._lightweightPlotEntityToPlotEntity(a)})},e.prototype._lightweightEntities=function(b){var c=this;void 0===b&&(b=this.datasets());var d=[];return b.forEach(function(b){var e=c._datasetToDrawer.get(b),f=0;b.data().forEach(function(g,h){var i=c._pixelPoint(g,h,b);a.Utils.Math.isNaN(i.x)||a.Utils.Math.isNaN(i.y)||(d.push({datum:g,index:h,dataset:b,position:i,component:c,drawer:e,validDatumIndex:f}),f++)})}),d},e.prototype._lightweightPlotEntityToPlotEntity=function(a){var b={datum:a.datum,position:a.position,dataset:a.dataset,index:a.index,component:a.component,selection:a.drawer.selectionForIndex(a.validDatumIndex)};return b},e.prototype.entityNearest=function(b){var c,d=this,e=1/0,f=this._lightweightEntities();return f.forEach(function(f){if(d._entityVisibleOnPlot(f.position,f.datum,f.index,f.dataset)){var g=a.Utils.Math.distanceSquared(f.position,b);e>g&&(e=g,c=f)}}),this._lightweightPlotEntityToPlotEntity(c)},e.prototype._visibleOnPlot=function(b,c){return a.Utils.Window.deprecated("Plot._visibleOnPlot()","v1.1.0"),!(c.x<0||c.y<0||c.x>this.width()||c.y>this.height())},e.prototype._entityVisibleOnPlot=function(a){return!(a.x<0||a.y<0||a.x>this.width()||a.y>this.height())},e.prototype._uninstallScaleForKey=function(a){a.offUpdate(this._renderCallback),a.removeIncludedValuesProvider(this._includedValuesProvider)},e.prototype._installScaleForKey=function(a){a.onUpdate(this._renderCallback),a.addIncludedValuesProvider(this._includedValuesProvider)},e.prototype._propertyProjectors=function(){return{}},e._scaledAccessor=function(a){return null==a.scale?a.accessor:function(b,c,d){return a.scale.scale(a.accessor(b,c,d))}},e.prototype._pixelPoint=function(){return{x:0,y:0}},e.prototype._animateOnNextRender=function(){return this._animate&&this._dataChanged},e._ANIMATION_MAX_DURATION=600,e}(a.Component);a.Plot=d}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(){var b=this;d.call(this),this._labelFormatter=a.Formatters.identity(),this._labelsEnabled=!1,this.innerRadius(0),this.outerRadius(function(){return Math.min(b.width(),b.height())/2}),this.addClass("pie-plot"),this.attr("fill",function(a,b){return String(b)},new a.Scales.Color)}return b(e,d),e.prototype.computeLayout=function(a,b,c){d.prototype.computeLayout.call(this,a,b,c),this._renderArea.attr("transform","translate("+this.width()/2+","+this.height()/2+")");var e=Math.min(this.width(),this.height())/2;return null!=this.innerRadius().scale&&this.innerRadius().scale.range([0,e]),null!=this.outerRadius().scale&&this.outerRadius().scale.range([0,e]),this},e.prototype.addDataset=function(b){return 1===this.datasets().length?(a.Utils.Window.warn("Only one dataset is supported in Pie plots"),this):(this._updatePieAngles(),d.prototype.addDataset.call(this,b),this)},e.prototype.removeDataset=function(a){return d.prototype.removeDataset.call(this,a),this._startAngles=[],this._endAngles=[],this},e.prototype._onDatasetUpdate=function(){this._updatePieAngles(),d.prototype._onDatasetUpdate.call(this)},e.prototype._createDrawer=function(b){return new a.Drawers.Arc(b)},e.prototype.entities=function(a){var b=this;void 0===a&&(a=this.datasets());var c=d.prototype.entities.call(this,a);return c.forEach(function(a){a.position.x+=b.width()/2,a.position.y+=b.height()/2}),c},e.prototype.sectorValue=function(a,b){return null==a?this._propertyBindings.get(e._SECTOR_VALUE_KEY):(this._bindProperty(e._SECTOR_VALUE_KEY,a,b),this._updatePieAngles(),this.render(),this)},e.prototype.innerRadius=function(a,b){return null==a?this._propertyBindings.get(e._INNER_RADIUS_KEY):(this._bindProperty(e._INNER_RADIUS_KEY,a,b),this.render(),this)},e.prototype.outerRadius=function(a,b){return null==a?this._propertyBindings.get(e._OUTER_RADIUS_KEY):(this._bindProperty(e._OUTER_RADIUS_KEY,a,b),this.render(),this)},e.prototype.labelsEnabled=function(a){return null==a?this._labelsEnabled:(this._labelsEnabled=a,this.render(),this)},e.prototype.labelFormatter=function(a){return null==a?this._labelFormatter:(this._labelFormatter=a,this.render(),this)},e.prototype.entitiesAt=function(a){var b={x:this.width()/2,y:this.height()/2},c={x:a.x-b.x,y:a.y-b.y},d=this._sliceIndexForPoint(c);return null==d?[]:[this.entities()[d]]},e.prototype._propertyProjectors=function(){var b=this,c=d.prototype._propertyProjectors.call(this),e=a.Plot._scaledAccessor(this.innerRadius()),f=a.Plot._scaledAccessor(this.outerRadius());return c.d=function(a,c,d){return d3.svg.arc().innerRadius(e(a,c,d)).outerRadius(f(a,c,d)).startAngle(b._startAngles[c]).endAngle(b._endAngles[c])(a,c)},c},e.prototype._updatePieAngles=function(){if(null!=this.sectorValue()&&0!==this.datasets().length){var b=a.Plot._scaledAccessor(this.sectorValue()),c=this.datasets()[0],d=c.data().filter(function(d,e){return a.Utils.Math.isValidNumber(b(d,e,c))}),e=d3.layout.pie().sort(null).value(function(a,d){return b(a,d,c)})(d);e.some(function(a){return a.value<0})&&a.Utils.Window.warn("Negative values will not render correctly in a Pie Plot."),this._startAngles=e.map(function(a){return a.startAngle}),this._endAngles=e.map(function(a){return a.endAngle})}},e.prototype._getDataToDraw=function(){var b=d.prototype._getDataToDraw.call(this);if(0===this.datasets().length)return b;var c=a.Plot._scaledAccessor(this.sectorValue()),e=this.datasets()[0],f=b.get(e),g=f.filter(function(b,d){return a.Utils.Math.isValidNumber(c(b,d,e))});return b.set(e,g),b},e.prototype._pixelPoint=function(b,c,d){var e=a.Plot._scaledAccessor(this.innerRadius())(b,c,d),f=a.Plot._scaledAccessor(this.outerRadius())(b,c,d),g=(e+f)/2,h=a.Plot._scaledAccessor(this.sectorValue()),i=d3.layout.pie().sort(null).value(function(a,b){return h(a,b,d)})(d.data()),j=i[c].startAngle,k=i[c].endAngle,l=(j+k)/2;return{x:g*Math.sin(l),y:-g*Math.cos(l)}},e.prototype._additionalPaint=function(b){var c=this;this._renderArea.select(".label-area").remove(),this._labelsEnabled&&a.Utils.Window.setTimeout(function(){return c._drawLabels()},b)},e.prototype._sliceIndexForPoint=function(a){var b=Math.sqrt(Math.pow(a.x,2)+Math.pow(a.y,2)),c=Math.acos(-a.y/b);a.x<0&&(c=2*Math.PI-c);for(var d,e=0;ec){d=e;break}if(void 0!==d){var f=this.datasets()[0],g=f.data()[d],h=this.innerRadius().accessor(g,d,f),i=this.outerRadius().accessor(g,d,f);if(b>h&&i>b)return d}return null},e.prototype._drawLabels=function(){var b=this,d=this._generateAttrToProjector(),e=this._renderArea.append("g").classed("label-area",!0),f=new c.Measurers.Measurer(e),g=new c.Writers.Writer(f),h=this.datasets()[0],i=this._getDataToDraw().get(h);i.forEach(function(c,i){var j=b.sectorValue().accessor(c,i,h);if(a.Utils.Math.isValidNumber(j)){j=b._labelFormatter(j);var k=f.measure(j),l=(b._endAngles[i]+b._startAngles[i])/2,m=b.outerRadius().accessor(c,i,h);b.outerRadius().scale&&(m=b.outerRadius().scale.scale(m));var n=b.innerRadius().accessor(c,i,h);b.innerRadius().scale&&(n=b.innerRadius().scale.scale(n));var o=(m+n)/2,p=Math.sin(l)*o-k.width/2,q=-Math.cos(l)*o-k.height/2,r=[{x:p,y:q},{x:p,y:q+k.height},{x:p+k.width,y:q},{x:p+k.width,y:q+k.height}],s=r.every(function(a){return Math.abs(a.x)<=b.width()/2&&Math.abs(a.y)<=b.height()/2});if(s){var t=r.map(function(a){return b._sliceIndexForPoint(a)});s=t.every(function(a){return a===i})}var u=d.fill(c,i,h),v=1.6*a.Utils.Color.contrast("white",u)=p-i&&q+i>=h)l=0;else{var r=d._isVertical?m.y:m.x;l=Math.abs(h-r)}}(e>k||k===e&&f>l)&&(c=j,e=k,f=l)}}),c},f.prototype._visibleOnPlot=function(b,c,d){a.Utils.Window.deprecated("Bar._visibleOnPlot()","v1.1.0");var e={min:0,max:this.width()},f={min:0,max:this.height()},g=a.Utils.DOM.elementBBox(d);return a.Utils.DOM.intersectsBBox(e,f,g)},f.prototype._entityVisibleOnPlot=function(b,c,d,e){var f={min:0,max:this.width()},g={min:0,max:this.height()},h=this._generateAttrToProjector(),i=h.width(c,d,e),j=h.height(c,d,e),k={x:b.x-i/2,y:b.y,width:i,height:j};return a.Utils.DOM.intersectsBBox(f,g,k)},f.prototype.entitiesAt=function(a){return this._entitiesIntersecting(a.x,a.y)},f.prototype.entitiesIn=function(a,b){var c,d;if(null==b){var e=a;c={min:e.topLeft.x,max:e.bottomRight.x},d={min:e.topLeft.y,max:e.bottomRight.y}}else c=a,d=b;return this._entitiesIntersecting(c,d)},f.prototype._entitiesIntersecting=function(b,c){var d=[];return this.entities().forEach(function(e){a.Utils.DOM.intersectsBBox(b,c,a.Utils.DOM.elementBBox(e.selection))&&d.push(e)}),d},f.prototype._updateValueScale=function(){if(this._projectorsReady()){var b=this._isVertical?this.y().scale:this.x().scale;if(b instanceof a.QuantitativeScale){var c=b;c.addPaddingExceptionsProvider(this._baselineValueProvider),c.addIncludedValuesProvider(this._baselineValueProvider)}}},f.prototype._additionalPaint=function(b){var c=this,d=this._isVertical?this.y().scale:this.x().scale,e=d.scale(this.baselineValue()),f={x1:this._isVertical?0:e,y1:this._isVertical?e:0,x2:this._isVertical?this.width():e,y2:this._isVertical?e:this.height()};this._getAnimator("baseline").animate(this._baseline,f),this.datasets().forEach(function(a){return c._labelConfig.get(a).labelArea.selectAll("g").remove()}),this._labelsEnabled&&a.Utils.Window.setTimeout(function(){return c._drawLabels()},b)},f.prototype._extentsForProperty=function(b){var c,d=this,f=e.prototype._extentsForProperty.call(this,b);if("x"===b&&this._isVertical)c=this.x();else{if("y"!==b||this._isVertical)return f;c=this.y()}if(!(c&&c.scale&&c.scale instanceof a.QuantitativeScale))return f;var g=c.scale;return f=f.map(function(a){return[g.invert(g.scale(a[0])-d._barPixelWidth/2),g.invert(g.scale(a[1])+d._barPixelWidth/2)]})},f.prototype._drawLabels=function(){var a=this,b=this._getDataToDraw(),c=!1;this.datasets().forEach(function(d){return c=c||a._drawLabel(b.get(d),d)}),this._hideBarsIfAnyAreTooWide&&c&&this.datasets().forEach(function(b){return a._labelConfig.get(b).labelArea.selectAll("g").remove()})},f.prototype._drawLabel=function(b,c){var d=this,e=this._generateAttrToProjector(),g=this._labelConfig.get(c),h=g.labelArea,i=g.measurer,j=g.writer,k=b.map(function(b,g){var k=d._isVertical?d.y().accessor:d.x().accessor,l=a.Plot._scaledAccessor(d._isVertical?d.y():d.x()),m=d._isVertical?d.y().scale:d.x().scale,n=m.scale(d.baselineValue()),o=d._labelFormatter(k(b,g,c)).toString(),p=e.width(b,g,c),q=e.height(b,g,c),r=e.x(b,g,c),s=e.y(b,g,c),t=l(b,g,c)<=n,u=i.measure(o),v=e.fill(b,g,c),w=1.6*a.Utils.Color.contrast("white",v)A;if(u.height<=q&&u.width<=p){var C=Math.min((x-y)/2,f._LABEL_VERTICAL_PADDING);t||(C=-1*C),d._isVertical?s+=C:r+=C;var D=!0,E={x:r,y:t?s:s+q-u.height};E.x=d._isVertical?r+p/2-u.width/2:t?r:r+p-u.width,(E.x<0||E.x+u.width>d.width()||E.y<0||E.y+u.height>d.height())&&(D=!1);var F=h.append("g").attr("transform","translate("+r+","+s+")"),G=w?"dark-label":"light-label";F.classed(G,!0),F.style("visibility",D?"inherit":"hidden");var H,I;d._isVertical?(H="center",I=t?"top":"bottom"):(H=t?"left":"right",I="center");var J={selection:F,xAlign:H,yAlign:I,textRotation:0};j.write(o,p,q,J)}return B});return k.some(function(a){return a})},f.prototype._generateDrawSteps=function(){var a=[];if(this._animateOnNextRender()){var b=this._generateAttrToProjector(),c=this._isVertical?this.y().scale:this.x().scale,e=c.scale(this.baselineValue()),f=this._isVertical?"y":"x",g=this._isVertical?"height":"width";b[f]=function(){return e},b[g]=function(){return 0},a.push({attrToProjector:b,animator:this._getAnimator(d.Animator.RESET)})}return a.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(d.Animator.MAIN)}),a},f.prototype._generateAttrToProjector=function(){var b=e.prototype._generateAttrToProjector.call(this),c=this._isVertical?this.y().scale:this.x().scale,d=this._isVertical?"y":"x",f=this._isVertical?"x":"y",g=c.scale(this.baselineValue()),h=a.Plot._scaledAccessor(this._isVertical?this.x():this.y()),i=b.width,j=a.Plot._scaledAccessor(this._isVertical?this.y():this.x()),k=function(a,b,c){return Math.abs(g-j(a,b,c))};return b.width=this._isVertical?i:k,b.height=this._isVertical?k:i,b[f]=function(a,b,c){return h(a,b,c)-i(a,b,c)/2},b[d]=function(a,b,c){var d=j(a,b,c);return d>g?g:d},b},f.prototype._getBarPixelWidth=function(){if(!this._projectorsReady())return 0;var b,c=this._isVertical?this.x().scale:this.y().scale;if(c instanceof a.Scales.Category)b=c.rangeBand();else{var d=this._isVertical?this.x().accessor:this.y().accessor,e=d3.set(a.Utils.Array.flatten(this.datasets().map(function(a){return a.data().map(function(b,c){return d(b,c,a)}).filter(function(a){return null!=a}).map(function(a){return a.valueOf()})}))).values().map(function(a){return+a});e.sort(function(a,b){return a-b});var g=e.map(function(a){return c.scale(a)}),h=d3.pairs(g),i=this._isVertical?this.width():this.height();b=a.Utils.Math.min(h,function(a){return Math.abs(a[1]-a[0])},i*f._SINGLE_BAR_DIMENSION_RATIO),b*=f._BAR_WIDTH_RATIO}return b},f.prototype._updateBarPixelWidth=function(){this._barPixelWidth=this._getBarPixelWidth()},f.prototype.entities=function(a){var b=this;if(void 0===a&&(a=this.datasets()),!this._projectorsReady())return[];var c=e.prototype.entities.call(this,a),d=(this._isVertical?this.y().scale:this.x().scale).scale(this.baselineValue());return c.forEach(function(a){var c=a.selection;b._isVertical&&Math.floor(+c.attr("y"))>=Math.floor(d)?a.position.y+=+c.attr("height"):!b._isVertical&&Math.floor(+c.attr("x"))b&&b||c>0&&c||0,e=this.y().scale.scale(d);return function(){return e}},e.prototype._generateDrawSteps=function(){var b=[];if(this._animateOnNextRender()){var d=this._generateAttrToProjector();d.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),this._getResetYFunction()),b.push({attrToProjector:d,animator:this._getAnimator(c.Animator.RESET)})}return b.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(c.Animator.MAIN)}),b},e.prototype._generateAttrToProjector=function(){var a=d.prototype._generateAttrToProjector.call(this);return Object.keys(a).forEach(function(b){if("d"!==b){var c=a[b];a[b]=function(a,b,d){return a.length>0?c(a[0],b,d):null}}}),a},e.prototype.entityNearest=function(a){var b,c=this,d=1/0,e=1/0;return this.entities().forEach(function(f){if(c._entityVisibleOnPlot(f.position,f.datum,f.index,f.dataset)){var g=Math.abs(a.x-f.position.x),h=Math.abs(a.y-f.position.y);(d>g||g===d&&e>h)&&(b=f,d=g,e=h)}}),b},e.prototype._propertyProjectors=function(){var b=d.prototype._propertyProjectors.call(this);return b.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),a.Plot._scaledAccessor(this.y())),b},e.prototype._constructLineProjector=function(b,c){var d=this,e=function(b,c,e){var f=a.Plot._scaledAccessor(d.x())(b,c,e),g=a.Plot._scaledAccessor(d.y())(b,c,e);return null!=f&&!a.Utils.Math.isNaN(f)&&null!=g&&!a.Utils.Math.isNaN(g)};return function(a,f,g){return d3.svg.line().x(function(a,c){return b(a,c,g)}).y(function(a,b){return c(a,b,g)}).interpolate(d.interpolator()).defined(function(a,b){return e(a,b,g)})(a)}},e.prototype._getDataToDraw=function(){var b=new a.Utils.Map;return this.datasets().forEach(function(a){return b.set(a,[a.data()])}),b},e}(a.XYPlot);c.Line=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(){d.call(this),this.addClass("area-plot"),this.y0(0),this.attr("fill-opacity",.25),this.attr("fill",(new a.Scales.Color).range()[0]),this._lineDrawers=new a.Utils.Map}return b(e,d),e.prototype._setup=function(){var a=this;d.prototype._setup.call(this),this._lineDrawers.forEach(function(b){return b.renderArea(a._renderArea.append("g"))})},e.prototype.y=function(a,b){if(null==a)return d.prototype.y.call(this);if(null==b?d.prototype.y.call(this,a):d.prototype.y.call(this,a,b),null!=b){var c=this.y0().accessor;null!=c&&this._bindProperty(e._Y0_KEY,c,b),this._updateYScale()}return this},e.prototype.y0=function(a){if(null==a)return this._propertyBindings.get(e._Y0_KEY);var b=this.y(),c=b&&b.scale;return this._bindProperty(e._Y0_KEY,a,c),this._updateYScale(),this.render(),this},e.prototype._onDatasetUpdate=function(){d.prototype._onDatasetUpdate.call(this),this._updateYScale()},e.prototype.addDataset=function(b){var c=new a.Drawers.Line(b);return this._isSetup&&c.renderArea(this._renderArea.append("g")),this._lineDrawers.set(b,c),d.prototype.addDataset.call(this,b),this},e.prototype._removeDatasetNodes=function(a){d.prototype._removeDatasetNodes.call(this,a),this._lineDrawers.get(a).remove()},e.prototype._additionalPaint=function(){var a=this,b=this._generateLineDrawSteps(),c=this._getDataToDraw();this.datasets().forEach(function(d){return a._lineDrawers.get(d).draw(c.get(d),b)})},e.prototype._generateLineDrawSteps=function(){var b=[];if(this._animateOnNextRender()){var d=this._generateLineAttrToProjector();d.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),this._getResetYFunction()),b.push({attrToProjector:d,animator:this._getAnimator(c.Animator.RESET)})}return b.push({attrToProjector:this._generateLineAttrToProjector(),animator:this._getAnimator(c.Animator.MAIN)}),b},e.prototype._generateLineAttrToProjector=function(){var b=this._generateAttrToProjector();return b.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),a.Plot._scaledAccessor(this.y())),b},e.prototype._createDrawer=function(b){return new a.Drawers.Area(b)},e.prototype._generateDrawSteps=function(){var b=[];if(this._animateOnNextRender()){var d=this._generateAttrToProjector();d.d=this._constructAreaProjector(a.Plot._scaledAccessor(this.x()),this._getResetYFunction(),a.Plot._scaledAccessor(this.y0())),b.push({attrToProjector:d,animator:this._getAnimator(c.Animator.RESET)})}return b.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(c.Animator.MAIN)}),b},e.prototype._updateYScale=function(){var b=this._propertyExtents.get("y0"),c=a.Utils.Array.flatten(b),d=a.Utils.Array.uniq(c),e=1===d.length?d[0]:null,f=this.y(),g=f&&f.scale;null!=g&&(null!=this._constantBaselineValueProvider&&(g.removePaddingExceptionsProvider(this._constantBaselineValueProvider),this._constantBaselineValueProvider=null),null!=e&&(this._constantBaselineValueProvider=function(){return[e]},g.addPaddingExceptionsProvider(this._constantBaselineValueProvider)))},e.prototype._getResetYFunction=function(){return a.Plot._scaledAccessor(this.y0())},e.prototype._propertyProjectors=function(){var b=d.prototype._propertyProjectors.call(this);return b.d=this._constructAreaProjector(a.Plot._scaledAccessor(this.x()),a.Plot._scaledAccessor(this.y()),a.Plot._scaledAccessor(this.y0())),b},e.prototype.selections=function(a){var b=this;void 0===a&&(a=this.datasets());var c=d.prototype.selections.call(this,a)[0],e=a.map(function(a){return b._lineDrawers.get(a)}).filter(function(a){return null!=a});return e.forEach(function(a,b){return c.push(a.selectionForIndex(b).node())}),d3.selectAll(c)},e.prototype._constructAreaProjector=function(b,c,d){var e=this,f=function(b,c,d){var f=a.Plot._scaledAccessor(e.x())(b,c,d),g=a.Plot._scaledAccessor(e.y())(b,c,d);return a.Utils.Math.isValidNumber(f)&&a.Utils.Math.isValidNumber(g)};return function(a,g,h){var i=d3.svg.area().x(function(a,c){return b(a,c,h)}).y1(function(a,b){return c(a,b,h)}).y0(function(a,b){return d(a,b,h)}).interpolate(e.interpolator()).defined(function(a,b){return f(a,b,h)});return i(a)}},e._Y0_KEY="y0",e}(c.Line);c.Area=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(b){void 0===b&&(b=c.Bar.ORIENTATION_VERTICAL),d.call(this,b),this._clusterOffsets=new a.Utils.Map}return b(e,d),e.prototype._generateAttrToProjector=function(){var a=this,b=d.prototype._generateAttrToProjector.call(this),c=this._makeInnerScale(),e=function(){return c.rangeBand()};b.width=this._isVertical?e:b.width,b.height=this._isVertical?b.height:e;var f=b.x,g=b.y;return b.x=this._isVertical?function(b,c,d){return f(b,c,d)+a._clusterOffsets.get(d)}:function(a,b,c){return f(a,b,c)},b.y=this._isVertical?function(a,b,c){return g(a,b,c)}:function(b,c,d){return g(b,c,d)+a._clusterOffsets.get(d)},b},e.prototype._updateClusterPosition=function(){var a=this,b=this._makeInnerScale();this.datasets().forEach(function(c,d){return a._clusterOffsets.set(c,b.scale(String(d))-b.rangeBand()/2)})},e.prototype._makeInnerScale=function(){var b=new a.Scales.Category;b.domain(this.datasets().map(function(a,b){return String(b)}));var c=a.Plot._scaledAccessor(this.attr("width"));return b.range([0,c(null,0,null)]),b},e.prototype._getDataToDraw=function(){return this._updateClusterPosition(),d.prototype._getDataToDraw.call(this)},e}(c.Bar);c.ClusteredBar=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.call(this),this._baselineValue=0,this.addClass("stacked-area-plot"),this.attr("fill-opacity",1),this._stackingResult=new a.Utils.Map,this._stackedExtent=[],this._baselineValueProvider=function(){return[b._baselineValue]}}return b(d,c),d.prototype._getAnimator=function(){return new a.Animators.Null},d.prototype._setup=function(){c.prototype._setup.call(this),this._baseline=this._renderArea.append("line").classed("baseline",!0)},d.prototype.x=function(a,b){return null==a?c.prototype.x.call(this):(null==b?c.prototype.x.call(this,a):c.prototype.x.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},d.prototype.y=function(a,b){return null==a?c.prototype.y.call(this):(null==b?c.prototype.y.call(this,a):c.prototype.y.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},d.prototype._additionalPaint=function(){var a=this.y().scale.scale(this._baselineValue),b={x1:0,y1:a,x2:this.width(),y2:a};this._getAnimator("baseline").animate(this._baseline,b)},d.prototype._updateYScale=function(){var a=this.y(),b=a&&a.scale;null!=b&&(b.addPaddingExceptionsProvider(this._baselineValueProvider),b.addIncludedValuesProvider(this._baselineValueProvider))},d.prototype._onDatasetUpdate=function(){return this._updateStackExtentsAndOffsets(),c.prototype._onDatasetUpdate.call(this),this},d.prototype._updateExtentsForProperty=function(a){c.prototype._updateExtentsForProperty.call(this,a),"x"!==a&&"y"!==a||!this._projectorsReady()||this._updateStackExtentsAndOffsets()},d.prototype._extentsForProperty=function(a){var b="y";return a===b?[this._stackedExtent]:c.prototype._extentsForProperty.call(this,a)},d.prototype._updateStackExtentsAndOffsets=function(){if(this._projectorsReady()){var b=this.datasets(),c=this.x().accessor,d=this.y().accessor,e=this._filterForProperty("y");this._checkSameDomain(b,c),this._stackingResult=a.Utils.Stacking.stack(b,c,d),this._stackedExtent=a.Utils.Stacking.stackedExtent(this._stackingResult,c,e)}},d.prototype._checkSameDomain=function(b,c){var e=b.map(function(a){return d3.set(a.data().map(function(b,d){return c(b,d,a).toString()})).values()}),f=d._domainKeys(b,c);e.some(function(a){return a.length!==f.length})&&a.Utils.Window.warn("the domains across the datasets are not the same. Plot may produce unintended behavior.")},d._domainKeys=function(a,b){var c=d3.set();return a.forEach(function(a){a.data().forEach(function(d,e){c.add(b(d,e,a))})}),c.values()},d.prototype._propertyProjectors=function(){var b=this,d=c.prototype._propertyProjectors.call(this),e=this.y().accessor,f=this.x().accessor,g=function(b,c,d){return a.Utils.Stacking.normalizeKey(f(b,c,d))},h=function(a,c,d){return b.y().scale.scale(+e(a,c,d)+b._stackingResult.get(d).get(g(a,c,d)).offset)},i=function(a,c,d){return b.y().scale.scale(b._stackingResult.get(d).get(g(a,c,d)).offset)};return d.d=this._constructAreaProjector(a.Plot._scaledAccessor(this.x()),h,i),d},d.prototype._pixelPoint=function(b,d,e){var f=c.prototype._pixelPoint.call(this,b,d,e),g=this.x().accessor(b,d,e),h=this.y().accessor(b,d,e),i=this.y().scale.scale(+h+this._stackingResult.get(e).get(a.Utils.Stacking.normalizeKey(g)).offset);return{x:f.x,y:i}},d}(c.Area);c.StackedArea=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(b){void 0===b&&(b=c.Bar.ORIENTATION_VERTICAL),d.call(this,b),this.addClass("stacked-bar-plot"),this._stackingResult=new a.Utils.Map,this._stackedExtent=[]}return b(e,d),e.prototype.x=function(a,b){return null==a?d.prototype.x.call(this):(null==b?d.prototype.x.call(this,a):d.prototype.x.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},e.prototype.y=function(a,b){return null==a?d.prototype.y.call(this):(null==b?d.prototype.y.call(this,a):d.prototype.y.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},e.prototype._generateAttrToProjector=function(){var b=this,c=d.prototype._generateAttrToProjector.call(this),e=this._isVertical?"y":"x",f=this._isVertical?"x":"y",g=this._isVertical?this.y().scale:this.x().scale,h=this._propertyBindings.get(e).accessor,i=this._propertyBindings.get(f).accessor,j=function(b,c,d){return a.Utils.Stacking.normalizeKey(i(b,c,d))},k=function(a,c,d){return g.scale(b._stackingResult.get(d).get(j(a,c,d)).offset)},l=function(a,c,d){return g.scale(+h(a,c,d)+b._stackingResult.get(d).get(j(a,c,d)).offset)},m=function(a,b,c){return Math.abs(l(a,b,c)-k(a,b,c))};c[this._isVertical?"height":"width"]=m;var n=function(a,b,c){return+h(a,b,c)<0?k(a,b,c):l(a,b,c)};return c[e]=function(a,c,d){return b._isVertical?n(a,c,d):n(a,c,d)-m(a,c,d)},c},e.prototype._onDatasetUpdate=function(){return this._updateStackExtentsAndOffsets(),d.prototype._onDatasetUpdate.call(this),this},e.prototype._updateExtentsForProperty=function(a){d.prototype._updateExtentsForProperty.call(this,a),"x"!==a&&"y"!==a||!this._projectorsReady()||this._updateStackExtentsAndOffsets()},e.prototype._extentsForProperty=function(a){var b=this._isVertical?"y":"x";return a===b?[this._stackedExtent]:d.prototype._extentsForProperty.call(this,a)},e.prototype._updateStackExtentsAndOffsets=function(){if(this._projectorsReady()){var b=this.datasets(),c=this._isVertical?this.x().accessor:this.y().accessor,d=this._isVertical?this.y().accessor:this.x().accessor,e=this._filterForProperty(this._isVertical?"y":"x");this._stackingResult=a.Utils.Stacking.stack(b,c,d),this._stackedExtent=a.Utils.Stacking.stackedExtent(this._stackingResult,c,e)}},e}(c.Bar);c.StackedBar=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){c.call(this),this.addClass("segment-plot"),this.attr("stroke",(new a.Scales.Color).range()[0]),this.attr("stroke-width","2px")}return b(d,c),d.prototype._createDrawer=function(b){return new a.Drawers.Segment(b)},d.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new a.Animators.Null}]},d.prototype._updateExtentsForProperty=function(a){c.prototype._updateExtentsForProperty.call(this,a),"x"===a?c.prototype._updateExtentsForProperty.call(this,"x2"):"y"===a&&c.prototype._updateExtentsForProperty.call(this,"y2")},d.prototype._filterForProperty=function(a){return"x2"===a?c.prototype._filterForProperty.call(this,"x"):"y2"===a?c.prototype._filterForProperty.call(this,"y"):c.prototype._filterForProperty.call(this,a)},d.prototype.x=function(a,b){if(null==a)return c.prototype.x.call(this);if(null==b)c.prototype.x.call(this,a);else{c.prototype.x.call(this,a,b);var e=this.x2(),f=e&&e.accessor;null!=f&&this._bindProperty(d._X2_KEY,f,b)}return this},d.prototype.x2=function(a){if(null==a)return this._propertyBindings.get(d._X2_KEY);var b=this.x(),c=b&&b.scale;return this._bindProperty(d._X2_KEY,a,c),this.render(),this},d.prototype.y=function(a,b){if(null==a)return c.prototype.y.call(this);if(null==b)c.prototype.y.call(this,a);else{c.prototype.y.call(this,a,b);var e=this.y2(),f=e&&e.accessor;null!=f&&this._bindProperty(d._Y2_KEY,f,b)}return this},d.prototype.y2=function(a){if(null==a)return this._propertyBindings.get(d._Y2_KEY);var b=this.y(),c=b&&b.scale;return this._bindProperty(d._Y2_KEY,a,c),this.render(),this},d.prototype._propertyProjectors=function(){var b=c.prototype._propertyProjectors.call(this);return b.x1=a.Plot._scaledAccessor(this.x()),b.x2=a.Plot._scaledAccessor(null==this.x2()?this.x():this.x2()),b.y1=a.Plot._scaledAccessor(this.y()),b.y2=a.Plot._scaledAccessor(null==this.y2()?this.y():this.y2()),b},d.prototype.entitiesIn=function(a,b){var c,d;if(null==b){var e=a;c={min:e.topLeft.x,max:e.bottomRight.x},d={min:e.topLeft.y,max:e.bottomRight.y}}else c=a,d=b;return this._entitiesIntersecting(c,d)},d.prototype._entitiesIntersecting=function(a,b){var c=this,d=[],e=this._generateAttrToProjector();return this.entities().forEach(function(f){c._lineIntersectsBox(f,a,b,e)&&d.push(f)}),d},d.prototype._lineIntersectsBox=function(a,b,c,d){var e=this,f=d.x1(a.datum,a.index,a.dataset),g=d.x2(a.datum,a.index,a.dataset),h=d.y1(a.datum,a.index,a.dataset),i=d.y2(a.datum,a.index,a.dataset);if(b.min<=f&&f<=b.max&&c.min<=h&&h<=c.max||b.min<=g&&g<=b.max&&c.min<=i&&i<=c.max)return!0;var j={x:f,y:h},k={x:g,y:i},l=[{x:b.min,y:c.min},{x:b.min,y:c.max},{x:b.max,y:c.max},{x:b.max,y:c.min}],m=l.filter(function(a,b){return 0!==b?e._lineIntersectsSegment(j,k,a,l[b-1])&&e._lineIntersectsSegment(a,l[b-1],j,k):void 0});return m.length>0},d.prototype._lineIntersectsSegment=function(a,b,c,d){var e=function(a,b,c){return(b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x)};return e(a,b,c)*e(a,b,d)<0},d._X2_KEY="x2",d._Y2_KEY="y2",d}(a.XYPlot);c.Segment=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){c.call(this),this._connectorsEnabled=!1,this.addClass("waterfall-plot")}return b(d,c),d.prototype.connectorsEnabled=function(a){return null==a?this._connectorsEnabled:(this._connectorsEnabled=a,this)},d.prototype.total=function(a){return null==a?this._propertyBindings.get(d._TOTAL_KEY):(this._bindProperty(d._TOTAL_KEY,a,null),this)},d.prototype._additionalPaint=function(b){var c=this;this._connectorArea.selectAll("line").remove(),this._connectorsEnabled&&a.Utils.Window.setTimeout(function(){return c._drawConnectors()},b)},d.prototype._createNodesForDataset=function(a){var b=c.prototype._createNodesForDataset.call(this,a);return this._connectorArea=this._renderArea.append("g").classed(d._CONNECTOR_AREA_CLASS,!0),b},d.prototype._extentsForProperty=function(a){var b="y";return a===b?[this._extent]:c.prototype._extentsForProperty.call(this,a)},d.prototype._generateAttrToProjector=function(){var b=this,e=c.prototype._generateAttrToProjector.call(this),f=this.y().scale,g=a.Plot._scaledAccessor(this.total()),h=this.attr("y");null==h&&(e.y=function(a,c,d){var e=b.y().accessor(a,c,d),h=g(a,c,d);if(h)return Math.min(f.scale(e),f.scale(0));var i=b._subtotals[c];if(0===c)return f.scale(0>e?i-e:i);var j=b._subtotals[c-1];return f.scale(i>j?i:j)});var i=this.attr("height");return null==i&&(e.height=function(a,c,d){var e=g(a,c,d),h=b.y().accessor(a,c,d);if(e)return Math.abs(f.scale(h)-f.scale(0));var i=b._subtotals[c];if(0===c)return Math.abs(f.scale(i)-f.scale(i-h));var j=b._subtotals[c-1];return Math.abs(f.scale(i)-f.scale(j))}),e["class"]=function(a,c,e){var f="";null!=b.attr("class")&&(f=b.attr("class").accessor(a,c,e)+" ");var h=g(a,c,e);if(h)return f+d._BAR_TOTAL_CLASS;var i=b.y().accessor(a,c,e);return f+(i>0?d._BAR_GROWTH_CLASS:d._BAR_DECLINE_CLASS)},e},d.prototype._onDatasetUpdate=function(){return this._updateSubtotals(),c.prototype._onDatasetUpdate.call(this),this},d.prototype._calculateSubtotalsAndExtent=function(a){var b=this,c=Number.MAX_VALUE,d=Number.MIN_VALUE,e=0,f=!1;a.data().forEach(function(g,h){var i=b.y().accessor(g,h,a),j=b.total().accessor(g,h,a);if(j&&0!==h||(e+=i),b._subtotals.push(e),c>e&&(c=e),e>d&&(d=e),j&&(c>i&&(c=i),i>d&&(d=i)),!f&&j){for(var k=i-e,l=0;l0&&this._subtotals[c]>this._subtotals[e]||this._subtotals[c]<0&&this._subtotals[c]>=this._subtotals[e])&&(j=a.y(f,c,b)+a.height(f,c,b)),this._connectorArea.append("line").classed(d._CONNECTOR_CLASS,!0).attr("x1",h).attr("x2",i).attr("y1",j).attr("y2",j)}},d.prototype._updateSubtotals=function(){var a=this.datasets();if(a.length>0){var b=a[a.length-1];this._subtotals=new Array,this._calculateSubtotalsAndExtent(b)}},d._BAR_DECLINE_CLASS="waterfall-decline",d._BAR_GROWTH_CLASS="waterfall-growth",d._BAR_TOTAL_CLASS="waterfall-total",d._CONNECTOR_CLASS="connector",d._CONNECTOR_AREA_CLASS="connector-area",d._TOTAL_KEY="total",d}(c.Bar);c.Waterfall=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function a(){}return a.prototype.totalTime=function(){return 0},a.prototype.animate=function(a,b){return a.attr(b)},a}();a.Null=b}(b=a.Animators||(a.Animators={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function a(){this._startDelay=a._DEFAULT_START_DELAY_MILLISECONDS,this._stepDuration=a._DEFAULT_STEP_DURATION_MILLISECONDS,this._stepDelay=a._DEFAULT_ITERATIVE_DELAY_MILLISECONDS,this._maxTotalDuration=a._DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS,this._easingMode=a._DEFAULT_EASING_MODE}return a.prototype.totalTime=function(a){var b=this._getAdjustedIterativeDelay(a);return this.startDelay()+b*Math.max(a-1,0)+this.stepDuration()},a.prototype.animate=function(a,b){var c=this,d=a[0].length,e=this._getAdjustedIterativeDelay(d);return a.transition().ease(this.easingMode()).duration(this.stepDuration()).delay(function(a,b){return c.startDelay()+e*b}).attr(b)},a.prototype.startDelay=function(a){return null==a?this._startDelay:(this._startDelay=a,this)},a.prototype.stepDuration=function(a){return null==a?Math.min(this._stepDuration,this._maxTotalDuration):(this._stepDuration=a,this)},a.prototype.stepDelay=function(a){return null==a?this._stepDelay:(this._stepDelay=a,this)},a.prototype.maxTotalDuration=function(a){return null==a?this._maxTotalDuration:(this._maxTotalDuration=a,this)},a.prototype.easingMode=function(a){return null==a?this._easingMode:(this._easingMode=a,this)},a.prototype._getAdjustedIterativeDelay=function(a){var b=this.maxTotalDuration()-this.stepDuration();b=Math.max(b,0);var c=b/Math.max(a-1,1);return Math.min(this.stepDelay(),c)},a._DEFAULT_START_DELAY_MILLISECONDS=0,a._DEFAULT_STEP_DURATION_MILLISECONDS=300,a._DEFAULT_ITERATIVE_DELAY_MILLISECONDS=15,a._DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS=1/0,a._DEFAULT_EASING_MODE="exp-out",a}();a.Easing=b}(b=a.Animators||(a.Animators={}))}(a||(a={}));var a;!function(a){var b=function(){function a(){this._eventToCallback={},this._callbacks=[],this._connected=!1}return a.prototype._hasNoListeners=function(){return this._callbacks.every(function(a){return 0===a.size})},a.prototype._connect=function(){var a=this;this._connected||(Object.keys(this._eventToCallback).forEach(function(b){var c=a._eventToCallback[b];document.addEventListener(b,c)}),this._connected=!0)},a.prototype._disconnect=function(){var a=this;this._connected&&this._hasNoListeners()&&(Object.keys(this._eventToCallback).forEach(function(b){var c=a._eventToCallback[b];document.removeEventListener(b,c)}),this._connected=!1)},a.prototype._setCallback=function(a,b){this._connect(),a.add(b)},a.prototype._unsetCallback=function(a,b){a["delete"](b),this._disconnect()},a}();a.Dispatcher=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(b){var d=this;c.call(this),this._translator=a.Utils.ClientToSVGTranslator.getTranslator(b),this._lastMousePosition={x:-1,y:-1},this._moveCallbacks=new a.Utils.CallbackSet,this._downCallbacks=new a.Utils.CallbackSet,this._upCallbacks=new a.Utils.CallbackSet,this._wheelCallbacks=new a.Utils.CallbackSet,this._dblClickCallbacks=new a.Utils.CallbackSet,this._callbacks=[this._moveCallbacks,this._downCallbacks,this._upCallbacks,this._wheelCallbacks,this._dblClickCallbacks];var e=function(a){return d._measureAndDispatch(a,d._moveCallbacks,"page")};this._eventToCallback.mouseover=e,this._eventToCallback.mousemove=e,this._eventToCallback.mouseout=e,this._eventToCallback.mousedown=function(a){return d._measureAndDispatch(a,d._downCallbacks)},this._eventToCallback.mouseup=function(a){return d._measureAndDispatch(a,d._upCallbacks,"page")},this._eventToCallback.wheel=function(a){return d._measureAndDispatch(a,d._wheelCallbacks)},this._eventToCallback.dblclick=function(a){return d._measureAndDispatch(a,d._dblClickCallbacks)}}return b(d,c),d.getDispatcher=function(b){var c=a.Utils.DOM.boundingSVG(b),e=c[d._DISPATCHER_KEY];return null==e&&(e=new d(c),c[d._DISPATCHER_KEY]=e),e},d.prototype.onMouseMove=function(a){return this._setCallback(this._moveCallbacks,a),this},d.prototype.offMouseMove=function(a){return this._unsetCallback(this._moveCallbacks,a),this},d.prototype.onMouseDown=function(a){return this._setCallback(this._downCallbacks,a),this},d.prototype.offMouseDown=function(a){return this._unsetCallback(this._downCallbacks,a),this},d.prototype.onMouseUp=function(a){return this._setCallback(this._upCallbacks,a),this},d.prototype.offMouseUp=function(a){return this._unsetCallback(this._upCallbacks,a),this},d.prototype.onWheel=function(a){return this._setCallback(this._wheelCallbacks,a),this},d.prototype.offWheel=function(a){return this._unsetCallback(this._wheelCallbacks,a),this},d.prototype.onDblClick=function(a){return this._setCallback(this._dblClickCallbacks,a),this},d.prototype.offDblClick=function(a){return this._unsetCallback(this._dblClickCallbacks,a),this},d.prototype._measureAndDispatch=function(a,b,c){if(void 0===c&&(c="element"),"page"!==c&&"element"!==c)throw new Error("Invalid scope '"+c+"', must be 'element' or 'page'");if("page"===c||this._translator.insideSVG(a)){var d=this._translator.computePosition(a.clientX,a.clientY);null!=d&&(this._lastMousePosition=d,b.callCallbacks(this.lastMousePosition(),a))}},d.prototype.lastMousePosition=function(){return this._lastMousePosition},d._DISPATCHER_KEY="__Plottable_Dispatcher_Mouse",d}(a.Dispatcher);c.Mouse=d}(c=a.Dispatchers||(a.Dispatchers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(b){var d=this;c.call(this),this._translator=a.Utils.ClientToSVGTranslator.getTranslator(b),this._startCallbacks=new a.Utils.CallbackSet,this._moveCallbacks=new a.Utils.CallbackSet,this._endCallbacks=new a.Utils.CallbackSet,this._cancelCallbacks=new a.Utils.CallbackSet,this._callbacks=[this._moveCallbacks,this._startCallbacks,this._endCallbacks,this._cancelCallbacks],this._eventToCallback.touchstart=function(a){return d._measureAndDispatch(a,d._startCallbacks)},this._eventToCallback.touchmove=function(a){return d._measureAndDispatch(a,d._moveCallbacks,"page")},this._eventToCallback.touchend=function(a){return d._measureAndDispatch(a,d._endCallbacks,"page")},this._eventToCallback.touchcancel=function(a){return d._measureAndDispatch(a,d._cancelCallbacks,"page")}}return b(d,c),d.getDispatcher=function(b){var c=a.Utils.DOM.boundingSVG(b),e=c[d._DISPATCHER_KEY];return null==e&&(e=new d(c),c[d._DISPATCHER_KEY]=e),e},d.prototype.onTouchStart=function(a){return this._setCallback(this._startCallbacks,a),this},d.prototype.offTouchStart=function(a){return this._unsetCallback(this._startCallbacks,a),this},d.prototype.onTouchMove=function(a){return this._setCallback(this._moveCallbacks,a),this},d.prototype.offTouchMove=function(a){return this._unsetCallback(this._moveCallbacks,a),this},d.prototype.onTouchEnd=function(a){return this._setCallback(this._endCallbacks,a),this},d.prototype.offTouchEnd=function(a){return this._unsetCallback(this._endCallbacks,a),this},d.prototype.onTouchCancel=function(a){return this._setCallback(this._cancelCallbacks,a),this},d.prototype.offTouchCancel=function(a){return this._unsetCallback(this._cancelCallbacks,a),this},d.prototype._measureAndDispatch=function(a,b,c){if(void 0===c&&(c="element"),"page"!==c&&"element"!==c)throw new Error("Invalid scope '"+c+"', must be 'element' or 'page'");if("element"!==c||this._translator.insideSVG(a)){for(var d=a.changedTouches,e={},f=[],g=0;g0&&b.callCallbacks(f,e,a)}},d._DISPATCHER_KEY="__Plottable_Dispatcher_Touch",d}(a.Dispatcher);c.Touch=d}(c=a.Dispatchers||(a.Dispatchers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.call(this),this._eventToCallback.keydown=function(a){return b._processKeydown(a)},this._eventToCallback.keyup=function(a){return b._processKeyup(a)},this._keydownCallbacks=new a.Utils.CallbackSet,this._keyupCallbacks=new a.Utils.CallbackSet,this._callbacks=[this._keydownCallbacks,this._keyupCallbacks]}return b(d,c),d.getDispatcher=function(){var a=document[d._DISPATCHER_KEY];return null==a&&(a=new d,document[d._DISPATCHER_KEY]=a),a},d.prototype.onKeyDown=function(a){return this._setCallback(this._keydownCallbacks,a),this},d.prototype.offKeyDown=function(a){return this._unsetCallback(this._keydownCallbacks,a),this},d.prototype.onKeyUp=function(a){return this._setCallback(this._keyupCallbacks,a),this},d.prototype.offKeyUp=function(a){return this._unsetCallback(this._keyupCallbacks,a),this},d.prototype._processKeydown=function(a){this._keydownCallbacks.callCallbacks(a.keyCode,a)},d.prototype._processKeyup=function(a){this._keyupCallbacks.callCallbacks(a.keyCode,a)},d._DISPATCHER_KEY="__Plottable_Dispatcher_Key",d}(a.Dispatcher);c.Key=d}(c=a.Dispatchers||(a.Dispatchers={}))}(a||(a={}));var a;!function(a){var b=function(){function a(){var a=this;this._anchorCallback=function(b){return a._anchor(b)},this._enabled=!0}return a.prototype._anchor=function(){this._isAnchored=!0},a.prototype._unanchor=function(){this._isAnchored=!1},a.prototype.attachTo=function(a){return this._disconnect(),this._componentAttachedTo=a,this._connect(),this},a.prototype._connect=function(){this.enabled()&&null!=this._componentAttachedTo&&!this._isAnchored&&this._componentAttachedTo.onAnchor(this._anchorCallback)},a.prototype.detachFrom=function(){return this._disconnect(),this._componentAttachedTo=null,this},a.prototype._disconnect=function(){this._isAnchored&&this._unanchor(),null!=this._componentAttachedTo&&this._componentAttachedTo.offAnchor(this._anchorCallback)},a.prototype.enabled=function(a){return null==a?this._enabled:(this._enabled=a,this._enabled?this._connect():this._disconnect(),this)},a.prototype._translateToComponentSpace=function(a){var b=this._componentAttachedTo.originToSVG();return{x:a.x-b.x,y:a.y-b.y}},a.prototype._isInsideComponent=function(a){return 0<=a.x&&0<=a.y&&a.x<=this._componentAttachedTo.width()&&a.y<=this._componentAttachedTo.height()},a}();a.Interaction=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.apply(this,arguments),this._clickedDown=!1,this._onClickCallbacks=new a.Utils.CallbackSet,this._mouseDownCallback=function(a){return b._handleClickDown(a)},this._mouseUpCallback=function(a){return b._handleClickUp(a)},this._touchStartCallback=function(a,c){return b._handleClickDown(c[a[0]])},this._touchEndCallback=function(a,c){return b._handleClickUp(c[a[0]])},this._touchCancelCallback=function(){return b._clickedDown=!1}}return b(d,c),d.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(b.content().node()),this._mouseDispatcher.onMouseDown(this._mouseDownCallback),this._mouseDispatcher.onMouseUp(this._mouseUpCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(b.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback),this._touchDispatcher.onTouchEnd(this._touchEndCallback),this._touchDispatcher.onTouchCancel(this._touchCancelCallback)},d.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._mouseDispatcher.offMouseDown(this._mouseDownCallback),this._mouseDispatcher.offMouseUp(this._mouseUpCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher.offTouchEnd(this._touchEndCallback),this._touchDispatcher.offTouchCancel(this._touchCancelCallback),this._touchDispatcher=null},d.prototype._handleClickDown=function(a){var b=this._translateToComponentSpace(a);this._isInsideComponent(b)&&(this._clickedDown=!0)},d.prototype._handleClickUp=function(a){var b=this._translateToComponentSpace(a);this._clickedDown&&this._isInsideComponent(b)&&this._onClickCallbacks.callCallbacks(b),this._clickedDown=!1},d.prototype.onClick=function(a){return this._onClickCallbacks.add(a),this},d.prototype.offClick=function(a){return this._onClickCallbacks["delete"](a),this},d}(a.Interaction);c.Click=d}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d;!function(a){a[a.NotClicked=0]="NotClicked",a[a.SingleClicked=1]="SingleClicked",a[a.DoubleClicked=2]="DoubleClicked"}(d||(d={}));var e=function(c){function e(){var b=this;c.apply(this,arguments),this._clickState=d.NotClicked,this._clickedDown=!1,this._onDoubleClickCallbacks=new a.Utils.CallbackSet,this._mouseDownCallback=function(a){return b._handleClickDown(a)},this._mouseUpCallback=function(a){return b._handleClickUp(a)},this._dblClickCallback=function(){return b._handleDblClick()},this._touchStartCallback=function(a,c){return b._handleClickDown(c[a[0]])},this._touchEndCallback=function(a,c){return b._handleClickUp(c[a[0]])},this._touchCancelCallback=function(){return b._handleClickCancel()}}return b(e,c),e.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(b.content().node()),this._mouseDispatcher.onMouseDown(this._mouseDownCallback),this._mouseDispatcher.onMouseUp(this._mouseUpCallback),this._mouseDispatcher.onDblClick(this._dblClickCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(b.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback),this._touchDispatcher.onTouchEnd(this._touchEndCallback),this._touchDispatcher.onTouchCancel(this._touchCancelCallback)},e.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._mouseDispatcher.offMouseDown(this._mouseDownCallback),this._mouseDispatcher.offMouseUp(this._mouseUpCallback),this._mouseDispatcher.offDblClick(this._dblClickCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher.offTouchEnd(this._touchEndCallback),this._touchDispatcher.offTouchCancel(this._touchCancelCallback),this._touchDispatcher=null},e.prototype._handleClickDown=function(a){var b=this._translateToComponentSpace(a);this._isInsideComponent(b)&&(this._clickState===d.SingleClicked&&e._pointsEqual(b,this._clickedPoint)||(this._clickState=d.NotClicked),this._clickedPoint=b,this._clickedDown=!0)},e.prototype._handleClickUp=function(a){var b=this._translateToComponentSpace(a);this._clickState=this._clickedDown&&e._pointsEqual(b,this._clickedPoint)?this._clickState===d.NotClicked?d.SingleClicked:d.DoubleClicked:d.NotClicked,this._clickedDown=!1},e.prototype._handleDblClick=function(){this._clickState===d.DoubleClicked&&(this._onDoubleClickCallbacks.callCallbacks(this._clickedPoint),this._clickState=d.NotClicked)},e.prototype._handleClickCancel=function(){this._clickState=d.NotClicked,this._clickedDown=!1},e._pointsEqual=function(a,b){return a.x===b.x&&a.y===b.y},e.prototype.onDoubleClick=function(a){return this._onDoubleClickCallbacks.add(a),this},e.prototype.offDoubleClick=function(a){return this._onDoubleClickCallbacks["delete"](a),this},e}(a.Interaction);c.DoubleClick=e}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.apply(this,arguments),this._keyPressCallbacks={},this._keyReleaseCallbacks={},this._mouseMoveCallback=function(){return!1},this._downedKeys=new a.Utils.Set,this._keyDownCallback=function(a,c){return b._handleKeyDownEvent(a,c)},this._keyUpCallback=function(a){return b._handleKeyUpEvent(a)}}return b(d,c),d.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._positionDispatcher=a.Dispatchers.Mouse.getDispatcher(this._componentAttachedTo._element.node()),this._positionDispatcher.onMouseMove(this._mouseMoveCallback),this._keyDispatcher=a.Dispatchers.Key.getDispatcher(),this._keyDispatcher.onKeyDown(this._keyDownCallback),this._keyDispatcher.onKeyUp(this._keyUpCallback)},d.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._positionDispatcher.offMouseMove(this._mouseMoveCallback),this._positionDispatcher=null,this._keyDispatcher.offKeyDown(this._keyDownCallback),this._keyDispatcher.offKeyUp(this._keyUpCallback),this._keyDispatcher=null},d.prototype._handleKeyDownEvent=function(a,b){var c=this._translateToComponentSpace(this._positionDispatcher.lastMousePosition());this._isInsideComponent(c)&&!b.repeat&&(this._keyPressCallbacks[a]&&this._keyPressCallbacks[a].callCallbacks(a),this._downedKeys.add(a))},d.prototype._handleKeyUpEvent=function(a){this._downedKeys.has(a)&&this._keyReleaseCallbacks[a]&&this._keyReleaseCallbacks[a].callCallbacks(a),this._downedKeys["delete"](a)},d.prototype.onKeyPress=function(b,c){return this._keyPressCallbacks[b]||(this._keyPressCallbacks[b]=new a.Utils.CallbackSet),this._keyPressCallbacks[b].add(c),this},d.prototype.offKeyPress=function(a,b){return this._keyPressCallbacks[a]["delete"](b),0===this._keyPressCallbacks[a].size&&delete this._keyPressCallbacks[a],this},d.prototype.onKeyRelease=function(b,c){return this._keyReleaseCallbacks[b]||(this._keyReleaseCallbacks[b]=new a.Utils.CallbackSet),this._keyReleaseCallbacks[b].add(c),this},d.prototype.offKeyRelease=function(a,b){return this._keyReleaseCallbacks[a]["delete"](b),0===this._keyReleaseCallbacks[a].size&&delete this._keyReleaseCallbacks[a],this},d}(a.Interaction);c.Key=d}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.apply(this,arguments),this._overComponent=!1,this._pointerEnterCallbacks=new a.Utils.CallbackSet,this._pointerMoveCallbacks=new a.Utils.CallbackSet,this._pointerExitCallbacks=new a.Utils.CallbackSet,this._mouseMoveCallback=function(a){return b._handlePointerEvent(a)},this._touchStartCallback=function(a,c){return b._handlePointerEvent(c[a[0]])}}return b(d,c),d.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(this._componentAttachedTo.content().node()),this._mouseDispatcher.onMouseMove(this._mouseMoveCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(this._componentAttachedTo.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback)},d.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._mouseDispatcher.offMouseMove(this._mouseMoveCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher=null},d.prototype._handlePointerEvent=function(a){var b=this._translateToComponentSpace(a);if(this._isInsideComponent(b)){var c=this._overComponent;this._overComponent=!0,c||this._pointerEnterCallbacks.callCallbacks(b),this._pointerMoveCallbacks.callCallbacks(b)}else this._overComponent&&(this._overComponent=!1,this._pointerExitCallbacks.callCallbacks(b))},d.prototype.onPointerEnter=function(a){return this._pointerEnterCallbacks.add(a),this},d.prototype.offPointerEnter=function(a){return this._pointerEnterCallbacks["delete"](a),this},d.prototype.onPointerMove=function(a){return this._pointerMoveCallbacks.add(a),this},d.prototype.offPointerMove=function(a){return this._pointerMoveCallbacks["delete"](a),this},d.prototype.onPointerExit=function(a){return this._pointerExitCallbacks.add(a),this},d.prototype.offPointerExit=function(a){return this._pointerExitCallbacks["delete"](a),this},d}(a.Interaction);c.Pointer=d}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(b,e){var f=this;d.call(this),this._wheelCallback=function(a,b){return f._handleWheelEvent(a,b)},this._touchStartCallback=function(a,b,c){return f._handleTouchStart(a,b,c)},this._touchMoveCallback=function(a,b,c){return f._handlePinch(a,b,c)},this._touchEndCallback=function(a,b,c){return f._handleTouchEnd(a,b,c)},this._touchCancelCallback=function(a,b,c){return f._handleTouchEnd(a,b,c)},this._xScales=new a.Utils.Set,this._yScales=new a.Utils.Set,this._dragInteraction=new c.Drag,this._setupDragInteraction(),this._touchIds=d3.map(),this._minDomainExtents=new a.Utils.Map,this._maxDomainExtents=new a.Utils.Map,null!=b&&this.addXScale(b),null!=e&&this.addYScale(e)}return b(e,d),e.prototype._anchor=function(b){d.prototype._anchor.call(this,b),this._dragInteraction.attachTo(b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(this._componentAttachedTo.content().node()),this._mouseDispatcher.onWheel(this._wheelCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(this._componentAttachedTo.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback),this._touchDispatcher.onTouchMove(this._touchMoveCallback),this._touchDispatcher.onTouchEnd(this._touchEndCallback),this._touchDispatcher.onTouchCancel(this._touchCancelCallback)},e.prototype._unanchor=function(){d.prototype._unanchor.call(this),this._mouseDispatcher.offWheel(this._wheelCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher.offTouchMove(this._touchMoveCallback),this._touchDispatcher.offTouchEnd(this._touchEndCallback),this._touchDispatcher.offTouchCancel(this._touchCancelCallback),this._touchDispatcher=null,this._dragInteraction.detachFrom(this._componentAttachedTo)},e.prototype._handleTouchStart=function(a,b){for(var c=0;c1,d=c?this.maxDomainExtent(a):this.minDomainExtent(a);if(null==d)return b;var e=a.domain(),f=Math.abs(e[1]-e[0]),g=c?Math.min:Math.max;return g(b,d/f)},e.prototype._setupDragInteraction=function(){var a=this;this._dragInteraction.constrainedToComponent(!1);var b;this._dragInteraction.onDragStart(function(){return b=null}),this._dragInteraction.onDrag(function(c,d){if(!(a._touchIds.size()>=2)){var e=(null==b?c.x:b.x)-d.x;a.xScales().forEach(function(b){a._translateScale(b,e)});var f=(null==b?c.y:b.y)-d.y;a.yScales().forEach(function(b){a._translateScale(b,f)}),b=d}})},e.prototype._nonLinearScaleWithExtents=function(b){return!(null==this.minDomainExtent(b)||null==this.maxDomainExtent(b)||b instanceof a.Scales.Linear||b instanceof a.Scales.Time)},e.prototype.xScales=function(b){var c=this;if(null==b){var d=[];return this._xScales.forEach(function(a){d.push(a)}),d}return this._xScales=new a.Utils.Set,b.forEach(function(a){c.addXScale(a)}),this},e.prototype.yScales=function(b){var c=this;if(null==b){var d=[];return this._yScales.forEach(function(a){d.push(a)}),d}return this._yScales=new a.Utils.Set,b.forEach(function(a){c.addYScale(a)}),this},e.prototype.addXScale=function(a){return this._xScales.add(a),this},e.prototype.removeXScale=function(a){return this._xScales["delete"](a),this._minDomainExtents["delete"](a),this._maxDomainExtents["delete"](a),this},e.prototype.addYScale=function(a){return this._yScales.add(a),this},e.prototype.removeYScale=function(a){return this._yScales["delete"](a),this._minDomainExtents["delete"](a),this._maxDomainExtents["delete"](a),this},e.prototype.minDomainExtent=function(b,c){if(null==c)return this._minDomainExtents.get(b);if(c.valueOf()<0)throw new Error("extent must be non-negative");var d=this.maxDomainExtent(b);if(null!=d&&d.valueOf()a)throw new Error("detection radius cannot be negative.");return this._detectionRadius=a,this.render(),this},d.prototype.resizable=function(a){return null==a?this._resizable:(this._resizable=a,this._setResizableClasses(a),this)},d.prototype._setResizableClasses=function(a){a&&this.enabled()?(this.addClass("x-resizable"),this.addClass("y-resizable")):(this.removeClass("x-resizable"),this.removeClass("y-resizable"))},d.prototype.movable=function(a){return null==a?this._movable:(this._movable=a,this._setMovableClass(),this)},d.prototype._setMovableClass=function(){this.movable()&&this.enabled()?this.addClass("movable"):this.removeClass("movable")},d.prototype.onDragStart=function(a){return this._dragStartCallbacks.add(a),this},d.prototype.offDragStart=function(a){return this._dragStartCallbacks["delete"](a),this},d.prototype.onDrag=function(a){return this._dragCallbacks.add(a),this},d.prototype.offDrag=function(a){return this._dragCallbacks["delete"](a),this},d.prototype.onDragEnd=function(a){return this._dragEndCallbacks.add(a),this},d.prototype.offDragEnd=function(a){return this._dragEndCallbacks["delete"](a),this},d.prototype.dragInteraction=function(){return this._dragInteraction},d.prototype.enabled=function(a){return null==a?this._dragInteraction.enabled():(this._dragInteraction.enabled(a),this._setResizableClasses(this.resizable()),this._setMovableClass(),this)},d}(c.SelectionBoxLayer);c.DragBoxLayer=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.call(this),this.addClass("x-drag-box-layer"),this._hasCorners=!1}return b(c,a),c.prototype.computeLayout=function(b,c,d){return a.prototype.computeLayout.call(this,b,c,d),this.bounds(this.bounds()),this},c.prototype._setBounds=function(b){a.prototype._setBounds.call(this,{topLeft:{x:b.topLeft.x,y:0},bottomRight:{x:b.bottomRight.x,y:this.height()}})},c.prototype._setResizableClasses=function(a){a&&this.enabled()?this.addClass("x-resizable"):this.removeClass("x-resizable")},c.prototype.yScale=function(a){if(null==a)throw new Error("XDragBoxLayer has no yScale");throw new Error("yScales cannot be set on an XDragBoxLayer")},c.prototype.yExtent=function(){throw new Error("XDragBoxLayer has no yExtent")},c}(a.DragBoxLayer);a.XDragBoxLayer=c}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.call(this),this.addClass("y-drag-box-layer"),this._hasCorners=!1}return b(c,a),c.prototype.computeLayout=function(b,c,d){return a.prototype.computeLayout.call(this,b,c,d),this.bounds(this.bounds()),this},c.prototype._setBounds=function(b){a.prototype._setBounds.call(this,{topLeft:{x:0,y:b.topLeft.y},bottomRight:{x:this.width(),y:b.bottomRight.y}})},c.prototype._setResizableClasses=function(a){a&&this.enabled()?this.addClass("y-resizable"):this.removeClass("y-resizable")},c.prototype.xScale=function(a){if(null==a)throw new Error("YDragBoxLayer has no xScale");throw new Error("xScales cannot be set on an YDragBoxLayer")},c.prototype.xExtent=function(){throw new Error("YDragBoxLayer has no xExtent")},c}(a.DragBoxLayer);a.YDragBoxLayer=c}(c=a.Components||(a.Components={}))}(a||(a={}));var c;!function(a){var b;!function(a){var b;!function(a){function b(a,b){if(null==a||null==b)return a===b;if(a.length!==b.length)return!1;for(var c=0;c0&&"\n"===b[0]?"\n":"";if(g>=c){var i=g/3,j=Math.floor(c/i);return{wrappedToken:h+"...".substr(0,j),remainingToken:b}}for(;f+g>c;)e=a.Utils.StringMethods.trimEnd(e.substr(0,e.length-1)),f=d.measure(e).width;return{wrappedToken:h+e+"...",remainingToken:a.Utils.StringMethods.trimEnd(b.substring(e.length),"-").trim()}},b.prototype.wrapNextToken=function(b,c,d){if(!c.canFitText||c.availableLines===c.wrapping.noLines||!this.canFitToken(b,c.availableWidth,d))return this.finishWrapping(b,c,d);for(var e=b;e;){var f=this.breakTokenToFitInWidth(e,c.currentLine,c.availableWidth,d);if(c.currentLine=f.line,e=f.remainingToken,null!=e){if(c.wrapping.noBrokeWords+=+f.breakWord,++c.wrapping.noLines,c.availableLines===c.wrapping.noLines){var g=this.addEllipsis(c.currentLine,c.availableWidth,d);return c.wrapping.wrappedText+=g.wrappedToken,c.wrapping.truncatedText+=g.remainingToken+e,c.currentLine="\n",c}c.wrapping.wrappedText+=a.Utils.StringMethods.trimEnd(c.currentLine),c.currentLine="\n"}}return c},b.prototype.finishWrapping=function(a,b,c){if(b.canFitText&&b.availableLines!==b.wrapping.noLines&&this._allowBreakingWords&&"none"!==this._textTrimming){var d=this.addEllipsis(b.currentLine+a,b.availableWidth,c);b.wrapping.wrappedText+=d.wrappedToken,b.wrapping.truncatedText+=d.remainingToken,b.wrapping.noBrokeWords+=+(d.remainingToken.length0),b.currentLine=""}else b.wrapping.truncatedText+=a;return b.canFitText=!1,b},b.prototype.breakTokenToFitInWidth=function(a,b,c,d,e){if(void 0===e&&(e=this._breakingCharacter),d.measure(b+a).width<=c)return{remainingToken:null,line:b+a,breakWord:!1};if(""===a.trim())return{remainingToken:"",line:b,breakWord:!1};if(!this._allowBreakingWords)return{remainingToken:a,line:b,breakWord:!1};for(var f=0;f0&&(g=e),{remainingToken:a.substring(f),line:b+a.substring(0,f)+g,breakWord:f>0}},b}();b.Wrapper=c}(b=a.Wrappers||(a.Wrappers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.apply(this,arguments)}return b(c,a),c.prototype.wrap=function(b,d,e,f){var g=this;void 0===f&&(f=1/0);var h=b.split("\n");if(h.length>1)throw new Error("SingleLineWrapper is designed to work only on single line");var i=function(c){return a.prototype.wrap.call(g,b,d,c,f)},j=i(e);if(j.noLines<2)return j;for(var k=0,l=e,m=0;mk;++m){var n=(l+k)/2,o=i(n);this.areSameResults(j,o)?(l=n,j=o):k=n}return j},c.prototype.areSameResults=function(a,b){return a.noLines===b.noLines&&a.truncatedText===b.truncatedText},c.NO_WRAP_ITERATIONS=5,c}(a.Wrapper);a.SingleLineWrapper=c}(c=a.Wrappers||(a.Wrappers={}))}(c||(c={}));var c;!function(a){var b;!function(b){var c=function(){function b(a,c){this._writerID=b.nextID++,this._elementID=0,this.measurer(a),c&&this.wrapper(c),this.addTitleElement(!1)}return b.prototype.measurer=function(a){return this._measurer=a,this},b.prototype.wrapper=function(a){return this._wrapper=a,this},b.prototype.addTitleElement=function(a){return this._addTitleElement=a,this},b.prototype.writeLine=function(c,d,e,f,g){var h=d.append("text");h.text(c);var i=e*b.XOffsetFactor[f],j=b.AnchorConverter[f];h.attr("text-anchor",j).classed("text-line",!0),a.Utils.DOM.transform(h,i,g).attr("y","-0.25em")},b.prototype.writeText=function(a,c,d,e,f,g){var h=this,i=a.split("\n"),j=this._measurer.measure().height,k=b.YOffsetFactor[g]*(e-i.length*j);i.forEach(function(a,b){h.writeLine(a,c,d,f,(b+1)*j+k)})},b.prototype.write=function(a,c,d,e){if(-1===b.SupportedRotation.indexOf(e.textRotation))throw new Error("unsupported rotation - "+e.textRotation);var f=Math.abs(Math.abs(e.textRotation)-90)>45,g=f?c:d,h=f?d:c,i=e.selection.append("g").classed("text-container",!0);this._addTitleElement&&i.append("title").text(a);var j=i.append("g").classed("text-area",!0),k=this._wrapper?this._wrapper.wrap(a,this._measurer,g,h).wrappedText:a;this.writeText(k,j,g,h,e.xAlign,e.yAlign);var l=d3.transform(""),m=d3.transform("");switch(l.rotate=e.textRotation,e.textRotation){case 90:l.translate=[c,0],m.rotate=-90,m.translate=[0,200];break;case-90:l.translate=[0,d],m.rotate=90,m.translate=[c,0];break;case 180:l.translate=[c,d],m.translate=[c,d],m.rotate=180}j.attr("transform",l.toString()),this.addClipPath(i,m),e.animator&&e.animator.animate(i)},b.prototype.addClipPath=function(b){var c=this._elementID++,d=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;d=d.split("#")[0];var e="clipPath"+this._writerID+"_"+c;b.select(".text-area").attr("clip-path",'url("'+d+"#"+e+'")');var f=b.append("clipPath").attr("id",e),g=a.Utils.DOM.getBBox(b.select(".text-area")),h=f.append("rect");h.classed("clip-rect",!0).attr({x:g.x,y:g.y,width:g.width,height:g.height})},b.nextID=0,b.SupportedRotation=[-90,0,180,90],b.AnchorConverter={left:"start",center:"middle",right:"end"},b.XOffsetFactor={left:0,center:.5,right:1},b.YOffsetFactor={top:0,center:.5,bottom:1},b}();b.Writer=c}(b=a.Writers||(a.Writers={}))}(c||(c={}));var c;!function(a){var b;!function(b){var c=function(){function b(a,b){this.textMeasurer=this.getTextMeasurer(a,b)}return b.prototype.checkSelectionIsText=function(a){return"text"===a[0][0].tagName||!a.select("text").empty()},b.prototype.getTextMeasurer=function(a,b){var c=this;if(this.checkSelectionIsText(a)){var d,e=a.node().parentNode;return d="text"===a[0][0].tagName?a:a.select("text"),a.remove(),function(b){e.appendChild(a.node());var f=c.measureBBox(d,b);return a.remove(),f}}var f=a.append("text");return b&&f.classed(b,!0),f.remove(),function(b){a.node().appendChild(f.node());var d=c.measureBBox(f,b);return f.remove(),d}},b.prototype.measureBBox=function(b,c){b.text(c);var d=a.Utils.DOM.getBBox(b);return{width:d.width,height:d.height}},b.prototype.measure=function(a){return void 0===a&&(a=b.HEIGHT_TEXT),this.textMeasurer(a)},b.HEIGHT_TEXT="bqpdl",b}();b.AbstractMeasurer=c}(b=a.Measurers||(a.Measurers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(c){function d(a,b,d){void 0===b&&(b=null),void 0===d&&(d=!1),c.call(this,a,b),this.useGuards=d}return b(d,c),d.prototype._addGuards=function(b){return a.AbstractMeasurer.HEIGHT_TEXT+b+a.AbstractMeasurer.HEIGHT_TEXT},d.prototype.getGuardWidth=function(){return null==this.guardWidth&&(this.guardWidth=c.prototype.measure.call(this).width),this.guardWidth},d.prototype._measureLine=function(a){var b=this.useGuards?this._addGuards(a):a,d=c.prototype.measure.call(this,b);return d.width-=this.useGuards?2*this.getGuardWidth():0,d},d.prototype.measure=function(b){var c=this;if(void 0===b&&(b=a.AbstractMeasurer.HEIGHT_TEXT),""===b.trim())return{width:0,height:0};var d=b.trim().split("\n").map(function(a){return c._measureLine(a)});return{width:d3.max(d,function(a){return a.width}),height:d3.sum(d,function(a){return a.height})}},d}(a.AbstractMeasurer);a.Measurer=c}(c=a.Measurers||(a.Measurers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.apply(this,arguments)}return b(c,a),c.prototype._measureCharacter=function(b){return a.prototype._measureLine.call(this,b)},c.prototype._measureLine=function(a){var b=this,c=a.split("").map(function(a){return b._measureCharacter(a)});return{width:d3.sum(c,function(a){return a.width}),height:d3.max(c,function(a){return a.height})}},c}(a.Measurer);a.CharacterMeasurer=c}(c=a.Measurers||(a.Measurers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};return function(a){var c;!function(c){var d=function(c){function d(b,d){var e=this;c.call(this,b,d),this.cache=new a.Utils.Cache(function(a){return e._measureCharacterNotFromCache(a)},a.Utils.Methods.objEq)}return b(d,c),d.prototype._measureCharacterNotFromCache=function(a){return c.prototype._measureCharacter.call(this,a)},d.prototype._measureCharacter=function(a){return this.cache.get(a)},d.prototype.reset=function(){this.cache.clear()},d}(c.CharacterMeasurer);c.CacheCharacterMeasurer=d}(c=a.Measurers||(a.Measurers={}))}(c||(c={})),a}); \ No newline at end of file +!function(a,b){if("object"==typeof exports)module.exports=b(require,exports,module);else if("function"==typeof define&&define.amd)define(["require","exports","module"],b);else{var c=function(b){return a[b]},d=a,e={exports:d};a.Plottable=b(c,d,e)}}(this,function(){var a;!function(a){var b;!function(b){var c;!function(b){function c(a,b,c){return k.min(b,c)<=a&&a<=k.max(b,c)}function d(a,b,c){return k.min(k.max(b,a),c)}function e(a,b,c){var d="function"==typeof b?b:null,e=null==d?b:c,f=null==d?d3.max(a):d3.max(a,d);return void 0!==f?f:e}function f(a,b,c){var d="function"==typeof b?b:null,e=null==d?b:c,f=null==d?d3.min(a):d3.min(a,d);return void 0!==f?f:e}function g(a){return a!==a}function h(b){return"number"==typeof b&&!a.Utils.Math.isNaN(b)&&isFinite(b)}function i(a,b,c){if(void 0===c&&(c=1),0===c)throw new Error("step cannot be 0");for(var d=k.max(k.ceil((b-a)/c),0),e=[],f=0;d>f;++f)e[f]=a+c*f;return e}function j(a,b){return k.pow(b.y-a.y,2)+k.pow(b.x-a.x,2)}var k=window.Math;b.inRange=c,b.clamp=d,b.max=e,b.min=f,b.isNaN=g,b.isValidNumber=h,b.range=i,b.distanceSquared=j}(c=b.Math||(b.Math={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function b(){"function"==typeof window.Map?this._es6Map=new window.Map:this._keyValuePairs=[]}return b.prototype.set=function(b,c){if(a.Math.isNaN(b))throw new Error("NaN may not be used as a key to the Map");if(null!=this._es6Map)return this._es6Map.set(b,c),this;for(var d=0;db.right?!1:a.bottomb.bottom?!1:!0}function h(a,b){return n.floor(b.left)<=n.ceil(a.left)&&n.floor(b.top)<=n.ceil(a.top)&&n.floor(a.right)<=n.ceil(b.right)&&n.floor(a.bottom)<=n.ceil(b.bottom)}function i(a){var b=a.ownerSVGElement;return null!=b?b:"svg"===a.nodeName.toLowerCase()?a:null}function j(){return"plottableClipPath"+ ++o}function k(a,b,c,d){void 0===d&&(d=.5);var e=l(a),f=l(b);return c.x+c.width>=e.min-d&&c.x<=e.max+d&&c.y+c.height>=f.min-d&&c.y<=f.max+d}function l(a){if("number"==typeof a){var b=a;return{min:b,max:b}}var c=a;if(c instanceof Object&&"min"in c&&"max"in c)return c;throw new Error("input '"+a+"' can't be parsed as an Range")}function m(a,b){var c=a.getPropertyValue(b),d=parseFloat(c);return d||0}var n=window.Math;a.elementBBox=b,a.SCREEN_REFRESH_RATE_MILLISECONDS=1e3/60,a.requestAnimationFramePolyfill=c,a.elementWidth=d,a.elementHeight=e,a.translate=f,a.clientRectsOverlap=g,a.clientRectInside=h,a.boundingSVG=i;var o=0;a.generateUniqueClipPathId=j,a.intersectsBBox=k}(b=a.DOM||(a.DOM={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b;!function(a){function b(a,b){var c=e(a)+.05,d=e(b)+.05;return c>d?c/d:d/c}function c(a,b){var c=d3.hsl(a).brighter(b);return c.rgb().toString()}function d(a,b){a.classed(b,!0);var c=a.style("background-color");if("transparent"===c)return null;var d=/\((.+)\)/.exec(c)[1].split(",").map(function(a){var b=+a,c=b.toString(16);return 16>b?"0"+c:c});if(4===d.length&&"00"===d[3])return null;var e="#"+d.join("");return a.classed(b,!1),e}function e(a){var b=d3.rgb(a),c=function(a){return a/=255,.03928>=a?a/12.92:f.pow((a+.055)/1.055,2.4)},d=c(b.r),e=c(b.g),g=c(b.b);return.2126*d+.7152*e+.0722*g}var f=window.Math;a.contrast=b,a.lightenColor=c,a.colorTest=d}(b=a.Color||(a.Color={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b;!function(a){function b(a,b){if(a.length!==b.length)throw new Error("attempted to add arrays of unequal length");return a.map(function(c,d){return a[d]+b[d]})}function c(a){var b=d3.set(),c=[];return a.forEach(function(a){b.has(String(a))||(b.add(String(a)),c.push(a))}),c}function d(a){return f.prototype.concat.apply([],a)}function e(a,b){for(var c=[],d=0;b>d;d++)c[d]="function"==typeof a?a(d):a;return c}var f=window.Array;a.add=b,a.uniq=c,a.flatten=d,a.createFilledArray=e}(b=a.Array||(a.Array={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.apply(this,arguments)}return b(c,a),c.prototype.callCallbacks=function(){for(var a=this,b=[],c=0;c=0?f:g;m.has(k)?(j=m.get(k),m.set(k,j+l)):(j=0,m.set(k,l)),i.set(k,{value:l,offset:j})}),h.set(b,i)}),h}function d(b,c,d){var g=[];b.forEach(function(a,b){b.data().forEach(function(f,h){if(null==d||d(f,h,b)){var i=a.get(e(c(f,h,b)));g.push(i.value+i.offset)}})});var h=a.Math.max(g,0),i=a.Math.min(g,0);return[f.min(i,0),f.max(0,h)]}function e(a){return String(a)}var f=window.Math;b.stack=c,b.stackedExtent=d,b.normalizeKey=e}(b=a.Stacking||(a.Stacking={}))}(b=a.Utils||(a.Utils={}))}(a||(a={}));var a;!function(a){var b;!function(b){var c;!function(c){function d(b){a.Configs.SHOW_WARNINGS&&null!=window.console&&(null!=window.console.warn?console.warn(b):null!=window.console.log&&console.log(b))}function e(a,b){for(var c=[],d=2;da&&(b="-"+b)),b}}function d(a){return void 0===a&&(a=3),m(a),function(b){return b.toFixed(a)}}function e(a){return void 0===a&&(a=3),m(a),function(b){if("number"==typeof b){var c=Math.pow(10,a);return String(Math.round(b*c)/c)}return String(b)}}function f(){return function(a){return String(a)}}function g(a){void 0===a&&(a=0);var c=b.fixed(a);return function(a){var b=100*a,d=a.toString(),e=Math.pow(10,d.length-(d.indexOf(".")+1));return b=parseInt((b*e).toString(),10)/e,c(b)+"%"}}function h(a){return void 0===a&&(a=3),m(a),function(b){return d3.format("."+a+"s")(b)}}function i(a){void 0===a&&(a=3),m(a);var b="KMBTQ",c=d3.format("."+a+"e"),d=d3.format("."+a+"f"),e=Math.pow(10,3*(b.length+1)),f=Math.pow(10,-a);return function(a){var g=Math.abs(a);if((f>g||g>=e)&&0!==g)return c(a);for(var h=-1;g>=Math.pow(1e3,h+2)&&h0&&"1000"===i.substr(0,4)||0>a&&"-1000"===i.substr(0,5))&&(hd;d++)if(b[d].filter(c))return d3.time.format(b[d].format)(c)}}function k(a){return d3.time.format(a)}function l(b,c,d){return void 0===b&&(b=0),void 0===c&&(c=a.MILLISECONDS_IN_ONE_DAY),void 0===d&&(d=""),a.Utils.Window.deprecated("relativeDate()","1.3","Not safe for use with time zones."),function(a){var e=Math.round((a.valueOf()-b)/c);return e.toString()+d}}function m(a){if(0>a||a>20)throw new RangeError("Formatter precision must be between 0 and 20");if(a!==Math.floor(a))throw new RangeError("Formatter precision must be an integer")}b.currency=c,b.fixed=d,b.general=e,b.identity=f,b.percentage=g,b.siSuffix=h,b.shortScale=i,b.multiTime=j,b.time=k,b.relativeDate=l}(b=a.Formatters||(a.Formatters={}))}(a||(a={}));var a;!function(a){var b;!function(a){function b(){return function(a){return d3.svg.symbol().type("circle").size(Math.PI*Math.pow(a/2,2))(null)}}function c(){return function(a){return d3.svg.symbol().type("square").size(Math.pow(a,2))(null)}}function d(){return function(a){return d3.svg.symbol().type("cross").size(5/9*Math.pow(a,2))(null)}}function e(){return function(a){return d3.svg.symbol().type("diamond").size(Math.tan(Math.PI/6)*Math.pow(a,2)/2)(null)}}function f(){return function(a){return d3.svg.symbol().type("triangle-up").size(Math.sqrt(3)*Math.pow(a/2,2))(null)}}function g(){return function(a){return d3.svg.symbol().type("triangle-down").size(Math.sqrt(3)*Math.pow(a/2,2))(null)}}a.circle=b,a.square=c,a.cross=d,a.diamond=e,a.triangleUp=f,a.triangleDown=g}(b=a.SymbolFactories||(a.SymbolFactories={}))}(a||(a={}));var a;!function(a){var b=function(){function b(){this._autoDomainAutomatically=!0,this._domainModificationInProgress=!1,this._callbacks=new a.Utils.CallbackSet,this._includedValuesProviders=new a.Utils.Set}return b.prototype.extentOfValues=function(){return[]},b.prototype._getAllIncludedValues=function(){var a=this,b=[];return this._includedValuesProviders.forEach(function(c){var d=c(a);b=b.concat(d)}),b},b.prototype._getExtent=function(){return[]},b.prototype.onUpdate=function(a){return this._callbacks.add(a),this},b.prototype.offUpdate=function(a){return this._callbacks["delete"](a),this},b.prototype._dispatchUpdate=function(){this._callbacks.callCallbacks(this)},b.prototype.autoDomain=function(){return this._autoDomainAutomatically=!0,this._setDomain(this._getExtent()),this},b.prototype._autoDomainIfAutomaticMode=function(){this._autoDomainAutomatically&&this.autoDomain()},b.prototype.scale=function(){throw new Error("Subclasses should override scale")},b.prototype.domain=function(a){return null==a?this._getDomain():(this._autoDomainAutomatically=!1,this._setDomain(a),this)},b.prototype._getDomain=function(){throw new Error("Subclasses should override _getDomain")},b.prototype._setDomain=function(a){this._domainModificationInProgress||(this._domainModificationInProgress=!0,this._setBackingScaleDomain(a),this._dispatchUpdate(),this._domainModificationInProgress=!1)},b.prototype._setBackingScaleDomain=function(){throw new Error("Subclasses should override _setBackingDomain")},b.prototype.range=function(a){return null==a?this._getRange():(this._setRange(a),this)},b.prototype._getRange=function(){throw new Error("Subclasses should override _getRange")},b.prototype._setRange=function(){throw new Error("Subclasses should override _setRange")},b.prototype.addIncludedValuesProvider=function(a){return this._includedValuesProviders.add(a),this._autoDomainIfAutomaticMode(),this},b.prototype.removeIncludedValuesProvider=function(a){return this._includedValuesProviders["delete"](a),this._autoDomainIfAutomaticMode(),this},b}();a.Scale=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c=function(c){function d(){c.call(this),this._tickGenerator=function(a){return a.defaultTicks()},this._padProportion=.05,this._snappingDomainEnabled=!0,this._paddingExceptionsProviders=new a.Utils.Set}return b(d,c),d.prototype.autoDomain=function(){return this._domainMin=null,this._domainMax=null,c.prototype.autoDomain.call(this),this},d.prototype._autoDomainIfAutomaticMode=function(){if(null!=this._domainMin&&null!=this._domainMax)return void this._setDomain([this._domainMin,this._domainMax]);var a=this._getExtent();if(null!=this._domainMin){var b=a[1];return this._domainMin>=b&&(b=this._expandSingleValueDomain([this._domainMin,this._domainMin])[1]),void this._setDomain([this._domainMin,b])}if(null!=this._domainMax){var d=a[0];return this._domainMax<=d&&(d=this._expandSingleValueDomain([this._domainMax,this._domainMax])[0]),void this._setDomain([d,this._domainMax])}c.prototype._autoDomainIfAutomaticMode.call(this)},d.prototype._getExtent=function(){var b=this._getAllIncludedValues(),c=this._defaultExtent();if(0!==b.length){var d=[a.Utils.Math.min(b,c[0]),a.Utils.Math.max(b,c[1])];c=this._padDomain(d)}return null!=this._domainMin&&(c[0]=this._domainMin),null!=this._domainMax&&(c[1]=this._domainMax),c},d.prototype.addPaddingExceptionsProvider=function(a){return this._paddingExceptionsProviders.add(a),this._autoDomainIfAutomaticMode(),this},d.prototype.removePaddingExceptionsProvider=function(a){return this._paddingExceptionsProviders["delete"](a),this._autoDomainIfAutomaticMode(),this},d.prototype.padProportion=function(a){if(null==a)return this._padProportion;if(0>a)throw new Error("padProportion must be non-negative");return this._padProportion=a,this._autoDomainIfAutomaticMode(),this},d.prototype._padDomain=function(a){var b=this;if(a[0].valueOf()===a[1].valueOf())return this._expandSingleValueDomain(a);if(0===this._padProportion)return a;var c=this._padProportion/2,d=a[0],e=a[1],f=!1,g=!1;this._paddingExceptionsProviders.forEach(function(a){var c=a(b);c.forEach(function(a){a.valueOf()===d.valueOf()&&(f=!0),a.valueOf()===e.valueOf()&&(g=!0)})});var h=f?d:this.invert(this.scale(d)-(this.scale(e)-this.scale(d))*c),i=g?e:this.invert(this.scale(e)+(this.scale(e)-this.scale(d))*c);return this._snappingDomainEnabled?this._niceDomain([h,i]):[h,i]},d.prototype.snappingDomainEnabled=function(a){return null==a?this._snappingDomainEnabled:(this._snappingDomainEnabled=a,this._autoDomainIfAutomaticMode(),this)},d.prototype._expandSingleValueDomain=function(a){return a},d.prototype.invert=function(){throw new Error("Subclasses should override invert")},d.prototype.domain=function(a){return null!=a&&(this._domainMin=a[0],this._domainMax=a[1]),c.prototype.domain.call(this,a)},d.prototype.domainMin=function(a){return null==a?this.domain()[0]:(this._domainMin=a,this._autoDomainIfAutomaticMode(),this)},d.prototype.domainMax=function(a){return null==a?this.domain()[1]:(this._domainMax=a,this._autoDomainIfAutomaticMode(),this)},d.prototype.extentOfValues=function(b){var c=d3.extent(b.filter(function(b){return a.Utils.Math.isValidNumber(+b)}));return null==c[0]||null==c[1]?[]:c},d.prototype._setDomain=function(b){var d=function(b){return a.Utils.Math.isNaN(b)||1/0===b||b===-1/0};return d(b[0])||d(b[1])?void a.Utils.Window.warn("Warning: QuantitativeScales cannot take NaN or Infinity as a domain value. Ignoring."):void c.prototype._setDomain.call(this,b)},d.prototype.defaultTicks=function(){throw new Error("Subclasses should override _getDefaultTicks")},d.prototype.ticks=function(){return this._tickGenerator(this)},d.prototype._niceDomain=function(){throw new Error("Subclasses should override _niceDomain")},d.prototype._defaultExtent=function(){throw new Error("Subclasses should override _defaultExtent")},d.prototype.tickGenerator=function(a){return null==a?this._tickGenerator:(this._tickGenerator=a,this)},d._DEFAULT_NUM_TICKS=10,d}(a.Scale);a.QuantitativeScale=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function d(){a.call(this),this._d3Scale=d3.scale.linear()}return b(d,a),d.prototype._defaultExtent=function(){return[0,1]},d.prototype._expandSingleValueDomain=function(a){return a[0]===a[1]?[a[0]-1,a[1]+1]:a},d.prototype.scale=function(a){return this._d3Scale(a)},d.prototype._getDomain=function(){return this._d3Scale.domain()},d.prototype._setBackingScaleDomain=function(a){this._d3Scale.domain(a)},d.prototype._getRange=function(){return this._d3Scale.range()},d.prototype._setRange=function(a){this._d3Scale.range(a)},d.prototype.invert=function(a){return this._d3Scale.invert(a)},d.prototype.defaultTicks=function(){return this._d3Scale.ticks(c.Linear._DEFAULT_NUM_TICKS)},d.prototype._niceDomain=function(a,b){return this._d3Scale.copy().domain(a).nice(b).domain()},d}(a.QuantitativeScale);c.Linear=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(a){if(void 0===a&&(a=10),d.call(this),this._d3Scale=d3.scale.linear(),this._base=a,this._pivot=this._base,this._setDomain(this._defaultExtent()),1>=a)throw new Error("ModifiedLogScale: The base must be > 1")}return b(e,d),e.prototype._adjustedLog=function(a){var b=0>a?-1:1;return a*=b,aa?-1:1;return a*=b,a=Math.pow(this._base,a),a=b&&c>=a}),n=m.sort(function(a,b){return a-b});return n},e.prototype._howManyTicks=function(b,d){var e=this._adjustedLog(a.Utils.Math.min(this._untransformedDomain,0)),f=this._adjustedLog(a.Utils.Math.max(this._untransformedDomain,0)),g=this._adjustedLog(b),h=this._adjustedLog(d),i=(h-g)/(f-e),j=Math.ceil(i*c.ModifiedLog._DEFAULT_NUM_TICKS);return j},e.prototype._niceDomain=function(a){return a},e.prototype._defaultExtent=function(){return[0,this._base]},e.prototype._expandSingleValueDomain=function(a){if(a[0]===a[1]){var b=a[0];return b>0?[b/this._base,b*this._base]:0===b?[-this._base,this._base]:[b*this._base,b/this._base]}return a},e.prototype._getRange=function(){return this._d3Scale.range()},e.prototype._setRange=function(a){this._d3Scale.range(a)},e.prototype.defaultTicks=function(){return this._d3Scale.ticks(c.ModifiedLog._DEFAULT_NUM_TICKS)},e}(a.QuantitativeScale);c.ModifiedLog=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){c.call(this),this._range=[0,1],this._d3Scale=d3.scale.ordinal();var a=.3;this._innerPadding=d._convertToPlottableInnerPadding(a),this._outerPadding=d._convertToPlottableOuterPadding(.5,a)}return b(d,c),d.prototype.extentOfValues=function(b){return a.Utils.Array.uniq(b)},d.prototype._getExtent=function(){return a.Utils.Array.uniq(this._getAllIncludedValues())},d.prototype.domain=function(a){return c.prototype.domain.call(this,a)},d.prototype._setDomain=function(a){c.prototype._setDomain.call(this,a),this.range(this.range())},d.prototype.range=function(a){if(null==a)return this._range;this._range=a;var b=1-1/(1+this.innerPadding()),c=this.outerPadding()/(1+this.innerPadding());return this._d3Scale.rangeBands(a,b,c),this},d._convertToPlottableInnerPadding=function(a){return 1/(1-a)-1},d._convertToPlottableOuterPadding=function(a,b){return a/(1-b)},d.prototype.rangeBand=function(){return this._d3Scale.rangeBand()},d.prototype.stepWidth=function(){return this.rangeBand()*(1+this.innerPadding())},d.prototype.innerPadding=function(a){return null==a?this._innerPadding:(this._innerPadding=a,this.range(this.range()),this._dispatchUpdate(),this)},d.prototype.outerPadding=function(a){return null==a?this._outerPadding:(this._outerPadding=a,this.range(this.range()),this._dispatchUpdate(),this)},d.prototype.scale=function(a){return this._d3Scale(a)+this.rangeBand()/2},d.prototype._getDomain=function(){return this._d3Scale.domain()},d.prototype._setBackingScaleDomain=function(a){this._d3Scale.domain(a)},d.prototype._getRange=function(){return this._d3Scale.range()},d.prototype._setRange=function(a){this._d3Scale.range(a)},d}(a.Scale);c.Category=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(a){c.call(this);var b;switch(a){case null:case void 0:null==d._plottableColorCache&&(d._plottableColorCache=d._getPlottableColors()),b=d3.scale.ordinal().range(d._plottableColorCache);break;case"Category10":case"category10":case"10":b=d3.scale.category10();break;case"Category20":case"category20":case"20":b=d3.scale.category20();break;case"Category20b":case"category20b":case"20b":b=d3.scale.category20b();break;case"Category20c":case"category20c":case"20c":b=d3.scale.category20c();break;default:throw new Error("Unsupported ColorScale type")}this._d3Scale=b}return b(d,c),d.prototype.extentOfValues=function(b){return a.Utils.Array.uniq(b)},d.prototype._getExtent=function(){return a.Utils.Array.uniq(this._getAllIncludedValues())},d.invalidateColorCache=function(){d._plottableColorCache=null},d._getPlottableColors=function(){for(var b,c=[],d=d3.select("body").append("plottable-color-tester"),e=a.Utils.Color.colorTest(d,""),f=0;null!==(b=a.Utils.Color.colorTest(d,"plottable-colors-"+f))&&f0&&this._setDomain([a.Utils.Math.min(b,0),a.Utils.Math.max(b,0)]),this},d.prototype.scale=function(a){return this._d3Scale(a)},d.prototype._getDomain=function(){return this._d3Scale.domain()},d.prototype._setBackingScaleDomain=function(a){this._d3Scale.domain(a)},d.prototype._getRange=function(){return this._colorRange},d.prototype._setRange=function(a){this._colorRange=a,this._resetScale()},d.REDS=["#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"],d.BLUES=["#FFFFFF","#CCFFFF","#A5FFFD","#85F7FB","#6ED3EF","#55A7E0","#417FD0","#2545D3","#0B02E1"],d.POSNEG=["#0B02E1","#2545D3","#417FD0","#55A7E0","#6ED3EF","#85F7FB","#A5FFFD","#CCFFFF","#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"],d}(a.Scale);c.InterpolatedColor=d}(c=a.Scales||(a.Scales={}))}(a||(a={}));var a;!function(a){var b;!function(b){var c;!function(b){function c(b){if(0>=b)throw new Error("interval must be positive number");return function(c){var d=c.domain(),e=Math.min(d[0],d[1]),f=Math.max(d[0],d[1]),g=Math.ceil(e/b)*b,h=Math.floor((f-g)/b)+1,i=e%b===0?[]:[e],j=a.Utils.Math.range(0,h).map(function(a){return g+a*b}),k=f%b===0?[]:[f];return i.concat(j).concat(k)}}function d(){return function(a){var b=a.defaultTicks();return b.filter(function(a,c){return a%1===0||0===c||c===b.length-1})}}b.intervalTickGenerator=c,b.integerTickGenerator=d}(c=b.TickGenerators||(b.TickGenerators={}))}(b=a.Scales||(a.Scales={}))}(a||(a={}));var a;!function(a){var b=function(){function b(a){this._cachedSelectionValid=!1,this._dataset=a}return b.prototype.renderArea=function(a){return null==a?this._renderArea:(this._renderArea=a,this._cachedSelectionValid=!1,this)},b.prototype.remove=function(){null!=this.renderArea()&&this.renderArea().remove()},b.prototype._bindSelectionData=function(a){var b=this.selection().data(a);b.enter().append(this._svgElementName),b.exit().remove(),this._applyDefaultAttributes(b)},b.prototype._applyDefaultAttributes=function(a){null!=this._className&&a.classed(this._className,!0)},b.prototype._drawStep=function(a){var b=this.selection(),c=["fill","stroke"];c.forEach(function(c){null!=a.attrToAppliedProjector[c]&&b.attr(c,a.attrToAppliedProjector[c])}),a.animator.animate(b,a.attrToAppliedProjector),null!=this._className&&this.selection().classed(this._className,!0)},b.prototype._appliedProjectors=function(a){var b=this,c={};return Object.keys(a).forEach(function(d){c[d]=function(c,e){return a[d](c,e,b._dataset)}}),c},b.prototype.totalDrawTime=function(a,b){var c=0;return b.forEach(function(b){c+=b.animator.totalTime(a.length)}),c},b.prototype.draw=function(b,c){var d=this,e=c.map(function(a){var b=d._appliedProjectors(a.attrToProjector);return{attrToAppliedProjector:b,animator:a.animator}});this._bindSelectionData(b),this._cachedSelectionValid=!1;var f=0;return e.forEach(function(c){a.Utils.Window.setTimeout(function(){return d._drawStep(c)},f),f+=c.animator.totalTime(b.length)}),this},b.prototype.selection=function(){return this._cachedSelectionValid||(this._cachedSelection=this.renderArea().selectAll(this.selector()),this._cachedSelectionValid=!0),this._cachedSelection},b.prototype.selector=function(){return this._svgElementName},b.prototype.selectionForIndex=function(a){return d3.select(this.selection()[0][a])},b}();a.Drawer=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="line",this._svgElementName="path"}return b(c,a),c.prototype._applyDefaultAttributes=function(b){a.prototype._applyDefaultAttributes.call(this,b),b.style("fill","none")},c.prototype.selectionForIndex=function(){return d3.select(this.selection()[0][0])},c}(a.Drawer);c.Line=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="area",this._svgElementName="path"}return b(c,a),c.prototype._applyDefaultAttributes=function(b){a.prototype._applyDefaultAttributes.call(this,b),b.style("stroke","none")},c.prototype.selectionForIndex=function(){return d3.select(this.selection()[0][0])},c}(a.Drawer);c.Area=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._svgElementName="rect"}return b(c,a),c}(a.Drawer);c.Rectangle=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="arc fill",this._svgElementName="path"}return b(c,a),c.prototype._applyDefaultAttributes=function(b){a.prototype._applyDefaultAttributes.call(this,b),b.style("stroke","none")},c}(a.Drawer);c.Arc=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._className="arc outline",this._svgElementName="path"}return b(c,a),c.prototype._applyDefaultAttributes=function(b){a.prototype._applyDefaultAttributes.call(this,b),b.style("fill","none")},c}(a.Drawer);c.ArcOutline=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._svgElementName="path",this._className="symbol"}return b(c,a),c}(a.Drawer);c.Symbol=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(b){a.call(this,b),this._svgElementName="line"}return b(c,a),c}(a.Drawer);c.Segment=d}(c=a.Drawers||(a.Drawers={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function a(){}return a.TOP="top",a.BOTTOM="bottom",a.LEFT="left",a.RIGHT="right",a.CENTER="center",a}();a.Alignment=b}(b=a.Components||(a.Components={}));var c=function(){function b(){this._clipPathEnabled=!1,this._origin={x:0,y:0},this._xAlignment="left",this._yAlignment="top",this._isSetup=!1,this._isAnchored=!1,this._boxes=[],this._isTopLevelComponent=!1,this._cssClasses=new a.Utils.Set,this._destroyed=!1,this._onAnchorCallbacks=new a.Utils.CallbackSet,this._onDetachCallbacks=new a.Utils.CallbackSet,this._cssClasses.add("component")}return b.prototype.anchor=function(a){if(this._destroyed)throw new Error("Can't reuse destroy()-ed Components!");return"svg"===a.node().nodeName.toLowerCase()&&(this._rootSVG=a,this._rootSVG.classed("plottable",!0),this._rootSVG.style("overflow","visible"),this._isTopLevelComponent=!0),null!=this._element?a.node().appendChild(this._element.node()):(this._element=a.append("g"),this._setup()),this._isAnchored=!0,this._onAnchorCallbacks.callCallbacks(this),this},b.prototype.onAnchor=function(a){return this._isAnchored&&a(this),this._onAnchorCallbacks.add(a),this},b.prototype.offAnchor=function(a){return this._onAnchorCallbacks["delete"](a),this},b.prototype._setup=function(){var b=this;this._isSetup||(this._cssClasses.forEach(function(a){b._element.classed(a,!0)}),this._cssClasses=new a.Utils.Set,this._backgroundContainer=this._element.append("g").classed("background-container",!0),this._addBox("background-fill",this._backgroundContainer),this._content=this._element.append("g").classed("content",!0),this._foregroundContainer=this._element.append("g").classed("foreground-container",!0),this._boxContainer=this._element.append("g").classed("box-container",!0),this._clipPathEnabled&&this._generateClipPath(),this._boundingBox=this._addBox("bounding-box"),this._isSetup=!0)},b.prototype.requestedSpace=function(){return{minWidth:0,minHeight:0}},b.prototype.computeLayout=function(c,d,e){var f=this;if(null==c||null==d||null==e){if(null==this._element)throw new Error("anchor() must be called before computeLayout()");if(!this._isTopLevelComponent)throw new Error("null arguments cannot be passed to computeLayout() on a non-root node");c={x:0,y:0},null==this._rootSVG.attr("width")&&this._rootSVG.attr("width","100%"),null==this._rootSVG.attr("height")&&this._rootSVG.attr("height","100%");var g=this._rootSVG.node();d=a.Utils.DOM.elementWidth(g),e=a.Utils.DOM.elementHeight(g)}var h=this._sizeFromOffer(d,e);this._width=h.width,this._height=h.height;var i=b._xAlignToProportion[this._xAlignment],j=b._yAlignToProportion[this._yAlignment];return this._origin={x:c.x+(d-this.width())*i,y:c.y+(e-this.height())*j},this._element.attr("transform","translate("+this._origin.x+","+this._origin.y+")"),this._boxes.forEach(function(a){return a.attr("width",f.width()).attr("height",f.height())}),this},b.prototype._sizeFromOffer=function(a,b){var c=this.requestedSpace(a,b);return{width:this.fixedWidth()?Math.min(a,c.minWidth):a,height:this.fixedHeight()?Math.min(b,c.minHeight):b}},b.prototype.render=function(){return this._isAnchored&&this._isSetup&&this.width()>=0&&this.height()>=0&&a.RenderController.registerToRender(this),this},b.prototype._scheduleComputeLayout=function(){this._isAnchored&&this._isSetup&&a.RenderController.registerToComputeLayout(this)},b.prototype.renderImmediately=function(){return this},b.prototype.redraw=function(){return this._isAnchored&&this._isSetup&&(this._isTopLevelComponent?this._scheduleComputeLayout():this.parent().redraw()),this},b.prototype.renderTo=function(b){if(this.detach(),null!=b){var c;if(c="string"==typeof b?d3.select(b):b,!c.node()||"svg"!==c.node().nodeName.toLowerCase())throw new Error("Plottable requires a valid SVG to renderTo");this.anchor(c)}if(null==this._element)throw new Error("If a Component has never been rendered before, then renderTo must be given a node to render to, or a d3.Selection, or a selector string");return this.computeLayout(),this.render(),a.RenderController.flush(),this},b.prototype.xAlignment=function(a){if(null==a)return this._xAlignment;if(a=a.toLowerCase(),null==b._xAlignToProportion[a])throw new Error("Unsupported alignment: "+a);return this._xAlignment=a,this.redraw(),this},b.prototype.yAlignment=function(a){if(null==a)return this._yAlignment;if(a=a.toLowerCase(),null==b._yAlignToProportion[a])throw new Error("Unsupported alignment: "+a);return this._yAlignment=a,this.redraw(),this},b.prototype._addBox=function(a,b){if(null==this._element)throw new Error("Adding boxes before anchoring is currently disallowed");b=null==b?this._boxContainer:b;var c=b.append("rect");return null!=a&&c.classed(a,!0),this._boxes.push(c),null!=this.width()&&null!=this.height()&&c.attr("width",this.width()).attr("height",this.height()),c},b.prototype._generateClipPath=function(){var b=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;b=b.split("#")[0];var c=a.Utils.DOM.generateUniqueClipPathId();this._element.attr("clip-path",'url("'+b+"#"+c+'")');var d=this._boxContainer.append("clipPath").attr("id",c);this._addBox("clip-rect",d)},b.prototype.hasClass=function(a){return null==a?!1:null==this._element?this._cssClasses.has(a):this._element.classed(a)},b.prototype.addClass=function(a){return null==a?this:(null==this._element?this._cssClasses.add(a):this._element.classed(a,!0),this)},b.prototype.removeClass=function(a){return null==a?this:(null==this._element?this._cssClasses["delete"](a):this._element.classed(a,!1),this)},b.prototype.fixedWidth=function(){return!1},b.prototype.fixedHeight=function(){return!1},b.prototype.detach=function(){return this.parent(null),this._isAnchored&&this._element.remove(),this._isAnchored=!1,this._onDetachCallbacks.callCallbacks(this),this},b.prototype.onDetach=function(a){return this._onDetachCallbacks.add(a),this},b.prototype.offDetach=function(a){return this._onDetachCallbacks["delete"](a),this},b.prototype.parent=function(a){if(void 0===a)return this._parent;if(null!==a&&!a.has(this))throw new Error("Passed invalid parent");return this._parent=a,this},b.prototype.destroy=function(){this._destroyed=!0,this.detach()},b.prototype.width=function(){return this._width},b.prototype.height=function(){return this._height},b.prototype.origin=function(){return{x:this._origin.x,y:this._origin.y}},b.prototype.originToSVG=function(){for(var a=this.origin(),b=this.parent();null!=b;){var c=b.origin();a.x+=c.x,a.y+=c.y,b=b.parent()}return a},b.prototype.foreground=function(){return this._foregroundContainer},b.prototype.content=function(){return this._content},b.prototype.background=function(){return this._backgroundContainer},b._xAlignToProportion={left:0,center:.5,right:1},b._yAlignToProportion={top:0,center:.5,bottom:1},b}();a.Component=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c=function(a){function c(){var b=this;a.call(this),this._detachCallback=function(a){return b.remove(a)}}return b(c,a),c.prototype.anchor=function(b){var c=this;return a.prototype.anchor.call(this,b),this._forEach(function(a){return a.anchor(c.content())}),this},c.prototype.render=function(){return this._forEach(function(a){return a.render()}),this},c.prototype.has=function(){throw new Error("has() is not implemented on ComponentContainer")},c.prototype._adoptAndAnchor=function(a){a.parent(this),a.onDetach(this._detachCallback),this._isAnchored&&a.anchor(this.content())},c.prototype.remove=function(a){return this.has(a)&&(a.offDetach(this._detachCallback),this._remove(a),a.detach(),this.redraw()),this},c.prototype._remove=function(){return!1},c.prototype._forEach=function(){throw new Error("_forEach() is not implemented on ComponentContainer")},c.prototype.destroy=function(){a.prototype.destroy.call(this),this._forEach(function(a){return a.destroy()})},c}(a.Component);a.ComponentContainer=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(a){var b=this;void 0===a&&(a=[]),c.call(this),this._components=[],this.addClass("component-group"),a.forEach(function(a){return b.append(a)})}return b(d,c),d.prototype._forEach=function(a){this.components().forEach(a)},d.prototype.has=function(a){return this._components.indexOf(a)>=0},d.prototype.requestedSpace=function(b,c){var d=this._components.map(function(a){return a.requestedSpace(b,c)});return{minWidth:a.Utils.Math.max(d,function(a){return a.minWidth},0),minHeight:a.Utils.Math.max(d,function(a){return a.minHeight},0)}},d.prototype.computeLayout=function(a,b,d){var e=this;return c.prototype.computeLayout.call(this,a,b,d),this._forEach(function(a){a.computeLayout({x:0,y:0},e.width(),e.height())}),this},d.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}},d.prototype.fixedWidth=function(){return this._components.every(function(a){return a.fixedWidth()})},d.prototype.fixedHeight=function(){return this._components.every(function(a){return a.fixedHeight()})},d.prototype.components=function(){return this._components.slice()},d.prototype.append=function(a){return null==a||this.has(a)||(a.detach(),this._components.push(a),this._adoptAndAnchor(a),this.redraw()),this},d.prototype._remove=function(a){var b=this._components.indexOf(a);return b>=0?(this._components.splice(b,1),!0):!1},d}(a.ComponentContainer);c.Group=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c=function(c){function d(b,d){var e=this;if(c.call(this),this._endTickLength=5,this._innerTickLength=5,this._tickLabelPadding=10,this._margin=15,this._showEndTickLabels=!1,null==b||null==d)throw new Error("Axis requires a scale and orientation");this._scale=b,this.orientation(d),this._setDefaultAlignment(),this.addClass("axis"),this.addClass(this._isHorizontal()?"x-axis":"y-axis"),this.formatter(a.Formatters.identity()),this._rescaleCallback=function(){return e._rescale()},this._scale.onUpdate(this._rescaleCallback)}return b(d,c),d.prototype.destroy=function(){c.prototype.destroy.call(this),this._scale.offUpdate(this._rescaleCallback)},d.prototype._isHorizontal=function(){return"top"===this._orientation||"bottom"===this._orientation},d.prototype._computeWidth=function(){return this._computedWidth=this._maxLabelTickLength(),this._computedWidth},d.prototype._computeHeight=function(){return this._computedHeight=this._maxLabelTickLength(),this._computedHeight},d.prototype.requestedSpace=function(){var a=0,b=0;return this._isHorizontal()?(null==this._computedHeight&&this._computeHeight(),b=this._computedHeight+this._margin):(null==this._computedWidth&&this._computeWidth(),a=this._computedWidth+this._margin),{minWidth:a,minHeight:b}},d.prototype.fixedHeight=function(){return this._isHorizontal()},d.prototype.fixedWidth=function(){return!this._isHorizontal()},d.prototype._rescale=function(){this.render()},d.prototype.computeLayout=function(a,b,d){return c.prototype.computeLayout.call(this,a,b,d),this._scale.range(this._isHorizontal()?[0,this.width()]:[this.height(),0]),this},d.prototype._setup=function(){c.prototype._setup.call(this),this._tickMarkContainer=this.content().append("g").classed(d.TICK_MARK_CLASS+"-container",!0),this._tickLabelContainer=this.content().append("g").classed(d.TICK_LABEL_CLASS+"-container",!0),this._baseline=this.content().append("line").classed("baseline",!0)},d.prototype._getTickValues=function(){return[]},d.prototype.renderImmediately=function(){var a=this._getTickValues(),b=this._tickMarkContainer.selectAll("."+d.TICK_MARK_CLASS).data(a);return b.enter().append("line").classed(d.TICK_MARK_CLASS,!0),b.attr(this._generateTickMarkAttrHash()),d3.select(b[0][0]).classed(d.END_TICK_MARK_CLASS,!0).attr(this._generateTickMarkAttrHash(!0)),d3.select(b[0][a.length-1]).classed(d.END_TICK_MARK_CLASS,!0).attr(this._generateTickMarkAttrHash(!0)),b.exit().remove(),this._baseline.attr(this._generateBaselineAttrHash()),this},d.prototype._generateBaselineAttrHash=function(){var a={x1:0,y1:0,x2:0,y2:0};switch(this._orientation){case"bottom":a.x2=this.width();break;case"top":a.x2=this.width(),a.y1=this.height(),a.y2=this.height();break;case"left":a.x1=this.width(),a.x2=this.width(),a.y2=this.height();break;case"right":a.y2=this.height()}return a},d.prototype._generateTickMarkAttrHash=function(a){var b=this;void 0===a&&(a=!1);var c={x1:0,y1:0,x2:0,y2:0},d=function(a){return b._scale.scale(a)};this._isHorizontal()?(c.x1=d,c.x2=d):(c.y1=d,c.y2=d);var e=a?this._endTickLength:this._innerTickLength;switch(this._orientation){case"bottom":c.y2=e;break;case"top":c.y1=this.height(),c.y2=this.height()-e;break;case"left":c.x1=this.width(),c.x2=this.width()-e;break;case"right":c.x2=e}return c},d.prototype.redraw=function(){return this._computedWidth=null,this._computedHeight=null,c.prototype.redraw.call(this)},d.prototype._setDefaultAlignment=function(){switch(this._orientation){case"bottom":this.yAlignment("top");break;case"top":this.yAlignment("bottom");break;case"left":this.xAlignment("right");break;case"right":this.xAlignment("left")}},d.prototype.formatter=function(a){return null==a?this._formatter:(this._formatter=a,this.redraw(),this)},d.prototype.tickLength=function(b){return a.Utils.Window.deprecated("tickLength()","v1.3.0","Replaced by innerTickLength()"),this.innerTickLength(b)},d.prototype.innerTickLength=function(a){if(null==a)return this._innerTickLength;if(0>a)throw new Error("inner tick length must be positive");return this._innerTickLength=a,this.redraw(),this},d.prototype.endTickLength=function(a){if(null==a)return this._endTickLength;if(0>a)throw new Error("end tick length must be positive");return this._endTickLength=a,this.redraw(),this},d.prototype._maxLabelTickLength=function(){return this.showEndTickLabels()?Math.max(this.innerTickLength(),this.endTickLength()):this.innerTickLength()},d.prototype.tickLabelPadding=function(a){if(null==a)return this._tickLabelPadding;if(0>a)throw new Error("tick label padding must be positive");return this._tickLabelPadding=a,this.redraw(),this},d.prototype.margin=function(a){if(null==a)return this._margin;if(0>a)throw new Error("margin size must be positive");return this._margin=a,this.redraw(),this},d.prototype.orientation=function(a){if(null==a)return this._orientation;var b=a.toLowerCase();if("top"!==b&&"bottom"!==b&&"left"!==b&&"right"!==b)throw new Error("unsupported orientation");return this._orientation=b,this.redraw(),this},d.prototype.showEndTickLabels=function(a){return null==a?this._showEndTickLabels:(this._showEndTickLabels=a,this.render(),this)},d.END_TICK_MARK_CLASS="end-tick-mark",d.TICK_MARK_CLASS="tick-mark",d.TICK_LABEL_CLASS="tick-label",d}(a.Component);a.Axis=c}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(a){a.second="second",a.minute="minute",a.hour="hour",a.day="day",a.week="week",a.month="month",a.year="year"}(d=a.TimeInterval||(a.TimeInterval={}));var e;!function(e){var f=function(e){function f(a,b){e.call(this,a,b),this._tierLabelPositions=[],this.addClass("time-axis"),this.tickLabelPadding(5),this.axisConfigurations(f._DEFAULT_TIME_AXIS_CONFIGURATIONS)}return b(f,e),f.prototype.tierLabelPositions=function(a){if(null==a)return this._tierLabelPositions;if(!a.every(function(a){return"between"===a.toLowerCase()||"center"===a.toLowerCase()}))throw new Error("Unsupported position for tier labels");return this._tierLabelPositions=a,this.redraw(),this},f.prototype.axisConfigurations=function(b){if(null==b)return this._possibleTimeAxisConfigurations;this._possibleTimeAxisConfigurations=b,this._numTiers=a.Utils.Math.max(this._possibleTimeAxisConfigurations.map(function(a){return a.length}),0),this._isAnchored&&this._setupDomElements();for(var c=this.tierLabelPositions(),d=[],e=0;ed&&a.every(function(a){return b._checkTimeAxisTierConfigurationWidth(a)})&&(c=d)}),c===this._possibleTimeAxisConfigurations.length&&(a.Utils.Window.warn("zoomed out too far: could not find suitable interval to display labels"),--c),c},f.prototype.orientation=function(a){if(a&&("right"===a.toLowerCase()||"left"===a.toLowerCase()))throw new Error(a+" is not a supported orientation for TimeAxis - only horizontal orientations are supported");return e.prototype.orientation.call(this,a)},f.prototype._computeHeight=function(){var a=this._measurer.measure().height;this._tierHeights=[];for(var b=0;bthis._scale.domain()[1])return this.width();var f=Math.abs(this._scale.scale(e)-this._scale.scale(c));return f},f.prototype._maxWidthForInterval=function(a){return this._measurer.measure(a.formatter(f._LONG_DATE)).width},f.prototype._checkTimeAxisTierConfigurationWidth=function(a){var b=this._maxWidthForInterval(a)+2*this.tickLabelPadding();return Math.min(this._getIntervalLength(a),this.width())>=b},f.prototype._sizeFromOffer=function(a,b){var c=e.prototype._sizeFromOffer.call(this,a,b),d=this._tierHeights.reduce(function(a,b){return a+b>c.height?a:a+b});return c.height=Math.min(c.height,d+this.margin()),c},f.prototype._setup=function(){e.prototype._setup.call(this),this._setupDomElements()},f.prototype._setupDomElements=function(){this.content().selectAll("."+f.TIME_AXIS_TIER_CLASS).remove(),this._tierLabelContainers=[],this._tierMarkContainers=[],this._tierBaselines=[],this._tickLabelContainer.remove(),this._baseline.remove();for(var b=0;b=f.length||g.push(new Date((f[b+1].valueOf()-f[b].valueOf())/2+f[b].valueOf()))}):g=f;var h=b.selectAll("."+a.Axis.TICK_LABEL_CLASS).data(g,function(a){return String(a.valueOf())}),i=h.enter().append("g").classed(a.Axis.TICK_LABEL_CLASS,!0);i.append("text");var j="center"===this._tierLabelPositions[d]||1===c.step?0:this.tickLabelPadding(),k="bottom"===this.orientation()?d3.sum(this._tierHeights.slice(0,d+1))-this.tickLabelPadding():this.height()-d3.sum(this._tierHeights.slice(0,d))-this.tickLabelPadding(),l=h.selectAll("text");l.size()>0&&a.Utils.DOM.translate(l,j,k),h.exit().remove(),h.attr("transform",function(a){return"translate("+e._scale.scale(a)+",0)"});var m="center"===this._tierLabelPositions[d]||1===c.step?"middle":"start";h.selectAll("text").text(c.formatter).style("text-anchor",m)},f.prototype._renderTickMarks=function(b,c){var d=this._tierMarkContainers[c].selectAll("."+a.Axis.TICK_MARK_CLASS).data(b);d.enter().append("line").classed(a.Axis.TICK_MARK_CLASS,!0);var e=this._generateTickMarkAttrHash(),f=this._tierHeights.slice(0,c).reduce(function(a,b){return a+b},0);"bottom"===this.orientation()?(e.y1=f,e.y2=f+("center"===this._tierLabelPositions[c]?this.innerTickLength():this._tierHeights[c])):(e.y1=this.height()-f,e.y2=this.height()-(f+("center"===this._tierLabelPositions[c]?this.innerTickLength():this._tierHeights[c]))),d.attr(e),"bottom"===this.orientation()?(e.y1=f,e.y2=f+this._tierHeights[c]):(e.y1=this.height()-f,e.y2=this.height()-(f+this._tierHeights[c])),d3.select(d[0][0]).attr(e),d3.select(d[0][0]).classed(a.Axis.END_TICK_MARK_CLASS,!0),d3.select(d[0][d.size()-1]).classed(a.Axis.END_TICK_MARK_CLASS,!0),d.exit().remove()},f.prototype._renderLabellessTickMarks=function(b){var c=this._tickMarkContainer.selectAll("."+a.Axis.TICK_MARK_CLASS).data(b);c.enter().append("line").classed(a.Axis.TICK_MARK_CLASS,!0);var d=this._generateTickMarkAttrHash();d.y2="bottom"===this.orientation()?this.tickLabelPadding():this.height()-this.tickLabelPadding(),c.attr(d),c.exit().remove()},f.prototype._generateLabellessTicks=function(){return this._mostPreciseConfigIndex<1?[]:this._getTickIntervalValues(this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex-1][0])},f.prototype.renderImmediately=function(){var a=this;this._mostPreciseConfigIndex=this._getMostPreciseConfigurationIndex();var b=this._possibleTimeAxisConfigurations[this._mostPreciseConfigIndex];this._cleanTiers(),b.forEach(function(b,c){return a._renderTierLabels(a._tierLabelContainers[c],b,c)});for(var c=b.map(function(b){return a._getTickValuesForConfiguration(b)}),d=0,e=0;e=i&&(g=this._generateLabellessTicks()),this._renderLabellessTickMarks(g),this._hideOverflowingTiers();for(var e=0;e=c?"inherit":"hidden"})},f.prototype._hideOverlappingAndCutOffLabels=function(b){var c,d=this,e=this._boundingBox.node().getBoundingClientRect(),f=function(a){return Math.floor(e.left)<=Math.ceil(a.left)&&Math.floor(e.top)<=Math.ceil(a.top)&&Math.floor(a.right)<=Math.ceil(e.left+d.width())&&Math.floor(a.bottom)<=Math.ceil(e.top+d.height())},g=this._tierMarkContainers[b].selectAll("."+a.Axis.TICK_MARK_CLASS).filter(function(){var a=d3.select(this).style("visibility");return"visible"===a||"inherit"===a}),h=g[0].map(function(a){return a.getBoundingClientRect()}),i=this._tierLabelContainers[b].selectAll("."+a.Axis.TICK_LABEL_CLASS).filter(function(){var a=d3.select(this).style("visibility");return"visible"===a||"inherit"===a});i.each(function(b,d){var e=this.getBoundingClientRect(),g=d3.select(this),i=h[d],j=h[d+1];!f(e)||null!=c&&a.Utils.DOM.clientRectsOverlap(e,c)||i.right>e.left||j.left=b[1]?b[0]:b[1];return c===b[0]?a.ticks().filter(function(a){return a>=c&&d>=a}):a.ticks().filter(function(a){return a>=c&&d>=a}).reverse()},e.prototype._rescale=function(){if(this._isSetup){if(!this._isHorizontal()){var a=this._computeWidth();if(a>this.width()||a=f.left)return!1}else if(e.top-c<=f.bottom)return!1}return!0},e}(a.Axis);d.Numeric=e}(d=a.Axes||(a.Axes={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(a,b){d.call(this,a,b),this._tickLabelAngle=0,this.addClass("category-axis")}return b(e,d),e.prototype._setup=function(){d.prototype._setup.call(this),this._measurer=new c.Measurers.CacheCharacterMeasurer(this._tickLabelContainer),this._wrapper=new c.Wrappers.SingleLineWrapper,this._writer=new c.Writers.Writer(this._measurer,this._wrapper)},e.prototype._rescale=function(){return this.redraw()},e.prototype.requestedSpace=function(a,b){var c=this._isHorizontal()?0:this._maxLabelTickLength()+this.tickLabelPadding()+this.margin(),d=this._isHorizontal()?this._maxLabelTickLength()+this.tickLabelPadding()+this.margin():0;if(0===this._scale.domain().length)return{minWidth:0,minHeight:0};var e=this._scale,f=this._measureTicks(a,b,e,e.domain());return{minWidth:f.usedWidth+c,minHeight:f.usedHeight+d}},e.prototype._getTickValues=function(){return this._scale.domain()},e.prototype.tickLabelAngle=function(a){if(null==a)return this._tickLabelAngle;if(0!==a&&90!==a&&-90!==a)throw new Error("Angle "+a+" not supported; only 0, 90, and -90 are valid values");return this._tickLabelAngle=a,this.redraw(),this},e.prototype._drawTicks=function(a,b,c,d){var e,f,g=this;switch(this.tickLabelAngle()){case 0:e={left:"right",right:"left",top:"center",bottom:"center"},f={left:"center",right:"center",top:"bottom",bottom:"top"};break;case 90:e={left:"center",right:"center",top:"right",bottom:"left"},f={left:"top",right:"bottom",top:"center",bottom:"center"};break;case-90:e={left:"center",right:"center",top:"left",bottom:"right"},f={left:"bottom",right:"top",top:"center",bottom:"center"}}d.each(function(d){var h=c.stepWidth(),i=g._isHorizontal()?h:a-g._maxLabelTickLength()-g.tickLabelPadding(),j=g._isHorizontal()?b-g._maxLabelTickLength()-g.tickLabelPadding():h,k={selection:d3.select(this),xAlign:e[g.orientation()],yAlign:f[g.orientation()],textRotation:g.tickLabelAngle()};g._writer.write(g.formatter()(d),i,j,k)})},e.prototype._measureTicks=function(b,d,e,f){var g=this,h=this._isHorizontal()?b:d,i=2*e.outerPadding(),j=(f.length-1)*e.innerPadding(),k=h/(i+j+f.length),l=k*(1+e.innerPadding()),m=f.map(function(a){var c=b-g._maxLabelTickLength()-g.tickLabelPadding();g._isHorizontal()&&(c=l,0!==g._tickLabelAngle&&(c=d-g._maxLabelTickLength()-g.tickLabelPadding()),c=Math.max(c,0));var e=l;return g._isHorizontal()&&(e=d-g._maxLabelTickLength()-g.tickLabelPadding(),0!==g._tickLabelAngle&&(e=b-g._maxLabelTickLength()-g.tickLabelPadding()),e=Math.max(e,0)),g._wrapper.wrap(g.formatter()(a),g._measurer,c,e)}),n=this._isHorizontal()&&0===this._tickLabelAngle?d3.sum:a.Utils.Math.max,o=this._isHorizontal()&&0===this._tickLabelAngle?a.Utils.Math.max:d3.sum,p=m.every(function(a){return!c.Utils.StringMethods.isNotEmptyString(a.truncatedText)&&1===a.noLines}),q=n(m,function(a){return g._measurer.measure(a.wrappedText).width},0),r=o(m,function(a){return g._measurer.measure(a.wrappedText).height},0);if(0!==this._tickLabelAngle){var s=r;r=q,q=s}return{textFits:p,usedWidth:q,usedHeight:r}},e.prototype.renderImmediately=function(){var b=this;d.prototype.renderImmediately.call(this);var c=this._scale,e=this._tickLabelContainer.selectAll("."+a.Axis.TICK_LABEL_CLASS).data(this._scale.domain(),function(a){return a}),f=function(a){var d=c.stepWidth()-c.rangeBand(),e=c.scale(a)-c.rangeBand()/2-d/2,f=b._isHorizontal()?e:0,g=b._isHorizontal()?0:e;return"translate("+f+","+g+")"};e.enter().append("g").classed(a.Axis.TICK_LABEL_CLASS,!0),e.exit().remove(),e.attr("transform",f),e.text(""),this._drawTicks(this.width(),this.height(),c,e);var g="right"===this.orientation()?this._maxLabelTickLength()+this.tickLabelPadding():0,h="bottom"===this.orientation()?this._maxLabelTickLength()+this.tickLabelPadding():0;return a.Utils.DOM.translate(this._tickLabelContainer,g,h),this},e.prototype.computeLayout=function(a,b,c){return this._measurer.reset(),d.prototype.computeLayout.call(this,a,b,c)},e}(a.Axis);d.Category=e}(d=a.Axes||(a.Axes={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(a){function d(b,c){void 0===b&&(b=""),void 0===c&&(c=0),a.call(this),this.addClass("label"),this.text(b),this.angle(c),this.xAlignment("center").yAlignment("center"),this._padding=0}return b(d,a),d.prototype.requestedSpace=function(){var a=this._measurer.measure(this._text),b=(0===this.angle()?a.width:a.height)+2*this.padding(),c=(0===this.angle()?a.height:a.width)+2*this.padding();return{minWidth:b,minHeight:c}},d.prototype._setup=function(){a.prototype._setup.call(this),this._textContainer=this.content().append("g"),this._measurer=new c.Measurers.Measurer(this._textContainer),this._wrapper=new c.Wrappers.Wrapper,this._writer=new c.Writers.Writer(this._measurer,this._wrapper),this.text(this._text)},d.prototype.text=function(a){if(null==a)return this._text;if("string"!=typeof a)throw new Error("Label.text() only takes strings as input");return this._text=a,this.redraw(),this},d.prototype.angle=function(a){if(null==a)return this._angle;if(a%=360,a>180?a-=360:-180>a&&(a+=360),-90!==a&&0!==a&&90!==a)throw new Error(a+" is not a valid angle for Label");return this._angle=a,this.redraw(),this},d.prototype.padding=function(a){if(null==a)return this._padding;if(a=+a,0>a)throw new Error(a+" is not a valid padding value. Cannot be less than 0.");return this._padding=a,this.redraw(),this},d.prototype.fixedWidth=function(){return!0},d.prototype.fixedHeight=function(){return!0},d.prototype.renderImmediately=function(){a.prototype.renderImmediately.call(this),this._textContainer.selectAll("g").remove();var b=this._measurer.measure(this._text),c=Math.max(Math.min((this.height()-b.height)/2,this.padding()),0),d=Math.max(Math.min((this.width()-b.width)/2,this.padding()),0);this._textContainer.attr("transform","translate("+d+","+c+")");var e=this.width()-2*d,f=this.height()-2*c,g={selection:this._textContainer,xAlign:this.xAlignment(),yAlign:this.yAlignment(),textRotation:this.angle()};return this._writer.write(this._text,e,f,g),this},d}(a.Component);d.Label=e;var f=function(a){function c(b,d){a.call(this,b,d),this.addClass(c.TITLE_LABEL_CLASS)}return b(c,a),c.TITLE_LABEL_CLASS="title-label",c}(e);d.TitleLabel=f;var g=function(a){function c(b,d){a.call(this,b,d),this.addClass(c.AXIS_LABEL_CLASS)}return b(c,a),c.AXIS_LABEL_CLASS="axis-label",c}(e);d.AxisLabel=g}(d=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(b){var c=this;if(d.call(this),this._padding=5,this.addClass("legend"),this.maxEntriesPerRow(1),null==b)throw new Error("Legend requires a colorScale");this._colorScale=b,this._redrawCallback=function(){return c.redraw()},this._colorScale.onUpdate(this._redrawCallback),this.xAlignment("right").yAlignment("top"),this.comparator(function(a,b){return c._colorScale.domain().indexOf(a)-c._colorScale.domain().indexOf(b)}),this._symbolFactoryAccessor=function(){return a.SymbolFactories.circle()},this._symbolOpacityAccessor=function(){return 1}}return b(e,d),e.prototype._setup=function(){d.prototype._setup.call(this);var a=this.content().append("g").classed(e.LEGEND_ROW_CLASS,!0),b=a.append("g").classed(e.LEGEND_ENTRY_CLASS,!0);b.append("text"),this._measurer=new c.Measurers.Measurer(a),this._wrapper=(new c.Wrappers.Wrapper).maxLines(1),this._writer=new c.Writers.Writer(this._measurer,this._wrapper).addTitleElement(!0)},e.prototype.maxEntriesPerRow=function(a){return null==a?this._maxEntriesPerRow:(this._maxEntriesPerRow=a,this.redraw(),this)},e.prototype.comparator=function(a){return null==a?this._comparator:(this._comparator=a,this.redraw(),this)},e.prototype.colorScale=function(a){return null!=a?(this._colorScale.offUpdate(this._redrawCallback),this._colorScale=a,this._colorScale.onUpdate(this._redrawCallback),this.redraw(),this):this._colorScale},e.prototype.destroy=function(){d.prototype.destroy.call(this),this._colorScale.offUpdate(this._redrawCallback)},e.prototype._calculateLayoutInfo=function(a,b){var c=this,d=this._measurer.measure().height,e=Math.max(0,a-this._padding),f=this._colorScale.domain().slice();f.sort(this.comparator());var g=d3.map(),h=d3.map();f.forEach(function(a){var b=d+c._measurer.measure(a).width+c._padding,f=Math.min(b,e);g.set(a,f),h.set(a,b)});var i=this._packRows(e,f,g),j=Math.floor((b-2*this._padding)/d);return j!==j&&(j=0),{textHeight:d,entryLengths:g,untruncatedEntryLengths:h,rows:i,numRowsToDraw:Math.max(Math.min(j,i.length),0)}},e.prototype.requestedSpace=function(b,c){var d=this._calculateLayoutInfo(b,c),e=d.rows.map(function(a){return d3.sum(a,function(a){return d.untruncatedEntryLengths.get(a)})}),f=a.Utils.Math.max(e,0);return{minWidth:this._padding+f,minHeight:d.rows.length*d.textHeight+2*this._padding}},e.prototype._packRows=function(a,b,c){var d=this,e=[],f=[],g=a;return b.forEach(function(b){var h=c.get(b);(h>g||f.length===d._maxEntriesPerRow)&&(e.push(f),f=[],g=a),f.push(b),g-=h}),0!==f.length&&e.push(f),e},e.prototype.entitiesAt=function(a){if(!this._isSetup)return[];var b=[],c=this._calculateLayoutInfo(this.width(),this.height()),d=this._padding,f=this;return this.content().selectAll("g."+e.LEGEND_ROW_CLASS).each(function(g,h){var i=h*c.textHeight+d,j=(h+1)*c.textHeight+d,k=(i+j)/2,l=d,m=d;d3.select(this).selectAll("g."+e.LEGEND_ENTRY_CLASS).each(function(d){m+=c.entryLengths.get(d);var e=l+c.textHeight/2;if(m>=a.x&&l<=a.x&&j>=a.y&&i<=a.y){var g=d3.select(this),h=g.datum();b.push({datum:h,position:{x:e,y:k},selection:g,component:f})}l+=c.entryLengths.get(d)})}),b},e.prototype.renderImmediately=function(){var a=this;d.prototype.renderImmediately.call(this);var b=this._calculateLayoutInfo(this.width(),this.height()),c=b.rows.slice(0,b.numRowsToDraw),f=this.content().selectAll("g."+e.LEGEND_ROW_CLASS).data(c);f.enter().append("g").classed(e.LEGEND_ROW_CLASS,!0),f.exit().remove(),f.attr("transform",function(c,d){return"translate(0, "+(d*b.textHeight+a._padding)+")"});var g=f.selectAll("g."+e.LEGEND_ENTRY_CLASS).data(function(a){return a}),h=g.enter().append("g").classed(e.LEGEND_ENTRY_CLASS,!0);h.append("path"),h.append("g").classed("text-container",!0),g.exit().remove();var i=this._padding;f.each(function(){var a=i,c=d3.select(this).selectAll("g."+e.LEGEND_ENTRY_CLASS);c.attr("transform",function(c){var d="translate("+a+", 0)";return a+=b.entryLengths.get(c),d})}),g.select("path").attr("d",function(c,d,e){return a.symbol()(c,e)(.6*b.textHeight)}).attr("transform","translate("+b.textHeight/2+","+b.textHeight/2+")").attr("fill",function(b){return a._colorScale.scale(b)}).attr("opacity",function(b,c,d){return a.symbolOpacity()(b,d)}).classed(e.LEGEND_SYMBOL_CLASS,!0);var j=this._padding,k=g.select("g.text-container");k.text(""),k.append("title").text(function(a){return a});var l=this;return k.attr("transform","translate("+b.textHeight+", 0)").each(function(a){var c=d3.select(this),d=b.entryLengths.get(a)-b.textHeight-j,e={selection:c,xAlign:"left",yAlign:"top",textRotation:0};l._writer.write(a,d,l.height(),e)}),this},e.prototype.symbol=function(a){return null==a?this._symbolFactoryAccessor:(this._symbolFactoryAccessor=a,this.render(),this)},e.prototype.symbolOpacity=function(a){return null==a?this._symbolOpacityAccessor:(this._symbolOpacityAccessor="number"==typeof a?function(){return a}:a,this.render(),this)},e.prototype.fixedWidth=function(){return!0},e.prototype.fixedHeight=function(){return!0},e.LEGEND_ROW_CLASS="legend-row",e.LEGEND_ENTRY_CLASS="legend-entry",e.LEGEND_SYMBOL_CLASS="legend-symbol",e}(a.Component);d.Legend=e}(d=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(b){var c=this;if(d.call(this),this._padding=5,this._numSwatches=10,null==b)throw new Error("InterpolatedColorLegend requires a interpolatedColorScale");this._scale=b,this._redrawCallback=function(){return c.redraw()},this._scale.onUpdate(this._redrawCallback),this._formatter=a.Formatters.general(),this._orientation="horizontal",this.addClass("legend"),this.addClass("interpolated-color-legend")}return b(e,d),e.prototype.destroy=function(){d.prototype.destroy.call(this),this._scale.offUpdate(this._redrawCallback)},e.prototype.formatter=function(a){return void 0===a?this._formatter:(this._formatter=a,this.redraw(),this)},e._ensureOrientation=function(a){if(a=a.toLowerCase(),"horizontal"===a||"left"===a||"right"===a)return a;throw new Error('"'+a+'" is not a valid orientation for InterpolatedColorLegend')},e.prototype.orientation=function(a){return null==a?this._orientation:(this._orientation=e._ensureOrientation(a),this.redraw(),this)},e.prototype.fixedWidth=function(){return!0},e.prototype.fixedHeight=function(){return!0},e.prototype._generateTicks=function(){for(var a=this._scale.domain(),b=(a[1]-a[0])/this._numSwatches,c=[],d=0;d<=this._numSwatches;d++)c.push(a[0]+b*d);return c},e.prototype._setup=function(){d.prototype._setup.call(this),this._swatchContainer=this.content().append("g").classed("swatch-container",!0),this._swatchBoundingBox=this.content().append("rect").classed("swatch-bounding-box",!0),this._lowerLabel=this.content().append("g").classed(e.LEGEND_LABEL_CLASS,!0),this._upperLabel=this.content().append("g").classed(e.LEGEND_LABEL_CLASS,!0),this._measurer=new c.Measurers.Measurer(this.content()),this._wrapper=new c.Wrappers.Wrapper,this._writer=new c.Writers.Writer(this._measurer,this._wrapper)},e.prototype.requestedSpace=function(){var b,c,d=this,e=this._measurer.measure().height,f=this._generateTicks(),g=f.length,h=this._scale.domain(),i=h.map(function(a){return d._measurer.measure(d._formatter(a)).width});if(this._isVertical()){var j=a.Utils.Math.max(i,0);c=this._padding+e+this._padding+j+this._padding,b=this._padding+g*e+this._padding}else b=this._padding+e+this._padding,c=this._padding+i[0]+this._padding+g*e+this._padding+i[1]+this._padding;return{minWidth:c,minHeight:b}},e.prototype._isVertical=function(){return"horizontal"!==this._orientation},e.prototype.renderImmediately=function(){var a=this;d.prototype.renderImmediately.call(this);var b,c,e,f,g=this._scale.domain(),h=this._formatter(g[0]),i=this._measurer.measure(h).width,j=this._formatter(g[1]),k=this._measurer.measure(j).width,l=this._generateTicks(),m=l.length,n=this._padding,o={x:0,y:0},p={x:0,y:0},q={selection:this._lowerLabel,xAlign:"center",yAlign:"center",textRotation:0},r={selection:this._upperLabel,xAlign:"center",yAlign:"center",textRotation:0},s={x:0,y:n,width:0,height:0};if(this._isVertical()){var t=Math.max(i,k);b=Math.max(this.width()-3*n-t,0),c=Math.max((this.height()-2*n)/m,0),f=function(a,b){return n+(m-(b+1))*c},r.yAlign="top",o.y=n,q.yAlign="bottom",p.y=-n,"left"===this._orientation?(e=function(){return n+t+n},r.xAlign="right",o.x=-(n+b+n),q.xAlign="right",p.x=-(n+b+n)):(e=function(){return n},r.xAlign="left",o.x=n+b+n,q.xAlign="left",p.x=n+b+n),s.width=b,s.height=m*c}else b=Math.max((this.width()-4*n-i-k)/m,0),c=Math.max(this.height()-2*n,0),e=function(a,c){return n+i+n+c*b},f=function(){return n},r.xAlign="right",o.x=-n,q.xAlign="left",p.x=n,s.width=m*b,s.height=c;s.x=e(null,0),this._upperLabel.text(""),this._writer.write(j,this.width(),this.height(),r);var u="translate("+o.x+", "+o.y+")";this._upperLabel.attr("transform",u),this._lowerLabel.text(""),this._writer.write(h,this.width(),this.height(),q);var v="translate("+p.x+", "+p.y+")";this._lowerLabel.attr("transform",v),this._swatchBoundingBox.attr(s);var w=this._swatchContainer.selectAll("rect.swatch").data(l);return w.enter().append("rect").classed("swatch",!0),w.exit().remove(),w.attr({fill:function(b){return a._scale.scale(b)},width:b,height:c,x:e,y:f}),this},e.LEGEND_LABEL_CLASS="legend-label",e}(a.Component);d.InterpolatedColorLegend=e}(d=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(b,d){var e=this;if(null!=b&&!a.QuantitativeScale.prototype.isPrototypeOf(b))throw new Error("xScale needs to inherit from Scale.QuantitativeScale");if(null!=d&&!a.QuantitativeScale.prototype.isPrototypeOf(d))throw new Error("yScale needs to inherit from Scale.QuantitativeScale");c.call(this),this.addClass("gridlines"),this._xScale=b,this._yScale=d,this._renderCallback=function(){return e.render()},this._xScale&&this._xScale.onUpdate(this._renderCallback),this._yScale&&this._yScale.onUpdate(this._renderCallback)}return b(d,c),d.prototype.destroy=function(){return c.prototype.destroy.call(this),this._xScale&&this._xScale.offUpdate(this._renderCallback),this._yScale&&this._yScale.offUpdate(this._renderCallback),this},d.prototype._setup=function(){c.prototype._setup.call(this),this._xLinesContainer=this.content().append("g").classed("x-gridlines",!0),this._yLinesContainer=this.content().append("g").classed("y-gridlines",!0)},d.prototype.renderImmediately=function(){return c.prototype.renderImmediately.call(this),this._redrawXLines(),this._redrawYLines(),this},d.prototype.computeLayout=function(a,b,d){return c.prototype.computeLayout.call(this,a,b,d),null!=this._xScale&&this._xScale.range([0,this.width()]),null!=this._yScale&&this._yScale.range([this.height(),0]),this},d.prototype._redrawXLines=function(){var a=this;if(this._xScale){var b=this._xScale.ticks(),c=function(b){return a._xScale.scale(b)},d=this._xLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",c).attr("y1",0).attr("x2",c).attr("y2",this.height()).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},d.prototype._redrawYLines=function(){var a=this;if(this._yScale){var b=this._yScale.ticks(),c=function(b){return a._yScale.scale(b)},d=this._yLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",0).attr("y1",c).attr("x2",this.width()).attr("y2",c).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},d}(a.Component);c.Gridlines=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(a){var b=this;void 0===a&&(a=[]),c.call(this),this._rowPadding=0,this._columnPadding=0,this._rows=[],this._rowWeights=[],this._columnWeights=[],this._nRows=0,this._nCols=0,this._calculatedLayout=null,this.addClass("table"),a.forEach(function(a,c){a.forEach(function(a,d){null!=a&&b.add(a,c,d)})})}return b(d,c),d.prototype._forEach=function(a){for(var b=0;b0&&f!==z,E=g>0&&g!==A;if(!D&&!E)break;if(w>5)break}return f=m-d3.sum(h.guaranteedWidths),g=n-d3.sum(h.guaranteedHeights),s=d._calcProportionalSpace(p,f),t=d._calcProportionalSpace(o,g),{colProportionalSpace:s,rowProportionalSpace:t,guaranteedWidths:h.guaranteedWidths,guaranteedHeights:h.guaranteedHeights,wantsWidth:i,wantsHeight:j}},d.prototype._determineGuarantees=function(b,c,d){void 0===d&&(d=!1);var e=a.Utils.Array.createFilledArray(0,this._nCols),f=a.Utils.Array.createFilledArray(0,this._nRows),g=a.Utils.Array.createFilledArray(!1,this._nCols),h=a.Utils.Array.createFilledArray(!1,this._nRows);return this._rows.forEach(function(a,i){a.forEach(function(a,j){var k;k=null!=a?a.requestedSpace(b[j],c[i]):{minWidth:0,minHeight:0};var l=d?Math.min(k.minWidth,b[j]):k.minWidth;e[j]=Math.max(e[j],l);var m=d?Math.min(k.minHeight,c[i]):k.minHeight;f[i]=Math.max(f[i],m);var n=k.minWidth>b[j];g[j]=g[j]||n;var o=k.minHeight>c[i];h[i]=h[i]||o})}),{guaranteedWidths:e,guaranteedHeights:f,wantsWidthArr:g,wantsHeightArr:h}},d.prototype.requestedSpace=function(a,b){return this._calculatedLayout=this._iterateLayout(a,b),{minWidth:d3.sum(this._calculatedLayout.guaranteedWidths),minHeight:d3.sum(this._calculatedLayout.guaranteedHeights)} +},d.prototype.computeLayout=function(b,d,e){var f=this;c.prototype.computeLayout.call(this,b,d,e);var g=d3.sum(this._calculatedLayout.guaranteedWidths),h=d3.sum(this._calculatedLayout.guaranteedHeights),i=this._calculatedLayout;(g>this.width()||h>this.height())&&(i=this._iterateLayout(this.width(),this.height(),!0));var j=0,k=a.Utils.Array.add(i.rowProportionalSpace,i.guaranteedHeights),l=a.Utils.Array.add(i.colProportionalSpace,i.guaranteedWidths);return this._rows.forEach(function(a,b){var c=0;a.forEach(function(a,d){null!=a&&a.computeLayout({x:c,y:j},l[d],k[b]),c+=l[d]+f._columnPadding}),j+=k[b]+f._rowPadding}),this},d.prototype.rowPadding=function(a){return null==a?this._rowPadding:(this._rowPadding=a,this.redraw(),this)},d.prototype.columnPadding=function(a){return null==a?this._columnPadding:(this._columnPadding=a,this.redraw(),this)},d.prototype.rowWeight=function(a,b){return null==b?this._rowWeights[a]:(this._rowWeights[a]=b,this.redraw(),this)},d.prototype.columnWeight=function(a,b){return null==b?this._columnWeights[a]:(this._columnWeights[a]=b,this.redraw(),this)},d.prototype.fixedWidth=function(){var a=d3.transpose(this._rows);return d._fixedSpace(a,function(a){return null==a||a.fixedWidth()})},d.prototype.fixedHeight=function(){return d._fixedSpace(this._rows,function(a){return null==a||a.fixedHeight()})},d.prototype._padTableToSize=function(a,b){for(var c=0;a>c;c++){void 0===this._rows[c]&&(this._rows[c]=[],this._rowWeights[c]=null);for(var d=0;b>d;d++)void 0===this._rows[c][d]&&(this._rows[c][d]=null)}for(var d=0;b>d;d++)void 0===this._columnWeights[d]&&(this._columnWeights[d]=null)},d._calcComponentWeights=function(a,b,c){return a.map(function(a,d){if(null!=a)return a;var e=b[d].map(c),f=e.reduce(function(a,b){return a&&b},!0);return f?0:1})},d._calcProportionalSpace=function(b,c){var d=d3.sum(b);return 0===d?a.Utils.Array.createFilledArray(0,b.length):b.map(function(a){return c*a/d})},d._fixedSpace=function(a,b){var c=function(a){return a.reduce(function(a,b){return a&&b},!0)},d=function(a){return c(a.map(b))};return c(a.map(d))},d}(a.ComponentContainer);c.Table=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(a){function c(){var b=this;a.call(this),this._boxVisible=!1,this._boxBounds={topLeft:{x:0,y:0},bottomRight:{x:0,y:0}},this.addClass("selection-box-layer"),this._adjustBoundsCallback=function(){b.bounds({topLeft:{x:b._xScale?b._xScale.scale(b._boxLeftDataValue):b._boxBounds.topLeft.x,y:b._yScale?b._yScale.scale(b._boxTopDataValue):b._boxBounds.topLeft.y},bottomRight:{x:b._xScale?b._xScale.scale(b._boxRightDataValue):b._boxBounds.bottomRight.x,y:b._yScale?b._yScale.scale(b._boxBottomDataValue):b._boxBounds.bottomRight.y}})}}return b(c,a),c.prototype._setup=function(){a.prototype._setup.call(this),this._box=this.content().append("g").classed("selection-box",!0).remove(),this._boxArea=this._box.append("rect").classed("selection-area",!0)},c.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}},c.prototype.bounds=function(a){return null==a?this._boxBounds:(this._setBounds(a),this.render(),this)},c.prototype._setBounds=function(a){var b={x:Math.min(a.topLeft.x,a.bottomRight.x),y:Math.min(a.topLeft.y,a.bottomRight.y)},c={x:Math.max(a.topLeft.x,a.bottomRight.x),y:Math.max(a.topLeft.y,a.bottomRight.y)};this._boxBounds={topLeft:b,bottomRight:c},this._bindBoxDataValues()},c.prototype.renderImmediately=function(){if(this._boxVisible){var a=this._boxBounds.topLeft.y,b=this._boxBounds.bottomRight.y,c=this._boxBounds.topLeft.x,d=this._boxBounds.bottomRight.x;this._boxArea.attr({x:c,y:a,width:d-c,height:b-a}),this.content().node().appendChild(this._box.node())}else this._box.remove();return this},c.prototype.boxVisible=function(a){return null==a?this._boxVisible:(this._boxVisible=a,this.render(),this)},c.prototype.fixedWidth=function(){return!0},c.prototype.fixedHeight=function(){return!0},c.prototype.xScale=function(a){return null==a?this._xScale:(null!=this._xScale&&this._xScale.offUpdate(this._adjustBoundsCallback),this._xScale=a,this._xScale.onUpdate(this._adjustBoundsCallback),this._bindBoxDataValues(),this)},c.prototype.yScale=function(a){return null==a?this._yScale:(null!=this._yScale&&this._yScale.offUpdate(this._adjustBoundsCallback),this._yScale=a,this._yScale.onUpdate(this._adjustBoundsCallback),this._bindBoxDataValues(),this)},c.prototype.xExtent=function(){return[this._boxLeftDataValue,this._boxRightDataValue]},c.prototype.yExtent=function(){return[this._boxTopDataValue,this._boxBottomDataValue]},c.prototype._bindBoxDataValues=function(){this._boxLeftDataValue=this._xScale?this._xScale.invert(this._boxBounds.topLeft.x):null,this._boxTopDataValue=this._yScale?this._yScale.invert(this._boxBounds.topLeft.y):null,this._boxRightDataValue=this._xScale?this._xScale.invert(this._boxBounds.bottomRight.x):null,this._boxBottomDataValue=this._yScale?this._yScale.invert(this._boxBounds.bottomRight.y):null},c.prototype.destroy=function(){a.prototype.destroy.call(this),null!=this._xScale&&this.xScale().offUpdate(this._adjustBoundsCallback),null!=this._yScale&&this.yScale().offUpdate(this._adjustBoundsCallback)},c}(a.Component);c.SelectionBoxLayer=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d;!function(a){a[a.VALUE=0]="VALUE",a[a.PIXEL=1]="PIXEL"}(d||(d={}));var e=function(c){function e(a){var b=this;if(c.call(this),this._mode=d.VALUE,a!==e.ORIENTATION_VERTICAL&&a!==e.ORIENTATION_HORIZONTAL)throw new Error(a+" is not a valid orientation for GuideLineLayer");this._orientation=a,this._clipPathEnabled=!0,this.addClass("guide-line-layer"),this._scaleUpdateCallback=function(){b._syncPixelPositionAndValue(),b.render()}}return b(e,c),e.prototype._setup=function(){c.prototype._setup.call(this),this._guideLine=this.content().append("line").classed("guide-line",!0)},e.prototype._sizeFromOffer=function(a,b){return{width:a,height:b}},e.prototype._isVertical=function(){return this._orientation===e.ORIENTATION_VERTICAL},e.prototype.fixedWidth=function(){return!0},e.prototype.fixedHeight=function(){return!0},e.prototype.computeLayout=function(a,b,d){return c.prototype.computeLayout.call(this,a,b,d),null!=this.scale()&&this.scale().range(this._isVertical()?[0,this.width()]:[this.height(),0]),this},e.prototype.renderImmediately=function(){return c.prototype.renderImmediately.call(this),this._syncPixelPositionAndValue(),this._guideLine.attr({x1:this._isVertical()?this.pixelPosition():0,y1:this._isVertical()?0:this.pixelPosition(),x2:this._isVertical()?this.pixelPosition():this.width(),y2:this._isVertical()?this.height():this.pixelPosition()}),this},e.prototype._syncPixelPositionAndValue=function(){null!=this.scale()&&(this._mode===d.VALUE&&null!=this.value()?this._pixelPosition=this.scale().scale(this.value()):this._mode===d.PIXEL&&null!=this.pixelPosition()&&(this._value=this.scale().invert(this.pixelPosition())))},e.prototype.scale=function(a){if(null==a)return this._scale;var b=this._scale;return null!=b&&b.offUpdate(this._scaleUpdateCallback),this._scale=a,this._scale.onUpdate(this._scaleUpdateCallback),this._syncPixelPositionAndValue(),this.redraw(),this},e.prototype.value=function(a){return null==a?this._value:(this._value=a,this._mode=d.VALUE,this._syncPixelPositionAndValue(),this.render(),this)},e.prototype.pixelPosition=function(b){if(null==b)return this._pixelPosition;if(!a.Utils.Math.isValidNumber(b))throw new Error("pixelPosition must be a finite number");return this._pixelPosition=b,this._mode=d.PIXEL,this._syncPixelPositionAndValue(),this.render(),this},e.prototype.destroy=function(){c.prototype.destroy.call(this),null!=this.scale()&&this.scale().offUpdate(this._scaleUpdateCallback)},e.ORIENTATION_VERTICAL="vertical",e.ORIENTATION_HORIZONTAL="horizontal",e}(a.Component);c.GuideLineLayer=e}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var b;!function(a){a.MAIN="main",a.RESET="reset"}(b=a.Animator||(a.Animator={}))}(c=a.Plots||(a.Plots={}));var d=function(d){function e(){var b=this;d.call(this),this._dataChanged=!1,this._animate=!1,this._animators={},this._clipPathEnabled=!0,this.addClass("plot"),this._datasetToDrawer=new a.Utils.Map,this._attrBindings=d3.map(),this._attrExtents=d3.map(),this._includedValuesProvider=function(a){return b._includedValuesForScale(a)},this._renderCallback=function(){return b.render()},this._onDatasetUpdateCallback=function(){return b._onDatasetUpdate()},this._propertyBindings=d3.map(),this._propertyExtents=d3.map();var f=(new a.Animators.Easing).maxTotalDuration(e._ANIMATION_MAX_DURATION);this.animator(c.Animator.MAIN,f),this.animator(c.Animator.RESET,new a.Animators.Null)}return b(e,d),e.prototype.anchor=function(a){return d.prototype.anchor.call(this,a),this._dataChanged=!0,this._updateExtents(),this},e.prototype._setup=function(){var a=this;d.prototype._setup.call(this),this._renderArea=this.content().append("g").classed("render-area",!0),this.datasets().forEach(function(b){return a._createNodesForDataset(b)})},e.prototype.destroy=function(){var a=this;d.prototype.destroy.call(this),this._scales().forEach(function(b){return b.offUpdate(a._renderCallback)}),this.datasets([])},e.prototype._createNodesForDataset=function(a){var b=this._datasetToDrawer.get(a);return b.renderArea(this._renderArea.append("g")),b},e.prototype._createDrawer=function(b){return new a.Drawer(b)},e.prototype._getAnimator=function(b){return this._animateOnNextRender()?this._animators[b]||new a.Animators.Null:new a.Animators.Null},e.prototype._onDatasetUpdate=function(){this._updateExtents(),this._dataChanged=!0,this.render()},e.prototype.attr=function(a,b,c){return null==b?this._attrBindings.get(a):(this._bindAttr(a,b,c),this.render(),this)},e.prototype._bindProperty=function(a,b,c){this._bind(a,b,c,this._propertyBindings,this._propertyExtents),this._updateExtentsForProperty(a)},e.prototype._bindAttr=function(a,b,c){this._bind(a,b,c,this._attrBindings,this._attrExtents),this._updateExtentsForAttr(a)},e.prototype._bind=function(a,b,c,d){var e=d.get(a),f=null!=e?e.scale:null;null!=f&&this._uninstallScaleForKey(f,a),null!=c&&this._installScaleForKey(c,a),d.set(a,{accessor:d3.functor(b),scale:c})},e.prototype._generateAttrToProjector=function(){var a={};this._attrBindings.forEach(function(b,c){var d=c.accessor,e=c.scale,f=e?function(a,b,c){return e.scale(d(a,b,c))}:d;a[b]=f});var b=this._propertyProjectors();return Object.keys(b).forEach(function(c){null==a[c]&&(a[c]=b[c])}),a},e.prototype.renderImmediately=function(){return this._isAnchored&&(this._paint(),this._dataChanged=!1),this},e.prototype.animated=function(a){return null==a?this._animate:(this._animate=a,this)},e.prototype.detach=function(){return d.prototype.detach.call(this),this._updateExtents(),this},e.prototype._scales=function(){var a=[];return this._attrBindings.forEach(function(b,c){var d=c.scale;null!=d&&-1===a.indexOf(d)&&a.push(d)}),this._propertyBindings.forEach(function(b,c){var d=c.scale;null!=d&&-1===a.indexOf(d)&&a.push(d)}),a},e.prototype._updateExtents=function(){var a=this;this._attrBindings.forEach(function(b){return a._updateExtentsForAttr(b)}),this._propertyExtents.forEach(function(b){return a._updateExtentsForProperty(b)}),this._scales().forEach(function(b){return b.addIncludedValuesProvider(a._includedValuesProvider)})},e.prototype._updateExtentsForAttr=function(a){this._updateExtentsForKey(a,this._attrBindings,this._attrExtents,null)},e.prototype._updateExtentsForProperty=function(a){this._updateExtentsForKey(a,this._propertyBindings,this._propertyExtents,this._filterForProperty(a))},e.prototype._filterForProperty=function(){return null},e.prototype._updateExtentsForKey=function(a,b,c,d){var e=this,f=b.get(a);null!=f&&null!=f.accessor&&c.set(a,this.datasets().map(function(a){return e._computeExtent(a,f,d)}))},e.prototype._computeExtent=function(a,b,c){var d=b.accessor,e=b.scale;if(null==e)return[];var f=a.data();null!=c&&(f=f.filter(function(b,d){return c(b,d,a)}));var g=function(b,c){return d(b,c,a)},h=f.map(g);return e.extentOfValues(h)},e.prototype._extentsForProperty=function(a){return this._propertyExtents.get(a)},e.prototype._includedValuesForScale=function(a){var b=this;if(!this._isAnchored)return[];var c=[];return this._attrBindings.forEach(function(d,e){if(e.scale===a){var f=b._attrExtents.get(d);null!=f&&(c=c.concat(d3.merge(f)))}}),this._propertyBindings.forEach(function(d,e){if(e.scale===a){var f=b._extentsForProperty(d);null!=f&&(c=c.concat(d3.merge(f)))}}),c},e.prototype.animator=function(a,b){return void 0===b?this._animators[a]:(this._animators[a]=b,this)},e.prototype.addDataset=function(a){return this._addDataset(a),this._onDatasetUpdate(),this},e.prototype._addDataset=function(a){this._removeDataset(a);var b=this._createDrawer(a);return this._datasetToDrawer.set(a,b),this._isSetup&&this._createNodesForDataset(a),a.onUpdate(this._onDatasetUpdateCallback),this},e.prototype.removeDataset=function(a){return this._removeDataset(a),this._onDatasetUpdate(),this},e.prototype._removeDataset=function(a){return-1===this.datasets().indexOf(a)?this:(this._removeDatasetNodes(a),a.offUpdate(this._onDatasetUpdateCallback),this._datasetToDrawer["delete"](a),this)},e.prototype._removeDatasetNodes=function(a){var b=this._datasetToDrawer.get(a);b.remove()},e.prototype.datasets=function(a){var b=this,c=[];return this._datasetToDrawer.forEach(function(a,b){return c.push(b)}),null==a?c:(c.forEach(function(a){return b._removeDataset(a)}),a.forEach(function(a){return b._addDataset(a)}),this._onDatasetUpdate(),this)},e.prototype._getDrawersInOrder=function(){var a=this;return this.datasets().map(function(b){return a._datasetToDrawer.get(b)})},e.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new a.Animators.Null}]},e.prototype._additionalPaint=function(){},e.prototype._getDataToDraw=function(){var b=new a.Utils.Map;return this.datasets().forEach(function(a){return b.set(a,a.data())}),b},e.prototype._paint=function(){var b=this._generateDrawSteps(),c=this._getDataToDraw(),d=this._getDrawersInOrder();this.datasets().forEach(function(a,e){return d[e].draw(c.get(a),b)});var e=this.datasets().map(function(a,e){return d[e].totalDrawTime(c.get(a),b)}),f=a.Utils.Math.max(e,0);this._additionalPaint(f)},e.prototype.selections=function(a){var b=this;void 0===a&&(a=this.datasets());var c=[];return a.forEach(function(a){var d=b._datasetToDrawer.get(a);null!=d&&d.renderArea().selectAll(d.selector()).each(function(){c.push(this)})}),d3.selectAll(c)},e.prototype.entities=function(a){var b=this;return void 0===a&&(a=this.datasets()),this._lightweightEntities(a).map(function(a){return b._lightweightPlotEntityToPlotEntity(a)})},e.prototype._lightweightEntities=function(b){var c=this;void 0===b&&(b=this.datasets());var d=[];return b.forEach(function(b){var e=c._datasetToDrawer.get(b),f=0;b.data().forEach(function(g,h){var i=c._pixelPoint(g,h,b);a.Utils.Math.isNaN(i.x)||a.Utils.Math.isNaN(i.y)||(d.push({datum:g,index:h,dataset:b,position:i,component:c,drawer:e,validDatumIndex:f}),f++)})}),d},e.prototype._lightweightPlotEntityToPlotEntity=function(a){var b={datum:a.datum,position:a.position,dataset:a.dataset,index:a.index,component:a.component,selection:a.drawer.selectionForIndex(a.validDatumIndex)};return b},e.prototype.entityNearest=function(b){var c,d=this,e=1/0,f=this._lightweightEntities();return f.forEach(function(f){if(d._entityVisibleOnPlot(f.position,f.datum,f.index,f.dataset)){var g=a.Utils.Math.distanceSquared(f.position,b);e>g&&(e=g,c=f)}}),this._lightweightPlotEntityToPlotEntity(c)},e.prototype._visibleOnPlot=function(b,c){return a.Utils.Window.deprecated("Plot._visibleOnPlot()","v1.1.0"),!(c.x<0||c.y<0||c.x>this.width()||c.y>this.height())},e.prototype._entityVisibleOnPlot=function(a){return!(a.x<0||a.y<0||a.x>this.width()||a.y>this.height())},e.prototype._uninstallScaleForKey=function(a){a.offUpdate(this._renderCallback),a.removeIncludedValuesProvider(this._includedValuesProvider)},e.prototype._installScaleForKey=function(a){a.onUpdate(this._renderCallback),a.addIncludedValuesProvider(this._includedValuesProvider)},e.prototype._propertyProjectors=function(){return{}},e._scaledAccessor=function(a){return null==a.scale?a.accessor:function(b,c,d){return a.scale.scale(a.accessor(b,c,d))}},e.prototype._pixelPoint=function(){return{x:0,y:0}},e.prototype._animateOnNextRender=function(){return this._animate&&this._dataChanged},e._ANIMATION_MAX_DURATION=600,e}(a.Component);a.Plot=d}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var d;!function(d){var e=function(d){function e(){var b=this;d.call(this),this._labelFormatter=a.Formatters.identity(),this._labelsEnabled=!1,this.innerRadius(0),this.outerRadius(function(){return Math.min(b.width(),b.height())/2}),this.addClass("pie-plot"),this.attr("fill",function(a,b){return String(b)},new a.Scales.Color),this._strokeDrawers=new a.Utils.Map}return b(e,d),e.prototype._setup=function(){var a=this;d.prototype._setup.call(this),this._strokeDrawers.forEach(function(b){return b.renderArea(a._renderArea.append("g"))})},e.prototype.computeLayout=function(a,b,c){d.prototype.computeLayout.call(this,a,b,c),this._renderArea.attr("transform","translate("+this.width()/2+","+this.height()/2+")");var e=Math.min(this.width(),this.height())/2;return null!=this.innerRadius().scale&&this.innerRadius().scale.range([0,e]),null!=this.outerRadius().scale&&this.outerRadius().scale.range([0,e]),this},e.prototype.addDataset=function(a){return d.prototype.addDataset.call(this,a),this},e.prototype._addDataset=function(b){if(1===this.datasets().length)return a.Utils.Window.warn("Only one dataset is supported in Pie plots"),this;this._updatePieAngles();var c=new a.Drawers.ArcOutline(b);return this._isSetup&&c.renderArea(this._renderArea.append("g")),this._strokeDrawers.set(b,c),d.prototype._addDataset.call(this,b),this},e.prototype.removeDataset=function(a){return d.prototype.removeDataset.call(this,a),this},e.prototype._removeDatasetNodes=function(a){d.prototype._removeDatasetNodes.call(this,a),this._strokeDrawers.get(a).remove()},e.prototype._removeDataset=function(a){return d.prototype._removeDataset.call(this,a),this._startAngles=[],this._endAngles=[],this},e.prototype.selections=function(a){var b=this;void 0===a&&(a=this.datasets());var c=d.prototype.selections.call(this,a)[0];return a.forEach(function(a){var d=b._strokeDrawers.get(a);null!=d&&d.renderArea().selectAll(d.selector()).each(function(){c.push(this)})}),d3.selectAll(c)},e.prototype._onDatasetUpdate=function(){this._updatePieAngles(),d.prototype._onDatasetUpdate.call(this)},e.prototype._createDrawer=function(b){return new a.Drawers.Arc(b)},e.prototype.entities=function(a){var b=this;void 0===a&&(a=this.datasets());var c=d.prototype.entities.call(this,a);return c.forEach(function(a){a.position.x+=b.width()/2,a.position.y+=b.height()/2;var c=b._strokeDrawers.get(a.dataset).selectionForIndex(a.index);a.selection[0].push(c[0][0])}),c},e.prototype.sectorValue=function(a,b){return null==a?this._propertyBindings.get(e._SECTOR_VALUE_KEY):(this._bindProperty(e._SECTOR_VALUE_KEY,a,b),this._updatePieAngles(),this.render(),this)},e.prototype.innerRadius=function(a,b){return null==a?this._propertyBindings.get(e._INNER_RADIUS_KEY):(this._bindProperty(e._INNER_RADIUS_KEY,a,b),this.render(),this)},e.prototype.outerRadius=function(a,b){return null==a?this._propertyBindings.get(e._OUTER_RADIUS_KEY):(this._bindProperty(e._OUTER_RADIUS_KEY,a,b),this.render(),this)},e.prototype.labelsEnabled=function(a){return null==a?this._labelsEnabled:(this._labelsEnabled=a,this.render(),this)},e.prototype.labelFormatter=function(a){return null==a?this._labelFormatter:(this._labelFormatter=a,this.render(),this)},e.prototype.entitiesAt=function(a){var b={x:this.width()/2,y:this.height()/2},c={x:a.x-b.x,y:a.y-b.y},d=this._sliceIndexForPoint(c);return null==d?[]:[this.entities()[d]]},e.prototype._propertyProjectors=function(){var b=this,c=d.prototype._propertyProjectors.call(this),e=a.Plot._scaledAccessor(this.innerRadius()),f=a.Plot._scaledAccessor(this.outerRadius());return c.d=function(a,c,d){return d3.svg.arc().innerRadius(e(a,c,d)).outerRadius(f(a,c,d)).startAngle(b._startAngles[c]).endAngle(b._endAngles[c])(a,c)},c},e.prototype._updatePieAngles=function(){if(null!=this.sectorValue()&&0!==this.datasets().length){var b=a.Plot._scaledAccessor(this.sectorValue()),c=this.datasets()[0],d=this._getDataToDraw().get(c),e=d3.layout.pie().sort(null).value(function(a,d){return b(a,d,c)})(d);this._startAngles=e.map(function(a){return a.startAngle}),this._endAngles=e.map(function(a){return a.endAngle})}},e.prototype._getDataToDraw=function(){var b=d.prototype._getDataToDraw.call(this);if(0===this.datasets().length)return b;var c=a.Plot._scaledAccessor(this.sectorValue()),f=this.datasets()[0],g=b.get(f),h=g.filter(function(a,b){return e._isValidData(c(a,b,f))});return b.set(f,h),b},e._isValidData=function(b){return a.Utils.Math.isValidNumber(b)&&b>=0},e.prototype._pixelPoint=function(b,c,d){var f=a.Plot._scaledAccessor(this.sectorValue());if(!e._isValidData(f(b,c,d)))return{x:0/0,y:0/0};var g=a.Plot._scaledAccessor(this.innerRadius())(b,c,d),h=a.Plot._scaledAccessor(this.outerRadius())(b,c,d),i=(g+h)/2,j=d3.layout.pie().sort(null).value(function(a,b){var c=f(a,b,d);return e._isValidData(c)?c:0})(d.data()),k=j[c].startAngle,l=j[c].endAngle,m=(k+l)/2;return{x:i*Math.sin(m),y:-i*Math.cos(m)}},e.prototype._additionalPaint=function(b){var c=this;this._renderArea.select(".label-area").remove(),this._labelsEnabled&&a.Utils.Window.setTimeout(function(){return c._drawLabels()},b);var d=this._generateStrokeDrawSteps(),e=this._getDataToDraw();this.datasets().forEach(function(a){return c._strokeDrawers.get(a).draw(e.get(a),d)})},e.prototype._generateStrokeDrawSteps=function(){var b=this._generateAttrToProjector();return[{attrToProjector:b,animator:new a.Animators.Null}]},e.prototype._sliceIndexForPoint=function(a){var b=Math.sqrt(Math.pow(a.x,2)+Math.pow(a.y,2)),c=Math.acos(-a.y/b);a.x<0&&(c=2*Math.PI-c);for(var d,e=0;ec){d=e;break}if(void 0!==d){var f=this.datasets()[0],g=f.data()[d],h=this.innerRadius().accessor(g,d,f),i=this.outerRadius().accessor(g,d,f);if(b>h&&i>b)return d}return null},e.prototype._drawLabels=function(){var b=this,d=this._generateAttrToProjector(),e=this._renderArea.append("g").classed("label-area",!0),f=new c.Measurers.Measurer(e),g=new c.Writers.Writer(f),h=this.datasets()[0],i=this._getDataToDraw().get(h);i.forEach(function(c,i){var j=b.sectorValue().accessor(c,i,h);if(a.Utils.Math.isValidNumber(j)){j=b._labelFormatter(j);var k=f.measure(j),l=(b._endAngles[i]+b._startAngles[i])/2,m=b.outerRadius().accessor(c,i,h);b.outerRadius().scale&&(m=b.outerRadius().scale.scale(m));var n=b.innerRadius().accessor(c,i,h);b.innerRadius().scale&&(n=b.innerRadius().scale.scale(n));var o=(m+n)/2,p=Math.sin(l)*o-k.width/2,q=-Math.cos(l)*o-k.height/2,r=[{x:p,y:q},{x:p,y:q+k.height},{x:p+k.width,y:q},{x:p+k.width,y:q+k.height}],s=r.every(function(a){return Math.abs(a.x)<=b.width()/2&&Math.abs(a.y)<=b.height()/2});if(s){var t=r.map(function(a){return b._sliceIndexForPoint(a)});s=t.every(function(a){return a===i})}var u=d.fill(c,i,h),v=1.6*a.Utils.Color.contrast("white",u)n||y.minp)return;if(f._overlayLabel(x,y,k,e,b))return;var z=null==g.fill?"black":g.fill(c,k,d),A=1.6*a.Utils.Color.contrast("white",z)=p-i&&q+i>=h)l=0;else{var r=d._isVertical?m.y:m.x;l=Math.abs(h-r)}}(e>k||k===e&&f>l)&&(c=j,e=k,f=l)}}),c},f.prototype._visibleOnPlot=function(b,c,d){a.Utils.Window.deprecated("Bar._visibleOnPlot()","v1.1.0");var e={min:0,max:this.width()},f={min:0,max:this.height()},g=a.Utils.DOM.elementBBox(d);return a.Utils.DOM.intersectsBBox(e,f,g)},f.prototype._entityVisibleOnPlot=function(b,c,d,e){var f={min:0,max:this.width()},g={min:0,max:this.height()},h=this._generateAttrToProjector(),i=h.width(c,d,e),j=h.height(c,d,e),k={x:b.x-i/2,y:b.y,width:i,height:j};return a.Utils.DOM.intersectsBBox(f,g,k)},f.prototype.entitiesAt=function(a){return this._entitiesIntersecting(a.x,a.y)},f.prototype.entitiesIn=function(a,b){var c,d;if(null==b){var e=a;c={min:e.topLeft.x,max:e.bottomRight.x},d={min:e.topLeft.y,max:e.bottomRight.y}}else c=a,d=b;return this._entitiesIntersecting(c,d)},f.prototype._entitiesIntersecting=function(b,c){var d=[];return this.entities().forEach(function(e){a.Utils.DOM.intersectsBBox(b,c,a.Utils.DOM.elementBBox(e.selection))&&d.push(e)}),d},f.prototype._updateValueScale=function(){if(this._projectorsReady()){var b=this._isVertical?this.y().scale:this.x().scale;if(b instanceof a.QuantitativeScale){var c=b;c.addPaddingExceptionsProvider(this._baselineValueProvider),c.addIncludedValuesProvider(this._baselineValueProvider)}}},f.prototype._additionalPaint=function(b){var c=this,d=this._isVertical?this.y().scale:this.x().scale,e=d.scale(this.baselineValue()),f={x1:this._isVertical?0:e,y1:this._isVertical?e:0,x2:this._isVertical?this.width():e,y2:this._isVertical?e:this.height()};this._getAnimator("baseline").animate(this._baseline,f),this.datasets().forEach(function(a){return c._labelConfig.get(a).labelArea.selectAll("g").remove()}),this._labelsEnabled&&a.Utils.Window.setTimeout(function(){return c._drawLabels()},b)},f.prototype._extentsForProperty=function(b){var c,d=this,f=e.prototype._extentsForProperty.call(this,b);if("x"===b&&this._isVertical)c=this.x();else{if("y"!==b||this._isVertical)return f;c=this.y()}if(!(c&&c.scale&&c.scale instanceof a.QuantitativeScale))return f;var g=c.scale;return f=f.map(function(a){return[g.invert(g.scale(a[0])-d._barPixelWidth/2),g.invert(g.scale(a[1])+d._barPixelWidth/2)]})},f.prototype._drawLabels=function(){var a=this,b=this._getDataToDraw(),c=!1;this.datasets().forEach(function(d){return c=c||a._drawLabel(b.get(d),d)}),this._hideBarsIfAnyAreTooWide&&c&&this.datasets().forEach(function(b){return a._labelConfig.get(b).labelArea.selectAll("g").remove()})},f.prototype._drawLabel=function(b,c){var d=this,e=this._generateAttrToProjector(),g=this._labelConfig.get(c),h=g.labelArea,i=g.measurer,j=g.writer,k=b.map(function(b,g){var k=d._isVertical?d.y().accessor:d.x().accessor,l=a.Plot._scaledAccessor(d._isVertical?d.y():d.x()),m=d._isVertical?d.y().scale:d.x().scale,n=m.scale(d.baselineValue()),o=d._labelFormatter(k(b,g,c)).toString(),p=e.width(b,g,c),q=e.height(b,g,c),r=e.x(b,g,c),s=e.y(b,g,c),t=l(b,g,c)<=n,u=i.measure(o),v=e.fill(b,g,c),w=1.6*a.Utils.Color.contrast("white",v)A;if(u.height<=q&&u.width<=p){var C=Math.min((x-y)/2,f._LABEL_VERTICAL_PADDING);t||(C=-1*C),d._isVertical?s+=C:r+=C;var D=!0,E={x:r,y:t?s:s+q-u.height};E.x=d._isVertical?r+p/2-u.width/2:t?r:r+p-u.width,(E.x<0||E.x+u.width>d.width()||E.y<0||E.y+u.height>d.height())&&(D=!1);var F=h.append("g").attr("transform","translate("+r+","+s+")"),G=w?"dark-label":"light-label";F.classed(G,!0),F.style("visibility",D?"inherit":"hidden");var H,I;d._isVertical?(H="center",I=t?"top":"bottom"):(H=t?"left":"right",I="center");var J={selection:F,xAlign:H,yAlign:I,textRotation:0};j.write(o,p,q,J)}return B});return k.some(function(a){return a})},f.prototype._generateDrawSteps=function(){var a=[];if(this._animateOnNextRender()){var b=this._generateAttrToProjector(),c=this._isVertical?this.y().scale:this.x().scale,e=c.scale(this.baselineValue()),f=this._isVertical?"y":"x",g=this._isVertical?"height":"width";b[f]=function(){return e},b[g]=function(){return 0},a.push({attrToProjector:b,animator:this._getAnimator(d.Animator.RESET)})}return a.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(d.Animator.MAIN)}),a},f.prototype._generateAttrToProjector=function(){var b=e.prototype._generateAttrToProjector.call(this),c=this._isVertical?this.y().scale:this.x().scale,d=this._isVertical?"y":"x",f=this._isVertical?"x":"y",g=c.scale(this.baselineValue()),h=a.Plot._scaledAccessor(this._isVertical?this.x():this.y()),i=b.width,j=a.Plot._scaledAccessor(this._isVertical?this.y():this.x()),k=function(a,b,c){return Math.abs(g-j(a,b,c))};return b.width=this._isVertical?i:k,b.height=this._isVertical?k:i,b[f]=function(a,b,c){return h(a,b,c)-i(a,b,c)/2},b[d]=function(a,b,c){var d=j(a,b,c);return d>g?g:d},b},f.prototype._getBarPixelWidth=function(){if(!this._projectorsReady())return 0;var b,c=this._isVertical?this.x().scale:this.y().scale;if(c instanceof a.Scales.Category)b=c.rangeBand();else{var d=this._isVertical?this.x().accessor:this.y().accessor,e=d3.set(a.Utils.Array.flatten(this.datasets().map(function(a){return a.data().map(function(b,c){return d(b,c,a)}).filter(function(a){return null!=a}).map(function(a){return a.valueOf()})}))).values().map(function(a){return+a});e.sort(function(a,b){return a-b});var g=e.map(function(a){return c.scale(a)}),h=d3.pairs(g),i=this._isVertical?this.width():this.height();b=a.Utils.Math.min(h,function(a){return Math.abs(a[1]-a[0])},i*f._SINGLE_BAR_DIMENSION_RATIO),b*=f._BAR_WIDTH_RATIO}return b},f.prototype._updateBarPixelWidth=function(){this._barPixelWidth=this._getBarPixelWidth()},f.prototype.entities=function(a){var b=this;if(void 0===a&&(a=this.datasets()),!this._projectorsReady())return[];var c=e.prototype.entities.call(this,a),d=(this._isVertical?this.y().scale:this.x().scale).scale(this.baselineValue());return c.forEach(function(a){var c=a.selection;b._isVertical&&Math.floor(+c.attr("y"))>=Math.floor(d)?a.position.y+=+c.attr("height"):!b._isVertical&&Math.floor(+c.attr("x"))n==p>=f&&(j=f-n,k=p-n,m=q-o,l=j*m/k,e.left.push({x:f,y:c.invert(o+l)})),g>n==p>=g&&(j=g-n,k=p-n,m=q-o,l=j*m/k,e.right.push({x:g,y:c.invert(o+l)})),i>o==q>=i&&(k=p-n,l=i-o,m=q-o,j=l*k/m,e.top.push({x:d.invert(n+j),y:i})),h>o==q>=h&&(k=p-n,l=h-o,m=q-o,j=l*k/m,e.bottom.push({x:d.invert(n+j),y:h}))}),e},e.prototype._getResetYFunction=function(){var a=this.y().scale.domain(),b=Math.max(a[0],a[1]),c=Math.min(a[0],a[1]),d=0>b&&b||c>0&&c||0,e=this.y().scale.scale(d);return function(){return e}},e.prototype._generateDrawSteps=function(){var b=[];if(this._animateOnNextRender()){var d=this._generateAttrToProjector();d.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),this._getResetYFunction()),b.push({attrToProjector:d,animator:this._getAnimator(c.Animator.RESET)})}return b.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(c.Animator.MAIN)}),b},e.prototype._generateAttrToProjector=function(){var a=d.prototype._generateAttrToProjector.call(this);return Object.keys(a).forEach(function(b){if("d"!==b){var c=a[b];a[b]=function(a,b,d){return a.length>0?c(a[0],b,d):null}}}),a},e.prototype.entityNearest=function(a){var b,c=this,d=1/0,e=1/0;return this.entities().forEach(function(f){if(c._entityVisibleOnPlot(f.position,f.datum,f.index,f.dataset)){var g=Math.abs(a.x-f.position.x),h=Math.abs(a.y-f.position.y);(d>g||g===d&&e>h)&&(b=f,d=g,e=h)}}),b},e.prototype._propertyProjectors=function(){var b=d.prototype._propertyProjectors.call(this);return b.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),a.Plot._scaledAccessor(this.y())),b},e.prototype._constructLineProjector=function(b,c){var d=this,e=function(b,c,e){var f=a.Plot._scaledAccessor(d.x())(b,c,e),g=a.Plot._scaledAccessor(d.y())(b,c,e);return null!=f&&!a.Utils.Math.isNaN(f)&&null!=g&&!a.Utils.Math.isNaN(g)};return function(a,f,g){return d3.svg.line().x(function(a,c){return b(a,c,g)}).y(function(a,b){return c(a,b,g)}).interpolate(d.interpolator()).defined(function(a,b){return e(a,b,g)})(a)}},e.prototype._getDataToDraw=function(){var b=new a.Utils.Map;return this.datasets().forEach(function(a){return b.set(a,[a.data()])}),b},e}(a.XYPlot);c.Line=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(){d.call(this),this.addClass("area-plot"),this.y0(0),this.attr("fill-opacity",.25),this.attr("fill",(new a.Scales.Color).range()[0]),this._lineDrawers=new a.Utils.Map}return b(e,d),e.prototype._setup=function(){var a=this;d.prototype._setup.call(this),this._lineDrawers.forEach(function(b){return b.renderArea(a._renderArea.append("g"))})},e.prototype.y=function(a,b){if(null==a)return d.prototype.y.call(this);if(null==b?d.prototype.y.call(this,a):d.prototype.y.call(this,a,b),null!=b){var c=this.y0().accessor;null!=c&&this._bindProperty(e._Y0_KEY,c,b),this._updateYScale()}return this},e.prototype.y0=function(a){if(null==a)return this._propertyBindings.get(e._Y0_KEY);var b=this.y(),c=b&&b.scale;return this._bindProperty(e._Y0_KEY,a,c),this._updateYScale(),this.render(),this},e.prototype._onDatasetUpdate=function(){d.prototype._onDatasetUpdate.call(this),this._updateYScale()},e.prototype.addDataset=function(a){return d.prototype.addDataset.call(this,a),this},e.prototype._addDataset=function(b){var c=new a.Drawers.Line(b);return this._isSetup&&c.renderArea(this._renderArea.append("g")),this._lineDrawers.set(b,c),d.prototype._addDataset.call(this,b),this},e.prototype._removeDatasetNodes=function(a){d.prototype._removeDatasetNodes.call(this,a),this._lineDrawers.get(a).remove()},e.prototype._additionalPaint=function(){var a=this,b=this._generateLineDrawSteps(),c=this._getDataToDraw();this.datasets().forEach(function(d){return a._lineDrawers.get(d).draw(c.get(d),b)})},e.prototype._generateLineDrawSteps=function(){var b=[];if(this._animateOnNextRender()){var d=this._generateLineAttrToProjector();d.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),this._getResetYFunction()),b.push({attrToProjector:d,animator:this._getAnimator(c.Animator.RESET)})}return b.push({attrToProjector:this._generateLineAttrToProjector(),animator:this._getAnimator(c.Animator.MAIN)}),b},e.prototype._generateLineAttrToProjector=function(){var b=this._generateAttrToProjector();return b.d=this._constructLineProjector(a.Plot._scaledAccessor(this.x()),a.Plot._scaledAccessor(this.y())),b},e.prototype._createDrawer=function(b){return new a.Drawers.Area(b)},e.prototype._generateDrawSteps=function(){var b=[];if(this._animateOnNextRender()){var d=this._generateAttrToProjector();d.d=this._constructAreaProjector(a.Plot._scaledAccessor(this.x()),this._getResetYFunction(),a.Plot._scaledAccessor(this.y0())),b.push({attrToProjector:d,animator:this._getAnimator(c.Animator.RESET)})}return b.push({attrToProjector:this._generateAttrToProjector(),animator:this._getAnimator(c.Animator.MAIN)}),b},e.prototype._updateYScale=function(){var b=this._propertyExtents.get("y0"),c=a.Utils.Array.flatten(b),d=a.Utils.Array.uniq(c),e=1===d.length?d[0]:null,f=this.y(),g=f&&f.scale;null!=g&&(null!=this._constantBaselineValueProvider&&(g.removePaddingExceptionsProvider(this._constantBaselineValueProvider),this._constantBaselineValueProvider=null),null!=e&&(this._constantBaselineValueProvider=function(){return[e]},g.addPaddingExceptionsProvider(this._constantBaselineValueProvider)))},e.prototype._getResetYFunction=function(){return a.Plot._scaledAccessor(this.y0())},e.prototype._propertyProjectors=function(){var b=d.prototype._propertyProjectors.call(this);return b.d=this._constructAreaProjector(a.Plot._scaledAccessor(this.x()),a.Plot._scaledAccessor(this.y()),a.Plot._scaledAccessor(this.y0())),b},e.prototype.selections=function(a){var b=this;void 0===a&&(a=this.datasets());var c=d.prototype.selections.call(this,a)[0],e=a.map(function(a){return b._lineDrawers.get(a)}).filter(function(a){return null!=a});return e.forEach(function(a,b){return c.push(a.selectionForIndex(b).node())}),d3.selectAll(c)},e.prototype._constructAreaProjector=function(b,c,d){var e=this,f=function(b,c,d){var f=a.Plot._scaledAccessor(e.x())(b,c,d),g=a.Plot._scaledAccessor(e.y())(b,c,d);return a.Utils.Math.isValidNumber(f)&&a.Utils.Math.isValidNumber(g)};return function(a,g,h){var i=d3.svg.area().x(function(a,c){return b(a,c,h)}).y1(function(a,b){return c(a,b,h)}).y0(function(a,b){return d(a,b,h)}).interpolate(e.interpolator()).defined(function(a,b){return f(a,b,h)});return i(a)}},e._Y0_KEY="y0",e}(c.Line);c.Area=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(b){void 0===b&&(b=c.Bar.ORIENTATION_VERTICAL),d.call(this,b),this._clusterOffsets=new a.Utils.Map}return b(e,d),e.prototype._generateAttrToProjector=function(){var a=this,b=d.prototype._generateAttrToProjector.call(this),c=this._makeInnerScale(),e=function(){return c.rangeBand()};b.width=this._isVertical?e:b.width,b.height=this._isVertical?b.height:e;var f=b.x,g=b.y;return b.x=this._isVertical?function(b,c,d){return f(b,c,d)+a._clusterOffsets.get(d)}:function(a,b,c){return f(a,b,c)},b.y=this._isVertical?function(a,b,c){return g(a,b,c)}:function(b,c,d){return g(b,c,d)+a._clusterOffsets.get(d)},b},e.prototype._updateClusterPosition=function(){var a=this,b=this._makeInnerScale();this.datasets().forEach(function(c,d){return a._clusterOffsets.set(c,b.scale(String(d))-b.rangeBand()/2)})},e.prototype._makeInnerScale=function(){var b=new a.Scales.Category;b.domain(this.datasets().map(function(a,b){return String(b)}));var c=a.Plot._scaledAccessor(this.attr("width"));return b.range([0,c(null,0,null)]),b},e.prototype._getDataToDraw=function(){return this._updateClusterPosition(),d.prototype._getDataToDraw.call(this)},e}(c.Bar);c.ClusteredBar=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.call(this),this._baselineValue=0,this.addClass("stacked-area-plot"),this.attr("fill-opacity",1),this._stackingResult=new a.Utils.Map,this._stackedExtent=[],this._baselineValueProvider=function(){return[b._baselineValue]}}return b(d,c),d.prototype._getAnimator=function(){return new a.Animators.Null},d.prototype._setup=function(){c.prototype._setup.call(this),this._baseline=this._renderArea.append("line").classed("baseline",!0)},d.prototype.x=function(a,b){return null==a?c.prototype.x.call(this):(null==b?c.prototype.x.call(this,a):c.prototype.x.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},d.prototype.y=function(a,b){return null==a?c.prototype.y.call(this):(null==b?c.prototype.y.call(this,a):c.prototype.y.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},d.prototype._additionalPaint=function(){var a=this.y().scale.scale(this._baselineValue),b={x1:0,y1:a,x2:this.width(),y2:a};this._getAnimator("baseline").animate(this._baseline,b)},d.prototype._updateYScale=function(){var a=this.y(),b=a&&a.scale;null!=b&&(b.addPaddingExceptionsProvider(this._baselineValueProvider),b.addIncludedValuesProvider(this._baselineValueProvider))},d.prototype._onDatasetUpdate=function(){return this._updateStackExtentsAndOffsets(),c.prototype._onDatasetUpdate.call(this),this},d.prototype._updateExtentsForProperty=function(a){c.prototype._updateExtentsForProperty.call(this,a),"x"!==a&&"y"!==a||!this._projectorsReady()||this._updateStackExtentsAndOffsets()},d.prototype._extentsForProperty=function(a){var b="y";return a===b?[this._stackedExtent]:c.prototype._extentsForProperty.call(this,a)},d.prototype._updateStackExtentsAndOffsets=function(){if(this._projectorsReady()){var b=this.datasets(),c=this.x().accessor,d=this.y().accessor,e=this._filterForProperty("y");this._checkSameDomain(b,c),this._stackingResult=a.Utils.Stacking.stack(b,c,d),this._stackedExtent=a.Utils.Stacking.stackedExtent(this._stackingResult,c,e) +}},d.prototype._checkSameDomain=function(b,c){var e=b.map(function(a){return d3.set(a.data().map(function(b,d){return c(b,d,a).toString()})).values()}),f=d._domainKeys(b,c);e.some(function(a){return a.length!==f.length})&&a.Utils.Window.warn("the domains across the datasets are not the same. Plot may produce unintended behavior.")},d._domainKeys=function(a,b){var c=d3.set();return a.forEach(function(a){a.data().forEach(function(d,e){c.add(b(d,e,a))})}),c.values()},d.prototype._propertyProjectors=function(){var b=this,d=c.prototype._propertyProjectors.call(this),e=this.y().accessor,f=this.x().accessor,g=function(b,c,d){return a.Utils.Stacking.normalizeKey(f(b,c,d))},h=function(a,c,d){return b.y().scale.scale(+e(a,c,d)+b._stackingResult.get(d).get(g(a,c,d)).offset)},i=function(a,c,d){return b.y().scale.scale(b._stackingResult.get(d).get(g(a,c,d)).offset)};return d.d=this._constructAreaProjector(a.Plot._scaledAccessor(this.x()),h,i),d},d.prototype._pixelPoint=function(b,d,e){var f=c.prototype._pixelPoint.call(this,b,d,e),g=this.x().accessor(b,d,e),h=this.y().accessor(b,d,e),i=this.y().scale.scale(+h+this._stackingResult.get(e).get(a.Utils.Stacking.normalizeKey(g)).offset);return{x:f.x,y:i}},d}(c.Area);c.StackedArea=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(b){void 0===b&&(b=c.Bar.ORIENTATION_VERTICAL),d.call(this,b),this.addClass("stacked-bar-plot"),this._stackingResult=new a.Utils.Map,this._stackedExtent=[]}return b(e,d),e.prototype.x=function(a,b){return null==a?d.prototype.x.call(this):(null==b?d.prototype.x.call(this,a):d.prototype.x.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},e.prototype.y=function(a,b){return null==a?d.prototype.y.call(this):(null==b?d.prototype.y.call(this,a):d.prototype.y.call(this,a,b),this._updateStackExtentsAndOffsets(),this)},e.prototype._generateAttrToProjector=function(){var b=this,c=d.prototype._generateAttrToProjector.call(this),e=this._isVertical?"y":"x",f=this._isVertical?"x":"y",g=this._isVertical?this.y().scale:this.x().scale,h=this._propertyBindings.get(e).accessor,i=this._propertyBindings.get(f).accessor,j=function(b,c,d){return a.Utils.Stacking.normalizeKey(i(b,c,d))},k=function(a,c,d){return g.scale(b._stackingResult.get(d).get(j(a,c,d)).offset)},l=function(a,c,d){return g.scale(+h(a,c,d)+b._stackingResult.get(d).get(j(a,c,d)).offset)},m=function(a,b,c){return Math.abs(l(a,b,c)-k(a,b,c))};c[this._isVertical?"height":"width"]=m;var n=function(a,b,c){return+h(a,b,c)<0?k(a,b,c):l(a,b,c)};return c[e]=function(a,c,d){return b._isVertical?n(a,c,d):n(a,c,d)-m(a,c,d)},c},e.prototype._onDatasetUpdate=function(){return this._updateStackExtentsAndOffsets(),d.prototype._onDatasetUpdate.call(this),this},e.prototype._updateExtentsForProperty=function(a){d.prototype._updateExtentsForProperty.call(this,a),"x"!==a&&"y"!==a||!this._projectorsReady()||this._updateStackExtentsAndOffsets()},e.prototype._extentsForProperty=function(a){var b=this._isVertical?"y":"x";return a===b?[this._stackedExtent]:d.prototype._extentsForProperty.call(this,a)},e.prototype._updateStackExtentsAndOffsets=function(){if(this._projectorsReady()){var b=this.datasets(),c=this._isVertical?this.x().accessor:this.y().accessor,d=this._isVertical?this.y().accessor:this.x().accessor,e=this._filterForProperty(this._isVertical?"y":"x");this._stackingResult=a.Utils.Stacking.stack(b,c,d),this._stackedExtent=a.Utils.Stacking.stackedExtent(this._stackingResult,c,e)}},e}(c.Bar);c.StackedBar=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){c.call(this),this.addClass("segment-plot"),this.attr("stroke",(new a.Scales.Color).range()[0]),this.attr("stroke-width","2px")}return b(d,c),d.prototype._createDrawer=function(b){return new a.Drawers.Segment(b)},d.prototype._generateDrawSteps=function(){return[{attrToProjector:this._generateAttrToProjector(),animator:new a.Animators.Null}]},d.prototype._updateExtentsForProperty=function(a){c.prototype._updateExtentsForProperty.call(this,a),"x"===a?c.prototype._updateExtentsForProperty.call(this,"x2"):"y"===a&&c.prototype._updateExtentsForProperty.call(this,"y2")},d.prototype._filterForProperty=function(a){return"x2"===a?c.prototype._filterForProperty.call(this,"x"):"y2"===a?c.prototype._filterForProperty.call(this,"y"):c.prototype._filterForProperty.call(this,a)},d.prototype.x=function(a,b){if(null==a)return c.prototype.x.call(this);if(null==b)c.prototype.x.call(this,a);else{c.prototype.x.call(this,a,b);var e=this.x2(),f=e&&e.accessor;null!=f&&this._bindProperty(d._X2_KEY,f,b)}return this},d.prototype.x2=function(a){if(null==a)return this._propertyBindings.get(d._X2_KEY);var b=this.x(),c=b&&b.scale;return this._bindProperty(d._X2_KEY,a,c),this.render(),this},d.prototype.y=function(a,b){if(null==a)return c.prototype.y.call(this);if(null==b)c.prototype.y.call(this,a);else{c.prototype.y.call(this,a,b);var e=this.y2(),f=e&&e.accessor;null!=f&&this._bindProperty(d._Y2_KEY,f,b)}return this},d.prototype.y2=function(a){if(null==a)return this._propertyBindings.get(d._Y2_KEY);var b=this.y(),c=b&&b.scale;return this._bindProperty(d._Y2_KEY,a,c),this.render(),this},d.prototype._propertyProjectors=function(){var b=c.prototype._propertyProjectors.call(this);return b.x1=a.Plot._scaledAccessor(this.x()),b.x2=a.Plot._scaledAccessor(null==this.x2()?this.x():this.x2()),b.y1=a.Plot._scaledAccessor(this.y()),b.y2=a.Plot._scaledAccessor(null==this.y2()?this.y():this.y2()),b},d.prototype.entitiesIn=function(a,b){var c,d;if(null==b){var e=a;c={min:e.topLeft.x,max:e.bottomRight.x},d={min:e.topLeft.y,max:e.bottomRight.y}}else c=a,d=b;return this._entitiesIntersecting(c,d)},d.prototype._entitiesIntersecting=function(a,b){var c=this,d=[],e=this._generateAttrToProjector();return this.entities().forEach(function(f){c._lineIntersectsBox(f,a,b,e)&&d.push(f)}),d},d.prototype._lineIntersectsBox=function(a,b,c,d){var e=this,f=d.x1(a.datum,a.index,a.dataset),g=d.x2(a.datum,a.index,a.dataset),h=d.y1(a.datum,a.index,a.dataset),i=d.y2(a.datum,a.index,a.dataset);if(b.min<=f&&f<=b.max&&c.min<=h&&h<=c.max||b.min<=g&&g<=b.max&&c.min<=i&&i<=c.max)return!0;var j={x:f,y:h},k={x:g,y:i},l=[{x:b.min,y:c.min},{x:b.min,y:c.max},{x:b.max,y:c.max},{x:b.max,y:c.min}],m=l.filter(function(a,b){return 0!==b?e._lineIntersectsSegment(j,k,a,l[b-1])&&e._lineIntersectsSegment(a,l[b-1],j,k):void 0});return m.length>0},d.prototype._lineIntersectsSegment=function(a,b,c,d){var e=function(a,b,c){return(b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x)};return e(a,b,c)*e(a,b,d)<0},d._X2_KEY="x2",d._Y2_KEY="y2",d}(a.XYPlot);c.Segment=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){c.call(this),this._connectorsEnabled=!1,this.addClass("waterfall-plot")}return b(d,c),d.prototype.connectorsEnabled=function(a){return null==a?this._connectorsEnabled:(this._connectorsEnabled=a,this)},d.prototype.total=function(a){return null==a?this._propertyBindings.get(d._TOTAL_KEY):(this._bindProperty(d._TOTAL_KEY,a,null),this)},d.prototype._additionalPaint=function(b){var c=this;this._connectorArea.selectAll("line").remove(),this._connectorsEnabled&&a.Utils.Window.setTimeout(function(){return c._drawConnectors()},b)},d.prototype._createNodesForDataset=function(a){var b=c.prototype._createNodesForDataset.call(this,a);return this._connectorArea=this._renderArea.append("g").classed(d._CONNECTOR_AREA_CLASS,!0),b},d.prototype._extentsForProperty=function(a){var b="y";return a===b?[this._extent]:c.prototype._extentsForProperty.call(this,a)},d.prototype._generateAttrToProjector=function(){var b=this,e=c.prototype._generateAttrToProjector.call(this),f=this.y().scale,g=a.Plot._scaledAccessor(this.total()),h=this.attr("y");null==h&&(e.y=function(a,c,d){var e=b.y().accessor(a,c,d),h=g(a,c,d);if(h)return Math.min(f.scale(e),f.scale(0));var i=b._subtotals[c];if(0===c)return f.scale(0>e?i-e:i);var j=b._subtotals[c-1];return f.scale(i>j?i:j)});var i=this.attr("height");return null==i&&(e.height=function(a,c,d){var e=g(a,c,d),h=b.y().accessor(a,c,d);if(e)return Math.abs(f.scale(h)-f.scale(0));var i=b._subtotals[c];if(0===c)return Math.abs(f.scale(i)-f.scale(i-h));var j=b._subtotals[c-1];return Math.abs(f.scale(i)-f.scale(j))}),e["class"]=function(a,c,e){var f="";null!=b.attr("class")&&(f=b.attr("class").accessor(a,c,e)+" ");var h=g(a,c,e);if(h)return f+d._BAR_TOTAL_CLASS;var i=b.y().accessor(a,c,e);return f+(i>0?d._BAR_GROWTH_CLASS:d._BAR_DECLINE_CLASS)},e},d.prototype._onDatasetUpdate=function(){return this._updateSubtotals(),c.prototype._onDatasetUpdate.call(this),this},d.prototype._calculateSubtotalsAndExtent=function(a){var b=this,c=Number.MAX_VALUE,d=Number.MIN_VALUE,e=0,f=!1;a.data().forEach(function(g,h){var i=b.y().accessor(g,h,a),j=b.total().accessor(g,h,a);if(j&&0!==h||(e+=i),b._subtotals.push(e),c>e&&(c=e),e>d&&(d=e),j&&(c>i&&(c=i),i>d&&(d=i)),!f&&j){for(var k=i-e,l=0;l0&&this._subtotals[c]>this._subtotals[e]||this._subtotals[c]<0&&this._subtotals[c]>=this._subtotals[e])&&(j=a.y(f,c,b)+a.height(f,c,b)),this._connectorArea.append("line").classed(d._CONNECTOR_CLASS,!0).attr("x1",h).attr("x2",i).attr("y1",j).attr("y2",j)}},d.prototype._updateSubtotals=function(){var a=this.datasets();if(a.length>0){var b=a[a.length-1];this._subtotals=new Array,this._calculateSubtotalsAndExtent(b)}},d._BAR_DECLINE_CLASS="waterfall-decline",d._BAR_GROWTH_CLASS="waterfall-growth",d._BAR_TOTAL_CLASS="waterfall-total",d._CONNECTOR_CLASS="connector",d._CONNECTOR_AREA_CLASS="connector-area",d._TOTAL_KEY="total",d}(c.Bar);c.Waterfall=d}(c=a.Plots||(a.Plots={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function a(){}return a.prototype.totalTime=function(){return 0},a.prototype.animate=function(a,b){return a.attr(b)},a}();a.Null=b}(b=a.Animators||(a.Animators={}))}(a||(a={}));var a;!function(a){var b;!function(a){var b=function(){function a(){this._startDelay=a._DEFAULT_START_DELAY_MILLISECONDS,this._stepDuration=a._DEFAULT_STEP_DURATION_MILLISECONDS,this._stepDelay=a._DEFAULT_ITERATIVE_DELAY_MILLISECONDS,this._maxTotalDuration=a._DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS,this._easingMode=a._DEFAULT_EASING_MODE}return a.prototype.totalTime=function(a){var b=this._getAdjustedIterativeDelay(a);return this.startDelay()+b*Math.max(a-1,0)+this.stepDuration()},a.prototype.animate=function(a,b){var c=this,d=a[0].length,e=this._getAdjustedIterativeDelay(d);return a.transition().ease(this.easingMode()).duration(this.stepDuration()).delay(function(a,b){return c.startDelay()+e*b}).attr(b)},a.prototype.startDelay=function(a){return null==a?this._startDelay:(this._startDelay=a,this)},a.prototype.stepDuration=function(a){return null==a?Math.min(this._stepDuration,this._maxTotalDuration):(this._stepDuration=a,this)},a.prototype.stepDelay=function(a){return null==a?this._stepDelay:(this._stepDelay=a,this)},a.prototype.maxTotalDuration=function(a){return null==a?this._maxTotalDuration:(this._maxTotalDuration=a,this)},a.prototype.easingMode=function(a){return null==a?this._easingMode:(this._easingMode=a,this)},a.prototype._getAdjustedIterativeDelay=function(a){var b=this.maxTotalDuration()-this.stepDuration();b=Math.max(b,0);var c=b/Math.max(a-1,1);return Math.min(this.stepDelay(),c)},a._DEFAULT_START_DELAY_MILLISECONDS=0,a._DEFAULT_STEP_DURATION_MILLISECONDS=300,a._DEFAULT_ITERATIVE_DELAY_MILLISECONDS=15,a._DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS=1/0,a._DEFAULT_EASING_MODE="exp-out",a}();a.Easing=b}(b=a.Animators||(a.Animators={}))}(a||(a={}));var a;!function(a){var b=function(){function a(){this._eventToCallback={},this._callbacks=[],this._connected=!1}return a.prototype._hasNoListeners=function(){return this._callbacks.every(function(a){return 0===a.size})},a.prototype._connect=function(){var a=this;this._connected||(Object.keys(this._eventToCallback).forEach(function(b){var c=a._eventToCallback[b];document.addEventListener(b,c)}),this._connected=!0)},a.prototype._disconnect=function(){var a=this;this._connected&&this._hasNoListeners()&&(Object.keys(this._eventToCallback).forEach(function(b){var c=a._eventToCallback[b];document.removeEventListener(b,c)}),this._connected=!1)},a.prototype._setCallback=function(a,b){this._connect(),a.add(b)},a.prototype._unsetCallback=function(a,b){a["delete"](b),this._disconnect()},a}();a.Dispatcher=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(b){var d=this;c.call(this),this._translator=a.Utils.ClientToSVGTranslator.getTranslator(b),this._lastMousePosition={x:-1,y:-1},this._moveCallbacks=new a.Utils.CallbackSet,this._downCallbacks=new a.Utils.CallbackSet,this._upCallbacks=new a.Utils.CallbackSet,this._wheelCallbacks=new a.Utils.CallbackSet,this._dblClickCallbacks=new a.Utils.CallbackSet,this._callbacks=[this._moveCallbacks,this._downCallbacks,this._upCallbacks,this._wheelCallbacks,this._dblClickCallbacks];var e=function(a){return d._measureAndDispatch(a,d._moveCallbacks,"page")};this._eventToCallback.mouseover=e,this._eventToCallback.mousemove=e,this._eventToCallback.mouseout=e,this._eventToCallback.mousedown=function(a){return d._measureAndDispatch(a,d._downCallbacks)},this._eventToCallback.mouseup=function(a){return d._measureAndDispatch(a,d._upCallbacks,"page")},this._eventToCallback.wheel=function(a){return d._measureAndDispatch(a,d._wheelCallbacks)},this._eventToCallback.dblclick=function(a){return d._measureAndDispatch(a,d._dblClickCallbacks)}}return b(d,c),d.getDispatcher=function(b){var c=a.Utils.DOM.boundingSVG(b),e=c[d._DISPATCHER_KEY];return null==e&&(e=new d(c),c[d._DISPATCHER_KEY]=e),e},d.prototype.onMouseMove=function(a){return this._setCallback(this._moveCallbacks,a),this},d.prototype.offMouseMove=function(a){return this._unsetCallback(this._moveCallbacks,a),this},d.prototype.onMouseDown=function(a){return this._setCallback(this._downCallbacks,a),this},d.prototype.offMouseDown=function(a){return this._unsetCallback(this._downCallbacks,a),this},d.prototype.onMouseUp=function(a){return this._setCallback(this._upCallbacks,a),this},d.prototype.offMouseUp=function(a){return this._unsetCallback(this._upCallbacks,a),this},d.prototype.onWheel=function(a){return this._setCallback(this._wheelCallbacks,a),this},d.prototype.offWheel=function(a){return this._unsetCallback(this._wheelCallbacks,a),this},d.prototype.onDblClick=function(a){return this._setCallback(this._dblClickCallbacks,a),this},d.prototype.offDblClick=function(a){return this._unsetCallback(this._dblClickCallbacks,a),this},d.prototype._measureAndDispatch=function(a,b,c){if(void 0===c&&(c="element"),"page"!==c&&"element"!==c)throw new Error("Invalid scope '"+c+"', must be 'element' or 'page'");if("page"===c||this._translator.insideSVG(a)){var d=this._translator.computePosition(a.clientX,a.clientY);null!=d&&(this._lastMousePosition=d,b.callCallbacks(this.lastMousePosition(),a))}},d.prototype.lastMousePosition=function(){return this._lastMousePosition},d._DISPATCHER_KEY="__Plottable_Dispatcher_Mouse",d}(a.Dispatcher);c.Mouse=d}(c=a.Dispatchers||(a.Dispatchers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(b){var d=this;c.call(this),this._translator=a.Utils.ClientToSVGTranslator.getTranslator(b),this._startCallbacks=new a.Utils.CallbackSet,this._moveCallbacks=new a.Utils.CallbackSet,this._endCallbacks=new a.Utils.CallbackSet,this._cancelCallbacks=new a.Utils.CallbackSet,this._callbacks=[this._moveCallbacks,this._startCallbacks,this._endCallbacks,this._cancelCallbacks],this._eventToCallback.touchstart=function(a){return d._measureAndDispatch(a,d._startCallbacks)},this._eventToCallback.touchmove=function(a){return d._measureAndDispatch(a,d._moveCallbacks,"page")},this._eventToCallback.touchend=function(a){return d._measureAndDispatch(a,d._endCallbacks,"page")},this._eventToCallback.touchcancel=function(a){return d._measureAndDispatch(a,d._cancelCallbacks,"page")}}return b(d,c),d.getDispatcher=function(b){var c=a.Utils.DOM.boundingSVG(b),e=c[d._DISPATCHER_KEY];return null==e&&(e=new d(c),c[d._DISPATCHER_KEY]=e),e},d.prototype.onTouchStart=function(a){return this._setCallback(this._startCallbacks,a),this},d.prototype.offTouchStart=function(a){return this._unsetCallback(this._startCallbacks,a),this},d.prototype.onTouchMove=function(a){return this._setCallback(this._moveCallbacks,a),this},d.prototype.offTouchMove=function(a){return this._unsetCallback(this._moveCallbacks,a),this},d.prototype.onTouchEnd=function(a){return this._setCallback(this._endCallbacks,a),this},d.prototype.offTouchEnd=function(a){return this._unsetCallback(this._endCallbacks,a),this},d.prototype.onTouchCancel=function(a){return this._setCallback(this._cancelCallbacks,a),this},d.prototype.offTouchCancel=function(a){return this._unsetCallback(this._cancelCallbacks,a),this},d.prototype._measureAndDispatch=function(a,b,c){if(void 0===c&&(c="element"),"page"!==c&&"element"!==c)throw new Error("Invalid scope '"+c+"', must be 'element' or 'page'");if("element"!==c||this._translator.insideSVG(a)){for(var d=a.changedTouches,e={},f=[],g=0;g0&&b.callCallbacks(f,e,a)}},d._DISPATCHER_KEY="__Plottable_Dispatcher_Touch",d}(a.Dispatcher);c.Touch=d}(c=a.Dispatchers||(a.Dispatchers={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.call(this),this._eventToCallback.keydown=function(a){return b._processKeydown(a)},this._eventToCallback.keyup=function(a){return b._processKeyup(a)},this._keydownCallbacks=new a.Utils.CallbackSet,this._keyupCallbacks=new a.Utils.CallbackSet,this._callbacks=[this._keydownCallbacks,this._keyupCallbacks]}return b(d,c),d.getDispatcher=function(){var a=document[d._DISPATCHER_KEY];return null==a&&(a=new d,document[d._DISPATCHER_KEY]=a),a},d.prototype.onKeyDown=function(a){return this._setCallback(this._keydownCallbacks,a),this},d.prototype.offKeyDown=function(a){return this._unsetCallback(this._keydownCallbacks,a),this},d.prototype.onKeyUp=function(a){return this._setCallback(this._keyupCallbacks,a),this},d.prototype.offKeyUp=function(a){return this._unsetCallback(this._keyupCallbacks,a),this},d.prototype._processKeydown=function(a){this._keydownCallbacks.callCallbacks(a.keyCode,a)},d.prototype._processKeyup=function(a){this._keyupCallbacks.callCallbacks(a.keyCode,a)},d._DISPATCHER_KEY="__Plottable_Dispatcher_Key",d}(a.Dispatcher);c.Key=d}(c=a.Dispatchers||(a.Dispatchers={}))}(a||(a={}));var a;!function(a){var b=function(){function a(){var a=this;this._anchorCallback=function(b){return a._anchor(b)},this._enabled=!0}return a.prototype._anchor=function(){this._isAnchored=!0},a.prototype._unanchor=function(){this._isAnchored=!1},a.prototype.attachTo=function(a){return this._disconnect(),this._componentAttachedTo=a,this._connect(),this},a.prototype._connect=function(){this.enabled()&&null!=this._componentAttachedTo&&!this._isAnchored&&this._componentAttachedTo.onAnchor(this._anchorCallback)},a.prototype.detachFrom=function(){return this._disconnect(),this._componentAttachedTo=null,this},a.prototype._disconnect=function(){this._isAnchored&&this._unanchor(),null!=this._componentAttachedTo&&this._componentAttachedTo.offAnchor(this._anchorCallback)},a.prototype.enabled=function(a){return null==a?this._enabled:(this._enabled=a,this._enabled?this._connect():this._disconnect(),this)},a.prototype._translateToComponentSpace=function(a){var b=this._componentAttachedTo.originToSVG();return{x:a.x-b.x,y:a.y-b.y}},a.prototype._isInsideComponent=function(a){return 0<=a.x&&0<=a.y&&a.x<=this._componentAttachedTo.width()&&a.y<=this._componentAttachedTo.height()},a}();a.Interaction=b}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.apply(this,arguments),this._clickedDown=!1,this._onClickCallbacks=new a.Utils.CallbackSet,this._mouseDownCallback=function(a){return b._handleClickDown(a)},this._mouseUpCallback=function(a){return b._handleClickUp(a)},this._touchStartCallback=function(a,c){return b._handleClickDown(c[a[0]])},this._touchEndCallback=function(a,c){return b._handleClickUp(c[a[0]])},this._touchCancelCallback=function(){return b._clickedDown=!1}}return b(d,c),d.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(b.content().node()),this._mouseDispatcher.onMouseDown(this._mouseDownCallback),this._mouseDispatcher.onMouseUp(this._mouseUpCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(b.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback),this._touchDispatcher.onTouchEnd(this._touchEndCallback),this._touchDispatcher.onTouchCancel(this._touchCancelCallback)},d.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._mouseDispatcher.offMouseDown(this._mouseDownCallback),this._mouseDispatcher.offMouseUp(this._mouseUpCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher.offTouchEnd(this._touchEndCallback),this._touchDispatcher.offTouchCancel(this._touchCancelCallback),this._touchDispatcher=null},d.prototype._handleClickDown=function(a){var b=this._translateToComponentSpace(a);this._isInsideComponent(b)&&(this._clickedDown=!0)},d.prototype._handleClickUp=function(a){var b=this._translateToComponentSpace(a);this._clickedDown&&this._isInsideComponent(b)&&this._onClickCallbacks.callCallbacks(b),this._clickedDown=!1},d.prototype.onClick=function(a){return this._onClickCallbacks.add(a),this},d.prototype.offClick=function(a){return this._onClickCallbacks["delete"](a),this},d}(a.Interaction);c.Click=d}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d;!function(a){a[a.NotClicked=0]="NotClicked",a[a.SingleClicked=1]="SingleClicked",a[a.DoubleClicked=2]="DoubleClicked"}(d||(d={}));var e=function(c){function e(){var b=this;c.apply(this,arguments),this._clickState=d.NotClicked,this._clickedDown=!1,this._onDoubleClickCallbacks=new a.Utils.CallbackSet,this._mouseDownCallback=function(a){return b._handleClickDown(a)},this._mouseUpCallback=function(a){return b._handleClickUp(a)},this._dblClickCallback=function(){return b._handleDblClick()},this._touchStartCallback=function(a,c){return b._handleClickDown(c[a[0]])},this._touchEndCallback=function(a,c){return b._handleClickUp(c[a[0]])},this._touchCancelCallback=function(){return b._handleClickCancel()}}return b(e,c),e.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(b.content().node()),this._mouseDispatcher.onMouseDown(this._mouseDownCallback),this._mouseDispatcher.onMouseUp(this._mouseUpCallback),this._mouseDispatcher.onDblClick(this._dblClickCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(b.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback),this._touchDispatcher.onTouchEnd(this._touchEndCallback),this._touchDispatcher.onTouchCancel(this._touchCancelCallback)},e.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._mouseDispatcher.offMouseDown(this._mouseDownCallback),this._mouseDispatcher.offMouseUp(this._mouseUpCallback),this._mouseDispatcher.offDblClick(this._dblClickCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher.offTouchEnd(this._touchEndCallback),this._touchDispatcher.offTouchCancel(this._touchCancelCallback),this._touchDispatcher=null},e.prototype._handleClickDown=function(a){var b=this._translateToComponentSpace(a);this._isInsideComponent(b)&&(this._clickState===d.SingleClicked&&e._pointsEqual(b,this._clickedPoint)||(this._clickState=d.NotClicked),this._clickedPoint=b,this._clickedDown=!0)},e.prototype._handleClickUp=function(a){var b=this._translateToComponentSpace(a);this._clickState=this._clickedDown&&e._pointsEqual(b,this._clickedPoint)?this._clickState===d.NotClicked?d.SingleClicked:d.DoubleClicked:d.NotClicked,this._clickedDown=!1},e.prototype._handleDblClick=function(){this._clickState===d.DoubleClicked&&(this._onDoubleClickCallbacks.callCallbacks(this._clickedPoint),this._clickState=d.NotClicked)},e.prototype._handleClickCancel=function(){this._clickState=d.NotClicked,this._clickedDown=!1},e._pointsEqual=function(a,b){return a.x===b.x&&a.y===b.y},e.prototype.onDoubleClick=function(a){return this._onDoubleClickCallbacks.add(a),this},e.prototype.offDoubleClick=function(a){return this._onDoubleClickCallbacks["delete"](a),this},e}(a.Interaction);c.DoubleClick=e}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.apply(this,arguments),this._keyPressCallbacks={},this._keyReleaseCallbacks={},this._mouseMoveCallback=function(){return!1},this._downedKeys=new a.Utils.Set,this._keyDownCallback=function(a,c){return b._handleKeyDownEvent(a,c)},this._keyUpCallback=function(a){return b._handleKeyUpEvent(a)}}return b(d,c),d.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._positionDispatcher=a.Dispatchers.Mouse.getDispatcher(this._componentAttachedTo._element.node()),this._positionDispatcher.onMouseMove(this._mouseMoveCallback),this._keyDispatcher=a.Dispatchers.Key.getDispatcher(),this._keyDispatcher.onKeyDown(this._keyDownCallback),this._keyDispatcher.onKeyUp(this._keyUpCallback)},d.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._positionDispatcher.offMouseMove(this._mouseMoveCallback),this._positionDispatcher=null,this._keyDispatcher.offKeyDown(this._keyDownCallback),this._keyDispatcher.offKeyUp(this._keyUpCallback),this._keyDispatcher=null},d.prototype._handleKeyDownEvent=function(a,b){var c=this._translateToComponentSpace(this._positionDispatcher.lastMousePosition());this._isInsideComponent(c)&&!b.repeat&&(this._keyPressCallbacks[a]&&this._keyPressCallbacks[a].callCallbacks(a),this._downedKeys.add(a))},d.prototype._handleKeyUpEvent=function(a){this._downedKeys.has(a)&&this._keyReleaseCallbacks[a]&&this._keyReleaseCallbacks[a].callCallbacks(a),this._downedKeys["delete"](a)},d.prototype.onKeyPress=function(b,c){return this._keyPressCallbacks[b]||(this._keyPressCallbacks[b]=new a.Utils.CallbackSet),this._keyPressCallbacks[b].add(c),this},d.prototype.offKeyPress=function(a,b){return this._keyPressCallbacks[a]["delete"](b),0===this._keyPressCallbacks[a].size&&delete this._keyPressCallbacks[a],this},d.prototype.onKeyRelease=function(b,c){return this._keyReleaseCallbacks[b]||(this._keyReleaseCallbacks[b]=new a.Utils.CallbackSet),this._keyReleaseCallbacks[b].add(c),this},d.prototype.offKeyRelease=function(a,b){return this._keyReleaseCallbacks[a]["delete"](b),0===this._keyReleaseCallbacks[a].size&&delete this._keyReleaseCallbacks[a],this},d}(a.Interaction);c.Key=d}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(c){function d(){var b=this;c.apply(this,arguments),this._overComponent=!1,this._pointerEnterCallbacks=new a.Utils.CallbackSet,this._pointerMoveCallbacks=new a.Utils.CallbackSet,this._pointerExitCallbacks=new a.Utils.CallbackSet,this._mouseMoveCallback=function(a){return b._handlePointerEvent(a)},this._touchStartCallback=function(a,c){return b._handlePointerEvent(c[a[0]])}}return b(d,c),d.prototype._anchor=function(b){c.prototype._anchor.call(this,b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(this._componentAttachedTo.content().node()),this._mouseDispatcher.onMouseMove(this._mouseMoveCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(this._componentAttachedTo.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback)},d.prototype._unanchor=function(){c.prototype._unanchor.call(this),this._mouseDispatcher.offMouseMove(this._mouseMoveCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher=null},d.prototype._handlePointerEvent=function(a){var b=this._translateToComponentSpace(a);if(this._isInsideComponent(b)){var c=this._overComponent;this._overComponent=!0,c||this._pointerEnterCallbacks.callCallbacks(b),this._pointerMoveCallbacks.callCallbacks(b)}else this._overComponent&&(this._overComponent=!1,this._pointerExitCallbacks.callCallbacks(b))},d.prototype.onPointerEnter=function(a){return this._pointerEnterCallbacks.add(a),this},d.prototype.offPointerEnter=function(a){return this._pointerEnterCallbacks["delete"](a),this},d.prototype.onPointerMove=function(a){return this._pointerMoveCallbacks.add(a),this},d.prototype.offPointerMove=function(a){return this._pointerMoveCallbacks["delete"](a),this},d.prototype.onPointerExit=function(a){return this._pointerExitCallbacks.add(a),this},d.prototype.offPointerExit=function(a){return this._pointerExitCallbacks["delete"](a),this},d}(a.Interaction);c.Pointer=d}(c=a.Interactions||(a.Interactions={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(c){var d=function(d){function e(b,e){var f=this;d.call(this),this._wheelCallback=function(a,b){return f._handleWheelEvent(a,b)},this._touchStartCallback=function(a,b,c){return f._handleTouchStart(a,b,c)},this._touchMoveCallback=function(a,b,c){return f._handlePinch(a,b,c)},this._touchEndCallback=function(a,b,c){return f._handleTouchEnd(a,b,c)},this._touchCancelCallback=function(a,b,c){return f._handleTouchEnd(a,b,c)},this._xScales=new a.Utils.Set,this._yScales=new a.Utils.Set,this._dragInteraction=new c.Drag,this._setupDragInteraction(),this._touchIds=d3.map(),this._minDomainExtents=new a.Utils.Map,this._maxDomainExtents=new a.Utils.Map,null!=b&&this.addXScale(b),null!=e&&this.addYScale(e)}return b(e,d),e.prototype._anchor=function(b){d.prototype._anchor.call(this,b),this._dragInteraction.attachTo(b),this._mouseDispatcher=a.Dispatchers.Mouse.getDispatcher(this._componentAttachedTo.content().node()),this._mouseDispatcher.onWheel(this._wheelCallback),this._touchDispatcher=a.Dispatchers.Touch.getDispatcher(this._componentAttachedTo.content().node()),this._touchDispatcher.onTouchStart(this._touchStartCallback),this._touchDispatcher.onTouchMove(this._touchMoveCallback),this._touchDispatcher.onTouchEnd(this._touchEndCallback),this._touchDispatcher.onTouchCancel(this._touchCancelCallback) +},e.prototype._unanchor=function(){d.prototype._unanchor.call(this),this._mouseDispatcher.offWheel(this._wheelCallback),this._mouseDispatcher=null,this._touchDispatcher.offTouchStart(this._touchStartCallback),this._touchDispatcher.offTouchMove(this._touchMoveCallback),this._touchDispatcher.offTouchEnd(this._touchEndCallback),this._touchDispatcher.offTouchCancel(this._touchCancelCallback),this._touchDispatcher=null,this._dragInteraction.detachFrom(this._componentAttachedTo)},e.prototype._handleTouchStart=function(a,b){for(var c=0;c1,d=c?this.maxDomainExtent(a):this.minDomainExtent(a);if(null==d)return b;var e=a.domain(),f=Math.abs(e[1]-e[0]),g=c?Math.min:Math.max;return g(b,d/f)},e.prototype._setupDragInteraction=function(){var a=this;this._dragInteraction.constrainedToComponent(!1);var b;this._dragInteraction.onDragStart(function(){return b=null}),this._dragInteraction.onDrag(function(c,d){if(!(a._touchIds.size()>=2)){var e=(null==b?c.x:b.x)-d.x;a.xScales().forEach(function(b){a._translateScale(b,e)});var f=(null==b?c.y:b.y)-d.y;a.yScales().forEach(function(b){a._translateScale(b,f)}),b=d}})},e.prototype._nonLinearScaleWithExtents=function(b){return!(null==this.minDomainExtent(b)||null==this.maxDomainExtent(b)||b instanceof a.Scales.Linear||b instanceof a.Scales.Time)},e.prototype.xScales=function(b){var c=this;if(null==b){var d=[];return this._xScales.forEach(function(a){d.push(a)}),d}return this._xScales=new a.Utils.Set,b.forEach(function(a){c.addXScale(a)}),this},e.prototype.yScales=function(b){var c=this;if(null==b){var d=[];return this._yScales.forEach(function(a){d.push(a)}),d}return this._yScales=new a.Utils.Set,b.forEach(function(a){c.addYScale(a)}),this},e.prototype.addXScale=function(a){return this._xScales.add(a),this},e.prototype.removeXScale=function(a){return this._xScales["delete"](a),this._minDomainExtents["delete"](a),this._maxDomainExtents["delete"](a),this},e.prototype.addYScale=function(a){return this._yScales.add(a),this},e.prototype.removeYScale=function(a){return this._yScales["delete"](a),this._minDomainExtents["delete"](a),this._maxDomainExtents["delete"](a),this},e.prototype.minDomainExtent=function(b,c){if(null==c)return this._minDomainExtents.get(b);if(c.valueOf()<0)throw new Error("extent must be non-negative");var d=this.maxDomainExtent(b);if(null!=d&&d.valueOf()a)throw new Error("detection radius cannot be negative.");return this._detectionRadius=a,this.render(),this},d.prototype.resizable=function(a){return null==a?this._resizable:(this._resizable=a,this._setResizableClasses(a),this)},d.prototype._setResizableClasses=function(a){a&&this.enabled()?(this.addClass("x-resizable"),this.addClass("y-resizable")):(this.removeClass("x-resizable"),this.removeClass("y-resizable"))},d.prototype.movable=function(a){return null==a?this._movable:(this._movable=a,this._setMovableClass(),this)},d.prototype._setMovableClass=function(){this.movable()&&this.enabled()?this.addClass("movable"):this.removeClass("movable")},d.prototype.onDragStart=function(a){return this._dragStartCallbacks.add(a),this},d.prototype.offDragStart=function(a){return this._dragStartCallbacks["delete"](a),this},d.prototype.onDrag=function(a){return this._dragCallbacks.add(a),this},d.prototype.offDrag=function(a){return this._dragCallbacks["delete"](a),this},d.prototype.onDragEnd=function(a){return this._dragEndCallbacks.add(a),this},d.prototype.offDragEnd=function(a){return this._dragEndCallbacks["delete"](a),this},d.prototype.dragInteraction=function(){return this._dragInteraction},d.prototype.enabled=function(a){return null==a?this._dragInteraction.enabled():(this._dragInteraction.enabled(a),this._setResizableClasses(this.resizable()),this._setMovableClass(),this)},d}(c.SelectionBoxLayer);c.DragBoxLayer=d}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.call(this),this.addClass("x-drag-box-layer"),this._hasCorners=!1}return b(c,a),c.prototype.computeLayout=function(b,c,d){return a.prototype.computeLayout.call(this,b,c,d),this.bounds(this.bounds()),this},c.prototype._setBounds=function(b){a.prototype._setBounds.call(this,{topLeft:{x:b.topLeft.x,y:0},bottomRight:{x:b.bottomRight.x,y:this.height()}})},c.prototype._setResizableClasses=function(a){a&&this.enabled()?this.addClass("x-resizable"):this.removeClass("x-resizable")},c.prototype.yScale=function(a){if(null==a)throw new Error("XDragBoxLayer has no yScale");throw new Error("yScales cannot be set on an XDragBoxLayer")},c.prototype.yExtent=function(){throw new Error("XDragBoxLayer has no yExtent")},c}(a.DragBoxLayer);a.XDragBoxLayer=c}(c=a.Components||(a.Components={}))}(a||(a={}));var a,b=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.call(this),this.addClass("y-drag-box-layer"),this._hasCorners=!1}return b(c,a),c.prototype.computeLayout=function(b,c,d){return a.prototype.computeLayout.call(this,b,c,d),this.bounds(this.bounds()),this},c.prototype._setBounds=function(b){a.prototype._setBounds.call(this,{topLeft:{x:0,y:b.topLeft.y},bottomRight:{x:this.width(),y:b.bottomRight.y}})},c.prototype._setResizableClasses=function(a){a&&this.enabled()?this.addClass("y-resizable"):this.removeClass("y-resizable")},c.prototype.xScale=function(a){if(null==a)throw new Error("YDragBoxLayer has no xScale");throw new Error("xScales cannot be set on an YDragBoxLayer")},c.prototype.xExtent=function(){throw new Error("YDragBoxLayer has no xExtent")},c}(a.DragBoxLayer);a.YDragBoxLayer=c}(c=a.Components||(a.Components={}))}(a||(a={}));var c;!function(a){var b;!function(a){var b;!function(a){function b(a,b){if(null==a||null==b)return a===b;if(a.length!==b.length)return!1;for(var c=0;c0&&"\n"===b[0]?"\n":"";if(g>=c){var i=g/3,j=Math.floor(c/i);return{wrappedToken:h+"...".substr(0,j),remainingToken:b}}for(;f+g>c;)e=a.Utils.StringMethods.trimEnd(e.substr(0,e.length-1)),f=d.measure(e).width;return{wrappedToken:h+e+"...",remainingToken:a.Utils.StringMethods.trimEnd(b.substring(e.length),"-").trim()}},b.prototype.wrapNextToken=function(b,c,d){if(!c.canFitText||c.availableLines===c.wrapping.noLines||!this.canFitToken(b,c.availableWidth,d))return this.finishWrapping(b,c,d);for(var e=b;e;){var f=this.breakTokenToFitInWidth(e,c.currentLine,c.availableWidth,d);if(c.currentLine=f.line,e=f.remainingToken,null!=e){if(c.wrapping.noBrokeWords+=+f.breakWord,++c.wrapping.noLines,c.availableLines===c.wrapping.noLines){var g=this.addEllipsis(c.currentLine,c.availableWidth,d);return c.wrapping.wrappedText+=g.wrappedToken,c.wrapping.truncatedText+=g.remainingToken+e,c.currentLine="\n",c}c.wrapping.wrappedText+=a.Utils.StringMethods.trimEnd(c.currentLine),c.currentLine="\n"}}return c},b.prototype.finishWrapping=function(a,b,c){if(b.canFitText&&b.availableLines!==b.wrapping.noLines&&this._allowBreakingWords&&"none"!==this._textTrimming){var d=this.addEllipsis(b.currentLine+a,b.availableWidth,c);b.wrapping.wrappedText+=d.wrappedToken,b.wrapping.truncatedText+=d.remainingToken,b.wrapping.noBrokeWords+=+(d.remainingToken.length0),b.currentLine=""}else b.wrapping.truncatedText+=a;return b.canFitText=!1,b},b.prototype.breakTokenToFitInWidth=function(a,b,c,d,e){if(void 0===e&&(e=this._breakingCharacter),d.measure(b+a).width<=c)return{remainingToken:null,line:b+a,breakWord:!1};if(""===a.trim())return{remainingToken:"",line:b,breakWord:!1};if(!this._allowBreakingWords)return{remainingToken:a,line:b,breakWord:!1};for(var f=0;f0&&(g=e),{remainingToken:a.substring(f),line:b+a.substring(0,f)+g,breakWord:f>0}},b}();b.Wrapper=c}(b=a.Wrappers||(a.Wrappers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.apply(this,arguments)}return b(c,a),c.prototype.wrap=function(b,d,e,f){var g=this;void 0===f&&(f=1/0);var h=b.split("\n");if(h.length>1)throw new Error("SingleLineWrapper is designed to work only on single line");var i=function(c){return a.prototype.wrap.call(g,b,d,c,f)},j=i(e);if(j.noLines<2)return j;for(var k=0,l=e,m=0;mk;++m){var n=(l+k)/2,o=i(n);this.areSameResults(j,o)?(l=n,j=o):k=n}return j},c.prototype.areSameResults=function(a,b){return a.noLines===b.noLines&&a.truncatedText===b.truncatedText},c.NO_WRAP_ITERATIONS=5,c}(a.Wrapper);a.SingleLineWrapper=c}(c=a.Wrappers||(a.Wrappers={}))}(c||(c={}));var c;!function(a){var b;!function(b){var c=function(){function b(a,c){this._writerID=b.nextID++,this._elementID=0,this.measurer(a),c&&this.wrapper(c),this.addTitleElement(!1)}return b.prototype.measurer=function(a){return this._measurer=a,this},b.prototype.wrapper=function(a){return this._wrapper=a,this},b.prototype.addTitleElement=function(a){return this._addTitleElement=a,this},b.prototype.writeLine=function(c,d,e,f,g){var h=d.append("text");h.text(c);var i=e*b.XOffsetFactor[f],j=b.AnchorConverter[f];h.attr("text-anchor",j).classed("text-line",!0),a.Utils.DOM.transform(h,i,g).attr("y","-0.25em")},b.prototype.writeText=function(a,c,d,e,f,g){var h=this,i=a.split("\n"),j=this._measurer.measure().height,k=b.YOffsetFactor[g]*(e-i.length*j);i.forEach(function(a,b){h.writeLine(a,c,d,f,(b+1)*j+k)})},b.prototype.write=function(a,c,d,e){if(-1===b.SupportedRotation.indexOf(e.textRotation))throw new Error("unsupported rotation - "+e.textRotation);var f=Math.abs(Math.abs(e.textRotation)-90)>45,g=f?c:d,h=f?d:c,i=e.selection.append("g").classed("text-container",!0);this._addTitleElement&&i.append("title").text(a);var j=i.append("g").classed("text-area",!0),k=this._wrapper?this._wrapper.wrap(a,this._measurer,g,h).wrappedText:a;this.writeText(k,j,g,h,e.xAlign,e.yAlign);var l=d3.transform(""),m=d3.transform("");switch(l.rotate=e.textRotation,e.textRotation){case 90:l.translate=[c,0],m.rotate=-90,m.translate=[0,200];break;case-90:l.translate=[0,d],m.rotate=90,m.translate=[c,0];break;case 180:l.translate=[c,d],m.translate=[c,d],m.rotate=180}j.attr("transform",l.toString()),this.addClipPath(i,m),e.animator&&e.animator.animate(i)},b.prototype.addClipPath=function(b){var c=this._elementID++,d=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;d=d.split("#")[0];var e="clipPath"+this._writerID+"_"+c;b.select(".text-area").attr("clip-path",'url("'+d+"#"+e+'")');var f=b.append("clipPath").attr("id",e),g=a.Utils.DOM.getBBox(b.select(".text-area")),h=f.append("rect");h.classed("clip-rect",!0).attr({x:g.x,y:g.y,width:g.width,height:g.height})},b.nextID=0,b.SupportedRotation=[-90,0,180,90],b.AnchorConverter={left:"start",center:"middle",right:"end"},b.XOffsetFactor={left:0,center:.5,right:1},b.YOffsetFactor={top:0,center:.5,bottom:1},b}();b.Writer=c}(b=a.Writers||(a.Writers={}))}(c||(c={}));var c;!function(a){var b;!function(b){var c=function(){function b(a,b){this.textMeasurer=this.getTextMeasurer(a,b)}return b.prototype.checkSelectionIsText=function(a){return"text"===a[0][0].tagName||!a.select("text").empty()},b.prototype.getTextMeasurer=function(a,b){var c=this;if(this.checkSelectionIsText(a)){var d,e=a.node().parentNode;return d="text"===a[0][0].tagName?a:a.select("text"),a.remove(),function(b){e.appendChild(a.node());var f=c.measureBBox(d,b);return a.remove(),f}}var f=a.append("text");return b&&f.classed(b,!0),f.remove(),function(b){a.node().appendChild(f.node());var d=c.measureBBox(f,b);return f.remove(),d}},b.prototype.measureBBox=function(b,c){b.text(c);var d=a.Utils.DOM.getBBox(b);return{width:d.width,height:d.height}},b.prototype.measure=function(a){return void 0===a&&(a=b.HEIGHT_TEXT),this.textMeasurer(a)},b.HEIGHT_TEXT="bqpdl",b}();b.AbstractMeasurer=c}(b=a.Measurers||(a.Measurers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(c){function d(a,b,d){void 0===b&&(b=null),void 0===d&&(d=!1),c.call(this,a,b),this.useGuards=d}return b(d,c),d.prototype._addGuards=function(b){return a.AbstractMeasurer.HEIGHT_TEXT+b+a.AbstractMeasurer.HEIGHT_TEXT},d.prototype.getGuardWidth=function(){return null==this.guardWidth&&(this.guardWidth=c.prototype.measure.call(this).width),this.guardWidth},d.prototype._measureLine=function(a){var b=this.useGuards?this._addGuards(a):a,d=c.prototype.measure.call(this,b);return d.width-=this.useGuards?2*this.getGuardWidth():0,d},d.prototype.measure=function(b){var c=this;if(void 0===b&&(b=a.AbstractMeasurer.HEIGHT_TEXT),""===b.trim())return{width:0,height:0};var d=b.trim().split("\n").map(function(a){return c._measureLine(a)});return{width:d3.max(d,function(a){return a.width}),height:d3.sum(d,function(a){return a.height})}},d}(a.AbstractMeasurer);a.Measurer=c}(c=a.Measurers||(a.Measurers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};!function(a){var c;!function(a){var c=function(a){function c(){a.apply(this,arguments)}return b(c,a),c.prototype._measureCharacter=function(b){return a.prototype._measureLine.call(this,b)},c.prototype._measureLine=function(a){var b=this,c=a.split("").map(function(a){return b._measureCharacter(a)});return{width:d3.sum(c,function(a){return a.width}),height:d3.max(c,function(a){return a.height})}},c}(a.Measurer);a.CharacterMeasurer=c}(c=a.Measurers||(a.Measurers={}))}(c||(c={}));var c,b=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c};return function(a){var c;!function(c){var d=function(c){function d(b,d){var e=this;c.call(this,b,d),this.cache=new a.Utils.Cache(function(a){return e._measureCharacterNotFromCache(a)},a.Utils.Methods.objEq)}return b(d,c),d.prototype._measureCharacterNotFromCache=function(a){return c.prototype._measureCharacter.call(this,a)},d.prototype._measureCharacter=function(a){return this.cache.get(a)},d.prototype.reset=function(){this.cache.clear() +},d}(c.CharacterMeasurer);c.CacheCharacterMeasurer=d}(c=a.Measurers||(a.Measurers={}))}(c||(c={})),a}); \ No newline at end of file diff --git a/plottable.zip b/plottable.zip index 586fd19f63cbe83c971c81765089b8d043061708..38301cd780cc1407ea4ec54131a3eea37f79d252 100644 GIT binary patch delta 196490 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�#fXFr0>iahLl>7=XF~IX&ALc5lia&(%*yt@bTC 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 z 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%0D*ZC=^}CYeMgh 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%0D9)l=J;m0r`Die}*`gyPVm&`HUtr#UaPkEi?Jl&| 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 E1NTI5M*si- delta 190939 zcmV(sK<&TVh7H-=3=L3A0|XQR2mlBGLU9g}4I+QXu{QeMzhcas#2`h27uilCTTUp7 zvU#H0CTTl+@zth5U`QeY0R$J3jJDP~AJ6YRzvMhmRo|xv7fQY*##SE6+s!{Vw~EH)WHKB-*xbD6PA;cs&Gz7GbJ*&&`jhTxb7%{% zezbo#7~YP$7nhS_XKVY@4gB+2@zRtlj?4CCf6yCTbj$HaPrL21KQ24PwBIR5#j}Is z1smBs>kZB}uUg|tIof=Bu($vGXn*yiwat${YMf8|?MZjgZ;S?m$$D|#YEK5E+tuRj zM+H9J^TyG!uF`V!dljF1us&#Idc8yx`#G=H{29 z^1K|C{dQRlTa(L&E6wJnd(@naSBlNAK4PC85?^?kC>rjmB{z$HJL&eu+6gBMf~$R$g@b{ciuF!1$Q}UZdM@_oicXaCI>_X9B0}ca{QTMD>5|*`&}&@{$7qwh1L1{f#R;&& zXlmWOdQWjUD~mQ;C_5>jiXeZXN#P;>cCV&aDpK=nwNwCs>#SOq(N=1AEm}r$(e@&} zui?COk$ksgo5A~#v0#1p6MPl`H>*PX`RtZroW z+M9eQn&M&50)!ovVlWQDDy+@5VlwV^`;!Nq?wCfzgR@q@zzofX!Veoo?`JgFx!-i; zSq1XpZwz8XgM<%k!sAf(XQ5!k&SCK}OafXYoU=RVv3r5G1MOj^lpC+(=B-{)9run56X0lMTP11#j;F?k^;8clgrWIy6BhJ#r|kC7&TU;m3FI70fe!$ zwUTg&m10iu38$uB*}o9mJuv}-pY5{SYoH^8VX*<^LBfC4VpBW4jvmDvwQ$vfdsv*j zs=hzRjNV}5U65hx3;g-g;PFLq?_RgA*8=jS%Qcr^QQT8fLZ?*QsP@(<3xN`skIQoP z(zNJjN@rx&X*#Hg@js^!E4zY#aWH9dF=y8|lj}h-9Kdc!MKxyhnlnsavhcfNxIM4H zPNjh9v0Hy65t+ttd%YO$to~10yhhw@2acp$9a}vkn5MNraE62H#&D;33$Yn)H(~ni ztb%9N0ykO!mg`O;O&QK42tgQa|+&zyE8NzM|w%{q4I|(<;hKK|D+p zqSQ*C*{Z1KUd06+^q+ZUABpT*adg?eDmV!Dk3N5g`8EueH*1A;f_2I_Wp6MnN6o9j zzq-9%t2r25Y?l3vZ;v)RgZ6my`|@n_|8Bi$9koZ@;bimB`YkrUhVQD?JAENOr}5^q zR-jpfNuCM-??9u#&5(|Lr*=`Yk-ns^p~5utn)5!W!u4x|Ts_w1WZOI~$Db=2)TbUs zBN2Z^R*1!sPs9)QHXeC=j*mirUEYcn__Bp%5Bi$ZhcVdr7f@>sM}x_LootTF31B#) zGyr{F*N(Y9k~UuQ&3uk3tGU98ax$;Ln1O)YihY84WlCQrESFXRD0Zz53>TYjgjFHQ zKh`x@JvN>_?0MK*KgfmF<{zViNcn1kn67`Uk(-AyTx;qaiFxYYy*gZd-y()%wrY}8 zGyq8WjM}vLXBuYhH)f$Kf2*CcwP*I6g{r-;KFOfa98SlVjkiSp0sk@5_P{tS-em?! zEh>Q@l^Dg6eNmO{9JM^1&9I##Ljf{&q&LwNMJa=Nl_b9?5s5m39(cv#Bqc8))qa0f zpBUiIFAzhT$-7IaghVU-SiD11zi!@PEgVypLxG>H5$#| zZV=~&4Dq%oR{9gBs1|GIPT9jsIpPz5=P+JY93q`&n4_)z zI>&jA@8e+)8^Mk4da<3EbjV|VEG2##4PjaXo4qt+Ars(dEk|1DuGoL%5($5{=a0KY zIw~iAd?rgIyaNLkSt6n2f=eWUNgtrqL@T+WOrdm2Q_%>PNYa{@9Tw)NstM;Vkwk|t zwl-o5g3`GAFRG)h7=gHPU>Gc&S{-ie+YZzJguUWiw<8V4ZqG3>LlQO7ih&$sM#T9E zk&h~}L-{IJFJx!mxW{aP=zo7KplK^yYGM)pTGwigluJ6RES{e-o&EKnXS_p>uxwcn=rd~1Iri^1(#K zqK|jdU8Ta0t&5RU^)e@#XdOJ@OE@;|I$KeWoYX!nu zxOv-Ni#tPhu6a+k{6yxxVWDkpfysr#V1e$s-d1&LV4)FMA{$1+Km#vAIkS%3d|0?* z|F&iwMe^~BXPy{=A%%bEsYYaRzdr#AIe%~%7Du{AE_FUwE50rfZpq!ovjMy)+>|^U z+;AfZ8<|)?ao;#FBejl=V?)fx5z0tp=Q~?EWo5eS~dw=8q4~i#<7CnDQPp=34PbS!@9gWZr z?9N_cYj%pQu>PQf-P~&g)ndQy7U8xl*s&S*TJR|L2mNxTz)l3n*5yPzM!;+bgc=u( zCr^q;(~IKs?VauIKdmM`0}hkXZAPmRJK_x9S(>x`#wy)@(&1zPu|jq3X}2bDm^8}K zC`Xu}k+;RogJOScy+CL1?{&8`xs-3{4v z=PrWr5NJB+KS9)I`9mTMYsG8!@Ms4An~ixE<9V98Lpy+)AlMu+{CqFA@}eri5Yn3 z<_j6^cJhB9pZMKIIP}XKplZofoRdxo@R)y&6j>5mW;h2~ZWz$MoW-Yk_QI^XzTsG` z^TTJx8WSu$R{lAV>zoqi3h!J!Q5~8yNr}NQ^L^aU%mCSI_1e>(gvLO=RM*%z1FP#2 zmW#-UQev!3Z%ReXx;@&Mn|X z(cr51xyDJh!?Dl>-bD(Zn*|KnzY(*=NqWY>qEYzc4HWIc^1^CI3K((s%4fp8WrG3|bX)pl9?641`OC2O_SlcA#anA@i zCJmn;;-Y9U>_US2R}tgBg~0mTYSr3SPPQ0lnAp?=U0-9HH8O2DN>^wE1C{*nmcrmVUV^Hk02ionTPR6U??^LvK1goK`fx%Q7f}@@L?(XzNt3Xmti%8BAp}p_HEoTiX}cqJTm@L zzKz9$PdFOG_QcrxDr!zp__5kkZHL%jkHjMkfNUr=@qOR^agvU^rx<*w{u%su+#w!h zG3hxneUGiAV2D;9#$YmI^)NhQ0e;d3;W-QP7DpM&(ViP-JfG0*(=sWrmJNU3q|zM= zSAOWFz>hPkVi7nAD(^Fl!@g5Dr6?}k|GA_4K*)%#m59LWDP41NWn?5gaChDtAcQ|5 zgc<1Z5ljihPg*qv|L}*H+8i(Vcwc5S-;4~m1zM4Ei#C#?XtYSCnY7oYDVg-0fqTY1iE`Co2c1t;-lb;QjYoVuuho zfSo59m?cQmj0sxui>2At=YUlACP~gL)l+f;uLkY=TDeGuVQ2D~My*d(>2S;C2eV!hB{xVWt&Xg>Y9Q zm4+I$OB6OB|wH!5roji*z7 zH3FoPS(v(+)oy=t)dKW0)u2y}c;S=^hSP8`?sDG<15h_0r)L|(?oHX_x%%m-)xJgN zFig$4cN~lFCW8UE04T&q7))2mdZAvb;t$3LPuEBH3`X@BDHHIQ=Vag{!<--v7VKq~ z&5LI7rrU}cuAm{!;4sVs?0T-E>J+;=x5Z`a4X}?eZ5DsK!6<;fy=?W)H(J`C9OQ9X zUV#iloF5vFy3jm{^q_sCRz=a=K$FTB@%9#9!Tli&U~&+g(DS^mG0zMT7+h0+|U-SEBlvf{gz2fY`wVkSbJ9|gm}nc8i*gn)icU}4=0h~X=xe7dOm_5*d7rV z<=!te3zL5e;tGhmBI~skBv4qP08;BG9I7?`TK(I1z>roW6{vv>O(;7Mu`pDDDA(Zz z5&r5Pi=Fj4+JOW_jh@k+3mwmbO|1gaq*Pcl0cB%W>Eu#tSy2PLF{huTTFe3nuY8OI zzhz1Sb1X^nmbfEI)oL;G359KqI3o++fnv21)u4YCu_g~jpq_E$5qjk(28x!EC*-Sr zk|PXTHt0*OYNJ(5D@VUo2tJ`1q+jn9E1zI%n6Vhx$QOCgLwkMYYOD zCgo^S>oB$~lRW|kUA#0EFzsMR%vG;;mP}A|r6^b-zn=64tx0W+qoH3|4<~#RJJ)v+ zflhxgqXAl@+xgue2-Y|M0q229={+Q=8+j%KaZ&Onl~-2r-UJYEnaHR^&BaFZW`vw} zj6CTw%tTXu@ko4|*rWj`#Um`j=+G*Z~tXXqB@_fh%4orDh30Rr%*Yd2Am zg~|3O2WFQ9mCN^+g2!wwC?P@N_4Rf0`o0{U+-)oA>r1a z7&Nu{J4^5lAvmU(1ZIs^x7AEWu(xq7qb_^f5Q5$mT9-z70|dVZ6L9M@FH%%*{7`>% zdOK0+v-;9zKm+_&to4@y-!}Q}0sq0b?YIR$w%L}*E;2V7L4#A(e2pt*=5Lizo^3u8 zFBB}eHWEGR?lBg+BB9Mf4$`$Rk!k}rBpzQOnN(L-co4&_<{yjyDK<1EU^ao+n~m!V>W5!`Sl9XPM7zz3%S6W|Tvn*(v=3eK% zUtJJg>5}v(>_uG*nsaJKJ+*(VVoa*iql3^hjB@LyDb8D77&&zS;gf z!*EtM#0n~519JOw%rh%nw4ohf%>Sm1Di-P4Spt^z!Nr+L79oC;Pq{DvsZZ`BGJxFN zLSm-bo43m_5%`I!1K@w(5p}fG{0FiHHCA%cB|X;Blp7=BXUfpb(95(HlOmR_Jt`?o zy+%!j;~=h<(cgzAS#JrSHBx+eyP{~Ag>hh$EnxtS3_xe609wTe{LRXw{K}^;I?U0} z*a8_L_G$$)7(~&Oj9Je{SP<|aA8xJLxTzZ!3^=-h)dxeU3WvmN}n&|ds;hd<6@+W2va<*p1%w4@7O z{pFXu_U(VjqIZ9n`2;<&f|*L*q*6#us`$ujP|>V<6F8KNj8;2tz2=@TmbWdoi^!sL zo2O8WdIVw1mN1S83}Ad<)fvyZRmYvN5!G{c^6FjDdWwS%;sVqFDrqQaCjppj>=444 zgJ8m^=7KPCY0}CO#%_?QQE|h0A1Z0bc$^%pcNH~>4UwLL?^@z>{6t7-W*bif4xw%RQ=9robt7BKPJi7zPJAZ(88~bRTJ>xo49InccoC-U^iCw7W_18kuAh z%xjzzD{2flYM3Gy(;&{Cgc&u+8Gcwum!v3`O9+1l;O+?P0+S>Mz{hM=jw71@(wo)V zG;hQ~igR@N;;{&^ko_pKnjzpOkxE-8mQFrR<(JQlpeew(!5DywH%Sc|@lRYhBj9!c z4c3Zg6zSM`Yy@877exAGXRV79h9+iXT+nEiF|SIvBJ_W?8c(EVAEBM_B1mRhc=sXy z@G*bkydZLLtL9KB^!#%?>B$;=6VF50S~QsS9HuZ}(y{h7mP=2@U~URBT_`$DaSAj} zaEnGOVOfsSra2JXe49&e-SC1NE6^z>o9qv5?$H0hT<^UeC@Wj9GElh_)_}a~4|qsg z&I-idsXT3@2726kACGv9V26e#IQR=wzVm-32st))ylOOrR}fU_a=4HzQQiqsK&NGp zF&kh+kO%85+L}OtNe_{yz77>_oQ@hsCQz>!N*ITVwkSRZ&2C%)WJL@cdywAbb&Voo z^5aSQL})DIMR!RkkU%3RH`F|cxvNn-+~fv`C@-&onwk0#@N|;5Df)$rW{=NmFXn&e zSMFlkGh1`9gi$*r{q};6HsaE8N$GsELJoAZ^2~#QZ7lUrN^N8P%x(nIoyt=x5N(Aok5Fx3w(sv53YbZRNpnc}Nw7$DBUSICZ?Z?%U0}#t^ed=VZtu z4QKeHWOD#dPZ^}8Z9?6^2RNlS8HIm4HU{MM)T<-{@xK&S$3MVpCKe*lFFwMeiz4V^ z$v)WiHqn%^hFA(7?#1}DCu(W3GLJj9PQ~vjXKUXKUPBSUJr5NhhEJ@SjQ}VLy7mx& z1mhGsVuH((V34!4odDQO^6A|8!e@@=GHoIo{#ipW8sh5eA>7BtNQ93aZne_SNnG;d~*vp9I2C;7__zsV3<0QiD^CHNE6+bHBPk?Vgwo|yqfg4$24()d({G!WsQQ?OKR8|J25w1Dh;LwX^D z&^{$QE6gy`*nG_U#35qlEXx%Ln=fuNiXg4UB;dC3LPX+Osc-9o@JIso6|mO6Oj*l{YV4VW=F9B9n?uYReQsMglr1rn22Fpw5rgw{sH#;7 zb<_CC)}*Dm>Z!`)(PKP9p+NCahHBSprZ~;e2F7y3mC3_dVx{_mRma=wHmg{?EBskBcD_l1L->J%^88ov_1xggcd z15`0(960yI!j;!EAzOcQFJ^}|TjeN=up{P%TpW-xBf;8F1Z0iVl0vqI<$@#%wP+i= z+x|>tk6*YZM~`HPk}xE&AvR^A@t7^KJqBt=}s zv=3BwAQfeT4L0G;?RyMGk{EPkWsW4 zwz$ycUnS_k9H^ErWS#@HZd=Zs6D2%;$ORQe?5af~TLa7MBn9CAB`8%8igMD7OJ)m$l~MxU1qvBh`H7PBEBk?<~3<$eOGNoHU(YB@;KV1 zqw${7Gb8b~eszBqw{K?TD6vHx#!38|eQ*Ez4mkvcy?4S3{flMa_xf$DTWs^@uQX{x zE@zfhd>t{=Rg|EfldxpF2QWo?Lz}q?7eL&dddPIX|4hqs79JiGP_=XT<4Y!*vWx`~)%3YP^VY}kes zg^a7TY3G0b6E!E+jq3_V5@|Z4>a3}~?CjGgFyYNqVjpRTlZjqCm79mC;8oD-Rzxx2 z%v2`@$_`|4ifj=>KSd?0O$s_cMhf14?&S1f*ky9{%B5!dsAj6m(LmACf0aq`a1Gzb zgFSphN`|DcL*G+|QPGWMr}>P|vaK4vsee9f+T4F0!h5p3HPuvYTmvts2XoKZON1*P z5wJ=g`e`jRT%d(_4TD$xC1HqYtOtNVmYD#|Fgo$;BDuvjhRL=uz{C*c(n;__qP`gQ z)nqvyGgnZ=$W~2m2byQAc0U%CjAnms?K(QWG3n}UI#esd9W;<=isYwT;mFw!0-(C! zUtNDiIe}U%R!`&hy5~Hb2p~ygHLAw7@i(m0MOsr*)TSCqP~eKij0(r`gn#(xe!mA-p6az;MDgbp{ zt;!kSwE#iJ(jx!>abVNQ#^8K|!lZlShE}p4#qZ2=kg~XDO7^naI7c@jjyd&4b8X?> zj-B`1?bzY2;nKSuR5(OmLZyFeuf9D;|m>wI+5h1>cbpxNw@W&W9Mq^hg zT)&$V$za^3(MKK{El4-i=jx^-+3;=QpfE0xMz{$MwY!-*o}rs!7@9c}avbD+4G(!( zK#+Bgv_WS*LLR;dI2@Qh!K_cIx+t5r9^QZs2)Uv@8xkLAJ7Y7XvYUTGJ{G?}bekJz z8omhqrz+C5;;@?s()$0cjbXIuGwGU8B<#HQ7%Gwq#`Y+4%EkBxEKp04W6;5V7xhZQ zOj;Kg4qef{JW+E-qiIq(P86g2mv@$O#fyZL#=6H&@HH6DBQm_azTjBRdC zT5zU#gsFxtp;^g(zZdu1w7Am5h9R=fbK*IN^Tvz|oC1)C$h3p>#c1fB>u)^lvI90i z23sCx^p!!tB^DOiN4F#~KmCHlz5m6RbGAjcZUZ@((i&vCY>}TblNOZen_yGb%Agi7R}n}8OE7WJMyh+<#-Pzb`+Bta z`4JmwQcH}7t#%R=LD~?Tt!WVZzQqwvE_V!(BYo-pOHlsR8O0%cm*}LraIufqbJPr6U z(>su{(GP9PLukRQsEFg4I`T`jjeL)qP>Fh;0iWqK!m9&d%)yI}V7kt&4dmfgG&5ca z4A`X;6S+*yg3ud;i+MA8cFc}ez_Hb+lB7g;%dAQBY zN-Cb1-_U;*_zrA#unkc@shBPzH%P5vt_j!8i1MXLegq158ET7a{yTz1<;#EPMR8ijkJBD-X;Q;0NaDws8v+)I-D`VJa zR#jEVH&3hr88sQD|L!qD*b6Ws)_;Fbku|XY+r!r03Pp0TKa>Q6Mtee{K%*`#%8q%R z5K4vC6fayU)gWWyMj@(+xCl{`WjpKR1H*qX2cjY=Lc0nQ8O3KrUKr_m5Q}J1D>pN0 zZh0)3VW45dnMv=k?4x}st^moopcA7xo%4PZp=NQQrU<9NtcT3>uf~9CPT+Q8bfhQ` znS3y9&+LBIqG=|E6!2O(J#~w)(`==cxE+IOwx}a$YEH&0#pYMboUw3i zHm&ysLc87kV{;3F`7_}}Wr{!(1|xr??*W%*uy@zhXzQ8~I}gFxH3{yaKa)ETur?+w zJ_+;>g0qmoiCKG%1ur!)Z`!iD_|ttJY|>-aWF*$~3|k%DGw3%{&Ek!p(;;Al+owS& zHR7RwCp?dGw8pDwAL^`U#flT+@$lr;EAes)Qj99#q-}c~^}@OyC63_4BL9Ez?Ymbz z$Zb+d8WOPwI3+4MRN>wY;=4kSes$v38K#pGaZLB3QZwWZXDQlcf^h6u)JHrToA~Wn z-og@9>{HSD#~2D}JvCqqSpM;Pl4w}_Mv;U-Szx(hm@(yS4dbM^a`nT*C|UFVC_en_ z*O`gd*<}`hmbgRZC=tX0#w>qZfyg-L@?#_HDlw7%$%%$3zGra3$wc!lWScz>jYOcP zyl&02EE#VehE+VL?MuJv9Q3~xaRyzS7`Qw4QqC*MEmmW>INkmV<}Gr^%y+Ee`4QL} z2|W+XD}+kMB&93oT8>ivh@_49ph$lx%ATLU2Wibc=69rSmCqfBV#I%AK1lf+jBM;5 z^?K?1gt5(20`ctSYd>Q6t7f}y&d6rXRMbd_Ju@7};*d-Pj+L@P#}^)}Km@BqvKk~J zlzo^IBT;LM5zGR+Gtn#nplH9wu-M(7fOv+~hK7oQw_d$^H3fjKEBZ59ABPesfO}HA zZCH$obzq0YuS14c)D?dN4#pDrEl~xqK7%-i);Xh)v07rv0i+4{utWUCB`#vts1Yvh^)6aEqVnpT2GxOW7bFh45+YBLaLV14uN=YjgM<}a zx!^dbModJbBW;IOJ@=KMFq9{w0j5SI$mk)CBV6OKd@v^Y(};hTL%_?o7ciEKxz%*# zfuH;C>n0pL#$E&RinWkp66*sA$JE~83Sl`>EH^SCMZ8*$rsr7uB8^0HPw!gMFbUw- zi|x(Nx3JsGfFZ;Qz#i*FCx!h?OxDF0BrnLnxY8UZ#)aR9lYWVv4N7uX56|O$qP6p^ zkJ0u#oXP*V5~zO}Kk!fzNl-B|cb)%$waGE!SrF{gSPieN=1uX;0>L!@Sb)H$Mo1UN zXe2w>x4L4|Nm(`gkR{X)f#(M~zz`6HfC{S!&PIc4#F&}Dt&UvH&bvsk&oC)!;MHpe z(~kw^%Jn)E_^n0$x`!76E3w*8UwQeC@5}Y)WX&8eo63P&@-%a5Cq8` zM`Jv|mybTI!11@9+b^k^GbBxtgo~pWibmmP2x-n9Hd}}ZD)V@;Rj}X zp>tzsg16U#pQ!n!FA;Fszt9>OWHF|yt&(+q9s(JJ3u26jEe^=Z+9A?~Fs(Gx zy(Kq%N{ihwHVa0=_$M@s$i-|)rM}lc0b%r2NDk^&ecC*D_H6(0!S3-sz^*u%NnF#W z?CyW_gJ-+P2QQwVJ~`ZdCN*3~#Nx?UJ3e@}|Ki(YHel3hP>vdk#x}3^O*z;!Z>Z|( z-dRn@F7YE&1HoW?JGe1>6_UK9AjUR8Xm~nU?W&mqAAV44gt?hjvw z_$1==0kEp)<&vlwk^KNDnF)SLGMRNpzI`{NH&s(bk(l515s@~y=p)fU2a~KH2M;7b zGJIn7t)Yz%PL`s=hFI6YN3tlrPF`= z#9cKeV>4xVy3TsGu##!WkR*@* z4_n_wJdY_Ue2*XbMi%FN#hUw(#ejbz1&j;D`Lon>%nO`P0#$`nH< z{KhI})_$T1syPzXllfqmV=ZWyd9-KSCL7|6~f>IG+M*RX%Ohi+*h zx6wJ)_gWFT8M{5vasF^oK$vI?(75){7EN#64sr&0SSh2}jDsxUmngBtXb#q@!Ri&L zA#qiHBO%Hp2WUGzgCH>DmUGW=Yd|>URPv+tgg1eg@@@7F-+C5mx1G7yyG=(Ni}T~hoBq~+aiWPvYne~0Y)e7} zG-)@=(PJjZVbqtz@z|2>U>-9Zjixw9gHd`u9YGwJZ&}>zwH>*Z1Jr*E;e~ z`ewn_d_n_@qcUu!Cbvbaq{zvAm79CvaDnuE0MP&xMchvS7R$WqO%|c9aK=6o*to_v z2JJiVzp0o8CWYuQ*5{g5>pSO{FNOl%-b!J_?yP3zwOtr4;sX0I!fV{DLmwC%UI;)! z%1?apXN|<)V^0>0WPg8K4$i&VY2wZcGYxqE4y^2RvP+SMFVP zJADbA<&lLB_AD6pLaSS5q^>#FyC#vf$k2>yXgg4wIF^eOCuwt-qL|91A~~U7ti-kAMY~q zb>~wo7Czsy|7>qV>pfa z)!=@Rq(^fDFtpF_iW8pJ#PRJxU&C`eV>)<_L~l6ji^E0|QzQ{)yzoZ0l6I_*Q1P-+ zJN78z$@uo_Y|wvGs17-ONL>gIo?M=1osVu zn5`Z2%szju30kqQW5C5d+vYM&uyY-xCayg(&&HC5K&%a(f{h<9+G@3{mh%x)VsOFk ztgrvXYS?kp4k!qm{ptZMprYlpUZ;!e>A0~`-XLWM7Nw!~jrDD~c8YX`Ir07e`uqN` zQy0DuAv20HRT;?;T~sUHPZb=ZC%WgiFRk`nPAPxc1!xC;@h8-GVf8SEBrB@YCCI7# zU0z6a(2b2%;nV(p+wG*VaXP+9z(TC#9OEqf@JpkP0F2$sm}O%;YTlH z&}HP<6b=OC7a_@BP|Tdd0c9@Yz*ZrrMb%`rlOyM2cZo4?aFEHDH|1?3PoA?(lDXc_ zU`BuQn=^${Rc<-Ol(ZIr(s^D3gPRI*}7F=UzQSO6_^r{19?=0Mqbm`haQ?kXsIB$Qf zG@-Wd72CO0P~25W{J1BULxe_nBRe8Yv1Zszi&VQ~bw{)?4BH`&7>;qx zc}myI8|dkOcpwWH{bU~ci@+FKO_Rde|Dnyq>vCWW;aVT0w(DNt-kcz9-J0kWY#NM< zqXW9TB(c`}E0#>7bjrjYo_K}eg>HXAj|C9c&WGq`M)tUSG(Cs0`u^kkN3z22bC2b! zg=@u|T$Q?ENU<8PtYWU3KQY-(LYVB=49OFj5wdoi&kjVhUu=t4z zT;vg+pV7G+6!~*pxQOMCHs>kah4-U6(1&E5|#0$gCQ$~ILf7b@=D zp9=8Hja1eub+=nU9u)VNzuFR~->VY^Qg?I`e5M-}bXinJ4(HVc%kgl8`l5pYC z#MrT*>EC4G7#?AA4c9P*zZ7f`*l2#^HWl=5l?m?66Z$@Doqq#GzRY+3l z28gw>onsI?>p;X(xG;aQW~^CffQAj0B^&92)cs}-IRW~wsvWD+0>-UwrprQ{>JqCb z>Ng}uDo4FrKIz9bq2=p{Z&~!E>#`lE6p_T+LT=eljg;8eKNjT)ze<07KAj;3eC-fgbX2lZ zwWaD4GuRb=EGqM?ahaWDrojO6KRl3HYh2tql6TmPRAP;DL%4ocR;=rtA($)${3gLH zX7LJ6jN_>IL8#6kt2)8(1pl9W7fEIbFe$mCt-G+Wa+sPMx9VUGcRm_iVd(fdTPs{n zCd2WA&CLr$qfCF#7|XPYo!RkZ(0;wyxxabcecjz8G8<-E!vOppIt7FGR1l5e5y1%x zYgr(OWCl?I|MEm`m3$k$Wgiqa!g!m%f4UN!5#u|2^jee${upQE3+iy^{#g(+020a! zlP>A&(b{JE=NV`{`2Eq{&^pp6hUGDmgw!)I`u)L!-#>r58&1!ql_O3OB4iRPq7Szh7p~9dA$j&5NFsP; zX@owXi_qOj_6&iIINrSM;QQk|bpCrGbTHpq(>506$UXBax@qQ($16i90Db+M2! z5^xEt)Y4TZKF1#{k}c)dwFjx}QTe&zNjO*VoO!{$@KJTiipl~{D!N9YmgdG><^U_P z7T|yF=6(KoK7c>9buNsgO!=_y;$Mhg9b=Qk z4=VP1vFV7GcGxBeATY9S|E?e3@zXLR^35PDavp`nvU zI9rOMc06M8M9$QvzQbkN3{$~H2?Bo-;mKo^*2vG72k_Q9mzakIN7>FgyosxDHzA`K zw2~Kp&#t5&O>F=i(=Wb?LwAhrkI{$im4b|V#gH1`m*xARAkh!~lIcf#G#GQ;_twv3 zIc?~Xn9m$Sw7qD21_u0jHP4&n`y<$rEo>vx8{G7Dg+mJ;v_A%>?UBeBHtv6%*liY{ z&*&fJZ#mgB?V*?ETc)3|NuWo2<+r%k{sXekg58)7qwbFXIhr)?*YxskBg{7SEpL7I zKW6mxF*g5xoZjLV%>GZ+U-lyCF@I{GF;^s72*v!okiLs&jr8p=Vd{|G?AoMo$wFqg zP)9P3FyRo5+ZZ$H`L9~A$?<;=0y21cUw@1#LV`E0T0`7)sL>qaX~kVy{9 zt`@n7a@Tn!hb>qfZ-Q~3X3EWMsp@WOI?yziQ)@aIJeDSR@y+0fP3GJ=W38bGJ{xo- zz=V-?2mP0$!3APWXd`6K$Z0+F{Vq9VIoB!xbE}&kpctdcH`sW`8Q6b?&I0s-S$AeXd7s?=H0@5Rh8l2aY2&AGsPFcA2YL^m;TVO(;gGgYYweVLrsPFgZz%wL zi=?~4@Ll24LuN{LsLU0T%!y_TFU7>RrvxNEwq!#P%q)Ox0gGDn8=E72Y);yXy_4$c z;a9_j2!ikD9Fp(fP;zI|`F*&YjGV=iIICV|}Pest5F=KPe+*5`{@_2nFhjcpN zlj*5RS+XRnV`=K4F#2-?F&8rf@9Qmpj@I#+n> zkvTYb=)fSsHM%oq7}-ye{FT1Gs|_Y(FFumq`|@di2X9pb_$G2;5*H}n#iG-B9OeX) z*D=u})9tCjr+XTq*-lErpughCEUCDE8m(hxRxE_D>3Tb3 zjNuX!UMg1y8IrR~(gx!^JDQ%!eUXeKRWpM&#)z?$0y6YX1;kB-!O$vXeBQhv`}GaH z!ia}hAU!+J^Q#D_leVWetc9A;mw5vxV<>ww#*ZG;8*c-!5I@;r!xvehOzB1oO*=Pp z(0K3Se71Rz3-a!N)b%pLp`L#qD@~Q>`4vbicO=OCT4-Okd?UX4s=)IRE=$KS6*3y3 zsO5}lFPec;&EbL1>J91Anw3Swi$#UOS)>;r^inMMjVMtTZ*9 ze&(1(rxZjjhu?qfNdpl#QpsJ44;ak?aY6cX3*B;(BNo=81{<9(*OsolO?2R(C4r+QQ4lBO@r87vg2i5cr@iBDP;dL56< zT{EuokIE*0!$u*wHU!73F;4<-t1-$>CM@ z_U@j}dU0kYAF&A<6E%cei;roVoi#68;}_TTB;sJ)fVRifiyyo66f#P<5w=b5tD2|?~|I#c`a?`O;9Pok^ z)2Fbm%aQFphpwYvqf&LfFvYzTB_ne;)1J7UwQ28HMx5DMIojxTUt8}aHL5<190$b# zR;N6_4Fh~4*QfA^7s!g!I#Zn43Ks&A0u3l1Jojq_$F52@D;pu&Ygv2et|wCAf&=~a z*K%Bc9s9W;vV-3kQ{X8PW_-x+rU__1Mm6jaMti4TgAQ9A3LQ=z@sK#ql{B|L^TdzJ zaiO+<(=L%_559NQx|;{OLJcp8O|Q?R{)N)xQ8K2Z9Nnqj%d0dqW#oKNwTvMfZB)xA>>Kbfy)cGs`neV0GhRh(CUJ-(;rRZ28ZIG8Dqb!B%FQK{RvcU(AN zuadPNfhYxHA&Kovss*!M&{4Ms`ln3=j*u9_j85iy!X|Jm>N^Q|!6m~?DX+nL2Bi`3oNQ=tTZ zhQ|z{5mI;iHKg8Jgw$x@O9aCjAho3SjVwdz)=friaa1CfFA{bEQd=A|Agl1^kA#Yb zsaFA6jf3f!i1Ra3vAAJ1Q<0F9u^ktV%iVO#%34<1zV1Vb>BCJH<&c?UtZ&m}%Q}>^ zxH)^itM&w=(Hv)8+z#zD$BCnX#e{!BHkUW zybi&5v$a|*u#Y;O6m4e+Mw-WeqMWLFl^4TO*L4Tu7qa9x_!()TVQl*olI-7%x9TVO zk=gr`dJASrGFbdFT=)3JRP-j5U#iNez{1-pQ7y0jsF7nmS#6>w)n~;u88v~UM;eRW zAM`i+<%O)zL&s#bWj8n@%0y6O#I=Ign#rOjwI9q3z*-(op#Nv_>lA2z==>S!8P)MA zmuN-QhtrV2S`Ra25cAKI4d(fF@H_=hx&=LH!snA;5E$HiSF02!Dp{%nm24=!X;?we zf=m)faHj0}Mm%K5XIzzqVL5@ajxL!3vWRvB$`t7K_iu3CY9 z#T|)iTo8ANZ&GhRu(O(fy*9i_OJV2rgzttMo=Z$m){H1V1BcL}7;Wd%%-f6RYWT z=uQ@7aBIU`Z{dc2iex-%3971Ef$DHpXjy+uR9FU|DV+N6V%28kvEp0NR=po(U1eb$ zjP|97qWF8u(Df=u8uxNhi%=^xRx6Z=I~&m`n4^K5AAeNzTJR?^#!O#@V-@mH6ILZB zsIpl6kt5G+S%}CZ2)UMiHu9*8V~OB%M4W%KyZ1N#|DZU3KH6@63PY?M_dl6%ABq|F zB!><5vk*r&pr_$^u)C#ph8$bfkpX>fHoB054*{5udFCImP>(0@xVeScJEqHz1~_Ly zMIEXMNB8u*2^+KN7d*SI%Cg3A)*sg$f7j}DJBn`Op4P!uR2l_ID@EHA@0Hoyz%d!~ zkj|#La+Ah?#K!}vCg{Z|6Ky9J8DD=vwXsx47s=fnKW{yMF*@jwcx_b2c)~FAud{A{_ zOFjy^&zNwjK!r((pW6bmB-XoUd)< zvpYh=jaoDHnEc}OIGUVn_OhQ=?*jdpTwaAX$zt|HxUn0FOv;yK3nMhIrvlc&*^P=w)oAr*nW16~o&Bee7i0K`2X2@Q5LLr6=}Z{L+u3K&GpIygPlo|77>ur^lzyzkPOke6aVoBeb_2 zBvChGr&3c}3&X3LM-qvmFZ_&9sfh+E&k%cr3*UQ#$)t6LnEL35EXuzXn_;Qz_*|e7 zs>>+%(GvfOfm*_w>K%FdIFx-_CQq>gi$8NhxnxGQv}|adObi!`MY@y^>dx@WJFg0V z`O~R&ZJ`oA#WH4Mhy3+Yjn3Enn6<)v=`p&-^c0lWW=}esx~u*0VP$PPh*erb(XqZ6 zL?_6mT3OM=!?xPe2l3(%32L;88%Hf}W>HW4KnPa}#ex9r$M&XL2PrC%y%p<@3^aJi z(!LX5OlUqa;43ga<0`6p!1TM{st&8d#reGe_^HxajWE^=g}o_Ewv`Q)d_T z;sx>?Q`$JOrSZT;#q#qAz3>X4wsEnT8>;)8MxLsMz>;X)$uzA+u{{_fho}{QNF5lf zO&X^SwQ=pM*;pD;(>{864vmdw#TW@dMl`~Z3IPF#zQ%KBx~LH}jx8Ab&>Avf^KnUl z`pwqinacMGN>{EZw}W7GeHUdcb8&<3uulLgESbL#n~+L}#toZ_ui0pM^UefD*{z%t=H7d_z4a;u!s7TG!=1n)ntlXXAO~1rKQrNf4qp}9X$Nb- zAd4IPW{68AEEp`LHr;6t2@qeF0JDW;dc5l(fn+Z5Ch_&AN1iO;m5((TDSs#k2|pJ^ zWp^TuK=R-BhB5s~d&y6wYQcMdG3Yc>#Cb0i(1y@u!$M5~)|l&oAW1&UbR@B1nxw+a zII*NY;xaU29)5URpP1->>}(q5A3s^}H9uNp*nI>7N zEjV&OE^F^VsCaV%LLX6#v5R2Ghz$e6xCp%_Y>S`R_KtsLmTZURWI93?2fF+^|GI~q??(NidrMHYd7ni6A~h@e~^WbO{< z?gv12naQ~5Oz8(s0n*n9611U3<(vu>8U`JnBC8Z$Aq55U`!gt1ngRNV>f{SVb}F7J zz_H|@XANSvE?rcEvFK4B;%Ogp%61rBjmzX^*@ByjsI*gPjV<;8oaIm=k=bTc-#h3 z6s~h^Gf!oD^ouEOP{iE>R-8|jfrGwgp2R?*YTPRRf_qpHL9tyORyV~Or+aE1TdP`# zBZGi~F_=Suq`?(5#^cjG)xo+^0Nc&5Znc3}_!W*xMXD2j0su&mIe&R&5txds!_Pwf zF?MMhGachq!xCLOl$~880Y5WqqT81|W!6FTxH}}yQhZF#DKTk>9nYD#ALWGKfz^xKoUKIw5+a<4!%FU7 zkZkKpJu#17HODyX8?13#dN$pbYeBu9F+hW76;nSHJEAQzR@gf{k^@+^gJ&H<%~gpO zh!VPglZS|tSa*PEx%8Cx@d8@}h~}HN1;51=0$PydWI*XUV?Ni54Q*ZIr3QU#llsOI z7>k2&Xr!m9Eb%SAnDdX#wzoou)X0N|3-=dT=zy;RTC6sacQp_IP7Rj(8#iQq6W5<2 z)Toj~#$w=mTZe%!fd+A>yfN7YpBfVC=+KaVJ3Yz=z6%o;puedsLgdZ?3iIX@Uh7&? zR`!IflkvnMh)Wy9kMfKmxwvPB$LqBj+;IA=)xT9PSq zy9uuLAm_|gs*%omlG-um$S8}~aWk9&<~pTG!>XNUZ5!eckNd=6s9of8Jtsc3A<}i@ z9y;|-iO)$oCOW?-+6CHqO6`#lEJ)QuB-gMg$8;l3Az2HXh1APX=j7S{jt3u&DF8$39Q$fqOFw5nE638tl2S+c!;!=GpUS!{7K{@ z#cZJ^wpHCw0S@VgFm_!fD`%r}-mE|6M2TaG{;{yndaGg;MbWV>#G{1OIofUYx&uip zXU19@e#uwWfk~X?aw6!h3wS4@%Rb!lTKdjKo_nGimgAvLiNb>u!)%w`o+kPSeH$`D zmjub?7*_@rraOhM4R~02!;&_Ch$&X^lm;8F3{0t@5SvzN)^$KG3md|z6t?L54FeVp znW;t;gRF#QI+y0UDtR ziaCMfU{(X4L&R12Vivq%Y?16Hh@90UOY>V>FpZ@KISuuIg!FgZ=E0e9rx0V(%%9}G z!Gtd}j;eRYn~SqiaC-4sW+;%op&B=Hz(Gbo%Qiu}m91f-3N zrRWzPGUzNiw@=j-B+us0&?doFm`NBEb&~;8E)z>Sb3j{EWxbF^R+V|aHn`*SS(8Ik zC4X8Yi9TvKlEax{!6dk8SIfl|O|(c&!%<{z)OOBlvBm;4f}h$FKi6XI{_>*Y#I}K} z$egAGEh-Ug@cG3wCJXqXu@#i&RqQ$PX<^5;ldy{2-_Y4Je8cP|Oti^2HSJd|H8v$N z$|-8xsa*&;vvOB_-UoxXu>!Y5z+Wp)b$`8$0uf<>-2sa#WlW<%n~&whZp_)mr1-}V znX4JL*qc6-W47U%W1dIc?ggkdY)apu+aEZ9E$rf4he5&@!^{AL?@t(|wMdXy00e_S z_@y9!3m5at+h0@;Q}sJ3lLFVMJ`U9|HT)jDK{&g`(|SSKd9h-))-r)&wvLIyl7IWM z^hR6Q>bYd5RE!m`(~Quo*g4@`54PR+3$$0O9Q$81{xh?Vs$!#2KuqT+9E{*xY4y@b zV0Mo5@7zD=_sh{slNXHfP51qfWhs6XdN(dy)PeW;=0Z|Netmh(tL0t8jD z9fw_|V%WVYd$_RII0fzPLA2ardVeb+eTM0w+Kc!ezR1Y{b$?i9sTm-w7>^&0z*sTyiAq{n3%G_qt3W)_ zbYn&6msRXWjOX5KRI5zqQ#qU+A}WV3>Zlx+S&GVG#VUd7s2tV;uHnxrkY5y)MNvfL zmGPaUD{Le!jXiTLxH$SX+A1E*5WRrw%~LZ!+vBFjbbknkW+esVeBroj1f?|=RBg@C zx|yN>^8^9r5c%<4Ww};=B0rfCAd7(?Ly-?kJQ9HwC%?x{TMJTczbb&=JWhT!`YZN0 z4SI6p%QEgJR$0o|ByEU1VP6;*v#X=Y+CI>JZ7FeC-q>f@fWg_4F?MpX$J;U$=2>7f zyiqPgx_>tPt~e3pdyJfAuZkB)?v51gD^|X@w^laYkDd6(S@f#ClHvq?-58f;aXFa` z#}76)FOY|6dWOKdtIeyk!FV!gzuxTJ-@NX=?ry$NXViv{wBNPW`Nv404I#)lxeQ

=ksM)jz*(&3deVBLKykI$Mdc8j2lAWXBGte5>twEhDmwel$6Dt5UaKj zpMUZrl!5lG`Y=u4P(3m;+B<{Xyw0N|ly>ru!H}n>7BfP7JEvIf>ue7_&{-r~xC|0e+u5pnKc^RGAE+Dc1-mi3+|E|r`#Ifc-?1BJQ!y__ zY_oE1_S-&nv_@pf2o)_aSu*DzmQ{${R)6<<7@`N_5gRKF)dRl>H$E0OkEgi!ngh9` zM_9~cCsb$#K7GthdP_A@i0VBN9Ue0M-TgoPDN>ec?*b4DIx(C!ZfeL=ur;9z@H=e_ zaDwFdH5|F^ptpjinM=HVnBA?=9_6PYnduT{$3IQ&>MRp2KXVf{XJa?_J=SC60)LIc zp}9y~R%o-I$0a;RJjlYisO%xnYh&eX(79b%Z6cfCC`leKHzTEqIZ-o{`cFK*moSQ}rdIoGW2wU||u zFxKc|HQ?e=t&0k(8c&hYdR9&BX*?a^y4>UlfdVvvUWWc=jAW#hC|nIX-SbyfJBh+@mo;MD&_<;`ro;>G zG2k`~T>g?T_gluixhdHA*$AzO0c4r=1hSrS>hb~DQ%7=rJVIx^D?^($SfPXSi z3|QX?TiUE)VNIiW8#QTv`v&t%KsIRQ$f1erKos1os$ka+>3<44|)$8hzm0QInlsAOa=2lfPca2b-7BE5Ki`lZ{_h0dte%U+Muhlg?l!f6aPd(<7{6 zN$jQ~Bl*D-nHUk9oUn6QnqXEz{?I9GOhBiAjyV{J2rZ_umh*Nt_L_rUh*Q6arSEIco1_G zR1r0d_MJD$wJY;vFo=BNf6Ar3EM-5~Qrhdau7<^=klT_<2n&y-L3*}dW#O|XZ>f=Z z76b+~kcLCQcl!-wlANT%WSin&#)h&9EG)U3*TJQ0$a3zarM5wGb|RyKVL1~XL5(?= zchTFXS-rbuk(PXx4FfKbd|QKmrPj8sB^lWkt8_kUwNcGBf&GJSe=b3}Z3{#>@Pia& z5ue7>wbt61iQdAE*X`uW7h4&Bjd(ys2Ses*>&%eoq`UQs*Ecg@31^n z*-G*#`59oYW_IX2g(X`m$v_S-k-0IZ!_`MT+utF45rCW-poLr0$>6ah%sM#V#rLZg zd~!&Zl--&z@Mj*oe_f)hzU{d^joGb4lb-RmZ;AOEwmOxOAi~&3qR~#-`HmY}UdO>Z zoXKcXRU_1QaGV7otlpcE6i(^nwlo_j-hq`QkBmVxC;xg)E`KPEYT;KIiL5HeV9tv> zxCF1pG~y#RE#+j+Mh`C0{7y`!dYPZgjxA zeUUxyrlY~P3n`Mau`E(+YDupEQ?)f0M;iP9e^Su|E5CappEO%K8kJX{?{DW{?LYZ+ zZ>#3j<3IoL^O{$Wc0S$9zk2+q$M;T4oX5{S0p&XJ7s4vnPLi@+kZ2^Zm#7_wxWh`)v1*`*{X@ zy8Xu|kMpl~KKt~u$M>^sZ9UrB0kcW3Gt3B)q|7DQ%NIw__rI=@Fax=I-^|MIX5cfU z7c=@kgJLu2JcBzkcq#)Y&mFw_PZ&970<8=nKfWUWf4LYY!OX0NO0!ZOa#VSyAb&aD zbZ5DI@loIic2BKUN=r+-sT~N)>SJ4wYMzC;X>5E1FtI%$gNkvH5CDN>d=7hz?SqZi zilLi>-Q4r^yDD81KbNkxBYl7+Q{cytZEh@5>w_WnKvb)TKtZ+DYz(Fb-xX&A9Jodt zBCg>~f7(fYI`6c)z2B*)02WuJoQft+ltk1@Y`|m}*DWe65u&<2v@jD%r{*vgqripN z_12~yuK53KTQ0oL-kDF4 zBYn|@dqeQs!1Xq`_m%IN@6G~S<++)9h`_=^BtpM;^<-m$cZr_7!d;@grXZO>Ep8;Q z=IXJ4oB}ataRgPd3h5fLeMqmzqF2VQ++9z&9U4+5do=|yAr>Tq#X(3?+Z(>E>5iEW ze=J?>B~U>R-NjI@y^QF*i%A}jSt9B6qdF-t=Ay@7v1MWOJchf3qO{6HZm1&Y3p%za zm9p5IueB_IJ8L5}7+DA+`?4gJ(M`v@#ez$tmW$Y4(@pqpJcZ` zoK6_HjC?F%&{mKe8plU@equ73wkLxi0?QvOHPzo09fc$3Gwk=)csywHUbGI5f2=~1 zxQsT~d3zzS0o=gR9yAP`u(KQoX5G#-FP$SfypEHy-|^T!#N!-RP7puh%Uh(d{iUb| zV&<^Xh6DG?2$8tuXcq}ioHRkYJT*`-oLt2YRENyk1 z(e7XrhPC}RVuduPXK33A^kbqB${c~Fq!MEi&-cx)6e$Kg2eqzUFiI#)Yl;UN_1{~PR*drTFQ`#&dXzZ2|G)?d|z%CjO ziv{u(e6^ys3o_zZ9%~<=fABl0B3hSq*X52*ayCfD(xC_j3%fw$R%y$^1RPTn4^l!> z^c;0Ea_995bs9^Hr`59_bxu~!amVBe@_%5C8N4o6Ud6SN8cl32?nCVd6JcB;#gQ$O z;UrBH_rHyf2ZnwxM*|)J9gI$52(M-d1Hrj23q0MGbA8eSW(&3ye@Ht4^W)`4ekCQe z7yT}_!jP$^C0|P9sAKvTsHmBZC!m%b1r?q0-h-hkcpTIaY{wYddclM%%yTbOMpL}% zuesz~Nu2=rpAy-5L%FJ_?LF)D=c#qv~5K0T^~j;-B;{y&=)q0yX&h0U3Zv z%!9pFuRUdKrdkNN_6|-Mh63{%*-7g)pX2shr2V6>OYKgpXXF)sgztd5r%!B;N?=1# zGvi*u3#Rt~O5ny>iHrLPJDh->3rj_C+~i+sJek4G_pxYHfBVLwAK+9?-7Ph0x=tK| z$}?;L0l;=mAaf)Uh!i0tB3p4UQN}xE4`;h836or%jP%-fx?J=)8i7=Z_h2)dc8%JB z{t--xrA*=Z>?t*(CQug>zQRlkbm-RKB#$K-RKe+X5xH+K07I{v=%5iR!Rj} zRcpmg&zaX+w7u{ub;bZr`L_HxPTiW{V`9-0(j39a%O03if5CKPrxGJ1;G{|mClyE{ z)lG(#KaSEMJ+nH4;*4w6hwi>rXAwoCC!M2d0)1T1q_jAtAzK=a$aAlgun%$HM081yY?%-G}95I_j&Am0Uk!O`51r zVrKj`pNxw)f8FsE^EwJ>0Hhx~vlbM#>oa)~^&(z%F58L6_q~aZ6~_oc8$rT0IbTR? z$vULstv4833$Bx#j6E5Q4rruB{j+A9ClMHDI*G_WtsII5%=gAB_H<69X1Jddu+9Kb zc~`o?p=k!7AL05Q_}GFd>wdD$Aj zxbDN!9^%He+r|*d7CR@%_k#Pw@ke{>0REy5GAWsjZVL3Md2aj7vCD2hWwh*4rw`#0iKS6U*24j0<%G?OABrr+kCu!FEQ?cqlH#%2 zBD#UbKIIHobq)cP>!4rf&gh<>18N|K*P*!~oSDMhyQU;RYdAkeA6}YtM>rUwBudgZ z2WoLmK`0Ap3uKjvnUbJlfDj{JE>s7y_$fyLe-tCNP1XVZeN|L5@9@}Z5CdQw>lOFZ z>X)$1xF~?>{>*PG=o*@p>Ksg@qHr{xAK|j33NqUnfv!^Zkd7>;=o_ptPX)2ekEnvU z>5=FZj*~m9Afo%LQbEQ=3TNp8N+{{wFF*+qqh*y4>p(&Hs=p~A%DkHtf6aE#A-vXz zf6SKP{UtP!t2R#^xq=^7CsmD|5jv76rr6jqv#>*G*-_vsVko%p3gox(@NY97c1Lo| z%#H2F{5iQjZwvtDhn0T6X9_F7HEJhvPiEYCLN>z$I4?Uulyt7*Z-e6BW>6g6;;yY8 z^xhIPgw~liG_=%*9UaxVA+r$nVKV&)H){S(@UVPYNYkXMx__vUcz&++k z+jJ-ZsQa$YgDvjY$m9(rI?+&n07`r#J;e!41My zs@G@PW{wBLr{$Zn=ejlv7_R5sqZ?fyG8wezx1P5L(xG&bt!`UK)Rz+Y_Hq1Eh5jt%+4;8?`@JRM+veGkE8&?!7IvI0AIC5Ian170EPMW^IV z1iGv2FOpl4J8Z@3t=V%L4F;2=?|6>c;o}uCQRPPmh$-sAa)V~Fe<8W73H-2$-G$;S z5Q9F#3AAfbRXDO$o)2!^Rli8Y-F|IL$c?}MM2Zf^SdKS8`}5A{fBw_wo7b1O8_a;Y zVJdH63k&%+HztD(?AiBuU*bl2byjwe;$s6;iLcJ7_QUKm*;W}7Yj91O=j(RIIc+pA zWWWoW*~*_4@(Pl{e+Mh$(%(X6>Q$KNm}Z5DH0gKtICM?iw5e(e1QRQJ6^ms}PB3M^ zMLm!d8@s*&;jEJy?2b-{sm6_)wTeENEUFaMLKXch+lx+#N|zH-wUF4c$~ z?6S8+1yR8>j1oa))JPcMIEbPO#-8SNBcA0r|2}^4EL2v!e{(vTmYHL@)dPb&w+2+% z!RRqcPg+C?(_HuJs_gJIPwzGa>ZQP+3UY{8TD)^zh>9C(ymjRRRs=yM?scGAE$t)a zN=%7$s+_#Ydm|t%Ljkn)bDRrML&-V;;H+n%ydUfBnVXRNKECyRq`*#UmcQK&EMmRv z2e<#YkPoKxe{S`Jf83$|PN&PMAqb7)RrmdpxA3$^ zw^d`9qthA$;YcbtS}?9V(-B9sj&01jkltw2A{NW4KSa$)k|~LFmMer%|296(SG>Sn zHv*FxZ!?~r$pow+*@%~T!xxZR+XstSh4Zs59bT=Vf9AKdbkYIFrA&Q%YB)q;r%o&9 zO*lSPUwFmIXSs11n4y^?BgQCC@gp!3@Mvc#B^5@rsgkuU@-d>e%JQZ^hvmhH85#DF zQoIGH2rs@Ifar|XDguX(qD?xvQJ*7l3%*wU%DOTLzCZ(DC#-5&i2X4wz@GVI>K zZd*4aRaXGW4=EQ;UUxe<1kA|%%aXntk!in7f6;4g87v;t;bQZ2ds1%rQhpS^-Cq#q|-c^5OJu9PMxL3Ms1(R$?QQt#H_oN=-pYh=4tLfGzO^CBVO?@4Li8R9er>=WE4)T1i~7gtW1nj1IMVGLsx zC5H-OTGur)F42$4WcXln^ZNR_d40b*7+q{0A8z6#!_M|54=i+G3tvvIdcQmC4cf0a zM&+;vCEwYQe%Ha3DQZEu-9ERie>`CAZWglVq;+2LTvKC3aDhW@j>wS>I$!6i!(T-D z<^+ostHQ;nbr@+U?v9eFe*{iVJG-Wl|aSOPEUv#+MXB2d+x?8m|`HuIQBhwAaHlcQKU%Hy9Cp4jt&0efOgHnA5TVus~4R18Zo7-8a?KZ%Bw0Fxat6@DL-Tazsscjd)IEFp^v>yc68)gf>t0t(@;R?@ts3zuEMv3RAb3>R{^I3{1Z> zmB7>{y~?a;1MH{i+vW|je}pA8MZzTkAcVq+G2{?SI~^E9Mrg4&XCU525RC{MkV;gA znRYrtGB6lbGI@WB89$o%U}b`=XmV>DUDfh~C%_wW3lzMY&C{TVE9;fVM02Gw4=Uxb zP(dcb>dGC5h1^N_GlPau2`K2w-O|jw)c(4+uKPH?n2dd6d$WBne;)xAyo?2BOrnty z*+26}N%8-)_wLYHKkd0f~q~ zfENHoGP?fm_xG#n_hV*2QjX(oEL#L-`cYl4uCA`GeixyejGe6`1Q+qsgj2etuezWR zG(A!_dyN&__Vz81||=}=#C4Jk`8 zv$A53`X=g9A4OdTWDC9~3!ndcK4IGRc*y~lL$A!rgtc^Nhx_*7bDh@|V=1#SB^uXF7bEyy;qN8$ zksaqaU5WK9_g(|GYj?jY|2*+KG_9=EMVUlY_D0xSPN9d@zMSmf062$0gIPfcK@OnD zMmjc(*5BRxg3|C?FAPEv~#%calAO61!=^Ya`ZLwWb?Qx zv1TAieG^EEbB+`YlV5lh14q?clXrL}0%97N7;&Vc&mA3D}2t#iOO>tY{;9GIUv+QWzWFWjJPU9SQu!wlgj3H$PVFE0Z5qXo+ zhfHNh-jaS#RtzX7S*X1AL{BqX^`^bi4F_=r`yt~S79Y)BuemvYK=au$vgkv= z7JLrTFdbVARqqA1n)I2%(xprtg@PapziN&&iGQ3b6LN}w+vd>WtJo-9;De6b>7p~rM5s}qDE|Jy0ZNpOl&hXGz@t{#SW3u{EfX4sWfUH_6 z^3eEpZjG$I$sT0&g`+{mc(`S<9_o&NZ$wjxVBj=_?L0BY9&7rZ5`~o^ucP935kCU^ zM*KELk;B+wur(hugzOxsu@pL;_aV|+x2b)Eryi*R!N1wLV-rlekcD?TsX!# zjTMwmTXeyLa+)_GFtvz7WLvZ(8g}6ru0k;aBNhQS2)Mn@FkcMNPyq%hW>@xq#vscV z_brwh;S2X1INQP)Fij%+uk1&tn}87-d}*Bq2|V!tjM$@nkL?a6gqzd!CRQ8u5b;NHnzJPg39RI3WAm@`}M)Ir;~eItoru{dAu z0-4DB^Veo;3;wwA;#jr}hS>AMwTX-Q@B|Hc%1{TpruEBkh3u>A!Pb9&Y%vX$obiD5 z#m;%f^@|(-ZQL#o=&o^*fteDg@Sd^n(g3YnoqcCpKBZlZ$%wkjTuP%9V_x+cg?1kKf^MG6N2VvpgU3Y%(oNCA>Po_vXf+V+qN zx9C^fdy5ffv`pdbPOOdCUc@@REfxzQ^e{%?;{F1nkl=A|l|^QMWC>Xo7J?v&xb3If zaGmy;YYRjsnIc{YN#!}#hiG?G9lRPg@?IPj=;OVy2{|Cvc`@BK;u2*iOE$0vAn&Fk znWe%W5r2B4p*7Id(-G|k{N+bkXB!_*u1jez;4XB^>5-7^zRyi~XDJs(gzdZ+_R((s zO*zO$qZ^V}RlyB^m`F5bYr`9I(O&DsBU_0koDJ?32pIBzBa)XnoM}ujn!!cANi1E& zAuka2&0M4cb%Ub_<~AaGVa*XNkzleDT^csfJ|p>k&S*|b=OTlUWR9uJRUeF~2~FSd zuMj0)+aMRWJA-Z6cV6ths_BgrJxnToN~cqNgeHS$)W)z*aU0?cLs*L(VvHso55^r- z!9sF{Ei;}2ontA98ZVyrVU2xDs#RW-q zuVoPv?+0nWy6B#`bUa}gMWCJef<2gJA3ig^ZIj-89D}ts{l{-UrP6}i0#0}n@0Hw5 zVIMn{9_qG`kG|)c)WGQG$+BNnL+=@;W`D8>)!H-*h9v7u&}+Lq!_8_=zqZa5k%skk zoa4GTu17elQ^547A)X~@;bbx6{Y4PWUq71NR*;KqadDN78G4g~jK`gx9=cU^q^Zyw z_rz%t`+PzCA5BhhBgnrC?)`yr9}aZ`^asuLrhu>0E(wkqZ171KJph8g^GpI2sDIhX zvg5Zll^k9SKZ>VLla20C^UyUE=)9o!Ja!@Pok`C&>fGejtMqPEhXX>{)#thMJ9e%J zU~=DaLBa1A$}~qlOiJ-L_78w9W>34$Z4UR%7Tq0>Z^y{Go!21bd33fi_bndC@q4aO z9DTk*?uav-cwU`gTN5XvO+t<^p??PsWAk_>=0479V?@Z#ub{ygs{x-aF8m%LAq-CQ zaOJ~YN|*7+EOKa}xc)qRQF_8WeYL+%BClIWL23an^ptrh2~a(^NP78A;#X7Mt!pal zXaNab|G4DU95BN&$65<|-pDxDe1Yh;O>YY21NPivVlks0-RzYvta=U9`&$guRuK=K z?1&;9-cI&KB*2hJFW3#nd~Cx;b?|1kQ$`3$@t`#80@p=lZVX?t zgfU)zxWq6s>oE;?g4y$@_`Nh*vp{e+5rp@n7s`3+ag(ir9DjEi`dmu0REb6iHd~yn zcjx2XJjda2ATJS|?uA`DkczXH4 zbR>)l+YHQS$Rz>fh%K#gu7UN*K$58`tnD!nI4q79i`ir}|5;pn`AU;9RXDN4++nY= z1H^P}rwC|6RzBSoT~PmU_bTkDu%ImQ&fzA^V-TEd1Ao=U;K}?gE^udLirY;9jwXz0 z-?OY|W8d5Z4`qO>zN0b9Kb8gSZchyOOhF#nspH04GEoO#z!!wXy~%MoH&9qwj2EAI zq#(8q2La*Gn69ru(>`uxWBzz0Vk&vFAW^3MCRfu6JWm5*hrPB%GJU2;d6xmgfrtDs;a%kSc}s082%}#s^#{VZE|E zm#vvb>IPyYMZ9j&8oOG|D(xUbm{Q9tyzw|uoNO&N za+5-Z6@QXWG=HGHS-&K18UfaSB~)bRn3d9T_Fnf8#=sK94cOMySPkVS<>#+GQ*BE! zgqYsRcvC>)3=|RCO%k~8nK%RI3N^^zB|SL_i4hA4D0D9?$h~5Cz=bxpb3xrrMcibz zS_Fr;*m#tc`+(hG#0<|ql=-YC@FaD@Q(|CNbO2F6uD=DC6W?QJ5ML0IRrqTh7F!unFY&6T@ zO1s8H<^(48<86Y0)ogl(y3s|5Lev-mS?|UEIO$ zu(5ly&3?QI0Y4>^^vS#i1EU#`ea@&t@tA)+aKsqV=NI#Dk-%}XTwe{&5Gy)Tp12A1C}m$F(O?ZdoSh<>jZv<4z88z965ixUF$y zcLgW3`lQ8sy^r-=^mH`c{iS_|2~{rSfpVnAR+#l)9U-KjqPl-)_By~~ zPNtMsFlcKasK*JjzElw_xzwb*9WLhIosF5qwb)Mpi$@MwD%iPykJ}Lj#MiI;!sy4D z0C_kKSR}$;$}QHIfcY=^Y^{zG_oV1PilbsH;B$SQU2Ym!6e&csrr>Q5PeLn1$XB86 zS{P)!)CZixlalsYpJujrGd+JU@Qmp|6TPAbg&EEr(PdukrJ@&MAZo;;w|iVYR)IGi znCs$3Bhyy;49$4EO4ok0Ip`8~6u1RV5?;_InNFfIZkS1-P4u5HYYA#w)e}9b6j%+U zm^F2@O3E%Q>Xn17=x}BGG3=Lgf7fv(XHHLqywQp}&Ie`$YJ+h}jSU2cWyLm=QHm1< zZal%#W0Pl!Lw^_tP($NX;N4pWhBGK8jNpRL9PaB_Fp_Y4-sbo1NA{u?lRTvx`B%k4 z=Wis9e=`}p#BI{@^g{EFzY1&%)`(R|McNC^%A*tGXvXG4d%FSWdSz3mQI9L`GOTMI z@3v3IsYBqB;@N2VlXDx``5EgrorfeJl*~L@zYJ=V3r47sZvJ*-^TaeX$@v9i|@J%h-m|>iLpD) zmv$eEP70HaO3oL76j*U0ueA7mVGNIU^wOsR0<#uK_-O9kkRy|(@*Mm6);+0K)*}mpxefVH~q~iTPYQ+dMIJ!bE7({ zl-X3{+dOq?!>v{X+22BGAwh-QuDg7g9qJ*iugZ@vKP;E#@@gcl+R(=c(c zN`Fl?2@5mXUt`^QkD_MznxAxNFSjl~+@kwd=wl{yKc8wP{r3nrP5+d?(oW@&)2;WI zaKy{4tA`#~YboR)l?Qqi478(e+el}V*Xym`$PM6aM{YLM{&dNz-qJ`BqHxlGs5j~~ zHW`her@ZP39SBJ>N4mVEsh*F7e!4QwTYnmEsU%SY)WbYzI!D!$V7KI*$;6Y`#NizK zD^M~7hXy`uC}&!QRts~FBrZu^56Hg*B+E?q+csKYBr`Hpl1fbik|)2_N_Oh8D0IrK zwPws~wdF|$luK3L1Uf^~U*jwg@900@V-IH&jY5=>LT5bw@o5HUHusO0~ zX18WtB5|H=>e^m?IFV{kwYl1z)>rwxT-K`&Mc;vlt?Uxma$noDdd!g&7c}5z&H{y{ z=q#uYfF6c)|EzU5w=TaNwoi9IkbiBFWEFB#kxjcWTPxS;rA@fljlY6nV79TZ(@U!y zq}>Qe{d@7eU*`(9!5FcEdz!L1CtLT@?lh-`NJJ}X90H@!br&;cZx5fB3Rjfyl&guD zS(j?uV$iF9Q6IclzR~D)k(-XnZ@_BM^Y@4wUtAzE3_%u1o{n72TfRM9+<%Ou<8L1h z|1^BSZ!gSs!gTQ@lV*O$b1(`7r$@mC0|Q&1(Ir)T43X5;4tkR|>BPfDlEwtCm_I?M zAIl+*;?gb)QIL*h`fLoy_68umjs9(q`)obiCBp!&w9$Axu6&vM_&T6nT-W2G&X2K? z6`I9{?1^t6KwV38M*tG8W`7MMTxt+^Ab^l z*S%>I)QQLF8K#9mbRZy!(Q_a3`E(Bu2aUE}(8Y!+f>{f4{UKew2qi9B1mzmW;NPs0 z*wvd=QM)~*07t`5W`C`m2baJFm`Q^ZSvN+yww6VeWf+eM=W4wtLnWKVA{OP_6f>kT zpZ8|Utc!SrF_uIS53?$OiqGPjMre6pJKZ=cYR*7cCL!58{)3A?OtvlTyw9fC#6{Gd zoc(qt50uDHoc(e2Fn6m>LJ<2p+7tG{&$WF&3~38hcQ{|{uz%$(Ke~;;lliL*8eg@6 zm25>4q}u^Ur&B@Ins-|x?epST(~B|n1;h%8RQdoH#uHfRr11b-hS)^3qA)xZ;g4vT z<+fk_u>yvy^};&8AEYo-EqN(hdCv#8Mw- zSdLBmLon>Ua0rHlBDKZ`@nINYlJr1~6pPIUoRRTGJAco~5T0hA(eptZPO;VUp&5nK zCfJaMR)XT}_)J`~_Ys;DEI)OyL1(>l96ip?u#RyvW6U#It0Dy;#~+`$@v{x9@S}6@ zdOBH3P}sMN)s#00Qb&fdMq1bu_a`CNfUkHM!Zl5WuPy5`Yw%IQ11dm_pqUXg^m_W{ zd@0eGD}ND$;o%pLzuf)q=>cMBo;^O?{o%>};okFazI^i4cQ1Aio;?3%KWQ+wEr`M3 z;6ibr4&Ah49R^Zv=a7u8>&mp*Lo6SdB*VkJ@0=Vl@NA;8u;MF1^FavmFg-^NXBviK z!N9NBmcd?z2fJyB>zaC4$}-Og2sTy z6@MBN=|+BKZju}*B3HZfw;`2?;PHU{xAU_v7N?Ij$0qV_=B>v3!MdDIkybs^t}T;w>HwO8@;7C8^FuyD=G`8IeMX@ zHsq|+LTggDF1S^pO+>U{i?~ZGB##hNe}8eAa=KWpdDZMOGBAo@XA*>BHiOt}+6*Kf7cNLuZQe6Kx91SFr-qme8#a%83t+pNk#yPR8rij6Wf z+N(0yGD$Z)HOqo~z#P&Il*U7dDW*!8kA)@?e=j+UW}IW z!PY+)i&G}bV}{iQ?s^<8A7KLERej7bj_aq!I6^aBOSW=L9Qssnvl8y@yXu(ocXrZ2 z{Ek>4xn}VM1@t&|SQH5fa3Q#BrJu{wN*Ah4mVxyh zfZ)Slk`)TCYClDeUFO+c;mih)Pw!yz#UE!rNsjwSP}<2W`QqRpaKSp=ntzlYELU8m z>U1(%oi8yU^92#?8b+2gsaBxM&^BtzsT7faBl8dm`&tj^0s^R=J0LNgnpoaq!Kr>5$++!^s zlc$4Iz;I8@-1OAuk?`E2)_-M5C^`G$K85A_3j~uuhvLa5x*Fd_O}RUWQN&9LTtzUQFpB zZoE4yG(=Tr8{&OIT!kg0!=aMqU6HGJ=o>YdJ`tT#IdSrsA#(=&6Mw5k^N(|wTZV!z zy&f{EBIjbUy^z>as$@6kTt>~JGTd-4BVB`zaZAdvDPsya#t7zqoO2tWBd?jCMzFGcD@XF6baxpA2aDVl|W3GYb(-4sD=C549YB!jn%XJEhzO>x1dI{rVqebU+Agm+EGV85@&1eF`*GQ zn#EIAa`EWMS^imgmb_+R`r`I*V^>MzuXlh{j%j+>?SJX3mV$lk+`D(DCGKE9RK6Us zgUO1Sr$umb-W`;$(xZ47m>u!sF($^Z>l68p&T$Gjf+IYz@4EF1XnKu?vfmzVX%~;` z7bGzTCZ_gHVCl*l& zclgY#%70ewTd-b8D9E$f8!0f%z6aRAvgVW?qmI-BI1qmP65~cjmD-0i18iHV@!n>D zcjz$#WdXVpTok5uKVbxUyI=67p^*0~LSBH7C-myQ%4a@e0292!nzef5Inqtf5sN=C zUb!Ojt@*=~g!iyTxfwl=c_+^SGzpcUpN~su@_#CeLqT!6)8(smsZ$dq3})S=TC(nF zuj-hW(#5MRXF`WgX`5i$)W{~?d9~5MH>W9FN9(KEWUz%4m(!!^Y`VVU@ro14Z`SQv z+C&Vn2vSZoo5>Nq9s3ncM)Kmf3v!5(>1MJ^^i$;236L~uJp-{)vQ-QqPOi=GWD6`j zbALM?zGW&AT!)~SPSBZ#CGG#>1_ikI`D?j^s97BSgLm9#qvs+&>eSt?pnyVu`VQ0+ zwDYheJi>E|#vy_yPo}Te1J^_%vMifx{!UOHUIP@FzzrPmR^(XE;jp?;2NT!m;785E zLTw{jB33zILACR&GHlri>DJh4AjNDO&3_81I9N3r56Cj!OoIPK1WG2T&_+BPP6a|< zG;YKQdg3L7V_aoU+)MJZlW*dyGT@y#KW)JgLFb3CshYmqJmgIvR%qHcJ+!i2gy&eX z?{fyRZ!FH#CZe4}ryG2!$~lS`tk*)mHOFv)JgXm__-;4%;XZ)-Hmn}9e1UrjN`Gnj zmIK`qRAR?LO;uug=_Jz}mH{27JO18$Dg&uU0}DoY7fGn;_SZ`!As7S-uW-!{VT~bs zOjoHHn!=hT6M7Tmoa&f%tLq42PMenw-7^0t%<@aa1UX)3Sp4hFMrsw!A+wYFSJ;%7pGgzUo$QszH2`Fq26$SjBrjo z5lduTq&a*|IdO`>bYe2Up?1&S+Iq@`U04Q`+P8P;#taiI`)l+R4H>pDq>l&){Iq^X z(({^z#eDJn*>G)HV!)mpJof@-xfc+vK-FCK9j-g_Fp-!+*%32jZ3#dyjek#Jw|Vdjlasi=MWEW(bT;1p=lvV9Wex)g0Xf-gM>s z96Ju|L=y~AlCpX3^G=J<;(r&V>>)`;XYnV!XBste1+;fn)u|jInUKOL#)r+?bpZUZ zW1HNiv>C+8X7|ZfCvMDsVxpV4zDYc`P7v>zJAPpGy0xnnQn0nECRv-dhMm>bYR#PH z&|O+99ZD`bq=PA_Nk7b(?`}Aun7lFBSyH#v8z9ecRDmOM-P2-sM1SK;)qL;qrWJXM z8n+xbMnG|H6E-LBZG@O!n4xH?^bipP{!^&uEbm{Oe^lghvgbVbtD<@h>;i6cxGPB& znc%UFNLX|4j>p_~mvdfvzzkbn2!nb(#SWs}4Llp+3yCh_(0j<>dW=o*#p(2)68qkq zoiERjgfw5Hw*YmFMm>?YG`MU)ba_4hWKO(F>z+G}9TTUJOf>o?9r~7AlS1~IKE>jm z;Y#fTD@>Rxyp_VPbRI3~*xCe|yUPgW3p|gd>9Fujb);UOBuMipOq|ji0)9qH8+#sHrTo<%!(`*~LrEBb{>!0WzAFNeb^;2T;4JO@{fX z*@=IjwDzMK-FI3p?CmEz47e&^1?G=k0>?W#(>d-+m=;}K9BK?EhwJ+>OEUD5LzJsS zQhP>k^;0wLlPyb{lm*rE?+Bzm34K@+P2u(hu9tE_e+p&f%aG8{mkfO@Mf=Fk zsQ>XN8UFs-Y*}ST=c3ul&e51oRXsVN%zhCsh&%oI3~{tLpYwvl&lmpE*WlT3z8J%C zJ%o<>+?3oyqLlgi1$K~2+JpQuT|Ix9uORK8Yone{w9)ab1Z{xvfy~2D6N}{_1cl+A z+YN{y?~f-_oOIU)5qH5?m0Uw?y3!<46jfT3H~kv4K*-siq`4G+=Mr~;yPNf)8IoE$ z0o<++E7he~^MnD3Ba%+$ah@7BOD?M*-S;x6k#q9tJF5e_1)qq9hv@qWwJIhX+(GW- zY1JGd87ZG%KD>YVp_qizBb;Q>Q&>D=$1^gcrJS#WKPjw=qpLFY=Po0M8BbSAFHI#g zCP!{Yc*Gm;r=U6H)oMfjtSWzl;_h?OyH21HTgjtai8<> z%7E@lkRh{PZ6ImKu5nAs-ZO+%HB_6@c`mCtz_txduuWhu2P&dR z8_=T<3#$;eL*xB}aGD!5? z0+0R;$n}Q$!AIhk;i(|8zjzPscyq_D!0Aj`p$SMFOOgWjsFyH;Qp6RZ|+$ zf!uB;MGrP3CN{|wYw>?0H9HgRpqZC30H~TjVT11w-GM0^VN8#tal5XC`H%Ghrf;5Y zd(=Ec^nl$(e-xZJ|I$80q8c7>-1_5_M}K_w=#Tr&AJ4Y75%HUW(b_3;cx~R}=gl8+ zD)Em$vcIgmS2+YXLc~YEBf@Y50)u{M36YK8dBSLkKm8Bp3C(|FxViSCzWnVd%NPrr z3C3>~3lBGwir*|6e&+_x78~lw-wro0h3hrc<8KoIf9h{M{WcNspa0Vl@bJU`i5R%n z0&j!`-Zd7JlE`^;jf3Un`&vp~YxKX3ppL@;!xz~J%KQ!+@!e2g2wxmq70$cLCUE$3( zL!JT&D)Gt>xy%B+`C6#K7kK8kCglM)5|c;vevz;j*>Hb!<oj=$<}aq-#r?xS6j{fPyfKJYj>dts!JFt#Hs<-zj+mQY#M?LL zrwF$_Cf3|Y23>cym`c~Yw#9ZSCyXKvZ|)>NadS&pT2uca0O5QzLsSWp)U6OsHsY-# z%mX-T{_pu{zD5q|_4Msz|F-UM$r`<_n_TX1Nv411`{owu_N4EQItC%X%-t^bERM<1 zfzStV%9g#;Bc>KON(By4NUH+~ouq!;JwxWi%jv0735TjivsIvN$cOw$O}C2|XpLZB zSL2Xp9T%M%{CL?yw%PZbOz^r{#te2{{L;Nhfff?L1*%xlW>J2zWEMLrn>@|g_xf%% zG+%!ZlF3VKktuLBc$l=9g!UD1X)-MfZPA@$ODeyNAE;r_mtzK0=wuOd4$LOr_WUz( z&7d!vINE^o_;Pf-4&JNovpC{kA2aX5H*97M;c8xIWB9r>5;mcr+f>sQ1NxL0evzC)Wr18+jKLO*q0f}AdV0yWl7u|It?>>e!K$~h0D%5A zqTD{lt(1ee1ymE=2Dv5#-Rc{cPTn@5Efp9;$XosyzeZ>WKR7S z?z}xfkVFST%qtuo>H?{o$FN4^La>v&i1QCr*GyOYTrjjFybCfiV$|l>IFWy=m*ijp zQ?QjS=PoCEIHs)bB=T1EdYV3RnK%tj#}Tu)BGnQWmJu9@h-Pk{N>j83i&vopmu*$&(>Lx)JPCWLAfpk92u!+Hk7tr40#=4u>*SF!lH+quTQLp zm=XUql-i8kEriOYBY$G&W0J#iELqOvhQcK>$ijL63neU2vN|K_igM1>CLdL}opf^O zu;9Jix)gchix4V2N8+10%?b@!$$T*U^GB`p_EH%MRSv?HR4w#V1huQ2 z!k}&)J3GSo#CG8LHgs+%Gg7^w zPOj;)6&xfnV!G^v%}{eUrS!iLHFeeZluLtaZ3Wnco9qOL#&l?PTY1^4ij#bn$;Nx# zed^@y6a+4zaxi~{!XncFg>2nCSqrxiHwousQ-~r4_gx_a_j*##njjCz30sG z3H9;;ad+stjQ9~#0J$!#7*;wUc7kXK#!Oh(S-xX~@R*|Otg@b@LAbVApC!$CQMQ=n z9CtB?k`&B9c)MM&QgrrqqjbEeIoF~D?1fHC93;%W!i|5YyEEC@zRN5R?-P2DNbrg>&_blsdlO=MhTT<>Vr?vRLBJJHKYgmp^*=QWJ0bg=J3Bb znZhw-uR1+mEa3z{LkOGH4wC$yjFjVadF(ooq+7EAyVn0nUpuluWph9 zw;W-|W*^F*TWQ5Kn!LD8(?}^j(!4=48f4l~FyjVKwRycIDR^9)fPH_$Z)tbP)WJ=$ zBI&92gC0!Bk}eMyq)oc+FC%Jtse(<@+N3l{^g}MQj@9k76N&1XaTS-)Kor>bNMhE^ z&u4$LQaO$_Q1e4%do$8yyM)%sB{ZKaT3mQ!GYiYpJq*GA7_Jvj7Z*sz3}<#}Mj~*2 z3h(Duw{<>n!)KQi9Xs2)?(GZX5Tis{$m}aK$<{E(&iGlMEOD(oWA`2}m&jchGy`Lg zaj(qaHiE#-rem?Cb&civlcdBWTuyH{8Et>yEEg6fan^oIyKj7xlZQ`RNW|B~bdEJ+ z-#ADuW?GPDEUMOxM|OBySi@#BxE3+RMu2V;XWlG%O8xe&-<=8g_~~9QAv!<=fwu3i z2C|p85tFe~TeJu6p3jdZ(t0qNGl^h{rO5&Mb|aNh@3(76L{bY^D)Q^ig9Hk0-Vc9U zzD?XpX5MI>6RF}7HmUZ4B%mm-;|ZQ!E61wS&}|Nkjjf*?g`#=wY_MW}$k}B6W_=>s z^g(IF9_e{&F)yf!XZpXo!$vslb1$8g7D}sLR_zPSofPag*pfq)vSy>mad1Wx|C0 z#Wm4reih8ATuzPFjrdv{tao{|gbOT7WnP%5S0O~UV{Uxq$+)d|;(wUv4=1N*I6qaD z4b`(bFXkfe896oQ+g4TmC0-P4B^_x$Ij2B+S!a72b1|F9hrY4x@7OQ%boGB?zhJ#C zmP^}Y5eWjp=V#*?q}Vdy_SF=e^L)BVfyLm|xwc_r!%p#W9xk>h`**Sd&~MR{?&AlOB1!W`OaXE|yrLxhiw)X-U1L(d6g-=y%Da zDawB|p;*cSp`>I$bi%uqW()>1eV+?OJcRp$Ul)&9!DrC(p%&v7u>uDJ(tM zi6`-9-Z~4INmPCp=>o=L+vBK%g#%;fRUhvn9%rZF$LOxgF=bma$2i}VpSJiXScxNc z&_gRBvc$rUqZtl%HXWvF(D1DhPL6J z875u^0hga_nVIiZ^L##`<+4T3`+fWPddVg%K)-0ViCr-Ui>EYX_J?NQf5F{6$5=%@GbdeBOUG?iR|9o=C4tz7T|1jF`-4jd z;ng$eBYxD#y1+e*)tnN1#gr2KYf}su$W2;-Ljz9&Z!%Mq=mPV;*O@!=3&yi3yE z*>dv#o@1Rd8Si6}6CV@A1@Oo{q{r~?L89cBo^&nE!?cg&2;B=bIYq_Kf3FU>Zm<^a zVQkUhVCe&w#-enJsx^ItQ0Ua0(8~!(SWYI>HzzQ_dIF;~zZoDHPvK~lx9NneLp{=p zaK!%G0WC%w4zkKY$?8!!GBgS);ZQ2p{(Os1!YJ}6D<~GQQ8}Wq9cg7?Wips#4RAek z$!hm-%u`{IK?|edrrof^f8?h_Wg=q)-w4OMY!rOykrshB#8#O(c6ztS%jMIA0e17| z6z^c>B0px(C4@+RmbArYr^rK{aTxPsOuz1)-ICQ#SUx~a{23)BL0M2|$F*WAq^B58 zk~5y__{8@kJ}CO%v|IlC^Mm;J&Y!DJs&tEeOCXTYRBeyp3G}|KX3o#f7E9>SzrZ&H zpAmB3{Tcs{=Hmv2gm1TP?j0SY&rtjnWNos{8Odd{&RrOWdGn-3@-*G(v0@RB{# znN0)jR?~lqePul{5^o3Z6%t!58qS&Y9O30DeP1l}#q(#W1=@VG9I{se0Zx;2v_b*( zlee^ne-UF4!a=mDaA6KKqqz>=;3tr!4cjy7xe9u2mk=U;A~rGZNF)fJ&Q{GiQ$1n# z>kWka?W8%LE|1Sobz3|+x1>$UzZTmrA)Y+Q(^lFlWym6^Zk2hxg<_4WkR9F|6S{71 zgZfo6-;hHiAio!T^4c6)g|SRue;mh)`eajPG)@a6s>Y)ZlL;4m>$A{g zTES$pLhXF~T@U7Kwy833Ze#}T)eLh$ZaRmf35|(sXi`T-(X9hZxYZo_lBV?|OPr~rE>}mj`ma4Z5 zg*J;|$ubzw6Hhc8oYSxkKcjbZ$>q@me__Zbd1ZhxPVXM}Oglxo=T@YRy0|Dxt;Pb$ zyhfWpfp6B;Z|!H-cbA4Ef-Vu$33j4!TDk z(0WP5fELy7S?9^hHu+g_!DbmEfio{JB_opb5ZOUVQZq-^Eu^7@de}Fct;#X7e@e)^ z66OHQOHi-h({#qD+n(My?0cyBOt^`gY{-NPWgI9JUZ_%05oR+;pmZ5CB22d(6yPAk z^^s**izGzpI&T;ZX!n@$tFqWDtqRGeY*-NMa=*K}@)+KZN_)+HENpiQP~mw_CEM2} zhHTVsGRgimf}^-!Ya3z2POTAce_aOyDnnus|nS0kcL(*itMAi4g3W zIDjC4$)tpSI=bR9wQxECVUW8SyLxZ2n&xR;(PY7Ioz+US4jA)$vLL*j3j~s3ZoqQf z?y7=cG&!~QiG0%5L&La_ev47aaJiDSlBB`#TN6q#|1Pjra@ zB3u(x(%*(a*<2f8!l!#iq)<=fx02iRYN_tac81W}DqslvRcrqqe?eFG(j$~ z$FC#`R)qdlD5cbeV%&hbLE)|&+oVeWP}*J72b_DO#sLC}!MRwRPC1*6uJ~pJQAOax z48eqQR0cCrB4*izZlB@sEOt2LYP?vq?*AKcWVpli&w_vz#E2(f}LC_aEFxJj@W$dGu{Um^EvE+E2XQ z;w*WAX%Ilp7#Q>)5|Q={KU}5-C1nDAyFh{uhT~X7bMzqg))tK37-Oad9T78>_`2p9 zqVWoqj3%ST*8N7WTm&rqBf8PY+0K}{qH1c0B@&FIFv)3qf5d}EKh=up{w9N75ZsG@ zCrj9Nx^WpltblxY=1vtQfrv5glyh)19X4IyRe|!q%_vZ$5Q@rduPp)&5LuQy1Gg}!nef5lpfqiQ)VCSE;gE6jd@wv`RQ zEsYx3DnZRw`N={#mEQ$}+ZwcqBf6LbwJl8WD@={JiKfJUY%m92yP+e;pf-RrAG|AV zR~O|X)df-xLkGR>tmp|YPfAE5u1)a`a-T_!d=xpNTBxkO{t*W~|1+7wI9`4{Y@ap{ z|4%h^f0sqIv7MI2a@bf;;Pd@_-0bw~2&YJ^P?tOMeQ-`=q%e}GS;TXai+&8B@fg1bsJm-H*Ic(kq7b*=LE6cWyrC9P>yb=UFW)Y6hJoZab}@izO| zeE%i$_+(9ZuTNrlkO6~jy(ZedZIIjed^Uzt?G!mH5U+)N4|IAN%MafE|M>7B-DXj( ze`NiM4!qgpjJa_0g>G@}qGs@Ok~XFxS648Fv`K4K`kh*Fm9cnXoLoBSQs7&+__7=F z1O0+)FEd6^eVLjgl zNcKD;Fzxn7j5OH_si0Sk=_0 zW=)fQy*z*1zKWOc-ai;S_S|`Q>$tBcz)OynEzufa*e0A=3sHPC_o;j5F2 zb}@lngNaTy0PNcII&v(7OAsl~K`a zD7^N&tifX@s4u?2shXd+!LXqglyvs4G@8^Rf4G1D{>RG+kM47$@ocm{`DAN2yzd?j z*Q>4O{-=K+BOe|@jB!B@!&}5&@ga%!ja;DX4O9e^99a#)72kl(oN-41kGTRl8Zu+v z#r%KUh&v-N75&kGTT!X)=3@@G(3S}@s_*ZuH)N>sC)5#lPkO*{x z8g%YXNuB;`fcrqEAK1(*n9oQ^_nI40ljRf+EPRJK%dhtu=KO^vh_VvWlN zyr7O$oy7w=^vH4fCWiJdj1iY|CP=KU+)?G04n@T3>hx$a`x5zYkSA*Q_!xc^2x^Gq z0KHDh5BGy=5cVNYiC~A3UDe2_Jw1PCLd$h$PY<((VrEhu6a?hF#~mXI{A=hd?Gv&E z^a%2d*C5_68Xhx2(qud^AU=Kk)#GozIDGN^`@_AbyZigFSmC27@J8GXg_%)+QODuF zRHdKC-yFR7v7;y7ru5=kr72zI+C%G_08qU)ynHV}Sz)}&f17P};S}7Z#L#~i)thaR zds{^)zvoiCZ|gIkAuu%-Y9w%-RyzJZ;^>P)-XbHl%9WY@&8( z38qoOqy?b`lR=e@4FuQkt&xK*wy;YeGQ$Aye0ZCQ528QT%Y{rrPG^Xzc8D6Q}d(ZySG)drly>5QFyR zVrld@;CH@#q<0#`<>+6Rtpc;A;3A!D6MoqGgm%R@qf?mgcF!S@F_#~1HJct6@AdNa zhcFb^YBYQ0gdKyHexJ%EH0&8?_fBz;vQij(p!WD22Y=P4UH}-}0gvN+^X_Gde~BWZ zrrayhTHMweazuaiU6_b4SJY4>$BXS)s_GaWk+E-6h9`(57vHyMkODHe)QAFH$TUaKP$O$PcUXeo>jws9JeZZiQohB$3DXg6ggOYf#hkA zyxwzrni0})@Dqhi-VoWb%!Zmw7|GAfZol22RLrB(Q_MwUcU;8Ge)%NTmXNZ*c8S^o z&b+EjdL0UmsC0k*EQm){u2hGLp0OrthbIDsX;9O$VcJ!N7kEF4YM+WrqNW^X3#Rs2 zf9IzKH&O_U_e$v5Y&S~=V7T(|OP0fOL1gNwCR%YxVUuTLm;Mnpo_Jq^7 zUZ%saVymBS%I|1LH7?NU*(0_vRL`ns*H0V8L^Nbe@l1cAIijqtlTn~}V=WqBW_~al zDA!VG#ni!1kv;}xVsP_5$+h%V70iR06gZ2?&Ca2|RDLdqC6zE|grIQqsodqFuwr|~ zkIv>hVicZn=cSA38hGqS*yikfbs|?8D8ecrvAFNIf>jpcXA{h_d_G6r zSkCu`h{=BdZ8;T7Izs%~j$JH5TTk5gL|Z;8qbXQF1}>RX3OUcdnlPa#c2FK81JfF; z2%BMY#?x>3jVL6YhGh77x!vH%&j|Zwydf298D7MTRAfmo(jDBaN7pyJ@i^?q6ckAK zx*T1R|KsenZRqFHW_OZzx#jxE&KnuIm_NFPFBr38Q9gwI*?D1 zT`egZ@4IBvF7ZIT?8dR-XC?k8%|B3mj3j5kL9rBh%TTPOXA<~O*hsvRr>>lE3`-Aw z)@O2gV}gZDSk;L{0ae#XGudD9AywLTb@@P0wF*R;Wn+Hi(4__Mrq%$VT^v5zdNbrP za6^BA)JMIYWv*J@j^*gAj0@*!cXc@WqJH{JwRu}OK#{3c5$_i z{)}}4>jWR=1*v*vs{YtW)vLClvjsvgL*BP(K0(n0|Mjuk7O*9VghysFaxF1q#`$T< zZxO)G-bI1vocFGEpsXj2;sh1jF58V^>-L87M=-!Ikqbh$;(owccl-TEq|oW?QyG6y zl8VO2>aI$6j~tzSWCW$Pv(kiZhm-4H`$kyhnk-!EvGmML43=6kPbAa1(Ujr2MdrzS za(X%$PqDT`-u2LQF7YV&vfV1qJgJ+7J+lLqQoy2_y$EQaDy~O~j`CHuOuM&cwZY3Nj|SG` zx}{VekL=e|CjX5!NP<9RV35->Ccg3nYSsnTw~L}o-cn7)LxHAwsUE0}<{H6n05TZa z!rPMj$8`9ZI7hGM=MaB;(jb`csvG2CCvMN0VP&N~>tf+BUCkCPlpQkQ2#0^@m&lf0 z*x#i#a)arjzlh&vCY&->?5oyW8cGU;(6E!s{gbJzczc>DW&}^>FJvv9Oof}UN30?V z4?ki1!!`ksp|zNjY>WeRSzh)f%^o-^kQEAw!2rYg;m#?fF=9*n*n&=N5mvjO(90Gw zlSBei84;yPru59Rl+M9}EoFaVgSs)s6bK;Db+7qHAcm?7bk=9GZoVDl#@QX5g!)hM zvlVCO0-X{Z7utlu#}nq7LMrbPuT?XZGm@JwajWz!8ltslt)4N;F4&fmFfRmn;?P&; zh!z@P6!k#GTSuY^NwT=4S}mij9NDw~sXa0|ShF3#l+Vq|2_ll&&lAe|;65eFLd zj+0J&9XOR!a?0=eTm>1Z-)55byk0NSFLOY_iFXPbCp??;q*W0Wk|y_3TiA>ACt2Kl z0g5DgG^ZmK5G%o*cL0AJIUk~dvZ9Kxlba92-Ar2VMb61|9T6f(f#vUpQ#bnU0U>i$ zOA#|{)t(HJyASKlk)r-YQ12VT4BY9}1wyZTF@kZ44)4OSzLw78KqUojm44<_=~@-2 zS_X4?4X%$$^EsEuwnBR_OaKouH3qSlE|45<;S@g<^lp7>qv8yC7Ahrmj5%HEo=1*Jy|zK{_eTY&QsxS6q4!VB6@as%i#_ zkTwYb5e5PqA?hRxr6pJ~+8vy6N z(UCA@cH_}M&UzQ4HBy0^yOofI;R1%kBoR)eJz6b}=}jHyT{IeQyc(UJA=@eUFkxED zvPHHbZ<*nf=3yb)jmANBW&fKN-o8UA)}eoG30Vf zesZ9Z#gAH3@i{Y8cNEnd-vet-9U?B8yyb`$C^XqPUR~jT;er~zJMrK8h$@6!>eCgR zWpI;@W+fwETL@B8V>nwre`hjxIvfO9E@cWVAzhmG1w$Oe_W?D!Gb`4OiB;i)z^?lR zg5AZ7HQeYJLt^oE4ogPR{#=*`y{Zl^%_obCjO6=knpdIs7M$m=k%Be zj_!v+cf5LkNjWU9F6}$E&mif$PN-q+a57(=FDK8jRf0_b2Es&A7_f5*55a3x3w{mP zi>Hf=$#M@V=1amtd!D7d z>&XG{bBt6?iT`Mo>2VwsRZXiCh&`i|(}Go2Gi19!je!<>`S2C|$>#fmS8|R4bR33e zSh*p8-mE|qV9B>JMFAwbo-#5=VGPVWJimLlG&C}mG_Ub74mxNK1^-SnEwF2> z2SUyysPQN^X2kb+e%ugGjNU!FrDKUo4?L!yN}$4)uA72gp6WJr*vse0BFUQ`K40)Q z8hMlVv&2OX!SyY+t0Pl)=V)<>4VKELxb}vBAf3t5<{zqb6Yja!gv5BLf^1A39iL+h z>R-~aJ@y5(_BsR~Bc;I9ipb4Q!N;sF(j+pinbL}&ZFKTIZhvD@y4}Mw?JHBNJZ>qO zqgz%BSu(lPdF@9ot*%pIM0&bp!Lido&r!svflSnmq`_dFEQ^Y-2 z))VZ~9Ho)*Vz_<@njGp0uu?wCLyU)s>q#CF54-=4JCHobm;r-i)n5KT?J!*la7O7S&F1c3<&WOH+&?R%2sP^k)OMf=!EEK zsnXUrES#k8K6o_t`nzJM{=iqrNaaoK;6ztMfUMy}k0w8BQ=_+954|LTrTyZ*BviH4 zh-R#>dS*6;DT`0-gp8uzuF`KI2v&8a6Z}4QGlk=Us}U&6#p!4|2ZL8MrPPamMI_U} zQpW1sj4y~0mUvk2{b5`04}0|fu)TL<>Z_E!m+8+c!$cS7l1glN>&^x`N}xM}WD(;2 zpydA43B($s8`l!+s4H|P2%AwvdF!{V8C>LyxlX5C%EisJmLh|+h0P?AOGWE2dA-qj zB9!6&6^u?7N5cMPM$!UpR*aT^_@S-(kL8zkorE>kF2d3vyzes6CK+%-<3SmNU}hs0 z<@Xmft*W(8Z$(&=`M!yj!mNXcLA|e+`tGRy*ol8_*&WNs-EW$)o{20;fhxwFYU=muuYS?BUImT735##DuFJr>h4X{C1 z%MS18kUKWv$`Xf<3Xg+-rXnP4FDFZXSo~C^Ja7|O@-+vcYgu>jb$?bLo)5W+`8Z_fg2hTrRf>2JhH5=Do3dtYOX|GIr~qTCo&|c*&i~tMXQ)m;#h4#vj@eLe7p4WV-72#}-J#HbgTDjO51{vw50%8@ zT>(C-qM&8^Oghyj+9at>vq`;Ft65c=(Va4TO<8G?lb+n`IlsibqIi3@6v%<1Uil`k zoy%k#4m!gZ3JK%r<(&jPRLXRwnM{TDUN4xz)viy^*_iR?82;&P{SAgS*D*tLm-v z88Y%yX3|yyOaX3f$unOKtx{q$v|@eQiq=d}3gEegY%&rWBy#SB@q+{6&JQ6&Yx=4K zt-g5SP?)?-fGNPOXjS3)-0wbVgNck3s&m*{Sx&8nt+^e4v+$fE_pXLo0b5vdW>sA9 zg{Ez@*R%3f~SVn0+$T)7fIX5+lc$(l{#(5VJB3d{t2rqP;l=w!{+n(snV z>a^ju+c_$K?fKbblc?}YV}PXcM!WevZX6i;O~#FXwVaN5%{%u1H;5E>)%wSV_laTt zzvm<7HbJ!9+sQtoO@GD_YyOoR;zdpIl*$oe-!K_Yn#<;mgCB{enr{)}Epb#PKb3#W z1XX4OB^6(HuY95RtG3>+Zlm{Dc{neSL-0Tm0Oz!SfKqa4aC&Rs^q`}}AkyT;X40Dv zf=hU^u?NAc(-khc(fib&zc%e`S9e>pC~4F2d@{lPJD}cleuCRv)_OgQ3~HG5-W{mN zS&qXp6uR-S40`(y%XIu6hGn*>!1wL(@IG$Y@p%bvYVH^+d}0L3Pai}iKU&O;>J!6m zwPLz|Gq(o_dtaKud^QMoDEZ60A5WnyF}Vj(%j9wB?7%`)u+;L!mG9ONzv5#LF>}Li zV<4Q62f_v=_5RYL`w?$~=qxk-FNEov_Zw_f$DEvOVw4E+-b42Esu8yU!2~RfmWR@X zF>YIzJ6_naA}n9_VmMarGTF3)tF8`u;BNDOjr$vJ%j3(r>2oG`)K8TUSaY)tBKW>c!uKaF22Fy*i17fvPpt4E^rUFsc|n znm3cd%fv%biYkcpU)-^oddy5-LWG|KwCvDyEOhk_reZWj-t$f9Y;FxxR*UFdg1eu8 zfu`Kqu9(@<WY;fbQZh(@H%a?QpB_^{n)fXTmPJYEEh87FoDxLpc&HIV(SwD^CiznfECl9yM>L zqqNDt|NZaGR3h=Nt7L=V4(Bubd8zxL%_Ymf%IwZN z4SG!aNq#ncyps-lFJB?|eDe}VRac+9eD$i?Z9d%j!X(B=HVRix++9bL296p{uS4v} z;4&X%qi)M%q}fM>bKLMrlN?vzPG&RWU2^ZIwJN?tMIWKN{_M-zVotn&T};QYgJ>CQ zW?h`vE2MYo>$5sUE8m(Rrs8EpY6au${rTy- z%C-urCA6tI@~^ZOfHAGN$N3w3$iRN;uzW4;c`x6Z3ZvxVBN7Vtj^MG}UGxP0n#&R^ zupbmERE3yp4(@x9_*rXz18jt=M^~k5>BtKF=n@0N^Hn{#LBBa(w0=*E$nm9X4h(vikvC2SQ7~sq1W5a&JEqG8rs_N<G`jWto$sDHg4OC1|L2o8#<)<--VgGgSWWpoC7bg>F zNt{`Ls$88-j;F7gn#`$G>OwPh6%}c$5>vvSj3}4^O)Z=MTM(72J11o&h)D?hvEB_h z2saj>jKVQ3*@bET^=P(A+V7_H?id?EqmZU*i+FN_5haO|P6IBoDV_gfIPWxHLJTLD zlEMiod66+`G8)rbxFMUDo_&YY)7UyZB$BXmXSei)RaP=uV z89c?7{h>m~uB)N2VCI*>!89s!UIIM;An=@J*M@~fj-<%LR4T(F$M+fpUgbqnpg*(Q z*Ioeua+5mQApuvDT-nJ1*OMmND*+{wQrbWPSF@Aa3;_Wzv!L4-0s*FzxZN`WOOx!~ z%K>S#xZe5!0^jhnwBRBF0r8X9;yMC9w6hcA0rQj3==uS>lgjB=0aueE>Zk!8lgsL}8n@l2-#y-9G~EOK zV}AP{XctE{q90q|KKbF3nCl$@I+M2RMi@5-y9ZC6e{=Y^$1e_^?Cm~fbkYXZzDAQ2 z>^uSOlTqv_1rcR4`*xFl>_Y)zv%>8B0RbbEzwV_04U=W>gMSRJ(iObc$Dod1L*DTr zDb7A(ztDv5d@0bVeW#*hmqMo@M(OOyy?AmeIzL9H#YVzHl9jN%$YLp{%n}W%jr4KY zOG)pnKf|!osn`P!)E+Fp05Rm;2KOw8CS?k}>gXA6t4b_!GobZ)`8nd=5S&ARaWIiWL@;x$$v`3{`&*0}`68e*nmRc#iV-Yk_A9hS zKjr|*et)1UJvnr_DRlZ0TpYix)El_Eq1A zvIq?fZ#^V}gK5?D5$Ohlq*OCF&!u@!a!C@n=dT^3AtCk7!?dCknF=EPxKPq7F;##%mS_Wvq zN`L)$$s}s$^aMg3SyJ|<%CtC^KKxOjPKtC~M{1Ft3`Hq`qegUhQKy>dQ~$sn|AkIX zDx3L2+wjD%>p4R(Wt%=@Gd;wXgjO#MsHJ0Iz|P=Nzdub7{`oFq6wiNZUQC|jc8|;T z3qetN?=_e>hlkcES-nK#ued~t!MAX%hJR{Fc*IfiVmYkry%y2Zx7`*jB`h6bDn*kD zL90FCHGp5)R16d4w@`-aV2-e4h(O~5916$3@JgQZ25=hfDZr$wE7RsUjj0)|Pll8u zHj&6dOfwxdL&kSeRLU2Ci>WSk91a@nJmLxz+*3Y+k-wwQoAWd5C(707oNQn;{eJ^_ zRl?;exF-PJcTmTq1h#)`76cJWt=WH1w>m2*^+UxbjxHv^tmxe6TE8k z5sSgdvhcbtgIXO!B|)NLl9(~XDc1x;%nRFL@J%{2KHFqiyC|PBSI2Oop+MQhBSHE! zv#!2}x7Jq6jRADQP(rW;f!{Tkl_c5#V~U@^3nTWI}eGM`|DJRyr5EWrON`4Rck!GDpoCn)hQ zXx9%oWZ1%Thp!#`q%B)s`2X4a*5)>kBi--$6)-=nAp zuv93J07a}p01JQ;5v~9Gd7kdMUtYW*DO>W2l~^P&)6>(p>FMd|vD5Uj(6b-Kf@3@A zoSmGhoRpiMP61Wh|1F4m41ZDo5MHD1)PR?@chb@n`>{B5XKql?C`LJh4oHg^S zPp9#>A(!l2tU+_kU`R@ZDgP>5)(GIqF&Wr{xGbF!^MFeGPs)1YrVtQC{7l`94apt0 z71s?3|M>Bwe>`Ktj+H5;fmvwIe7``>lI@PJUkB&sqv04*jEbH~B!8>oevOyA5VM;-fe~*drWcLC&L#r> zqr`SK)6h749hCN)ozUtIVG>qnoe{N}3*Gn_`P1}YQC4|yv6`tSB4Xwhz=}KNKRP+9 z%Y3A-8%4i=42Tp(qNJc2YY23wRjbB}kP4=w}8E?IyWwyoU(Vm*+)vfEbh^R3S z#b~opvc$bX)PL}xc&^ngo?QVGIrT~q2*f8@ru!wzMLeY3q$Uj3{JZgFHNtTtO0!%{ zhKP0`0Yfr*<|yF}!Nc3mPU4o4At)Gm0Q?rd`XN_pLq*KV0VqU(4#N~F=np^%YL1>U zwVaPr=zk%GE^h9fkcJ(Nk=)c{ihT+W%o$=_GtnOZO}$7Cs1n)~CkO!HRu$zrK za)0koqyU@qhm=l*d~-Ka^->NfhVA(kYo$9@Qp2#cx7 z@=UdX1hU`B2DZQsdFI|T3#WL|LQ>{$m5&kSM?{v|I1VLN3MtL^+oxpoqcJ6a$ohN* zt7e7?vTu};$$9NVY~ERBtpGvW8#pc*V~C70lu5L+j5$lT7l%nbC@%t4NeN^lU4Jig zLbTz4ICpVMN;6I@F< zWAr2(X8zNpt)bCXKavfLT>*ECcfmoi6HY<< z9IOVoMXOgAl0HOElT(%l(xq5@DUC`;hP2Ll=g;rTi{#Va=84{QAmES_9_bu2gy%OrG+9 zD6%N4@p*PKgDBQ?c4szs%TEJrG8yu!q>Uh_6cHm8HjO9OoEdLrx)>qMrGJ{AC`w6+ zovN1E`WAG@u+8^xMc{cx*5c#?!O^9}%77E8bTP?jX8Q$1FZK~TND1{F^dqB+X(wsc zOk}+3#^?5|O&TgZzIMl7#cmjqi+U{~$oxW7r9f#;jl$=U3`S3aMD>x8DUF1AjPe|i zu7m=!?$H;N;!+%6(pa4_DSy8!SfXx6;z%fE6Wu~MK;Q*!1Les)L7Y4wKD_j`^-RrK zl(Ql_QlOQNp+p8w89v@q364%6oSxz-xx`K6x!#eb>?=vowGbF}fVc|=;(fXTe@l)V z=I&xaJUEpCTiE?Gj*e(f(3;1q3~^g%L&2M8CvGexYn2?_AcGh?N`D73STXAn4tD_{ zHpF(aB@JwjDA=B|9eFcD88N;xXv1X%IYoTQlO8mpNJm(uK?FNOx=xySNczzSR$q@N?@{kB4nR zm@wrJVe-clP<=G2S%08S+6V|GpQV3WL;mjpQXX{Bxvrkyv)l=#c7M8(S2?ru!>g&L z;T=`e3PiJFy7616rOtbax+|xHiwP%y^QJ8{QB(PsJ(?dGcMUwfK-JX|$pK2F@QB~e zFJ(4G`aLV75dgK)6Fv*4FKk+3T1R)8o=M0=m|$dAI-_y{41Z4?IChRuUDGoTZU^$k zron}%egM&86?ssT$os@|68fv7<>#iNm;=k=Dlq+xhjNbBtqq5LY9(jqm|<;#*Y0e1U#&bPE{ z`nNHJ1txk}?TnN+b)ngdOqMgA(JV!6oSj66TyTuQXn%j|D%2=~L5g_Bns)Ysys48G z50Mud^M*zSO*8o`Zxl$0Y3M%58#_1StBxI9M8^3qx;2FBw|I zy+mFWwQBa3vhJ~=Q0UYMnFQr@nV_84-5P#-GMOQLY_&H=D*yCkbok#F-~dx*52jM+ zCwXfu=pq9uoju1X5NspJ>TC3MhbLKoY@fo4sDE=$XUD;~Sbb(3B5h?Jqk1wWFRVa2 zy>uF&>!Nni{7K}*h!om*UUku`Em-+tMN$ki(h{+3aZQ@#hzDGb>21l7KL8-5nXY9}U;Ng^JEQZ|?W*_wJ>I zJB&g7%ogs#_`OST^B&zT@7nd&<}+`n$OrrcZ7y;3Smn`m^!imCgsTW#c>OA+l%@ce)4eJgHAaln zgc`|!?flL0M70#pf3~C?sV>c^M5CL6|N)~x=T?2KX+TKOSb2c03BN*B5v2gokzqD znD&Q{=|&y*&IZdTZ>LZpxr5f7!vh)~&3WnW4^-yu>6nKrLEty9cSZ$u1n#0kq2w9c zM4K9ZP%Bj?-+9lTe>%nhd{(iH4TQ@SZ(z%Ryd3je{%ojR#wMyBlfm(5f`2_8%G)6| z7Vx}~x=)uq9HWT;n;yj_aF+fdk;08V*LXa|>GZR~aD1`srYBXd(G0g-Y$HdIuzHqz zty^7uTbkUQIykSTbGP##j&gDc{s;lE@H|9u?`0Q7O-Fa;(96{4@=b9#-rYft@B|K; zM~T_Of#p5KDHUpDjcHTUQh!v3Op0Ij9?m9m%n-9Jc6`D5z#%o6;CSW-WC4@>=%{%4 zdOXEB{F}iTyqt`F=KIOP-~Sjfo@}*SCT{+dUH^+l@wWiEU2Qi=JRwIoq)gc&C0ZYU zXSEnim#{SFbamyA3H;&iPUm*)l7e^mXy;4!g=H(b%5QF!xJC6?h<|wfFg_oXUQSko z=T21QFAMUPNJ_TM()>xgP-<~}L{>KCox9l=`US5$1bDs*JZ#ISSSa|Z!zWabZSX1d zyAD2P2_%VP_6JKU@s0%=YPYAS!;v&|ZARp)B&}}VrVUeSCZp+VT#aL1adOO&_OmNgl!5tMf5Dq#?5TAIsZNhYt(&2%VFq{Ij`BODgzr1Hp(hn)W2>i$aWx z6MNXW4I<(lXiU#9O;%A$l-umVP~RWMRO-9-eeLp9UcJ)z8G#w)uoH<#Y?Qa9)Ghjn zrJ5pX3qCh>Qh!Q3Cr5*pO{uB@nyO=V5C5(1i}iXBmz4hD{=?@_p7rHT!2Un?UnXKp zNHsIeO|sk36oE0g$5Kr)WjnQ)U>u;e9gv3V4V8@k)y!7lU_@LAKDVeB%mKL)w7em% z96Wx!|E&LPckkfG!)tRT1;&t}+dO&KEF9) zr@-L-`<{68q%T(1%#8VZEBZ!*o=X}}e%`pe1qWOTrk9*B?( z+0C&ixDrN03@}rn;BVNephDS^fVLFv-a3+2uU^IS*r=JVq6yrRHfI&2;$~M`XdK_{ z03k9*xG=c)i3_wK*kBk*z!W(626AR`dS2w%Q=-5X&0#2U}eI|*GYI|Z9~C*mRJHgOV-1BmN%V1MwVlxQ;o^)5i(iUMZdM(={2Ma>{|v+uUn z(r&|H((WbJjF{UVXl`1%{M8NhHax!eMis8H#4nTu=-P=Ul`{(Wbu3nMInRM^P9$*N z!{1QPC8B#>sXWAFwu@14-jl@gHxJH}1qo9W#GR6W5iuU_`*@+0r3X@AWncbQOn;cQ zL5MXON$C~EG9Qm#<1LOiBk%*0T1p{7xd)?8W#?pus(2@?iif!7Kq8xBolB9;T&&Hq z8O7%~x%m21d2ZgyG#teAojHLVwS{c^EmxF#(J z3wmrj*x=1;Jw3)yp@W43!2oLIJdfDQ;hnxQWfzr}SO+UYb@hbt0<>h+DSxi{!BSNI ze$)EIL&$g@$>QkNC!DI8Rk^}JZ=``dreOTRp8q@+U@KVLYFz)jrzvxcZ=47_?ZPJ}$vr6LpZL5pvmOk|yYqrp3 zRaa;};$iacyE|}MkeH!QAAjA#&Be6f1v~S{Ehqgb+O(wy0qNk)VrWm`s02QW$)e_U zk{^f{k1Uzq!0W~Zd5YbKX1eA(aY%*tmWpr4P>1Kt$#-Tz%>44d;n>M<^V!?(oNhpn)qx7za8`0!A5U zk@7(Az6s+$l!j0#zm6BQXg9m@ES=@yKx|{bPPx^V$HcCH~_&S!LpE3+fCcMaeJ| z^7&}6yjV!=mN@{2KYjmvJs-VY;N|W`?~(a(>3-`vObTX?@U$n;%%S}(K$kuJw`)hP z0NPIVI5c}W`b1kWNI3qMojLP~ViBNJuxsHq5k59|V$D6>k|3}@hZpY*&dijMSxYXDsF=lrp?Pvd$3#2URS$ zQG8JZZew@c;S+Y|@kLL(S6I%CGZHRLL4%6xsIyBqDhjIEGJ4o;I9Gxw+l`ta5wQRP zCr-g`2Q zTy=Nep26Ef?z`YX+i}15pV(S$>UKOqjZoLEED^-wHBfMFTlfs<=Jb1HC7OJD*BV+I2NPI^sIheo8_`dE57+i*R;HvH`2Y!u+)EW=F z?|;ap+3^Im0YDKiO~7G1JsZLE6a>!3L)={{opBJD@p|PS^-u8lxVkH$i3&ebo&2(L zibtUCKJZta*L8b(xeMA%K_bnh*r~T%w{E#Y@#kkKGsh>{alNi+0!tPn{j3nN>8D9} z5HS!M%gY_T!mtywm)op*+*ULJK~)t;~0aB;r#gFg*qt?75E8M zG1O>~5UuNEI?(ue6_l3oeLMliR(dNh94Bt*ntZyr_ZHXXxXFb~(PlXM{^d`>!sg^0K?~Ts~s5UYj^8gjPh0~uGsC+u?ybSWUf)udYT|b}Cbx42y*UqK< zD;3o)^;ClOP4H?{2-np~G@aJI)4JNpCw;k~hSDdyP)JhCS`JDx=H>NB$cyVRhzkJS ziRA4Bs>H7~xX5Ryb|s1Hh2XZQkAK4&1H~-$c-gWCip1eHiqY^HA|J5sU`+$~ z6C~#2+)&VXfrdv63+Z!1i3_L`2;0Bh+}>Xryj&OW3>vZsNnR=%Po{e5_&XF(fAJ9H zWW8_B!DXu~DHDOCV;n5aODjQUmB#ppF^z>F4qCFypO5!yR;PL2N7u}H^k$SoLDQSWt1b-faV|>jQJ(-~Dkv+TWr))~B73r3>0dH!@Uqy@!WkQod zu|=>f62e%DIWm6=ohf}u=a-evHT_c9fG!ORI_4VG^(<{t&^6aYtc*%sDSpj%Tgnd# zLLf6vW#RspxXoGe*m2;9879ks;eEpC#Dg_T|F5-L2(`r47Lt3p6@SinFL7Bjt>%|} zIR9GgHQ$dWyeBq7hu%<@uM&a1rtkor%Z3RJ7R2kt(fwDqaK^Z?*}Yc?CVRJmldwPW z7>S^l;HOOlHcDG0#+&f1)v&Wx87NK!P|}GM2BIgPEHN@p)zqdG-bQw)B_EFL5SzBL z!?rPB3$9R!x20xRlz*LrrjhehX6Mqj;Vas~PeuYPyvo8+? z=~7tDOCCE*J0pblcV%rlD-OpWg`9d)ao>hzFvgz%9U4Z&1eBAo_Gr+g#C=<%5hJBD z%=iHC*=I3t0zUdL0+GuE?J^Q99O!6lA)PZRgr@b%`oX|GcOxjec5R04zbIVnEzLf< zW*v0~k`7Nl%YTTGeIHv0BL(TS*hgut_d#Bo7YBDyD8jvwoh|f{6_D;_r#7I8N3)3; z>xdahI@6dTim)Bv2bOw?RPe02VGr~YmI<1r$FMeNU^fgnP7yV56vWPpl z3@J6u(piu>_B-$hVd%>ppYi6!auX#2;pz3y2fvKIlYd(=->xk--JNy1+lkf4t*tRS z>moXvw4?<(m(A!H2yv!WlQtA*-HHd?x6yoPxK9<_5+Sll_QPZwNFLh$4G)TP7@H6W zyi5<5!xL)*rJEhZ*$i6C-+5D_piLVPAWTD6znhSg$4%u?+0*_ID-_mx&Gd5_($sZI zh+>=bUw<>Gi@*26i&)cV1Qu-)ES2o(s2s-ngHhyN3j%Q3?Qht9=0xGpfyD4n{={M* z|Fyl;U862*e!-^%%tysdT?DQ18c$bbO9H`x(~sxI#iT^5VdrmV39CnZEr@90BIWE$ zZQ8XIv$b7g>{Lu8&8A#Njc3EH*|I2Uj$bALVhS1uQu(>VwA$Dy*VimOc8lE_1p zVqeT+$0A*_GIE+uo`eBMDK<1tVpZX`*Io6vMOLnOv$!Us#)|E5X!O$s2iKy4LzCP$ z;$Vym2l4vRB=TJT#nL^R;eGTl1{8ghGKh1H8Z}N+=w;IK^o}$=Z(ji7^`F6a*L-H||QZjP<6BG)hOO_W#=C>j)6}o|4 zOpnfqQ|cI!f_%;oG}((kW=K5-EgZe2yASPEz2l(sTVHK{o6&S9w#fuHQl@&Qd8PS@ zJY0!|SD#`-&&quh?A7@|Sq;y{?5!lf?|&~AsO!3OFh!yYUgT4+Z_50r&v_gcD?Sdi zK1Z?<3ZL*9lFu*k$LH(M`Dn@KB+BQleDL-LE2`}p8LYO&T|4h0uOnM)q7nRxbJgmx z^qVe?k57$-Y3^Z_inUf69iHF-1WjCP#H{S^x~RpSXz?^S(p0}yTLhI+1p|}3nSc7U zu?-_u>jZTyT`?BY$fE9A19kg*4fVBlYS>LUlkV0_?iT z*`ivwP$up`r4+F_swqim-eR)wlTBrvvSDO!I|dF3HxCmJy7kI#inA7D7Lnehi;`e! zdYgbp5OU~ZsVYc-kwY)vHLkZ7Sbtg>U42rC^Mq;gY|IRb0kmt)KMQh18W0OvtSXe} z%~G!|dRxvv%?*>~O`p=#^H+K0_IQRe!zSfR?YcZx$*fa(v62a6QOeeHm@Bv_c+7G* zLsIn=DP}VylP^$69j0vL*8&`c9FNWhZ^rQ}w%*htXG~=n4@~LKOP`e@aDRqH%x)~` z;LmWgof;9|olN%h-jokDG|6&N6H?gzAq$KeqfJCH5Yjx4hu*))_2{R!+v44;liMF1H^(_!G_PR;&!H;d@B8*Lq-N0tWF9Eb|GJqb% zMlrfhy%C|{Q>$7aj}IpDw{rD2kT@ZqtOnbHp$_{glC*{kdRxhXtAs1{^3kSNVWhH= ziqQ?!jZ!Cv_C}iGIgk`wQLbHYNC1uSSl?*)olPbTV-+lS<%740gMUwI5`ZmO&BUY) ztaW(^C>|4mj^~#`e%Tf>*}W06kpPcs7}8$;#I4!mi}T~r!aY~}f=Lvak`l`;fTV?| z14$tyu^D74at%>UpnUbX_V$4n2CY7%V3c!VAtn7Bz&F%g!+tiDiIk+QKo)cC*W_|_9?aXgA9_#>9)Cv>Df^|IJ@U&ikYwO%8-*QSwg@kEcou1EfU@1fE}!man1I*N zC#Qf^yt9AR`x&IX36};pH00B8wWkevhIB&xp;gH=_c6 z^%^;W)mdqFOz}zEO4p{NpiubSC z)lI}(j9&l7UmS6xREl*3>q!-+0AOA$_A@T7Loxje*NQbZM|)d&$(SbFkq5N z9yzx3`Y#?Zx9F8$;@O!$1hC!$joe#zP+FkzvI&h=aWprYMo|4mt`u}*WA5|~g&M-G zY?+d8M}GpvJ4sFH$S3wU+Fc0%9V>CikhUzmPCky`>?98MC&T4(8$8ZY(xQk5GWE#o zR%pbAgorf+elvWxp`C6y@WPx~j(_I!cP7059!OLo0T^_z_h3wN^{l=C0M{#)xGy zYJV(6iS+oz6sx*@OW8Ute0uG0HJY=oK(o7IMm~C%PT6LES&+LiMY>4Kv;L%Sig)(Z zdyHJnTb*B%mA=hfH0e4&^@^s1xfc^{scyMPRRif=sxK)p3NfZW0n&QfuWj~j$sfP^ z;5(NO(i1%b%ME!oefNg(S+~Ha4KuHnE`QCr7l;m=3cDaSHqxAPJ{vz|d47yaSnY{^ zhHd`yf$?l;A7h7HjA+qA-HYK95Q4Rk~&zuBF_R9GpgBkz3e(!;OGrzRie5gjeVE*0|8U1W<=#T;2Y>c# zsiubAoBL%a31 zN1(h>V}Gx0!*4)31w{FB7f}mn6XV^2MR7{Dze81F6chhDygO6kWPnR%pVn8fw7O&1 zG-A_G*k84hf^95qFcW~s|3oNS4MXKNlWJjU*Va%%i9`Yz!HyYBit~rUxqqgz`993W zvjAFHTJ+w4631zlW!-duBCxbost`=BhWRJIiKR8nxQ?Y&5Wlyj73TZ>*SczH*|3!c zE32&wXDp(plmsYP4|^5`CM~3S1@c`r zahS;9bX8tP(3X4{;o>|OSei7pHnm;tTj}y=y){p6d49^5bwQ@JeSd1a-06iR$|A4#% zzHNh;xcgX7^q(Se;E3EWEKA*y78&`6AWe2u9OtO9zLraxy1ajzVa? z@T{O(&;!0#%tEr*N6JyN@?DdtbdY2vO{iEh&kBA0?YFZy-hZO@2vOHK5ZfSzEsSJ) z18GIKopChedKWKFDl#32STczwgIO+OjHkFV7k_~7GhUmz5E|F+1Z@G0N+L>9|tQah59O2A<9d_A+%KgwR)zI zgOLta--fUCr3aC|LkHhSo-Q>{bFXx@{f@&pDfI_+6nN z54thhKu!s*ndG)<+nbCJ`|&`IggvYITP1S^@DsCKrhmD^h+F)vF~ZRaQ#IOPMEI>R zG8|84e+90OFGrK7vO@_S9W18d1Lf)pmo)2!l$&4{SU#Bsp3JFfMTqB1-dRA*`py8= zmxVf@pPBMe0@l1X)B*luBnh7d^foLIWsr0YlybM_U&Z%s=RvtSw-#*9y1D$w zmu@c8?tcxJ7;GEE!eJye){@fu(@S2iEr}HsPQJX>-BL3F0i-uezeV7`v?a~WY=fsM zGH+hE1348>)^Jjzg|$gPG8I>li|Yb>wv-A2EAF$Hq7-8OgoErs|1c09eTC1JEn>Ti z#bDh#oj}}2d@u-Cndu9oDX#*=@2r?FN+j1|-G5qQTAIfOQ!vOi0}M#e>SBTSzTI!>{-5vk!L!Ak{N z{(svAIt{~{UV=o_Yfw7krIwN zlu&nxDNbFs?3$N!T{J7+I)O#%+->WR8ZFuS&P_N6YPRaDRkkb=#!Rk25xgg1C%QW8 z#m|suYoElSBK54^OCoYt8A6uV_dA4JbbsIPFn%SD$En*MFO2yms)Bx&%%Rad4=J`P zRV6Yf=ny0NzHz5#cJ1x;HNMVP@JHiTW@Ojce;ZzM>gmm=U^WzzWzTg3Z1=l@Fx@{r zeZyN&STDuM1UE^j`j9DEhWdSf69S(f`@fWyzsuFCL*zqXy9#`^xL9R6ZF8;4j(hRTEzMZpNpC8XAaO3q70~N!BhU0ZRcpHbNtM)#Qd>0>zI8W4!U%ba*_OqKW)wp{w zOQl-z77VeF70BdAg0%74WfLctz5M}Roqt_g!fd`JUMm|cR(m77E7bjSpqLzlKS8_E zeD4A;1mk_7?t?#-uv%^M5sQ?fqK7-+KMs#|MvgpC3GV+<&zDqQCd!Gx?)1 zyokGnD}L*;w`=Czd$fD-*k_Jbdt;&Q?#$+c6Mc&9UhhAfn_>V_K(4>-oMcy-z~0FS zwP^S#AAI74RGz%W;_u$nDaFhg`f~iQQMWV_S$8sC;9-zMkHA=^ws)^zD-$wxp(wHoAYr1@3GMAn_EU+g^TUSA>%HBusiA1a>Fe?NjM# zB)Ev##QRcI+=UeTY9L2XrjJK>U{P`u5d zdRE5FI`&o~V(KNtv^wB5yf1H&P9Pv8Mx^O*i5RB!1y*2&aBW4N5iCiNU!!#6_%l)x zW^a4L(R?vt=IgM#W5dXuX=J+nu4>ZqH{?$7>&?iX1zTu#Ig5DleX8 z#fEQ6=+SUXQ1vVMl-hr7p&3cfMS5;-m4xIw+7ZLTMIiBI%8F930-Uz7YYGfY3|>!K)ro8d`mu<9cJldxlFs%|GNs!5>zYmm%X2x zPo+_^Dv%fj`WRl7W)#ym>6@=AvZzQJ4G8SL;5e!5Q}!SEV1IugA^$6~|2|BUYD8bQ zGgf#J=gQ8JOsY}E*l}*6>5zJD$pfk1JEMA|v5l463M41Pu-rxqT<&ftO0m{d&K?dr znSLw@%95}geutw_v1yLDk zDM6p4t(l|g;!%HUbLe9_0d~~=(}B-aHs4bA?qfXg`4(!k)nN}hY;({<`1C@}AG1izm=Kr+B~~M?b8ghXT|rD%V-g@Wz3pe#E~2Hpf1lzndCusNsg8e(fCL zVFK7V2^#!$2gS2jW1JDdReXX$Q7+4Wba&?rZT~ex(cdS|C{oP=3+g8@pR7}}@i z>{><$10c8u@Yl|p8J>Q?Th{OJl!L<`48wrEC(jP{A3xWFnVBWM~whRncCMqo>SdL{rJuD?HIG4RO`_A)WwUc6ZRDdOnv@{xeX% zMq%3hkQb%4{{UH#Dm{2E&v(Wqq)D3)S# zd0yf+6eOtBQQ8>Biv$=agTYH-ec0v^n}+&bi-J)6Ov#9uedlc> z!&?z2gd*}KgeuwcV2=?Sfy7gdg@P`)mu-I?zakW9-pnGawaW|CW(tHaxb@#^-V_RR zyL`ilnNS2nAqLQDw1#Bj4d5|?aHKE{g~ET_ZvWtgqUpkQxb&DprE_?Qu^#8no{KBijGX%eTZQq#XeH@{qM&KrHXT;QgEr@9sZ49B*RW`t*9rOnCIgWq% zyF1+B?A+>|&?Dv9tL+2diOz1K^Nn`ab`={QP3w)xqL1|fwu2^6zT9MU*-+;YkMdcw zsiu93v?b~t3qITOC-yJ&GsSe9S9WYaGkRe&P#=r?GNFp`7!3C!O&4PD3dd5s3UkEG zdmi#Zd1|EMXC87%b+3cBR5E|%`S`qe=_VPTzU>~5JWAPubpqCjo-?;3RoLWG zVsj#DWA#&iViTEZ$wEm>)wj~ufl$VyG-?>Oj-ZAq3E^ED#`R!JO6)XW^{%x#XBNog z;jNH=W+k2wxfGJ^J=ylf=p65lU6nfSdFU#pb_&JEQ5a#he|O90lGPi7{5lH%pz1? zFM0ASajP0-U4!ju>!M$qkmp?65!Zp_+HFzK!4u#H>&7NGMPK8zJ;pQCOJKOAhRb;p zlHMf1ktu2!b~}w_W*@eH-lc!S(rdja`g#3tcc1llpY8AVAO5g=cvy6&NGD<_GDNqm z$y0kBxM?!L54+#)|Il`b^U+{=u@EwFQAOG5=j-|C?P82HpWY+$C7((?IU7AZ!($>R z_`-hPbqE&BA19!2fPD`8XBlGI(|@}bj{=}T&o#IeUt@ab$@G=~6$yWS2KletZ(kaG zzOs0w2U~%BDjQ=dZ`5~G;ty6D5zENeZCH$R`O9Io6Fw(2E((|v54Rba%OIXXJU>pK zhF!R7AZ&1?gQh(v3=n>jqU7Ijh#Vy?O5T7~quniR;GfCm-=t{T8d5kwnyP)ZgFp+z8w{T7)ww zwRssjFsA5>J49%dp56%TCxEdZ+gT22u)gl2!!VKhR9wIw`iQ0Y@^ z6e!fO4X`!OMxC-QRN6n@2;#PsIU18H5WgzJBWb+J6A-oDO96p zO^=O?h1+)#G{L*H;!|mxkK5P+XZ%lUaJEFDKs+2j)S}7D zi{m?Up0`n@ajooR%?JT*+v`*IVEj0V-$CL5RFx6+nGx3f($s6~{F^E8#={zYs{t55zv0y6b^BJ0VMsFY>%UgfwdVyn)bq8-B1N#WmUgu}n zjNuS=V>O$MkUNgr0Ej#Cl@)23zHSEiWVUboSGFxn#K~l~gz?M26niYfi@Y+X=FArR zSnh*cUn>lj1qXbri=+c4azavsg`kru)!$49eobzjn|1GG+TI%d>(mu z+nI8_m#2lo(O})Vmr0qO9aa)klZ|#TttS=U4KRduGF))H2$cT7XC+uk?tEw(zKkpb z6h@JPt80b2k*~rfp{O@TM!X_xq*ND6WPUAJA zG6b9sb-UAT8cUPig8?N)zJWrNoXq}zgWKcD6z_PkV8TMy1&M9!5+aXlB~FqGr*(GT z{5OA8HhMD9EOE-fET`ZdvZb?}52h%ouwp`kv6WCybPQnzzlr=?%hf8GwmK z{Ge|S!tS+P&6}2S^^;@^mO2EHG)xcibMPdN(%~e`~R2y+r2(+>w1TvvR?t49u*?1!(%s76rMD+hGLlUD5vG z2B_zoT({HNpf+C;K`;wRa^J4pNMIls$Hd5T3wy&(|IJWKB#~pkXJIeIno!qGBQyJ^ z;4-ViT)#4ZJlSdm{-oK)_yo3iX-R+m(wbz*sG&MhX}NQR*e{k0sU$sTCGL4IO)^SY zLWAqm@I0W%Bz(HO1eHn%XY?qzw*iusE24iYU2ch$-Mx#&uUHa2mP8!hZ&QQXt)JBj z(>D=Zd0N=YyOB4QhAwq(i~}_8&E2pg)cpE=DnutdO_MGnewIv|L^RZ}!7_iDdeYBE zgCVa3S9X)NP*d(4b2asuG(bj2iUJq%(Kb0cL^%LjOrZI{7Xz+8xHa-dvrlSsA%_30 z*+C|sMUqu=KZ9DO4SR@5ny26PFHc5u##@&*L%fuKWxq>2N2{kE>cRA6axokYC28iW zAY(2hhBOfu%tXS)gUQnYggJkbmQ^MBh!m6EwP9yYDz-3tFwJqg8NL&&aBBFiy>#UE zdNPhCbtwm;6t-fiZi2I|cHz`wI%Rin=korJt#}hj?mYw&VuZ?m+s?WIAnpuk_bLET zF0zP$=#F@dD7w-XnF_2783C@oX7^U?SwVCY!J;s$a^q~y-XIAQB~gDxS#F+;5(VM5 zN-tWF2L%lgpyq_O9FMohx7k&Z@HjR+=MBzgb*H#HnRIuUIpB_Ji-n75cyx{e*=7mV zOiQ}fm>NC^%ydQy9423>SL~Kjp|--&>szc!E;&6 za*${&Dp|n~?X2Wen1Fwooc&(#BgAS&w3a+{;a|tN?G?*G@^n>VT@*I+QD6b(h33e> zV7;k61l`Wam;nGaPa4Pv50eJm*f~KtG!DzeqL`v*c_WRR*-0Vzh3BIfuT}BzR-z^w z$pFTb_K=yHj}>#6iY8If9EG)@VDfLTj02Y9);PS2#eult$83L>3Xhl(b5;Fabx1x&h^ge*z-UcYIz!k))iO|WylGqe)79(3y;%GY? z!qvkSCwD8@p8J2aqz#0uOMt)h+H_ZT%jGKt9siBUd%8qOu8>Zm7cO)`wsDaSenG2U z=7pw3qnGGR+4+E0>DXMhl%`0S$SzO1f>+p1vXaoIwehY@B^{n1lG-R}SI%H_qG}Q+ zg_{b^yFs~;VmF&I2*kr)_TzFVm*W_A(GSZVq@7nI(msDNh^D4~(Fzhzv(?!34}BQ@ z@JnFlZ$@Xh&xD;GEtkl8`pSG5zWb3QN%7_|$a;G{o?@qDQf$6s4a3q%-tXgYSur^6 zBHQb)f@6q=w&g-!7O!NdRl>*(Y1Yqh;&MIHwYcN57_YEIdD@8p zz(>?1aC?6mX}Q@Y_q{Tr7Ub+uDnpdi#SZWm&=c(o4i+MS^_dsn67uH>EurwPb%sj* z#6uko-pkDZrQ$|99{-0nO8OX(^0HQnD|+wDKy-P=2O z{C$7t8-Kh{BE)!=$EJG}64_85I&#LnN%)o03E#Y}c}Q09XQ!u#0D#YuOoH5nt~GgZ z*R3rlt@wlw-hU5fWoyOQIaSn)Bgux!YJL++Z0t}nzkJcTbH7XxwvPQPeqw((XePaz z21i+37$zagRmNihqiPH!~PyUgu32r~)UW>T{X-HA=r^>W6Axz_& z=2F)X_7p8QA&(x5CI$yVL-2(-wF~5{TR;n}C19OVIJQmli^^hz~i|b|=dgq$>Js%KZiare{OIb_Yi` zF!q-f#TV}2*bmny8=>f0DWGJ9u7E2&>T(n!$;YoFd9jih6DKP+XAMAcfMGa+>InC$ zK%IDgdaTCMS^hN!$dM;DLG28MgaiCr1}Xb9ON;9WPgN~cU+%iAAWVNx7{P5BO<%9h zcIqd_Kpj91?Pbgg7?t8iDAWx)W7Udbe|e-r_! z7!@2v!>FtaRzM)oplyigimBQh(3J_9YZi|0h%XyST`lP4Ya!$ls;y4&u@z;z!aCekqn~gnrKGh`3TA*xV zMo8=$earkeY(ac)L=X47oC_H|vzl?KC@{j($7IU402rxEyZ~)OSi4YumrxCq)k&tG z7b6}m2x=S;nusf4OBo6{4I&1ANwVK}(*)C;C*(8C^uejQ0XTn05M2zswF!vMuYyas z3*`7m4cK_9bh)b>%hnPz#>rrT0@O?^jCfNVtudgTnY;GR z=i+MvWf*mWp^^7wr&jE5l#6A)?FkAa%8@C(1&1#F1jZofkdwI}3}&E2DdMh4w?dNF z!`b=#Vg;(2w5@+2`2)FJxNvX3U~LZhea@rGc?IFL2{u+z3W}A_OQX8-#=_{jX6&oZmQO_ZH8>c8*7^DUcP!u;oQIVUT72 z24fyWKSW=N?C8HyeE`>I1)JqL2*ZLX?l$G|X!Uk9nkIi_>8#!&OK$jIh|%NdiwD*q z2~y{lxB-HMS|q=-dIF*=fIVKyt~I4>)5R3z2duEK3s@E|1*J_K11H;7T{Lo5xbdHF zcWF{UHjhy(j#OmRnT zg3cDzbiqMfBUUO75&Yy2;zV(gj;X`M_((IHWS)NkcEg_BA$W2M=4W9Ri^{LJ@cN{* z%ZVl*2LNx&2X$CQ{vrH>^gU<%y2v{^4qy)8TpZUyQtU*Xq~IlFp*%)H1ilm$jN#Nl zAnCo!29hMAP9enI0Xz;Ok~rtDnvN(q6Fq(A$1ugg`xduNGE>?=}MS#yb&8L&Tx0(1BDn^6IjB8LMdlY zX8d^Ot!L8OuJUf#H>DX*E=k?Ey85%3m7RN)~Jza9$SCT znM%fDuk+)QHQr7qv)KY3+*~SAspY4Ch~*g-+VJWTJUjgkpJ+X;@f2xBOH{KMO;0Fp zgOkN!v6$f7m>bordK}D< zz&g#SlY@MS0J_<47ue3;xoio{32J|Mi4<=!jZ04B>l>N{Ub&5CAxlKH+==6w)xj!d zJflWa+!vLRG8e$ruLm%a?JHg+TVepxrK1wyP1g#}fM$W!AYY(!0`3ThFvx#8EFu)o zGz9dr1W1xIw*(}fKna+N(Ds=9L&9w(h(;W?14&6&a!2M~iFsRys#9S4&sT=X!RKWX zQgSO$Um7ScA4~wjbvZAbWqqvEU3nM1X-WJQYlBwnFz&nsJI!P7zY!avk6lQ@44p z@TvCTv%4!Vev+lBQDZPC-+YUAwAeS%GRN;NlvV_UIGC+#?hBYNOZZ!5WfKf;TH5Vv z_UtO-!2kn^TU{)s<(&f*0CAn+W7&>(lL;C#0x-^>!kYJQ|CV`xM2vqw#m&ivA@c0+ z8y~`%o%cHvZ;Rq_>RVoN(A;!l)Wa}TiCs{uhIPzC+NeI^i$FFB7t-WkG>Re6x`bVP zHZnW;dc(;99lNEwHgvex`#(tyQ)yV=B}$+F$WcmatrM4Hyse0`v4avOY2kF+Ub0v2 zFehh2S4%0It_%RBiBx|xwzK9&D=~dPxi(MWq65Zu-99~i`;k9=`vc#b-RkXI_Soj} zTN#0-*}Q(s_n&a|{+gFvaCv?;z$>)eE%FUq9%P&%>J=UZaLdTgr_ho#_8%_=C}qX% zBa+HbR&c z7X-G+kY0cH@xdc~JNMDSzsxOrGimuD~ z;PN>#4ky>gLMeY}UtQ%CmOV?1-lN@v$6w;m5~b?FiNYMTx8xr~MrOb84pU56aanN) z!uwQ+$jgyh_ZF{z*SHx#yQAwo5}F^(v3res#G6wJT~NGCN*{R%a&Nm1IHfk>D7qc~;_VyhT|#OqGTb@P9Z>WL9B?oZ0N7_$@=>;RsP z;5@zj&c1CFZgomLLwF3G^fY;WN1|f*V2YCLv>%L#(b%aNLuE|`S~(QWY!t1;dT(}) zdP6W0LTz^l*c-~{CEFky5&0IikI_*=VbId9fdzrb&QIYY0H08VvJgO!p%ns-0c@|0 z5I_d4tt)?a|6ilUOde0*+-7q;Vlb<5Zwp7rs2NFl)s6-A5Z1`!T~S|C7a9P zAs0G3Qo<@}(e=0#C~kDc+lDmV#_qGy(cu2aBAkExnM<_D;^>3Pdro$RR?xS(`cIKf zz#Q!i@$S71nK-wB)Ifn9t=*O_mr7fE&ZUueW}h)7V!Z4z+aR_E#YjA{ahayoMBD^l zzp~llRT#{!eS&DP6h7NO+<$(ncoLi2_06c*$*ExM#)+a`%-$}#El}esUB=8vxI^bk zQk#Du2L^kMDOqFcXF_T8$pc807>kb~6;$@gF~z8dK-V%2ZIqtEAR6)#NC{8M3|D*C zNRG@P!?nijpcIYi$j|wc%K<+nIZ)0?#UF%7NORz)>BVGHMl*jgfgGkGxRFdM2AO~=%qn%54-AA zYswrR4r+7Z0X&&<6ZC<-gL7$!B~Ibscxm41U|OFP_|_S?S9^Mw1=~rg(HMWN z8(^)G8IraOI}V;#>1sExax}w`YGH#9aUNi=WBc+Wb3Wkz*eDYzA;tXEc<@KMJ_mV(ncC%>vGcY1@turuxs6~{khgzcl>wDdMP*#7$ZOyx>ndO&e z+;n$$NRT@-RPfTmD))L1{#>wkNr&qn>+~nkX9hr#a|*R?Y2spkoJ0-Ic>1t;7jppH zY+jokw%m;t$c>(}5Gb5fVFwyr3JD*XH%Y1f+4-=ZPr>Xa%S}RuI2Q~L%;?p&RIRx3 zbI*q6yooWHlp3&+G1-3^Ro0CJiCN_aJJc&z%_BAqh3ORJGas!XD|G{SM=-xY5qS@BA~qPZF%(nT>%Y9$|K~o! zTkCrblOlwCVjiw$2ELR@mVA!9uaOv{6;Ex0;F3CCdDr(!b2fieX(zKvn7JW}DUZLD zqSK-@hCr7F{Bno}C_vBbqp1ycx(wq^5Fn*|MvsX;eF)cCt4e92S4Vxd>OV3~!iNAJ`o`4xnU zva7g{mxo-eN<)8968uo%GND~-t3oKxo;t*K_(=wC`u-f6C6AoKC$7uf!OEl?b8SI08)yIrVazPPn_FLG(o$Xl@ za3&9YpI_!Gi=!Q$s6wkMlXK>^f(QnuSuQ_$qga1)7aWK zDpMn}0yWyZLD9N&tIaF7p4H;y;4v$~VdpYpG^26=N2VpmUq#mKrf0(W`a#Q)fV$z} zt&@m9{uw;gC8PQ8aSop@wf3C6fM6>*rj<`7mI++)eM##JU~X90HpHMs7Mo8B3OL4E zv%y3os|kM>WN0);Ov(1Hsj+q?oi@u{**_pJ-LkP2DwgX+##TS{_>>SySA*Z!X0;HZ z_V$W&b7vw9UMFcGC{Xm|AXW=13HaV38eGfF`S2n3hj{#(aG+96RX17owU zLaG3gBT2jg8r)ZpVcWzUUgN)y%1!aNNX@Bc;}B1~^R&c**^HTEsbZ=iAyLzH$u_Qq zuCgg_71~i5$p_CjE8d?9G&vkM&*7US zH=ZNnsUtQS`syj)%`|7CJHFMM@;()uxyCbWBxwjQc5x#uf}N<^2BRQGl~?2<9gBYq zmCxNkWZo$^BlYf&s|hDrpXNG5BmZy7Hu84LW=x=tR(w_6W)4YyQRcguL?n0{?)tp# z@S9`~iFLrn=X-Z`Nvr1}jcCAqWJ7+;@03P#KRC-TXCwvIz)O9rRGe&Cr=8$8DtOIqK3JXob*I<6>ptqOmOGuh-~5TX=<-m|U5;^>XQ;ln%}|j$YF>XBVQN_( zQAC&54!Z<1m-@1|5$FIj>C};~yoN1K95~heXG8Ym8ip z=Gz-GOuz3lA_&C)rLczn1ANUW6@h|Se~~#lTK?rvfl|3o?PNF)VSoZnnl5cK3LBd~ zoLu0JGzyhzX@j7-dOKlz_Hlod?uI?L$oz>%B&MC$i`m5-b^7m%YV&AT&4YqJQ7IXJB|fgZzRj#jJLrd6}-;!0%Y-yAck>fqL^qV7K{j@ zCI88>XNy66%7nJrex!eff#0137Tr<@xoFfaxxdd!);8?$WoJ1{dT)D@()&upQ z@*X9)MRH}lr$~8GH@g`wIhJvPy1kcxFK(MB`uZo4V(PXQh5=n!B6IMCXWFF`;PlJ!)^xX;US!i!q1+x&eXi3o6Ahx2UH+yIv zuUtYsU%uI0%T475<6{gmytjV@O}a@jZZ!Y-I&_@_d!y)y^+9vPfclJ z2P=5UwUG#elK+z1V(C}4!JZYCRv1DlUdRpRfeL>fg_Z}GN5d{^XyS;2pCLH0xELjZ z(rR8TXyu8D62_O}8IT%R zaM^$6!(i~0lFygCx)r{}DWZu~BHhiHJ&nq%wK9^bQ&1;5^0tkM8@wy-!FMk2@8A*b z^6T6?YknEyRcU$o04)VK@#;}ht32GA?P7>o!$gNDD>`d$S)_ zvc!zC!xE};2nXz|klI&Gk}n#`NAtkdg zA?d;%XGMO(+?;Wh+=Lu^oqrC}y99W?&_c}Rh^|1_elMp2crb$-$M`coKH?7X@Rfg7 zWm`TQ4Tj7tuUy%<8i!)hZYMh<&1J2Tl)irnNh)ygEGyVhd|sJEA_$>R(7ptcnq#Eo zNaw%QEsC<}RnCHVzU<$ypc>G*9OM)TB|r$UY3O#OZc?~Nj!V=bC9n3RP@{h(9`VbE-`q{#rLe>F_0K?NyO6$u zAyzRuIUAk)a)?7wEr#n7>*V6zX`e1hqQ0i65m2$+0(sR`l&E-RZ#6TaVTpzNM=o}~JuU@`6P@Jv;qxukyv`N$?VFu#BgQ}aV69`r^7_USgRf!*4*u zFL6ffUxkh(?h83GUW|Y{i?~c@o#DlNf*cIIA$`lHY$#p$*JyBZW=DVTb)GAH5Ddi8 zjE3>)c$7TE{ROB2Y)1G8*273?o~4oEWiutrT#sJ;>Mb`1b~NBj-=2+u*xM2BqAUg{ z$|i$0D3H9x=Sz!PtN8U`y8h-@63c!flk;Tt)O17v4>FvM=9=^l;=CKMEg%txO0kNQ zI4X*Db*tocg@#FOOF@4jt)(kfT~V1hoW__7ai2^1O)T(!3v5CP;240kIu z50)#=ps{|NOWiIVLlI8NfR#S8_SO$8%QtRd$3`(x)sRE50V_E)=v}oC<>qr&>u`rR z62Qvb)3XhqIyc;VddZYXCfamIVE`0wVzaMuX_;cXZ1#$#vju;iS|9&wG<*?sj#gPG zAfCGwb8fhnT6N(H-4r+2KS%4XL$-`K#K%*zzyp6H*d^?)WRLiw?KPj^jGpl<7#uf*H#DNZ1#OO}V72N}LPsS_Qc>74 zm~{juv|(F;k-*mQWd=+GUh?1WZ8O$wwU_-(!rRhL$(VS1zN(?t#o(Klo-I9n{xU*5 z(dFb%1Lsg<4?J7;B()g>l0Y6vDCe;31zo_f;4cMWJL7*lKWFLrDcyiieSt0?c8 z=++tLzF+%fgIy~>9F0Pv2J-!8mwQBI$X2=KOVyJ!@f!9^GS`FL^0v^!%<>BKY=044 zRmi?GndOH(Tl&=;ByVV>7m;g?bi4AtbJRV#!u0df_JE;+AZz?X$WYJIOpfue<{WZd z+V}_2Ugv+m!5YNb5;u@H5(gMOfrG@3Pl*TgJQ~92nUnLOCmz6n2K@b$cd#vgKlHqV zn7_5FBQPg^J6bZL-0W`-HSjbj*cAb4rVlj?{0<;+9LWs+aP&944Yn(XWyW=m?pol4 z0|i)c#^~Kq?W?^R4666V$t3!&D}BwuoUD+TlA3?xXmA($5JwuY!^zG)|WiAgj^_mTD3F&DvTgY<#~ z?T34o~Jc{⁡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®l%%S4ka(B^xNSF}CuFSu> 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�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 Yo