From 5e32947e26d34fc6f86e2ac9b4baba6de10defb1 Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Wed, 13 Aug 2014 15:55:50 -0700 Subject: [PATCH] Release version 0.24.0 --- bower.json | 2 +- package.json | 2 +- plottable.d.ts | 2147 ++++++++++++++++++++++++++++----- plottable.js | 3017 +++++++++++++++++++++++++++++++++++++++------- plottable.min.js | 8 +- plottable.zip | Bin 120491 -> 125003 bytes 6 files changed, 4411 insertions(+), 765 deletions(-) diff --git a/bower.json b/bower.json index 12e7877f98..df937e9add 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "plottable", "description": "A library for creating charts out of D3", - "version": "0.23.2", + "version": "0.24.0", "main": ["plottable.js", "plottable.css"], "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index bbcdea5e53..ac01b42cbd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plottable.js", - "version": "0.23.2", + "version": "0.24.0", "description": "Build flexible, performant, interactive charts using D3", "repository": { "type": "git", diff --git a/plottable.d.ts b/plottable.d.ts index c8c4a0340f..37c3c56ae8 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2,18 +2,80 @@ declare module Plottable { module Util { module Methods { + /** + * Checks if x is between a and b. + * + * @param {number} x The value to test if in range + * @param {number} a The beginning of the (inclusive) range + * @param {number} b The ending of the (inclusive) range + * @return {boolean} Whether x is in [a, b] + */ function inRange(x: number, a: number, b: number): boolean; + /** Print a warning message to the console, if it is available. + * + * @param {string} The warnings to print + */ function warn(warning: string): void; + /** + * Takes two arrays of numbers and adds them together + * + * @param {number[]} alist The first array of numbers + * @param {number[]} blist The second array of numbers + * @return {number[]} An array of numbers where x[i] = alist[i] + blist[i] + */ function addArrays(alist: number[], blist: number[]): number[]; + /** + * Takes two sets and returns the intersection + * + * @param {D3.Set} set1 The first set + * @param {D3.Set} set2 The second set + * @return {D3.Set} A set that contains elements that appear in both set1 and set2 + */ function intersection(set1: D3.Set, set2: D3.Set): D3.Set; + /** + * Take an accessor object (may be a string to be made into a key, or a value, or a color code) + * and "activate" it by turning it into a function in (datum, index, metadata) + */ function _accessorize(accessor: any): IAccessor; + /** + * Takes two sets and returns the union + * + * @param{D3.Set} set1 The first set + * @param{D3.Set} set2 The second set + * @return{D3.Set} A set that contains elements that appear in either set1 or set2 + */ function union(set1: D3.Set, set2: D3.Set): D3.Set; - function _applyAccessor(accessor: IAccessor, plot: Plottable.Abstract.Plot): (d: any, i: number) => any; + /** + * Take an accessor object, activate it, and partially apply it to a Plot's datasource's metadata + */ + function _applyAccessor(accessor: IAccessor, plot: Abstract.Plot): (d: any, i: number) => any; function uniq(strings: string[]): string[]; function uniqNumbers(a: number[]): number[]; + /** + * Creates an array of length `count`, filled with value or (if value is a function), value() + * + * @param {any} value The value to fill the array with, or, if a function, a generator for values + * @param {number} count The length of the array to generate + * @return {any[]} + */ function createFilledArray(value: any, count: number): any[]; + /** + * @param {T[][]} a The 2D array that will have its elements joined together. + * @return {T[]} Every array in a, concatenated together in the order they appear. + */ function flatten(a: T[][]): T[]; + /** + * Check if two arrays are equal by strict equality. + */ function arrayEq(a: T[], b: T[]): boolean; + /** + * @param {any} a Object to check against b for equality. + * @param {any} b Object to check against a for equality. + * + * @returns {boolean} whether or not two objects share the same keys, and + * values associated with those keys. Values will be compared + * with ===. + */ function objEq(a: any, b: any): boolean; } } @@ -23,6 +85,42 @@ declare module Plottable { declare module Plottable { module Util { module OpenSource { + /** + * Returns the sortedIndex for inserting a value into an array. + * Takes a number and an array of numbers OR an array of objects and an accessor that returns a number. + * @param {number} value: The numerical value to insert + * @param {any[]} arr: Array to find insertion index, can be number[] or any[] (if accessor provided) + * @param {IAccessor} accessor: If provided, this function is called on members of arr to determine insertion index + * @returns {number} The insertion index. + * The behavior is undefined for arrays that are unsorted + * If there are multiple valid insertion indices that maintain sorted order (e.g. addign 1 to [1,1,1,1,1]) then + * the behavior must satisfy that the array is sorted post-insertion, but is otherwise unspecified. + * This is a modified version of Underscore.js's implementation of sortedIndex. + * Underscore.js is released under the MIT License: + * Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative + * Reporters & Editors + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ function sortedIndex(val: number, arr: number[]): number; function sortedIndex(val: number, arr: any[], accessor: IAccessor): number; } @@ -33,9 +131,9 @@ declare module Plottable { declare module Plottable { module Util { class IDCounter { - increment(id: any): number; - decrement(id: any): number; - get(id: any): number; + public increment(id: any): number; + public decrement(id: any): number; + public get(id: any): number; } } } @@ -43,14 +141,63 @@ declare module Plottable { declare module Plottable { module Util { + /** + * An associative array that can be keyed by anything (inc objects). + * Uses pointer equality checks which is why this works. + * This power has a price: everything is linear time since it is actually backed by an array... + */ class StrictEqualityAssociativeArray { - set(key: any, value: any): boolean; - get(key: any): any; - has(key: any): boolean; - values(): any[]; - keys(): any[]; - map(cb: (key?: any, val?: any, index?: number) => any): any[]; - delete(key: any): boolean; + /** + * Set a new key/value pair in the store. + * + * @param {any} key Key to set in the store + * @param {any} value Value to set in the store + * @return {boolean} True if key already in store, false otherwise + */ + public set(key: any, value: any): boolean; + /** + * Get a value from the store, given a key. + * + * @param {any} key Key associated with value to retrieve + * @return {any} Value if found, undefined otherwise + */ + public get(key: any): any; + /** + * Test whether store has a value associated with given key. + * + * Will return true if there is a key/value entry, + * even if the value is explicitly `undefined`. + * + * @param {any} key Key to test for presence of an entry + * @return {boolean} Whether there was a matching entry for that key + */ + public has(key: any): boolean; + /** + * Return an array of the values in the key-value store + * + * @return {any[]} The values in the store + */ + public values(): any[]; + /** + * Return an array of keys in the key-value store + * + * @return {any[]} The keys in the store + */ + public keys(): any[]; + /** + * Execute a callback for each entry in the array. + * + * @param {(key: any, val?: any, index?: number) => any} callback The callback to eecute + * @return {any[]} The results of mapping the callback over the entries + */ + public map(cb: (key?: any, val?: any, index?: number) => any): any[]; + /** + * Delete a key from the key-value store. Return whether the key was present. + * + * @param {any} The key to remove + * @return {boolean} Whether a matching entry was found and removed + */ + public delete(key: any): boolean; } } } @@ -59,9 +206,36 @@ declare module Plottable { declare module Plottable { module Util { class Cache { + /** + * @constructor + * + * @param {string} compute The function whose results will be cached. + * @param {string} [canonicalKey] If present, when clear() is called, + * this key will be re-computed. If its result hasn't been changed, + * the cache will not be cleared. + * @param {(v: T, w: T) => boolean} [valueEq] + * Used to determine if the value of canonicalKey has changed. + * If omitted, defaults to === comparision. + */ constructor(compute: (k: string) => T, canonicalKey?: string, valueEq?: (v: T, w: T) => boolean); - get(k: string): T; - clear(): Cache; + /** + * Attempt to look up k in the cache, computing the result if it isn't + * found. + * + * @param {string} k The key to look up in the cache. + * @return {T} The value associated with k; the result of compute(k). + */ + public get(k: string): T; + /** + * Reset the cache empty. + * + * If canonicalKey was provided at construction, compute(canonicalKey) + * will be re-run. If the result matches what is already in the cache, + * it will not clear the cache. + * + * @return {Cache} The calling Cache. + */ + public clear(): Cache; } } } @@ -77,15 +251,62 @@ declare module Plottable { interface TextMeasurer { (s: string): Dimensions; } + /** + * Returns a quasi-pure function of typesignature (t: string) => Dimensions which measures height and width of text + * + * @param {D3.Selection} selection: The selection in which text will be drawn and measured + * @returns {Dimensions} width and height of the text + */ function getTextMeasure(selection: D3.Selection): TextMeasurer; + /** + * This class will measure text by measuring each character individually, + * then adding up the dimensions. It will also cache the dimensions of each + * letter. + */ class CachingCharacterMeasurer { - measure: TextMeasurer; + /** + * @param {string} s The string to be measured. + * @return {Dimensions} The width and height of the measured text. + */ + public measure: TextMeasurer; + /** + * @param {D3.Selection} g The element that will have text inserted into + * it in order to measure text. The styles present for text in + * this element will to the text being measured. + */ constructor(g: D3.Selection); - clear(): CachingCharacterMeasurer; + /** + * Clear the cache, if it seems that the text has changed size. + */ + public clear(): CachingCharacterMeasurer; } + /** + * Gets a truncated version of a sting that fits in the available space, given the element in which to draw the text + * + * @param {string} text: The string to be truncated + * @param {number} availableWidth: The available width, in pixels + * @param {D3.Selection} element: The text element used to measure the text + * @returns {string} text - the shortened text + */ function getTruncatedText(text: string, availableWidth: number, measurer: TextMeasurer): string; + /** + * Gets the height of a text element, as rendered. + * + * @param {D3.Selection} textElement + * @return {number} The height of the text element, in pixels. + */ function getTextHeight(selection: D3.Selection): number; + /** + * Gets the width of a text element, as rendered. + * + * @param {D3.Selection} textElement + * @return {number} The width of the text element, in pixels. + */ function getTextWidth(textElement: D3.Selection, text: string): number; + /** + * Takes a line, a width to fit it in, and a text measurer. Will attempt to add ellipses to the end of the line, + * shortening the line as required to ensure that it fits within width. + */ function _addEllipsesToLine(line: string, width: number, measureText: TextMeasurer): string; function writeLineHorizontally(line: string, g: D3.Selection, width: number, height: number, xAlign?: string, yAlign?: string): { width: number; @@ -113,6 +334,12 @@ declare module Plottable { xAlign: string; yAlign: string; } + /** + * @param {write} [IWriteOptions] If supplied, the text will be written + * To the given g. Will align the text vertically if it seems like + * that is appropriate. + * Returns an IWriteTextResult with info on whether the text fit, and how much width/height was used. + */ function writeText(text: string, width: number, height: number, tm: TextMeasurer, horizontally?: boolean, write?: IWriteOptions): IWriteTextResult; } } @@ -127,7 +354,16 @@ declare module Plottable { lines: string[]; textFits: boolean; } + /** + * Takes a block of text, a width and height to fit it in, and a 2-d text measurement function. + * Wraps words and fits as much of the text as possible into the given width and height. + */ function breakTextToFitRect(text: string, width: number, height: number, measureText: Text.TextMeasurer): IWrappedText; + /** + * Determines if it is possible to fit a given text within width without breaking any of the words. + * Simple algorithm, split the text up into tokens, and make sure that the widest token doesn't exceed + * allowed width. + */ function canWrapWithoutBreakingWords(text: string, width: number, widthMeasure: (s: string) => number): boolean; } } @@ -136,6 +372,11 @@ declare module Plottable { declare module Plottable { module Util { module DOM { + /** + * Gets the bounding box of an element. + * @param {D3.Selection} element + * @returns {SVGRed} The bounding box. + */ function getBBox(element: D3.Selection): SVGRect; var POLYFILL_TIMEOUT_MSEC: number; function requestAnimationFramePolyfill(fn: () => any): void; @@ -156,13 +397,76 @@ declare module Plottable { } var MILLISECONDS_IN_ONE_DAY: number; class Formatters { + /** + * Creates a formatter for currency values. + * + * @param {number} [precision] The number of decimal places to show (default 2). + * @param {string} [symbol] The currency symbol to use (default "$"). + * @param {boolean} [prefix] Whether to prepend or append the currency symbol (default true). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter for currency values. + */ static currency(precision?: number, symbol?: string, prefix?: boolean, onlyShowUnchanged?: boolean): (d: any) => string; + /** + * Creates a formatter that displays exactly [precision] decimal places. + * + * @param {number} [precision] The number of decimal places to show (default 3). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter that displays exactly [precision] decimal places. + */ static fixed(precision?: number, onlyShowUnchanged?: boolean): (d: any) => string; + /** + * Creates a formatter that formats numbers to show no more than + * [precision] decimal places. All other values are stringified. + * + * @param {number} [precision] The number of decimal places to show (default 3). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter for general values. + */ static general(precision?: number, onlyShowUnchanged?: boolean): (d: any) => string; + /** + * Creates a formatter that stringifies its input. + * + * @returns {Formatter} A formatter that stringifies its input. + */ static identity(): (d: any) => string; + /** + * Creates a formatter for percentage values. + * Multiplies the input by 100 and appends "%". + * + * @param {number} [precision] The number of decimal places to show (default 0). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter for percentage values. + */ static percentage(precision?: number, onlyShowUnchanged?: boolean): (d: any) => string; + /** + * Creates a formatter for values that displays [precision] significant figures + * and puts SI notation. + * + * @param {number} [precision] The number of significant figures to show (default 3). + * + * @returns {Formatter} A formatter for SI values. + */ static siSuffix(precision?: number): (d: any) => string; + /** + * Creates a formatter that displays dates. + * + * @returns {Formatter} A formatter for time/date values. + */ static time(): (d: any) => string; + /** + * Creates a formatter for relative dates. + * + * @param {number} baseValue The start date (as epoch time) used in computing relative dates (default 0) + * @param {number} increment The unit used in calculating relative date values (default MILLISECONDS_IN_ONE_DAY) + * @param {string} label The label to append to the formatted string (default "") + * + * @returns {Formatter} A formatter for time/date values. + */ static relativeDate(baseValue?: number, increment?: number, label?: string): (d: any) => string; } } @@ -202,32 +506,119 @@ declare module Plottable { declare module Plottable { module Core { + /** + * This interface represents anything in Plottable which can have a listener attached. + * Listeners attach by referencing the Listenable's broadcaster, and calling registerListener + * on it. + * + * e.g.: + * listenable: Plottable.IListenable; + * listenable.broadcaster.registerListener(callbackToCallOnBroadcast) + */ interface IListenable { broadcaster: Broadcaster; } + /** + * This interface represents the callback that should be passed to the Broadcaster on a Listenable. + * + * The callback will be called with the attached Listenable as the first object, and optional arguments + * as the subsequent arguments. + * + * The Listenable is passed as the first argument so that it is easy for the callback to reference the + * current state of the Listenable in the resolution logic. + */ interface IBroadcasterCallback { (listenable: IListenable, ...args: any[]): any; } - class Broadcaster extends Plottable.Abstract.PlottableObject { - listenable: IListenable; + /** + * The Broadcaster class is owned by an IListenable. Third parties can register and deregister listeners + * from the broadcaster. When the broadcaster.broadcast method is activated, all registered callbacks are + * called. The registered callbacks are called with the registered Listenable that the broadcaster is attached + * to, along with optional arguments passed to the `broadcast` method. + * + * The listeners are called synchronously. + */ + class Broadcaster extends Abstract.PlottableObject { + public listenable: IListenable; + /** + * Construct a broadcaster, taking the Listenable that the broadcaster will be attached to. + * + * @constructor + * @param {IListenable} listenable The Listenable-object that this broadcaster is attached to. + */ constructor(listenable: IListenable); - registerListener(key: any, callback: IBroadcasterCallback): Broadcaster; - broadcast(...args: any[]): Broadcaster; - deregisterListener(key: any): Broadcaster; - deregisterAllListeners(): void; - } - } -} - - -declare module Plottable { - class DataSource extends Plottable.Abstract.PlottableObject implements Plottable.Core.IListenable { - broadcaster: any; + /** + * Registers a callback to be called when the broadcast method is called. Also takes a key which + * is used to support deregistering the same callback later, by passing in the same key. + * If there is already a callback associated with that key, then the callback will be replaced. + * + * @param key The key associated with the callback. Key uniqueness is determined by deep equality. + * @param {IBroadcasterCallback} callback A callback to be called when the Scale's domain changes. + * @returns {Broadcaster} this object + */ + public registerListener(key: any, callback: IBroadcasterCallback): Broadcaster; + /** + * Call all listening callbacks, optionally with arguments passed through. + * + * @param ...args A variable number of optional arguments + * @returns {Broadcaster} this object + */ + public broadcast(...args: any[]): Broadcaster; + /** + * Deregisters the callback associated with a key. + * + * @param key The key to deregister. + * @returns {Broadcaster} this object + */ + public deregisterListener(key: any): Broadcaster; + /** + * Deregisters all listeners and callbacks associated with the broadcaster. + * + * @returns {Broadcaster} this object + */ + public deregisterAllListeners(): void; + } + } +} + + +declare module Plottable { + class DataSource extends Abstract.PlottableObject implements Core.IListenable { + public broadcaster: Core.Broadcaster; + /** + * Creates a new DataSource. + * + * @constructor + * @param {any[]} data + * @param {any} metadata An object containing additional information. + */ constructor(data?: any[], metadata?: any); - data(): any[]; - data(data: any[]): DataSource; - metadata(): any; - metadata(metadata: any): DataSource; + /** + * Gets the data. + * + * @returns {any[]} The current data. + */ + public data(): any[]; + /** + * Sets new data. + * + * @param {any[]} data The new data. + * @returns {DataSource} The calling DataSource. + */ + public data(data: any[]): DataSource; + /** + * Gets the metadata. + * + * @returns {any} The current metadata. + */ + public metadata(): any; + /** + * Sets the metadata. + * + * @param {any} metadata The new metadata. + * @returns {DataSource} The calling DataSource. + */ + public metadata(metadata: any): DataSource; } } @@ -235,29 +626,107 @@ declare module Plottable { declare module Plottable { module Abstract { class Component extends PlottableObject { - element: D3.Selection; - content: D3.Selection; - backgroundContainer: D3.Selection; - foregroundContainer: D3.Selection; - clipPathEnabled: boolean; - availableWidth: number; - availableHeight: number; - xOrigin: number; - yOrigin: number; + public element: D3.Selection; + public content: D3.Selection; + public backgroundContainer: D3.Selection; + public foregroundContainer: D3.Selection; + public clipPathEnabled: boolean; + public availableWidth: number; + public availableHeight: number; + public xOrigin: number; + public yOrigin: number; static AUTORESIZE_BY_DEFAULT: boolean; - renderTo(element: any): Component; - resize(width?: number, height?: number): Component; - autoResize(flag: boolean): Component; - xAlign(alignment: string): Component; - yAlign(alignment: string): Component; - xOffset(offset: number): Component; - yOffset(offset: number): Component; - registerInteraction(interaction: Interaction): Component; - classed(cssClass: string): boolean; - classed(cssClass: string, addClass: boolean): Component; - merge(c: Component): Plottable.Component.Group; - detach(): Component; - remove(): void; + /** + * Renders the Component into a given DOM element. + * + * @param {String|D3.Selection} element A D3 selection or a selector for getting the element to render into. + * @return {Component} The calling component. + */ + public renderTo(element: any): Component; + /** + * Cause the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. + * + * @param {number} [availableWidth] - the width of the container element + * @param {number} [availableHeight] - the height of the container element + */ + public resize(width?: number, height?: number): Component; + /** + * Enables and disables auto-resize. + * + * If enabled, window resizes will enqueue this component for a re-layout + * and re-render. Animations are disabled during window resizes when auto- + * resize is enabled. + * + * @param {boolean} flag - Enables (true) or disables (false) auto-resize. + */ + public autoResize(flag: boolean): Component; + /** + * Sets the x alignment of the Component. + * + * @param {string} alignment The x alignment of the Component (one of LEFT/CENTER/RIGHT). + * @returns {Component} The calling Component. + */ + public xAlign(alignment: string): Component; + /** + * Sets the y alignment of the Component. + * + * @param {string} alignment The y alignment of the Component (one of TOP/CENTER/BOTTOM). + * @returns {Component} The calling Component. + */ + public yAlign(alignment: string): Component; + /** + * Sets the x offset of the Component. + * + * @param {number} offset The desired x offset, in pixels. + * @returns {Component} The calling Component. + */ + public xOffset(offset: number): Component; + /** + * Sets the y offset of the Component. + * + * @param {number} offset The desired y offset, in pixels. + * @returns {Component} The calling Component. + */ + public yOffset(offset: number): Component; + /** + * Attaches an Interaction to the Component, so that the Interaction will listen for events on the Component. + * + * @param {Interaction} interaction The Interaction to attach to the Component. + * @return {Component} The calling Component. + */ + public registerInteraction(interaction: Interaction): Component; + /** + * Adds/removes a given CSS class to/from the Component, or checks if the Component has a particular CSS class. + * + * @param {string} cssClass The CSS class to add/remove/check for. + * @param {boolean} [addClass] Whether to add or remove the CSS class. If not supplied, checks for the CSS class. + * @return {boolean|Component} Whether the Component has the given CSS class, or the calling Component (if addClass is supplied). + */ + public classed(cssClass: string): boolean; + public classed(cssClass: string, addClass: boolean): Component; + /** + * Merges this Component with another Component, returning a ComponentGroup. + * There are four cases: + * Component + Component: Returns a ComponentGroup with both components inside it. + * ComponentGroup + Component: Returns the ComponentGroup with the Component appended. + * Component + ComponentGroup: Returns the ComponentGroup with the Component prepended. + * ComponentGroup + ComponentGroup: Returns a new ComponentGroup with two ComponentGroups inside it. + * + * @param {Component} c The component to merge in. + * @return {ComponentGroup} + */ + public merge(c: Component): Component.Group; + /** + * Detaches a Component from the DOM. The component can be reused. + * + * @returns The calling Component. + */ + public detach(): Component; + /** + * Removes a Component from the DOM and disconnects it from everything it's + * listening to (effectively destroying it). + */ + public remove(): void; } } } @@ -266,10 +735,26 @@ declare module Plottable { declare module Plottable { module Abstract { class ComponentContainer extends Component { - components(): Component[]; - empty(): boolean; - detachAll(): ComponentContainer; - remove(): void; + /** + * Returns a list of components in the ComponentContainer + * + * @returns{Component[]} the contained Components + */ + public components(): Component[]; + /** + * Returns true iff the ComponentContainer is empty. + * + * @returns {boolean} Whether the calling ComponentContainer is empty. + */ + public empty(): boolean; + /** + * Detaches all components contained in the ComponentContainer, and + * empties the ComponentContainer. + * + * @returns {ComponentContainer} The calling ComponentContainer + */ + public detachAll(): ComponentContainer; + public remove(): void; } } } @@ -277,9 +762,15 @@ declare module Plottable { declare module Plottable { module Component { - class Group extends Plottable.Abstract.ComponentContainer { - constructor(components?: Plottable.Abstract.Component[]); - merge(c: Plottable.Abstract.Component): Group; + class Group extends Abstract.ComponentContainer { + /** + * Creates a ComponentGroup. + * + * @constructor + * @param {Component[]} [components] The Components in the Group. + */ + constructor(components?: Abstract.Component[]); + public merge(c: Abstract.Component): Group; } } } @@ -295,12 +786,49 @@ declare module Plottable { wantsWidth: boolean; wantsHeight: boolean; } - class Table extends Plottable.Abstract.ComponentContainer { - constructor(rows?: Plottable.Abstract.Component[][]); - addComponent(row: number, col: number, component: Plottable.Abstract.Component): Table; - padding(rowPadding: number, colPadding: number): Table; - rowWeight(index: number, weight: number): Table; - colWeight(index: number, weight: number): Table; + class Table extends Abstract.ComponentContainer { + /** + * Creates a Table. + * + * @constructor + * @param {Component[][]} [rows] A 2-D array of the Components to place in the table. + * null can be used if a cell is empty. + */ + constructor(rows?: Abstract.Component[][]); + /** + * Adds a Component in the specified cell. + * + * @param {number} row The row in which to add the Component. + * @param {number} col The column in which to add the Component. + * @param {Component} component The Component to be added. + */ + public addComponent(row: number, col: number, component: Abstract.Component): Table; + /** + * Sets the row and column padding on the Table. + * + * @param {number} rowPadding The padding above and below each row, in pixels. + * @param {number} colPadding the padding to the left and right of each column, in pixels. + * @returns {Table} The calling Table. + */ + public padding(rowPadding: number, colPadding: number): Table; + /** + * Sets the layout weight of a particular row. + * Space is allocated to rows based on their weight. Rows with higher weights receive proportionally more space. + * + * @param {number} index The index of the row. + * @param {number} weight The weight to be set on the row. + * @returns {Table} The calling Table. + */ + public rowWeight(index: number, weight: number): Table; + /** + * Sets the layout weight of a particular column. + * Space is allocated to columns based on their weight. Columns with higher weights receive proportionally more space. + * + * @param {number} index The index of the column. + * @param {number} weight The weight to be set on the column. + * @returns {Table} The calling Table. + */ + public colWeight(index: number, weight: number): Table; } } } @@ -308,18 +836,77 @@ declare module Plottable { declare module Plottable { module Abstract { - class Scale extends PlottableObject implements Plottable.Core.IListenable { - broadcaster: any; + class Scale extends PlottableObject implements Core.IListenable { + public broadcaster: Core.Broadcaster; + /** + * Creates a new Scale. + * + * @constructor + * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. + */ constructor(scale: D3.Scale.Scale); - autoDomain(): Scale; - scale(value: any): any; - domain(): any[]; - domain(values: any[]): Scale; - range(): any[]; - range(values: any[]): Scale; - copy(): Scale; - updateExtent(rendererID: number, attr: string, extent: any[]): Scale; - removeExtent(rendererID: number, attr: string): Scale; + /** + * Modify the domain on the scale so that it includes the extent of all + * perspectives it depends on. Extent: The (min, max) pair for a + * QuantitiativeScale, all covered strings for an OrdinalScale. + * Perspective: A combination of a DataSource and an Accessor that + * represents a view in to the data. + */ + public autoDomain(): Scale; + /** + * Returns the range value corresponding to a given domain value. + * + * @param value {any} A domain value to be scaled. + * @returns {any} The range value corresponding to the supplied domain value. + */ + public scale(value: any): any; + /** + * Gets the domain. + * + * @returns {any[]} The current domain. + */ + public domain(): any[]; + /** + * Sets the Scale's domain to the specified values. + * + * @param {any[]} values The new value for the domain. This array may + * contain more than 2 values if the scale type allows it (e.g. + * ordinal scales). Other scales such as quantitative scales accept + * only a 2-value extent array. + * @returns {Scale} The calling Scale. + */ + public domain(values: any[]): Scale; + /** + * Gets the range. + * + * @returns {any[]} The current range. + */ + public range(): any[]; + /** + * Sets the Scale's range to the specified values. + * + * @param {any[]} values The new values for the range. + * @returns {Scale} The calling Scale. + */ + public range(values: any[]): Scale; + /** + * Creates a copy of the Scale with the same domain and range but without any registered listeners. + * + * @returns {Scale} A copy of the calling Scale. + */ + public copy(): Scale; + /** + * When a renderer determines that the extent of a projector has changed, + * it will call this function. This function should ensure that + * the scale has a domain at least large enough to include extent. + * + * @param {number} rendererID A unique indentifier of the renderer sending + * the new extent. + * @param {string} attr The attribute being projected, e.g. "x", "y0", "r" + * @param {any[]} extent The new extent to be included in the scale. + */ + public updateExtent(rendererID: number, attr: string, extent: any[]): Scale; + public removeExtent(rendererID: number, attr: string): Scale; } } } @@ -335,19 +922,55 @@ declare module Plottable { [attrToSet: string]: IAppliedAccessor; } class Plot extends Component { - renderArea: D3.Selection; - element: D3.Selection; + public renderArea: D3.Selection; + public element: D3.Selection; + /** + * Creates a Plot. + * + * @constructor + * @param {any[]|DataSource} [dataset] The data or DataSource to be associated with this Plot. + */ constructor(); constructor(dataset: any[]); constructor(dataset: DataSource); - remove(): void; - dataSource(): DataSource; - dataSource(source: DataSource): Plot; - project(attrToSet: string, accessor: any, scale?: Scale): Plot; - animate(enabled: boolean): Plot; - detach(): Plot; - animator(animatorKey: string): Plottable.Animator.IPlotAnimator; - animator(animatorKey: string, animator: Plottable.Animator.IPlotAnimator): Plot; + public remove(): void; + /** + * Gets the Plot's DataSource. + * + * @return {DataSource} The current DataSource. + */ + public dataSource(): DataSource; + /** + * Sets the Plot's DataSource. + * + * @param {DataSource} source The DataSource the Plot should use. + * @return {Plot} The calling Plot. + */ + public dataSource(source: DataSource): Plot; + public project(attrToSet: string, accessor: any, scale?: Scale): Plot; + /** + * Enables or disables animation. + * + * @param {boolean} enabled Whether or not to animate. + */ + public animate(enabled: boolean): Plot; + public detach(): Plot; + /** + * Gets the animator associated with the specified Animator key. + * + * @param {string} animatorKey The key for the Animator. + * @return {Animator.IPlotAnimator} The Animator for the specified key. + */ + public animator(animatorKey: string): Animator.IPlotAnimator; + /** + * Sets the animator associated with the specified Animator key. + * + * @param {string} animatorKey The key for the Animator. + * @param {Animator.IPlotAnimator} animator An Animator to be assigned to + * the specified key. + * @return {Plot} The calling Plot. + */ + public animator(animatorKey: string, animator: Animator.IPlotAnimator): Plot; } } } @@ -361,13 +984,13 @@ declare module Plottable { render(): any; } class Immediate implements IRenderPolicy { - render(): void; + public render(): void; } class AnimationFrame implements IRenderPolicy { - render(): void; + public render(): void; } class Timeout implements IRenderPolicy { - render(): void; + public render(): void; } } } @@ -377,11 +1000,33 @@ declare module Plottable { declare module Plottable { module Core { + /** + * The RenderController is responsible for enqueueing and synchronizing + * layout and render calls for Plottable components. + * + * Layouts and renders occur inside an animation callback + * (window.requestAnimationFrame if available). + * + * If you require immediate rendering, call RenderController.flush() to + * perform enqueued layout and rendering serially. + */ module RenderController { var _renderPolicy: RenderPolicy.IRenderPolicy; function setRenderPolicy(policy: RenderPolicy.IRenderPolicy): any; - function registerToRender(c: Plottable.Abstract.Component): void; - function registerToComputeLayout(c: Plottable.Abstract.Component): void; + /** + * If the RenderController is enabled, we enqueue the component for + * render. Otherwise, it is rendered immediately. + * + * @param {Abstract.Component} component Any Plottable component. + */ + function registerToRender(c: Abstract.Component): void; + /** + * If the RenderController is enabled, we enqueue the component for + * layout and render. Otherwise, it is rendered immediately. + * + * @param {Abstract.Component} component Any Plottable component. + */ + function registerToComputeLayout(c: Abstract.Component): void; function flush(): void; } } @@ -390,11 +1035,41 @@ declare module Plottable { declare module Plottable { module Core { + /** + * The ResizeBroadcaster will broadcast a notification to any registered + * components when the window is resized. + * + * The broadcaster and single event listener are lazily constructed. + * + * Upon resize, the _resized flag will be set to true until after the next + * flush of the RenderController. This is used, for example, to disable + * animations during resize. + */ module ResizeBroadcaster { + /** + * Returns true if the window has been resized and the RenderController + * has not yet been flushed. + */ function resizing(): boolean; function clearResizing(): any; - function register(c: Plottable.Abstract.Component): void; - function deregister(c: Plottable.Abstract.Component): void; + /** + * Registers a component. + * + * When the window is resized, we invoke ._invalidateLayout() on the + * component, which will enqueue the component for layout and rendering + * with the RenderController. + * + * @param {Abstract.Component} component Any Plottable component. + */ + function register(c: Abstract.Component): void; + /** + * Deregisters the components. + * + * The component will no longer receive updates on window resize. + * + * @param {Abstract.Component} component Any Plottable component. + */ + function deregister(c: Abstract.Component): void; } } } @@ -403,7 +1078,18 @@ declare module Plottable { declare module Plottable { module Animator { interface IPlotAnimator { - animate(selection: any, attrToProjector: Plottable.Abstract.IAttributeToProjector, plot: Plottable.Abstract.Plot): any; + /** + * Applies the supplied attributes to a D3.Selection with some animation. + * + * @param {D3.Selection} selection The update selection or transition selection that we wish to animate. + * @param {Abstract.IAttributeToProjector} attrToProjector The set of + * IAccessors that we will use to set attributes on the selection. + * @param {Abstract.Plot} plot The plot being animated. + * @return {D3.Selection} Animators should return the selection or + * transition object so that plots may chain the transitions between + * animators. + */ + animate(selection: any, attrToProjector: Abstract.IAttributeToProjector, plot: Abstract.Plot): any; } interface IPlotAnimatorMap { [animatorKey: string]: IPlotAnimator; @@ -461,14 +1147,94 @@ declare module Plottable { declare module Plottable { class Domainer { + /** + * @param {(extents: any[][]) => any[]} combineExtents + * If present, this function will be used by the Domainer to merge + * all the extents that are present on a scale. + * + * A plot may draw multiple things relative to a scale, e.g. + * different stocks over time. The plot computes their extents, + * which are a [min, max] pair. combineExtents is responsible for + * merging them all into one [min, max] pair. It defaults to taking + * the min of the first elements and the max of the second arguments. + */ constructor(combineExtents?: (extents: any[][]) => any[]); - computeDomain(extents: any[][], scale: Plottable.Abstract.QuantitativeScale): any[]; - pad(padProportion?: number): Domainer; - addPaddingException(exception: any, key?: string): Domainer; - removePaddingException(keyOrException: any): Domainer; - addIncludedValue(value: any, key?: string): Domainer; - removeIncludedValue(valueOrKey: any): Domainer; - nice(count?: number): Domainer; + /** + * @param {any[][]} extents The list of extents to be reduced to a single + * extent. + * @param {Abstract.QuantitativeScale} scale + * Since nice() must do different things depending on Linear, Log, + * or Time scale, the scale must be passed in for nice() to work. + * @return {any[]} The domain, as a merging of all exents, as a [min, max] + * pair. + */ + public computeDomain(extents: any[][], scale: Abstract.QuantitativeScale): any[]; + /** + * Sets the Domainer to pad by a given ratio. + * + * @param {number} [padProportion] Proportionally how much bigger the + * new domain should be (0.05 = 5% larger). + * + * A domainer will pad equal visual amounts on each side. + * On a linear scale, this means both sides are padded the same + * amount: [10, 20] will be padded to [5, 25]. + * On a log scale, the top will be padded more than the bottom, so + * [10, 100] will be padded to [1, 1000]. + * + * @return {Domainer} The calling Domainer. + */ + public pad(padProportion?: number): Domainer; + /** + * Add a padding exception, a value that will not be padded at either end of the domain. + * + * Eg, if a padding exception is added at x=0, then [0, 100] will pad to [0, 105] instead of [-2.5, 102.5]. + * If a key is provided, it will be registered under that key with standard map semantics. (Overwrite / remove by key) + * If a key is not provided, it will be added with set semantics (Can be removed by value) + * + * @param {any} exception The padding exception to add. + * @param string [key] The key to register the exception under. + * @return Domainer The calling domainer + */ + public addPaddingException(exception: any, key?: string): Domainer; + /** + * Remove a padding exception, allowing the domain to pad out that value again. + * + * If a string is provided, it is assumed to be a key and the exception associated with that key is removed. + * If a non-string is provdied, it is assumed to be an unkeyed exception and that exception is removed. + * + * @param {any} keyOrException The key for the value to remove, or the value to remove + * @return Domainer The calling domainer + */ + public removePaddingException(keyOrException: any): Domainer; + /** + * Add an included value, a value that must be included inside the domain. + * + * Eg, if a value exception is added at x=0, then [50, 100] will expand to [0, 100] rather than [50, 100]. + * If a key is provided, it will be registered under that key with standard map semantics. (Overwrite / remove by key) + * If a key is not provided, it will be added with set semantics (Can be removed by value) + * + * @param {any} value The included value to add. + * @param string [key] The key to register the value under. + * @return Domainer The calling domainer + */ + public addIncludedValue(value: any, key?: string): Domainer; + /** + * Remove an included value, allowing the domain to not include that value gain again. + * + * If a string is provided, it is assumed to be a key and the value associated with that key is removed. + * If a non-string is provdied, it is assumed to be an unkeyed value and that value is removed. + * + * @param {any} keyOrException The key for the value to remove, or the value to remove + * @return Domainer The calling domainer + */ + public removeIncludedValue(valueOrKey: any): Domainer; + /** + * Extends the scale's domain so it starts and ends with "nice" values. + * + * @param {number} [count] The number of ticks that should fit inside the new domain. + * @return {Domainer} The calling Domainer. + */ + public nice(count?: number): Domainer; } } @@ -476,20 +1242,89 @@ declare module Plottable { declare module Plottable { module Abstract { class QuantitativeScale extends Scale { + /** + * Creates a new QuantitativeScale. + * + * @constructor + * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale backing the QuantitativeScale. + */ constructor(scale: D3.Scale.QuantitativeScale); - invert(value: number): number; - copy(): QuantitativeScale; - domain(): any[]; - domain(values: any[]): QuantitativeScale; - interpolate(): D3.Transition.Interpolate; - interpolate(factory: D3.Transition.Interpolate): QuantitativeScale; - rangeRound(values: number[]): QuantitativeScale; - clamp(): boolean; - clamp(clamp: boolean): QuantitativeScale; - ticks(count?: number): any[]; - tickFormat(count: number, format?: string): (n: number) => string; - domainer(): Domainer; - domainer(domainer: Domainer): QuantitativeScale; + /** + * Retrieves the domain value corresponding to a supplied range value. + * + * @param {number} value: A value from the Scale's range. + * @returns {number} The domain value corresponding to the supplied range value. + */ + public invert(value: number): number; + /** + * Creates a copy of the QuantitativeScale with the same domain and range but without any registered listeners. + * + * @returns {QuantitativeScale} A copy of the calling QuantitativeScale. + */ + public copy(): QuantitativeScale; + public domain(): any[]; + public domain(values: any[]): QuantitativeScale; + /** + * Sets or gets the QuantitativeScale's output interpolator + * + * @param {D3.Transition.Interpolate} [factory] The output interpolator to use. + * @returns {D3.Transition.Interpolate|QuantitativeScale} The current output interpolator, or the calling QuantitativeScale. + */ + public interpolate(): D3.Transition.Interpolate; + public interpolate(factory: D3.Transition.Interpolate): QuantitativeScale; + /** + * Sets the range of the QuantitativeScale and sets the interpolator to d3.interpolateRound. + * + * @param {number[]} values The new range value for the range. + */ + public rangeRound(values: number[]): QuantitativeScale; + /** + * Gets the clamp status of the QuantitativeScale (whether to cut off values outside the ouput range). + * + * @returns {boolean} The current clamp status. + */ + public clamp(): boolean; + /** + * Sets the clamp status of the QuantitativeScale (whether to cut off values outside the ouput range). + * + * @param {boolean} clamp Whether or not to clamp the QuantitativeScale. + * @returns {QuantitativeScale} The calling QuantitativeScale. + */ + public clamp(clamp: boolean): QuantitativeScale; + /** + * Generates tick values. + * + * @param {number} [count] The number of ticks to generate. + * @returns {any[]} The generated ticks. + */ + public ticks(count?: number): any[]; + /** + * Gets a tick formatting function for displaying tick values. + * + * @param {number} count The number of ticks to be displayed + * @param {string} [format] A format specifier string. + * @returns {(n: number) => string} A formatting function. + */ + public tickFormat(count: number, format?: string): (n: number) => string; + /** + * Retrieve a Domainer of a scale. A Domainer is responsible for combining + * multiple extents into a single domain. + * + * @return {QuantitativeScale} The scale's current domainer. + */ + public domainer(): Domainer; + /** + * Sets a Domainer of a scale. A Domainer is responsible for combining + * multiple extents into a single domain. + * + * When you set domainer, we assume that you know what you want the domain + * to look like better that we do. Ensuring that the domain is padded, + * includes 0, etc., will be the responsability of the new domainer. + * + * @param {Domainer} domainer The domainer to be set. + * @return {QuantitativeScale} The calling scale. + */ + public domainer(domainer: Domainer): QuantitativeScale; } } } @@ -497,10 +1332,21 @@ declare module Plottable { declare module Plottable { module Scale { - class Linear extends Plottable.Abstract.QuantitativeScale { + class Linear extends Abstract.QuantitativeScale { + /** + * Creates a new LinearScale. + * + * @constructor + * @param {D3.Scale.LinearScale} [scale] The D3 LinearScale backing the LinearScale. If not supplied, uses a default scale. + */ constructor(); constructor(scale: D3.Scale.LinearScale); - copy(): Linear; + /** + * Creates a copy of the LinearScale with the same domain and range but without any registered listeners. + * + * @returns {LinearScale} A copy of the calling LinearScale. + */ + public copy(): Linear; } } } @@ -508,10 +1354,27 @@ declare module Plottable { declare module Plottable { module Scale { - class Log extends Plottable.Abstract.QuantitativeScale { + class Log extends Abstract.QuantitativeScale { + /** + * Creates a new Scale.Log. + * + * Warning: Log is deprecated; if possible, use ModifiedLog. Log scales are + * very unstable due to the fact that they can't handle 0 or negative + * numbers. The only time when you would want to use a Log scale over a + * ModifiedLog scale is if you're plotting very small data, such as all + * data < 1. + * + * @constructor + * @param {D3.Scale.LogScale} [scale] The D3 Scale.Log backing the Scale.Log. If not supplied, uses a default scale. + */ constructor(); constructor(scale: D3.Scale.LogScale); - copy(): Log; + /** + * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. + * + * @returns {Scale.Log} A copy of the calling Scale.Log. + */ + public copy(): Log; } } } @@ -519,14 +1382,51 @@ declare module Plottable { declare module Plottable { module Scale { - class ModifiedLog extends Plottable.Abstract.QuantitativeScale { + class ModifiedLog extends Abstract.QuantitativeScale { + /** + * Creates a new Scale.ModifiedLog. + * + * A ModifiedLog scale acts as a regular log scale for large numbers. + * As it approaches 0, it gradually becomes linear. This means that the + * scale won't freak out if you give it 0 or a negative number, where an + * ordinary Log scale would. + * + * However, it does mean that scale will be effectively linear as values + * approach 0. If you want very small values on a log scale, you should use + * an ordinary Scale.Log instead. + * + * @constructor + * @param {number} [base] + * The base of the log. Defaults to 10, and must be > 1. + * + * For base <= x, scale(x) = log(x). + * + * For 0 < x < base, scale(x) will become more and more + * linear as it approaches 0. + * + * At x == 0, scale(x) == 0. + * + * For negative values, scale(-x) = -scale(x). + */ constructor(base?: number); - scale(x: number): number; - invert(x: number): number; - ticks(count?: number): number[]; - copy(): ModifiedLog; - showIntermediateTicks(): boolean; - showIntermediateTicks(show: boolean): ModifiedLog; + public scale(x: number): number; + public invert(x: number): number; + public ticks(count?: number): number[]; + public copy(): ModifiedLog; + /** + * @returns {boolean} + * Whether or not to return tick values other than powers of base. + * + * This defaults to false, so you'll normally only see ticks like + * [10, 100, 1000]. If you turn it on, you might see ticks values + * like [10, 50, 100, 500, 1000]. + */ + public showIntermediateTicks(): boolean; + /** + * @param {boolean} show + * Whether or not to return ticks values other than powers of the base. + */ + public showIntermediateTicks(show: boolean): ModifiedLog; } } } @@ -534,18 +1434,72 @@ declare module Plottable { declare module Plottable { module Scale { - class Ordinal extends Plottable.Abstract.Scale { + class Ordinal extends Abstract.Scale { + /** + * Creates a new OrdinalScale. Domain and Range are set later. + * + * @constructor + */ constructor(scale?: D3.Scale.OrdinalScale); - domain(): any[]; - domain(values: any[]): Ordinal; - range(): number[]; - range(values: number[]): Ordinal; - rangeBand(): number; - innerPadding(): number; - fullBandStartAndWidth(v: any): number[]; - rangeType(): string; - rangeType(rangeType: string, outerPadding?: number, innerPadding?: number): Ordinal; - copy(): Ordinal; + /** + * Gets the domain. + * + * @returns {any[]} The current domain. + */ + public domain(): any[]; + /** + * Sets the domain. + * + * @param {any[]} values The new values for the domain. This array may contain more than 2 values. + * @returns {Ordinal} The calling Ordinal Scale. + */ + public domain(values: any[]): Ordinal; + /** + * Gets the range of pixels spanned by the Ordinal Scale. + * + * @returns {number[]} The pixel range. + */ + public range(): number[]; + /** + * Sets the range of pixels spanned by the Ordinal Scale. + * + * @param {number[]} values The pixel range to to be spanend by the scale. + * @returns {Ordinal} The calling Ordinal Scale. + */ + public range(values: number[]): Ordinal; + /** + * Returns the width of the range band. Only valid when rangeType is set to "bands". + * + * @returns {number} The range band width or 0 if rangeType isn't "bands". + */ + public rangeBand(): number; + public innerPadding(): number; + public fullBandStartAndWidth(v: any): number[]; + /** + * Gets the range type. + * + * @returns {string} The current range type. + */ + public rangeType(): string; + /** + * Sets the range type. + * + * @param {string} rangeType Either "points" or "bands" indicating the + * d3 method used to generate range bounds. + * @param {number} [outerPadding] The padding outside the range, + * proportional to the range step. + * @param {number} [innerPadding] The padding between bands in the range, + * proportional to the range step. This parameter is only used in + * "bands" type ranges. + * @returns {Ordinal} The calling Ordinal Scale. + */ + public rangeType(rangeType: string, outerPadding?: number, innerPadding?: number): Ordinal; + /** + * Creates a copy of the Scale with the same domain and range but without any registered listeners. + * + * @returns {Ordinal} A copy of the calling Scale. + */ + public copy(): Ordinal; } } } @@ -553,7 +1507,15 @@ declare module Plottable { declare module Plottable { module Scale { - class Color extends Plottable.Abstract.Scale { + class Color extends Abstract.Scale { + /** + * Creates a ColorScale. + * + * @constructor + * @param {string} [scaleType] the type of color scale to create + * (Category10/Category20/Category20b/Category20c). + * See https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors + */ constructor(scaleType?: string); } } @@ -562,13 +1524,24 @@ declare module Plottable { declare module Plottable { module Scale { - class Time extends Plottable.Abstract.QuantitativeScale { + class Time extends Abstract.QuantitativeScale { + /** + * Creates a new Time Scale. + * + * @constructor + * @param {D3.Scale.Time} [scale] The D3 LinearScale backing the TimeScale. If not supplied, uses a default scale. + */ constructor(); constructor(scale: D3.Scale.LinearScale); - tickInterval(interval: D3.Time.Interval, step?: number): any[]; - domain(): any[]; - domain(values: any[]): Time; - copy(): Time; + public tickInterval(interval: D3.Time.Interval, step?: number): any[]; + public domain(): any[]; + public domain(values: any[]): Time; + /** + * Creates a copy of the TimeScale with the same domain and range but without any registered listeners. + * + * @returns {TimeScale} A copy of the calling TimeScale. + */ + public copy(): Time; } } } @@ -576,13 +1549,58 @@ declare module Plottable { declare module Plottable { module Scale { - class InterpolatedColor extends Plottable.Abstract.QuantitativeScale { + /** + * This class implements a color scale that takes quantitive input and + * interpolates between a list of color values. It returns a hex string + * representing the interpolated color. + * + * By default it generates a linear scale internally. + */ + class InterpolatedColor extends Abstract.QuantitativeScale { + /** + * Creates a InterpolatedColorScale. + * + * @constructor + * @param {string|string[]} [colorRange] the type of color scale to + * create. Default is "reds". @see {@link colorRange} for further + * options. + * @param {string} [scaleType] the type of underlying scale to use + * (linear/pow/log/sqrt). Default is "linear". @see {@link scaleType} + * for further options. + */ constructor(colorRange?: any, scaleType?: string); - colorRange(): string[]; - colorRange(colorRange: any): InterpolatedColor; - scaleType(): string; - scaleType(scaleType: string): InterpolatedColor; - autoDomain(): InterpolatedColor; + /** + * Gets the color range. + * + * @returns {string[]} the current color values for the range as strings. + */ + public colorRange(): string[]; + /** + * Sets the color range. + * + * @param {string|string[]} colorRange. If colorRange is one of + * (reds/blues/posneg), uses the built-in color groups. If colorRange + * is an array of strings with at least 2 values + * (e.g. ["#FF00FF", "red", "dodgerblue"], the resulting scale + * will interpolate between the color values across the domain. + * @returns {InterpolatedColor} The calling InterpolatedColor Scale. + */ + public colorRange(colorRange: any): InterpolatedColor; + /** + * Gets the internal scale type. + * + * @returns {string} The current scale type. + */ + public scaleType(): string; + /** + * Sets the internal scale type. + * + * @param {string} scaleType. The type of d3 scale to use internally. + * (linear/log/sqrt/pow). + * @returns {InterpolatedColor} The calling InterpolatedColor Scale. + */ + public scaleType(scaleType: string): InterpolatedColor; + public autoDomain(): InterpolatedColor; } } } @@ -591,8 +1609,14 @@ declare module Plottable { declare module Plottable { module Util { class ScaleDomainCoordinator { - constructor(scales: Plottable.Abstract.Scale[]); - rescale(scale: Plottable.Abstract.Scale): void; + /** + * Creates a ScaleDomainCoordinator. + * + * @constructor + * @param {Scale[]} scales A list of scales whose domains should be linked. + */ + constructor(scales: Abstract.Scale[]); + public rescale(scale: Abstract.Scale): void; } } } @@ -601,29 +1625,138 @@ declare module Plottable { declare module Plottable { module Abstract { class Axis extends Component { + /** + * The css class applied to each end tick mark (the line on the end tick). + */ static END_TICK_MARK_CLASS: string; + /** + * The css class applied to each tick mark (the line on the tick). + */ static TICK_MARK_CLASS: string; + /** + * The css class applied to each tick label (the text associated with the tick). + */ static TICK_LABEL_CLASS: string; constructor(scale: Scale, orientation: string, formatter?: (d: any) => string); - remove(): void; - width(): number; - width(w: any): Axis; - height(): number; - height(h: any): Axis; - formatter(): Formatter; - formatter(formatter: Formatter): Axis; - tickLength(): number; - tickLength(length: number): Axis; - endTickLength(): number; - endTickLength(length: number): Axis; - tickLabelPadding(): number; - tickLabelPadding(padding: number): Axis; - gutter(): number; - gutter(size: number): Axis; - orient(): string; - orient(newOrientation: string): Axis; - showEndTickLabels(): boolean; - showEndTickLabels(show: boolean): Axis; + public remove(): void; + /** + * Gets the current width. + * + * @returns {number} The current width. + */ + public width(): number; + /** + * Sets a user-specified width. + * + * @param {number|String} w A fixed width for the Axis, or "auto" for automatic mode. + * @returns {Axis} The calling Axis. + */ + public width(w: any): Axis; + /** + * Gets the current height. + * + * @returns {number} The current height. + */ + public height(): number; + /** + * Sets a user-specified height. + * + * @param {number|String} h A fixed height for the Axis, or "auto" for automatic mode. + * @returns {Axis} The calling Axis. + */ + public height(h: any): Axis; + /** + * Get the current formatter on the axis. + * + * @returns {Formatter} the axis formatter + */ + public formatter(): Formatter; + /** + * Sets a new tick formatter. + * + * @param {Formatter} formatter + * @returns {Abstract.Axis} The calling Axis. + */ + public formatter(formatter: Formatter): Axis; + /** + * Gets the current tick mark length. + * + * @returns {number} The current tick mark length. + */ + public tickLength(): number; + /** + * Sets the tick mark length. + * + * @param {number} length The length of each tick. + * @returns {BaseAxis} The calling Axis. + */ + public tickLength(length: number): Axis; + /** + * Gets the current end tick mark length. + * + * @returns {number} The current end tick mark length. + */ + public endTickLength(): number; + /** + * Sets the end tick mark length. + * + * @param {number} length The length of the end ticks. + * @returns {BaseAxis} The calling Axis. + */ + public endTickLength(length: number): Axis; + /** + * Gets the padding between each tick mark and its associated label. + * + * @returns {number} The current padding, in pixels. + */ + public tickLabelPadding(): number; + /** + * Sets the padding between each tick mark and its associated label. + * + * @param {number} padding The desired padding, in pixels. + * @returns {Axis} The calling Axis. + */ + public tickLabelPadding(padding: number): Axis; + /** + * Gets the size of the gutter (the extra space between the tick labels and the outer edge of the axis). + * + * @returns {number} The current size of the gutter, in pixels. + */ + public gutter(): number; + /** + * Sets the size of the gutter (the extra space between the tick labels and the outer edge of the axis). + * + * @param {number} size The desired size of the gutter, in pixels. + * @returns {Axis} The calling Axis. + */ + public gutter(size: number): Axis; + /** + * Gets the orientation of the Axis. + * + * @returns {string} The current orientation. + */ + public orient(): string; + /** + * Sets the orientation of the Axis. + * + * @param {string} newOrientation The desired orientation (top/bottom/left/right). + * @returns {Axis} The calling Axis. + */ + public orient(newOrientation: string): Axis; + /** + * Checks whether the Axis is currently set to show the first and last + * tick labels. + * + * @returns {boolean} + */ + public showEndTickLabels(): boolean; + /** + * Set whether or not to show the first and last tick labels. + * + * @param {boolean} show Whether or not to show the first and last labels. + * @returns {Axis} The calling Axis. + */ + public showEndTickLabels(show: boolean): Axis; } } } @@ -636,13 +1769,20 @@ declare module Plottable { step: number; formatString: string; } - class Time extends Plottable.Abstract.Axis { + class Time extends Abstract.Axis { static minorIntervals: ITimeInterval[]; static majorIntervals: ITimeInterval[]; - constructor(scale: Plottable.Scale.Time, orientation: string); - calculateWorstWidth(container: D3.Selection, format: string): number; - getIntervalLength(interval: ITimeInterval): number; - isEnoughSpace(container: D3.Selection, interval: ITimeInterval): boolean; + /** + * Creates a TimeAxis + * + * @constructor + * @param {TimeScale} scale The scale to base the Axis on. + * @param {string} orientation The orientation of the Axis (top/bottom) + */ + constructor(scale: Scale.Time, orientation: string); + public calculateWorstWidth(container: D3.Selection, format: string): number; + public getIntervalLength(interval: ITimeInterval): number; + public isEnoughSpace(container: D3.Selection, interval: ITimeInterval): boolean; } } } @@ -650,12 +1790,54 @@ declare module Plottable { declare module Plottable { module Axis { - class Numeric extends Plottable.Abstract.Axis { - constructor(scale: Plottable.Abstract.QuantitativeScale, orientation: string, formatter?: (d: any) => string); - tickLabelPosition(): string; - tickLabelPosition(position: string): Numeric; - showEndTickLabel(orientation: string): boolean; - showEndTickLabel(orientation: string, show: boolean): Numeric; + class Numeric extends Abstract.Axis { + /** + * Creates a NumericAxis. + * + * @constructor + * @param {QuantitativeScale} scale The QuantitativeScale to base the NumericAxis on. + * @param {string} orientation The orientation of the QuantitativeScale (top/bottom/left/right) + * @param {Formatter} [formatter] A function to format tick labels (default Formatters.general(3, false)). + */ + constructor(scale: Abstract.QuantitativeScale, orientation: string, formatter?: (d: any) => string); + /** + * Gets the tick label position relative to the tick marks. + * + * @returns {string} The current tick label position. + */ + public tickLabelPosition(): string; + /** + * Sets the tick label position relative to the tick marks. + * + * @param {string} position The relative position of the tick label. + * [top/center/bottom] for a vertical NumericAxis, + * [left/center/right] for a horizontal NumericAxis. + * @returns {NumericAxis} The calling NumericAxis. + */ + public tickLabelPosition(position: string): Numeric; + /** + * Return whether or not the tick labels at the end of the graph are + * displayed when partially cut off. + * + * @param {string} orientation Where on the scale to change tick labels. + * On a "top" or "bottom" axis, this can be "left" or + * "right". On a "left" or "right" axis, this can be "top" + * or "bottom". + * @returns {boolean} The current setting. + */ + public showEndTickLabel(orientation: string): boolean; + /** + * Control whether or not the tick labels at the end of the graph are + * displayed when partially cut off. + * + * @param {string} orientation Where on the scale to change tick labels. + * On a "top" or "bottom" axis, this can be "left" or + * "right". On a "left" or "right" axis, this can be "top" + * or "bottom". + * @param {boolean} show Whether or not the given tick should be displayed. + * @returns {Numeric} The calling Numeric. + */ + public showEndTickLabel(orientation: string, show: boolean): Numeric; } } } @@ -663,8 +1845,19 @@ declare module Plottable { declare module Plottable { module Axis { - class Category extends Plottable.Abstract.Axis { - constructor(scale: Plottable.Scale.Ordinal, orientation?: string, formatter?: (d: any) => string); + class Category extends Abstract.Axis { + /** + * Creates a CategoryAxis. + * + * A CategoryAxis takes an OrdinalScale and includes word-wrapping algorithms and advanced layout logic to try to + * display the scale as efficiently as possible. + * + * @constructor + * @param {OrdinalScale} scale The scale to base the Axis on. + * @param {string} orientation The orientation of the Axis (top/bottom/left/right) + * @param {Formatter} [formatter] The Formatter for the Axis (default Formatters.identity()) + */ + constructor(scale: Scale.Ordinal, orientation?: string, formatter?: (d: any) => string); } } } @@ -672,12 +1865,30 @@ declare module Plottable { declare module Plottable { module Component { - class Label extends Plottable.Abstract.Component { + class Label extends Abstract.Component { + /** + * Creates a Label. + * + * @constructor + * @param {string} [displayText] The text of the Label. + * @param {string} [orientation] The orientation of the Label (horizontal/vertical-left/vertical-right). + */ constructor(displayText?: string, orientation?: string); - xAlign(alignment: string): Label; - yAlign(alignment: string): Label; - text(): string; - text(displayText: string): Label; + public xAlign(alignment: string): Label; + public yAlign(alignment: string): Label; + /** + * Retrieve the current text on the Label. + * + * @returns {string} The text on the label. + */ + public text(): string; + /** + * Sets the text on the Label. + * + * @param {string} displayText The new text for the Label. + * @returns {Label} The calling Label. + */ + public text(displayText: string): Label; } class TitleLabel extends Label { constructor(text?: string, orientation?: string); @@ -697,16 +1908,55 @@ declare module Plottable { interface HoverCallback { (datum?: string): any; } - class Legend extends Plottable.Abstract.Component { + class Legend extends Abstract.Component { + /** + * The css class applied to each legend row + */ static SUBELEMENT_CLASS: string; - constructor(colorScale?: Plottable.Scale.Color); - remove(): void; - toggleCallback(callback: ToggleCallback): Legend; - toggleCallback(): ToggleCallback; - hoverCallback(callback: HoverCallback): Legend; - hoverCallback(): HoverCallback; - scale(scale: Plottable.Scale.Color): Legend; - scale(): Plottable.Scale.Color; + /** + * Creates a Legend. + * + * A legend consists of a series of legend rows, each with a color and label taken from the `colorScale`. + * The rows will be displayed in the order of the `colorScale` domain. + * This legend also allows interactions, through the functions `toggleCallback` and `hoverCallback` + * Setting a callback will also put classes on the individual rows. + * + * @constructor + * @param {Scale.Color} colorScale + */ + constructor(colorScale?: Scale.Color); + public remove(): void; + /** + * Assigns or gets the callback to the Legend + * + * This callback is associated with toggle events, which trigger when a legend row is clicked. + * Internally, this will change the state of of the row from "toggled-on" to "toggled-off" and vice versa. + * Setting a callback will also set a class to each individual legend row as "toggled-on" or "toggled-off". + * Call with argument of null to remove the callback. This will also remove the above classes to legend rows. + * + * @param {ToggleCallback} callback The new callback function + */ + public toggleCallback(callback: ToggleCallback): Legend; + public toggleCallback(): ToggleCallback; + /** + * Assigns or gets the callback to the Legend + * This callback is associated with hover events, which trigger when the mouse enters or leaves a legend row + * Setting a callback will also set the class "hover" to all legend row, + * as well as the class "focus" to the legend row being hovered over. + * Call with argument of null to remove the callback. This will also remove the above classes to legend rows. + * + * @param{HoverCallback} callback The new callback function + */ + public hoverCallback(callback: HoverCallback): Legend; + public hoverCallback(): HoverCallback; + /** + * Assigns a new ColorScale to the Legend. + * + * @param {ColorScale} scale + * @returns {Legend} The calling Legend. + */ + public scale(scale: Scale.Color): Legend; + public scale(): Scale.Color; } } } @@ -714,9 +1964,16 @@ declare module Plottable { declare module Plottable { module Component { - class Gridlines extends Plottable.Abstract.Component { - constructor(xScale: Plottable.Abstract.QuantitativeScale, yScale: Plottable.Abstract.QuantitativeScale); - remove(): Gridlines; + class Gridlines extends Abstract.Component { + /** + * Creates a set of Gridlines. + * @constructor + * + * @param {QuantitativeScale} xScale The scale to base the x gridlines on. Pass null if no gridlines are desired. + * @param {QuantitativeScale} yScale The scale to base the y gridlines on. Pass null if no gridlines are desired. + */ + constructor(xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); + public remove(): Gridlines; } } } @@ -725,10 +1982,18 @@ declare module Plottable { declare module Plottable { module Abstract { class XYPlot extends Plot { - xScale: Scale; - yScale: Scale; + public xScale: Scale; + public yScale: Scale; + /** + * Creates an XYPlot. + * + * @constructor + * @param {any[]|DataSource} [dataset] The data or DataSource to be associated with this Renderer. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(dataset: any, xScale: Scale, yScale: Scale); - project(attrToSet: string, accessor: any, scale?: Scale): XYPlot; + public project(attrToSet: string, accessor: any, scale?: Scale): XYPlot; } } } @@ -736,9 +2001,17 @@ declare module Plottable { declare module Plottable { module Plot { - class Scatter extends Plottable.Abstract.XYPlot { - constructor(dataset: any, xScale: Plottable.Abstract.Scale, yScale: Plottable.Abstract.Scale); - project(attrToSet: string, accessor: any, scale?: Plottable.Abstract.Scale): Scatter; + class Scatter extends Abstract.XYPlot { + /** + * Creates a ScatterPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ + constructor(dataset: any, xScale: Abstract.Scale, yScale: Abstract.Scale); + public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Scatter; } } } @@ -746,12 +2019,22 @@ declare module Plottable { declare module Plottable { module Plot { - class Grid extends Plottable.Abstract.XYPlot { - colorScale: Plottable.Abstract.Scale; - xScale: Plottable.Scale.Ordinal; - yScale: Plottable.Scale.Ordinal; - constructor(dataset: any, xScale: Plottable.Scale.Ordinal, yScale: Plottable.Scale.Ordinal, colorScale: Plottable.Abstract.Scale); - project(attrToSet: string, accessor: any, scale?: Plottable.Abstract.Scale): Grid; + class Grid extends Abstract.XYPlot { + public colorScale: Abstract.Scale; + public xScale: Scale.Ordinal; + public yScale: Scale.Ordinal; + /** + * Creates a GridPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {OrdinalScale} xScale The x scale to use. + * @param {OrdinalScale} yScale The y scale to use. + * @param {ColorScale|InterpolatedColorScale} colorScale The color scale to use for each grid + * cell. + */ + constructor(dataset: any, xScale: Scale.Ordinal, yScale: Scale.Ordinal, colorScale: Abstract.Scale); + public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Grid; } } } @@ -761,16 +2044,53 @@ declare module Plottable { module Abstract { class BarPlot extends XYPlot { static _BarAlignmentToFactor: { - [x: string]: number; + [alignment: string]: number; }; + /** + * Creates an AbstractBarPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(dataset: any, xScale: Scale, yScale: Scale); - baseline(value: number): BarPlot; - barAlignment(alignment: string): BarPlot; - selectBar(xValOrExtent: IExtent, yValOrExtent: IExtent, select?: boolean): D3.Selection; - selectBar(xValOrExtent: number, yValOrExtent: IExtent, select?: boolean): D3.Selection; - selectBar(xValOrExtent: IExtent, yValOrExtent: number, select?: boolean): D3.Selection; - selectBar(xValOrExtent: number, yValOrExtent: number, select?: boolean): D3.Selection; - deselectAll(): BarPlot; + /** + * Sets the baseline for the bars to the specified value. + * + * @param {number} value The value to position the baseline at. + * @return {AbstractBarPlot} The calling AbstractBarPlot. + */ + public baseline(value: number): BarPlot; + /** + * Sets the bar alignment relative to the independent axis. + * VerticalBarPlot supports "left", "center", "right" + * HorizontalBarPlot supports "top", "center", "bottom" + * + * @param {string} alignment The desired alignment. + * @return {AbstractBarPlot} The calling AbstractBarPlot. + */ + public barAlignment(alignment: string): BarPlot; + /** + * Selects the bar under the given pixel position (if [xValOrExtent] + * and [yValOrExtent] are {number}s), under a given line (if only one + * of [xValOrExtent] or [yValOrExtent] are {IExtent}s) or are under a + * 2D area (if [xValOrExtent] and [yValOrExtent] are both {IExtent}s). + * + * @param {any} xValOrExtent The pixel x position, or range of x values. + * @param {any} yValOrExtent The pixel y position, or range of y values. + * @param {boolean} [select] Whether or not to select the bar (by classing it "selected"); + * @return {D3.Selection} The selected bar, or null if no bar was selected. + */ + public selectBar(xValOrExtent: IExtent, yValOrExtent: IExtent, select?: boolean): D3.Selection; + public selectBar(xValOrExtent: number, yValOrExtent: IExtent, select?: boolean): D3.Selection; + public selectBar(xValOrExtent: IExtent, yValOrExtent: number, select?: boolean): D3.Selection; + public selectBar(xValOrExtent: number, yValOrExtent: number, select?: boolean): D3.Selection; + /** + * Deselects all bars. + * @return {AbstractBarPlot} The calling AbstractBarPlot. + */ + public deselectAll(): BarPlot; } } } @@ -778,11 +2098,28 @@ declare module Plottable { declare module Plottable { module Plot { - class VerticalBar extends Plottable.Abstract.BarPlot { + /** + * A VerticalBarPlot draws bars vertically. + * Key projected attributes: + * - "width" - the horizontal width of a bar. + * - if an ordinal scale is attached, this defaults to ordinalScale.rangeBand() + * - if a quantitative scale is attached, this defaults to 10 + * - "x" - the horizontal position of a bar + * - "y" - the vertical height of a bar + */ + class VerticalBar extends Abstract.BarPlot { static _BarAlignmentToFactor: { - [x: string]: number; + [alignment: string]: number; }; - constructor(dataset: any, xScale: Plottable.Abstract.Scale, yScale: Plottable.Abstract.QuantitativeScale); + /** + * Creates a VerticalBarPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ + constructor(dataset: any, xScale: Abstract.Scale, yScale: Abstract.QuantitativeScale); } } } @@ -790,12 +2127,29 @@ declare module Plottable { declare module Plottable { module Plot { - class HorizontalBar extends Plottable.Abstract.BarPlot { + /** + * A HorizontalBarPlot draws bars horizontally. + * Key projected attributes: + * - "width" - the vertical height of a bar (since the bar is rotated horizontally) + * - if an ordinal scale is attached, this defaults to ordinalScale.rangeBand() + * - if a quantitative scale is attached, this defaults to 10 + * - "x" - the horizontal length of a bar + * - "y" - the vertical position of a bar + */ + class HorizontalBar extends Abstract.BarPlot { static _BarAlignmentToFactor: { - [x: string]: number; + [alignment: string]: number; }; - isVertical: boolean; - constructor(dataset: any, xScale: Plottable.Abstract.QuantitativeScale, yScale: Plottable.Abstract.Scale); + public isVertical: boolean; + /** + * Creates a HorizontalBarPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ + constructor(dataset: any, xScale: Abstract.QuantitativeScale, yScale: Abstract.Scale); } } } @@ -803,8 +2157,16 @@ declare module Plottable { declare module Plottable { module Plot { - class Line extends Plottable.Abstract.XYPlot { - constructor(dataset: any, xScale: Plottable.Abstract.Scale, yScale: Plottable.Abstract.Scale); + class Line extends Abstract.XYPlot { + /** + * Creates a LinePlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ + constructor(dataset: any, xScale: Abstract.Scale, yScale: Abstract.Scale); } } } @@ -812,9 +2174,20 @@ declare module Plottable { declare module Plottable { module Plot { + /** + * An AreaPlot draws a filled region (area) between the plot's projected "y" and projected "y0" values. + */ class Area extends Line { - constructor(dataset: any, xScale: Plottable.Abstract.Scale, yScale: Plottable.Abstract.Scale); - project(attrToSet: string, accessor: any, scale?: Plottable.Abstract.Scale): Area; + /** + * Creates an AreaPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ + constructor(dataset: any, xScale: Abstract.Scale, yScale: Abstract.Scale); + public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Area; } } } @@ -822,8 +2195,12 @@ declare module Plottable { declare module Plottable { module Animator { + /** + * An animator implementation with no animation. The attributes are + * immediately set on the selection. + */ class Null implements IPlotAnimator { - animate(selection: any, attrToProjector: Plottable.Abstract.IAttributeToProjector, plot: Plottable.Abstract.Plot): any; + public animate(selection: any, attrToProjector: Abstract.IAttributeToProjector, plot: Abstract.Plot): any; } } } @@ -831,14 +2208,50 @@ declare module Plottable { declare module Plottable { module Animator { + /** + * The default animator implementation with easing, duration, and delay. + */ class Default implements IPlotAnimator { - animate(selection: any, attrToProjector: Plottable.Abstract.IAttributeToProjector, plot: Plottable.Abstract.Plot): any; - duration(): Number; - duration(duration: Number): Default; - delay(): Number; - delay(delay: Number): Default; - easing(): string; - easing(easing: string): Default; + public animate(selection: any, attrToProjector: Abstract.IAttributeToProjector, plot: Abstract.Plot): any; + /** + * Gets the duration of the animation in milliseconds. + * + * @returns {Number} The current duration. + */ + public duration(): Number; + /** + * Sets the duration of the animation in milliseconds. + * + * @param {Number} duration The duration in milliseconds. + * @returns {Default} The calling Default Animator. + */ + public duration(duration: Number): Default; + /** + * Gets the delay of the animation in milliseconds. + * + * @returns {Number} The current delay. + */ + public delay(): Number; + /** + * Sets the delay of the animation in milliseconds. + * + * @param {Number} delay The delay in milliseconds. + * @returns {Default} The calling Default Animator. + */ + public delay(delay: Number): Default; + /** + * Gets the current easing of the animation. + * + * @returns {string} the current easing mode. + */ + public easing(): string; + /** + * Sets the easing mode of the animation. + * + * @param {string} easing The desired easing mode. + * @returns {Default} The calling Default Animator. + */ + public easing(easing: string): Default; } } } @@ -846,8 +2259,14 @@ declare module Plottable { declare module Plottable { module Animator { + /** + * An animator that delays the animation of the attributes using the index + * of the selection data. + * + * The delay between animations can be configured with the .delay getter/setter. + */ class IterativeDelay extends Default { - animate(selection: any, attrToProjector: Plottable.Abstract.IAttributeToProjector, plot: Plottable.Abstract.Plot): any; + public animate(selection: any, attrToProjector: Abstract.IAttributeToProjector, plot: Abstract.Plot): any; } } } @@ -869,10 +2288,20 @@ declare module Plottable { declare module Plottable { module Abstract { class Interaction { - hitBox: D3.Selection; - componentToListenTo: Component; + public hitBox: D3.Selection; + public componentToListenTo: Component; + /** + * Creates an Interaction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for interactions on. + */ constructor(componentToListenTo: Component); - registerWithComponent(): Interaction; + /** + * Registers the Interaction on the Component it's listening to. + * This needs to be called to activate the interaction. + */ + public registerWithComponent(): Interaction; } } } @@ -880,12 +2309,29 @@ declare module Plottable { declare module Plottable { module Interaction { - class Click extends Plottable.Abstract.Interaction { - constructor(componentToListenTo: Plottable.Abstract.Component); - callback(cb: (x: number, y: number) => any): Click; + class Click extends Abstract.Interaction { + /** + * Creates a ClickInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for clicks on. + */ + constructor(componentToListenTo: Abstract.Component); + /** + * Sets an callback to be called when a click is received. + * + * @param {(x: number, y: number) => any} cb: Callback to be called. Takes click x and y in pixels. + */ + public callback(cb: (x: number, y: number) => any): Click; } class DoubleClick extends Click { - constructor(componentToListenTo: Plottable.Abstract.Component); + /** + * Creates a DoubleClickInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for clicks on. + */ + constructor(componentToListenTo: Abstract.Component); } } } @@ -893,9 +2339,9 @@ declare module Plottable { declare module Plottable { module Interaction { - class Mousemove extends Plottable.Abstract.Interaction { - constructor(componentToListenTo: Plottable.Abstract.Component); - mousemove(x: number, y: number): void; + class Mousemove extends Abstract.Interaction { + constructor(componentToListenTo: Abstract.Component); + public mousemove(x: number, y: number): void; } } } @@ -903,9 +2349,21 @@ declare module Plottable { declare module Plottable { module Interaction { - class Key extends Plottable.Abstract.Interaction { - constructor(componentToListenTo: Plottable.Abstract.Component, keyCode: number); - callback(cb: () => any): Key; + class Key extends Abstract.Interaction { + /** + * Creates a KeyInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for keypresses on. + * @param {number} keyCode The key code to listen for. + */ + constructor(componentToListenTo: Abstract.Component, keyCode: number); + /** + * Sets an callback to be called when the designated key is pressed. + * + * @param {() => any} cb: Callback to be called. + */ + public callback(cb: () => any): Key; } } } @@ -913,11 +2371,19 @@ declare module Plottable { declare module Plottable { module Interaction { - class PanZoom extends Plottable.Abstract.Interaction { - xScale: Plottable.Abstract.QuantitativeScale; - yScale: Plottable.Abstract.QuantitativeScale; - constructor(componentToListenTo: Plottable.Abstract.Component, xScale?: Plottable.Abstract.QuantitativeScale, yScale?: Plottable.Abstract.QuantitativeScale); - resetZoom(): void; + class PanZoom extends Abstract.Interaction { + public xScale: Abstract.QuantitativeScale; + public yScale: Abstract.QuantitativeScale; + /** + * Creates a PanZoomInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for interactions on. + * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. + * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. + */ + constructor(componentToListenTo: Abstract.Component, xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale); + public resetZoom(): void; } } } @@ -925,13 +2391,24 @@ declare module Plottable { declare module Plottable { module Interaction { - class Drag extends Plottable.Abstract.Interaction { - origin: number[]; - location: number[]; - callbackToCall: (dragInfo: any) => any; - constructor(componentToListenTo: Plottable.Abstract.Component); - callback(cb?: (a: any) => any): Drag; - setupZoomCallback(xScale?: Plottable.Abstract.QuantitativeScale, yScale?: Plottable.Abstract.QuantitativeScale): Drag; + class Drag extends Abstract.Interaction { + public origin: number[]; + public location: number[]; + public callbackToCall: (dragInfo: any) => any; + /** + * Creates a Drag. + * + * @param {Component} componentToListenTo The component to listen for interactions on. + */ + constructor(componentToListenTo: Abstract.Component); + /** + * Adds a callback to be called when the AreaInteraction triggers. + * + * @param {(a: SelectionArea) => any} cb The function to be called. Takes in a SelectionArea in pixels. + * @returns {AreaInteraction} The calling AreaInteraction. + */ + public callback(cb?: (a: any) => any): Drag; + public setupZoomCallback(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale): Drag; } } } @@ -940,10 +2417,15 @@ declare module Plottable { declare module Plottable { module Interaction { class DragBox extends Drag { - dragBox: D3.Selection; - boxIsDrawn: boolean; - clearBox(): DragBox; - setBox(x0: number, x1: number, y0: number, y1: number): DragBox; + public dragBox: D3.Selection; + public boxIsDrawn: boolean; + /** + * Clears the highlighted drag-selection box drawn by the AreaInteraction. + * + * @returns {AreaInteraction} The calling AreaInteraction. + */ + public clearBox(): DragBox; + public setBox(x0: number, x1: number, y0: number, y1: number): DragBox; } } } @@ -952,7 +2434,7 @@ declare module Plottable { declare module Plottable { module Interaction { class XDragBox extends DragBox { - setBox(x0: number, x1: number): XDragBox; + public setBox(x0: number, x1: number): XDragBox; } } } @@ -969,7 +2451,7 @@ declare module Plottable { declare module Plottable { module Interaction { class YDragBox extends DragBox { - setBox(y0: number, y1: number): YDragBox; + public setBox(y0: number, y1: number): YDragBox; } } } @@ -978,11 +2460,37 @@ declare module Plottable { declare module Plottable { module Abstract { class Dispatcher extends PlottableObject { + /** + * Creates a Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ constructor(target: D3.Selection); - target(): D3.Selection; - target(targetElement: D3.Selection): Dispatcher; - connect(): Dispatcher; - disconnect(): Dispatcher; + /** + * Gets the target of the Dispatcher. + * + * @returns {D3.Selection} The Dispatcher's current target. + */ + public target(): D3.Selection; + /** + * Sets the target of the Dispatcher. + * + * @param {D3.Selection} target The element to listen for updates on. + * @returns {Dispatcher} The calling Dispatcher. + */ + public target(targetElement: D3.Selection): Dispatcher; + /** + * Attaches the Dispatcher's listeners to the Dispatcher's target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ + public connect(): Dispatcher; + /** + * Detaches the Dispatcher's listeners from the Dispatchers' target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ + public disconnect(): Dispatcher; } } } @@ -990,14 +2498,55 @@ declare module Plottable { declare module Plottable { module Dispatcher { - class Mouse extends Plottable.Abstract.Dispatcher { + class Mouse extends Abstract.Dispatcher { + /** + * Creates a Mouse Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ constructor(target: D3.Selection); - mouseover(): (location: Point) => any; - mouseover(callback: (location: Point) => any): Mouse; - mousemove(): (location: Point) => any; - mousemove(callback: (location: Point) => any): Mouse; - mouseout(): (location: Point) => any; - mouseout(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mouseover. + * + * @return {(location: Point) => any} The current mouseover callback. + */ + public mouseover(): (location: Point) => any; + /** + * Attaches a callback to be called on mouseover. + * + * @param {(location: Point) => any} callback A function that takes the pixel position of the mouse event. + * Pass in null to remove the callback. + * @return {Mouse} The calling Mouse Handler. + */ + public mouseover(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mousemove. + * + * @return {(location: Point) => any} The current mousemove callback. + */ + public mousemove(): (location: Point) => any; + /** + * Attaches a callback to be called on mousemove. + * + * @param {(location: Point) => any} callback A function that takes the pixel position of the mouse event. + * Pass in null to remove the callback. + * @return {Mouse} The calling Mouse Handler. + */ + public mousemove(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mouseout. + * + * @return {(location: Point) => any} The current mouseout callback. + */ + public mouseout(): (location: Point) => any; + /** + * Attaches a callback to be called on mouseout. + * + * @param {(location: Point) => any} callback A function that takes the pixel position of the mouse event. + * Pass in null to remove the callback. + * @return {Mouse} The calling Mouse Handler. + */ + public mouseout(callback: (location: Point) => any): Mouse; } } } @@ -1005,22 +2554,22 @@ declare module Plottable { declare module Plottable { module Template { - class StandardChart extends Plottable.Component.Table { + class StandardChart extends Component.Table { constructor(); - yAxis(y: Plottable.Abstract.Axis): StandardChart; - yAxis(): Plottable.Abstract.Axis; - xAxis(x: Plottable.Abstract.Axis): StandardChart; - xAxis(): Plottable.Abstract.Axis; - yLabel(y: Plottable.Component.AxisLabel): StandardChart; - yLabel(y: string): StandardChart; - yLabel(): Plottable.Component.AxisLabel; - xLabel(x: Plottable.Component.AxisLabel): StandardChart; - xLabel(x: string): StandardChart; - xLabel(): Plottable.Component.AxisLabel; - titleLabel(x: Plottable.Component.TitleLabel): StandardChart; - titleLabel(x: string): StandardChart; - titleLabel(): Plottable.Component.TitleLabel; - center(c: Plottable.Abstract.Component): StandardChart; + public yAxis(y: Abstract.Axis): StandardChart; + public yAxis(): Abstract.Axis; + public xAxis(x: Abstract.Axis): StandardChart; + public xAxis(): Abstract.Axis; + public yLabel(y: Component.AxisLabel): StandardChart; + public yLabel(y: string): StandardChart; + public yLabel(): Component.AxisLabel; + public xLabel(x: Component.AxisLabel): StandardChart; + public xLabel(x: string): StandardChart; + public xLabel(): Component.AxisLabel; + public titleLabel(x: Component.TitleLabel): StandardChart; + public titleLabel(x: string): StandardChart; + public titleLabel(): Component.TitleLabel; + public center(c: Abstract.Component): StandardChart; } } } diff --git a/plottable.js b/plottable.js index 32a48b42cc..09011dbe49 100644 --- a/plottable.js +++ b/plottable.js @@ -1,35 +1,68 @@ /*! -Plottable 0.23.2 (https://github.com/palantir/plottable) +Plottable 0.24.0 (https://github.com/palantir/plottable) Copyright 2014 Palantir Technologies Licensed under MIT (https://github.com/palantir/plottable/blob/master/LICENSE) */ +/// var Plottable; (function (Plottable) { (function (Util) { (function (Methods) { + /** + * Checks if x is between a and b. + * + * @param {number} x The value to test if in range + * @param {number} a The beginning of the (inclusive) range + * @param {number} b The ending of the (inclusive) range + * @return {boolean} Whether x is in [a, b] + */ function inRange(x, a, b) { return (Math.min(a, b) <= x && x <= Math.max(a, b)); } Methods.inRange = inRange; + + /** Print a warning message to the console, if it is available. + * + * @param {string} The warnings to print + */ function warn(warning) { + /* tslint:disable:no-console */ if (window.console != null) { if (window.console.warn != null) { console.warn(warning); - } - else if (window.console.log != null) { + } else if (window.console.log != null) { console.log(warning); } } + /* tslint:enable:no-console */ } Methods.warn = warn; + + /** + * Takes two arrays of numbers and adds them together + * + * @param {number[]} alist The first array of numbers + * @param {number[]} blist The second array of numbers + * @return {number[]} An array of numbers where x[i] = alist[i] + blist[i] + */ function addArrays(alist, blist) { if (alist.length !== blist.length) { throw new Error("attempted to add arrays of unequal length"); } - return alist.map(function (_, i) { return alist[i] + blist[i]; }); + return alist.map(function (_, i) { + return alist[i] + blist[i]; + }); } Methods.addArrays = addArrays; + + /** + * Takes two sets and returns the intersection + * + * @param {D3.Set} set1 The first set + * @param {D3.Set} set2 The second set + * @return {D3.Set} A set that contains elements that appear in both set1 and set2 + */ function intersection(set1, set2) { var set = d3.set(); set1.forEach(function (v) { @@ -40,37 +73,66 @@ var Plottable; return set; } Methods.intersection = intersection; + + /** + * Take an accessor object (may be a string to be made into a key, or a value, or a color code) + * and "activate" it by turning it into a function in (datum, index, metadata) + */ function _accessorize(accessor) { if (typeof (accessor) === "function") { return accessor; - } - else if (typeof (accessor) === "string" && accessor[0] !== "#") { - return function (d, i, s) { return d[accessor]; }; - } - else { - return function (d, i, s) { return accessor; }; + } else if (typeof (accessor) === "string" && accessor[0] !== "#") { + return function (d, i, s) { + return d[accessor]; + }; + } else { + return function (d, i, s) { + return accessor; + }; } ; } Methods._accessorize = _accessorize; + + /** + * Takes two sets and returns the union + * + * @param{D3.Set} set1 The first set + * @param{D3.Set} set2 The second set + * @return{D3.Set} A set that contains elements that appear in either set1 or set2 + */ function union(set1, set2) { var set = d3.set(); - set1.forEach(function (v) { return set.add(v); }); - set2.forEach(function (v) { return set.add(v); }); + set1.forEach(function (v) { + return set.add(v); + }); + set2.forEach(function (v) { + return set.add(v); + }); return set; } Methods.union = union; + + /** + * Take an accessor object, activate it, and partially apply it to a Plot's datasource's metadata + */ function _applyAccessor(accessor, plot) { var activatedAccessor = _accessorize(accessor); - return function (d, i) { return activatedAccessor(d, i, plot.dataSource().metadata()); }; + return function (d, i) { + return activatedAccessor(d, i, plot.dataSource().metadata()); + }; } Methods._applyAccessor = _applyAccessor; + function uniq(strings) { var seen = {}; - strings.forEach(function (s) { return seen[s] = true; }); + strings.forEach(function (s) { + return seen[s] = true; + }); return d3.keys(seen); } Methods.uniq = uniq; + function uniqNumbers(a) { var seen = d3.set(); var result = []; @@ -83,6 +145,14 @@ var Plottable; return result; } Methods.uniqNumbers = uniqNumbers; + + /** + * Creates an array of length `count`, filled with value or (if value is a function), value() + * + * @param {any} value The value to fill the array with, or, if a function, a generator for values + * @param {number} count The length of the array to generate + * @return {any[]} + */ function createFilledArray(value, count) { var out = []; for (var i = 0; i < count; i++) { @@ -91,11 +161,21 @@ var Plottable; return out; } Methods.createFilledArray = createFilledArray; + + /** + * @param {T[][]} a The 2D array that will have its elements joined together. + * @return {T[]} Every array in a, concatenated together in the order they appear. + */ function flatten(a) { return Array.prototype.concat.apply([], a); } Methods.flatten = flatten; + + /** + * Check if two arrays are equal by strict equality. + */ function arrayEq(a, b) { + // Technically, null and undefined are arrays too if (a == null || b == null) { return a === b; } @@ -110,14 +190,27 @@ var Plottable; return true; } Methods.arrayEq = arrayEq; + + /** + * @param {any} a Object to check against b for equality. + * @param {any} b Object to check against a for equality. + * + * @returns {boolean} whether or not two objects share the same keys, and + * values associated with those keys. Values will be compared + * with ===. + */ function objEq(a, b) { if (a == null || b == null) { return a === b; } var keysA = Object.keys(a).sort(); var keysB = Object.keys(b).sort(); - var valuesA = keysA.map(function (k) { return a[k]; }); - var valuesB = keysB.map(function (k) { return b[k]; }); + var valuesA = keysA.map(function (k) { + return a[k]; + }); + var valuesB = keysB.map(function (k) { + return b[k]; + }); return arrayEq(keysA, keysB) && arrayEq(valuesA, valuesB); } Methods.objEq = objEq; @@ -127,20 +220,26 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// +// This file contains open source utilities, along with their copyright notices var Plottable; (function (Plottable) { (function (Util) { (function (OpenSource) { + + function sortedIndex(val, arr, accessor) { var low = 0; var high = arr.length; while (low < high) { + /* tslint:disable:no-bitwise */ var mid = (low + high) >>> 1; + + /* tslint:enable:no-bitwise */ var x = accessor == null ? arr[mid] : accessor(arr[mid]); if (x < val) { low = mid + 1; - } - else { + } else { high = mid; } } @@ -154,6 +253,7 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { @@ -166,14 +266,17 @@ var Plottable; this.counter[id] = 0; } }; + IDCounter.prototype.increment = function (id) { this.setDefault(id); return ++this.counter[id]; }; + IDCounter.prototype.decrement = function (id) { this.setDefault(id); return --this.counter[id]; }; + IDCounter.prototype.get = function (id) { this.setDefault(id); return this.counter[id]; @@ -185,13 +288,26 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { + /** + * An associative array that can be keyed by anything (inc objects). + * Uses pointer equality checks which is why this works. + * This power has a price: everything is linear time since it is actually backed by an array... + */ var StrictEqualityAssociativeArray = (function () { function StrictEqualityAssociativeArray() { this.keyValuePairs = []; } + /** + * Set a new key/value pair in the store. + * + * @param {any} key Key to set in the store + * @param {any} value Value to set in the store + * @return {boolean} True if key already in store, false otherwise + */ StrictEqualityAssociativeArray.prototype.set = function (key, value) { if (key !== key) { throw new Error("NaN may not be used as a key to the StrictEqualityAssociativeArray"); @@ -205,6 +321,13 @@ var Plottable; this.keyValuePairs.push([key, value]); return false; }; + + /** + * Get a value from the store, given a key. + * + * @param {any} key Key associated with value to retrieve + * @return {any} Value if found, undefined otherwise + */ StrictEqualityAssociativeArray.prototype.get = function (key) { for (var i = 0; i < this.keyValuePairs.length; i++) { if (this.keyValuePairs[i][0] === key) { @@ -213,6 +336,16 @@ var Plottable; } return undefined; }; + + /** + * Test whether store has a value associated with given key. + * + * Will return true if there is a key/value entry, + * even if the value is explicitly `undefined`. + * + * @param {any} key Key to test for presence of an entry + * @return {boolean} Whether there was a matching entry for that key + */ StrictEqualityAssociativeArray.prototype.has = function (key) { for (var i = 0; i < this.keyValuePairs.length; i++) { if (this.keyValuePairs[i][0] === key) { @@ -221,17 +354,47 @@ var Plottable; } return false; }; + + /** + * Return an array of the values in the key-value store + * + * @return {any[]} The values in the store + */ StrictEqualityAssociativeArray.prototype.values = function () { - return this.keyValuePairs.map(function (x) { return x[1]; }); + return this.keyValuePairs.map(function (x) { + return x[1]; + }); }; + + /** + * Return an array of keys in the key-value store + * + * @return {any[]} The keys in the store + */ StrictEqualityAssociativeArray.prototype.keys = function () { - return this.keyValuePairs.map(function (x) { return x[0]; }); + return this.keyValuePairs.map(function (x) { + return x[0]; + }); }; + + /** + * Execute a callback for each entry in the array. + * + * @param {(key: any, val?: any, index?: number) => any} callback The callback to eecute + * @return {any[]} The results of mapping the callback over the entries + */ StrictEqualityAssociativeArray.prototype.map = function (cb) { return this.keyValuePairs.map(function (kv, index) { return cb(kv[0], kv[1], index); }); }; + + /** + * Delete a key from the key-value store. Return whether the key was present. + * + * @param {any} The key to remove + * @return {boolean} Whether a matching entry was found and removed + */ StrictEqualityAssociativeArray.prototype.delete = function (key) { for (var i = 0; i < this.keyValuePairs.length; i++) { if (this.keyValuePairs[i][0] === key) { @@ -248,12 +411,26 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { var Cache = (function () { + /** + * @constructor + * + * @param {string} compute The function whose results will be cached. + * @param {string} [canonicalKey] If present, when clear() is called, + * this key will be re-computed. If its result hasn't been changed, + * the cache will not be cleared. + * @param {(v: T, w: T) => boolean} [valueEq] + * Used to determine if the value of canonicalKey has changed. + * If omitted, defaults to === comparision. + */ function Cache(compute, canonicalKey, valueEq) { - if (valueEq === void 0) { valueEq = function (v, w) { return v === w; }; } + if (typeof valueEq === "undefined") { valueEq = function (v, w) { + return v === w; + }; } this.cache = d3.map(); this.canonicalKey = null; this.compute = compute; @@ -263,12 +440,29 @@ var Plottable; this.cache.set(this.canonicalKey, this.compute(this.canonicalKey)); } } + /** + * Attempt to look up k in the cache, computing the result if it isn't + * found. + * + * @param {string} k The key to look up in the cache. + * @return {T} The value associated with k; the result of compute(k). + */ Cache.prototype.get = function (k) { if (!this.cache.has(k)) { this.cache.set(k, this.compute(k)); } return this.cache.get(k); }; + + /** + * Reset the cache empty. + * + * If canonicalKey was provided at construction, compute(canonicalKey) + * will be re-run. If the result matches what is already in the cache, + * it will not clear the cache. + * + * @return {Cache} The calling Cache. + */ Cache.prototype.clear = function () { if (this.canonicalKey === undefined || !this.valueEq(this.cache.get(this.canonicalKey), this.compute(this.canonicalKey))) { this.cache = d3.map(); @@ -282,12 +476,21 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { (function (Text) { ; + ; + + /** + * Returns a quasi-pure function of typesignature (t: string) => Dimensions which measures height and width of text + * + * @param {D3.Selection} selection: The selection in which text will be drawn and measured + * @returns {Dimensions} width and height of the text + */ function getTextMeasure(selection) { return function (s) { if (s.trim() === "") { @@ -300,8 +503,7 @@ var Plottable; bb = Util.DOM.getBBox(selection); selection.text(originalText); return { width: bb.width, height: bb.height }; - } - else { + } else { var t = selection.append("text").text(s); bb = Util.DOM.getBBox(t); t.remove(); @@ -310,19 +512,45 @@ var Plottable; }; } Text.getTextMeasure = getTextMeasure; + + /** + * @return {TextMeasurer} A test measurer that will treat all sequences + * of consecutive whitespace as a single " ". + */ function combineWhitespace(tm) { - return function (s) { return tm(s.replace(/\s+/g, " ")); }; + return function (s) { + return tm(s.replace(/\s+/g, " ")); + }; } + + /** + * Returns a text measure that measures each individual character of the + * string with tm, then combines all the individual measurements. + */ function measureByCharacter(tm) { return function (s) { var whs = s.trim().split("").map(tm); return { - width: d3.sum(whs, function (wh) { return wh.width; }), - height: d3.max(whs, function (wh) { return wh.height; }) + width: d3.sum(whs, function (wh) { + return wh.width; + }), + height: d3.max(whs, function (wh) { + return wh.height; + }) }; }; } + var CANONICAL_CHR = "a"; + + /** + * Some TextMeasurers get confused when measuring something that's only + * whitespace: only whitespace in a dom node takes up 0 x 0 space. + * + * @return {TextMeasurer} A function that if its argument is all + * whitespace, it will wrap its argument in CANONICAL_CHR before + * measuring in order to get a non-zero size of the whitespace. + */ function wrapWhitespace(tm) { return function (s) { if (/^\s*$/.test(s)) { @@ -335,21 +563,40 @@ var Plottable; }; }); return { - width: d3.sum(whs, function (x) { return x.width; }), - height: d3.max(whs, function (x) { return x.height; }) + width: d3.sum(whs, function (x) { + return x.width; + }), + height: d3.max(whs, function (x) { + return x.height; + }) }; - } - else { + } else { return tm(s); } }; } + + /** + * This class will measure text by measuring each character individually, + * then adding up the dimensions. It will also cache the dimensions of each + * letter. + */ var CachingCharacterMeasurer = (function () { + /** + * @param {D3.Selection} g The element that will have text inserted into + * it in order to measure text. The styles present for text in + * this element will to the text being measured. + */ function CachingCharacterMeasurer(g) { var _this = this; this.cache = new Util.Cache(getTextMeasure(g), CANONICAL_CHR, Util.Methods.objEq); - this.measure = combineWhitespace(measureByCharacter(wrapWhitespace(function (s) { return _this.cache.get(s); }))); + this.measure = combineWhitespace(measureByCharacter(wrapWhitespace(function (s) { + return _this.cache.get(s); + }))); } + /** + * Clear the cache, if it seems that the text has changed size. + */ CachingCharacterMeasurer.prototype.clear = function () { this.cache.clear(); return this; @@ -357,26 +604,55 @@ var Plottable; return CachingCharacterMeasurer; })(); Text.CachingCharacterMeasurer = CachingCharacterMeasurer; + + /** + * Gets a truncated version of a sting that fits in the available space, given the element in which to draw the text + * + * @param {string} text: The string to be truncated + * @param {number} availableWidth: The available width, in pixels + * @param {D3.Selection} element: The text element used to measure the text + * @returns {string} text - the shortened text + */ function getTruncatedText(text, availableWidth, measurer) { if (measurer(text).width <= availableWidth) { return text; - } - else { + } else { return _addEllipsesToLine(text, availableWidth, measurer); } } Text.getTruncatedText = getTruncatedText; + + /** + * Gets the height of a text element, as rendered. + * + * @param {D3.Selection} textElement + * @return {number} The height of the text element, in pixels. + */ function getTextHeight(selection) { return getTextMeasure(selection)("bqpdl").height; } Text.getTextHeight = getTextHeight; + + /** + * Gets the width of a text element, as rendered. + * + * @param {D3.Selection} textElement + * @return {number} The width of the text element, in pixels. + */ function getTextWidth(textElement, text) { return getTextMeasure(textElement)(text).width; } Text.getTextWidth = getTextWidth; + + /** + * Takes a line, a width to fit it in, and a text measurer. Will attempt to add ellipses to the end of the line, + * shortening the line as required to ensure that it fits within width. + */ function _addEllipsesToLine(line, width, measureText) { var mutatedLine = line.trim(); - var widthMeasure = function (s) { return measureText(s).width; }; + var widthMeasure = function (s) { + return measureText(s).width; + }; var lineWidth = widthMeasure(line); var ellipsesWidth = widthMeasure("..."); if (width < ellipsesWidth) { @@ -394,9 +670,10 @@ var Plottable; return mutatedLine + "..."; } Text._addEllipsesToLine = _addEllipsesToLine; + function writeLineHorizontally(line, g, width, height, xAlign, yAlign) { - if (xAlign === void 0) { xAlign = "left"; } - if (yAlign === void 0) { yAlign = "top"; } + if (typeof xAlign === "undefined") { xAlign = "left"; } + if (typeof yAlign === "undefined") { yAlign = "top"; } var xOffsetFactor = { left: 0, center: 0.5, right: 1 }; var yOffsetFactor = { top: 0, center: 0.5, bottom: 1 }; if (xOffsetFactor[xAlign] === undefined || yOffsetFactor[yAlign] === undefined) { @@ -423,10 +700,11 @@ var Plottable; return { width: w, height: h }; } Text.writeLineHorizontally = writeLineHorizontally; + function writeLineVertically(line, g, width, height, xAlign, yAlign, rotation) { - if (xAlign === void 0) { xAlign = "left"; } - if (yAlign === void 0) { yAlign = "top"; } - if (rotation === void 0) { rotation = "right"; } + if (typeof xAlign === "undefined") { xAlign = "left"; } + if (typeof yAlign === "undefined") { yAlign = "top"; } + if (typeof rotation === "undefined") { rotation = "right"; } if (rotation !== "right" && rotation !== "left") { throw new Error("unrecognized rotation: " + rotation); } @@ -440,12 +718,14 @@ var Plottable; xForm.rotate = rotation === "right" ? 90 : -90; xForm.translate = [isRight ? width : 0, isRight ? 0 : height]; innerG.attr("transform", xForm.toString()); + return wh; } Text.writeLineVertically = writeLineVertically; + function writeTextHorizontally(brokenText, g, width, height, xAlign, yAlign) { - if (xAlign === void 0) { xAlign = "left"; } - if (yAlign === void 0) { yAlign = "top"; } + if (typeof xAlign === "undefined") { xAlign = "left"; } + if (typeof yAlign === "undefined") { yAlign = "top"; } var h = getTextHeight(g); var maxWidth = 0; var blockG = g.append("g"); @@ -464,10 +744,11 @@ var Plottable; return { width: maxWidth, height: usedSpace }; } Text.writeTextHorizontally = writeTextHorizontally; + function writeTextVertically(brokenText, g, width, height, xAlign, yAlign, rotation) { - if (xAlign === void 0) { xAlign = "left"; } - if (yAlign === void 0) { yAlign = "top"; } - if (rotation === void 0) { rotation = "left"; } + if (typeof xAlign === "undefined") { xAlign = "left"; } + if (typeof yAlign === "undefined") { yAlign = "top"; } + if (typeof rotation === "undefined") { rotation = "left"; } var h = getTextHeight(g); var maxHeight = 0; var blockG = g.append("g"); @@ -483,32 +764,50 @@ var Plottable; var freeSpace = width - usedSpace; var translator = { center: 0.5, left: 0, right: 1 }; Util.DOM.translate(blockG, freeSpace * translator[xAlign], 0); + return { width: usedSpace, height: maxHeight }; } Text.writeTextVertically = writeTextVertically; + ; + + /** + * @param {write} [IWriteOptions] If supplied, the text will be written + * To the given g. Will align the text vertically if it seems like + * that is appropriate. + * Returns an IWriteTextResult with info on whether the text fit, and how much width/height was used. + */ function writeText(text, width, height, tm, horizontally, write) { var orientHorizontally = (horizontally != null) ? horizontally : width * 1.1 > height; var primaryDimension = orientHorizontally ? width : height; var secondaryDimension = orientHorizontally ? height : width; var wrappedText = Util.WordWrap.breakTextToFitRect(text, primaryDimension, secondaryDimension, tm); + if (wrappedText.lines.length === 0) { return { textFits: wrappedText.textFits, usedWidth: 0, usedHeight: 0 }; } + var usedWidth, usedHeight; if (write == null) { var widthFn = orientHorizontally ? d3.max : d3.sum; var heightFn = orientHorizontally ? d3.sum : d3.max; - usedWidth = widthFn(wrappedText.lines, function (line) { return tm(line).width; }); - usedHeight = heightFn(wrappedText.lines, function (line) { return tm(line).height; }); - } - else { + usedWidth = widthFn(wrappedText.lines, function (line) { + return tm(line).width; + }); + usedHeight = heightFn(wrappedText.lines, function (line) { + return tm(line).height; + }); + } else { var innerG = write.g.append("g").classed("writeText-inner-g", true); + + // the outerG contains general transforms for positining the whole block, the inner g + // will contain transforms specific to orienting the text properly within the block. var writeTextFn = orientHorizontally ? writeTextHorizontally : writeTextVertically; var wh = writeTextFn(wrappedText.lines, innerG, width, height, write.xAlign, write.yAlign); usedWidth = wh.width; usedHeight = wh.height; } + return { textFits: wrappedText.textFits, usedWidth: usedWidth, usedHeight: usedHeight }; } Text.writeText = writeText; @@ -518,6 +817,7 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { @@ -525,9 +825,17 @@ var Plottable; var LINE_BREAKS_BEFORE = /[{\[]/; var LINE_BREAKS_AFTER = /[!"%),-.:;?\]}]/; var SPACES = /^\s+$/; + ; + + /** + * Takes a block of text, a width and height to fit it in, and a 2-d text measurement function. + * Wraps words and fits as much of the text as possible into the given width and height. + */ function breakTextToFitRect(text, width, height, measureText) { - var widthMeasure = function (s) { return measureText(s).width; }; + var widthMeasure = function (s) { + return measureText(s).width; + }; var lines = breakTextToFitWidth(text, width, widthMeasure); var textHeight = measureText("hello world").height; var nLinesThatFit = Math.floor(height / textHeight); @@ -535,12 +843,19 @@ var Plottable; if (!textFit) { lines = lines.splice(0, nLinesThatFit); if (nLinesThatFit > 0) { + // Overwrite the last line to one that has had a ... appended to the end lines[nLinesThatFit - 1] = Util.Text._addEllipsesToLine(lines[nLinesThatFit - 1], width, measureText); } } return { originalText: text, lines: lines, textFits: textFit }; } WordWrap.breakTextToFitRect = breakTextToFitRect; + + /** + * Splits up the text so that it will fit in width (or splits into a list of single characters if it is impossible + * to fit in width). Tries to avoid breaking words on non-linebreak-or-space characters, and will only break a word if + * the word is too big to fit within width on its own. + */ function breakTextToFitWidth(text, width, widthMeasure) { var ret = []; var paragraphs = text.split("\n"); @@ -548,13 +863,18 @@ var Plottable; var paragraph = paragraphs[i]; if (paragraph !== null) { ret = ret.concat(breakParagraphToFitWidth(paragraph, width, widthMeasure)); - } - else { + } else { ret.push(""); } } return ret; } + + /** + * Determines if it is possible to fit a given text within width without breaking any of the words. + * Simple algorithm, split the text up into tokens, and make sure that the widest token doesn't exceed + * allowed width. + */ function canWrapWithoutBreakingWords(text, width, widthMeasure) { var tokens = tokenize(text); var widths = tokens.map(widthMeasure); @@ -562,6 +882,13 @@ var Plottable; return maxWidth <= width; } WordWrap.canWrapWithoutBreakingWords = canWrapWithoutBreakingWords; + + /** + * A paragraph is a string of text containing no newlines. + * Given a paragraph, break it up into lines that are no + * wider than width. widthMeasure is a function that takes + * text as input, and returns the width of the text in pixels. + */ function breakParagraphToFitWidth(text, width, widthMeasure) { var lines = []; var tokens = tokenize(text); @@ -573,8 +900,10 @@ var Plottable; nextToken = tokens[i++]; } var brokenToken = breakNextTokenToFitInWidth(curLine, nextToken, width, widthMeasure); + var canAdd = brokenToken[0]; var leftOver = brokenToken[1]; + if (canAdd !== null) { curLine += canAdd; } @@ -589,6 +918,15 @@ var Plottable; } return lines; } + + /** + * Breaks up the next token and so that some part of it can be + * added to curLine and fits in the width. the return value + * is an array with 2 elements, the part that can be added + * and the left over part of the token + * widthMeasure is a function that takes text as input, + * and returns the width of the text in pixels. + */ function breakNextTokenToFitInWidth(curLine, nextToken, width, widthMeasure) { if (isBlank(nextToken)) { return [nextToken, null]; @@ -603,8 +941,7 @@ var Plottable; while (i < nextToken.length) { if (widthMeasure(curLine + nextToken[i] + "-") <= width) { curLine += nextToken[i++]; - } - else { + } else { break; } } @@ -615,6 +952,15 @@ var Plottable; } return [nextToken.substring(0, i) + append, nextToken.substring(i)]; } + + /** + * Breaks up into tokens for word wrapping + * Each token is comprised of either: + * 1) Only word and non line break characters + * 2) Only spaces characters + * 3) Line break characters such as ":" or ";" or "," + * (will be single character token, unless there is a repeated linebreak character) + */ function tokenize(text) { var ret = []; var token = ""; @@ -623,8 +969,7 @@ var Plottable; var curChar = text[i]; if (token === "" || isTokenizedTogether(token[0], curChar, lastChar)) { token += curChar; - } - else { + } else { ret.push(token); token = curChar; } @@ -635,17 +980,31 @@ var Plottable; } return ret; } + + /** + * Returns whether a string is blank. + * + * @param {string} str: The string to test for blank-ness + * @returns {boolean} Whether the string is blank + */ function isBlank(text) { return text == null ? true : text.trim() === ""; } + + /** + * Given a token (ie a string of characters that are similar and shouldn't be broken up) and a character, determine + * whether that character should be added to the token. Groups of characters that don't match the space or line break + * regex are always tokenzied together. Spaces are always tokenized together. Line break characters are almost always + * split into their own token, except that two subsequent identical line break characters are put into the same token. + * For isTokenizedTogether(":", ",") == False but isTokenizedTogether("::") == True. + */ function isTokenizedTogether(text, nextChar, lastChar) { if (!(text && nextChar)) { false; } if (SPACES.test(text) && SPACES.test(nextChar)) { return true; - } - else if (SPACES.test(text) || SPACES.test(nextChar)) { + } else if (SPACES.test(text) || SPACES.test(nextChar)) { return false; } if (LINE_BREAKS_AFTER.test(lastChar) || LINE_BREAKS_BEFORE.test(nextChar)) { @@ -663,20 +1022,26 @@ var Plottable; (function (Plottable) { (function (Util) { (function (DOM) { + /** + * Gets the bounding box of an element. + * @param {D3.Selection} element + * @returns {SVGRed} The bounding box. + */ function getBBox(element) { return element.node().getBBox(); } DOM.getBBox = getBBox; + DOM.POLYFILL_TIMEOUT_MSEC = 1000 / 60; function requestAnimationFramePolyfill(fn) { if (window.requestAnimationFrame != null) { window.requestAnimationFrame(fn); - } - else { + } else { setTimeout(fn, DOM.POLYFILL_TIMEOUT_MSEC); } } DOM.requestAnimationFramePolyfill = requestAnimationFramePolyfill; + function _getParsedStyleValue(style, prop) { var value = style.getPropertyValue(prop); var parsedValue = parseFloat(value); @@ -685,6 +1050,8 @@ var Plottable; } return parsedValue; } + + // function isSelectionRemovedFromSVG(selection) { var n = selection.node(); while (n !== null && n.nodeName !== "svg") { @@ -693,20 +1060,25 @@ var Plottable; return (n == null); } DOM.isSelectionRemovedFromSVG = isSelectionRemovedFromSVG; + function getElementWidth(elem) { var style = window.getComputedStyle(elem); return _getParsedStyleValue(style, "width") + _getParsedStyleValue(style, "padding-left") + _getParsedStyleValue(style, "padding-right") + _getParsedStyleValue(style, "border-left-width") + _getParsedStyleValue(style, "border-right-width"); } DOM.getElementWidth = getElementWidth; + function getElementHeight(elem) { var style = window.getComputedStyle(elem); return _getParsedStyleValue(style, "height") + _getParsedStyleValue(style, "padding-top") + _getParsedStyleValue(style, "padding-bottom") + _getParsedStyleValue(style, "border-top-width") + _getParsedStyleValue(style, "border-bottom-width"); } DOM.getElementHeight = getElementHeight; + function getSVGPixelWidth(svg) { var width = svg.node().clientWidth; + if (width === 0) { var widthAttr = svg.attr("width"); + if (widthAttr.indexOf("%") !== -1) { var ancestorNode = svg.node().parentNode; while (ancestorNode != null && ancestorNode.clientWidth === 0) { @@ -716,20 +1088,20 @@ var Plottable; throw new Error("Could not compute width of element"); } width = ancestorNode.clientWidth * parseFloat(widthAttr) / 100; - } - else { + } else { width = parseFloat(widthAttr); } } + return width; } DOM.getSVGPixelWidth = getSVGPixelWidth; + function translate(s, x, y) { var xform = d3.transform(s.attr("transform")); if (x == null) { return xform.translate; - } - else { + } else { y = (y == null) ? 0 : y; xform.translate[0] = x; xform.translate[1] = y; @@ -738,6 +1110,7 @@ var Plottable; } } DOM.translate = translate; + function boxesOverlap(boxA, boxB) { if (boxA.right < boxB.left) { return false; @@ -760,17 +1133,29 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { Plottable.MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000; + var Formatters = (function () { function Formatters() { } + /** + * Creates a formatter for currency values. + * + * @param {number} [precision] The number of decimal places to show (default 2). + * @param {string} [symbol] The currency symbol to use (default "$"). + * @param {boolean} [prefix] Whether to prepend or append the currency symbol (default true). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter for currency values. + */ Formatters.currency = function (precision, symbol, prefix, onlyShowUnchanged) { - if (precision === void 0) { precision = 2; } - if (symbol === void 0) { symbol = "$"; } - if (prefix === void 0) { prefix = true; } - if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } + if (typeof precision === "undefined") { precision = 2; } + if (typeof symbol === "undefined") { symbol = "$"; } + if (typeof prefix === "undefined") { prefix = true; } + if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } var fixedFormatter = Formatters.fixed(precision); return function (d) { var formattedValue = fixedFormatter(Math.abs(d)); @@ -780,10 +1165,10 @@ var Plottable; if (formattedValue !== "") { if (prefix) { formattedValue = symbol + formattedValue; - } - else { + } else { formattedValue += symbol; } + if (d < 0) { formattedValue = "-" + formattedValue; } @@ -791,9 +1176,18 @@ var Plottable; return formattedValue; }; }; + + /** + * Creates a formatter that displays exactly [precision] decimal places. + * + * @param {number} [precision] The number of decimal places to show (default 3). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter that displays exactly [precision] decimal places. + */ Formatters.fixed = function (precision, onlyShowUnchanged) { - if (precision === void 0) { precision = 3; } - if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } + if (typeof precision === "undefined") { precision = 3; } + if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } Formatters.verifyPrecision(precision); return function (d) { var formattedValue = d.toFixed(precision); @@ -803,9 +1197,19 @@ var Plottable; return formattedValue; }; }; + + /** + * Creates a formatter that formats numbers to show no more than + * [precision] decimal places. All other values are stringified. + * + * @param {number} [precision] The number of decimal places to show (default 3). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter for general values. + */ Formatters.general = function (precision, onlyShowUnchanged) { - if (precision === void 0) { precision = 3; } - if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } + if (typeof precision === "undefined") { precision = 3; } + if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } Formatters.verifyPrecision(precision); return function (d) { if (typeof d === "number") { @@ -815,20 +1219,35 @@ var Plottable; return ""; } return formattedValue; - } - else { + } else { return String(d); } }; }; + + /** + * Creates a formatter that stringifies its input. + * + * @returns {Formatter} A formatter that stringifies its input. + */ Formatters.identity = function () { return function (d) { return String(d); }; }; + + /** + * Creates a formatter for percentage values. + * Multiplies the input by 100 and appends "%". + * + * @param {number} [precision] The number of decimal places to show (default 0). + * @param {boolean} [onlyShowUnchanged] Whether to return a value if value changes after formatting (default true). + * + * @returns {Formatter} A formatter for percentage values. + */ Formatters.percentage = function (precision, onlyShowUnchanged) { - if (precision === void 0) { precision = 0; } - if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } + if (typeof precision === "undefined") { precision = 0; } + if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } var fixedFormatter = Formatters.fixed(precision); return function (d) { var formattedValue = fixedFormatter(d * 100); @@ -841,48 +1260,84 @@ var Plottable; return formattedValue; }; }; + + /** + * Creates a formatter for values that displays [precision] significant figures + * and puts SI notation. + * + * @param {number} [precision] The number of significant figures to show (default 3). + * + * @returns {Formatter} A formatter for SI values. + */ Formatters.siSuffix = function (precision) { - if (precision === void 0) { precision = 3; } + if (typeof precision === "undefined") { precision = 3; } Formatters.verifyPrecision(precision); return function (d) { return d3.format("." + precision + "s")(d); }; }; + + /** + * Creates a formatter that displays dates. + * + * @returns {Formatter} A formatter for time/date values. + */ Formatters.time = function () { var numFormats = 8; + + // these defaults were taken from d3 + // https://github.com/mbostock/d3/wiki/Time-Formatting#format_multi var timeFormat = {}; + timeFormat[0] = { format: ".%L", - filter: function (d) { return d.getMilliseconds() !== 0; } + filter: function (d) { + return d.getMilliseconds() !== 0; + } }; timeFormat[1] = { format: ":%S", - filter: function (d) { return d.getSeconds() !== 0; } + filter: function (d) { + return d.getSeconds() !== 0; + } }; timeFormat[2] = { format: "%I:%M", - filter: function (d) { return d.getMinutes() !== 0; } + filter: function (d) { + return d.getMinutes() !== 0; + } }; timeFormat[3] = { format: "%I %p", - filter: function (d) { return d.getHours() !== 0; } + filter: function (d) { + return d.getHours() !== 0; + } }; timeFormat[4] = { format: "%a %d", - filter: function (d) { return d.getDay() !== 0 && d.getDate() !== 1; } + filter: function (d) { + return d.getDay() !== 0 && d.getDate() !== 1; + } }; timeFormat[5] = { format: "%b %d", - filter: function (d) { return d.getDate() !== 1; } + filter: function (d) { + return d.getDate() !== 1; + } }; timeFormat[6] = { format: "%b", - filter: function (d) { return d.getMonth() !== 0; } + filter: function (d) { + return d.getMonth() !== 0; + } }; timeFormat[7] = { format: "%Y", - filter: function () { return true; } + filter: function () { + return true; + } }; + return function (d) { for (var i = 0; i < numFormats; i++) { if (timeFormat[i].filter(d)) { @@ -891,20 +1346,32 @@ var Plottable; } }; }; + + /** + * Creates a formatter for relative dates. + * + * @param {number} baseValue The start date (as epoch time) used in computing relative dates (default 0) + * @param {number} increment The unit used in calculating relative date values (default MILLISECONDS_IN_ONE_DAY) + * @param {string} label The label to append to the formatted string (default "") + * + * @returns {Formatter} A formatter for time/date values. + */ Formatters.relativeDate = function (baseValue, increment, label) { - if (baseValue === void 0) { baseValue = 0; } - if (increment === void 0) { increment = Plottable.MILLISECONDS_IN_ONE_DAY; } - if (label === void 0) { label = ""; } + if (typeof baseValue === "undefined") { baseValue = 0; } + if (typeof increment === "undefined") { increment = Plottable.MILLISECONDS_IN_ONE_DAY; } + if (typeof label === "undefined") { label = ""; } return function (d) { var relativeDate = Math.round((d.valueOf() - baseValue) / increment); return relativeDate.toString() + label; }; }; + Formatters.verifyPrecision = function (precision) { if (precision < 0 || precision > 20) { throw new RangeError("Formatter precision must be between 0 and 20"); } }; + Formatters._valueChanged = function (d, formattedValue) { return d !== parseFloat(formattedValue); }; @@ -913,11 +1380,13 @@ var Plottable; Plottable.Formatters = Formatters; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { - Plottable.version = "0.23.2"; + Plottable.version = "0.24.0"; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { @@ -934,6 +1403,7 @@ var Plottable; Colors.CERISE_RED = "#db2e65"; Colors.BRIGHT_SUN = "#ffe43d"; Colors.JACARTA = "#2c2b6f"; + Colors.PLOTTABLE_COLORS = [ Colors.CORAL_RED, Colors.INDIGO, @@ -953,6 +1423,7 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Abstract) { @@ -968,6 +1439,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -977,30 +1449,79 @@ var __extends = this.__extends || function (d, b) { var Plottable; (function (Plottable) { (function (Core) { + + + + + /** + * The Broadcaster class is owned by an IListenable. Third parties can register and deregister listeners + * from the broadcaster. When the broadcaster.broadcast method is activated, all registered callbacks are + * called. The registered callbacks are called with the registered Listenable that the broadcaster is attached + * to, along with optional arguments passed to the `broadcast` method. + * + * The listeners are called synchronously. + */ var Broadcaster = (function (_super) { __extends(Broadcaster, _super); + /** + * Construct a broadcaster, taking the Listenable that the broadcaster will be attached to. + * + * @constructor + * @param {IListenable} listenable The Listenable-object that this broadcaster is attached to. + */ function Broadcaster(listenable) { _super.call(this); this.key2callback = new Plottable.Util.StrictEqualityAssociativeArray(); this.listenable = listenable; } + /** + * Registers a callback to be called when the broadcast method is called. Also takes a key which + * is used to support deregistering the same callback later, by passing in the same key. + * If there is already a callback associated with that key, then the callback will be replaced. + * + * @param key The key associated with the callback. Key uniqueness is determined by deep equality. + * @param {IBroadcasterCallback} callback A callback to be called when the Scale's domain changes. + * @returns {Broadcaster} this object + */ Broadcaster.prototype.registerListener = function (key, callback) { this.key2callback.set(key, callback); return this; }; + + /** + * Call all listening callbacks, optionally with arguments passed through. + * + * @param ...args A variable number of optional arguments + * @returns {Broadcaster} this object + */ Broadcaster.prototype.broadcast = function () { var _this = this; var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + for (var _i = 0; _i < (arguments.length - 0); _i++) { + args[_i] = arguments[_i + 0]; } - this.key2callback.values().forEach(function (callback) { return callback(_this.listenable, args); }); + this.key2callback.values().forEach(function (callback) { + return callback(_this.listenable, args); + }); return this; }; + + /** + * Deregisters the callback associated with a key. + * + * @param key The key to deregister. + * @returns {Broadcaster} this object + */ Broadcaster.prototype.deregisterListener = function (key) { this.key2callback.delete(key); return this; }; + + /** + * Deregisters all listeners and callbacks associated with the broadcaster. + * + * @returns {Broadcaster} this object + */ Broadcaster.prototype.deregisterAllListeners = function () { this.key2callback = new Plottable.Util.StrictEqualityAssociativeArray(); }; @@ -1011,6 +1532,7 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1021,9 +1543,16 @@ var Plottable; (function (Plottable) { var DataSource = (function (_super) { __extends(DataSource, _super); + /** + * Creates a new DataSource. + * + * @constructor + * @param {any[]} data + * @param {any} metadata An object containing additional information. + */ function DataSource(data, metadata) { - if (data === void 0) { data = []; } - if (metadata === void 0) { metadata = {}; } + if (typeof data === "undefined") { data = []; } + if (typeof metadata === "undefined") { metadata = {}; } _super.call(this); this.broadcaster = new Plottable.Core.Broadcaster(this); this._data = data; @@ -1033,25 +1562,25 @@ var Plottable; DataSource.prototype.data = function (data) { if (data == null) { return this._data; - } - else { + } else { this._data = data; this.accessor2cachedExtent = new Plottable.Util.StrictEqualityAssociativeArray(); this.broadcaster.broadcast(); return this; } }; + DataSource.prototype.metadata = function (metadata) { if (metadata == null) { return this._metadata; - } - else { + } else { this._metadata = metadata; this.accessor2cachedExtent = new Plottable.Util.StrictEqualityAssociativeArray(); this.broadcaster.broadcast(); return this; } }; + DataSource.prototype._getExtent = function (accessor) { var cachedExtent = this.accessor2cachedExtent.get(accessor); if (cachedExtent === undefined) { @@ -1060,20 +1589,18 @@ var Plottable; } return cachedExtent; }; + DataSource.prototype.computeExtent = function (accessor) { var mappedData = this._data.map(accessor); if (mappedData.length === 0) { return []; - } - else if (typeof (mappedData[0]) === "string") { + } else if (typeof (mappedData[0]) === "string") { return Plottable.Util.Methods.uniq(mappedData); - } - else { + } else { var extent = d3.extent(mappedData); if (extent[0] == null || extent[1] == null) { return []; - } - else { + } else { return extent; } } @@ -1083,6 +1610,7 @@ var Plottable; Plottable.DataSource = DataSource; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1111,25 +1639,41 @@ var Plottable; this._isAnchored = false; this.removed = false; } + /** + * Attaches the Component as a child of a given a DOM element. Usually only directly invoked on root-level Components. + * + * @param {D3.Selection} element A D3 selection consisting of the element to anchor under. + */ Component.prototype._anchor = function (element) { if (this.removed) { throw new Error("Can't reuse remove()-ed components!"); } + if (element.node().nodeName === "svg") { + // svg node gets the "plottable" CSS class this.rootSVG = element; this.rootSVG.classed("plottable", true); + + // visible overflow for firefox https://stackoverflow.com/questions/5926986/why-does-firefox-appear-to-truncate-embedded-svgs this.rootSVG.style("overflow", "visible"); this.isTopLevelComponent = true; } + if (this.element != null) { + // reattach existing element element.node().appendChild(this.element.node()); - } - else { + } else { this.element = element.append("g"); this._setup(); } this._isAnchored = true; }; + + /** + * Creates additional elements as necessary for the Component to function. + * Called during _anchor() if the Component's element has not been created yet. + * Override in subclasses to provide additional functionality. + */ Component.prototype._setup = function () { var _this = this; if (this._isSetup) { @@ -1139,45 +1683,67 @@ var Plottable; _this.element.classed(cssClass, true); }); this.cssClasses = null; + this.backgroundContainer = this.element.append("g").classed("background-container", true); this.content = this.element.append("g").classed("content", true); this.foregroundContainer = this.element.append("g").classed("foreground-container", true); this.boxContainer = this.element.append("g").classed("box-container", true); + if (this.clipPathEnabled) { this.generateClipPath(); } ; + this.addBox("bounding-box"); - this.interactionsToRegister.forEach(function (r) { return _this.registerInteraction(r); }); + + this.interactionsToRegister.forEach(function (r) { + return _this.registerInteraction(r); + }); this.interactionsToRegister = null; if (this.isTopLevelComponent) { this.autoResize(Component.AUTORESIZE_BY_DEFAULT); } this._isSetup = true; }; + Component.prototype._requestedSpace = function (availableWidth, availableHeight) { return { width: 0, height: 0, wantsWidth: false, wantsHeight: false }; }; + + /** + * Computes the size, position, and alignment from the specified values. + * If no parameters are supplied and the component is a root node, + * they are inferred from the size of the component's element. + * + * @param {number} xOrigin + * @param {number} yOrigin + * @param {number} availableWidth + * @param {number} availableHeight + */ Component.prototype._computeLayout = function (xOrigin, yOrigin, availableWidth, availableHeight) { var _this = this; if (xOrigin == null || yOrigin == null || availableWidth == null || availableHeight == null) { if (this.element == null) { throw new Error("anchor must be called before computeLayout"); - } - else if (this.isTopLevelComponent) { + } else if (this.isTopLevelComponent) { + // we are the root node, retrieve height/width from root SVG xOrigin = 0; yOrigin = 0; + + // Set width/height to 100% if not specified, to allow accurate size calculation + // see http://www.w3.org/TR/CSS21/visudet.html#block-replaced-width + // and http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-height if (this.rootSVG.attr("width") == null) { this.rootSVG.attr("width", "100%"); } if (this.rootSVG.attr("height") == null) { this.rootSVG.attr("height", "100%"); } + var elem = this.rootSVG.node(); availableWidth = Plottable.Util.DOM.getElementWidth(elem); availableHeight = Plottable.Util.DOM.getElementHeight(elem); - } - else { + } else { throw new Error("null arguments cannot be passed to _computeLayout() on a non-root node"); } } @@ -1185,51 +1751,71 @@ var Plottable; this.yOrigin = yOrigin; var xPosition = this.xOrigin; var yPosition = this.yOrigin; + var requestedSpace = this._requestedSpace(availableWidth, availableHeight); + xPosition += (availableWidth - requestedSpace.width) * this._xAlignProportion; xPosition += this._xOffset; if (this._isFixedWidth()) { + // Decrease size so hitbox / bounding box and children are sized correctly availableWidth = Math.min(availableWidth, requestedSpace.width); } + yPosition += (availableHeight - requestedSpace.height) * this._yAlignProportion; yPosition += this._yOffset; if (this._isFixedHeight()) { availableHeight = Math.min(availableHeight, requestedSpace.height); } + this.availableWidth = availableWidth; this.availableHeight = availableHeight; this.element.attr("transform", "translate(" + xPosition + "," + yPosition + ")"); - this.boxes.forEach(function (b) { return b.attr("width", _this.availableWidth).attr("height", _this.availableHeight); }); + this.boxes.forEach(function (b) { + return b.attr("width", _this.availableWidth).attr("height", _this.availableHeight); + }); }; + + /** + * Renders the component. + */ Component.prototype._render = function () { if (this._isAnchored && this._isSetup) { Plottable.Core.RenderController.registerToRender(this); } }; + Component.prototype._scheduleComputeLayout = function () { if (this._isAnchored && this._isSetup) { Plottable.Core.RenderController.registerToComputeLayout(this); } }; + Component.prototype._doRender = function () { + //no-op }; + Component.prototype._invalidateLayout = function () { if (this._isAnchored && this._isSetup) { if (this.isTopLevelComponent) { this._scheduleComputeLayout(); - } - else { + } else { this._parent._invalidateLayout(); } } }; + + /** + * Renders the Component into a given DOM element. + * + * @param {String|D3.Selection} element A D3 selection or a selector for getting the element to render into. + * @return {Component} The calling component. + */ Component.prototype.renderTo = function (element) { if (element != null) { var selection; if (typeof (element.node) === "function") { selection = element; - } - else { + } else { selection = d3.select(element); } this._anchor(selection); @@ -1238,6 +1824,13 @@ var Plottable; this._render(); return this; }; + + /** + * Cause the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. + * + * @param {number} [availableWidth] - the width of the container element + * @param {number} [availableHeight] - the height of the container element + */ Component.prototype.resize = function (width, height) { if (!this.isTopLevelComponent) { throw new Error("Cannot resize on non top-level component"); @@ -1248,59 +1841,91 @@ var Plottable; this._invalidateLayout(); return this; }; + + /** + * Enables and disables auto-resize. + * + * If enabled, window resizes will enqueue this component for a re-layout + * and re-render. Animations are disabled during window resizes when auto- + * resize is enabled. + * + * @param {boolean} flag - Enables (true) or disables (false) auto-resize. + */ Component.prototype.autoResize = function (flag) { if (flag) { Plottable.Core.ResizeBroadcaster.register(this); - } - else { + } else { Plottable.Core.ResizeBroadcaster.deregister(this); } return this; }; + + /** + * Sets the x alignment of the Component. + * + * @param {string} alignment The x alignment of the Component (one of LEFT/CENTER/RIGHT). + * @returns {Component} The calling Component. + */ Component.prototype.xAlign = function (alignment) { alignment = alignment.toLowerCase(); if (alignment === "left") { this._xAlignProportion = 0; - } - else if (alignment === "center") { + } else if (alignment === "center") { this._xAlignProportion = 0.5; - } - else if (alignment === "right") { + } else if (alignment === "right") { this._xAlignProportion = 1; - } - else { + } else { throw new Error("Unsupported alignment"); } this._invalidateLayout(); return this; }; + + /** + * Sets the y alignment of the Component. + * + * @param {string} alignment The y alignment of the Component (one of TOP/CENTER/BOTTOM). + * @returns {Component} The calling Component. + */ Component.prototype.yAlign = function (alignment) { alignment = alignment.toLowerCase(); if (alignment === "top") { this._yAlignProportion = 0; - } - else if (alignment === "center") { + } else if (alignment === "center") { this._yAlignProportion = 0.5; - } - else if (alignment === "bottom") { + } else if (alignment === "bottom") { this._yAlignProportion = 1; - } - else { + } else { throw new Error("Unsupported alignment"); } this._invalidateLayout(); return this; }; + + /** + * Sets the x offset of the Component. + * + * @param {number} offset The desired x offset, in pixels. + * @returns {Component} The calling Component. + */ Component.prototype.xOffset = function (offset) { this._xOffset = offset; this._invalidateLayout(); return this; }; + + /** + * Sets the y offset of the Component. + * + * @param {number} offset The desired y offset, in pixels. + * @returns {Component} The calling Component. + */ Component.prototype.yOffset = function (offset) { this._yOffset = offset; this._invalidateLayout(); return this; }; + Component.prototype.addBox = function (className, parentElement) { if (this.element == null) { throw new Error("Adding boxes before anchoring is currently disallowed"); @@ -1317,37 +1942,46 @@ var Plottable; } return box; }; + Component.prototype.generateClipPath = function () { + // The clip path will prevent content from overflowing its component space. this.element.attr("clip-path", "url(#clipPath" + this._plottableID + ")"); var clipPathParent = this.boxContainer.append("clipPath").attr("id", "clipPath" + this._plottableID); this.addBox("clip-rect", clipPathParent); }; + + /** + * Attaches an Interaction to the Component, so that the Interaction will listen for events on the Component. + * + * @param {Interaction} interaction The Interaction to attach to the Component. + * @return {Component} The calling Component. + */ Component.prototype.registerInteraction = function (interaction) { + // Interactions can be registered before or after anchoring. If registered before, they are + // pushed to this.interactionsToRegister and registered during anchoring. If after, they are + // registered immediately if (this.element != null) { if (this.hitBox == null) { this.hitBox = this.addBox("hit-box"); - this.hitBox.style("fill", "#ffffff").style("opacity", 0); + this.hitBox.style("fill", "#ffffff").style("opacity", 0); // We need to set these so Chrome will register events } interaction._anchor(this.hitBox); - } - else { + } else { this.interactionsToRegister.push(interaction); } return this; }; + Component.prototype.classed = function (cssClass, addClass) { if (addClass == null) { if (cssClass == null) { return false; - } - else if (this.element == null) { + } else if (this.element == null) { return (this.cssClasses.indexOf(cssClass) !== -1); - } - else { + } else { return this.element.classed(cssClass); } - } - else { + } else { if (cssClass == null) { return this; } @@ -1355,23 +1989,47 @@ var Plottable; var classIndex = this.cssClasses.indexOf(cssClass); if (addClass && classIndex === -1) { this.cssClasses.push(cssClass); - } - else if (!addClass && classIndex !== -1) { + } else if (!addClass && classIndex !== -1) { this.cssClasses.splice(classIndex, 1); } - } - else { + } else { this.element.classed(cssClass, addClass); } return this; } }; + + /** + * Checks if the Component has a fixed width or false if it grows to fill available space. + * Returns false by default on the base Component class. + * + * @return {boolean} Whether the component has a fixed width. + */ Component.prototype._isFixedWidth = function () { return this._fixedWidthFlag; }; + + /** + * Checks if the Component has a fixed height or false if it grows to fill available space. + * Returns false by default on the base Component class. + * + * @return {boolean} Whether the component has a fixed height. + */ Component.prototype._isFixedHeight = function () { return this._fixedHeightFlag; }; + + /** + * Merges this Component with another Component, returning a ComponentGroup. + * There are four cases: + * Component + Component: Returns a ComponentGroup with both components inside it. + * ComponentGroup + Component: Returns the ComponentGroup with the Component appended. + * Component + ComponentGroup: Returns the ComponentGroup with the Component prepended. + * ComponentGroup + ComponentGroup: Returns a new ComponentGroup with two ComponentGroups inside it. + * + * @param {Component} c The component to merge in. + * @return {ComponentGroup} + */ Component.prototype.merge = function (c) { var cg; if (this._isSetup || this._isAnchored) { @@ -1381,12 +2039,17 @@ var Plottable; cg = c; cg._addComponent(this, true); return cg; - } - else { + } else { cg = new Plottable.Component.Group([this, c]); return cg; } }; + + /** + * Detaches a Component from the DOM. The component can be reused. + * + * @returns The calling Component. + */ Component.prototype.detach = function () { if (this._isAnchored) { this.element.remove(); @@ -1398,6 +2061,11 @@ var Plottable; this._parent = null; return this; }; + + /** + * Removes a Component from the DOM and disconnects it from everything it's + * listening to (effectively destroying it). + */ Component.prototype.remove = function () { this.removed = true; this.detach(); @@ -1411,6 +2079,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1424,16 +2093,26 @@ var Plottable; __extends(ComponentContainer, _super); function ComponentContainer() { _super.apply(this, arguments); + /* + * An abstract ComponentContainer class to encapsulate Table and ComponentGroup's shared functionality. + * It will not do anything if instantiated directly. + */ this._components = []; } ComponentContainer.prototype._anchor = function (element) { var _this = this; _super.prototype._anchor.call(this, element); - this._components.forEach(function (c) { return c._anchor(_this.content); }); + this._components.forEach(function (c) { + return c._anchor(_this.content); + }); }; + ComponentContainer.prototype._render = function () { - this._components.forEach(function (c) { return c._render(); }); + this._components.forEach(function (c) { + return c._render(); + }); }; + ComponentContainer.prototype._removeComponent = function (c) { var removeIndex = this._components.indexOf(c); if (removeIndex >= 0) { @@ -1441,15 +2120,16 @@ var Plottable; this._invalidateLayout(); } }; + ComponentContainer.prototype._addComponent = function (c, prepend) { - if (prepend === void 0) { prepend = false; } + if (typeof prepend === "undefined") { prepend = false; } if (c == null || this._components.indexOf(c) >= 0) { return false; } + if (prepend) { this._components.unshift(c); - } - else { + } else { this._components.push(c); } c._parent = this; @@ -1459,19 +2139,45 @@ var Plottable; this._invalidateLayout(); return true; }; + + /** + * Returns a list of components in the ComponentContainer + * + * @returns{Component[]} the contained Components + */ ComponentContainer.prototype.components = function () { return this._components.slice(); }; + + /** + * Returns true iff the ComponentContainer is empty. + * + * @returns {boolean} Whether the calling ComponentContainer is empty. + */ ComponentContainer.prototype.empty = function () { return this._components.length === 0; }; + + /** + * Detaches all components contained in the ComponentContainer, and + * empties the ComponentContainer. + * + * @returns {ComponentContainer} The calling ComponentContainer + */ ComponentContainer.prototype.detachAll = function () { - this._components.slice().forEach(function (c) { return c.detach(); }); + // Calling c.remove() will mutate this._components because the component will call this._parent._removeComponent(this) + // Since mutating an array while iterating over it is dangerous, we instead iterate over a copy generated by Arr.slice() + this._components.slice().forEach(function (c) { + return c.detach(); + }); return this; }; + ComponentContainer.prototype.remove = function () { _super.prototype.remove.call(this); - this._components.slice().forEach(function (c) { return c.remove(); }); + this._components.slice().forEach(function (c) { + return c.remove(); + }); }; return ComponentContainer; })(Abstract.Component); @@ -1480,6 +2186,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1491,27 +2198,51 @@ var Plottable; (function (Component) { var Group = (function (_super) { __extends(Group, _super); + /** + * Creates a ComponentGroup. + * + * @constructor + * @param {Component[]} [components] The Components in the Group. + */ function Group(components) { - if (components === void 0) { components = []; } - _super.call(this); + if (typeof components === "undefined") { components = []; } var _this = this; + _super.call(this); this.classed("component-group", true); - components.forEach(function (c) { return _this._addComponent(c); }); + components.forEach(function (c) { + return _this._addComponent(c); + }); } Group.prototype._requestedSpace = function (offeredWidth, offeredHeight) { - var requests = this._components.map(function (c) { return c._requestedSpace(offeredWidth, offeredHeight); }); + var requests = this._components.map(function (c) { + return c._requestedSpace(offeredWidth, offeredHeight); + }); var isEmpty = this.empty(); return { - width: isEmpty ? 0 : d3.max(requests, function (request) { return request.width; }), - height: isEmpty ? 0 : d3.max(requests, function (request) { return request.height; }), - wantsWidth: isEmpty ? false : requests.map(function (r) { return r.wantsWidth; }).some(function (x) { return x; }), - wantsHeight: isEmpty ? false : requests.map(function (r) { return r.wantsHeight; }).some(function (x) { return x; }) + width: isEmpty ? 0 : d3.max(requests, function (request) { + return request.width; + }), + height: isEmpty ? 0 : d3.max(requests, function (request) { + return request.height; + }), + wantsWidth: isEmpty ? false : requests.map(function (r) { + return r.wantsWidth; + }).some(function (x) { + return x; + }), + wantsHeight: isEmpty ? false : requests.map(function (r) { + return r.wantsHeight; + }).some(function (x) { + return x; + }) }; }; + Group.prototype.merge = function (c) { this._addComponent(c); return this; }; + Group.prototype._computeLayout = function (xOrigin, yOrigin, availableWidth, availableHeight) { var _this = this; _super.prototype._computeLayout.call(this, xOrigin, yOrigin, availableWidth, availableHeight); @@ -1520,11 +2251,17 @@ var Plottable; }); return this; }; + Group.prototype._isFixedWidth = function () { - return this._components.every(function (c) { return c._isFixedWidth(); }); + return this._components.every(function (c) { + return c._isFixedWidth(); + }); }; + Group.prototype._isFixedHeight = function () { - return this._components.every(function (c) { return c._isFixedHeight(); }); + return this._components.every(function (c) { + return c._isFixedHeight(); + }); }; return Group; })(Plottable.Abstract.ComponentContainer); @@ -1533,6 +2270,7 @@ var Plottable; var Component = Plottable.Component; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1543,12 +2281,20 @@ var Plottable; (function (Plottable) { (function (Component) { ; + var Table = (function (_super) { __extends(Table, _super); + /** + * Creates a Table. + * + * @constructor + * @param {Component[][]} [rows] A 2-D array of the Components to place in the table. + * null can be used if a cell is empty. + */ function Table(rows) { - if (rows === void 0) { rows = []; } - _super.call(this); + if (typeof rows === "undefined") { rows = []; } var _this = this; + _super.call(this); this.rowPadding = 0; this.colPadding = 0; this.rows = []; @@ -1563,24 +2309,35 @@ var Plottable; }); }); } + /** + * Adds a Component in the specified cell. + * + * @param {number} row The row in which to add the Component. + * @param {number} col The column in which to add the Component. + * @param {Component} component The Component to be added. + */ Table.prototype.addComponent = function (row, col, component) { if (this._addComponent(component)) { this.nRows = Math.max(row + 1, this.nRows); this.nCols = Math.max(col + 1, this.nCols); this.padTableToSize(this.nRows, this.nCols); + var currentComponent = this.rows[row][col]; if (currentComponent != null) { throw new Error("Table.addComponent cannot be called on a cell where a component already exists (for the moment)"); } + this.rows[row][col] = component; } return this; }; + Table.prototype._removeComponent = function (component) { _super.prototype._removeComponent.call(this, component); var rowpos; var colpos; - outer: for (var i = 0; i < this.nRows; i++) { + outer: + for (var i = 0; i < this.nRows; i++) { for (var j = 0; j < this.nCols; j++) { if (this.rows[i][j] === component) { rowpos = i; @@ -1589,24 +2346,63 @@ var Plottable; } } } + if (rowpos !== undefined) { this.rows[rowpos][colpos] = null; } }; + Table.prototype.iterateLayout = function (availableWidth, availableHeight) { + /* + * Given availableWidth and availableHeight, figure out how to allocate it between rows and columns using an iterative algorithm. + * + * For both dimensions, keeps track of "guaranteedSpace", which the fixed-size components have requested, and + * "proportionalSpace", which is being given to proportionally-growing components according to the weights on the table. + * Here is how it works (example uses width but it is the same for height). First, columns are guaranteed no width, and + * the free width is allocated to columns based on their colWeights. Then, in determineGuarantees, every component is + * offered its column's width and may request some amount of it, which increases that column's guaranteed + * width. If there are some components that were not satisfied with the width they were offered, and there is free + * width that has not already been guaranteed, then the remaining width is allocated to the unsatisfied columns and the + * algorithm runs again. If all components are satisfied, then the remaining width is allocated as proportional space + * according to the colWeights. + * + * The guaranteed width for each column is monotonically increasing as the algorithm iterates. Since it is deterministic + * and monotonically increasing, if the freeWidth does not change during an iteration it implies that no further progress + * is possible, so the algorithm will not continue iterating on that dimension's account. + * + * If the algorithm runs more than 5 times, we stop and just use whatever we arrived at. It's not clear under what + * circumstances this will happen or if it will happen at all. A message will be printed to the console if this occurs. + * + */ var cols = d3.transpose(this.rows); var availableWidthAfterPadding = availableWidth - this.colPadding * (this.nCols - 1); var availableHeightAfterPadding = availableHeight - this.rowPadding * (this.nRows - 1); - var rowWeights = Table.calcComponentWeights(this.rowWeights, this.rows, function (c) { return (c == null) || c._isFixedHeight(); }); - var colWeights = Table.calcComponentWeights(this.colWeights, cols, function (c) { return (c == null) || c._isFixedWidth(); }); - var heuristicColWeights = colWeights.map(function (c) { return c === 0 ? 0.5 : c; }); - var heuristicRowWeights = rowWeights.map(function (c) { return c === 0 ? 0.5 : c; }); + + var rowWeights = Table.calcComponentWeights(this.rowWeights, this.rows, function (c) { + return (c == null) || c._isFixedHeight(); + }); + var colWeights = Table.calcComponentWeights(this.colWeights, cols, function (c) { + return (c == null) || c._isFixedWidth(); + }); + + // To give the table a good starting position to iterate from, we give the fixed-width components half-weight + // so that they will get some initial space allocated to work with + var heuristicColWeights = colWeights.map(function (c) { + return c === 0 ? 0.5 : c; + }); + var heuristicRowWeights = rowWeights.map(function (c) { + return c === 0 ? 0.5 : c; + }); + var colProportionalSpace = Table.calcProportionalSpace(heuristicColWeights, availableWidthAfterPadding); var rowProportionalSpace = Table.calcProportionalSpace(heuristicRowWeights, availableHeightAfterPadding); + var guaranteedWidths = Plottable.Util.Methods.createFilledArray(0, this.nCols); var guaranteedHeights = Plottable.Util.Methods.createFilledArray(0, this.nRows); + var freeWidth; var freeHeight; + var nIterations = 0; while (true) { var offeredHeights = Plottable.Util.Methods.addArrays(guaranteedHeights, rowProportionalSpace); @@ -1614,46 +2410,68 @@ var Plottable; var guarantees = this.determineGuarantees(offeredWidths, offeredHeights); guaranteedWidths = guarantees.guaranteedWidths; guaranteedHeights = guarantees.guaranteedHeights; - var wantsWidth = guarantees.wantsWidthArr.some(function (x) { return x; }); - var wantsHeight = guarantees.wantsHeightArr.some(function (x) { return x; }); + var wantsWidth = guarantees.wantsWidthArr.some(function (x) { + return x; + }); + var wantsHeight = guarantees.wantsHeightArr.some(function (x) { + return x; + }); + var lastFreeWidth = freeWidth; var lastFreeHeight = freeHeight; freeWidth = availableWidthAfterPadding - d3.sum(guarantees.guaranteedWidths); freeHeight = availableHeightAfterPadding - d3.sum(guarantees.guaranteedHeights); var xWeights; if (wantsWidth) { - xWeights = guarantees.wantsWidthArr.map(function (x) { return x ? 0.1 : 0; }); + xWeights = guarantees.wantsWidthArr.map(function (x) { + return x ? 0.1 : 0; + }); xWeights = Plottable.Util.Methods.addArrays(xWeights, colWeights); - } - else { + } else { xWeights = colWeights; } + var yWeights; if (wantsHeight) { - yWeights = guarantees.wantsHeightArr.map(function (x) { return x ? 0.1 : 0; }); + yWeights = guarantees.wantsHeightArr.map(function (x) { + return x ? 0.1 : 0; + }); yWeights = Plottable.Util.Methods.addArrays(yWeights, rowWeights); - } - else { + } else { yWeights = rowWeights; } + colProportionalSpace = Table.calcProportionalSpace(xWeights, freeWidth); rowProportionalSpace = Table.calcProportionalSpace(yWeights, freeHeight); nIterations++; + var canImproveWidthAllocation = freeWidth > 0 && wantsWidth && freeWidth !== lastFreeWidth; var canImproveHeightAllocation = freeHeight > 0 && wantsHeight && freeHeight !== lastFreeHeight; + if (!(canImproveWidthAllocation || canImproveHeightAllocation)) { break; } + if (nIterations > 5) { break; } } + + // Redo the proportional space one last time, to ensure we use the real weights not the wantsWidth/Height weights freeWidth = availableWidthAfterPadding - d3.sum(guarantees.guaranteedWidths); freeHeight = availableHeightAfterPadding - d3.sum(guarantees.guaranteedHeights); colProportionalSpace = Table.calcProportionalSpace(colWeights, freeWidth); rowProportionalSpace = Table.calcProportionalSpace(rowWeights, freeHeight); - return { colProportionalSpace: colProportionalSpace, rowProportionalSpace: rowProportionalSpace, guaranteedWidths: guarantees.guaranteedWidths, guaranteedHeights: guarantees.guaranteedHeights, wantsWidth: wantsWidth, wantsHeight: wantsHeight }; + + return { + colProportionalSpace: colProportionalSpace, + rowProportionalSpace: rowProportionalSpace, + guaranteedWidths: guarantees.guaranteedWidths, + guaranteedHeights: guarantees.guaranteedHeights, + wantsWidth: wantsWidth, + wantsHeight: wantsHeight }; }; + Table.prototype.determineGuarantees = function (offeredWidths, offeredHeights) { var requestedWidths = Plottable.Util.Methods.createFilledArray(0, this.nCols); var requestedHeights = Plottable.Util.Methods.createFilledArray(0, this.nRows); @@ -1664,35 +2482,51 @@ var Plottable; var spaceRequest; if (component != null) { spaceRequest = component._requestedSpace(offeredWidths[colIndex], offeredHeights[rowIndex]); - } - else { + } else { spaceRequest = { width: 0, height: 0, wantsWidth: false, wantsHeight: false }; } + var allocatedWidth = Math.min(spaceRequest.width, offeredWidths[colIndex]); var allocatedHeight = Math.min(spaceRequest.height, offeredHeights[rowIndex]); + requestedWidths[colIndex] = Math.max(requestedWidths[colIndex], allocatedWidth); requestedHeights[rowIndex] = Math.max(requestedHeights[rowIndex], allocatedHeight); layoutWantsWidth[colIndex] = layoutWantsWidth[colIndex] || spaceRequest.wantsWidth; layoutWantsHeight[rowIndex] = layoutWantsHeight[rowIndex] || spaceRequest.wantsHeight; }); }); - return { guaranteedWidths: requestedWidths, guaranteedHeights: requestedHeights, wantsWidthArr: layoutWantsWidth, wantsHeightArr: layoutWantsHeight }; + return { + guaranteedWidths: requestedWidths, + guaranteedHeights: requestedHeights, + wantsWidthArr: layoutWantsWidth, + wantsHeightArr: layoutWantsHeight }; }; + Table.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var layout = this.iterateLayout(offeredWidth, offeredHeight); - return { width: d3.sum(layout.guaranteedWidths), height: d3.sum(layout.guaranteedHeights), wantsWidth: layout.wantsWidth, wantsHeight: layout.wantsHeight }; + return { + width: d3.sum(layout.guaranteedWidths), + height: d3.sum(layout.guaranteedHeights), + wantsWidth: layout.wantsWidth, + wantsHeight: layout.wantsHeight }; }; + + // xOffset is relative to parent element, not absolute Table.prototype._computeLayout = function (xOffset, yOffset, availableWidth, availableHeight) { var _this = this; _super.prototype._computeLayout.call(this, xOffset, yOffset, availableWidth, availableHeight); var layout = this.iterateLayout(this.availableWidth, this.availableHeight); - var sumPair = function (p) { return p[0] + p[1]; }; + + var sumPair = function (p) { + return p[0] + p[1]; + }; var rowHeights = Plottable.Util.Methods.addArrays(layout.rowProportionalSpace, layout.guaranteedHeights); var colWidths = Plottable.Util.Methods.addArrays(layout.colProportionalSpace, layout.guaranteedWidths); var childYOffset = 0; this.rows.forEach(function (row, rowIndex) { var childXOffset = 0; row.forEach(function (component, colIndex) { + // recursively compute layout if (component != null) { component._computeLayout(childXOffset, childYOffset, colWidths[colIndex], rowHeights[rowIndex]); } @@ -1701,29 +2535,62 @@ var Plottable; childYOffset += rowHeights[rowIndex] + _this.rowPadding; }); }; + + /** + * Sets the row and column padding on the Table. + * + * @param {number} rowPadding The padding above and below each row, in pixels. + * @param {number} colPadding the padding to the left and right of each column, in pixels. + * @returns {Table} The calling Table. + */ Table.prototype.padding = function (rowPadding, colPadding) { this.rowPadding = rowPadding; this.colPadding = colPadding; this._invalidateLayout(); return this; }; + + /** + * Sets the layout weight of a particular row. + * Space is allocated to rows based on their weight. Rows with higher weights receive proportionally more space. + * + * @param {number} index The index of the row. + * @param {number} weight The weight to be set on the row. + * @returns {Table} The calling Table. + */ Table.prototype.rowWeight = function (index, weight) { this.rowWeights[index] = weight; this._invalidateLayout(); return this; }; + + /** + * Sets the layout weight of a particular column. + * Space is allocated to columns based on their weight. Columns with higher weights receive proportionally more space. + * + * @param {number} index The index of the column. + * @param {number} weight The weight to be set on the column. + * @returns {Table} The calling Table. + */ Table.prototype.colWeight = function (index, weight) { this.colWeights[index] = weight; this._invalidateLayout(); return this; }; + Table.prototype._isFixedWidth = function () { var cols = d3.transpose(this.rows); - return Table.fixedSpace(cols, function (c) { return (c == null) || c._isFixedWidth(); }); + return Table.fixedSpace(cols, function (c) { + return (c == null) || c._isFixedWidth(); + }); }; + Table.prototype._isFixedHeight = function () { - return Table.fixedSpace(this.rows, function (c) { return (c == null) || c._isFixedHeight(); }); + return Table.fixedSpace(this.rows, function (c) { + return (c == null) || c._isFixedHeight(); + }); }; + Table.prototype.padTableToSize = function (nRows, nCols) { for (var i = 0; i < nRows; i++) { if (this.rows[i] === undefined) { @@ -1742,28 +2609,43 @@ var Plottable; } } }; + Table.calcComponentWeights = function (setWeights, componentGroups, fixityAccessor) { + // If the row/col weight was explicitly set, then return it outright + // If the weight was not explicitly set, then guess it using the heuristic that if all components are fixed-space + // then weight is 0, otherwise weight is 1 return setWeights.map(function (w, i) { if (w != null) { return w; } var fixities = componentGroups[i].map(fixityAccessor); - var allFixed = fixities.reduce(function (a, b) { return a && b; }, true); + var allFixed = fixities.reduce(function (a, b) { + return a && b; + }, true); return allFixed ? 0 : 1; }); }; + Table.calcProportionalSpace = function (weights, freeSpace) { var weightSum = d3.sum(weights); if (weightSum === 0) { return Plottable.Util.Methods.createFilledArray(0, weights.length); - } - else { - return weights.map(function (w) { return freeSpace * w / weightSum; }); + } else { + return weights.map(function (w) { + return freeSpace * w / weightSum; + }); } }; + Table.fixedSpace = function (componentGroup, fixityAccessor) { - var all = function (bools) { return bools.reduce(function (a, b) { return a && b; }, true); }; - var group_isFixed = function (components) { return all(components.map(fixityAccessor)); }; + var all = function (bools) { + return bools.reduce(function (a, b) { + return a && b; + }, true); + }; + var group_isFixed = function (components) { + return all(components.map(fixityAccessor)); + }; return all(componentGroup.map(group_isFixed)); }; return Table; @@ -1773,6 +2655,7 @@ var Plottable; var Component = Plottable.Component; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1784,6 +2667,12 @@ var Plottable; (function (Abstract) { var Scale = (function (_super) { __extends(Scale, _super); + /** + * Creates a new Scale. + * + * @constructor + * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. + */ function Scale(scale) { _super.call(this); this.autoDomainAutomatically = true; @@ -1794,56 +2683,93 @@ var Plottable; Scale.prototype._getAllExtents = function () { return d3.values(this._rendererAttrID2Extent); }; + Scale.prototype._getExtent = function () { return []; }; + + /** + * Modify the domain on the scale so that it includes the extent of all + * perspectives it depends on. Extent: The (min, max) pair for a + * QuantitiativeScale, all covered strings for an OrdinalScale. + * Perspective: A combination of a DataSource and an Accessor that + * represents a view in to the data. + */ Scale.prototype.autoDomain = function () { this.autoDomainAutomatically = true; this._setDomain(this._getExtent()); return this; }; + Scale.prototype._autoDomainIfAutomaticMode = function () { if (this.autoDomainAutomatically) { this.autoDomain(); } }; + + /** + * Returns the range value corresponding to a given domain value. + * + * @param value {any} A domain value to be scaled. + * @returns {any} The range value corresponding to the supplied domain value. + */ Scale.prototype.scale = function (value) { return this._d3Scale(value); }; + Scale.prototype.domain = function (values) { if (values == null) { return this._getDomain(); - } - else { + } else { this.autoDomainAutomatically = false; this._setDomain(values); return this; } }; + Scale.prototype._getDomain = function () { return this._d3Scale.domain(); }; + Scale.prototype._setDomain = function (values) { this._d3Scale.domain(values); this.broadcaster.broadcast(); }; + Scale.prototype.range = function (values) { if (values == null) { return this._d3Scale.range(); - } - else { + } else { this._d3Scale.range(values); return this; } }; + + /** + * Creates a copy of the Scale with the same domain and range but without any registered listeners. + * + * @returns {Scale} A copy of the calling Scale. + */ Scale.prototype.copy = function () { return new Scale(this._d3Scale.copy()); }; + + /** + * When a renderer determines that the extent of a projector has changed, + * it will call this function. This function should ensure that + * the scale has a domain at least large enough to include extent. + * + * @param {number} rendererID A unique indentifier of the renderer sending + * the new extent. + * @param {string} attr The attribute being projected, e.g. "x", "y0", "r" + * @param {any[]} extent The new extent to be included in the scale. + */ Scale.prototype.updateExtent = function (rendererID, attr, extent) { this._rendererAttrID2Extent[rendererID + attr] = extent; this._autoDomainIfAutomaticMode(); return this; }; + Scale.prototype.removeExtent = function (rendererID, attr) { delete this._rendererAttrID2Extent[rendererID + attr]; this._autoDomainIfAutomaticMode(); @@ -1856,6 +2782,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -1877,16 +2804,15 @@ var Plottable; this.animateOnNextRender = true; this.clipPathEnabled = true; this.classed("plot", true); + var dataSource; if (dataset != null) { if (typeof dataset.data === "function") { dataSource = dataset; - } - else { + } else { dataSource = dataSource = new Plottable.DataSource(dataset); } - } - else { + } else { dataSource = new Plottable.DataSource(); } this.dataSource(dataSource); @@ -1897,10 +2823,13 @@ var Plottable; this._dataChanged = true; this.updateAllProjectors(); }; + Plot.prototype.remove = function () { var _this = this; _super.prototype.remove.call(this); this._dataSource.broadcaster.deregisterListener(this); + + // deregister from all scales var properties = Object.keys(this._projectors); properties.forEach(function (property) { var projector = _this._projectors[property]; @@ -1909,6 +2838,7 @@ var Plottable; } }); }; + Plot.prototype.dataSource = function (source) { var _this = this; if (source == null) { @@ -1919,34 +2849,43 @@ var Plottable; this._dataSource.broadcaster.deregisterListener(this); } this._dataSource = source; - this._dataSource.broadcaster.registerListener(this, function () { return _this._onDataSourceUpdate(); }); + this._dataSource.broadcaster.registerListener(this, function () { + return _this._onDataSourceUpdate(); + }); this._onDataSourceUpdate(); return this; }; + Plot.prototype._onDataSourceUpdate = function () { this.updateAllProjectors(); this.animateOnNextRender = true; this._dataChanged = true; this._render(); }; + Plot.prototype.project = function (attrToSet, accessor, scale) { var _this = this; attrToSet = attrToSet.toLowerCase(); var currentProjection = this._projectors[attrToSet]; var existingScale = (currentProjection != null) ? currentProjection.scale : null; + if (existingScale != null) { existingScale.removeExtent(this._plottableID, attrToSet); existingScale.broadcaster.deregisterListener(this); } + if (scale != null) { - scale.broadcaster.registerListener(this, function () { return _this._render(); }); + scale.broadcaster.registerListener(this, function () { + return _this._render(); + }); } var activatedAccessor = Plottable.Util.Methods._applyAccessor(accessor, this); this._projectors[attrToSet] = { accessor: activatedAccessor, scale: scale }; this.updateProjector(attrToSet); - this._render(); + this._render(); // queue a re-render upon changing projector return this; }; + Plot.prototype._generateAttrToProjector = function () { var _this = this; var h = {}; @@ -1954,11 +2893,14 @@ var Plottable; var projector = _this._projectors[a]; var accessor = projector.accessor; var scale = projector.scale; - var fn = scale == null ? accessor : function (d, i) { return scale.scale(accessor(d, i)); }; + var fn = scale == null ? accessor : function (d, i) { + return scale.scale(accessor(d, i)); + }; h[a] = fn; }); return h; }; + Plot.prototype._doRender = function () { if (this._isAnchored) { this._paint(); @@ -1966,52 +2908,85 @@ var Plottable; this.animateOnNextRender = false; } }; + Plot.prototype._paint = function () { + // no-op }; + Plot.prototype._setup = function () { _super.prototype._setup.call(this); this.renderArea = this.content.append("g").classed("render-area", true); }; + + /** + * Enables or disables animation. + * + * @param {boolean} enabled Whether or not to animate. + */ Plot.prototype.animate = function (enabled) { this._animate = enabled; return this; }; + Plot.prototype.detach = function () { _super.prototype.detach.call(this); + + // make the domain resize this.updateAllProjectors(); return this; }; + + /** + * This function makes sure that all of the scales in this._projectors + * have an extent that includes all the data that is projected onto them. + */ Plot.prototype.updateAllProjectors = function () { var _this = this; - d3.keys(this._projectors).forEach(function (attr) { return _this.updateProjector(attr); }); + d3.keys(this._projectors).forEach(function (attr) { + return _this.updateProjector(attr); + }); return this; }; + Plot.prototype.updateProjector = function (attr) { var projector = this._projectors[attr]; if (projector.scale != null) { var extent = this.dataSource()._getExtent(projector.accessor); if (extent.length === 0 || !this._isAnchored) { projector.scale.removeExtent(this._plottableID, attr); - } - else { + } else { projector.scale.updateExtent(this._plottableID, attr, extent); } } return this; }; + + /** + * Apply attributes to the selection. + * + * If animation is enabled and a valid animator's key is specified, the + * attributes are applied with the animator. Otherwise, they are applied + * immediately to the selection. + * + * The animation will not animate during auto-resize renders. + * + * @param {D3.Selection} selection The selection of elements to update. + * @param {string} animatorKey The key for the animator. + * @param {Abstract.IAttributeToProjector} attrToProjector The set of attributes to set on the selection. + * @return {D3.Selection} The resulting selection (potentially after the transition) + */ Plot.prototype._applyAnimatedAttributes = function (selection, animatorKey, attrToProjector) { if (this._animate && this.animateOnNextRender && this._animators[animatorKey] != null) { return this._animators[animatorKey].animate(selection, attrToProjector, this); - } - else { + } else { return selection.attr(attrToProjector); } }; + Plot.prototype.animator = function (animatorKey, animator) { if (animator === undefined) { return this._animators[animatorKey]; - } - else { + } else { this._animators[animatorKey] = animator; return this; } @@ -2023,6 +2998,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { @@ -2037,6 +3013,7 @@ var Plottable; return Immediate; })(); RenderPolicy.Immediate = Immediate; + var AnimationFrame = (function () { function AnimationFrame() { } @@ -2046,6 +3023,7 @@ var Plottable; return AnimationFrame; })(); RenderPolicy.AnimationFrame = AnimationFrame; + var Timeout = (function () { function Timeout() { this._timeoutMsec = Plottable.Util.DOM.POLYFILL_TIMEOUT_MSEC; @@ -2064,57 +3042,101 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { + /** + * The RenderController is responsible for enqueueing and synchronizing + * layout and render calls for Plottable components. + * + * Layouts and renders occur inside an animation callback + * (window.requestAnimationFrame if available). + * + * If you require immediate rendering, call RenderController.flush() to + * perform enqueued layout and rendering serially. + */ (function (RenderController) { var _componentsNeedingRender = {}; var _componentsNeedingComputeLayout = {}; var _animationRequested = false; RenderController._renderPolicy = new RenderController.RenderPolicy.AnimationFrame(); + function setRenderPolicy(policy) { RenderController._renderPolicy = policy; } RenderController.setRenderPolicy = setRenderPolicy; + + /** + * If the RenderController is enabled, we enqueue the component for + * render. Otherwise, it is rendered immediately. + * + * @param {Abstract.Component} component Any Plottable component. + */ function registerToRender(c) { _componentsNeedingRender[c._plottableID] = c; requestRender(); } RenderController.registerToRender = registerToRender; + + /** + * If the RenderController is enabled, we enqueue the component for + * layout and render. Otherwise, it is rendered immediately. + * + * @param {Abstract.Component} component Any Plottable component. + */ function registerToComputeLayout(c) { _componentsNeedingComputeLayout[c._plottableID] = c; _componentsNeedingRender[c._plottableID] = c; requestRender(); } RenderController.registerToComputeLayout = registerToComputeLayout; + function requestRender() { + // Only run or enqueue flush on first request. if (!_animationRequested) { _animationRequested = true; RenderController._renderPolicy.render(); } } + function flush() { if (_animationRequested) { + // Layout var toCompute = d3.values(_componentsNeedingComputeLayout); - toCompute.forEach(function (c) { return c._computeLayout(); }); + toCompute.forEach(function (c) { + return c._computeLayout(); + }); + + // Top level render. + // Containers will put their children in the toRender queue var toRender = d3.values(_componentsNeedingRender); - toRender.forEach(function (c) { return c._render(); }); + toRender.forEach(function (c) { + return c._render(); + }); + + // Finally, perform render of all components var failed = {}; Object.keys(_componentsNeedingRender).forEach(function (k) { - try { + try { _componentsNeedingRender[k]._doRender(); - } - catch (err) { + } catch (err) { + // using setTimeout instead of console.log, we get the familiar red + // stack trace setTimeout(function () { throw err; }, 0); failed[k] = _componentsNeedingRender[k]; } }); + + // Reset queues _componentsNeedingComputeLayout = {}; _componentsNeedingRender = failed; _animationRequested = false; } + + // Reset resize flag regardless of queue'd components Core.ResizeBroadcaster.clearResizing(); } RenderController.flush = flush; @@ -2124,35 +3146,74 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { + /** + * The ResizeBroadcaster will broadcast a notification to any registered + * components when the window is resized. + * + * The broadcaster and single event listener are lazily constructed. + * + * Upon resize, the _resized flag will be set to true until after the next + * flush of the RenderController. This is used, for example, to disable + * animations during resize. + */ (function (ResizeBroadcaster) { var broadcaster; var _resizing = false; + function _lazyInitialize() { if (broadcaster === undefined) { broadcaster = new Core.Broadcaster(ResizeBroadcaster); window.addEventListener("resize", _onResize); } } + function _onResize() { _resizing = true; broadcaster.broadcast(); } + + /** + * Returns true if the window has been resized and the RenderController + * has not yet been flushed. + */ function resizing() { return _resizing; } ResizeBroadcaster.resizing = resizing; + function clearResizing() { _resizing = false; } ResizeBroadcaster.clearResizing = clearResizing; + + /** + * Registers a component. + * + * When the window is resized, we invoke ._invalidateLayout() on the + * component, which will enqueue the component for layout and rendering + * with the RenderController. + * + * @param {Abstract.Component} component Any Plottable component. + */ function register(c) { _lazyInitialize(); - broadcaster.registerListener(c._plottableID, function () { return c._invalidateLayout(); }); + broadcaster.registerListener(c._plottableID, function () { + return c._invalidateLayout(); + }); } ResizeBroadcaster.register = register; + + /** + * Deregisters the components. + * + * The component will no longer receive updates on window resize. + * + * @param {Abstract.Component} component Any Plottable component. + */ function deregister(c) { if (broadcaster) { broadcaster.deregisterListener(c._plottableID); @@ -2165,94 +3226,186 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { ; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { var Domainer = (function () { + /** + * @param {(extents: any[][]) => any[]} combineExtents + * If present, this function will be used by the Domainer to merge + * all the extents that are present on a scale. + * + * A plot may draw multiple things relative to a scale, e.g. + * different stocks over time. The plot computes their extents, + * which are a [min, max] pair. combineExtents is responsible for + * merging them all into one [min, max] pair. It defaults to taking + * the min of the first elements and the max of the second arguments. + */ function Domainer(combineExtents) { this.doNice = false; this.padProportion = 0.0; this.paddingExceptions = d3.map(); this.unregisteredPaddingExceptions = d3.set(); this.includedValues = d3.map(); + // includedValues needs to be a map, even unregistered, to support getting un-stringified values back out this.unregisteredIncludedValues = d3.map(); this.combineExtents = combineExtents; } + /** + * @param {any[][]} extents The list of extents to be reduced to a single + * extent. + * @param {Abstract.QuantitativeScale} scale + * Since nice() must do different things depending on Linear, Log, + * or Time scale, the scale must be passed in for nice() to work. + * @return {any[]} The domain, as a merging of all exents, as a [min, max] + * pair. + */ Domainer.prototype.computeDomain = function (extents, scale) { var domain; if (this.combineExtents != null) { domain = this.combineExtents(extents); - } - else if (extents.length === 0) { + } else if (extents.length === 0) { domain = scale._defaultExtent(); - } - else { - domain = [d3.min(extents, function (e) { return e[0]; }), d3.max(extents, function (e) { return e[1]; })]; + } else { + domain = [d3.min(extents, function (e) { + return e[0]; + }), d3.max(extents, function (e) { + return e[1]; + })]; } domain = this.includeDomain(domain); domain = this.padDomain(scale, domain); domain = this.niceDomain(scale, domain); return domain; }; + + /** + * Sets the Domainer to pad by a given ratio. + * + * @param {number} [padProportion] Proportionally how much bigger the + * new domain should be (0.05 = 5% larger). + * + * A domainer will pad equal visual amounts on each side. + * On a linear scale, this means both sides are padded the same + * amount: [10, 20] will be padded to [5, 25]. + * On a log scale, the top will be padded more than the bottom, so + * [10, 100] will be padded to [1, 1000]. + * + * @return {Domainer} The calling Domainer. + */ Domainer.prototype.pad = function (padProportion) { - if (padProportion === void 0) { padProportion = 0.05; } + if (typeof padProportion === "undefined") { padProportion = 0.05; } this.padProportion = padProportion; return this; }; + + /** + * Add a padding exception, a value that will not be padded at either end of the domain. + * + * Eg, if a padding exception is added at x=0, then [0, 100] will pad to [0, 105] instead of [-2.5, 102.5]. + * If a key is provided, it will be registered under that key with standard map semantics. (Overwrite / remove by key) + * If a key is not provided, it will be added with set semantics (Can be removed by value) + * + * @param {any} exception The padding exception to add. + * @param string [key] The key to register the exception under. + * @return Domainer The calling domainer + */ Domainer.prototype.addPaddingException = function (exception, key) { if (key != null) { this.paddingExceptions.set(key, exception); - } - else { + } else { this.unregisteredPaddingExceptions.add(exception); } return this; }; + + /** + * Remove a padding exception, allowing the domain to pad out that value again. + * + * If a string is provided, it is assumed to be a key and the exception associated with that key is removed. + * If a non-string is provdied, it is assumed to be an unkeyed exception and that exception is removed. + * + * @param {any} keyOrException The key for the value to remove, or the value to remove + * @return Domainer The calling domainer + */ Domainer.prototype.removePaddingException = function (keyOrException) { if (typeof (keyOrException) === "string") { this.paddingExceptions.remove(keyOrException); - } - else { + } else { this.unregisteredPaddingExceptions.remove(keyOrException); } return this; }; + + /** + * Add an included value, a value that must be included inside the domain. + * + * Eg, if a value exception is added at x=0, then [50, 100] will expand to [0, 100] rather than [50, 100]. + * If a key is provided, it will be registered under that key with standard map semantics. (Overwrite / remove by key) + * If a key is not provided, it will be added with set semantics (Can be removed by value) + * + * @param {any} value The included value to add. + * @param string [key] The key to register the value under. + * @return Domainer The calling domainer + */ Domainer.prototype.addIncludedValue = function (value, key) { if (key != null) { this.includedValues.set(key, value); - } - else { + } else { this.unregisteredIncludedValues.set(value, value); } return this; }; + + /** + * Remove an included value, allowing the domain to not include that value gain again. + * + * If a string is provided, it is assumed to be a key and the value associated with that key is removed. + * If a non-string is provdied, it is assumed to be an unkeyed value and that value is removed. + * + * @param {any} keyOrException The key for the value to remove, or the value to remove + * @return Domainer The calling domainer + */ Domainer.prototype.removeIncludedValue = function (valueOrKey) { if (typeof (valueOrKey) === "string") { this.includedValues.remove(valueOrKey); - } - else { + } else { this.unregisteredIncludedValues.remove(valueOrKey); } return this; }; + + /** + * Extends the scale's domain so it starts and ends with "nice" values. + * + * @param {number} [count] The number of ticks that should fit inside the new domain. + * @return {Domainer} The calling Domainer. + */ Domainer.prototype.nice = function (count) { this.doNice = true; this.niceCount = count; return this; }; + Domainer.defaultCombineExtents = function (extents) { if (extents.length === 0) { return [0, 1]; - } - else { - return [d3.min(extents, function (e) { return e[0]; }), d3.max(extents, function (e) { return e[1]; })]; + } else { + return [d3.min(extents, function (e) { + return e[0]; + }), d3.max(extents, function (e) { + return e[1]; + })]; } }; + Domainer.prototype.padDomain = function (scale, domain) { var min = domain[0]; var max = domain[1]; @@ -2260,15 +3413,20 @@ var Plottable; var d = min.valueOf(); if (min instanceof Date) { return [d - Domainer.ONE_DAY, d + Domainer.ONE_DAY]; - } - else { - return [d - Domainer.PADDING_FOR_IDENTICAL_DOMAIN, d + Domainer.PADDING_FOR_IDENTICAL_DOMAIN]; + } else { + return [ + d - Domainer.PADDING_FOR_IDENTICAL_DOMAIN, + d + Domainer.PADDING_FOR_IDENTICAL_DOMAIN]; } } + if (scale.domain()[0] === scale.domain()[1]) { return domain; } var p = this.padProportion / 2; + + // This scaling is done to account for log scales and other non-linear + // scales. A log scale should be padded more on the max than on the min. var newMin = scale.invert(scale.scale(min) - (scale.scale(max) - scale.scale(min)) * p); var newMax = scale.invert(scale.scale(max) + (scale.scale(max) - scale.scale(min)) * p); var exceptionValues = this.paddingExceptions.values().concat(this.unregisteredPaddingExceptions.values()); @@ -2281,17 +3439,20 @@ var Plottable; } return [newMin, newMax]; }; + Domainer.prototype.niceDomain = function (scale, domain) { if (this.doNice) { return scale._niceDomain(domain, this.niceCount); - } - else { + } else { return domain; } }; + Domainer.prototype.includeDomain = function (domain) { var includedValues = this.includedValues.values().concat(this.unregisteredIncludedValues.values()); - return includedValues.reduce(function (domain, value) { return [Math.min(domain[0], value), Math.max(domain[1], value)]; }, domain); + return includedValues.reduce(function (domain, value) { + return [Math.min(domain[0], value), Math.max(domain[1], value)]; + }, domain); }; Domainer.PADDING_FOR_IDENTICAL_DOMAIN = 1; Domainer.ONE_DAY = 1000 * 60 * 60 * 24; @@ -2300,6 +3461,7 @@ var Plottable; Plottable.Domainer = Domainer; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2311,6 +3473,12 @@ var Plottable; (function (Abstract) { var QuantitativeScale = (function (_super) { __extends(QuantitativeScale, _super); + /** + * Creates a new QuantitativeScale. + * + * @constructor + * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale backing the QuantitativeScale. + */ function QuantitativeScale(scale) { _super.call(this, scale); this._lastRequestedTickCount = 10; @@ -2321,23 +3489,41 @@ var Plottable; QuantitativeScale.prototype._getExtent = function () { return this._domainer.computeDomain(this._getAllExtents(), this); }; + + /** + * Retrieves the domain value corresponding to a supplied range value. + * + * @param {number} value: A value from the Scale's range. + * @returns {number} The domain value corresponding to the supplied range value. + */ QuantitativeScale.prototype.invert = function (value) { return this._d3Scale.invert(value); }; + + /** + * Creates a copy of the QuantitativeScale with the same domain and range but without any registered listeners. + * + * @returns {QuantitativeScale} A copy of the calling QuantitativeScale. + */ QuantitativeScale.prototype.copy = function () { return new QuantitativeScale(this._d3Scale.copy()); }; + QuantitativeScale.prototype.domain = function (values) { return _super.prototype.domain.call(this, values); }; + QuantitativeScale.prototype._setDomain = function (values) { - var isNaNOrInfinity = function (x) { return x !== x || x === Infinity || x === -Infinity; }; + var isNaNOrInfinity = function (x) { + return x !== x || x === Infinity || x === -Infinity; + }; if (isNaNOrInfinity(values[0]) || isNaNOrInfinity(values[1])) { Plottable.Util.Methods.warn("Warning: QuantitativeScales cannot take NaN or Infinity as a domain value. Ignoring."); return; } _super.prototype._setDomain.call(this, values); }; + QuantitativeScale.prototype.interpolate = function (factory) { if (factory == null) { return this._d3Scale.interpolate(); @@ -2345,10 +3531,17 @@ var Plottable; this._d3Scale.interpolate(factory); return this; }; + + /** + * Sets the range of the QuantitativeScale and sets the interpolator to d3.interpolateRound. + * + * @param {number[]} values The new range value for the range. + */ QuantitativeScale.prototype.rangeRound = function (values) { this._d3Scale.rangeRound(values); return this; }; + QuantitativeScale.prototype.clamp = function (clamp) { if (clamp == null) { return this._d3Scale.clamp(); @@ -2356,29 +3549,50 @@ var Plottable; this._d3Scale.clamp(clamp); return this; }; + + /** + * Generates tick values. + * + * @param {number} [count] The number of ticks to generate. + * @returns {any[]} The generated ticks. + */ QuantitativeScale.prototype.ticks = function (count) { if (count != null) { this._lastRequestedTickCount = count; } return this._d3Scale.ticks(this._lastRequestedTickCount); }; + + /** + * Gets a tick formatting function for displaying tick values. + * + * @param {number} count The number of ticks to be displayed + * @param {string} [format] A format specifier string. + * @returns {(n: number) => string} A formatting function. + */ QuantitativeScale.prototype.tickFormat = function (count, format) { return this._d3Scale.tickFormat(count, format); }; + + /** + * Given a domain, expands its domain onto "nice" values, e.g. whole + * numbers. + */ QuantitativeScale.prototype._niceDomain = function (domain, count) { return this._d3Scale.copy().domain(domain).nice(count).domain(); }; + QuantitativeScale.prototype.domainer = function (domainer) { if (domainer == null) { return this._domainer; - } - else { + } else { this._domainer = domainer; this._userSetDomainer = true; this._autoDomainIfAutomaticMode(); return this; } }; + QuantitativeScale.prototype._defaultExtent = function () { return [0, 1]; }; @@ -2389,6 +3603,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2403,6 +3618,11 @@ var Plottable; function Linear(scale) { _super.call(this, scale == null ? d3.scale.linear() : scale); } + /** + * Creates a copy of the LinearScale with the same domain and range but without any registered listeners. + * + * @returns {LinearScale} A copy of the calling LinearScale. + */ Linear.prototype.copy = function () { return new Linear(this._d3Scale.copy()); }; @@ -2413,6 +3633,7 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2431,9 +3652,15 @@ var Plottable; Plottable.Util.Methods.warn("Plottable.Scale.Log is deprecated. If possible, use Plottable.Scale.ModifiedLog instead."); } } + /** + * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. + * + * @returns {Scale.Log} A copy of the calling Scale.Log. + */ Log.prototype.copy = function () { return new Log(this._d3Scale.copy()); }; + Log.prototype._defaultExtent = function () { return [1, 10]; }; @@ -2445,6 +3672,7 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2456,8 +3684,33 @@ var Plottable; (function (Scale) { var ModifiedLog = (function (_super) { __extends(ModifiedLog, _super); + /** + * Creates a new Scale.ModifiedLog. + * + * A ModifiedLog scale acts as a regular log scale for large numbers. + * As it approaches 0, it gradually becomes linear. This means that the + * scale won't freak out if you give it 0 or a negative number, where an + * ordinary Log scale would. + * + * However, it does mean that scale will be effectively linear as values + * approach 0. If you want very small values on a log scale, you should use + * an ordinary Scale.Log instead. + * + * @constructor + * @param {number} [base] + * The base of the log. Defaults to 10, and must be > 1. + * + * For base <= x, scale(x) = log(x). + * + * For 0 < x < base, scale(x) will become more and more + * linear as it approaches 0. + * + * At x == 0, scale(x) == 0. + * + * For negative values, scale(-x) = -scale(x). + */ function ModifiedLog(base) { - if (base === void 0) { base = 10; } + if (typeof base === "undefined") { base = 10; } _super.call(this, d3.scale.linear()); this._showIntermediateTicks = false; this.base = base; @@ -2468,61 +3721,111 @@ var Plottable; throw new Error("ModifiedLogScale: The base must be > 1"); } } + /** + * Returns an adjusted log10 value for graphing purposes. The first + * adjustment is that negative values are changed to positive during + * the calculations, and then the answer is negated at the end. The + * second is that, for values less than 10, an increasingly large + * (0 to 1) scaling factor is added such that at 0 the value is + * adjusted to 1, resulting in a returned result of 0. + */ ModifiedLog.prototype.adjustedLog = function (x) { var negationFactor = x < 0 ? -1 : 1; x *= negationFactor; + if (x < this.pivot) { x += (this.pivot - x) / this.pivot; } + x = Math.log(x) / Math.log(this.base); + x *= negationFactor; return x; }; + ModifiedLog.prototype.invertedAdjustedLog = function (x) { var negationFactor = x < 0 ? -1 : 1; x *= negationFactor; + x = Math.pow(this.base, x); + if (x < this.pivot) { x = (this.pivot * (x - 1)) / (this.pivot - 1); } + x *= negationFactor; return x; }; + ModifiedLog.prototype.scale = function (x) { return this._d3Scale(this.adjustedLog(x)); }; + ModifiedLog.prototype.invert = function (x) { return this.invertedAdjustedLog(this._d3Scale.invert(x)); }; + ModifiedLog.prototype._getDomain = function () { return this.untransformedDomain; }; + ModifiedLog.prototype._setDomain = function (values) { this.untransformedDomain = values; var transformedDomain = [this.adjustedLog(values[0]), this.adjustedLog(values[1])]; this._d3Scale.domain(transformedDomain); this.broadcaster.broadcast(); }; + ModifiedLog.prototype.ticks = function (count) { if (count != null) { _super.prototype.ticks.call(this, count); } - var middle = function (x, y, z) { return [x, y, z].sort(function (a, b) { return a - b; })[1]; }; + + // Say your domain is [-100, 100] and your pivot is 10. + // then we're going to draw negative log ticks from -100 to -10, + // linear ticks from -10 to 10, and positive log ticks from 10 to 100. + var middle = function (x, y, z) { + return [x, y, z].sort(function (a, b) { + return a - b; + })[1]; + }; var min = d3.min(this.untransformedDomain); var max = d3.max(this.untransformedDomain); var negativeLower = min; var negativeUpper = middle(min, max, -this.pivot); var positiveLower = middle(min, max, this.pivot); var positiveUpper = max; - var negativeLogTicks = this.logTicks(-negativeUpper, -negativeLower).map(function (x) { return -x; }).reverse(); + + var negativeLogTicks = this.logTicks(-negativeUpper, -negativeLower).map(function (x) { + return -x; + }).reverse(); var positiveLogTicks = this.logTicks(positiveLower, positiveUpper); - var linearTicks = this._showIntermediateTicks ? d3.scale.linear().domain([negativeUpper, positiveLower]).ticks(this.howManyTicks(negativeUpper, positiveLower)) : [-this.pivot, 0, this.pivot].filter(function (x) { return min <= x && x <= max; }); + var linearTicks = this._showIntermediateTicks ? d3.scale.linear().domain([negativeUpper, positiveLower]).ticks(this.howManyTicks(negativeUpper, positiveLower)) : [-this.pivot, 0, this.pivot].filter(function (x) { + return min <= x && x <= max; + }); + var ticks = negativeLogTicks.concat(linearTicks).concat(positiveLogTicks); + + // If you only have 1 tick, you can't tell how big the scale is. if (ticks.length <= 1) { ticks = d3.scale.linear().domain([min, max]).ticks(this._lastRequestedTickCount); } return ticks; }; + + /** + * Return an appropriate number of ticks from lower to upper. + * + * This will first try to fit as many powers of this.base as it can from + * lower to upper. + * + * If it still has ticks after that, it will generate ticks in "clusters", + * e.g. [20, 30, ... 90, 100] would be a cluster, [200, 300, ... 900, 1000] + * would be another cluster. + * + * This function will generate clusters as large as it can while not + * drastically exceeding its number of ticks. + */ ModifiedLog.prototype.logTicks = function (lower, upper) { var _this = this; var nTicks = this.howManyTicks(lower, upper); @@ -2535,12 +3838,28 @@ var Plottable; var nMultiples = this._showIntermediateTicks ? Math.floor(nTicks / bases.length) : 1; var multiples = d3.range(this.base, 1, -(this.base - 1) / nMultiples).map(Math.floor); var uniqMultiples = Plottable.Util.Methods.uniqNumbers(multiples); - var clusters = bases.map(function (b) { return uniqMultiples.map(function (x) { return Math.pow(_this.base, b - 1) * x; }); }); + var clusters = bases.map(function (b) { + return uniqMultiples.map(function (x) { + return Math.pow(_this.base, b - 1) * x; + }); + }); var flattened = Plottable.Util.Methods.flatten(clusters); - var filtered = flattened.filter(function (x) { return lower <= x && x <= upper; }); - var sorted = filtered.sort(function (x, y) { return x - y; }); + var filtered = flattened.filter(function (x) { + return lower <= x && x <= upper; + }); + var sorted = filtered.sort(function (x, y) { + return x - y; + }); return sorted; }; + + /** + * How many ticks does the range [lower, upper] deserve? + * + * e.g. if your domain was [10, 1000] and I asked howManyTicks(10, 100), + * I would get 1/2 of the ticks. The range 10, 100 takes up 1/2 of the + * distance when plotted. + */ ModifiedLog.prototype.howManyTicks = function (lower, upper) { var adjustedMin = this.adjustedLog(d3.min(this.untransformedDomain)); var adjustedMax = this.adjustedLog(d3.max(this.untransformedDomain)); @@ -2550,17 +3869,19 @@ var Plottable; var ticks = Math.ceil(proportion * this._lastRequestedTickCount); return ticks; }; + ModifiedLog.prototype.copy = function () { return new ModifiedLog(this.base); }; + ModifiedLog.prototype._niceDomain = function (domain, count) { return domain; }; + ModifiedLog.prototype.showIntermediateTicks = function (show) { if (show == null) { return this._showIntermediateTicks; - } - else { + } else { this._showIntermediateTicks = show; } }; @@ -2571,6 +3892,7 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2582,10 +3904,16 @@ var Plottable; (function (Scale) { var Ordinal = (function (_super) { __extends(Ordinal, _super); + /** + * Creates a new OrdinalScale. Domain and Range are set later. + * + * @constructor + */ function Ordinal(scale) { _super.call(this, scale == null ? d3.scale.ordinal() : scale); this._range = [0, 1]; this._rangeType = "bands"; + // Padding as a proportion of the spacing between domain values this._innerPadding = 0.3; this._outerPadding = 0.5; if (this._innerPadding > this._outerPadding) { @@ -2596,31 +3924,39 @@ var Plottable; var extents = this._getAllExtents(); return Plottable.Util.Methods.uniq(Plottable.Util.Methods.flatten(extents)); }; + Ordinal.prototype.domain = function (values) { return _super.prototype.domain.call(this, values); }; + Ordinal.prototype._setDomain = function (values) { _super.prototype._setDomain.call(this, values); - this.range(this.range()); + this.range(this.range()); // update range }; + Ordinal.prototype.range = function (values) { if (values == null) { return this._range; - } - else { + } else { this._range = values; if (this._rangeType === "points") { - this._d3Scale.rangePoints(values, 2 * this._outerPadding); - } - else if (this._rangeType === "bands") { + this._d3Scale.rangePoints(values, 2 * this._outerPadding); // d3 scale takes total padding + } else if (this._rangeType === "bands") { this._d3Scale.rangeBands(values, this._innerPadding, this._outerPadding); } return this; } }; + + /** + * Returns the width of the range band. Only valid when rangeType is set to "bands". + * + * @returns {number} The range band width or 0 if rangeType isn't "bands". + */ Ordinal.prototype.rangeBand = function () { return this._d3Scale.rangeBand(); }; + Ordinal.prototype.innerPadding = function () { var d = this.domain(); if (d.length < 2) { @@ -2629,16 +3965,17 @@ var Plottable; var step = Math.abs(this.scale(d[1]) - this.scale(d[0])); return step - this.rangeBand(); }; + Ordinal.prototype.fullBandStartAndWidth = function (v) { var start = this.scale(v) - this.innerPadding() / 2; var width = this.rangeBand() + this.innerPadding(); return [start, width]; }; + Ordinal.prototype.rangeType = function (rangeType, outerPadding, innerPadding) { if (rangeType == null) { return this._rangeType; - } - else { + } else { if (!(rangeType === "points" || rangeType === "bands")) { throw new Error("Unsupported range type: " + rangeType); } @@ -2653,6 +3990,12 @@ var Plottable; return this; } }; + + /** + * Creates a copy of the Scale with the same domain and range but without any registered listeners. + * + * @returns {Ordinal} A copy of the calling Scale. + */ Ordinal.prototype.copy = function () { return new Ordinal(this._d3Scale.copy()); }; @@ -2663,6 +4006,7 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2674,6 +4018,14 @@ var Plottable; (function (Scale) { var Color = (function (_super) { __extends(Color, _super); + /** + * Creates a ColorScale. + * + * @constructor + * @param {string} [scaleType] the type of color scale to create + * (Category10/Category20/Category20b/Category20c). + * See https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors + */ function Color(scaleType) { var scale; switch (scaleType) { @@ -2706,6 +4058,7 @@ var Plottable; } _super.call(this, scale); } + // Duplicated from OrdinalScale._getExtent - should be removed in #388 Color.prototype._getExtent = function () { var extents = this._getAllExtents(); var concatenatedExtents = []; @@ -2721,6 +4074,7 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2733,26 +4087,37 @@ var Plottable; var Time = (function (_super) { __extends(Time, _super); function Time(scale) { + // need to cast since d3 time scales do not descend from Quantitative scales _super.call(this, scale == null ? d3.time.scale() : scale); this._PADDING_FOR_IDENTICAL_DOMAIN = 1000 * 60 * 60 * 24; } Time.prototype.tickInterval = function (interval, step) { + // temporarily creats a time scale from our linear scale into a time scale so we can get access to its api var tempScale = d3.time.scale(); tempScale.domain(this.domain()); tempScale.range(this.range()); return tempScale.ticks(interval.range, step); }; + Time.prototype.domain = function (values) { if (values == null) { return _super.prototype.domain.call(this); - } - else { + } else { + // attempt to parse dates if (typeof (values[0]) === "string") { - values = values.map(function (d) { return new Date(d); }); + values = values.map(function (d) { + return new Date(d); + }); } return _super.prototype.domain.call(this, values); } }; + + /** + * Creates a copy of the TimeScale with the same domain and range but without any registered listeners. + * + * @returns {TimeScale} A copy of the calling TimeScale. + */ Time.prototype.copy = function () { return new Time(this._d3Scale.copy()); }; @@ -2763,6 +4128,7 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2773,15 +4139,43 @@ var Plottable; (function (Plottable) { (function (Scale) { ; + + /** + * This class implements a color scale that takes quantitive input and + * interpolates between a list of color values. It returns a hex string + * representing the interpolated color. + * + * By default it generates a linear scale internally. + */ var InterpolatedColor = (function (_super) { __extends(InterpolatedColor, _super); + /** + * Creates a InterpolatedColorScale. + * + * @constructor + * @param {string|string[]} [colorRange] the type of color scale to + * create. Default is "reds". @see {@link colorRange} for further + * options. + * @param {string} [scaleType] the type of underlying scale to use + * (linear/pow/log/sqrt). Default is "linear". @see {@link scaleType} + * for further options. + */ function InterpolatedColor(colorRange, scaleType) { - if (colorRange === void 0) { colorRange = "reds"; } - if (scaleType === void 0) { scaleType = "linear"; } + if (typeof colorRange === "undefined") { colorRange = "reds"; } + if (typeof scaleType === "undefined") { scaleType = "linear"; } this._colorRange = this._resolveColorValues(colorRange); this._scaleType = scaleType; _super.call(this, InterpolatedColor.getD3InterpolatedScale(this._colorRange, this._scaleType)); } + /** + * Converts the string array into a d3 scale. + * + * @param {string[]} colors an array of strings representing color + * values in hex ("#FFFFFF") or keywords ("white"). + * @param {string} scaleType a string representing the underlying scale + * type ("linear"/"log"/"sqrt"/"pow") + * @returns a Quantitative d3 scale. + */ InterpolatedColor.getD3InterpolatedScale = function (colors, scaleType) { var scale; switch (scaleType) { @@ -2803,6 +4197,18 @@ var Plottable; } return scale.range([0, 1]).interpolate(InterpolatedColor.interpolateColors(colors)); }; + + /** + * Creates a d3 interpolator given the color array. + * + * d3 doesn't accept more than 2 range values unless we use a ordinal + * scale. So, in order to interpolate smoothly between the full color + * range, we must override the interpolator and compute the color values + * manually. + * + * @param {string[]} colors an array of strings representing color + * values in hex ("#FFFFFF") or keywords ("white"). + */ InterpolatedColor.interpolateColors = function (colors) { if (colors.length < 2) { throw new Error("Color scale arrays must have at least two elements."); @@ -2810,15 +4216,21 @@ var Plottable; ; return function (ignored) { return function (t) { + // Clamp t parameter to [0,1] t = Math.max(0, Math.min(1, t)); + + // Determine indices for colors var tScaled = t * (colors.length - 1); var i0 = Math.floor(tScaled); var i1 = Math.ceil(tScaled); var frac = (tScaled - i0); + + // Interpolate in the L*a*b color space return d3.interpolateLab(colors[i0], colors[i1])(frac); }; }; }; + InterpolatedColor.prototype.colorRange = function (colorRange) { if (colorRange == null) { return this._colorRange; @@ -2827,6 +4239,7 @@ var Plottable; this._resetScale(); return this; }; + InterpolatedColor.prototype.scaleType = function (scaleType) { if (scaleType == null) { return this._scaleType; @@ -2835,26 +4248,32 @@ var Plottable; this._resetScale(); return this; }; + InterpolatedColor.prototype._resetScale = function () { this._d3Scale = InterpolatedColor.getD3InterpolatedScale(this._colorRange, this._scaleType); this._autoDomainIfAutomaticMode(); this.broadcaster.broadcast(); }; + InterpolatedColor.prototype._resolveColorValues = function (colorRange) { if (colorRange instanceof Array) { return colorRange; - } - else if (InterpolatedColor.COLOR_SCALES[colorRange] != null) { + } else if (InterpolatedColor.COLOR_SCALES[colorRange] != null) { return InterpolatedColor.COLOR_SCALES[colorRange]; - } - else { + } else { return InterpolatedColor.COLOR_SCALES["reds"]; } }; + InterpolatedColor.prototype.autoDomain = function () { + // unlike other QuantitativeScales, interpolatedColorScale ignores its domainer var extents = this._getAllExtents(); if (extents.length > 0) { - this._setDomain([d3.min(extents, function (x) { return x[0]; }), d3.max(extents, function (x) { return x[1]; })]); + this._setDomain([d3.min(extents, function (x) { + return x[0]; + }), d3.max(extents, function (x) { + return x[1]; + })]); } return this; }; @@ -2908,18 +4327,33 @@ var Plottable; var Scale = Plottable.Scale; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { var ScaleDomainCoordinator = (function () { + /** + * Creates a ScaleDomainCoordinator. + * + * @constructor + * @param {Scale[]} scales A list of scales whose domains should be linked. + */ function ScaleDomainCoordinator(scales) { var _this = this; + /* This class is responsible for maintaining coordination between linked scales. + It registers event listeners for when one of its scales changes its domain. When the scale + does change its domain, it re-propogates the change to every linked scale. + */ this.rescaleInProgress = false; if (scales == null) { throw new Error("ScaleDomainCoordinator requires scales to coordinate"); } this.scales = scales; - this.scales.forEach(function (s) { return s.broadcaster.registerListener(_this, function (sx) { return _this.rescale(sx); }); }); + this.scales.forEach(function (s) { + return s.broadcaster.registerListener(_this, function (sx) { + return _this.rescale(sx); + }); + }); } ScaleDomainCoordinator.prototype.rescale = function (scale) { if (this.rescaleInProgress) { @@ -2927,7 +4361,9 @@ var Plottable; } this.rescaleInProgress = true; var newDomain = scale.domain(); - this.scales.forEach(function (s) { return s.domain(newDomain); }); + this.scales.forEach(function (s) { + return s.domain(newDomain); + }); this.rescaleInProgress = false; }; return ScaleDomainCoordinator; @@ -2937,6 +4373,7 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -2949,9 +4386,9 @@ var Plottable; var Axis = (function (_super) { __extends(Axis, _super); function Axis(scale, orientation, formatter) { - if (formatter === void 0) { formatter = Plottable.Formatters.identity(); } - _super.call(this); + if (typeof formatter === "undefined") { formatter = Plottable.Formatters.identity(); } var _this = this; + _super.call(this); this._width = "auto"; this._height = "auto"; this._endTickLength = 5; @@ -2964,34 +4401,45 @@ var Plottable; } this._scale = scale; this.orient(orientation); + this.classed("axis", true); if (this._isHorizontal()) { this.classed("x-axis", true); - } - else { + } else { this.classed("y-axis", true); } + this.formatter(formatter); - this._scale.broadcaster.registerListener(this, function () { return _this.rescale(); }); + + this._scale.broadcaster.registerListener(this, function () { + return _this.rescale(); + }); } Axis.prototype.remove = function () { _super.prototype.remove.call(this); this._scale.broadcaster.deregisterListener(this); }; + Axis.prototype._isHorizontal = function () { return this._orientation === "top" || this._orientation === "bottom"; }; + Axis.prototype._computeWidth = function () { + // to be overridden by subclass logic this._computedWidth = this._maxLabelTickLength(); return this._computedWidth; }; + Axis.prototype._computeHeight = function () { + // to be overridden by subclass logic this._computedHeight = this._maxLabelTickLength(); return this._computedHeight; }; + Axis.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var requestedWidth = this._width; var requestedHeight = this._height; + if (this._isHorizontal()) { if (this._height === "auto") { if (this._computedHeight == null) { @@ -3000,8 +4448,7 @@ var Plottable; requestedHeight = this._computedHeight + this._gutter; } requestedWidth = 0; - } - else { + } else { if (this._width === "auto") { if (this._computedWidth == null) { this._computeWidth(); @@ -3010,6 +4457,7 @@ var Plottable; } requestedHeight = 0; } + return { width: requestedWidth, height: requestedHeight, @@ -3017,30 +4465,39 @@ var Plottable; wantsHeight: this._isHorizontal() && offeredHeight < requestedHeight }; }; + Axis.prototype._isFixedHeight = function () { return this._isHorizontal(); }; + Axis.prototype._isFixedWidth = function () { return !this._isHorizontal(); }; + Axis.prototype._computeLayout = function (xOffset, yOffset, availableWidth, availableHeight) { _super.prototype._computeLayout.call(this, xOffset, yOffset, availableWidth, availableHeight); if (this._isHorizontal()) { this._scale.range([0, this.availableWidth]); - } - else { + } else { this._scale.range([this.availableHeight, 0]); } }; + Axis.prototype._setup = function () { _super.prototype._setup.call(this); this._tickMarkContainer = this.content.append("g").classed(Axis.TICK_MARK_CLASS + "-container", true); this._tickLabelContainer = this.content.append("g").classed(Axis.TICK_LABEL_CLASS + "-container", true); this._baseline = this.content.append("line").classed("baseline", true); }; + + /* + * Function for generating tick values in data-space (as opposed to pixel values). + * To be implemented by subclasses. + */ Axis.prototype._getTickValues = function () { return []; }; + Axis.prototype._doRender = function () { var tickMarkValues = this._getTickValues(); var tickMarks = this._tickMarkContainer.selectAll("." + Axis.TICK_MARK_CLASS).data(tickMarkValues); @@ -3051,6 +4508,7 @@ var Plottable; tickMarks.exit().remove(); this._baseline.attr(this._generateBaselineAttrHash()); }; + Axis.prototype._generateBaselineAttrHash = function () { var baselineAttrHash = { x1: 0, @@ -3058,76 +4516,92 @@ var Plottable; x2: 0, y2: 0 }; + switch (this._orientation) { case "bottom": baselineAttrHash.x2 = this.availableWidth; break; + case "top": baselineAttrHash.x2 = this.availableWidth; baselineAttrHash.y1 = this.availableHeight; baselineAttrHash.y2 = this.availableHeight; break; + case "left": baselineAttrHash.x1 = this.availableWidth; baselineAttrHash.x2 = this.availableWidth; baselineAttrHash.y2 = this.availableHeight; break; + case "right": baselineAttrHash.y2 = this.availableHeight; break; } + return baselineAttrHash; }; + Axis.prototype._generateTickMarkAttrHash = function (isEndTickMark) { var _this = this; - if (isEndTickMark === void 0) { isEndTickMark = false; } + if (typeof isEndTickMark === "undefined") { isEndTickMark = false; } var tickMarkAttrHash = { x1: 0, y1: 0, x2: 0, y2: 0 }; - var scalingFunction = function (d) { return _this._scale.scale(d); }; + + var scalingFunction = function (d) { + return _this._scale.scale(d); + }; if (this._isHorizontal()) { tickMarkAttrHash["x1"] = scalingFunction; tickMarkAttrHash["x2"] = scalingFunction; - } - else { + } else { tickMarkAttrHash["y1"] = scalingFunction; tickMarkAttrHash["y2"] = scalingFunction; } + var tickLength = isEndTickMark ? this._endTickLength : this._tickLength; + switch (this._orientation) { case "bottom": tickMarkAttrHash["y2"] = tickLength; break; + case "top": tickMarkAttrHash["y1"] = this.availableHeight; tickMarkAttrHash["y2"] = this.availableHeight - tickLength; break; + case "left": tickMarkAttrHash["x1"] = this.availableWidth; tickMarkAttrHash["x2"] = this.availableWidth - tickLength; break; + case "right": tickMarkAttrHash["x2"] = tickLength; break; } + return tickMarkAttrHash; }; + Axis.prototype.rescale = function () { return (this.element != null) ? this._render() : null; }; + Axis.prototype._invalidateLayout = function () { this._computedWidth = null; this._computedHeight = null; _super.prototype._invalidateLayout.call(this); }; + Axis.prototype.width = function (w) { if (w == null) { return this.availableWidth; - } - else { + } else { if (this._isHorizontal()) { throw new Error("width cannot be set on a horizontal Axis"); } @@ -3139,11 +4613,11 @@ var Plottable; return this; } }; + Axis.prototype.height = function (h) { if (h == null) { return this.availableHeight; - } - else { + } else { if (!this._isHorizontal()) { throw new Error("height cannot be set on a vertical Axis"); } @@ -3155,6 +4629,7 @@ var Plottable; return this; } }; + Axis.prototype.formatter = function (formatter) { if (formatter === undefined) { return this._formatter; @@ -3163,11 +4638,11 @@ var Plottable; this._invalidateLayout(); return this; }; + Axis.prototype.tickLength = function (length) { if (length == null) { return this._tickLength; - } - else { + } else { if (length < 0) { throw new Error("tick length must be positive"); } @@ -3176,11 +4651,11 @@ var Plottable; return this; } }; + Axis.prototype.endTickLength = function (length) { if (length == null) { return this._endTickLength; - } - else { + } else { if (length < 0) { throw new Error("end tick length must be positive"); } @@ -3189,19 +4664,19 @@ var Plottable; return this; } }; + Axis.prototype._maxLabelTickLength = function () { if (this.showEndTickLabels()) { return Math.max(this.tickLength(), this.endTickLength()); - } - else { + } else { return this.tickLength(); } }; + Axis.prototype.tickLabelPadding = function (padding) { if (padding == null) { return this._tickLabelPadding; - } - else { + } else { if (padding < 0) { throw new Error("tick label padding must be positive"); } @@ -3210,11 +4685,11 @@ var Plottable; return this; } }; + Axis.prototype.gutter = function (size) { if (size == null) { return this._gutter; - } - else { + } else { if (size < 0) { throw new Error("gutter size must be positive"); } @@ -3223,11 +4698,11 @@ var Plottable; return this; } }; + Axis.prototype.orient = function (newOrientation) { if (newOrientation == null) { return this._orientation; - } - else { + } else { var newOrientationLC = newOrientation.toLowerCase(); if (newOrientationLC !== "top" && newOrientationLC !== "bottom" && newOrientationLC !== "left" && newOrientationLC !== "right") { throw new Error("unsupported orientation"); @@ -3237,6 +4712,7 @@ var Plottable; return this; } }; + Axis.prototype.showEndTickLabels = function (show) { if (show == null) { return this._showEndTickLabels; @@ -3245,12 +4721,15 @@ var Plottable; this._render(); return this; }; + Axis.prototype._hideEndTickLabels = function () { var _this = this; var boundingBox = this.element.select(".bounding-box")[0][0].getBoundingClientRect(); + var isInsideBBox = function (tickBox) { return (Math.floor(boundingBox.left) <= Math.ceil(tickBox.left) && Math.floor(boundingBox.top) <= Math.ceil(tickBox.top) && Math.floor(tickBox.right) <= Math.ceil(boundingBox.left + _this.availableWidth) && Math.floor(tickBox.bottom) <= Math.ceil(boundingBox.top + _this.availableHeight)); }; + var tickLabels = this._tickLabelContainer.selectAll("." + Abstract.Axis.TICK_LABEL_CLASS); if (tickLabels[0].length === 0) { return; @@ -3264,25 +4743,28 @@ var Plottable; d3.select(lastTickLabel).style("visibility", "hidden"); } }; + Axis.prototype._hideOverlappingTickLabels = function () { var visibleTickLabels = this._tickLabelContainer.selectAll("." + Abstract.Axis.TICK_LABEL_CLASS).filter(function (d, i) { return d3.select(this).style("visibility") === "visible"; }); var lastLabelClientRect; + visibleTickLabels.each(function (d) { var clientRect = this.getBoundingClientRect(); var tickLabel = d3.select(this); if (lastLabelClientRect != null && Plottable.Util.DOM.boxesOverlap(clientRect, lastLabelClientRect)) { tickLabel.style("visibility", "hidden"); - } - else { + } else { lastLabelClientRect = clientRect; tickLabel.style("visibility", "visible"); } }); }; Axis.END_TICK_MARK_CLASS = "end-tick-mark"; + Axis.TICK_MARK_CLASS = "tick-mark"; + Axis.TICK_LABEL_CLASS = "tick-label"; return Axis; })(Abstract.Component); @@ -3291,6 +4773,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -3301,8 +4784,16 @@ var Plottable; (function (Plottable) { (function (Axis) { ; + var Time = (function (_super) { __extends(Time, _super); + /** + * Creates a TimeAxis + * + * @constructor + * @param {TimeScale} scale The scale to base the Axis on. + * @param {string} orientation The orientation of the Axis (top/bottom) + */ function Time(scale, orientation) { orientation = orientation.toLowerCase(); if (orientation !== "top" && orientation !== "bottom") { @@ -3324,31 +4815,46 @@ var Plottable; this._computedHeight = this._maxLabelTickLength() + 2 * this.tickLabelPadding(); return this._computedHeight; }; + Time.prototype.calculateWorstWidth = function (container, format) { + // returns the worst case width for a format + // September 29, 9999 at 12:59.9999 PM Wednesday var longDate = new Date(9999, 8, 29, 12, 59, 9999); return Plottable.Util.Text.getTextWidth(container, d3.time.format(format)(longDate)); }; + Time.prototype.getIntervalLength = function (interval) { var testDate = this._scale.domain()[0]; + + // meausre how much space one date can get var stepLength = Math.abs(this._scale.scale(interval.timeUnit.offset(testDate, interval.step)) - this._scale.scale(testDate)); return stepLength; }; + Time.prototype.isEnoughSpace = function (container, interval) { + // compute number of ticks + // if less than a certain threshold var worst = this.calculateWorstWidth(container, interval.formatString) + 2 * this.tickLabelPadding(); var stepLength = Math.min(this.getIntervalLength(interval), this.availableWidth); return worst < stepLength; }; + Time.prototype._setup = function () { _super.prototype._setup.call(this); this._majorTickLabels = this.content.append("g").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); this._minorTickLabels = this.content.append("g").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); }; + + // returns a number to index into the major/minor intervals Time.prototype.getTickLevel = function () { + // for zooming, don't start search all the way from beginning. var startingPoint = Time.minorIntervals.length - 1; var curSpan = Math.abs(this._scale.domain()[1] - this._scale.domain()[0]); if (curSpan <= this.previousSpan + 1) { startingPoint = this.previousIndex; } + + // find lowest granularity that will fit var i = startingPoint; while (i >= 0) { if (!(this.isEnoughSpace(this._minorTickLabels, Time.minorIntervals[i]) && this.isEnoughSpace(this._majorTickLabels, Time.majorIntervals[i]))) { @@ -3364,23 +4870,28 @@ var Plottable; } this.previousIndex = Math.max(0, i - 1); this.previousSpan = curSpan; + return i; }; + Time.prototype._getTickIntervalValues = function (interval) { return this._scale.tickInterval(interval.timeUnit, interval.step); }; + Time.prototype._getTickValues = function () { var index = this.getTickLevel(); var minorTicks = this._getTickIntervalValues(Time.minorIntervals[index]); var majorTicks = this._getTickIntervalValues(Time.majorIntervals[index]); return minorTicks.concat(majorTicks); }; + Time.prototype._measureTextHeight = function (container) { var fakeTickLabel = container.append("g").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); var textHeight = Plottable.Util.Text.getTextHeight(fakeTickLabel.append("text")); fakeTickLabel.remove(); return textHeight; }; + Time.prototype.renderTickLabels = function (container, interval, height) { var _this = this; container.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).remove(); @@ -3388,6 +4899,8 @@ var Plottable; tickPos.splice(0, 0, this._scale.domain()[0]); tickPos.push(this._scale.domain()[1]); var shouldCenterText = interval.step === 1; + + // only center when the label should span the whole interval var labelPos = []; if (shouldCenterText) { tickPos.map(function (datum, index) { @@ -3396,12 +4909,15 @@ var Plottable; } labelPos.push(new Date((tickPos[index + 1].valueOf() - tickPos[index].valueOf()) / 2 + tickPos[index].valueOf())); }); - } - else { + } else { labelPos = tickPos; } - labelPos = labelPos.filter(function (d) { return _this.canFitLabelFilter(container, d, d3.time.format(interval.formatString)(d), shouldCenterText); }); - var tickLabels = container.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).data(labelPos, function (d) { return d.valueOf(); }); + labelPos = labelPos.filter(function (d) { + return _this.canFitLabelFilter(container, d, d3.time.format(interval.formatString)(d), shouldCenterText); + }); + var tickLabels = container.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).data(labelPos, function (d) { + return d.valueOf(); + }); var tickLabelsEnter = tickLabels.enter().append("g").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); tickLabelsEnter.append("text"); var xTranslate = shouldCenterText ? 0 : this.tickLabelPadding(); @@ -3411,10 +4927,15 @@ var Plottable; Plottable.Util.DOM.translate(textSelection, xTranslate, yTranslate); } tickLabels.exit().remove(); - tickLabels.attr("transform", function (d) { return "translate(" + _this._scale.scale(d) + ",0)"; }); + tickLabels.attr("transform", function (d) { + return "translate(" + _this._scale.scale(d) + ",0)"; + }); var anchor = shouldCenterText ? "middle" : "start"; - tickLabels.selectAll("text").text(function (d) { return d3.time.format(interval.formatString)(d); }).style("text-anchor", anchor); + tickLabels.selectAll("text").text(function (d) { + return d3.time.format(interval.formatString)(d); + }).style("text-anchor", anchor); }; + Time.prototype.canFitLabelFilter = function (container, position, label, isCentered) { var endPosition; var startPosition; @@ -3422,33 +4943,42 @@ var Plottable; if (isCentered) { endPosition = this._scale.scale(position) + width / 2; startPosition = this._scale.scale(position) - width / 2; - } - else { + } else { endPosition = this._scale.scale(position) + width; startPosition = this._scale.scale(position); } + return endPosition < this.availableWidth && startPosition > 0; }; + Time.prototype.adjustTickLength = function (height, interval) { var tickValues = this._getTickIntervalValues(interval); - var selection = this._tickMarkContainer.selectAll("." + Plottable.Abstract.Axis.TICK_MARK_CLASS).filter(function (d) { return tickValues.map(function (x) { return x.valueOf(); }).indexOf(d.valueOf()) >= 0; }); + var selection = this._tickMarkContainer.selectAll("." + Plottable.Abstract.Axis.TICK_MARK_CLASS).filter(function (d) { + return tickValues.map(function (x) { + return x.valueOf(); + }).indexOf(d.valueOf()) >= 0; + }); if (this._orientation === "top") { height = this.availableHeight - height; } selection.attr("y2", height); }; + Time.prototype.generateLabellessTicks = function (index) { if (index < 0) { return; } + var smallTicks = this._getTickIntervalValues(Time.minorIntervals[index]); var allTicks = this._getTickValues().concat(smallTicks); + var tickMarks = this._tickMarkContainer.selectAll("." + Plottable.Abstract.Axis.TICK_MARK_CLASS).data(allTicks); tickMarks.enter().append("line").classed(Plottable.Abstract.Axis.TICK_MARK_CLASS, true); tickMarks.attr(this._generateTickMarkAttrHash()); tickMarks.exit().remove(); this.adjustTickLength(this.tickLabelPadding(), Time.minorIntervals[index]); }; + Time.prototype._doRender = function () { _super.prototype._doRender.call(this); var index = this.getTickLevel(); @@ -3459,7 +4989,11 @@ var Plottable; if (this.getIntervalLength(Time.minorIntervals[index]) * 1.5 >= totalLength) { this.generateLabellessTicks(index - 1); } + + // make minor ticks shorter this.adjustTickLength(this._maxLabelTickLength() / 2, Time.minorIntervals[index]); + + // however, we need to make major ticks longer, since they may have overlapped with some minor ticks this.adjustTickLength(this._maxLabelTickLength(), Time.majorIntervals[index]); }; Time.minorIntervals = [ @@ -3493,6 +5027,7 @@ var Plottable; { timeUnit: d3.time.year, step: 500, formatString: "%Y" }, { timeUnit: d3.time.year, step: 1000, formatString: "%Y" } ]; + Time.majorIntervals = [ { timeUnit: d3.time.day, step: 1, formatString: "%B %e, %Y" }, { timeUnit: d3.time.day, step: 1, formatString: "%B %e, %Y" }, @@ -3531,6 +5066,7 @@ var Plottable; var Axis = Plottable.Axis; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -3542,10 +5078,20 @@ var Plottable; (function (Axis) { var Numeric = (function (_super) { __extends(Numeric, _super); + /** + * Creates a NumericAxis. + * + * @constructor + * @param {QuantitativeScale} scale The QuantitativeScale to base the NumericAxis on. + * @param {string} orientation The orientation of the QuantitativeScale (top/bottom/left/right) + * @param {Formatter} [formatter] A function to format tick labels (default Formatters.general(3, false)). + */ function Numeric(scale, orientation, formatter) { - if (formatter === void 0) { formatter = Plottable.Formatters.general(3, false); } + if (typeof formatter === "undefined") { formatter = Plottable.Formatters.general(3, false); } _super.call(this, scale, orientation, formatter); this.tickLabelPositioning = "center"; + // Whether or not first/last tick label will still be displayed even if + // the label is cut off. this.showFirstTickLabel = false; this.showLastTickLabel = false; } @@ -3553,48 +5099,62 @@ var Plottable; var _this = this; var tickValues = this._getTickValues(); var testTextEl = this._tickLabelContainer.append("text").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); + + // create a new text measurerer every time; see issue #643 var measurer = Plottable.Util.Text.getTextMeasure(testTextEl); var textLengths = tickValues.map(function (v) { var formattedValue = _this._formatter(v); return measurer(formattedValue).width; }); testTextEl.remove(); + var maxTextLength = d3.max(textLengths); + if (this.tickLabelPositioning === "center") { this._computedWidth = this._maxLabelTickLength() + this.tickLabelPadding() + maxTextLength; - } - else { + } else { this._computedWidth = Math.max(this._maxLabelTickLength(), this.tickLabelPadding() + maxTextLength); } + return this._computedWidth; }; + Numeric.prototype._computeHeight = function () { var testTextEl = this._tickLabelContainer.append("text").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); + + // create a new text measurerer every time; see issue #643 var measurer = Plottable.Util.Text.getTextMeasure(testTextEl); var textHeight = measurer("test").height; testTextEl.remove(); + if (this.tickLabelPositioning === "center") { this._computedHeight = this._maxLabelTickLength() + this.tickLabelPadding() + textHeight; - } - else { + } else { this._computedHeight = Math.max(this._maxLabelTickLength(), this.tickLabelPadding() + textHeight); } + return this._computedHeight; }; + Numeric.prototype._getTickValues = function () { return this._scale.ticks(); }; + Numeric.prototype._doRender = function () { _super.prototype._doRender.call(this); + var tickLabelAttrHash = { x: 0, y: 0, dx: "0em", dy: "0.3em" }; + var tickMarkLength = this._maxLabelTickLength(); var tickLabelPadding = this.tickLabelPadding(); + var tickLabelTextAnchor = "middle"; + var labelGroupTransformX = 0; var labelGroupTransformY = 0; var labelGroupShiftX = 0; @@ -3615,8 +5175,7 @@ var Plottable; labelGroupShiftY = tickLabelPadding; break; } - } - else { + } else { switch (this.tickLabelPositioning) { case "top": tickLabelAttrHash["dy"] = "-0.3em"; @@ -3633,6 +5192,7 @@ var Plottable; break; } } + var tickMarkAttrHash = this._generateTickMarkAttrHash(); switch (this._orientation) { case "bottom": @@ -3640,46 +5200,53 @@ var Plottable; tickLabelAttrHash["dy"] = "0.95em"; labelGroupTransformY = tickMarkAttrHash["y1"] + labelGroupShiftY; break; + case "top": tickLabelAttrHash["x"] = tickMarkAttrHash["x1"]; tickLabelAttrHash["dy"] = "-.25em"; labelGroupTransformY = tickMarkAttrHash["y1"] - labelGroupShiftY; break; + case "left": tickLabelTextAnchor = "end"; labelGroupTransformX = tickMarkAttrHash["x1"] - labelGroupShiftX; tickLabelAttrHash["y"] = tickMarkAttrHash["y1"]; break; + case "right": tickLabelTextAnchor = "start"; labelGroupTransformX = tickMarkAttrHash["x1"] + labelGroupShiftX; tickLabelAttrHash["y"] = tickMarkAttrHash["y1"]; break; } + var tickLabelValues = this._getTickValues(); var tickLabels = this._tickLabelContainer.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).data(tickLabelValues); tickLabels.enter().append("text").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); tickLabels.exit().remove(); + tickLabels.style("text-anchor", tickLabelTextAnchor).style("visibility", "visible").attr(tickLabelAttrHash).text(this._formatter); + var labelGroupTransform = "translate(" + labelGroupTransformX + ", " + labelGroupTransformY + ")"; this._tickLabelContainer.attr("transform", labelGroupTransform); + if (!this.showEndTickLabels()) { this._hideEndTickLabels(); } + this._hideOverlappingTickLabels(); }; + Numeric.prototype.tickLabelPosition = function (position) { if (position == null) { return this.tickLabelPositioning; - } - else { + } else { var positionLC = position.toLowerCase(); if (this._isHorizontal()) { if (!(positionLC === "left" || positionLC === "center" || positionLC === "right")) { throw new Error(positionLC + " is not a valid tick label position for a horizontal NumericAxis"); } - } - else { + } else { if (!(positionLC === "top" || positionLC === "center" || positionLC === "bottom")) { throw new Error(positionLC + " is not a valid tick label position for a vertical NumericAxis"); } @@ -3689,28 +5256,25 @@ var Plottable; return this; } }; + Numeric.prototype.showEndTickLabel = function (orientation, show) { if ((this._isHorizontal() && orientation === "left") || (!this._isHorizontal() && orientation === "bottom")) { if (show === undefined) { return this.showFirstTickLabel; - } - else { + } else { this.showFirstTickLabel = show; this._render(); return this; } - } - else if ((this._isHorizontal() && orientation === "right") || (!this._isHorizontal() && orientation === "top")) { + } else if ((this._isHorizontal() && orientation === "right") || (!this._isHorizontal() && orientation === "top")) { if (show === undefined) { return this.showLastTickLabel; - } - else { + } else { this.showLastTickLabel = show; this._render(); return this; } - } - else { + } else { throw new Error("Attempt to show " + orientation + " tick label on a " + (this._isHorizontal() ? "horizontal" : "vertical") + " axis"); } }; @@ -3721,6 +5285,7 @@ var Plottable; var Axis = Plottable.Axis; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -3732,35 +5297,51 @@ var Plottable; (function (Axis) { var Category = (function (_super) { __extends(Category, _super); + /** + * Creates a CategoryAxis. + * + * A CategoryAxis takes an OrdinalScale and includes word-wrapping algorithms and advanced layout logic to try to + * display the scale as efficiently as possible. + * + * @constructor + * @param {OrdinalScale} scale The scale to base the Axis on. + * @param {string} orientation The orientation of the Axis (top/bottom/left/right) + * @param {Formatter} [formatter] The Formatter for the Axis (default Formatters.identity()) + */ function Category(scale, orientation, formatter) { - if (orientation === void 0) { orientation = "bottom"; } - if (formatter === void 0) { formatter = Plottable.Formatters.identity(); } - _super.call(this, scale, orientation, formatter); + if (typeof orientation === "undefined") { orientation = "bottom"; } + if (typeof formatter === "undefined") { formatter = Plottable.Formatters.identity(); } var _this = this; + _super.call(this, scale, orientation, formatter); this.classed("category-axis", true); if (scale.rangeType() !== "bands") { throw new Error("Only rangeBands category axes are implemented"); } - this._scale.broadcaster.registerListener(this, function () { return _this._invalidateLayout(); }); + this._scale.broadcaster.registerListener(this, function () { + return _this._invalidateLayout(); + }); } Category.prototype._setup = function () { _super.prototype._setup.call(this); this.measurer = new Plottable.Util.Text.CachingCharacterMeasurer(this._tickLabelContainer); }; + Category.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var widthRequiredByTicks = this._isHorizontal() ? 0 : this._maxLabelTickLength() + this.tickLabelPadding(); var heightRequiredByTicks = this._isHorizontal() ? this._maxLabelTickLength() + this.tickLabelPadding() : 0; + if (this._scale.domain().length === 0) { return { width: 0, height: 0, wantsWidth: false, wantsHeight: false }; } + var fakeScale = this._scale.copy(); if (this._isHorizontal()) { fakeScale.range([0, offeredWidth]); - } - else { + } else { fakeScale.range([offeredHeight, 0]); } var textResult = this.measureTicks(offeredWidth, offeredHeight, fakeScale, this._scale.domain()); + return { width: textResult.usedWidth + widthRequiredByTicks, height: textResult.usedHeight + heightRequiredByTicks, @@ -3768,19 +5349,29 @@ var Plottable; wantsHeight: !textResult.textFits }; }; + Category.prototype._getTickValues = function () { return this._scale.domain(); }; + Category.prototype.measureTicks = function (axisWidth, axisHeight, scale, dataOrTicks) { var draw = typeof dataOrTicks[0] !== "string"; var self = this; var textWriteResults = []; - var tm = function (s) { return self.measurer.measure(s); }; - var iterator = draw ? function (f) { return dataOrTicks.each(f); } : function (f) { return dataOrTicks.forEach(f); }; + var tm = function (s) { + return self.measurer.measure(s); + }; + var iterator = draw ? function (f) { + return dataOrTicks.each(f); + } : function (f) { + return dataOrTicks.forEach(f); + }; + iterator(function (d) { var bandWidth = scale.fullBandStartAndWidth(d)[1]; var width = self._isHorizontal() ? bandWidth : axisWidth - self._maxLabelTickLength() - self.tickLabelPadding(); var height = self._isHorizontal() ? axisHeight - self._maxLabelTickLength() - self.tickLabelPadding() : bandWidth; + var textWriteResult; var formatter = self._formatter; if (draw) { @@ -3792,24 +5383,35 @@ var Plottable; xAlign: xAlign[self._orientation], yAlign: yAlign[self._orientation] }); - } - else { + } else { textWriteResult = Plottable.Util.Text.writeText(formatter(d), width, height, tm, true); } + textWriteResults.push(textWriteResult); }); + var widthFn = this._isHorizontal() ? d3.sum : d3.max; var heightFn = this._isHorizontal() ? d3.max : d3.sum; return { - textFits: textWriteResults.every(function (t) { return t.textFits; }), - usedWidth: widthFn(textWriteResults, function (t) { return t.usedWidth; }), - usedHeight: heightFn(textWriteResults, function (t) { return t.usedHeight; }) + textFits: textWriteResults.every(function (t) { + return t.textFits; + }), + usedWidth: widthFn(textWriteResults, function (t) { + return t.usedWidth; + }), + usedHeight: heightFn(textWriteResults, function (t) { + return t.usedHeight; + }) }; }; + Category.prototype._doRender = function () { var _this = this; _super.prototype._doRender.call(this); - var tickLabels = this._tickLabelContainer.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).data(this._scale.domain(), function (d) { return d; }); + var tickLabels = this._tickLabelContainer.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).data(this._scale.domain(), function (d) { + return d; + }); + var getTickLabelTransform = function (d, i) { var startAndWidth = _this._scale.fullBandStartAndWidth(d); var bandStartPosition = startAndWidth[0]; @@ -3820,15 +5422,22 @@ var Plottable; tickLabels.enter().append("g").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true); tickLabels.exit().remove(); tickLabels.attr("transform", getTickLabelTransform); + + // erase all text first, then rewrite tickLabels.text(""); this.measureTicks(this.availableWidth, this.availableHeight, this._scale, tickLabels); var translate = this._isHorizontal() ? [this._scale.rangeBand() / 2, 0] : [0, this._scale.rangeBand() / 2]; + var xTranslate = this._orientation === "right" ? this._maxLabelTickLength() + this.tickLabelPadding() : 0; var yTranslate = this._orientation === "bottom" ? this._maxLabelTickLength() + this.tickLabelPadding() : 0; Plottable.Util.DOM.translate(this._tickLabelContainer, xTranslate, yTranslate); Plottable.Util.DOM.translate(this._tickMarkContainer, translate[0], translate[1]); }; + Category.prototype._computeLayout = function (xOrigin, yOrigin, availableWidth, availableHeight) { + // When anyone calls _invalidateLayout, _computeLayout will be called + // on everyone, including this. Since CSS or something might have + // affected the size of the characters, clear the cache. this.measurer.clear(); return _super.prototype._computeLayout.call(this, xOrigin, yOrigin, availableWidth, availableHeight); }; @@ -3839,6 +5448,7 @@ var Plottable; var Axis = Plottable.Axis; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -3850,9 +5460,16 @@ var Plottable; (function (Component) { var Label = (function (_super) { __extends(Label, _super); + /** + * Creates a Label. + * + * @constructor + * @param {string} [displayText] The text of the Label. + * @param {string} [orientation] The orientation of the Label (horizontal/vertical-left/vertical-right). + */ function Label(displayText, orientation) { - if (displayText === void 0) { displayText = ""; } - if (orientation === void 0) { orientation = "horizontal"; } + if (typeof displayText === "undefined") { displayText = ""; } + if (typeof orientation === "undefined") { orientation = "horizontal"; } _super.call(this); this.classed("label", true); this.text(displayText); @@ -3865,8 +5482,7 @@ var Plottable; } if (orientation === "horizontal" || orientation === "left" || orientation === "right") { this.orientation = orientation; - } - else { + } else { throw new Error(orientation + " is not a valid orientation for LabelComponent"); } this.xAlign("center").yAlign("center"); @@ -3885,10 +5501,12 @@ var Plottable; this.yAlignment = alignmentLC; return this; }; + Label.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var desiredWH = this.measurer(this._text); var desiredWidth = (this.orientation === "horizontal" ? desiredWH.width : desiredWH.height); var desiredHeight = (this.orientation === "horizontal" ? desiredWH.height : desiredWH.width); + return { width: desiredWidth, height: desiredHeight, @@ -3896,22 +5514,24 @@ var Plottable; wantsHeight: desiredHeight > offeredHeight }; }; + Label.prototype._setup = function () { _super.prototype._setup.call(this); this.textContainer = this.content.append("g"); this.measurer = Plottable.Util.Text.getTextMeasure(this.textContainer); this.text(this._text); }; + Label.prototype.text = function (displayText) { if (displayText === undefined) { return this._text; - } - else { + } else { this._text = displayText; this._invalidateLayout(); return this; } }; + Label.prototype._doRender = function () { _super.prototype._doRender.call(this); this.textContainer.text(""); @@ -3919,19 +5539,20 @@ var Plottable; var truncatedText = Plottable.Util.Text.getTruncatedText(this._text, dimension, this.measurer); if (this.orientation === "horizontal") { Plottable.Util.Text.writeLineHorizontally(truncatedText, this.textContainer, this.availableWidth, this.availableHeight, this.xAlignment, this.yAlignment); - } - else { + } else { Plottable.Util.Text.writeLineVertically(truncatedText, this.textContainer, this.availableWidth, this.availableHeight, this.xAlignment, this.yAlignment, this.orientation); } }; + Label.prototype._computeLayout = function (xOffset, yOffset, availableWidth, availableHeight) { _super.prototype._computeLayout.call(this, xOffset, yOffset, availableWidth, availableHeight); - this.measurer = Plottable.Util.Text.getTextMeasure(this.textContainer); + this.measurer = Plottable.Util.Text.getTextMeasure(this.textContainer); // reset it in case fonts have changed return this; }; return Label; })(Plottable.Abstract.Component); Component.Label = Label; + var TitleLabel = (function (_super) { __extends(TitleLabel, _super); function TitleLabel(text, orientation) { @@ -3941,6 +5562,7 @@ var Plottable; return TitleLabel; })(Label); Component.TitleLabel = TitleLabel; + var AxisLabel = (function (_super) { __extends(AxisLabel, _super); function AxisLabel(text, orientation) { @@ -3954,6 +5576,7 @@ var Plottable; var Component = Plottable.Component; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -3965,6 +5588,17 @@ var Plottable; (function (Component) { var Legend = (function (_super) { __extends(Legend, _super); + /** + * Creates a Legend. + * + * A legend consists of a series of legend rows, each with a color and label taken from the `colorScale`. + * The rows will be displayed in the order of the `colorScale` domain. + * This legend also allows interactions, through the functions `toggleCallback` and `hoverCallback` + * Setting a callback will also put classes on the individual rows. + * + * @constructor + * @param {Scale.Color} colorScale + */ function Legend(colorScale) { _super.call(this); this.classed("legend", true); @@ -3980,6 +5614,7 @@ var Plottable; this.colorScale.broadcaster.deregisterListener(this); } }; + Legend.prototype.toggleCallback = function (callback) { if (callback !== undefined) { this._toggleCallback = callback; @@ -3987,11 +5622,11 @@ var Plottable; this.updateListeners(); this.updateClasses(); return this; - } - else { + } else { return this._toggleCallback; } }; + Legend.prototype.hoverCallback = function (callback) { if (callback !== undefined) { this._hoverCallback = callback; @@ -3999,11 +5634,11 @@ var Plottable; this.updateListeners(); this.updateClasses(); return this; - } - else { + } else { return this._hoverCallback; } }; + Legend.prototype.scale = function (scale) { var _this = this; if (scale != null) { @@ -4011,14 +5646,16 @@ var Plottable; this.colorScale.broadcaster.deregisterListener(this); } this.colorScale = scale; - this.colorScale.broadcaster.registerListener(this, function () { return _this.updateDomain(); }); + this.colorScale.broadcaster.registerListener(this, function () { + return _this.updateDomain(); + }); this.updateDomain(); return this; - } - else { + } else { return this.colorScale; } }; + Legend.prototype.updateDomain = function () { if (this._toggleCallback != null) { this.isOff = Plottable.Util.Methods.intersection(this.isOff, d3.set(this.scale().domain())); @@ -4028,19 +5665,23 @@ var Plottable; } this._invalidateLayout(); }; + Legend.prototype._computeLayout = function (xOrigin, yOrigin, availableWidth, availableHeight) { _super.prototype._computeLayout.call(this, xOrigin, yOrigin, availableWidth, availableHeight); var textHeight = this.measureTextHeight(); var totalNumRows = this.colorScale.domain().length; this.nRowsDrawn = Math.min(totalNumRows, Math.floor(this.availableHeight / textHeight)); }; + Legend.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var textHeight = this.measureTextHeight(); var totalNumRows = this.colorScale.domain().length; var rowsICanFit = Math.min(totalNumRows, Math.floor((offeredHeight - 2 * Legend.MARGIN) / textHeight)); var fakeLegendEl = this.content.append("g").classed(Legend.SUBELEMENT_CLASS, true); var fakeText = fakeLegendEl.append("text"); - var maxWidth = d3.max(this.colorScale.domain(), function (d) { return Plottable.Util.Text.getTextWidth(fakeText, d); }); + var maxWidth = d3.max(this.colorScale.domain(), function (d) { + return Plottable.Util.Text.getTextWidth(fakeText, d); + }); fakeLegendEl.remove(); maxWidth = maxWidth === undefined ? 0 : maxWidth; var desiredWidth = rowsICanFit === 0 ? 0 : maxWidth + textHeight + 2 * Legend.MARGIN; @@ -4052,26 +5693,36 @@ var Plottable; wantsHeight: offeredHeight < desiredHeight }; }; + Legend.prototype.measureTextHeight = function () { + // note: can't be called before anchoring atm var fakeLegendEl = this.content.append("g").classed(Legend.SUBELEMENT_CLASS, true); var textHeight = Plottable.Util.Text.getTextHeight(fakeLegendEl.append("text")); + + // HACKHACK if (textHeight === 0) { textHeight = 1; } fakeLegendEl.remove(); return textHeight; }; + Legend.prototype._doRender = function () { _super.prototype._doRender.call(this); var domain = this.colorScale.domain().slice(0, this.nRowsDrawn); var textHeight = this.measureTextHeight(); var availableWidth = this.availableWidth - textHeight - Legend.MARGIN; var r = textHeight * 0.3; - var legend = this.content.selectAll("." + Legend.SUBELEMENT_CLASS).data(domain, function (d) { return d; }); + var legend = this.content.selectAll("." + Legend.SUBELEMENT_CLASS).data(domain, function (d) { + return d; + }); var legendEnter = legend.enter().append("g").classed(Legend.SUBELEMENT_CLASS, true); + legendEnter.append("circle"); legendEnter.append("g").classed("text-container", true); + legend.exit().remove(); + legend.selectAll("circle").attr("cx", textHeight / 2).attr("cy", textHeight / 2).attr("r", r).attr("fill", this.colorScale._d3Scale); legend.selectAll("g.text-container").text("").attr("transform", "translate(" + textHeight + ", 0)").each(function (d) { var d3this = d3.select(this); @@ -4080,12 +5731,15 @@ var Plottable; var writeLineMeasure = measure(writeLine); Plottable.Util.Text.writeLineHorizontally(writeLine, d3this, writeLineMeasure.width, writeLineMeasure.height); }); + legend.attr("transform", function (d) { return "translate(" + Legend.MARGIN + "," + (domain.indexOf(d) * textHeight + Legend.MARGIN) + ")"; }); + this.updateClasses(); this.updateListeners(); }; + Legend.prototype.updateListeners = function () { var _this = this; if (!this._isSetup) { @@ -4093,35 +5747,40 @@ var Plottable; } var dataSelection = this.content.selectAll("." + Legend.SUBELEMENT_CLASS); if (this._hoverCallback != null) { - var hoverRow = function (mouseover) { return function (datum) { - _this.datumCurrentlyFocusedOn = mouseover ? datum : undefined; - _this._hoverCallback(_this.datumCurrentlyFocusedOn); - _this.updateClasses(); - }; }; + // tag the element that is being hovered over with the class "focus" + // this callback will trigger with the specific element being hovered over. + var hoverRow = function (mouseover) { + return function (datum) { + _this.datumCurrentlyFocusedOn = mouseover ? datum : undefined; + _this._hoverCallback(_this.datumCurrentlyFocusedOn); + _this.updateClasses(); + }; + }; dataSelection.on("mouseover", hoverRow(true)); dataSelection.on("mouseout", hoverRow(false)); - } - else { + } else { + // remove all mouseover/mouseout listeners dataSelection.on("mouseover", null); dataSelection.on("mouseout", null); } + if (this._toggleCallback != null) { dataSelection.on("click", function (datum) { var turningOn = _this.isOff.has(datum); if (turningOn) { _this.isOff.remove(datum); - } - else { + } else { _this.isOff.add(datum); } _this._toggleCallback(datum, turningOn); _this.updateClasses(); }); - } - else { + } else { + // remove all click listeners dataSelection.on("click", null); } }; + Legend.prototype.updateClasses = function () { var _this = this; if (!this._isSetup) { @@ -4129,18 +5788,22 @@ var Plottable; } var dataSelection = this.content.selectAll("." + Legend.SUBELEMENT_CLASS); if (this._hoverCallback != null) { - dataSelection.classed("focus", function (d) { return _this.datumCurrentlyFocusedOn === d; }); + dataSelection.classed("focus", function (d) { + return _this.datumCurrentlyFocusedOn === d; + }); dataSelection.classed("hover", this.datumCurrentlyFocusedOn !== undefined); - } - else { + } else { dataSelection.classed("hover", false); dataSelection.classed("focus", false); } if (this._toggleCallback != null) { - dataSelection.classed("toggled-on", function (d) { return !_this.isOff.has(d); }); - dataSelection.classed("toggled-off", function (d) { return _this.isOff.has(d); }); - } - else { + dataSelection.classed("toggled-on", function (d) { + return !_this.isOff.has(d); + }); + dataSelection.classed("toggled-off", function (d) { + return _this.isOff.has(d); + }); + } else { dataSelection.classed("toggled-on", false); dataSelection.classed("toggled-off", false); } @@ -4154,6 +5817,7 @@ var Plottable; var Component = Plottable.Component; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4165,9 +5829,16 @@ var Plottable; (function (Component) { var Gridlines = (function (_super) { __extends(Gridlines, _super); + /** + * Creates a set of Gridlines. + * @constructor + * + * @param {QuantitativeScale} xScale The scale to base the x gridlines on. Pass null if no gridlines are desired. + * @param {QuantitativeScale} yScale The scale to base the y gridlines on. Pass null if no gridlines are desired. + */ function Gridlines(xScale, yScale) { - _super.call(this); var _this = this; + _super.call(this); if (xScale == null && yScale == null) { throw new Error("Gridlines must have at least one scale"); } @@ -4175,10 +5846,14 @@ var Plottable; this.xScale = xScale; this.yScale = yScale; if (this.xScale != null) { - this.xScale.broadcaster.registerListener(this, function () { return _this._render(); }); + this.xScale.broadcaster.registerListener(this, function () { + return _this._render(); + }); } if (this.yScale != null) { - this.yScale.broadcaster.registerListener(this, function () { return _this._render(); }); + this.yScale.broadcaster.registerListener(this, function () { + return _this._render(); + }); } } Gridlines.prototype.remove = function () { @@ -4191,35 +5866,47 @@ var Plottable; } return this; }; + Gridlines.prototype._setup = function () { _super.prototype._setup.call(this); this.xLinesContainer = this.content.append("g").classed("x-gridlines", true); this.yLinesContainer = this.content.append("g").classed("y-gridlines", true); }; + Gridlines.prototype._doRender = function () { _super.prototype._doRender.call(this); this.redrawXLines(); this.redrawYLines(); }; + Gridlines.prototype.redrawXLines = function () { var _this = this; if (this.xScale != null) { var xTicks = this.xScale.ticks(); - var getScaledXValue = function (tickVal) { return _this.xScale.scale(tickVal); }; + var getScaledXValue = function (tickVal) { + return _this.xScale.scale(tickVal); + }; var xLines = this.xLinesContainer.selectAll("line").data(xTicks); xLines.enter().append("line"); - xLines.attr("x1", getScaledXValue).attr("y1", 0).attr("x2", getScaledXValue).attr("y2", this.availableHeight).classed("zeroline", function (t) { return t === 0; }); + xLines.attr("x1", getScaledXValue).attr("y1", 0).attr("x2", getScaledXValue).attr("y2", this.availableHeight).classed("zeroline", function (t) { + return t === 0; + }); xLines.exit().remove(); } }; + Gridlines.prototype.redrawYLines = function () { var _this = this; if (this.yScale != null) { var yTicks = this.yScale.ticks(); - var getScaledYValue = function (tickVal) { return _this.yScale.scale(tickVal); }; + var getScaledYValue = function (tickVal) { + return _this.yScale.scale(tickVal); + }; var yLines = this.yLinesContainer.selectAll("line").data(yTicks); yLines.enter().append("line"); - yLines.attr("x1", 0).attr("y1", getScaledYValue).attr("x2", this.availableWidth).attr("y2", getScaledYValue).classed("zeroline", function (t) { return t === 0; }); + yLines.attr("x1", 0).attr("y1", getScaledYValue).attr("x2", this.availableWidth).attr("y2", getScaledYValue).classed("zeroline", function (t) { + return t === 0; + }); yLines.exit().remove(); } }; @@ -4230,6 +5917,7 @@ var Plottable; var Component = Plottable.Component; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4241,32 +5929,48 @@ var Plottable; (function (Abstract) { var XYPlot = (function (_super) { __extends(XYPlot, _super); + /** + * Creates an XYPlot. + * + * @constructor + * @param {any[]|DataSource} [dataset] The data or DataSource to be associated with this Renderer. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function XYPlot(dataset, xScale, yScale) { _super.call(this, dataset); if (xScale == null || yScale == null) { throw new Error("XYPlots require an xScale and yScale"); } this.classed("xy-plot", true); - this.project("x", "x", xScale); - this.project("y", "y", yScale); + + this.project("x", "x", xScale); // default accessor + this.project("y", "y", yScale); // default accessor } XYPlot.prototype.project = function (attrToSet, accessor, scale) { + // We only want padding and nice-ing on scales that will correspond to axes / pixel layout. + // So when we get an "x" or "y" scale, enable autoNiceing and autoPadding. if (attrToSet === "x" && scale != null) { this.xScale = scale; this._updateXDomainer(); } + if (attrToSet === "y" && scale != null) { this.yScale = scale; this._updateYDomainer(); } + _super.prototype.project.call(this, attrToSet, accessor, scale); + return this; }; + XYPlot.prototype._computeLayout = function (xOffset, yOffset, availableWidth, availableHeight) { _super.prototype._computeLayout.call(this, xOffset, yOffset, availableWidth, availableHeight); this.xScale.range([0, this.availableWidth]); this.yScale.range([this.availableHeight, 0]); }; + XYPlot.prototype._updateXDomainer = function () { if (this.xScale instanceof Abstract.QuantitativeScale) { var scale = this.xScale; @@ -4275,6 +5979,7 @@ var Plottable; } } }; + XYPlot.prototype._updateYDomainer = function () { if (this.yScale instanceof Abstract.QuantitativeScale) { var scale = this.yScale; @@ -4290,6 +5995,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4301,6 +6007,14 @@ var Plottable; (function (Plot) { var Scatter = (function (_super) { __extends(Scatter, _super); + /** + * Creates a ScatterPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function Scatter(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this._animators = { @@ -4308,9 +6022,11 @@ var Plottable; "circles": new Plottable.Animator.IterativeDelay().duration(250).delay(5) }; this.classed("scatter-plot", true); - this.project("r", 3); - this.project("opacity", 0.6); - this.project("fill", function () { return Plottable.Core.Colors.INDIGO; }); + this.project("r", 3); // default + this.project("opacity", 0.6); // default + this.project("fill", function () { + return Plottable.Core.Colors.INDIGO; + }); // default } Scatter.prototype.project = function (attrToSet, accessor, scale) { attrToSet = attrToSet === "cx" ? "x" : attrToSet; @@ -4318,21 +6034,28 @@ var Plottable; _super.prototype.project.call(this, attrToSet, accessor, scale); return this; }; + Scatter.prototype._paint = function () { _super.prototype._paint.call(this); + var attrToProjector = this._generateAttrToProjector(); attrToProjector["cx"] = attrToProjector["x"]; attrToProjector["cy"] = attrToProjector["y"]; delete attrToProjector["x"]; delete attrToProjector["y"]; + var circles = this.renderArea.selectAll("circle").data(this._dataSource.data()); circles.enter().append("circle"); + if (this._dataChanged) { var rFunction = attrToProjector["r"]; - attrToProjector["r"] = function () { return 0; }; + attrToProjector["r"] = function () { + return 0; + }; this._applyAnimatedAttributes(circles, "circles-reset", attrToProjector); attrToProjector["r"] = rFunction; } + this._applyAnimatedAttributes(circles, "circles", attrToProjector); circles.exit().remove(); }; @@ -4343,6 +6066,7 @@ var Plottable; var Plot = Plottable.Plot; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4354,16 +6078,29 @@ var Plottable; (function (Plot) { var Grid = (function (_super) { __extends(Grid, _super); + /** + * Creates a GridPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {OrdinalScale} xScale The x scale to use. + * @param {OrdinalScale} yScale The y scale to use. + * @param {ColorScale|InterpolatedColorScale} colorScale The color scale to use for each grid + * cell. + */ function Grid(dataset, xScale, yScale, colorScale) { _super.call(this, dataset, xScale, yScale); this._animators = { "cells": new Plottable.Animator.Null() }; this.classed("grid-plot", true); + + // The x and y scales should render in bands with no padding this.xScale.rangeType("bands", 0, 0); this.yScale.rangeType("bands", 0, 0); + this.colorScale = colorScale; - this.project("fill", "value", colorScale); + this.project("fill", "value", colorScale); // default } Grid.prototype.project = function (attrToSet, accessor, scale) { _super.prototype.project.call(this, attrToSet, accessor, scale); @@ -4372,15 +6109,24 @@ var Plottable; } return this; }; + Grid.prototype._paint = function () { _super.prototype._paint.call(this); + var cells = this.renderArea.selectAll("rect").data(this._dataSource.data()); cells.enter().append("rect"); + var xStep = this.xScale.rangeBand(); var yStep = this.yScale.rangeBand(); + var attrToProjector = this._generateAttrToProjector(); - attrToProjector["width"] = function () { return xStep; }; - attrToProjector["height"] = function () { return yStep; }; + attrToProjector["width"] = function () { + return xStep; + }; + attrToProjector["height"] = function () { + return yStep; + }; + this._applyAnimatedAttributes(cells, "cells", attrToProjector); cells.exit().remove(); }; @@ -4391,6 +6137,7 @@ var Plottable; var Plot = Plottable.Plot; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4400,8 +6147,20 @@ var __extends = this.__extends || function (d, b) { var Plottable; (function (Plottable) { (function (Abstract) { + /* + * An Abstract.BarPlot is the base implementation for HorizontalBarPlot and + * VerticalBarPlot. It should not be used on its own. + */ var BarPlot = (function (_super) { __extends(BarPlot, _super); + /** + * Creates an AbstractBarPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function BarPlot(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this._baselineValue = 0; @@ -4412,7 +6171,13 @@ var Plottable; "baseline": new Plottable.Animator.Null() }; this.classed("bar-plot", true); - this.project("fill", function () { return Plottable.Core.Colors.INDIGO; }); + this.project("fill", function () { + return Plottable.Core.Colors.INDIGO; + }); + + // because this._baselineValue was not initialized during the super() + // call, we must call this in order to get this._baselineValue + // to be used by the Domainer. this.baseline(this._baselineValue); } BarPlot.prototype._setup = function () { @@ -4420,34 +6185,52 @@ var Plottable; this._baseline = this.renderArea.append("line").classed("baseline", true); this._bars = this.renderArea.selectAll("rect").data([]); }; + BarPlot.prototype._paint = function () { _super.prototype._paint.call(this); this._bars = this.renderArea.selectAll("rect").data(this._dataSource.data()); this._bars.enter().append("rect"); + var primaryScale = this._isVertical ? this.yScale : this.xScale; var scaledBaseline = primaryScale.scale(this._baselineValue); var positionAttr = this._isVertical ? "y" : "x"; var dimensionAttr = this._isVertical ? "height" : "width"; + if (this._dataChanged && this._animate) { var resetAttrToProjector = this._generateAttrToProjector(); - resetAttrToProjector[positionAttr] = function () { return scaledBaseline; }; - resetAttrToProjector[dimensionAttr] = function () { return 0; }; + resetAttrToProjector[positionAttr] = function () { + return scaledBaseline; + }; + resetAttrToProjector[dimensionAttr] = function () { + return 0; + }; this._applyAnimatedAttributes(this._bars, "bars-reset", resetAttrToProjector); } + var attrToProjector = this._generateAttrToProjector(); if (attrToProjector["fill"] != null) { - this._bars.attr("fill", attrToProjector["fill"]); + this._bars.attr("fill", attrToProjector["fill"]); // so colors don't animate } this._applyAnimatedAttributes(this._bars, "bars", attrToProjector); + this._bars.exit().remove(); + var baselineAttr = { "x1": this._isVertical ? 0 : scaledBaseline, "y1": this._isVertical ? scaledBaseline : 0, "x2": this._isVertical ? this.availableWidth : scaledBaseline, "y2": this._isVertical ? scaledBaseline : this.availableHeight }; + this._applyAnimatedAttributes(this._baseline, "baseline", baselineAttr); }; + + /** + * Sets the baseline for the bars to the specified value. + * + * @param {number} value The value to position the baseline at. + * @return {AbstractBarPlot} The calling AbstractBarPlot. + */ BarPlot.prototype.baseline = function (value) { this._baselineValue = value; this._updateXDomainer(); @@ -4455,6 +6238,15 @@ var Plottable; this._render(); return this; }; + + /** + * Sets the bar alignment relative to the independent axis. + * VerticalBarPlot supports "left", "center", "right" + * HorizontalBarPlot supports "top", "center", "bottom" + * + * @param {string} alignment The desired alignment. + * @return {AbstractBarPlot} The calling AbstractBarPlot. + */ BarPlot.prototype.barAlignment = function (alignment) { var alignmentLC = alignment.toLowerCase(); var align2factor = this.constructor._BarAlignmentToFactor; @@ -4462,67 +6254,87 @@ var Plottable; throw new Error("unsupported bar alignment"); } this._barAlignmentFactor = align2factor[alignmentLC]; + this._render(); return this; }; + BarPlot.prototype.parseExtent = function (input) { if (typeof (input) === "number") { return { min: input, max: input }; - } - else if (input instanceof Object && "min" in input && "max" in input) { + } else if (input instanceof Object && "min" in input && "max" in input) { return input; - } - else { + } else { throw new Error("input '" + input + "' can't be parsed as an IExtent"); } }; + BarPlot.prototype.selectBar = function (xValOrExtent, yValOrExtent, select) { - if (select === void 0) { select = true; } + if (typeof select === "undefined") { select = true; } if (!this._isSetup) { return null; } + var selectedBars = []; + var xExtent = this.parseExtent(xValOrExtent); var yExtent = this.parseExtent(yValOrExtent); + + // the SVGRects are positioned with sub-pixel accuracy (the default unit + // for the x, y, height & width attributes), but user selections (e.g. via + // mouse events) usually have pixel accuracy. A tolerance of half-a-pixel + // seems appropriate: var tolerance = 0.5; + + // currently, linear scan the bars. If inversion is implemented on non-numeric scales we might be able to do better. this._bars.each(function (d) { var bbox = this.getBBox(); if (bbox.x + bbox.width >= xExtent.min - tolerance && bbox.x <= xExtent.max + tolerance && bbox.y + bbox.height >= yExtent.min - tolerance && bbox.y <= yExtent.max + tolerance) { selectedBars.push(this); } }); + if (selectedBars.length > 0) { var selection = d3.selectAll(selectedBars); selection.classed("selected", select); return selection; - } - else { + } else { return null; } }; + + /** + * Deselects all bars. + * @return {AbstractBarPlot} The calling AbstractBarPlot. + */ BarPlot.prototype.deselectAll = function () { if (this._isSetup) { this._bars.classed("selected", false); } return this; }; + BarPlot.prototype._updateDomainer = function (scale) { if (scale instanceof Abstract.QuantitativeScale) { var qscale = scale; if (!qscale._userSetDomainer) { if (this._baselineValue != null) { qscale.domainer().addPaddingException(this._baselineValue, "BAR_PLOT+" + this._plottableID).addIncludedValue(this._baselineValue, "BAR_PLOT+" + this._plottableID); - } - else { + } else { qscale.domainer().removePaddingException("BAR_PLOT+" + this._plottableID).removeIncludedValue("BAR_PLOT+" + this._plottableID); } qscale.domainer().pad(); } + + // prepending "BAR_PLOT" is unnecessary but reduces likely of user accidentally creating collisions qscale._autoDomainIfAutomaticMode(); } }; + BarPlot.prototype._generateAttrToProjector = function () { var _this = this; + // Primary scale/direction: the "length" of the bars + // Secondary scale/direction: the "width" of the bars var attrToProjector = _super.prototype._generateAttrToProjector.call(this); var primaryScale = this._isVertical ? this.yScale : this.xScale; var secondaryScale = this._isVertical ? this.xScale : this.yScale; @@ -4532,28 +6344,42 @@ var Plottable; var scaledBaseline = primaryScale.scale(this._baselineValue); if (attrToProjector["width"] == null) { var constantWidth = bandsMode ? secondaryScale.rangeBand() : BarPlot.DEFAULT_WIDTH; - attrToProjector["width"] = function (d, i) { return constantWidth; }; + attrToProjector["width"] = function (d, i) { + return constantWidth; + }; } + var positionF = attrToProjector[secondaryAttr]; var widthF = attrToProjector["width"]; if (!bandsMode) { - attrToProjector[secondaryAttr] = function (d, i) { return positionF(d, i) - widthF(d, i) * _this._barAlignmentFactor; }; - } - else { + attrToProjector[secondaryAttr] = function (d, i) { + return positionF(d, i) - widthF(d, i) * _this._barAlignmentFactor; + }; + } else { var bandWidth = secondaryScale.rangeBand(); - attrToProjector[secondaryAttr] = function (d, i) { return positionF(d, i) - widthF(d, i) / 2 + bandWidth / 2; }; + attrToProjector[secondaryAttr] = function (d, i) { + return positionF(d, i) - widthF(d, i) / 2 + bandWidth / 2; + }; } + var originalPositionFn = attrToProjector[primaryAttr]; attrToProjector[primaryAttr] = function (d, i) { var originalPos = originalPositionFn(d, i); + + // If it is past the baseline, it should start at the baselin then width/height + // carries it over. If it's not past the baseline, leave it at original position and + // then width/height carries it to baseline return (originalPos > scaledBaseline) ? scaledBaseline : originalPos; }; + attrToProjector["height"] = function (d, i) { return Math.abs(scaledBaseline - originalPositionFn(d, i)); }; + return attrToProjector; }; BarPlot.DEFAULT_WIDTH = 10; + BarPlot._BarAlignmentToFactor = {}; return BarPlot; })(Abstract.XYPlot); @@ -4562,6 +6388,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4571,8 +6398,25 @@ var __extends = this.__extends || function (d, b) { var Plottable; (function (Plottable) { (function (Plot) { + /** + * A VerticalBarPlot draws bars vertically. + * Key projected attributes: + * - "width" - the horizontal width of a bar. + * - if an ordinal scale is attached, this defaults to ordinalScale.rangeBand() + * - if a quantitative scale is attached, this defaults to 10 + * - "x" - the horizontal position of a bar + * - "y" - the vertical height of a bar + */ var VerticalBar = (function (_super) { __extends(VerticalBar, _super); + /** + * Creates a VerticalBarPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ function VerticalBar(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this._isVertical = true; @@ -4588,6 +6432,7 @@ var Plottable; var Plot = Plottable.Plot; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4597,8 +6442,25 @@ var __extends = this.__extends || function (d, b) { var Plottable; (function (Plottable) { (function (Plot) { + /** + * A HorizontalBarPlot draws bars horizontally. + * Key projected attributes: + * - "width" - the vertical height of a bar (since the bar is rotated horizontally) + * - if an ordinal scale is attached, this defaults to ordinalScale.rangeBand() + * - if a quantitative scale is attached, this defaults to 10 + * - "x" - the horizontal length of a bar + * - "y" - the vertical position of a bar + */ var HorizontalBar = (function (_super) { __extends(HorizontalBar, _super); + /** + * Creates a HorizontalBarPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function HorizontalBar(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this.isVertical = false; @@ -4606,8 +6468,12 @@ var Plottable; HorizontalBar.prototype._updateXDomainer = function () { this._updateDomainer(this.xScale); }; + HorizontalBar.prototype._generateAttrToProjector = function () { var attrToProjector = _super.prototype._generateAttrToProjector.call(this); + + // by convention, for API users the 2ndary dimension of a bar is always called its "width", so + // the "width" of a horziontal bar plot is actually its "height" from the perspective of a svg rect var widthF = attrToProjector["width"]; attrToProjector["width"] = attrToProjector["height"]; attrToProjector["height"] = widthF; @@ -4621,6 +6487,7 @@ var Plottable; var Plot = Plottable.Plot; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4632,6 +6499,14 @@ var Plottable; (function (Plot) { var Line = (function (_super) { __extends(Line, _super); + /** + * Creates a LinePlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function Line(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this._animators = { @@ -4639,27 +6514,38 @@ var Plottable; "line": new Plottable.Animator.Default().duration(600).easing("exp-in-out") }; this.classed("line-plot", true); - this.project("stroke", function () { return Plottable.Core.Colors.INDIGO; }); - this.project("stroke-width", function () { return "2px"; }); + this.project("stroke", function () { + return Plottable.Core.Colors.INDIGO; + }); // default + this.project("stroke-width", function () { + return "2px"; + }); // default } Line.prototype._setup = function () { _super.prototype._setup.call(this); this.linePath = this.renderArea.append("path").classed("line", true); }; + Line.prototype._getResetYFunction = function () { + // gets the y-value generator for the animation start point var yDomain = this.yScale.domain(); var domainMax = Math.max(yDomain[0], yDomain[1]); var domainMin = Math.min(yDomain[0], yDomain[1]); + + // start from zero, or the closest domain value to zero + // avoids lines zooming on from offscreen. var startValue = 0; if (domainMax < 0) { startValue = domainMax; - } - else if (domainMin > 0) { + } else if (domainMin > 0) { startValue = domainMin; } var scaledStartValue = this.yScale.scale(startValue); - return function (d, i) { return scaledStartValue; }; + return function (d, i) { + return scaledStartValue; + }; }; + Line.prototype._generateAttrToProjector = function () { var attrToProjector = _super.prototype._generateAttrToProjector.call(this); var wholeDatumAttributes = this._wholeDatumAttributes(); @@ -4672,14 +6558,14 @@ var Plottable; attrToProjector[attribute] = function (data, i) { if (data.length > 0) { return projector(data[0], i); - } - else { + } else { return null; } }; }); return attrToProjector; }; + Line.prototype._paint = function () { _super.prototype._paint.call(this); var attrToProjector = this._generateAttrToProjector(); @@ -4687,14 +6573,18 @@ var Plottable; var yFunction = attrToProjector["y"]; delete attrToProjector["x"]; delete attrToProjector["y"]; + this.linePath.datum(this._dataSource.data()); + if (this._dataChanged) { attrToProjector["d"] = d3.svg.line().x(xFunction).y(this._getResetYFunction()); this._applyAnimatedAttributes(this.linePath, "line-reset", attrToProjector); } + attrToProjector["d"] = d3.svg.line().x(xFunction).y(yFunction); this._applyAnimatedAttributes(this.linePath, "line", attrToProjector); }; + Line.prototype._wholeDatumAttributes = function () { return ["x", "y"]; }; @@ -4705,6 +6595,7 @@ var Plottable; var Plot = Plottable.Plot; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4714,15 +6605,32 @@ var __extends = this.__extends || function (d, b) { var Plottable; (function (Plottable) { (function (Plot) { + /** + * An AreaPlot draws a filled region (area) between the plot's projected "y" and projected "y0" values. + */ var Area = (function (_super) { __extends(Area, _super); + /** + * Creates an AreaPlot. + * + * @constructor + * @param {IDataset} dataset The dataset to render. + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function Area(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this.classed("area-plot", true); - this.project("y0", 0, yScale); - this.project("fill", function () { return Plottable.Core.Colors.INDIGO; }); - this.project("fill-opacity", function () { return 0.25; }); - this.project("stroke", function () { return Plottable.Core.Colors.INDIGO; }); + this.project("y0", 0, yScale); // default + this.project("fill", function () { + return Plottable.Core.Colors.INDIGO; + }); // default + this.project("fill-opacity", function () { + return 0.25; + }); // default + this.project("stroke", function () { + return Plottable.Core.Colors.INDIGO; + }); // default this._animators["area-reset"] = new Plottable.Animator.Null(); this._animators["area"] = new Plottable.Animator.Default().duration(600).easing("exp-in-out"); } @@ -4730,29 +6638,35 @@ var Plottable; _super.prototype._setup.call(this); this.areaPath = this.renderArea.append("path").classed("area", true); }; + Area.prototype._onDataSourceUpdate = function () { _super.prototype._onDataSourceUpdate.call(this); if (this.yScale != null) { this._updateYDomainer(); } }; + Area.prototype._updateYDomainer = function () { _super.prototype._updateYDomainer.call(this); var scale = this.yScale; + var y0Projector = this._projectors["y0"]; var y0Accessor = y0Projector != null ? y0Projector.accessor : null; var extent = y0Accessor != null ? this.dataSource()._getExtent(y0Accessor) : []; var constantBaseline = (extent.length === 2 && extent[0] === extent[1]) ? extent[0] : null; + if (!scale._userSetDomainer) { if (constantBaseline != null) { scale.domainer().addPaddingException(constantBaseline, "AREA_PLOT+" + this._plottableID); - } - else { + } else { scale.domainer().removePaddingException("AREA_PLOT+" + this._plottableID); } + + // prepending "AREA_PLOT" is unnecessary but reduces likely of user accidentally creating collisions scale._autoDomainIfAutomaticMode(); } }; + Area.prototype.project = function (attrToSet, accessor, scale) { _super.prototype.project.call(this, attrToSet, accessor, scale); if (attrToSet === "y0") { @@ -4760,9 +6674,11 @@ var Plottable; } return this; }; + Area.prototype._getResetYFunction = function () { return this._generateAttrToProjector()["y0"]; }; + Area.prototype._paint = function () { _super.prototype._paint.call(this); var attrToProjector = this._generateAttrToProjector(); @@ -4772,14 +6688,18 @@ var Plottable; delete attrToProjector["x"]; delete attrToProjector["y0"]; delete attrToProjector["y"]; + this.areaPath.datum(this._dataSource.data()); + if (this._dataChanged) { attrToProjector["d"] = d3.svg.area().x(xFunction).y0(y0Function).y1(this._getResetYFunction()); this._applyAnimatedAttributes(this.areaPath, "area-reset", attrToProjector); } + attrToProjector["d"] = d3.svg.area().x(xFunction).y0(y0Function).y1(yFunction); this._applyAnimatedAttributes(this.areaPath, "area", attrToProjector); }; + Area.prototype._wholeDatumAttributes = function () { var wholeDatumAttributes = _super.prototype._wholeDatumAttributes.call(this); wholeDatumAttributes.push("y0"); @@ -4792,9 +6712,14 @@ var Plottable; var Plot = Plottable.Plot; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Animator) { + /** + * An animator implementation with no animation. The attributes are + * immediately set on the selection. + */ var Null = (function () { function Null() { } @@ -4808,9 +6733,13 @@ var Plottable; var Animator = Plottable.Animator; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Animator) { + /** + * The default animator implementation with easing, duration, and delay. + */ var Default = (function () { function Default() { this._durationMsec = 300; @@ -4820,29 +6749,29 @@ var Plottable; Default.prototype.animate = function (selection, attrToProjector, plot) { return selection.transition().ease(this._easing).duration(this._durationMsec).delay(this._delayMsec).attr(attrToProjector); }; + Default.prototype.duration = function (duration) { if (duration === undefined) { return this._durationMsec; - } - else { + } else { this._durationMsec = duration; return this; } }; + Default.prototype.delay = function (delay) { if (delay === undefined) { return this._delayMsec; - } - else { + } else { this._delayMsec = delay; return this; } }; + Default.prototype.easing = function (easing) { if (easing === undefined) { return this._easing; - } - else { + } else { this._easing = easing; return this; } @@ -4854,6 +6783,7 @@ var Plottable; var Animator = Plottable.Animator; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4863,6 +6793,12 @@ var __extends = this.__extends || function (d, b) { var Plottable; (function (Plottable) { (function (Animator) { + /** + * An animator that delays the animation of the attributes using the index + * of the selection data. + * + * The delay between animations can be configured with the .delay getter/setter. + */ var IterativeDelay = (function (_super) { __extends(IterativeDelay, _super); function IterativeDelay() { @@ -4871,7 +6807,9 @@ var Plottable; } IterativeDelay.prototype.animate = function (selection, attrToProjector, plot) { var _this = this; - return selection.transition().ease(this._easing).duration(this._durationMsec).delay(function (d, i) { return i * _this._delayMsec; }).attr(attrToProjector); + return selection.transition().ease(this._easing).duration(this._durationMsec).delay(function (d, i) { + return i * _this._delayMsec; + }).attr(attrToProjector); }; return IterativeDelay; })(Animator.Default); @@ -4880,12 +6818,14 @@ var Plottable; var Animator = Plottable.Animator; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { (function (KeyEventListener) { var _initialized = false; var _callbacks = []; + function initialize() { if (_initialized) { return; @@ -4894,20 +6834,25 @@ var Plottable; _initialized = true; } KeyEventListener.initialize = initialize; + function addCallback(keyCode, cb) { if (!_initialized) { initialize(); } + if (_callbacks[keyCode] == null) { _callbacks[keyCode] = []; } + _callbacks[keyCode].push(cb); } KeyEventListener.addCallback = addCallback; + function processEvent() { if (_callbacks[d3.event.keyCode] == null) { return; } + _callbacks[d3.event.keyCode].forEach(function (cb) { cb(d3.event); }); @@ -4918,10 +6863,17 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Abstract) { var Interaction = (function () { + /** + * Creates an Interaction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for interactions on. + */ function Interaction(componentToListenTo) { if (componentToListenTo == null) { throw new Error("Interactions require a component to listen to"); @@ -4931,6 +6883,11 @@ var Plottable; Interaction.prototype._anchor = function (hitBox) { this.hitBox = hitBox; }; + + /** + * Registers the Interaction on the Component it's listening to. + * This needs to be called to activate the interaction. + */ Interaction.prototype.registerWithComponent = function () { this.componentToListenTo.registerInteraction(this); return this; @@ -4942,6 +6899,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -4953,6 +6911,12 @@ var Plottable; (function (Interaction) { var Click = (function (_super) { __extends(Click, _super); + /** + * Creates a ClickInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for clicks on. + */ function Click(componentToListenTo) { _super.call(this, componentToListenTo); } @@ -4966,9 +6930,16 @@ var Plottable; _this._callback(x, y); }); }; + Click.prototype._listenTo = function () { return "click"; }; + + /** + * Sets an callback to be called when a click is received. + * + * @param {(x: number, y: number) => any} cb: Callback to be called. Takes click x and y in pixels. + */ Click.prototype.callback = function (cb) { this._callback = cb; return this; @@ -4976,8 +6947,15 @@ var Plottable; return Click; })(Plottable.Abstract.Interaction); Interaction.Click = Click; + var DoubleClick = (function (_super) { __extends(DoubleClick, _super); + /** + * Creates a DoubleClickInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for clicks on. + */ function DoubleClick(componentToListenTo) { _super.call(this, componentToListenTo); } @@ -4991,6 +6969,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5015,6 +6994,7 @@ var Plottable; _this.mousemove(x, y); }); }; + Mousemove.prototype.mousemove = function (x, y) { return; }; @@ -5025,6 +7005,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5036,6 +7017,13 @@ var Plottable; (function (Interaction) { var Key = (function (_super) { __extends(Key, _super); + /** + * Creates a KeyInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for keypresses on. + * @param {number} keyCode The key code to listen for. + */ function Key(componentToListenTo, keyCode) { _super.call(this, componentToListenTo); this.activated = false; @@ -5050,12 +7038,19 @@ var Plottable; hitBox.on("mouseout", function () { _this.activated = false; }); + Plottable.Core.KeyEventListener.addCallback(this.keyCode, function (e) { if (_this.activated && _this._callback != null) { _this._callback(); } }); }; + + /** + * Sets an callback to be called when the designated key is pressed. + * + * @param {() => any} cb: Callback to be called. + */ Key.prototype.callback = function (cb) { this._callback = cb; return this; @@ -5067,6 +7062,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5078,9 +7074,17 @@ var Plottable; (function (Interaction) { var PanZoom = (function (_super) { __extends(PanZoom, _super); + /** + * Creates a PanZoomInteraction. + * + * @constructor + * @param {Component} componentToListenTo The component to listen for interactions on. + * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. + * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. + */ function PanZoom(componentToListenTo, xScale, yScale) { - _super.call(this, componentToListenTo); var _this = this; + _super.call(this, componentToListenTo); if (xScale == null) { xScale = new Plottable.Scale.Linear(); } @@ -5092,21 +7096,30 @@ var Plottable; this.zoom = d3.behavior.zoom(); this.zoom.x(this.xScale._d3Scale); this.zoom.y(this.yScale._d3Scale); - this.zoom.on("zoom", function () { return _this.rerenderZoomed(); }); + this.zoom.on("zoom", function () { + return _this.rerenderZoomed(); + }); } PanZoom.prototype.resetZoom = function () { var _this = this; + // HACKHACK #254 this.zoom = d3.behavior.zoom(); this.zoom.x(this.xScale._d3Scale); this.zoom.y(this.yScale._d3Scale); - this.zoom.on("zoom", function () { return _this.rerenderZoomed(); }); + this.zoom.on("zoom", function () { + return _this.rerenderZoomed(); + }); this.zoom(this.hitBox); }; + PanZoom.prototype._anchor = function (hitBox) { _super.prototype._anchor.call(this, hitBox); this.zoom(hitBox); }; + PanZoom.prototype.rerenderZoomed = function () { + // HACKHACK since the d3.zoom.x modifies d3 scales and not our TS scales, and the TS scales have the + // event listener machinery, let's grab the domain out of the d3 scale and pipe it back into the TS scale var xDomain = this.xScale._d3Scale.domain(); var yDomain = this.yScale._d3Scale.domain(); this.xScale.domain(xDomain); @@ -5119,6 +7132,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5130,35 +7144,62 @@ var Plottable; (function (Interaction) { var Drag = (function (_super) { __extends(Drag, _super); + /** + * Creates a Drag. + * + * @param {Component} componentToListenTo The component to listen for interactions on. + */ function Drag(componentToListenTo) { - _super.call(this, componentToListenTo); var _this = this; + _super.call(this, componentToListenTo); this.dragInitialized = false; this.origin = [0, 0]; this.location = [0, 0]; this.dragBehavior = d3.behavior.drag(); - this.dragBehavior.on("dragstart", function () { return _this._dragstart(); }); - this.dragBehavior.on("drag", function () { return _this._drag(); }); - this.dragBehavior.on("dragend", function () { return _this._dragend(); }); + this.dragBehavior.on("dragstart", function () { + return _this._dragstart(); + }); + this.dragBehavior.on("drag", function () { + return _this._drag(); + }); + this.dragBehavior.on("dragend", function () { + return _this._dragend(); + }); } + /** + * Adds a callback to be called when the AreaInteraction triggers. + * + * @param {(a: SelectionArea) => any} cb The function to be called. Takes in a SelectionArea in pixels. + * @returns {AreaInteraction} The calling AreaInteraction. + */ Drag.prototype.callback = function (cb) { this.callbackToCall = cb; return this; }; + Drag.prototype._dragstart = function () { var availableWidth = this.componentToListenTo.availableWidth; var availableHeight = this.componentToListenTo.availableHeight; - var constraintFunction = function (min, max) { return function (x) { return Math.min(Math.max(x, min), max); }; }; + + // the constraint functions ensure that the selection rectangle will not exceed the hit box + var constraintFunction = function (min, max) { + return function (x) { + return Math.min(Math.max(x, min), max); + }; + }; this.constrainX = constraintFunction(0, availableWidth); this.constrainY = constraintFunction(0, availableHeight); }; + Drag.prototype._drag = function () { if (!this.dragInitialized) { this.origin = [d3.event.x, d3.event.y]; this.dragInitialized = true; } + this.location = [this.constrainX(d3.event.x), this.constrainY(d3.event.y)]; }; + Drag.prototype._dragend = function () { if (!this.dragInitialized) { return; @@ -5166,16 +7207,21 @@ var Plottable; this.dragInitialized = false; this._doDragend(); }; + Drag.prototype._doDragend = function () { + // seperated out so it can be over-ridden by dragInteractions that want to pass out diff information + // eg just x values for an xSelectionInteraction if (this.callbackToCall != null) { this.callbackToCall([this.origin, this.location]); } }; + Drag.prototype._anchor = function (hitBox) { _super.prototype._anchor.call(this, hitBox); hitBox.call(this.dragBehavior); return this; }; + Drag.prototype.setupZoomCallback = function (xScale, yScale) { var xDomainOriginal = xScale != null ? xScale.domain() : null; var yDomainOriginal = yScale != null ? yScale.domain() : null; @@ -5213,6 +7259,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5235,6 +7282,12 @@ var Plottable; } this.clearBox(); }; + + /** + * Clears the highlighted drag-selection box drawn by the AreaInteraction. + * + * @returns {AreaInteraction} The calling AreaInteraction. + */ DragBox.prototype.clearBox = function () { if (this.dragBox == null) { return; @@ -5243,6 +7296,7 @@ var Plottable; this.boxIsDrawn = false; return this; }; + DragBox.prototype.setBox = function (x0, x1, y0, y1) { if (this.dragBox == null) { return; @@ -5255,6 +7309,7 @@ var Plottable; this.boxIsDrawn = (w > 0 && h > 0); return this; }; + DragBox.prototype._anchor = function (hitBox) { _super.prototype._anchor.call(this, hitBox); var cname = DragBox.CLASS_DRAG_BOX; @@ -5270,6 +7325,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5288,6 +7344,7 @@ var Plottable; _super.prototype._drag.call(this); this.setBox(this.origin[0], this.location[0]); }; + XDragBox.prototype._doDragend = function () { if (this.callbackToCall == null) { return; @@ -5297,6 +7354,7 @@ var Plottable; var pixelArea = { xMin: xMin, xMax: xMax }; this.callbackToCall(pixelArea); }; + XDragBox.prototype.setBox = function (x0, x1) { _super.prototype.setBox.call(this, x0, x1, 0, this.componentToListenTo.availableHeight); return this; @@ -5308,6 +7366,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5326,6 +7385,7 @@ var Plottable; _super.prototype._drag.call(this); this.setBox(this.origin[0], this.location[0], this.origin[1], this.location[1]); }; + XYDragBox.prototype._doDragend = function () { if (this.callbackToCall == null) { return; @@ -5344,6 +7404,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5362,6 +7423,7 @@ var Plottable; _super.prototype._drag.call(this); this.setBox(this.origin[1], this.location[1]); }; + YDragBox.prototype._doDragend = function () { if (this.callbackToCall == null) { return; @@ -5371,6 +7433,7 @@ var Plottable; var pixelArea = { yMin: yMin, yMax: yMax }; this.callbackToCall(pixelArea); }; + YDragBox.prototype.setBox = function (y0, y1) { _super.prototype.setBox.call(this, 0, this.componentToListenTo.availableWidth, y0, y1); return this; @@ -5382,6 +7445,7 @@ var Plottable; var Interaction = Plottable.Interaction; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5393,6 +7457,11 @@ var Plottable; (function (Abstract) { var Dispatcher = (function (_super) { __extends(Dispatcher, _super); + /** + * Creates a Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ function Dispatcher(target) { _super.call(this); this._event2Callback = {}; @@ -5407,13 +7476,24 @@ var Plottable; this.disconnect(); this._target = targetElement; if (wasConnected) { + // re-connect to the new target this.connect(); } return this; }; + + /** + * Gets a namespaced version of the event name. + */ Dispatcher.prototype.getEventString = function (eventName) { return eventName + ".dispatcher" + this._plottableID; }; + + /** + * Attaches the Dispatcher's listeners to the Dispatcher's target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ Dispatcher.prototype.connect = function () { var _this = this; if (this.connected) { @@ -5424,8 +7504,15 @@ var Plottable; var callback = _this._event2Callback[event]; _this._target.on(_this.getEventString(event), callback); }); + return this; }; + + /** + * Detaches the Dispatcher's listeners from the Dispatchers' target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ Dispatcher.prototype.disconnect = function () { var _this = this; this.connected = false; @@ -5441,6 +7528,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5452,19 +7540,27 @@ var Plottable; (function (Dispatcher) { var Mouse = (function (_super) { __extends(Mouse, _super); + /** + * Creates a Mouse Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ function Mouse(target) { - _super.call(this, target); var _this = this; + _super.call(this, target); + this._event2Callback["mouseover"] = function () { if (_this._mouseover != null) { _this._mouseover(_this.getMousePosition()); } }; + this._event2Callback["mousemove"] = function () { if (_this._mousemove != null) { _this._mousemove(_this.getMousePosition()); } }; + this._event2Callback["mouseout"] = function () { if (_this._mouseout != null) { _this._mouseout(_this.getMousePosition()); @@ -5478,6 +7574,7 @@ var Plottable; y: xy[1] }; }; + Mouse.prototype.mouseover = function (callback) { if (callback === undefined) { return this._mouseover; @@ -5485,6 +7582,7 @@ var Plottable; this._mouseover = callback; return this; }; + Mouse.prototype.mousemove = function (callback) { if (callback === undefined) { return this._mousemove; @@ -5492,6 +7590,7 @@ var Plottable; this._mousemove = callback; return this; }; + Mouse.prototype.mouseout = function (callback) { if (callback === undefined) { return this._mouseout; @@ -5506,6 +7605,7 @@ var Plottable; var Dispatcher = Plottable.Dispatcher; })(Plottable || (Plottable = {})); +/// var __extends = this.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -5533,11 +7633,11 @@ var Plottable; this._yAxis = y; this.yTable.addComponent(0, 1, this._yAxis); return this; - } - else { + } else { return this._yAxis; } }; + StandardChart.prototype.xAxis = function (x) { if (x != null) { if (this._xAxis != null) { @@ -5546,19 +7646,18 @@ var Plottable; this._xAxis = x; this.xTable.addComponent(0, 0, this._xAxis); return this; - } - else { + } else { return this._xAxis; } }; + StandardChart.prototype.yLabel = function (y) { if (y != null) { if (this._yLabel != null) { if (typeof (y) === "string") { this._yLabel.text(y); return this; - } - else { + } else { throw new Error("yLabel already assigned!"); } } @@ -5568,19 +7667,18 @@ var Plottable; this._yLabel = y; this.yTable.addComponent(0, 0, this._yLabel); return this; - } - else { + } else { return this._yLabel; } }; + StandardChart.prototype.xLabel = function (x) { if (x != null) { if (this._xLabel != null) { if (typeof (x) === "string") { this._xLabel.text(x); return this; - } - else { + } else { throw new Error("xLabel already assigned!"); } } @@ -5590,19 +7688,18 @@ var Plottable; this._xLabel = x; this.xTable.addComponent(1, 0, this._xLabel); return this; - } - else { + } else { return this._xLabel; } }; + StandardChart.prototype.titleLabel = function (x) { if (x != null) { if (this._titleLabel != null) { if (typeof (x) === "string") { this._titleLabel.text(x); return this; - } - else { + } else { throw new Error("titleLabel already assigned!"); } } @@ -5612,11 +7709,11 @@ var Plottable; this._titleLabel = x; this.addComponent(0, 0, this._titleLabel); return this; - } - else { + } else { return this._titleLabel; } }; + StandardChart.prototype.center = function (c) { this.centerComponent.merge(c); return this; diff --git a/plottable.min.js b/plottable.min.js index 6b2604621e..4fce561909 100644 --- a/plottable.min.js +++ b/plottable.min.js @@ -1,4 +1,4 @@ -var Plottable;!function(a){!function(a){!function(a){function b(a,b,c){return Math.min(b,c)<=a&&a<=Math.max(b,c)}function c(a){null!=window.console&&(null!=window.console.warn?console.warn(a):null!=window.console.log&&console.log(a))}function d(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 e(a,b){var c=d3.set();return a.forEach(function(a){b.has(a)&&c.add(a)}),c}function f(a,b){var c=d3.set();return a.forEach(function(a){return c.add(a)}),b.forEach(function(a){return c.add(a)}),c}function g(a){return"function"==typeof a?a:"string"==typeof a&&"#"!==a[0]?function(b){return b[a]}:function(){return a}}function h(a,b){var c=g(a);return function(a,d){return c(a,d,b.metadata())}}function i(a){var b={};return a.forEach(function(a){return b[a]=!0}),d3.keys(b)}function j(a){var b=d3.set(),c=[];return a.forEach(function(a){b.has(a)||(b.add(a),c.push(a))}),c}function k(a,b){for(var c=[],d=0;b>d;d++)c[d]="function"==typeof a?a(d):a;return c}function l(a){return Array.prototype.concat.apply([],a)}function m(a,b){if(null==a||null==b)return a===b;if(a.length!==b.length)return!1;for(var c=0;cd;){var f=d+e>>>1,g=null==c?b[f]:c(b[f]);a>g?d=f+1:e=f}return d}a.sortedIndex=b}(a.OpenSource||(a.OpenSource={}));a.OpenSource}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this.counter={}}return a.prototype.setDefault=function(a){null==this.counter[a]&&(this.counter[a]=0)},a.prototype.increment=function(a){return this.setDefault(a),++this.counter[a]},a.prototype.decrement=function(a){return this.setDefault(a),--this.counter[a]},a.prototype.get=function(a){return this.setDefault(a),this.counter[a]},a}();a.IDCounter=b}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this.keyValuePairs=[]}return a.prototype.set=function(a,b){if(a!==a)throw new Error("NaN may not be used as a key to the StrictEqualityAssociativeArray");for(var c=0;cb){var h=e("."),i=Math.floor(b/h);return"...".substr(0,i)}for(;f+g>b;)d=d.substr(0,d.length-1).trim(),f=e(d);if(e(d+"...")>b)throw new Error("_addEllipsesToLine failed :(");return d+"..."}function k(b,c,d,e,f,g){"undefined"==typeof f&&(f="left"),"undefined"==typeof g&&(g="top");var h={left:0,center:.5,right:1},i={top:0,center:.5,bottom:1};if(void 0===h[f]||void 0===i[g])throw new Error("unrecognized alignment x:"+f+", y:"+g);var j=c.append("g"),k=j.append("text");k.text(b);var l=a.Util.DOM.getBBox(k),m=l.height,n=l.width;if(n>d||m>e)return a.Util.Methods.warn("Insufficient space to fit text"),{width:0,height:0};var o={left:"start",center:"middle",right:"end"},p=o[f],q=d*h[f],r=e*i[g]+m*(1-i[g]),s=-.4*(1-i[g]);return k.attr("text-anchor",p).attr("y",s+"em"),a.Util.DOM.translate(j,q,r),{width:n,height:m}}function l(a,b,c,d,e,f,g){if("undefined"==typeof e&&(e="left"),"undefined"==typeof f&&(f="top"),"undefined"==typeof g&&(g="right"),"right"!==g&&"left"!==g)throw new Error("unrecognized rotation: "+g);var h="right"===g,i={left:"bottom",right:"top",center:"center",top:"left",bottom:"right"},j={left:"top",right:"bottom",center:"center",top:"right",bottom:"left"},l=h?i:j,m=b.append("g"),n=k(a,m,d,c,l[f],l[e]),o=d3.transform("");return o.rotate="right"===g?90:-90,o.translate=[h?c:0,h?0:d],m.attr("transform",o.toString()),n}function m(b,c,d,e,f,g){"undefined"==typeof f&&(f="left"),"undefined"==typeof g&&(g="top");var i=h(c),j=0,l=c.append("g");b.forEach(function(b,c){var e=l.append("g");a.Util.DOM.translate(e,0,c*i);var h=k(b,e,d,i,f,g);h.width>j&&(j=h.width)});var m=i*b.length,n=e-m,o={center:.5,top:0,bottom:1};return a.Util.DOM.translate(l,0,n*o[g]),{width:j,height:m}}function n(b,c,d,e,f,g,i){"undefined"==typeof f&&(f="left"),"undefined"==typeof g&&(g="top"),"undefined"==typeof i&&(i="left");var j=h(c),k=0,m=c.append("g");b.forEach(function(b,c){var d=m.append("g");a.Util.DOM.translate(d,c*j,0);var h=l(b,d,j,e,f,g,i);h.height>k&&(k=h.height)});var n=j*b.length,o=d-n,p={center:.5,left:0,right:1};return a.Util.DOM.translate(m,o*p[f],0),{width:n,height:k}}function o(b,c,d,e,f,g){var h=null!=f?f:1.1*c>d,i=h?c:d,j=h?d:c,k=a.Util.WordWrap.breakTextToFitRect(b,i,j,e);if(0===k.lines.length)return{textFits:k.textFits,usedWidth:0,usedHeight:0};var l,o;if(null==g){var p=h?d3.max:d3.sum,q=h?d3.sum:d3.max;l=p(k.lines,function(a){return e(a).width}),o=q(k.lines,function(a){return e(a).height})}else{var r=g.g.append("g").classed("writeText-inner-g",!0),s=h?m:n,t=s(k.lines,r,c,d,g.xAlign,g.yAlign);l=t.width,o=t.height}return{textFits:k.textFits,usedWidth:l,usedHeight:o}}b.getTextMeasure=c;var p="a",q=function(){function b(b){var g=this;this.cache=new a.Util.Cache(c(b),p,a.Util.Methods.objEq),this.measure=d(e(f(function(a){return g.cache.get(a)})))}return b.prototype.clear=function(){return this.cache.clear(),this},b}();b.CachingCharacterMeasurer=q,b.getTruncatedText=g,b.getTextHeight=h,b.getTextWidth=i,b._addEllipsesToLine=j,b.writeLineHorizontally=k,b.writeLineVertically=l,b.writeTextHorizontally=m,b.writeTextVertically=n,b.writeText=o}(b.Text||(b.Text={}));b.Text}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(b){!function(b){function c(b,c,e,f){var g=function(a){return f(a).width},h=d(b,c,g),i=f("hello world").height,j=Math.floor(e/i),k=j>=h.length;return k||(h=h.splice(0,j),j>0&&(h[j-1]=a.Util.Text._addEllipsesToLine(h[j-1],c,f))),{originalText:b,lines:h,textFits:k}}function d(a,b,c){for(var d=[],e=a.split("\n"),g=0,h=e.length;h>g;g++){var i=e[g];null!==i?d=d.concat(f(i,b,c)):d.push("")}return d}function e(a,b,c){var d=h(a),e=d.map(c),f=d3.max(e);return b>=f}function f(a,b,c){for(var d,e=[],f=h(a),i="",j=0;d||je;e++){var g=a[e];""===c||j(c[0],g,d)?c+=g:(b.push(c),c=g),d=g}return c&&b.push(c),b}function i(a){return null==a?!0:""===a.trim()}function j(a,b,c){return m.test(a)&&m.test(b)?!0:m.test(a)||m.test(b)?!1:l.test(c)||k.test(b)?!1:!0}var k=/[{\[]/,l=/[!"%),-.:;?\]}]/,m=/^\s+$/;b.breakTextToFitRect=c,b.canWrapWithoutBreakingWords=e}(b.WordWrap||(b.WordWrap={}));b.WordWrap}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(a){function b(a){return a.node().getBBox()}function c(b){null!=window.requestAnimationFrame?window.requestAnimationFrame(b):setTimeout(b,a.POLYFILL_TIMEOUT_MSEC)}function d(a,b){var c=a.getPropertyValue(b),d=parseFloat(c);return d!==d?0:d}function e(a){for(var b=a.node();null!==b&&"svg"!==b.nodeName;)b=b.parentNode;return null==b}function f(a){var b=window.getComputedStyle(a);return d(b,"width")+d(b,"padding-left")+d(b,"padding-right")+d(b,"border-left-width")+d(b,"border-right-width")}function g(a){var b=window.getComputedStyle(a);return d(b,"height")+d(b,"padding-top")+d(b,"padding-bottom")+d(b,"border-top-width")+d(b,"border-bottom-width")}function h(a){var b=a.node().clientWidth;if(0===b){var c=a.attr("width");if(-1!==c.indexOf("%")){for(var d=a.node().parentNode;null!=d&&0===d.clientWidth;)d=d.parentNode;if(null==d)throw new Error("Could not compute width of element");b=d.clientWidth*parseFloat(c)/100}else b=parseFloat(c)}return b}function i(a,b,c){var d=d3.transform(a.attr("transform"));return null==b?d.translate:(c=null==c?0:c,d.translate[0]=b,d.translate[1]=c,a.attr("transform",d.toString()),a)}function j(a,b){return a.rightb.right?!1:a.bottomb.bottom?!1:!0}a.getBBox=b,a.POLYFILL_TIMEOUT_MSEC=1e3/60,a.requestAnimationFramePolyfill=c,a.isSelectionRemovedFromSVG=e,a.getElementWidth=f,a.getElementHeight=g,a.getSVGPixelWidth=h,a.translate=i,a.boxesOverlap=j}(a.DOM||(a.DOM={}));a.DOM}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(a){this._onlyShowUnchanged=!0,this.precision(a)}return a.prototype.format=function(a){var b=this._formatFunction(a);return this._onlyShowUnchanged&&this._valueChanged(a,b)?"":b},a.prototype._valueChanged=function(a,b){return a!==parseFloat(b)},a.prototype.precision=function(a){if(void 0===a)return this._precision;if(0>a||a>20)throw new RangeError("Formatter precision must be between 0 and 20");return this._precision=a,this},a.prototype.showOnlyUnchangedValues=function(a){return void 0===a?this._onlyShowUnchanged:(this._onlyShowUnchanged=a,this)},a}();a.Formatter=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.call(this,null),this.showOnlyUnchangedValues(!1),this._formatFunction=function(a){return String(a)}}return __extends(b,a),b}(a.Abstract.Formatter);b.Identity=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){"undefined"==typeof b&&(b=3),a.call(this,b),this._formatFunction=function(a){if("number"==typeof a){var b=Math.pow(10,this._precision);return String(Math.round(a*b)/b)}return String(a)}}return __extends(b,a),b.prototype._valueChanged=function(a,b){return"number"==typeof a?a!==parseFloat(b):!1},b}(a.Abstract.Formatter);b.General=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){"undefined"==typeof b&&(b=3),a.call(this,b),this._formatFunction=function(a){return a.toFixed(this._precision)}}return __extends(b,a),b}(a.Abstract.Formatter);b.Fixed=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c,d){"undefined"==typeof b&&(b=2),"undefined"==typeof c&&(c="$"),"undefined"==typeof d&&(d=!0),a.call(this,b),this.symbol=c,this.prefix=d}return __extends(b,a),b.prototype.format=function(b){var c=a.prototype.format.call(this,Math.abs(b));return""!==c&&(this.prefix?c=this.symbol+c:c+=this.symbol,0>b&&(c="-"+c)),c},b}(a.Formatter.Fixed);b.Currency=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){"undefined"==typeof b&&(b=0),a.call(this,b)}return __extends(b,a),b.prototype.format=function(b){var c=a.prototype.format.call(this,100*b);return""!==c&&(c+="%"),c},b}(a.Formatter.Fixed);b.Percentage=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){"undefined"==typeof b&&(b=3),a.call(this,b),this.showOnlyUnchangedValues(!1)}return __extends(b,a),b.prototype.precision=function(b){var c=a.prototype.precision.call(this,b);return this._formatFunction=d3.format("."+this._precision+"s"),c},b}(a.Abstract.Formatter);b.SISuffix=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c){if("undefined"==typeof c&&(c=0),a.call(this,c),null==b)throw new Error("Custom Formatters require a formatting function");this._onlyShowUnchanged=!1,this._formatFunction=function(a){return b(a,this)}}return __extends(b,a),b}(a.Abstract.Formatter);b.Custom=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.call(this,null);var b=8,c={};c[0]={format:".%L",filter:function(a){return 0!==a.getMilliseconds()}},c[1]={format:":%S",filter:function(a){return 0!==a.getSeconds()}},c[2]={format:"%I:%M",filter:function(a){return 0!==a.getMinutes()}},c[3]={format:"%I %p",filter:function(a){return 0!==a.getHours()}},c[4]={format:"%a %d",filter:function(a){return 0!==a.getDay()&&1!==a.getDate()}},c[5]={format:"%b %d",filter:function(a){return 1!==a.getDate()}},c[6]={format:"%b",filter:function(a){return 0!==a.getMonth()}},c[7]={format:"%Y",filter:function(){return!0}},this._formatFunction=function(a){for(var d=0;b>d;d++)if(c[d].filter(a))return d3.time.format(c[d].format)(a)},this.showOnlyUnchangedValues(!1)}return __extends(b,a),b}(a.Abstract.Formatter);b.Time=c}(a.Formatter||(a.Formatter={}));a.Formatter}(Plottable||(Plottable={}));var Plottable;!function(a){a.version="0.23.2"}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this._plottableID=a.nextID++}return a.nextID=0,a}();a.PlottableObject=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this),this.listener2Callback=new a.Util.StrictEqualityAssociativeArray,this.listenable=c}return __extends(c,b),c.prototype.registerListener=function(a,b){return this.listener2Callback.set(a,b),this},c.prototype.broadcast=function(){for(var a=this,b=[],c=0;c=0&&(this._components.splice(b,1),this._invalidateLayout()),this},b.prototype._addComponent=function(a,b){return"undefined"==typeof b&&(b=!1),null==a||this._components.indexOf(a)>=0?!1:(b?this._components.unshift(a):this._components.push(a),a._parent=this,this._isAnchored&&a._anchor(this.content),this._invalidateLayout(),!0)},b.prototype.components=function(){return this._components.slice()},b.prototype.empty=function(){return 0===this._components.length},b.prototype.detachAll=function(){return this._components.slice().forEach(function(a){return a.detach()}),this},b.prototype.remove=function(){a.prototype.remove.call(this),this._components.slice().forEach(function(a){return a.remove()})},b}(a.Abstract.Component);b.ComponentContainer=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){"undefined"==typeof b&&(b=[]);var c=this;a.call(this),this.classed("component-group",!0),b.forEach(function(a){return c._addComponent(a)})}return __extends(b,a),b.prototype._requestedSpace=function(a,b){var c=this._components.map(function(c){return c._requestedSpace(a,b)}),d=this.empty(),e=d?0:d3.max(c,function(a){return a.width}),f=d?0:d3.max(c,function(a){return a.height});return{width:Math.min(e,a),height:Math.min(f,b),wantsWidth:d?!1:c.map(function(a){return a.wantsWidth}).some(function(a){return a}),wantsHeight:d?!1:c.map(function(a){return a.wantsHeight}).some(function(a){return a})}},b.prototype.merge=function(a){return this._addComponent(a),this},b.prototype._computeLayout=function(b,c,d,e){var f=this;return a.prototype._computeLayout.call(this,b,c,d,e),this._components.forEach(function(a){a._computeLayout(0,0,f.availableWidth,f.availableHeight)}),this},b.prototype._isFixedWidth=function(){return this._components.every(function(a){return a._isFixedWidth()})},b.prototype._isFixedHeight=function(){return this._components.every(function(a){return a._isFixedHeight()})},b}(a.Abstract.ComponentContainer);b.Group=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){"undefined"==typeof a&&(a=[]);var c=this;b.call(this),this.rowPadding=0,this.colPadding=0,this.rows=[],this.rowWeights=[],this.colWeights=[],this.nRows=0,this.nCols=0,this.classed("table",!0),a.forEach(function(a,b){a.forEach(function(a,d){c.addComponent(b,d,a)})})}return __extends(c,b),c.prototype.addComponent=function(a,b,c){if(this._addComponent(c)){this.nRows=Math.max(a+1,this.nRows),this.nCols=Math.max(b+1,this.nCols),this.padTableToSize(this.nRows,this.nCols);var d=this.rows[a][b];if(null!=d)throw new Error("Table.addComponent cannot be called on a cell where a component already exists (for the moment)");this.rows[a][b]=c}return this},c.prototype._removeComponent=function(a){b.prototype._removeComponent.call(this,a);var c,d;a:for(var e=0;e0&&v&&e!==x,C=f>0&&w&&f!==y;if(!B&&!C)break;if(r>5)break}return e=h-d3.sum(u.guaranteedWidths),f=i-d3.sum(u.guaranteedHeights),n=c.calcProportionalSpace(k,e),o=c.calcProportionalSpace(j,f),{colProportionalSpace:n,rowProportionalSpace:o,guaranteedWidths:u.guaranteedWidths,guaranteedHeights:u.guaranteedHeights,wantsWidth:v,wantsHeight:w}},c.prototype.determineGuarantees=function(b,c){var d=a.Util.Methods.createFilledArray(0,this.nCols),e=a.Util.Methods.createFilledArray(0,this.nRows),f=a.Util.Methods.createFilledArray(!1,this.nCols),g=a.Util.Methods.createFilledArray(!1,this.nRows);return this.rows.forEach(function(h,i){h.forEach(function(h,j){var k; -k=null!=h?h._requestedSpace(b[j],c[i]):{width:0,height:0,wantsWidth:!1,wantsHeight:!1};var l=.001,m=function(a,b){return a-b-l>0};(m(k.width,b[j])||m(k.height,c[i]))&&a.Util.Methods.warn("Invariant Violation: Abstract.Component cannot request more space than is offered"),d[j]=Math.max(d[j],k.width),e[i]=Math.max(e[i],k.height),f[j]=f[j]||k.wantsWidth,g[i]=g[i]||k.wantsHeight})}),{guaranteedWidths:d,guaranteedHeights:e,wantsWidthArr:f,wantsHeightArr:g}},c.prototype._requestedSpace=function(a,b){var c=this.iterateLayout(a,b);return{width:d3.sum(c.guaranteedWidths),height:d3.sum(c.guaranteedHeights),wantsWidth:c.wantsWidth,wantsHeight:c.wantsHeight}},c.prototype._computeLayout=function(c,d,e,f){var g=this;b.prototype._computeLayout.call(this,c,d,e,f);var h=this.iterateLayout(this.availableWidth,this.availableHeight),i=a.Util.Methods.addArrays(h.rowProportionalSpace,h.guaranteedHeights),j=a.Util.Methods.addArrays(h.colProportionalSpace,h.guaranteedWidths),k=0;return this.rows.forEach(function(a,b){var c=0;a.forEach(function(a,d){null!=a&&a._computeLayout(c,k,j[d],i[b]),c+=j[d]+g.colPadding}),k+=i[b]+g.rowPadding}),this},c.prototype.padding=function(a,b){return this.rowPadding=a,this.colPadding=b,this._invalidateLayout(),this},c.prototype.rowWeight=function(a,b){return this.rowWeights[a]=b,this._invalidateLayout(),this},c.prototype.colWeight=function(a,b){return this.colWeights[a]=b,this._invalidateLayout(),this},c.prototype._isFixedWidth=function(){var a=d3.transpose(this.rows);return c.fixedSpace(a,function(a){return null==a||a._isFixedWidth()})},c.prototype._isFixedHeight=function(){return c.fixedSpace(this.rows,function(a){return null==a||a._isFixedHeight()})},c.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(d=0;b>d;d++)void 0===this.colWeights[d]&&(this.colWeights[d]=null)},c.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})},c.calcProportionalSpace=function(b,c){var d=d3.sum(b);return 0===d?a.Util.Methods.createFilledArray(0,b.length):b.map(function(a){return c*a/d})},c.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))},c}(a.Abstract.ComponentContainer);b.Table=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this),this.autoDomainAutomatically=!0,this.broadcaster=new a.Core.Broadcaster(this),this._rendererAttrID2Extent={},this._d3Scale=c}return __extends(c,b),c.prototype._getAllExtents=function(){return d3.values(this._rendererAttrID2Extent)},c.prototype._getExtent=function(){return[]},c.prototype.autoDomain=function(){return this.autoDomainAutomatically=!0,this._setDomain(this._getExtent()),this},c.prototype._autoDomainIfAutomaticMode=function(){this.autoDomainAutomatically&&this.autoDomain()},c.prototype.scale=function(a){return this._d3Scale(a)},c.prototype.domain=function(a){return null==a?this._getDomain():(this.autoDomainAutomatically=!1,this._setDomain(a),this)},c.prototype._getDomain=function(){return this._d3Scale.domain()},c.prototype._setDomain=function(a){this._d3Scale.domain(a),this.broadcaster.broadcast()},c.prototype.range=function(a){return null==a?this._d3Scale.range():(this._d3Scale.range(a),this)},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c.prototype.updateExtent=function(a,b,c){return this._rendererAttrID2Extent[a+b]=c,this._autoDomainIfAutomaticMode(),this},c.prototype.removeExtent=function(a,b){return delete this._rendererAttrID2Extent[a+b],this._autoDomainIfAutomaticMode(),this},c}(a.Abstract.PlottableObject);b.Scale=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this),this._dataChanged=!1,this._animate=!1,this._animators={},this._ANIMATION_DURATION=250,this._projectors={},this.animateOnNextRender=!0,this.clipPathEnabled=!0,this.classed("renderer",!0);var d;d=null!=c?"function"==typeof c.data?c:d=new a.DataSource(c):new a.DataSource,this.dataSource(d)}return __extends(c,b),c.prototype._anchor=function(a){return b.prototype._anchor.call(this,a),this.animateOnNextRender=!0,this._dataChanged=!0,this.updateAllProjectors(),this},c.prototype.remove=function(){var a=this;b.prototype.remove.call(this),this._dataSource.broadcaster.deregisterListener(this);var c=Object.keys(this._projectors);c.forEach(function(b){var c=a._projectors[b];null!=c.scale&&c.scale.broadcaster.deregisterListener(a)})},c.prototype.dataSource=function(a){var b=this;if(null==a)return this._dataSource;var c=this._dataSource;return null!=c&&this._dataSource.broadcaster.deregisterListener(this),this._dataSource=a,this._dataSource.broadcaster.registerListener(this,function(){return b._onDataSourceUpdate()}),this._onDataSourceUpdate(),this},c.prototype._onDataSourceUpdate=function(){this.updateAllProjectors(),this.animateOnNextRender=!0,this._dataChanged=!0,this._render()},c.prototype.project=function(a,b,c){var d=this;a=a.toLowerCase();var e=this._projectors[a],f=null!=e?e.scale:null;return null!=f&&(f.removeExtent(this._plottableID,a),f.broadcaster.deregisterListener(this)),null!=c&&c.broadcaster.registerListener(this,function(){return d._render()}),this._projectors[a]={accessor:b,scale:c},this.updateProjector(a),this._render(),this},c.prototype._generateAttrToProjector=function(){var b=this,c={};return d3.keys(this._projectors).forEach(function(d){var e=b._projectors[d],f=a.Util.Methods.applyAccessor(e.accessor,b.dataSource()),g=e.scale,h=null==g?f:function(a,b){return g.scale(f(a,b))};c[d]=h}),c},c.prototype._doRender=function(){return null!=this.element&&(this._paint(),this._dataChanged=!1,this.animateOnNextRender=!1),this},c.prototype._paint=function(){},c.prototype._setup=function(){return b.prototype._setup.call(this),this.renderArea=this.content.append("g").classed("render-area",!0),this},c.prototype.animate=function(a){return this._animate=a,this},c.prototype.detach=function(){return b.prototype.detach.call(this),this.updateAllProjectors(),this},c.prototype.updateAllProjectors=function(){var a=this;return d3.keys(this._projectors).forEach(function(b){return a.updateProjector(b)}),this},c.prototype.updateProjector=function(a){var b=this._projectors[a];if(null!=b.scale){var c=this.dataSource()._getExtent(b.accessor);0!==c.length&&this._isAnchored?b.scale.updateExtent(this._plottableID,a,c):b.scale.removeExtent(this._plottableID,a)}return this},c.prototype._applyAnimatedAttributes=function(a,b,c){return this._animate&&this.animateOnNextRender&&null!=this._animators[b]?this._animators[b].animate(a,c,this):a.attr(c)},c.prototype.animator=function(a,b){return void 0===b?this._animators[a]:(this._animators[a]=b,this)},c}(a.Abstract.Component);b.Plot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var Plottable;!function(a){!function(b){!function(b){!function(b){var c=function(){function b(){}return b.prototype.render=function(){a.Core.RenderController.flush()},b}();b.Immediate=c;var d=function(){function b(){}return b.prototype.render=function(){a.Util.DOM.requestAnimationFramePolyfill(a.Core.RenderController.flush)},b}();b.AnimationFrame=d;var e=function(){function b(){this._timeoutMsec=a.Util.DOM.POLYFILL_TIMEOUT_MSEC}return b.prototype.render=function(){setTimeout(a.Core.RenderController.flush,this._timeoutMsec)},b}();b.Timeout=e}(b.RenderPolicy||(b.RenderPolicy={}));b.RenderPolicy}(b.RenderController||(b.RenderController={}));b.RenderController}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(b){!function(b){function c(a){b._renderPolicy=a}function d(a){h[a._plottableID]=a,f()}function e(a){i[a._plottableID]=a,h[a._plottableID]=a,f()}function f(){j||(j=!0,b._renderPolicy.render())}function g(){if(j){var b=d3.values(i);b.forEach(function(a){return a._computeLayout()});var c=d3.values(h);c.forEach(function(a){return a._render()}),c=d3.values(h),c.forEach(function(a){return a._doRender()}),i={},h={},j=!1}a.Core.ResizeBroadcaster.clearResizing()}var h={},i={},j=!1;b._renderPolicy=new a.Core.RenderController.RenderPolicy.AnimationFrame,b.setRenderPolicy=c,b.registerToRender=d,b.registerToComputeLayout=e,b.flush=g}(b.RenderController||(b.RenderController={}));b.RenderController}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(b){!function(b){function c(){void 0===i&&(i=new a.Core.Broadcaster(b),window.addEventListener("resize",d))}function d(){j=!0,i.broadcast()}function e(){return j}function f(){j=!1}function g(a){c(),i.registerListener(a._plottableID,function(){return a._invalidateLayout()})}function h(a){i&&i.deregisterListener(a._plottableID)}var i,j=!1;b.resizing=e,b.clearResizing=f,b.register=g,b.deregister=h}(b.ResizeBroadcaster||(b.ResizeBroadcaster={}));b.ResizeBroadcaster}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(){}(Plottable||(Plottable={}));var Plottable;!function(a){var b=function(){function a(a){this.doNice=!1,this.padProportion=0,this.paddingExceptions=d3.map(),this.unregisteredPaddingExceptions=d3.set(),this.includedValues=d3.map(),this.unregisteredIncludedValues=d3.map(),this.combineExtents=a}return a.prototype.computeDomain=function(a,b){var c;return c=null!=this.combineExtents?this.combineExtents(a):0===a.length?b._defaultExtent():[d3.min(a,function(a){return a[0]}),d3.max(a,function(a){return a[1]})],c=this.includeDomain(c),c=this.padDomain(b,c),c=this.niceDomain(b,c)},a.prototype.pad=function(a){return"undefined"==typeof a&&(a=.05),this.padProportion=a,this},a.prototype.addPaddingException=function(a,b){return null!=b?this.paddingExceptions.set(b,a):this.unregisteredPaddingExceptions.add(a),this},a.prototype.removePaddingException=function(a){return"string"==typeof a?this.paddingExceptions.remove(a):this.unregisteredPaddingExceptions.remove(a),this},a.prototype.addIncludedValue=function(a,b){return null!=b?this.includedValues.set(b,a):this.unregisteredIncludedValues.set(a,a),this},a.prototype.removeIncludedValue=function(a){return"string"==typeof a?this.includedValues.remove(a):this.unregisteredIncludedValues.remove(a),this},a.prototype.nice=function(a){return this.doNice=!0,this.niceCount=a,this},a.defaultCombineExtents=function(a){return 0===a.length?[0,1]:[d3.min(a,function(a){return a[0]}),d3.max(a,function(a){return a[1]})]},a.prototype.padDomain=function(b,c){var d=c[0],e=c[1];if(d===e&&this.padProportion>0){var f=d.valueOf();return d instanceof Date?[f-a.ONE_DAY,f+a.ONE_DAY]:[f-a.PADDING_FOR_IDENTICAL_DOMAIN,f+a.PADDING_FOR_IDENTICAL_DOMAIN]}var g=this.padProportion/2,h=b.invert(b.scale(d)-(b.scale(e)-b.scale(d))*g),i=b.invert(b.scale(e)+(b.scale(e)-b.scale(d))*g),j=this.paddingExceptions.values().concat(this.unregisteredPaddingExceptions.values()),k=d3.set(j);return k.has(d)&&(h=d),k.has(e)&&(i=e),[h,i]},a.prototype.niceDomain=function(a,b){return this.doNice?a._niceDomain(b,this.niceCount):b},a.prototype.includeDomain=function(a){var b=this.includedValues.values().concat(this.unregisteredIncludedValues.values());return b.reduce(function(a,b){return[Math.min(a[0],b),Math.max(a[1],b)]},a)},a.PADDING_FOR_IDENTICAL_DOMAIN=1,a.ONE_DAY=864e5,a}();a.Domainer=b}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this,c),this._lastRequestedTickCount=10,this._PADDING_FOR_IDENTICAL_DOMAIN=1,this._userSetDomainer=!1,this._domainer=new a.Domainer}return __extends(c,b),c.prototype._getExtent=function(){return this._domainer.computeDomain(this._getAllExtents(),this)},c.prototype.invert=function(a){return this._d3Scale.invert(a)},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c.prototype.domain=function(a){return b.prototype.domain.call(this,a)},c.prototype._setDomain=function(c){var d=function(a){return a!==a||1/0===a||a===-1/0};return d(c[0])||d(c[1])?void a.Util.Methods.warn("Warning: QuantitativeScales cannot take NaN or Infinity as a domain value. Ignoring."):void b.prototype._setDomain.call(this,c)},c.prototype.interpolate=function(a){return null==a?this._d3Scale.interpolate():(this._d3Scale.interpolate(a),this)},c.prototype.rangeRound=function(a){return this._d3Scale.rangeRound(a),this},c.prototype.clamp=function(a){return null==a?this._d3Scale.clamp():(this._d3Scale.clamp(a),this)},c.prototype.ticks=function(a){return null!=a&&(this._lastRequestedTickCount=a),this._d3Scale.ticks(this._lastRequestedTickCount)},c.prototype.tickFormat=function(a,b){return this._d3Scale.tickFormat(a,b)},c.prototype._niceDomain=function(a,b){return this._d3Scale.copy().domain(a).nice(b).domain()},c.prototype.domainer=function(a){return null==a?this._domainer:(this._domainer=a,this._userSetDomainer=!0,this._autoDomainIfAutomaticMode(),this)},c.prototype._defaultExtent=function(){return[0,1]},c}(a.Abstract.Scale);b.QuantitativeScale=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,null==b?d3.scale.linear():b)}return __extends(b,a),b.prototype.copy=function(){return new b(this._d3Scale.copy())},b}(a.Abstract.QuantitativeScale);b.Linear=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,null==b?d3.scale.log():b)}return __extends(b,a),b.prototype.copy=function(){return new b(this._d3Scale.copy())},b.prototype._defaultExtent=function(){return[1,10]},b}(a.Abstract.QuantitativeScale);b.Log=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){if("undefined"==typeof a&&(a=10),b.call(this,d3.scale.linear()),this._showIntermediateTicks=!1,this.base=a,this.pivot=this.base,this.untransformedDomain=this._defaultExtent(),this._lastRequestedTickCount=10,1>=a)throw new Error("ModifiedLogScale: The base must be > 1")}return __extends(c,b),c.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=d&&e>=a});return j.concat(l).concat(k)},c.prototype.logTicks=function(b,c){var d=this,e=this.howManyTicks(b,c);if(0===e)return[];var f=Math.floor(Math.log(b)/Math.log(this.base)),g=Math.ceil(Math.log(c)/Math.log(this.base)),h=d3.range(g,f,-Math.ceil((g-f)/e)),i=this._showIntermediateTicks?Math.floor(e/h.length):1,j=d3.range(this.base,1,-(this.base-1)/i).map(Math.floor),k=a.Util.Methods.uniqNumbers(j),l=h.map(function(a){return k.map(function(b){return Math.pow(d.base,a-1)*b})}),m=a.Util.Methods.flatten(l),n=m.filter(function(a){return a>=b&&c>=a}),o=n.sort(function(a,b){return a-b});return o},c.prototype.howManyTicks=function(a,b){var c=this.adjustedLog(d3.min(this.untransformedDomain)),d=this.adjustedLog(d3.max(this.untransformedDomain)),e=this.adjustedLog(a),f=this.adjustedLog(b),g=(f-e)/(d-c),h=Math.ceil(g*this._lastRequestedTickCount);return h},c.prototype.copy=function(){return new c(this.base)},c.prototype._niceDomain=function(a){return a},c.prototype.showIntermediateTicks=function(a){return null==a?this._showIntermediateTicks:void(this._showIntermediateTicks=a)},c}(a.Abstract.QuantitativeScale);b.ModifiedLog=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){if(b.call(this,null==a?d3.scale.ordinal():a),this._range=[0,1],this._rangeType="bands",this._innerPadding=.3,this._outerPadding=.5,this._innerPadding>this._outerPadding)throw new Error("outerPadding must be >= innerPadding so cat axis bands work out reasonably")}return __extends(c,b),c.prototype._getExtent=function(){var b=this._getAllExtents();return a.Util.Methods.uniq(a.Util.Methods.flatten(b))},c.prototype.domain=function(a){return b.prototype.domain.call(this,a)},c.prototype._setDomain=function(a){b.prototype._setDomain.call(this,a),this.range(this.range())},c.prototype.range=function(a){return null==a?this._range:(this._range=a,"points"===this._rangeType?this._d3Scale.rangePoints(a,2*this._outerPadding):"bands"===this._rangeType&&this._d3Scale.rangeBands(a,this._innerPadding,this._outerPadding),this)},c.prototype.rangeBand=function(){return this._d3Scale.rangeBand()},c.prototype.innerPadding=function(){var a=this.domain();if(a.length<2)return 0;var b=Math.abs(this.scale(a[1])-this.scale(a[0]));return b-this.rangeBand()},c.prototype.fullBandStartAndWidth=function(a){var b=this.scale(a)-this.innerPadding()/2,c=this.rangeBand()+this.innerPadding();return[b,c]},c.prototype.rangeType=function(a,b,c){if(null==a)return this._rangeType;if("points"!==a&&"bands"!==a)throw new Error("Unsupported range type: "+a);return this._rangeType=a,null!=b&&(this._outerPadding=b),null!=c&&(this._innerPadding=c),this.broadcaster.broadcast(),this},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c}(a.Abstract.Scale);b.Ordinal=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){var c;switch(a){case"Category10":case"category10":case"10":c=d3.scale.category10();break;case"Category20":case"category20":case"20":c=d3.scale.category20();break;case"Category20b":case"category20b":case"20b":c=d3.scale.category20b();break;case"Category20c":case"category20c":case"20c":c=d3.scale.category20c();break;case null:case void 0:c=d3.scale.ordinal();break;default:throw new Error("Unsupported ColorScale type")}b.call(this,c)}return __extends(c,b),c.prototype._getExtent=function(){var b=this._getAllExtents(),c=[];return b.forEach(function(a){c=c.concat(a)}),a.Util.Methods.uniq(c)},c}(a.Abstract.Scale);b.Color=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,null==b?d3.time.scale():b),this._PADDING_FOR_IDENTICAL_DOMAIN=864e5}return __extends(b,a),b.prototype.tickInterval=function(a,b){var c=d3.time.scale();return c.domain(this.domain()),c.range(this.range()),c.ticks(a.range,b)},b.prototype.domain=function(b){return null==b?a.prototype.domain.call(this):("string"==typeof b[0]&&(b=b.map(function(a){return new Date(a)})),a.prototype.domain.call(this,b))},b.prototype.copy=function(){return new b(this._d3Scale.copy())},b}(a.Abstract.QuantitativeScale);b.Time=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(c,d){"undefined"==typeof c&&(c="reds"),"undefined"==typeof d&&(d="linear"),this._colorRange=this._resolveColorValues(c),this._scaleType=d,a.call(this,b.getD3InterpolatedScale(this._colorRange,this._scaleType))}return __extends(b,a),b.getD3InterpolatedScale=function(a,c){var d;switch(c){case"linear":d=d3.scale.linear();break;case"log":d=d3.scale.log();break;case"sqrt":d=d3.scale.sqrt();break;case"pow":d=d3.scale.pow()}if(null==d)throw new Error("unknown Quantitative scale type "+c);return d.range([0,1]).interpolate(b.interpolateColors(a))},b.interpolateColors=function(a){if(a.length<2)throw new Error("Color scale arrays must have at least two elements.");return function(){return function(b){b=Math.max(0,Math.min(1,b));var c=b*(a.length-1),d=Math.floor(c),e=Math.ceil(c),f=c-d;return d3.interpolateLab(a[d],a[e])(f)}}},b.prototype.colorRange=function(a){return null==a?this._colorRange:(this._colorRange=this._resolveColorValues(a),void this._resetScale())},b.prototype.scaleType=function(a){return null==a?this._scaleType:(this._scaleType=a,void this._resetScale())},b.prototype._resetScale=function(){this._d3Scale=b.getD3InterpolatedScale(this._colorRange,this._scaleType),this._autoDomainIfAutomaticMode(),this.broadcaster.broadcast()},b.prototype._resolveColorValues=function(a){return a instanceof Array?a:null!=b.COLOR_SCALES[a]?b.COLOR_SCALES[a]:b.COLOR_SCALES.reds},b.prototype.autoDomain=function(){var a=this._getAllExtents();return a.length>0&&this._setDomain([d3.min(a,function(a){return a[0]}),d3.max(a,function(a){return a[1]})]),this},b.COLOR_SCALES={reds:["#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"],blues:["#FFFFFF","#CCFFFF","#A5FFFD","#85F7FB","#6ED3EF","#55A7E0","#417FD0","#2545D3","#0B02E1"],posneg:["#0B02E1","#2545D3","#417FD0","#55A7E0","#6ED3EF","#85F7FB","#A5FFFD","#CCFFFF","#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"]},b}(a.Abstract.QuantitativeScale);b.InterpolatedColor=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(a){var b=this;if(this.rescaleInProgress=!1,null==a)throw new Error("ScaleDomainCoordinator requires scales to coordinate");this.scales=a,this.scales.forEach(function(a){return a.broadcaster.registerListener(b,function(a){return b.rescale(a)})})}return a.prototype.rescale=function(a){if(!this.rescaleInProgress){this.rescaleInProgress=!0;var b=a.domain();this.scales.forEach(function(a){return a.domain(b)}),this.rescaleInProgress=!1}},a}();a.ScaleDomainCoordinator=b}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){var f=this;if(b.call(this),this._width="auto",this._height="auto",this._tickLength=5,this._tickLabelPadding=3,this._showEndTickLabels=!1,null==c||null==d)throw new Error("Axis requires a scale and orientation");this._scale=c,this.orient(d),this.classed("axis",!0),this._isHorizontal()?this.classed("x-axis",!0):this.classed("y-axis",!0),null==e&&(e=new a.Formatter.General,e.showOnlyUnchangedValues(!1)),this.formatter(e),this._scale.broadcaster.registerListener(this,function(){return f.rescale()})}return __extends(c,b),c.prototype.remove=function(){b.prototype.remove.call(this),this._scale.broadcaster.deregisterListener(this)},c.prototype._isHorizontal=function(){return"top"===this._orientation||"bottom"===this._orientation},c.prototype._computeWidth=function(){return this._computedWidth=this._tickLength,this._computedWidth},c.prototype._computeHeight=function(){return this._computedHeight=this._tickLength,this._computedHeight},c.prototype._requestedSpace=function(a,b){var c=this._width,d=this._height;return this._isHorizontal()?("auto"===this._height&&(null==this._computedHeight&&this._computeHeight(),d=this._computedHeight),c=0):("auto"===this._width&&(null==this._computedWidth&&this._computeWidth(),c=this._computedWidth),d=0),{width:Math.min(a,c),height:Math.min(b,d),wantsWidth:!this._isHorizontal()&&c>a,wantsHeight:this._isHorizontal()&&d>b}},c.prototype._computeLayout=function(a,c,d,e){return b.prototype._computeLayout.call(this,a,c,d,e),this._scale.range(this._isHorizontal()?[0,this.availableWidth]:[this.availableHeight,0]),this},c.prototype._setup=function(){return b.prototype._setup.call(this),this._tickMarkContainer=this.content.append("g").classed(c.TICK_MARK_CLASS+"-container",!0),this._tickLabelContainer=this.content.append("g").classed(c.TICK_LABEL_CLASS+"-container",!0),this._baseline=this.content.append("line").classed("baseline",!0),this},c.prototype._getTickValues=function(){return[]},c.prototype._doRender=function(){var a=this._getTickValues(),b=this._tickMarkContainer.selectAll("."+c.TICK_MARK_CLASS).data(a);return b.enter().append("line").classed(c.TICK_MARK_CLASS,!0),b.attr(this._generateTickMarkAttrHash()),b.exit().remove(),this._baseline.attr(this._generateBaselineAttrHash()),this},c.prototype._generateBaselineAttrHash=function(){var a={x1:0,y1:0,x2:0,y2:0};switch(this._orientation){case"bottom":a.x2=this.availableWidth;break;case"top":a.x2=this.availableWidth,a.y1=this.availableHeight,a.y2=this.availableHeight;break;case"left":a.x1=this.availableWidth,a.x2=this.availableWidth,a.y2=this.availableHeight;break;case"right":a.y2=this.availableHeight}return a},c.prototype._generateTickMarkAttrHash=function(){var a=this,b={x1:0,y1:0,x2:0,y2:0},c=function(b){return a._scale.scale(b)};switch(this._isHorizontal()?(b.x1=c,b.x2=c):(b.y1=c,b.y2=c),this._orientation){case"bottom":b.y2=this._tickLength;break;case"top":b.y1=this.availableHeight,b.y2=this.availableHeight-this._tickLength;break;case"left":b.x1=this.availableWidth,b.x2=this.availableWidth-this._tickLength;break;case"right":b.x2=this._tickLength}return b},c.prototype.rescale=function(){return null!=this.element?this._render():null},c.prototype._invalidateLayout=function(){b.prototype._invalidateLayout.call(this),this._computedWidth=null,this._computedHeight=null},c.prototype.width=function(a){if(null==a)return this.availableWidth;if(this._isHorizontal())throw new Error("width cannot be set on a horizontal Axis");if("auto"!==a&&0>a)throw new Error("invalid value for width");return this._width=a,this._invalidateLayout(),this},c.prototype.height=function(a){if(null==a)return this.availableHeight;if(!this._isHorizontal())throw new Error("height cannot be set on a vertical Axis");if("auto"!==a&&0>a)throw new Error("invalid value for height");return this._height=a,this._invalidateLayout(),this},c.prototype.formatter=function(b){return void 0===b?this._formatter:("function"==typeof b&&(b=new a.Formatter.Custom(b),b.showOnlyUnchangedValues(!1)),this._formatter=b,this._invalidateLayout(),this)},c.prototype.tickLength=function(a){if(null==a)return this._tickLength;if(0>a)throw new Error("tick length must be positive");return this._tickLength=a,this._invalidateLayout(),this},c.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._invalidateLayout(),this},c.prototype.orient=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._invalidateLayout(),this},c.prototype.showEndTickLabels=function(a){return null==a?this._showEndTickLabels:(this._showEndTickLabels=a,this._render(),this)},c.prototype._hideEndTickLabels=function(){var b=this,c=this.element.select(".bounding-box")[0][0].getBoundingClientRect(),d=function(a){return Math.floor(c.left)<=Math.ceil(a.left)&&Math.floor(c.top)<=Math.ceil(a.top)&&Math.floor(a.right)<=Math.ceil(c.left+b.availableWidth)&&Math.floor(a.bottom)<=Math.ceil(c.top+b.availableHeight)},e=this._tickLabelContainer.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS);if(0!==e[0].length){var f=e[0][0];d(f.getBoundingClientRect())||d3.select(f).style("visibility","hidden");var g=e[0][e[0].length-1];d(g.getBoundingClientRect())||d3.select(g).style("visibility","hidden")}},c.prototype._hideOverlappingTickLabels=function(){var b,c=this._tickLabelContainer.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).filter(function(){return"visible"===d3.select(this).style("visibility")});c.each(function(){var c=this.getBoundingClientRect(),d=d3.select(this);null!=b&&a.Util.DOM.boxesOverlap(c,b)?d.style("visibility","hidden"):(b=c,d.style("visibility","visible"))})},c.TICK_MARK_CLASS="tick-mark",c.TICK_LABEL_CLASS="tick-label",c}(a.Abstract.Component);b.Axis=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,d){if(d=d.toLowerCase(),"top"!==d&&"bottom"!==d)throw new Error("unsupported orientation: "+d);b.call(this,a,d),this.classed("time-axis",!0),this.previousSpan=0,this.previousIndex=c.minorIntervals.length-1,this.tickLabelPadding(5)}return __extends(c,b),c.prototype._computeHeight=function(){if(null!==this._computedHeight)return this._computedHeight;var a=this._measureTextHeight(this._majorTickLabels)+this._measureTextHeight(this._minorTickLabels);return this.tickLength(a),this._computedHeight=a+2*this.tickLabelPadding(),this._computedHeight},c.prototype.calculateWorstWidth=function(b,c){var d=new Date(9999,8,29,12,59,9999);return a.Util.Text.getTextWidth(b,d3.time.format(c)(d))},c.prototype.getIntervalLength=function(a){var b=this._scale.domain()[0],c=Math.abs(this._scale.scale(a.timeUnit.offset(b,a.step))-this._scale.scale(b));return c},c.prototype.isEnoughSpace=function(a,b){var c=this.calculateWorstWidth(a,b.formatString)+2*this.tickLabelPadding(),d=Math.min(this.getIntervalLength(b),this.availableWidth);return d>c},c.prototype._setup=function(){return b.prototype._setup.call(this),this._majorTickLabels=this.content.append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),this._minorTickLabels=this.content.append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),this},c.prototype.getTickLevel=function(){var b=c.minorIntervals.length-1,d=Math.abs(this._scale.domain()[1]-this._scale.domain()[0]);d<=this.previousSpan+1&&(b=this.previousIndex);for(var e=b;e>=0;){if(!this.isEnoughSpace(this._minorTickLabels,c.minorIntervals[e])||!this.isEnoughSpace(this._majorTickLabels,c.majorIntervals[e])){e++; -break}e--}return e=Math.min(e,c.minorIntervals.length-1),0>e&&(e=0,a.Util.Methods.warn("could not find suitable interval to display labels")),this.previousIndex=Math.max(0,e-1),this.previousSpan=d,e},c.prototype._getTickIntervalValues=function(a){return this._scale.tickInterval(a.timeUnit,a.step)},c.prototype._getTickValues=function(){var a=this.getTickLevel(),b=this._getTickIntervalValues(c.minorIntervals[a]),d=this._getTickIntervalValues(c.majorIntervals[a]);return b.concat(d)},c.prototype._measureTextHeight=function(b){var c=b.append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),d=a.Util.Text.getTextHeight(c.append("text"));return c.remove(),d},c.prototype.renderTickLabels=function(b,c,d){var e=this;b.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).remove();var f=this._scale.tickInterval(c.timeUnit,c.step);f.splice(0,0,this._scale.domain()[0]),f.push(this._scale.domain()[1]);var g=1===c.step,h=[];g?f.map(function(a,b){b+1>=f.length||h.push(new Date((f[b+1].valueOf()-f[b].valueOf())/2+f[b].valueOf()))}):h=f,h=h.filter(function(a){return e.canFitLabelFilter(b,a,d3.time.format(c.formatString)(a),g)});var i=b.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).data(h,function(a){return a.valueOf()}),j=i.enter().append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0);j.append("text");var k=g?0:this.tickLabelPadding(),l="bottom"===this._orientation?this.tickLength()/2*d:this.availableHeight-this.tickLength()/2*d+2*this.tickLabelPadding(),m=i.selectAll("text");m.size()>0&&a.Util.DOM.translate(m,k,l),i.exit().remove(),i.attr("transform",function(a){return"translate("+e._scale.scale(a)+",0)"});var n=g?"middle":"left";i.selectAll("text").text(function(a){return d3.time.format(c.formatString)(a)}).style("text-anchor",n)},c.prototype.canFitLabelFilter=function(b,c,d,e){var f,g,h=a.Util.Text.getTextWidth(b,d)+this.tickLabelPadding();return e?(f=this._scale.scale(c)+h/2,g=this._scale.scale(c)-h/2):(f=this._scale.scale(c)+h,g=this._scale.scale(c)),f0},c.prototype.adjustTickLength=function(b,c){var d=this._getTickIntervalValues(c),e=this._tickMarkContainer.selectAll("."+a.Abstract.Axis.TICK_MARK_CLASS).filter(function(a){return d.map(function(a){return a.valueOf()}).indexOf(a.valueOf())>=0});"top"===this._orientation&&(b=this.availableHeight-b),e.attr("y2",b)},c.prototype.generateLabellessTicks=function(b){if(!(0>b)){var d=this._getTickIntervalValues(c.minorIntervals[b]),e=this._getTickValues().concat(d),f=this._tickMarkContainer.selectAll("."+a.Abstract.Axis.TICK_MARK_CLASS).data(e);f.enter().append("line").classed(a.Abstract.Axis.TICK_MARK_CLASS,!0),f.attr(this._generateTickMarkAttrHash()),f.exit().remove(),this.adjustTickLength(this.tickLabelPadding(),c.minorIntervals[b])}},c.prototype._doRender=function(){b.prototype._doRender.call(this);var a=this.getTickLevel();this.renderTickLabels(this._minorTickLabels,c.minorIntervals[a],1),this.renderTickLabels(this._majorTickLabels,c.majorIntervals[a],2);var d=this._scale.domain(),e=this._scale.scale(d[1])-this._scale.scale(d[0]);return 1.5*this.getIntervalLength(c.minorIntervals[a])>=e&&this.generateLabellessTicks(a-1),this.adjustTickLength(this.tickLength()/2,c.minorIntervals[a]),this.adjustTickLength(this.tickLength(),c.majorIntervals[a]),this},c.minorIntervals=[{timeUnit:d3.time.second,step:1,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:5,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:10,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:15,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:30,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.minute,step:1,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:5,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:10,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:15,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:30,formatString:"%I:%M %p"},{timeUnit:d3.time.hour,step:1,formatString:"%I %p"},{timeUnit:d3.time.hour,step:3,formatString:"%I %p"},{timeUnit:d3.time.hour,step:6,formatString:"%I %p"},{timeUnit:d3.time.hour,step:12,formatString:"%I %p"},{timeUnit:d3.time.day,step:1,formatString:"%a %e"},{timeUnit:d3.time.day,step:1,formatString:"%e"},{timeUnit:d3.time.month,step:1,formatString:"%B"},{timeUnit:d3.time.month,step:1,formatString:"%b"},{timeUnit:d3.time.month,step:3,formatString:"%B"},{timeUnit:d3.time.month,step:6,formatString:"%B"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%y"},{timeUnit:d3.time.year,step:5,formatString:"%Y"},{timeUnit:d3.time.year,step:25,formatString:"%Y"},{timeUnit:d3.time.year,step:50,formatString:"%Y"},{timeUnit:d3.time.year,step:100,formatString:"%Y"},{timeUnit:d3.time.year,step:200,formatString:"%Y"},{timeUnit:d3.time.year,step:500,formatString:"%Y"},{timeUnit:d3.time.year,step:1e3,formatString:"%Y"}],c.majorIntervals=[{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""}],c}(a.Abstract.Axis);b.Time=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,c,d){b.call(this,a,c,d),this.tickLabelPositioning="center",this.showFirstTickLabel=!1,this.showLastTickLabel=!1}return __extends(c,b),c.prototype._computeWidth=function(){var b=this._getTickValues(),c=function(a){var b=Math.floor(Math.log(Math.abs(a))/Math.LN10);return b>0?b:1},d=Math.max.apply(null,b.map(c)),e=this._formatter.precision(),f=-(Math.pow(10,d)+Math.pow(10,-e)),g=this._tickLabelContainer.append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),h=this._formatter.format(f),i=g.text(h).node().getComputedTextLength();return g.remove(),this._computedWidth="center"===this.tickLabelPositioning?this.tickLength()+this.tickLabelPadding()+i:Math.max(this.tickLength(),this.tickLabelPadding()+i),this._computedWidth},c.prototype._computeHeight=function(){var b=this._tickLabelContainer.append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),c=a.Util.DOM.getBBox(b.text("test")).height;return b.remove(),this._computedHeight="center"===this.tickLabelPositioning?this.tickLength()+this.tickLabelPadding()+c:Math.max(this.tickLength(),this.tickLabelPadding()+c),this._computedHeight},c.prototype._getTickValues=function(){return this._scale.ticks()},c.prototype._doRender=function(){var c=this;b.prototype._doRender.call(this);var d={x:0,y:0,dx:"0em",dy:"0.3em"},e=this.tickLength(),f=this.tickLabelPadding(),g="middle",h=0,i=0,j=0,k=0;if(this._isHorizontal())switch(this.tickLabelPositioning){case"left":g="end",h=-f,k=f;break;case"center":k=e+f;break;case"right":g="start",h=f,k=f}else switch(this.tickLabelPositioning){case"top":d.dy="-0.3em",j=f,i=-f;break;case"center":j=e+f;break;case"bottom":d.dy="1em",j=f,i=f}var l=this._generateTickMarkAttrHash();switch(this._orientation){case"bottom":d.x=l.x1,d.dy="0.95em",i=l.y1+k;break;case"top":d.x=l.x1,d.dy="-.25em",i=l.y1-k;break;case"left":g="end",h=l.x1-j,d.y=l.y1;break;case"right":g="start",h=l.x1+j,d.y=l.y1}var m=this._getTickValues(),n=this._tickLabelContainer.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).data(m);n.enter().append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),n.exit().remove();var o=function(a){return c._formatter.format(a)};n.style("text-anchor",g).style("visibility","visible").attr(d).text(o);var p="translate("+h+", "+i+")";return this._tickLabelContainer.attr("transform",p),this.showEndTickLabels()||this._hideEndTickLabels(),this._hideOverlappingTickLabels(),this},c.prototype.tickLabelPosition=function(a){if(null==a)return this.tickLabelPositioning;var b=a.toLowerCase();if(this._isHorizontal()){if("left"!==b&&"center"!==b&&"right"!==b)throw new Error(b+" is not a valid tick label position for a horizontal NumericAxis")}else if("top"!==b&&"center"!==b&&"bottom"!==b)throw new Error(b+" is not a valid tick label position for a vertical NumericAxis");return this.tickLabelPositioning=b,this._invalidateLayout(),this},c.prototype.showEndTickLabel=function(a,b){if(this._isHorizontal()&&"left"===a||!this._isHorizontal()&&"bottom"===a)return void 0===b?this.showFirstTickLabel:(this.showFirstTickLabel=b,this._render());if(this._isHorizontal()&&"right"===a||!this._isHorizontal()&&"top"===a)return void 0===b?this.showLastTickLabel:(this.showLastTickLabel=b,this._render());throw new Error("Attempt to show "+a+" tick label on a "+(this._isHorizontal()?"horizontal":"vertical")+" axis")},c}(a.Abstract.Axis);b.Numeric=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){"undefined"==typeof d&&(d="bottom"),"undefined"==typeof e&&(e=new a.Formatter.Identity);var f=this;if(b.call(this,c,d,e),this.classed("category-axis",!0),"bands"!==c.rangeType())throw new Error("Only rangeBands category axes are implemented");this._scale.broadcaster.registerListener(this,function(){return f._invalidateLayout()})}return __extends(c,b),c.prototype._setup=function(){return b.prototype._setup.call(this),this.measurer=new a.Util.Text.CachingCharacterMeasurer(this._tickLabelContainer),this},c.prototype._requestedSpace=function(a,b){var c=this._isHorizontal()?0:this.tickLength()+this.tickLabelPadding(),d=this._isHorizontal()?this.tickLength()+this.tickLabelPadding():0;if(0>a||0>b)return{width:a,height:b,wantsWidth:!this._isHorizontal(),wantsHeight:this._isHorizontal()};if(0===this._scale.domain().length)return{width:0,height:0,wantsWidth:!1,wantsHeight:!1};var e=this._scale.copy();e.range(this._isHorizontal()?[0,a]:[b,0]);var f=this.measureTicks(a,b,e,this._scale.domain());return{width:f.usedWidth+c,height:f.usedHeight+d,wantsWidth:!f.textFits,wantsHeight:!f.textFits}},c.prototype._getTickValues=function(){return this._scale.domain()},c.prototype.measureTicks=function(b,c,d,e){var f="string"!=typeof e[0],g=this,h=[],i=function(a){return g.measurer.measure(a)},j=f?function(a){return e.each(a)}:function(a){return e.forEach(a)};j(function(e){var j,k=d.fullBandStartAndWidth(e)[1],l=g._isHorizontal()?k:b-g.tickLength()-g.tickLabelPadding(),m=g._isHorizontal()?c-g.tickLength()-g.tickLabelPadding():k,n=g._formatter;if(f){var o=d3.select(this),p={left:"right",right:"left",top:"center",bottom:"center"},q={left:"center",right:"center",top:"bottom",bottom:"top"};j=a.Util.Text.writeText(n.format(e),l,m,i,!0,{g:o,xAlign:p[g._orientation],yAlign:q[g._orientation]})}else j=a.Util.Text.writeText(n.format(e),l,m,i,!0);h.push(j)});var k=this._isHorizontal()?d3.sum:d3.max,l=this._isHorizontal()?d3.max:d3.sum;return{textFits:h.every(function(a){return a.textFits}),usedWidth:k(h,function(a){return a.usedWidth}),usedHeight:l(h,function(a){return a.usedHeight})}},c.prototype._doRender=function(){var c=this;b.prototype._doRender.call(this);var d=this._tickLabelContainer.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).data(this._scale.domain(),function(a){return a}),e=function(a){var b=c._scale.fullBandStartAndWidth(a),d=b[0],e=c._isHorizontal()?d:0,f=c._isHorizontal()?0:d;return"translate("+e+","+f+")"};d.enter().append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),d.exit().remove(),d.attr("transform",e),d.text(""),this.measureTicks(this.availableWidth,this.availableHeight,this._scale,d);var f=this._isHorizontal()?[this._scale.rangeBand()/2,0]:[0,this._scale.rangeBand()/2],g="right"===this._orientation?this.tickLength()+this.tickLabelPadding():0,h="bottom"===this._orientation?this.tickLength()+this.tickLabelPadding():0;return a.Util.DOM.translate(this._tickLabelContainer,g,h),a.Util.DOM.translate(this._tickMarkContainer,f[0],f[1]),this},c.prototype._computeLayout=function(a,c,d,e){return this.measurer.clear(),b.prototype._computeLayout.call(this,a,c,d,e)},c}(a.Abstract.Axis);b.Category=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,c){if("undefined"==typeof a&&(a=""),"undefined"==typeof c&&(c="horizontal"),b.call(this),this.classed("label",!0),this.text(a),c=c.toLowerCase(),"vertical-left"===c&&(c="left"),"vertical-right"===c&&(c="right"),"horizontal"!==c&&"left"!==c&&"right"!==c)throw new Error(c+" is not a valid orientation for LabelComponent");this.orientation=c,this.xAlign("center").yAlign("center")}return __extends(c,b),c.prototype.xAlign=function(a){var c=a.toLowerCase();return b.prototype.xAlign.call(this,c),this.xAlignment=c,this},c.prototype.yAlign=function(a){var c=a.toLowerCase();return b.prototype.yAlign.call(this,c),this.yAlignment=c,this},c.prototype._requestedSpace=function(a,b){var c=this.measurer(this._text),d="horizontal"===this.orientation?c.width:c.height,e="horizontal"===this.orientation?c.height:c.width;return{width:Math.min(d,a),height:Math.min(e,b),wantsWidth:d>a,wantsHeight:e>b}},c.prototype._setup=function(){return b.prototype._setup.call(this),this.textContainer=this.content.append("g"),this.measurer=a.Util.Text.getTextMeasure(this.textContainer),this.text(this._text),this},c.prototype.text=function(a){return void 0===a?this._text:(this._text=a,this._invalidateLayout(),this)},c.prototype._doRender=function(){b.prototype._doRender.call(this),this.textContainer.selectAll("text").remove();var c="horizontal"===this.orientation?this.availableWidth:this.availableHeight,d=a.Util.Text.getTruncatedText(this._text,c,this.measurer);return"horizontal"===this.orientation?a.Util.Text.writeLineHorizontally(d,this.textContainer,this.availableWidth,this.availableHeight,this.xAlignment,this.yAlignment):a.Util.Text.writeLineVertically(d,this.textContainer,this.availableWidth,this.availableHeight,this.xAlignment,this.yAlignment,this.orientation),this},c.prototype._computeLayout=function(c,d,e,f){return b.prototype._computeLayout.call(this,c,d,e,f),this.measurer=a.Util.Text.getTextMeasure(this.textContainer),this},c}(a.Abstract.Component);b.Label=c;var d=function(a){function b(b,c){a.call(this,b,c),this.classed("title-label",!0)}return __extends(b,a),b}(c);b.TitleLabel=d;var e=function(a){function b(b,c){a.call(this,b,c),this.classed("axis-label",!0)}return __extends(b,a),b}(c);b.AxisLabel=e}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){b.call(this),this.classed("legend",!0),this.scale(a),this.xAlign("RIGHT").yAlign("TOP"),this.xOffset(5).yOffset(5)}return __extends(c,b),c.prototype.remove=function(){b.prototype.remove.call(this),null!=this.colorScale&&this.colorScale.broadcaster.deregisterListener(this)},c.prototype.toggleCallback=function(a){return void 0!==a?(this._toggleCallback=a,this.isOff=d3.set(),this.updateListeners(),this.updateClasses(),this):this._toggleCallback},c.prototype.hoverCallback=function(a){return void 0!==a?(this._hoverCallback=a,this.datumCurrentlyFocusedOn=void 0,this.updateListeners(),this.updateClasses(),this):this._hoverCallback},c.prototype.scale=function(a){var b=this;return null!=a?(null!=this.colorScale&&this.colorScale.broadcaster.deregisterListener(this),this.colorScale=a,this.colorScale.broadcaster.registerListener(this,function(){return b.updateDomain()}),this.updateDomain(),this):this.colorScale},c.prototype.updateDomain=function(){null!=this._toggleCallback&&(this.isOff=a.Util.Methods.intersection(this.isOff,d3.set(this.scale().domain()))),null!=this._hoverCallback&&(this.datumCurrentlyFocusedOn=this.scale().domain().indexOf(this.datumCurrentlyFocusedOn)>=0?this.datumCurrentlyFocusedOn:void 0),this._invalidateLayout()},c.prototype._computeLayout=function(a,c,d,e){b.prototype._computeLayout.call(this,a,c,d,e);var f=this.measureTextHeight(),g=this.colorScale.domain().length;return this.nRowsDrawn=Math.min(g,Math.floor(this.availableHeight/f)),this},c.prototype._requestedSpace=function(b,d){var e=this.measureTextHeight(),f=this.colorScale.domain().length,g=Math.min(f,Math.floor(d/e)),h=this.content.append("g").classed(c.SUBELEMENT_CLASS,!0),i=h.append("text"),j=d3.max(this.colorScale.domain(),function(b){return a.Util.Text.getTextWidth(i,b)});h.remove(),j=void 0===j?0:j;var k=j+e+2*c.MARGIN;return{width:Math.min(k,b),height:g*e,wantsWidth:k>b,wantsHeight:f>g}},c.prototype.measureTextHeight=function(){var b=this.content.append("g").classed(c.SUBELEMENT_CLASS,!0),d=a.Util.Text.getTextHeight(b.append("text"));return 0===d&&(d=1),b.remove(),d},c.prototype._doRender=function(){b.prototype._doRender.call(this);var d=this.colorScale.domain().slice(0,this.nRowsDrawn),e=this.measureTextHeight(),f=this.availableWidth-e-c.MARGIN,g=e/2-c.MARGIN,h=this.content.selectAll("."+c.SUBELEMENT_CLASS).data(d,function(a){return a}),i=h.enter().append("g").classed(c.SUBELEMENT_CLASS,!0);return i.append("circle").attr("cx",c.MARGIN+g).attr("cy",c.MARGIN+g).attr("r",g),i.append("text").attr("x",e).attr("y",c.MARGIN+e/2),h.exit().remove(),h.attr("transform",function(a){return"translate(0,"+d.indexOf(a)*e+")"}),h.selectAll("circle").attr("fill",this.colorScale._d3Scale),h.selectAll("text").text(function(b){var c=a.Util.Text.getTextMeasure(d3.select(this));return a.Util.Text.getTruncatedText(b,f,c)}),this.updateClasses(),this.updateListeners(),this},c.prototype.updateListeners=function(){var a=this;if(this._isSetup){var b=this.content.selectAll("."+c.SUBELEMENT_CLASS);if(null!=this._hoverCallback){var d=function(b){return function(c){a.datumCurrentlyFocusedOn=b?c:void 0,a._hoverCallback(a.datumCurrentlyFocusedOn),a.updateClasses()}};b.on("mouseover",d(!0)),b.on("mouseout",d(!1))}else b.on("mouseover",null),b.on("mouseout",null);null!=this._toggleCallback?b.on("click",function(b){var c=a.isOff.has(b);c?a.isOff.remove(b):a.isOff.add(b),a._toggleCallback(b,c),a.updateClasses()}):b.on("click",null)}},c.prototype.updateClasses=function(){var a=this;if(this._isSetup){var b=this.content.selectAll("."+c.SUBELEMENT_CLASS);null!=this._hoverCallback?(b.classed("focus",function(b){return a.datumCurrentlyFocusedOn===b}),b.classed("hover",void 0!==this.datumCurrentlyFocusedOn)):(b.classed("hover",!1),b.classed("focus",!1)),null!=this._toggleCallback?(b.classed("toggled-on",function(b){return!a.isOff.has(b)}),b.classed("toggled-off",function(b){return a.isOff.has(b)})):(b.classed("toggled-on",!1),b.classed("toggled-off",!1))}},c.SUBELEMENT_CLASS="legend-row",c.MARGIN=5,c}(a.Abstract.Component);b.Legend=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c){var d=this;if(a.call(this),null==b&&null==c)throw new Error("Gridlines must have at least one scale");this.classed("gridlines",!0),this.xScale=b,this.yScale=c,null!=this.xScale&&this.xScale.broadcaster.registerListener(this,function(){return d._render()}),null!=this.yScale&&this.yScale.broadcaster.registerListener(this,function(){return d._render()})}return __extends(b,a),b.prototype.remove=function(){return a.prototype.remove.call(this),null!=this.xScale&&this.xScale.broadcaster.deregisterListener(this),null!=this.yScale&&this.yScale.broadcaster.deregisterListener(this),this},b.prototype._setup=function(){return a.prototype._setup.call(this),this.xLinesContainer=this.content.append("g").classed("x-gridlines",!0),this.yLinesContainer=this.content.append("g").classed("y-gridlines",!0),this},b.prototype._doRender=function(){return a.prototype._doRender.call(this),this.redrawXLines(),this.redrawYLines(),this},b.prototype.redrawXLines=function(){var a=this;if(null!=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.availableHeight),d.exit().remove()}},b.prototype.redrawYLines=function(){var a=this;if(null!=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.availableWidth).attr("y2",c),d.exit().remove()}},b}(a.Abstract.Component);b.Gridlines=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(a){function b(b,c,d){"undefined"==typeof c&&(c=a.ONE_DAY),"undefined"==typeof d&&(d="");var e=function(a){var e=Math.round((a.valueOf()-b)/c);return e.toString()+d};return e}a.ONE_DAY=864e5,a.generateRelativeDateFormatter=b}(a.Axis||(a.Axis={}));a.Axis}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,c,d){if(b.call(this,a),null==c||null==d)throw new Error("XYPlots require an xScale and yScale");this.classed("xy-renderer",!0),this.project("x","x",c),this.project("y","y",d)}return __extends(c,b),c.prototype.project=function(a,c,d){return"x"===a&&null!=d&&(this.xScale=d,this._updateXDomainer()),"y"===a&&null!=d&&(this.yScale=d,this._updateYDomainer()),b.prototype.project.call(this,a,c,d),this},c.prototype._computeLayout=function(a,c,d,e){return b.prototype._computeLayout.call(this,a,c,d,e),this.xScale.range([0,this.availableWidth]),this.yScale.range([this.availableHeight,0]),this},c.prototype._updateXDomainer=function(){if(this.xScale instanceof a.Abstract.QuantitativeScale){var b=this.xScale;b._userSetDomainer||b.domainer().pad().nice()}return this},c.prototype._updateYDomainer=function(){if(this.yScale instanceof a.Abstract.QuantitativeScale){var b=this.yScale;b._userSetDomainer||b.domainer().pad().nice()}return this},c}(a.Abstract.Plot);b.XYPlot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._animators={"circles-reset":new a.Animator.Null,circles:(new a.Animator.IterativeDelay).duration(250).delay(5)},this.classed("circle-renderer",!0),this.project("r",3),this.project("fill",function(){return"steelblue"})}return __extends(c,b),c.prototype.project=function(a,c,d){return a="cx"===a?"x":a,a="cy"===a?"y":a,b.prototype.project.call(this,a,c,d),this},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector();a.cx=a.x,a.cy=a.y,delete a.x,delete a.y;var c=this.renderArea.selectAll("circle").data(this._dataSource.data());if(c.enter().append("circle"),this._dataChanged){var d=a.r;a.r=function(){return 0},this._applyAnimatedAttributes(c,"circles-reset",a),a.r=d}this._applyAnimatedAttributes(c,"circles",a),c.exit().remove()},c}(a.Abstract.XYPlot);b.Scatter=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e,f){b.call(this,c,d,e),this._animators={cells:new a.Animator.Null},this.classed("grid-renderer",!0),this.xScale.rangeType("bands",0,0),this.yScale.rangeType("bands",0,0),this.colorScale=f,this.project("fill","value",f)}return __extends(c,b),c.prototype.project=function(a,c,d){return b.prototype.project.call(this,a,c,d),"fill"===a&&(this.colorScale=this._projectors.fill.scale),this},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this.renderArea.selectAll("rect").data(this._dataSource.data());a.enter().append("rect");var c=this.xScale.rangeBand(),d=this.yScale.rangeBand(),e=this._generateAttrToProjector();e.width=function(){return c},e.height=function(){return d},this._applyAnimatedAttributes(a,"cells",e),a.exit().remove()},c}(a.Abstract.XYPlot);b.Grid=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._baselineValue=0,this._barAlignmentFactor=0,this._animators={"bars-reset":new a.Animator.Null,bars:new a.Animator.IterativeDelay,baseline:new a.Animator.Null},this.classed("bar-renderer",!0),this.project("fill",function(){return"steelblue"}),this.baseline(this._baselineValue)}return __extends(c,b),c.prototype._setup=function(){return b.prototype._setup.call(this),this._baseline=this.renderArea.append("line").classed("baseline",!0),this._bars=this.renderArea.selectAll("rect").data([]),this},c.prototype._paint=function(){b.prototype._paint.call(this),this._bars=this.renderArea.selectAll("rect").data(this._dataSource.data()),this._bars.enter().append("rect");var a=this._isVertical?this.yScale:this.xScale,c=a.scale(this._baselineValue),d=this._isVertical?"y":"x",e=this._isVertical?"height":"width";if(this._dataChanged&&this._animate){var f=this._generateAttrToProjector();f[d]=function(){return c},f[e]=function(){return 0},this._applyAnimatedAttributes(this._bars,"bars-reset",f)}var g=this._generateAttrToProjector();null!=g.fill&&this._bars.attr("fill",g.fill),this._applyAnimatedAttributes(this._bars,"bars",g),this._bars.exit().remove();var h={x1:this._isVertical?0:c,y1:this._isVertical?c:0,x2:this._isVertical?this.availableWidth:c,y2:this._isVertical?c:this.availableHeight};this._applyAnimatedAttributes(this._baseline,"baseline",h)},c.prototype.baseline=function(a){return this._baselineValue=a,this._updateXDomainer(),this._updateYDomainer(),this._render(),this},c.prototype.barAlignment=function(a){var b=a.toLowerCase(),c=this.constructor._BarAlignmentToFactor;if(void 0===c[b])throw new Error("unsupported bar alignment");return this._barAlignmentFactor=c[b],this._render(),this},c.prototype.parseExtent=function(a){if("number"==typeof a)return{min:a,max:a};if(a instanceof Object&&"min"in a&&"max"in a)return a;throw new Error("input '"+a+"' can't be parsed as an IExtent")},c.prototype.selectBar=function(a,b,c){if("undefined"==typeof c&&(c=!0),!this._isSetup)return null;var d=[],e=this.parseExtent(a),f=this.parseExtent(b),g=.5;if(this._bars.each(function(){var a=this.getBBox();a.x+a.width>=e.min-g&&a.x<=e.max+g&&a.y+a.height>=f.min-g&&a.y<=f.max+g&&d.push(this)}),d.length>0){var h=d3.selectAll(d);return h.classed("selected",c),h}return null},c.prototype.deselectAll=function(){return this._isSetup&&this._bars.classed("selected",!1),this},c.prototype._updateDomainer=function(b){if(b instanceof a.Abstract.QuantitativeScale){var c=b;c._userSetDomainer||(null!=this._baselineValue?c.domainer().addPaddingException(this._baselineValue,"BAR_PLOT+"+this._plottableID).addIncludedValue(this._baselineValue,"BAR_PLOT+"+this._plottableID):c.domainer().removePaddingException("BAR_PLOT+"+this._plottableID).removeIncludedValue("BAR_PLOT+"+this._plottableID)),c._autoDomainIfAutomaticMode()}return this},c.prototype._generateAttrToProjector=function(){var d=this,e=b.prototype._generateAttrToProjector.call(this),f=this._isVertical?this.yScale:this.xScale,g=this._isVertical?this.xScale:this.yScale,h=this._isVertical?"y":"x",i=this._isVertical?"x":"y",j=g instanceof a.Scale.Ordinal&&"bands"===g.rangeType(),k=f.scale(this._baselineValue);if(null==e.width){var l=j?g.rangeBand():c.DEFAULT_WIDTH;e.width=function(){return l}}var m=e[i],n=e.width;if(j){var o=g.rangeBand();e[i]=function(a,b){return m(a,b)-n(a,b)/2+o/2}}else e[i]=function(a,b){return m(a,b)-n(a,b)*d._barAlignmentFactor};var p=e[h];return e[h]=function(a,b){var c=p(a,b);return c>k?k:c},e.height=function(a,b){return Math.abs(k-p(a,b))},e},c.DEFAULT_WIDTH=10,c._BarAlignmentToFactor={},c}(a.Abstract.XYPlot);b.BarPlot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c,d){a.call(this,b,c,d),this._isVertical=!0}return __extends(b,a),b.prototype._updateYDomainer=function(){return this._updateDomainer(this.yScale),this},b._BarAlignmentToFactor={left:0,center:.5,right:1},b}(a.Abstract.BarPlot);b.VerticalBar=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c,d){a.call(this,b,c,d),this.isVertical=!1}return __extends(b,a),b.prototype._updateXDomainer=function(){return this._updateDomainer(this.xScale),this},b.prototype._generateAttrToProjector=function(){var b=a.prototype._generateAttrToProjector.call(this),c=b.width;return b.width=b.height,b.height=c,b},b._BarAlignmentToFactor={top:0,center:.5,bottom:1},b}(a.Abstract.BarPlot);b.HorizontalBar=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._animators={"line-reset":new a.Animator.Null,line:(new a.Animator.Default).duration(600).easing("exp-in-out")},this.classed("line-renderer",!0),this.project("stroke",function(){return"steelblue"}),this.project("stroke-width",function(){return"2px"})}return __extends(c,b),c.prototype._setup=function(){return b.prototype._setup.call(this),this.linePath=this.renderArea.append("path").classed("line",!0),this},c.prototype._getResetYFunction=function(){var a=this.yScale.domain(),b=Math.max(a[0],a[1]),c=Math.min(a[0],a[1]),d=0; -0>b?d=b:c>0&&(d=c);var e=this.yScale.scale(d);return function(){return e}},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector(),c=a.x,d=a.y;delete a.x,delete a.y,this.linePath.datum(this._dataSource.data()),this._dataChanged&&(a.d=d3.svg.line().x(c).y(this._getResetYFunction()),this._applyAnimatedAttributes(this.linePath,"line-reset",a)),a.d=d3.svg.line().x(c).y(d),this._applyAnimatedAttributes(this.linePath,"line",a)},c}(a.Abstract.XYPlot);b.Line=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this.classed("area-renderer",!0),this.project("y0",0,e),this.project("fill",function(){return"steelblue"}),this.project("fill-opacity",function(){return.5}),this.project("stroke",function(){return"none"}),this._animators["area-reset"]=new a.Animator.Null,this._animators.area=(new a.Animator.Default).duration(600).easing("exp-in-out")}return __extends(c,b),c.prototype._setup=function(){return b.prototype._setup.call(this),this.areaPath=this.renderArea.append("path").classed("area",!0),this},c.prototype._onDataSourceUpdate=function(){b.prototype._onDataSourceUpdate.call(this),null!=this.yScale&&this._updateYDomainer()},c.prototype._updateYDomainer=function(){b.prototype._updateYDomainer.call(this);var a=this.yScale,c=this._projectors.y0,d=null!=c?c.accessor:null,e=null!=d?this.dataSource()._getExtent(d):[],f=2===e.length&&e[0]===e[1]?e[0]:null;return a._userSetDomainer||(null!=f?a.domainer().addPaddingException(f,"AREA_PLOT+"+this._plottableID):a.domainer().removePaddingException("AREA_PLOT+"+this._plottableID),a._autoDomainIfAutomaticMode()),this},c.prototype.project=function(a,c,d){return b.prototype.project.call(this,a,c,d),"y0"===a&&this._updateYDomainer(),this},c.prototype._getResetYFunction=function(){return this._generateAttrToProjector().y0},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector(),c=a.x,d=a.y0,e=a.y;delete a.x,delete a.y0,delete a.y,this.areaPath.datum(this._dataSource.data()),this._dataChanged&&(a.d=d3.svg.area().x(c).y0(d).y1(this._getResetYFunction()),this._applyAnimatedAttributes(this.areaPath,"area-reset",a)),a.d=d3.svg.area().x(c).y0(d).y1(e),this._applyAnimatedAttributes(this.areaPath,"area",a)},c}(a.Plot.Line);b.Area=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){}return a.prototype.animate=function(a,b){return a.attr(b)},a}();a.Null=b}(a.Animator||(a.Animator={}));a.Animator}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this._durationMsec=300,this._delayMsec=0,this._easing="exp-out"}return a.prototype.animate=function(a,b){return a.transition().ease(this._easing).duration(this._durationMsec).delay(this._delayMsec).attr(b)},a.prototype.duration=function(a){return void 0===a?this._durationMsec:(this._durationMsec=a,this)},a.prototype.delay=function(a){return void 0===a?this._delayMsec:(this._delayMsec=a,this)},a.prototype.easing=function(a){return void 0===a?this._easing:(this._easing=a,this)},a}();a.Default=b}(a.Animator||(a.Animator={}));a.Animator}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.apply(this,arguments),this._delayMsec=15}return __extends(b,a),b.prototype.animate=function(a,b){var c=this;return a.transition().ease(this._easing).duration(this._durationMsec).delay(function(a,b){return b*c._delayMsec}).attr(b)},b}(a.Animator.Default);b.IterativeDelay=c}(a.Animator||(a.Animator={}));a.Animator}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(a){function b(){e||(d3.select(document).on("keydown",d),e=!0)}function c(a,c){e||b(),null==f[a]&&(f[a]=[]),f[a].push(c)}function d(){null!=f[d3.event.keyCode]&&f[d3.event.keyCode].forEach(function(a){a(d3.event)})}var e=!1,f=[];a.initialize=b,a.addCallback=c}(a.KeyEventListener||(a.KeyEventListener={}));a.KeyEventListener}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(a){if(null==a)throw new Error("Interactions require a component to listen to");this.componentToListenTo=a}return a.prototype._anchor=function(a){this.hitBox=a},a.prototype.registerWithComponent=function(){return this.componentToListenTo.registerInteraction(this),this},a}();a.Interaction=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,b)}return __extends(b,a),b.prototype._anchor=function(b){var c=this;a.prototype._anchor.call(this,b),b.on(this._listenTo(),function(){var a=d3.mouse(b.node()),d=a[0],e=a[1];c._callback(d,e)})},b.prototype._listenTo=function(){return"click"},b.prototype.callback=function(a){return this._callback=a,this},b}(a.Abstract.Interaction);b.Click=c;var d=function(a){function b(b){a.call(this,b)}return __extends(b,a),b.prototype._listenTo=function(){return"dblclick"},b}(c);b.DoubleClick=d}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,b)}return __extends(b,a),b.prototype._anchor=function(b){var c=this;a.prototype._anchor.call(this,b),b.on("mousemove",function(){var a=d3.mouse(b.node()),d=a[0],e=a[1];c.mousemove(d,e)})},b.prototype.mousemove=function(){},b}(a.Abstract.Interaction);b.Mousemove=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,c){b.call(this,a),this.activated=!1,this.keyCode=c}return __extends(c,b),c.prototype._anchor=function(c){var d=this;b.prototype._anchor.call(this,c),c.on("mouseover",function(){d.activated=!0}),c.on("mouseout",function(){d.activated=!1}),a.Core.KeyEventListener.addCallback(this.keyCode,function(){d.activated&&null!=d._callback&&d._callback()})},c.prototype.callback=function(a){return this._callback=a,this},c}(a.Abstract.Interaction);b.Key=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c,d){var e=this;if(a.call(this,b),null==c||null==d)throw new Error("panZoomInteractions require an xScale and yScale");this.xScale=c,this.yScale=d,this.zoom=d3.behavior.zoom(),this.zoom.x(this.xScale._d3Scale),this.zoom.y(this.yScale._d3Scale),this.zoom.on("zoom",function(){return e.rerenderZoomed()})}return __extends(b,a),b.prototype.resetZoom=function(){var a=this;this.zoom=d3.behavior.zoom(),this.zoom.x(this.xScale._d3Scale),this.zoom.y(this.yScale._d3Scale),this.zoom.on("zoom",function(){return a.rerenderZoomed()}),this.zoom(this.hitBox)},b.prototype._anchor=function(b){a.prototype._anchor.call(this,b),this.zoom(b)},b.prototype.rerenderZoomed=function(){var a=this.xScale._d3Scale.domain(),b=this.yScale._d3Scale.domain();this.xScale.domain(a),this.yScale.domain(b)},b}(a.Abstract.Interaction);b.PanZoom=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){var c=this;a.call(this,b),this.dragInitialized=!1,this.origin=[0,0],this.location=[0,0],this.dragBehavior=d3.behavior.drag(),this.dragBehavior.on("dragstart",function(){return c._dragstart()}),this.dragBehavior.on("drag",function(){return c._drag()}),this.dragBehavior.on("dragend",function(){return c._dragend()})}return __extends(b,a),b.prototype.callback=function(a){return this.callbackToCall=a,this},b.prototype._dragstart=function(){var a=this.componentToListenTo.availableWidth,b=this.componentToListenTo.availableHeight,c=function(a,b){return function(c){return Math.min(Math.max(c,a),b)}};this.constrainX=c(0,a),this.constrainY=c(0,b)},b.prototype._drag=function(){this.dragInitialized||(this.origin=[d3.event.x,d3.event.y],this.dragInitialized=!0),this.location=[this.constrainX(d3.event.x),this.constrainY(d3.event.y)]},b.prototype._dragend=function(){this.dragInitialized&&(this.dragInitialized=!1,this._doDragend())},b.prototype._doDragend=function(){null!=this.callbackToCall&&this.callbackToCall([this.origin,this.location])},b.prototype._anchor=function(b){return a.prototype._anchor.call(this,b),b.call(this.dragBehavior),this},b.prototype.setupZoomCallback=function(a,b){function c(c){return null==c?(f&&(null!=a&&a.domain(d),null!=b&&b.domain(e)),void(f=!f)):(f=!1,null!=a&&a.domain([a.invert(c.xMin),a.invert(c.xMax)]),null!=b&&b.domain([b.invert(c.yMax),b.invert(c.yMin)]),void this.clearBox())}var d=null!=a?a.domain():null,e=null!=b?b.domain():null,f=!1;return this.callback(c),this},b}(a.Abstract.Interaction);b.Drag=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.apply(this,arguments),this.boxIsDrawn=!1}return __extends(b,a),b.prototype._dragstart=function(){a.prototype._dragstart.call(this),null!=this.callbackToCall&&this.callbackToCall(null),this.clearBox()},b.prototype.clearBox=function(){return null!=this.dragBox?(this.dragBox.attr("height",0).attr("width",0),this.boxIsDrawn=!1,this):void 0},b.prototype.setBox=function(a,b,c,d){if(null!=this.dragBox){var e=Math.abs(a-b),f=Math.abs(c-d),g=Math.min(a,b),h=Math.min(c,d);return this.dragBox.attr({x:g,y:h,width:e,height:f}),this.boxIsDrawn=e>0&&f>0,this}},b.prototype._anchor=function(c){a.prototype._anchor.call(this,c);var d=b.CLASS_DRAG_BOX,e=this.componentToListenTo.foregroundContainer;return this.dragBox=e.append("rect").classed(d,!0).attr("x",0).attr("y",0),this},b.CLASS_DRAG_BOX="drag-box",b}(a.Interaction.Drag);b.DragBox=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype._drag=function(){a.prototype._drag.call(this),this.setBox(this.origin[0],this.location[0])},b.prototype._doDragend=function(){if(null!=this.callbackToCall){var a=Math.min(this.origin[0],this.location[0]),b=Math.max(this.origin[0],this.location[0]),c={xMin:a,xMax:b};this.callbackToCall(c)}},b.prototype.setBox=function(b,c){return a.prototype.setBox.call(this,b,c,0,this.componentToListenTo.availableHeight),this},b}(a.Interaction.DragBox);b.XDragBox=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype._drag=function(){a.prototype._drag.call(this),this.setBox(this.origin[0],this.location[0],this.origin[1],this.location[1])},b.prototype._doDragend=function(){if(null!=this.callbackToCall){var a=Math.min(this.origin[0],this.location[0]),b=Math.max(this.origin[0],this.location[0]),c=Math.min(this.origin[1],this.location[1]),d=Math.max(this.origin[1],this.location[1]),e={xMin:a,xMax:b,yMin:c,yMax:d};this.callbackToCall(e)}},b}(a.Interaction.DragBox);b.XYDragBox=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype._drag=function(){a.prototype._drag.call(this),this.setBox(this.origin[1],this.location[1])},b.prototype._doDragend=function(){if(null!=this.callbackToCall){var a=Math.min(this.origin[1],this.location[1]),b=Math.max(this.origin[1],this.location[1]),c={yMin:a,yMax:b};this.callbackToCall(c)}},b.prototype.setBox=function(b,c){return a.prototype.setBox.call(this,0,this.componentToListenTo.availableWidth,b,c),this},b}(a.Interaction.DragBox);b.YDragBox=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(){b.call(this),this.xTable=new a.Component.Table,this.yTable=new a.Component.Table,this.centerComponent=new a.Component.Group,this.xyTable=(new a.Component.Table).addComponent(0,0,this.yTable).addComponent(1,1,this.xTable).addComponent(0,1,this.centerComponent),this.addComponent(1,0,this.xyTable)}return __extends(c,b),c.prototype.yAxis=function(a){if(null!=a){if(null!=this._yAxis)throw new Error("yAxis already assigned!");return this._yAxis=a,this.yTable.addComponent(0,1,this._yAxis),this}return this._yAxis},c.prototype.xAxis=function(a){if(null!=a){if(null!=this._xAxis)throw new Error("xAxis already assigned!");return this._xAxis=a,this.xTable.addComponent(0,0,this._xAxis),this}return this._xAxis},c.prototype.yLabel=function(b){if(null!=b){if(null!=this._yLabel){if("string"==typeof b)return this._yLabel.text(b),this;throw new Error("yLabel already assigned!")}return"string"==typeof b&&(b=new a.Component.AxisLabel(b,"vertical-left")),this._yLabel=b,this.yTable.addComponent(0,0,this._yLabel),this}return this._yLabel},c.prototype.xLabel=function(b){if(null!=b){if(null!=this._xLabel){if("string"==typeof b)return this._xLabel.text(b),this;throw new Error("xLabel already assigned!")}return"string"==typeof b&&(b=new a.Component.AxisLabel(b,"horizontal")),this._xLabel=b,this.xTable.addComponent(1,0,this._xLabel),this}return this._xLabel},c.prototype.titleLabel=function(b){if(null!=b){if(null!=this._titleLabel){if("string"==typeof b)return this._titleLabel.text(b),this;throw new Error("titleLabel already assigned!")}return"string"==typeof b&&(b=new a.Component.TitleLabel(b,"horizontal")),this._titleLabel=b,this.addComponent(0,0,this._titleLabel),this}return this._titleLabel},c.prototype.center=function(a){return this.centerComponent.merge(a),this},c}(a.Component.Table);b.StandardChart=c}(a.Template||(a.Template={}));a.Template}(Plottable||(Plottable={})); \ No newline at end of file +var Plottable;!function(a){!function(a){!function(a){function b(a,b,c){return Math.min(b,c)<=a&&a<=Math.max(b,c)}function c(a){null!=window.console&&(null!=window.console.warn?console.warn(a):null!=window.console.log&&console.log(a))}function d(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 e(a,b){var c=d3.set();return a.forEach(function(a){b.has(a)&&c.add(a)}),c}function f(a){return"function"==typeof a?a:"string"==typeof a&&"#"!==a[0]?function(b){return b[a]}:function(){return a}}function g(a,b){var c=d3.set();return a.forEach(function(a){return c.add(a)}),b.forEach(function(a){return c.add(a)}),c}function h(a,b){var c=f(a);return function(a,d){return c(a,d,b.dataSource().metadata())}}function i(a){var b={};return a.forEach(function(a){return b[a]=!0}),d3.keys(b)}function j(a){var b=d3.set(),c=[];return a.forEach(function(a){b.has(a)||(b.add(a),c.push(a))}),c}function k(a,b){for(var c=[],d=0;b>d;d++)c[d]="function"==typeof a?a(d):a;return c}function l(a){return Array.prototype.concat.apply([],a)}function m(a,b){if(null==a||null==b)return a===b;if(a.length!==b.length)return!1;for(var c=0;cd;){var f=d+e>>>1,g=null==c?b[f]:c(b[f]);a>g?d=f+1:e=f}return d}a.sortedIndex=b}(a.OpenSource||(a.OpenSource={}));a.OpenSource}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this.counter={}}return a.prototype.setDefault=function(a){null==this.counter[a]&&(this.counter[a]=0)},a.prototype.increment=function(a){return this.setDefault(a),++this.counter[a]},a.prototype.decrement=function(a){return this.setDefault(a),--this.counter[a]},a.prototype.get=function(a){return this.setDefault(a),this.counter[a]},a}();a.IDCounter=b}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this.keyValuePairs=[]}return a.prototype.set=function(a,b){if(a!==a)throw new Error("NaN may not be used as a key to the StrictEqualityAssociativeArray");for(var c=0;cb){var h=e("."),i=Math.floor(b/h);return"...".substr(0,i)}for(;f+g>b;)d=d.substr(0,d.length-1).trim(),f=e(d);if(e(d+"...")>b)throw new Error("_addEllipsesToLine failed :(");return d+"..."}function k(b,c,d,e,f,g){"undefined"==typeof f&&(f="left"),"undefined"==typeof g&&(g="top");var h={left:0,center:.5,right:1},i={top:0,center:.5,bottom:1};if(void 0===h[f]||void 0===i[g])throw new Error("unrecognized alignment x:"+f+", y:"+g);var j=c.append("g"),k=j.append("text");k.text(b);var l=a.DOM.getBBox(k),m=l.height,n=l.width;if(n>d||m>e)return a.Methods.warn("Insufficient space to fit text: "+b),k.text(""),{width:0,height:0};var o={left:"start",center:"middle",right:"end"},p=o[f],q=d*h[f],r=e*i[g],s=.85-i[g];return k.attr("text-anchor",p).attr("y",s+"em"),a.DOM.translate(j,q,r),{width:n,height:m}}function l(a,b,c,d,e,f,g){if("undefined"==typeof e&&(e="left"),"undefined"==typeof f&&(f="top"),"undefined"==typeof g&&(g="right"),"right"!==g&&"left"!==g)throw new Error("unrecognized rotation: "+g);var h="right"===g,i={left:"bottom",right:"top",center:"center",top:"left",bottom:"right"},j={left:"top",right:"bottom",center:"center",top:"right",bottom:"left"},l=h?i:j,m=b.append("g"),n=k(a,m,d,c,l[f],l[e]),o=d3.transform("");return o.rotate="right"===g?90:-90,o.translate=[h?c:0,h?0:d],m.attr("transform",o.toString()),n}function m(b,c,d,e,f,g){"undefined"==typeof f&&(f="left"),"undefined"==typeof g&&(g="top");var i=h(c),j=0,l=c.append("g");b.forEach(function(b,c){var e=l.append("g");a.DOM.translate(e,0,c*i);var h=k(b,e,d,i,f,g);h.width>j&&(j=h.width)});var m=i*b.length,n=e-m,o={center:.5,top:0,bottom:1};return a.DOM.translate(l,0,n*o[g]),{width:j,height:m}}function n(b,c,d,e,f,g,i){"undefined"==typeof f&&(f="left"),"undefined"==typeof g&&(g="top"),"undefined"==typeof i&&(i="left");var j=h(c),k=0,m=c.append("g");b.forEach(function(b,c){var d=m.append("g");a.DOM.translate(d,c*j,0);var h=l(b,d,j,e,f,g,i);h.height>k&&(k=h.height)});var n=j*b.length,o=d-n,p={center:.5,left:0,right:1};return a.DOM.translate(m,o*p[f],0),{width:n,height:k}}function o(b,c,d,e,f,g){var h=null!=f?f:1.1*c>d,i=h?c:d,j=h?d:c,k=a.WordWrap.breakTextToFitRect(b,i,j,e);if(0===k.lines.length)return{textFits:k.textFits,usedWidth:0,usedHeight:0};var l,o;if(null==g){var p=h?d3.max:d3.sum,q=h?d3.sum:d3.max;l=p(k.lines,function(a){return e(a).width}),o=q(k.lines,function(a){return e(a).height})}else{var r=g.g.append("g").classed("writeText-inner-g",!0),s=h?m:n,t=s(k.lines,r,c,d,g.xAlign,g.yAlign);l=t.width,o=t.height}return{textFits:k.textFits,usedWidth:l,usedHeight:o}}b.getTextMeasure=c;var p="a",q=function(){function b(b){var g=this;this.cache=new a.Cache(c(b),p,a.Methods.objEq),this.measure=d(e(f(function(a){return g.cache.get(a)})))}return b.prototype.clear=function(){return this.cache.clear(),this},b}();b.CachingCharacterMeasurer=q,b.getTruncatedText=g,b.getTextHeight=h,b.getTextWidth=i,b._addEllipsesToLine=j,b.writeLineHorizontally=k,b.writeLineVertically=l,b.writeTextHorizontally=m,b.writeTextVertically=n,b.writeText=o}(a.Text||(a.Text={}));a.Text}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(b){function c(b,c,e,f){var g=function(a){return f(a).width},h=d(b,c,g),i=f("hello world").height,j=Math.floor(e/i),k=j>=h.length;return k||(h=h.splice(0,j),j>0&&(h[j-1]=a.Text._addEllipsesToLine(h[j-1],c,f))),{originalText:b,lines:h,textFits:k}}function d(a,b,c){for(var d=[],e=a.split("\n"),g=0,h=e.length;h>g;g++){var i=e[g];null!==i?d=d.concat(f(i,b,c)):d.push("")}return d}function e(a,b,c){var d=h(a),e=d.map(c),f=d3.max(e);return b>=f}function f(a,b,c){for(var d,e=[],f=h(a),i="",j=0;d||je;e++){var g=a[e];""===c||j(c[0],g,d)?c+=g:(b.push(c),c=g),d=g}return c&&b.push(c),b}function i(a){return null==a?!0:""===a.trim()}function j(a,b,c){return m.test(a)&&m.test(b)?!0:m.test(a)||m.test(b)?!1:l.test(c)||k.test(b)?!1:!0}var k=/[{\[]/,l=/[!"%),-.:;?\]}]/,m=/^\s+$/;b.breakTextToFitRect=c,b.canWrapWithoutBreakingWords=e}(a.WordWrap||(a.WordWrap={}));a.WordWrap}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(a){function b(a){return a.node().getBBox()}function c(b){null!=window.requestAnimationFrame?window.requestAnimationFrame(b):setTimeout(b,a.POLYFILL_TIMEOUT_MSEC)}function d(a,b){var c=a.getPropertyValue(b),d=parseFloat(c);return d!==d?0:d}function e(a){for(var b=a.node();null!==b&&"svg"!==b.nodeName;)b=b.parentNode;return null==b}function f(a){var b=window.getComputedStyle(a);return d(b,"width")+d(b,"padding-left")+d(b,"padding-right")+d(b,"border-left-width")+d(b,"border-right-width")}function g(a){var b=window.getComputedStyle(a);return d(b,"height")+d(b,"padding-top")+d(b,"padding-bottom")+d(b,"border-top-width")+d(b,"border-bottom-width")}function h(a){var b=a.node().clientWidth;if(0===b){var c=a.attr("width");if(-1!==c.indexOf("%")){for(var d=a.node().parentNode;null!=d&&0===d.clientWidth;)d=d.parentNode;if(null==d)throw new Error("Could not compute width of element");b=d.clientWidth*parseFloat(c)/100}else b=parseFloat(c)}return b}function i(a,b,c){var d=d3.transform(a.attr("transform"));return null==b?d.translate:(c=null==c?0:c,d.translate[0]=b,d.translate[1]=c,a.attr("transform",d.toString()),a)}function j(a,b){return a.rightb.right?!1:a.bottomb.bottom?!1:!0}a.getBBox=b,a.POLYFILL_TIMEOUT_MSEC=1e3/60,a.requestAnimationFramePolyfill=c,a.isSelectionRemovedFromSVG=e,a.getElementWidth=f,a.getElementHeight=g,a.getSVGPixelWidth=h,a.translate=i,a.boxesOverlap=j}(a.DOM||(a.DOM={}));a.DOM}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var Plottable;!function(a){a.MILLISECONDS_IN_ONE_DAY=864e5;var b=function(){function b(){}return b.currency=function(a,c,d,e){"undefined"==typeof a&&(a=2),"undefined"==typeof c&&(c="$"),"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=!0);var f=b.fixed(a);return function(a){var g=f(Math.abs(a));return e&&b._valueChanged(Math.abs(a),g)?"":(""!==g&&(d?g=c+g:g+=c,0>a&&(g="-"+g)),g)}},b.fixed=function(a,c){return"undefined"==typeof a&&(a=3),"undefined"==typeof c&&(c=!0),b.verifyPrecision(a),function(d){var e=d.toFixed(a);return c&&b._valueChanged(d,e)?"":e}},b.general=function(a,c){return"undefined"==typeof a&&(a=3),"undefined"==typeof c&&(c=!0),b.verifyPrecision(a),function(d){if("number"==typeof d){var e=Math.pow(10,a),f=String(Math.round(d*e)/e);return c&&b._valueChanged(d,f)?"":f}return String(d)}},b.identity=function(){return function(a){return String(a)}},b.percentage=function(a,c){"undefined"==typeof a&&(a=0),"undefined"==typeof c&&(c=!0);var d=b.fixed(a);return function(a){var e=d(100*a);return c&&b._valueChanged(100*a,e)?"":(""!==e&&(e+="%"),e)}},b.siSuffix=function(a){return"undefined"==typeof a&&(a=3),b.verifyPrecision(a),function(b){return d3.format("."+a+"s")(b)}},b.time=function(){var a=8,b={};return b[0]={format:".%L",filter:function(a){return 0!==a.getMilliseconds()}},b[1]={format:":%S",filter:function(a){return 0!==a.getSeconds()}},b[2]={format:"%I:%M",filter:function(a){return 0!==a.getMinutes()}},b[3]={format:"%I %p",filter:function(a){return 0!==a.getHours()}},b[4]={format:"%a %d",filter:function(a){return 0!==a.getDay()&&1!==a.getDate()}},b[5]={format:"%b %d",filter:function(a){return 1!==a.getDate()}},b[6]={format:"%b",filter:function(a){return 0!==a.getMonth()}},b[7]={format:"%Y",filter:function(){return!0}},function(c){for(var d=0;a>d;d++)if(b[d].filter(c))return d3.time.format(b[d].format)(c)}},b.relativeDate=function(b,c,d){return"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=a.MILLISECONDS_IN_ONE_DAY),"undefined"==typeof d&&(d=""),function(a){var e=Math.round((a.valueOf()-b)/c);return e.toString()+d}},b.verifyPrecision=function(a){if(0>a||a>20)throw new RangeError("Formatter precision must be between 0 and 20")},b._valueChanged=function(a,b){return a!==parseFloat(b)},b}();a.Formatters=b}(Plottable||(Plottable={}));var Plottable;!function(a){a.version="0.24.0"}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){}return a.CORAL_RED="#fd373e",a.INDIGO="#5177c4",a.ROBINS_EGG_BLUE="#06bdbd",a.FERN="#62bb60",a.BURNING_ORANGE="#ff7939",a.ROYAL_HEATH="#962565",a.CONIFER="#99ce50",a.CERISE_RED="#db2e65",a.BRIGHT_SUN="#ffe43d",a.JACARTA="#2c2b6f",a.PLOTTABLE_COLORS=[a.CORAL_RED,a.INDIGO,a.ROBINS_EGG_BLUE,a.FERN,a.BURNING_ORANGE,a.ROYAL_HEATH,a.CONIFER,a.CERISE_RED,a.BRIGHT_SUN,a.JACARTA],a}();a.Colors=b}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this._plottableID=a.nextID++}return a.nextID=0,a}();a.PlottableObject=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this),this.key2callback=new a.Util.StrictEqualityAssociativeArray,this.listenable=c}return __extends(c,b),c.prototype.registerListener=function(a,b){return this.key2callback.set(a,b),this},c.prototype.broadcast=function(){for(var a=this,b=[],c=0;c=0&&(this._components.splice(b,1),this._invalidateLayout())},b.prototype._addComponent=function(a,b){return"undefined"==typeof b&&(b=!1),null==a||this._components.indexOf(a)>=0?!1:(b?this._components.unshift(a):this._components.push(a),a._parent=this,this._isAnchored&&a._anchor(this.content),this._invalidateLayout(),!0)},b.prototype.components=function(){return this._components.slice()},b.prototype.empty=function(){return 0===this._components.length},b.prototype.detachAll=function(){return this._components.slice().forEach(function(a){return a.detach()}),this},b.prototype.remove=function(){a.prototype.remove.call(this),this._components.slice().forEach(function(a){return a.remove()})},b}(a.Component);a.ComponentContainer=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){"undefined"==typeof b&&(b=[]);var c=this;a.call(this),this.classed("component-group",!0),b.forEach(function(a){return c._addComponent(a)})}return __extends(b,a),b.prototype._requestedSpace=function(a,b){var c=this._components.map(function(c){return c._requestedSpace(a,b)}),d=this.empty();return{width:d?0:d3.max(c,function(a){return a.width}),height:d?0:d3.max(c,function(a){return a.height}),wantsWidth:d?!1:c.map(function(a){return a.wantsWidth}).some(function(a){return a}),wantsHeight:d?!1:c.map(function(a){return a.wantsHeight}).some(function(a){return a})}},b.prototype.merge=function(a){return this._addComponent(a),this},b.prototype._computeLayout=function(b,c,d,e){var f=this;return a.prototype._computeLayout.call(this,b,c,d,e),this._components.forEach(function(a){a._computeLayout(0,0,f.availableWidth,f.availableHeight)}),this},b.prototype._isFixedWidth=function(){return this._components.every(function(a){return a._isFixedWidth()})},b.prototype._isFixedHeight=function(){return this._components.every(function(a){return a._isFixedHeight()})},b}(a.Abstract.ComponentContainer);b.Group=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){"undefined"==typeof a&&(a=[]);var c=this;b.call(this),this.rowPadding=0,this.colPadding=0,this.rows=[],this.rowWeights=[],this.colWeights=[],this.nRows=0,this.nCols=0,this.classed("table",!0),a.forEach(function(a,b){a.forEach(function(a,d){c.addComponent(b,d,a)})})}return __extends(c,b),c.prototype.addComponent=function(a,b,c){if(this._addComponent(c)){this.nRows=Math.max(a+1,this.nRows),this.nCols=Math.max(b+1,this.nCols),this.padTableToSize(this.nRows,this.nCols);var d=this.rows[a][b];if(null!=d)throw new Error("Table.addComponent cannot be called on a cell where a component already exists (for the moment)");this.rows[a][b]=c}return this},c.prototype._removeComponent=function(a){b.prototype._removeComponent.call(this,a);var c,d;a:for(var e=0;e0&&v&&e!==x,C=f>0&&w&&f!==y;if(!B&&!C)break;if(r>5)break}return e=h-d3.sum(u.guaranteedWidths),f=i-d3.sum(u.guaranteedHeights),n=c.calcProportionalSpace(k,e),o=c.calcProportionalSpace(j,f),{colProportionalSpace:n,rowProportionalSpace:o,guaranteedWidths:u.guaranteedWidths,guaranteedHeights:u.guaranteedHeights,wantsWidth:v,wantsHeight:w}},c.prototype.determineGuarantees=function(b,c){var d=a.Util.Methods.createFilledArray(0,this.nCols),e=a.Util.Methods.createFilledArray(0,this.nRows),f=a.Util.Methods.createFilledArray(!1,this.nCols),g=a.Util.Methods.createFilledArray(!1,this.nRows);return this.rows.forEach(function(a,h){a.forEach(function(a,i){var j;j=null!=a?a._requestedSpace(b[i],c[h]):{width:0,height:0,wantsWidth:!1,wantsHeight:!1};var k=Math.min(j.width,b[i]),l=Math.min(j.height,c[h]);d[i]=Math.max(d[i],k),e[h]=Math.max(e[h],l),f[i]=f[i]||j.wantsWidth,g[h]=g[h]||j.wantsHeight})}),{guaranteedWidths:d,guaranteedHeights:e,wantsWidthArr:f,wantsHeightArr:g}},c.prototype._requestedSpace=function(a,b){var c=this.iterateLayout(a,b);return{width:d3.sum(c.guaranteedWidths),height:d3.sum(c.guaranteedHeights),wantsWidth:c.wantsWidth,wantsHeight:c.wantsHeight}},c.prototype._computeLayout=function(c,d,e,f){var g=this;b.prototype._computeLayout.call(this,c,d,e,f);var h=this.iterateLayout(this.availableWidth,this.availableHeight),i=a.Util.Methods.addArrays(h.rowProportionalSpace,h.guaranteedHeights),j=a.Util.Methods.addArrays(h.colProportionalSpace,h.guaranteedWidths),k=0;this.rows.forEach(function(a,b){var c=0;a.forEach(function(a,d){null!=a&&a._computeLayout(c,k,j[d],i[b]),c+=j[d]+g.colPadding}),k+=i[b]+g.rowPadding})},c.prototype.padding=function(a,b){return this.rowPadding=a,this.colPadding=b,this._invalidateLayout(),this},c.prototype.rowWeight=function(a,b){return this.rowWeights[a]=b,this._invalidateLayout(),this},c.prototype.colWeight=function(a,b){return this.colWeights[a]=b,this._invalidateLayout(),this},c.prototype._isFixedWidth=function(){var a=d3.transpose(this.rows);return c.fixedSpace(a,function(a){return null==a||a._isFixedWidth()})},c.prototype._isFixedHeight=function(){return c.fixedSpace(this.rows,function(a){return null==a||a._isFixedHeight()})},c.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(d=0;b>d;d++)void 0===this.colWeights[d]&&(this.colWeights[d]=null)},c.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})},c.calcProportionalSpace=function(b,c){var d=d3.sum(b);return 0===d?a.Util.Methods.createFilledArray(0,b.length):b.map(function(a){return c*a/d})},c.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))},c}(a.Abstract.ComponentContainer);b.Table=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this),this.autoDomainAutomatically=!0,this.broadcaster=new a.Core.Broadcaster(this),this._rendererAttrID2Extent={},this._d3Scale=c}return __extends(c,b),c.prototype._getAllExtents=function(){return d3.values(this._rendererAttrID2Extent)},c.prototype._getExtent=function(){return[]},c.prototype.autoDomain=function(){return this.autoDomainAutomatically=!0,this._setDomain(this._getExtent()),this},c.prototype._autoDomainIfAutomaticMode=function(){this.autoDomainAutomatically&&this.autoDomain() +},c.prototype.scale=function(a){return this._d3Scale(a)},c.prototype.domain=function(a){return null==a?this._getDomain():(this.autoDomainAutomatically=!1,this._setDomain(a),this)},c.prototype._getDomain=function(){return this._d3Scale.domain()},c.prototype._setDomain=function(a){this._d3Scale.domain(a),this.broadcaster.broadcast()},c.prototype.range=function(a){return null==a?this._d3Scale.range():(this._d3Scale.range(a),this)},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c.prototype.updateExtent=function(a,b,c){return this._rendererAttrID2Extent[a+b]=c,this._autoDomainIfAutomaticMode(),this},c.prototype.removeExtent=function(a,b){return delete this._rendererAttrID2Extent[a+b],this._autoDomainIfAutomaticMode(),this},c}(b.PlottableObject);b.Scale=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this),this._dataChanged=!1,this._animate=!1,this._animators={},this._ANIMATION_DURATION=250,this._projectors={},this.animateOnNextRender=!0,this.clipPathEnabled=!0,this.classed("plot",!0);var d;d=null!=c?"function"==typeof c.data?c:d=new a.DataSource(c):new a.DataSource,this.dataSource(d)}return __extends(c,b),c.prototype._anchor=function(a){b.prototype._anchor.call(this,a),this.animateOnNextRender=!0,this._dataChanged=!0,this.updateAllProjectors()},c.prototype.remove=function(){var a=this;b.prototype.remove.call(this),this._dataSource.broadcaster.deregisterListener(this);var c=Object.keys(this._projectors);c.forEach(function(b){var c=a._projectors[b];null!=c.scale&&c.scale.broadcaster.deregisterListener(a)})},c.prototype.dataSource=function(a){var b=this;if(null==a)return this._dataSource;var c=this._dataSource;return null!=c&&this._dataSource.broadcaster.deregisterListener(this),this._dataSource=a,this._dataSource.broadcaster.registerListener(this,function(){return b._onDataSourceUpdate()}),this._onDataSourceUpdate(),this},c.prototype._onDataSourceUpdate=function(){this.updateAllProjectors(),this.animateOnNextRender=!0,this._dataChanged=!0,this._render()},c.prototype.project=function(b,c,d){var e=this;b=b.toLowerCase();var f=this._projectors[b],g=null!=f?f.scale:null;null!=g&&(g.removeExtent(this._plottableID,b),g.broadcaster.deregisterListener(this)),null!=d&&d.broadcaster.registerListener(this,function(){return e._render()});var h=a.Util.Methods._applyAccessor(c,this);return this._projectors[b]={accessor:h,scale:d},this.updateProjector(b),this._render(),this},c.prototype._generateAttrToProjector=function(){var a=this,b={};return d3.keys(this._projectors).forEach(function(c){var d=a._projectors[c],e=d.accessor,f=d.scale,g=null==f?e:function(a,b){return f.scale(e(a,b))};b[c]=g}),b},c.prototype._doRender=function(){this._isAnchored&&(this._paint(),this._dataChanged=!1,this.animateOnNextRender=!1)},c.prototype._paint=function(){},c.prototype._setup=function(){b.prototype._setup.call(this),this.renderArea=this.content.append("g").classed("render-area",!0)},c.prototype.animate=function(a){return this._animate=a,this},c.prototype.detach=function(){return b.prototype.detach.call(this),this.updateAllProjectors(),this},c.prototype.updateAllProjectors=function(){var a=this;return d3.keys(this._projectors).forEach(function(b){return a.updateProjector(b)}),this},c.prototype.updateProjector=function(a){var b=this._projectors[a];if(null!=b.scale){var c=this.dataSource()._getExtent(b.accessor);0!==c.length&&this._isAnchored?b.scale.updateExtent(this._plottableID,a,c):b.scale.removeExtent(this._plottableID,a)}return this},c.prototype._applyAnimatedAttributes=function(a,b,c){return this._animate&&this.animateOnNextRender&&null!=this._animators[b]?this._animators[b].animate(a,c,this):a.attr(c)},c.prototype.animator=function(a,b){return void 0===b?this._animators[a]:(this._animators[a]=b,this)},c}(b.Component);b.Plot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var Plottable;!function(a){!function(b){!function(b){!function(c){var d=function(){function a(){}return a.prototype.render=function(){b.flush()},a}();c.Immediate=d;var e=function(){function c(){}return c.prototype.render=function(){a.Util.DOM.requestAnimationFramePolyfill(b.flush)},c}();c.AnimationFrame=e;var f=function(){function c(){this._timeoutMsec=a.Util.DOM.POLYFILL_TIMEOUT_MSEC}return c.prototype.render=function(){setTimeout(b.flush,this._timeoutMsec)},c}();c.Timeout=f}(b.RenderPolicy||(b.RenderPolicy={}));b.RenderPolicy}(b.RenderController||(b.RenderController={}));b.RenderController}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(b){function c(a){b._renderPolicy=a}function d(a){h[a._plottableID]=a,f()}function e(a){i[a._plottableID]=a,h[a._plottableID]=a,f()}function f(){j||(j=!0,b._renderPolicy.render())}function g(){if(j){var b=d3.values(i);b.forEach(function(a){return a._computeLayout()});var c=d3.values(h);c.forEach(function(a){return a._render()});var d={};Object.keys(h).forEach(function(a){try{h[a]._doRender()}catch(b){setTimeout(function(){throw b},0),d[a]=h[a]}}),i={},h=d,j=!1}a.ResizeBroadcaster.clearResizing()}var h={},i={},j=!1;b._renderPolicy=new b.RenderPolicy.AnimationFrame,b.setRenderPolicy=c,b.registerToRender=d,b.registerToComputeLayout=e,b.flush=g}(a.RenderController||(a.RenderController={}));a.RenderController}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(b){function c(){void 0===i&&(i=new a.Broadcaster(b),window.addEventListener("resize",d))}function d(){j=!0,i.broadcast()}function e(){return j}function f(){j=!1}function g(a){c(),i.registerListener(a._plottableID,function(){return a._invalidateLayout()})}function h(a){i&&i.deregisterListener(a._plottableID)}var i,j=!1;b.resizing=e,b.clearResizing=f,b.register=g,b.deregister=h}(a.ResizeBroadcaster||(a.ResizeBroadcaster={}));a.ResizeBroadcaster}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(){}(Plottable||(Plottable={}));var Plottable;!function(a){var b=function(){function a(a){this.doNice=!1,this.padProportion=0,this.paddingExceptions=d3.map(),this.unregisteredPaddingExceptions=d3.set(),this.includedValues=d3.map(),this.unregisteredIncludedValues=d3.map(),this.combineExtents=a}return a.prototype.computeDomain=function(a,b){var c;return c=null!=this.combineExtents?this.combineExtents(a):0===a.length?b._defaultExtent():[d3.min(a,function(a){return a[0]}),d3.max(a,function(a){return a[1]})],c=this.includeDomain(c),c=this.padDomain(b,c),c=this.niceDomain(b,c)},a.prototype.pad=function(a){return"undefined"==typeof a&&(a=.05),this.padProportion=a,this},a.prototype.addPaddingException=function(a,b){return null!=b?this.paddingExceptions.set(b,a):this.unregisteredPaddingExceptions.add(a),this},a.prototype.removePaddingException=function(a){return"string"==typeof a?this.paddingExceptions.remove(a):this.unregisteredPaddingExceptions.remove(a),this},a.prototype.addIncludedValue=function(a,b){return null!=b?this.includedValues.set(b,a):this.unregisteredIncludedValues.set(a,a),this},a.prototype.removeIncludedValue=function(a){return"string"==typeof a?this.includedValues.remove(a):this.unregisteredIncludedValues.remove(a),this},a.prototype.nice=function(a){return this.doNice=!0,this.niceCount=a,this},a.defaultCombineExtents=function(a){return 0===a.length?[0,1]:[d3.min(a,function(a){return a[0]}),d3.max(a,function(a){return a[1]})]},a.prototype.padDomain=function(b,c){var d=c[0],e=c[1];if(d===e&&this.padProportion>0){var f=d.valueOf();return d instanceof Date?[f-a.ONE_DAY,f+a.ONE_DAY]:[f-a.PADDING_FOR_IDENTICAL_DOMAIN,f+a.PADDING_FOR_IDENTICAL_DOMAIN]}if(b.domain()[0]===b.domain()[1])return c;var g=this.padProportion/2,h=b.invert(b.scale(d)-(b.scale(e)-b.scale(d))*g),i=b.invert(b.scale(e)+(b.scale(e)-b.scale(d))*g),j=this.paddingExceptions.values().concat(this.unregisteredPaddingExceptions.values()),k=d3.set(j);return k.has(d)&&(h=d),k.has(e)&&(i=e),[h,i]},a.prototype.niceDomain=function(a,b){return this.doNice?a._niceDomain(b,this.niceCount):b},a.prototype.includeDomain=function(a){var b=this.includedValues.values().concat(this.unregisteredIncludedValues.values());return b.reduce(function(a,b){return[Math.min(a[0],b),Math.max(a[1],b)]},a)},a.PADDING_FOR_IDENTICAL_DOMAIN=1,a.ONE_DAY=864e5,a}();a.Domainer=b}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){b.call(this,c),this._lastRequestedTickCount=10,this._PADDING_FOR_IDENTICAL_DOMAIN=1,this._userSetDomainer=!1,this._domainer=new a.Domainer}return __extends(c,b),c.prototype._getExtent=function(){return this._domainer.computeDomain(this._getAllExtents(),this)},c.prototype.invert=function(a){return this._d3Scale.invert(a)},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c.prototype.domain=function(a){return b.prototype.domain.call(this,a)},c.prototype._setDomain=function(c){var d=function(a){return a!==a||1/0===a||a===-1/0};return d(c[0])||d(c[1])?void a.Util.Methods.warn("Warning: QuantitativeScales cannot take NaN or Infinity as a domain value. Ignoring."):void b.prototype._setDomain.call(this,c)},c.prototype.interpolate=function(a){return null==a?this._d3Scale.interpolate():(this._d3Scale.interpolate(a),this)},c.prototype.rangeRound=function(a){return this._d3Scale.rangeRound(a),this},c.prototype.clamp=function(a){return null==a?this._d3Scale.clamp():(this._d3Scale.clamp(a),this)},c.prototype.ticks=function(a){return null!=a&&(this._lastRequestedTickCount=a),this._d3Scale.ticks(this._lastRequestedTickCount)},c.prototype.tickFormat=function(a,b){return this._d3Scale.tickFormat(a,b)},c.prototype._niceDomain=function(a,b){return this._d3Scale.copy().domain(a).nice(b).domain()},c.prototype.domainer=function(a){return null==a?this._domainer:(this._domainer=a,this._userSetDomainer=!0,this._autoDomainIfAutomaticMode(),this)},c.prototype._defaultExtent=function(){return[0,1]},c}(b.Scale);b.QuantitativeScale=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,null==b?d3.scale.linear():b)}return __extends(b,a),b.prototype.copy=function(){return new b(this._d3Scale.copy())},b}(a.Abstract.QuantitativeScale);b.Linear=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(d){b.call(this,null==d?d3.scale.log():d),c.warned||(c.warned=!0,a.Util.Methods.warn("Plottable.Scale.Log is deprecated. If possible, use Plottable.Scale.ModifiedLog instead."))}return __extends(c,b),c.prototype.copy=function(){return new c(this._d3Scale.copy())},c.prototype._defaultExtent=function(){return[1,10]},c.warned=!1,c}(a.Abstract.QuantitativeScale);b.Log=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){if("undefined"==typeof a&&(a=10),b.call(this,d3.scale.linear()),this._showIntermediateTicks=!1,this.base=a,this.pivot=this.base,this.untransformedDomain=this._defaultExtent(),this._lastRequestedTickCount=10,1>=a)throw new Error("ModifiedLogScale: The base must be > 1")}return __extends(c,b),c.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=d&&e>=a}),m=j.concat(l).concat(k);return m.length<=1&&(m=d3.scale.linear().domain([d,e]).ticks(this._lastRequestedTickCount)),m},c.prototype.logTicks=function(b,c){var d=this,e=this.howManyTicks(b,c);if(0===e)return[];var f=Math.floor(Math.log(b)/Math.log(this.base)),g=Math.ceil(Math.log(c)/Math.log(this.base)),h=d3.range(g,f,-Math.ceil((g-f)/e)),i=this._showIntermediateTicks?Math.floor(e/h.length):1,j=d3.range(this.base,1,-(this.base-1)/i).map(Math.floor),k=a.Util.Methods.uniqNumbers(j),l=h.map(function(a){return k.map(function(b){return Math.pow(d.base,a-1)*b})}),m=a.Util.Methods.flatten(l),n=m.filter(function(a){return a>=b&&c>=a}),o=n.sort(function(a,b){return a-b});return o},c.prototype.howManyTicks=function(a,b){var c=this.adjustedLog(d3.min(this.untransformedDomain)),d=this.adjustedLog(d3.max(this.untransformedDomain)),e=this.adjustedLog(a),f=this.adjustedLog(b),g=(f-e)/(d-c),h=Math.ceil(g*this._lastRequestedTickCount);return h},c.prototype.copy=function(){return new c(this.base)},c.prototype._niceDomain=function(a){return a},c.prototype.showIntermediateTicks=function(a){return null==a?this._showIntermediateTicks:void(this._showIntermediateTicks=a)},c}(a.Abstract.QuantitativeScale);b.ModifiedLog=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){if(b.call(this,null==a?d3.scale.ordinal():a),this._range=[0,1],this._rangeType="bands",this._innerPadding=.3,this._outerPadding=.5,this._innerPadding>this._outerPadding)throw new Error("outerPadding must be >= innerPadding so cat axis bands work out reasonably")}return __extends(c,b),c.prototype._getExtent=function(){var b=this._getAllExtents();return a.Util.Methods.uniq(a.Util.Methods.flatten(b))},c.prototype.domain=function(a){return b.prototype.domain.call(this,a)},c.prototype._setDomain=function(a){b.prototype._setDomain.call(this,a),this.range(this.range())},c.prototype.range=function(a){return null==a?this._range:(this._range=a,"points"===this._rangeType?this._d3Scale.rangePoints(a,2*this._outerPadding):"bands"===this._rangeType&&this._d3Scale.rangeBands(a,this._innerPadding,this._outerPadding),this)},c.prototype.rangeBand=function(){return this._d3Scale.rangeBand()},c.prototype.innerPadding=function(){var a=this.domain();if(a.length<2)return 0;var b=Math.abs(this.scale(a[1])-this.scale(a[0]));return b-this.rangeBand()},c.prototype.fullBandStartAndWidth=function(a){var b=this.scale(a)-this.innerPadding()/2,c=this.rangeBand()+this.innerPadding();return[b,c]},c.prototype.rangeType=function(a,b,c){if(null==a)return this._rangeType;if("points"!==a&&"bands"!==a)throw new Error("Unsupported range type: "+a);return this._rangeType=a,null!=b&&(this._outerPadding=b),null!=c&&(this._innerPadding=c),this.broadcaster.broadcast(),this},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c}(a.Abstract.Scale);b.Ordinal=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c){var d;switch(c){case null:case void 0:d=d3.scale.ordinal().range(a.Core.Colors.PLOTTABLE_COLORS);break;case"Category10":case"category10":case"10":d=d3.scale.category10();break;case"Category20":case"category20":case"20":d=d3.scale.category20();break;case"Category20b":case"category20b":case"20b":d=d3.scale.category20b();break;case"Category20c":case"category20c":case"20c":d=d3.scale.category20c();break;default:throw new Error("Unsupported ColorScale type")}b.call(this,d)}return __extends(c,b),c.prototype._getExtent=function(){var b=this._getAllExtents(),c=[];return b.forEach(function(a){c=c.concat(a)}),a.Util.Methods.uniq(c)},c}(a.Abstract.Scale);b.Color=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,null==b?d3.time.scale():b),this._PADDING_FOR_IDENTICAL_DOMAIN=864e5}return __extends(b,a),b.prototype.tickInterval=function(a,b){var c=d3.time.scale();return c.domain(this.domain()),c.range(this.range()),c.ticks(a.range,b)},b.prototype.domain=function(b){return null==b?a.prototype.domain.call(this):("string"==typeof b[0]&&(b=b.map(function(a){return new Date(a)})),a.prototype.domain.call(this,b))},b.prototype.copy=function(){return new b(this._d3Scale.copy())},b}(a.Abstract.QuantitativeScale);b.Time=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(c,d){"undefined"==typeof c&&(c="reds"),"undefined"==typeof d&&(d="linear"),this._colorRange=this._resolveColorValues(c),this._scaleType=d,a.call(this,b.getD3InterpolatedScale(this._colorRange,this._scaleType))}return __extends(b,a),b.getD3InterpolatedScale=function(a,c){var d;switch(c){case"linear":d=d3.scale.linear();break;case"log":d=d3.scale.log();break;case"sqrt":d=d3.scale.sqrt();break;case"pow":d=d3.scale.pow()}if(null==d)throw new Error("unknown Quantitative scale type "+c);return d.range([0,1]).interpolate(b.interpolateColors(a))},b.interpolateColors=function(a){if(a.length<2)throw new Error("Color scale arrays must have at least two elements.");return function(){return function(b){b=Math.max(0,Math.min(1,b));var c=b*(a.length-1),d=Math.floor(c),e=Math.ceil(c),f=c-d;return d3.interpolateLab(a[d],a[e])(f)}}},b.prototype.colorRange=function(a){return null==a?this._colorRange:(this._colorRange=this._resolveColorValues(a),this._resetScale(),this)},b.prototype.scaleType=function(a){return null==a?this._scaleType:(this._scaleType=a,this._resetScale(),this)},b.prototype._resetScale=function(){this._d3Scale=b.getD3InterpolatedScale(this._colorRange,this._scaleType),this._autoDomainIfAutomaticMode(),this.broadcaster.broadcast()},b.prototype._resolveColorValues=function(a){return a instanceof Array?a:null!=b.COLOR_SCALES[a]?b.COLOR_SCALES[a]:b.COLOR_SCALES.reds},b.prototype.autoDomain=function(){var a=this._getAllExtents();return a.length>0&&this._setDomain([d3.min(a,function(a){return a[0]}),d3.max(a,function(a){return a[1]})]),this},b.COLOR_SCALES={reds:["#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"],blues:["#FFFFFF","#CCFFFF","#A5FFFD","#85F7FB","#6ED3EF","#55A7E0","#417FD0","#2545D3","#0B02E1"],posneg:["#0B02E1","#2545D3","#417FD0","#55A7E0","#6ED3EF","#85F7FB","#A5FFFD","#CCFFFF","#FFFFFF","#FFF6E1","#FEF4C0","#FED976","#FEB24C","#FD8D3C","#FC4E2A","#E31A1C","#B10026"]},b}(a.Abstract.QuantitativeScale);b.InterpolatedColor=c}(a.Scale||(a.Scale={}));a.Scale}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(a){var b=this;if(this.rescaleInProgress=!1,null==a)throw new Error("ScaleDomainCoordinator requires scales to coordinate");this.scales=a,this.scales.forEach(function(a){return a.broadcaster.registerListener(b,function(a){return b.rescale(a)})})}return a.prototype.rescale=function(a){if(!this.rescaleInProgress){this.rescaleInProgress=!0;var b=a.domain();this.scales.forEach(function(a){return a.domain(b)}),this.rescaleInProgress=!1}},a}();a.ScaleDomainCoordinator=b}(a.Util||(a.Util={}));a.Util}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(c){function d(b,d,e){"undefined"==typeof e&&(e=a.Formatters.identity());var f=this;if(c.call(this),this._width="auto",this._height="auto",this._endTickLength=5,this._tickLength=5,this._tickLabelPadding=10,this._gutter=15,this._showEndTickLabels=!1,null==b||null==d)throw new Error("Axis requires a scale and orientation");this._scale=b,this.orient(d),this.classed("axis",!0),this._isHorizontal()?this.classed("x-axis",!0):this.classed("y-axis",!0),this.formatter(e),this._scale.broadcaster.registerListener(this,function(){return f.rescale()})}return __extends(d,c),d.prototype.remove=function(){c.prototype.remove.call(this),this._scale.broadcaster.deregisterListener(this)},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(a,b){var c=this._width,d=this._height;return this._isHorizontal()?("auto"===this._height&&(null==this._computedHeight&&this._computeHeight(),d=this._computedHeight+this._gutter),c=0):("auto"===this._width&&(null==this._computedWidth&&this._computeWidth(),c=this._computedWidth+this._gutter),d=0),{width:c,height:d,wantsWidth:!this._isHorizontal()&&c>a,wantsHeight:this._isHorizontal()&&d>b}},d.prototype._isFixedHeight=function(){return this._isHorizontal()},d.prototype._isFixedWidth=function(){return!this._isHorizontal()},d.prototype._computeLayout=function(a,b,d,e){c.prototype._computeLayout.call(this,a,b,d,e),this._scale.range(this._isHorizontal()?[0,this.availableWidth]:[this.availableHeight,0])},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._doRender=function(){var a=this._getTickValues(),b=this._tickMarkContainer.selectAll("."+d.TICK_MARK_CLASS).data(a);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())},d.prototype._generateBaselineAttrHash=function(){var a={x1:0,y1:0,x2:0,y2:0};switch(this._orientation){case"bottom":a.x2=this.availableWidth;break;case"top":a.x2=this.availableWidth,a.y1=this.availableHeight,a.y2=this.availableHeight;break;case"left":a.x1=this.availableWidth,a.x2=this.availableWidth,a.y2=this.availableHeight;break;case"right":a.y2=this.availableHeight}return a},d.prototype._generateTickMarkAttrHash=function(a){var b=this;"undefined"==typeof 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._tickLength;switch(this._orientation){case"bottom":c.y2=e;break;case"top":c.y1=this.availableHeight,c.y2=this.availableHeight-e;break;case"left":c.x1=this.availableWidth,c.x2=this.availableWidth-e;break;case"right":c.x2=e}return c},d.prototype.rescale=function(){return null!=this.element?this._render():null},d.prototype._invalidateLayout=function(){this._computedWidth=null,this._computedHeight=null,c.prototype._invalidateLayout.call(this)},d.prototype.width=function(a){if(null==a)return this.availableWidth;if(this._isHorizontal())throw new Error("width cannot be set on a horizontal Axis");if("auto"!==a&&0>a)throw new Error("invalid value for width");return this._width=a,this._invalidateLayout(),this},d.prototype.height=function(a){if(null==a)return this.availableHeight;if(!this._isHorizontal())throw new Error("height cannot be set on a vertical Axis");if("auto"!==a&&0>a)throw new Error("invalid value for height");return this._height=a,this._invalidateLayout(),this},d.prototype.formatter=function(a){return void 0===a?this._formatter:(this._formatter=a,this._invalidateLayout(),this)},d.prototype.tickLength=function(a){if(null==a)return this._tickLength;if(0>a)throw new Error("tick length must be positive");return this._tickLength=a,this._invalidateLayout(),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._invalidateLayout(),this},d.prototype._maxLabelTickLength=function(){return this.showEndTickLabels()?Math.max(this.tickLength(),this.endTickLength()):this.tickLength()},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._invalidateLayout(),this},d.prototype.gutter=function(a){if(null==a)return this._gutter;if(0>a)throw new Error("gutter size must be positive");return this._gutter=a,this._invalidateLayout(),this},d.prototype.orient=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._invalidateLayout(),this},d.prototype.showEndTickLabels=function(a){return null==a?this._showEndTickLabels:(this._showEndTickLabels=a,this._render(),this)},d.prototype._hideEndTickLabels=function(){var a=this,c=this.element.select(".bounding-box")[0][0].getBoundingClientRect(),d=function(b){return Math.floor(c.left)<=Math.ceil(b.left)&&Math.floor(c.top)<=Math.ceil(b.top)&&Math.floor(b.right)<=Math.ceil(c.left+a.availableWidth)&&Math.floor(b.bottom)<=Math.ceil(c.top+a.availableHeight)},e=this._tickLabelContainer.selectAll("."+b.Axis.TICK_LABEL_CLASS);if(0!==e[0].length){var f=e[0][0];d(f.getBoundingClientRect())||d3.select(f).style("visibility","hidden");var g=e[0][e[0].length-1];d(g.getBoundingClientRect())||d3.select(g).style("visibility","hidden")}},d.prototype._hideOverlappingTickLabels=function(){var c,d=this._tickLabelContainer.selectAll("."+b.Axis.TICK_LABEL_CLASS).filter(function(){return"visible"===d3.select(this).style("visibility")});d.each(function(){var b=this.getBoundingClientRect(),d=d3.select(this);null!=c&&a.Util.DOM.boxesOverlap(b,c)?d.style("visibility","hidden"):(c=b,d.style("visibility","visible"))})},d.END_TICK_MARK_CLASS="end-tick-mark",d.TICK_MARK_CLASS="tick-mark",d.TICK_LABEL_CLASS="tick-label",d}(b.Component);b.Axis=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,d){if(d=d.toLowerCase(),"top"!==d&&"bottom"!==d)throw new Error("unsupported orientation: "+d);b.call(this,a,d),this.classed("time-axis",!0),this.previousSpan=0,this.previousIndex=c.minorIntervals.length-1,this.tickLabelPadding(5)}return __extends(c,b),c.prototype._computeHeight=function(){if(null!==this._computedHeight)return this._computedHeight;var a=this._measureTextHeight(this._majorTickLabels)+this._measureTextHeight(this._minorTickLabels);return this.tickLength(a),this.endTickLength(a),this._computedHeight=this._maxLabelTickLength()+2*this.tickLabelPadding(),this._computedHeight},c.prototype.calculateWorstWidth=function(b,c){var d=new Date(9999,8,29,12,59,9999);return a.Util.Text.getTextWidth(b,d3.time.format(c)(d))},c.prototype.getIntervalLength=function(a){var b=this._scale.domain()[0],c=Math.abs(this._scale.scale(a.timeUnit.offset(b,a.step))-this._scale.scale(b));return c},c.prototype.isEnoughSpace=function(a,b){var c=this.calculateWorstWidth(a,b.formatString)+2*this.tickLabelPadding(),d=Math.min(this.getIntervalLength(b),this.availableWidth);return d>c},c.prototype._setup=function(){b.prototype._setup.call(this),this._majorTickLabels=this.content.append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),this._minorTickLabels=this.content.append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0)},c.prototype.getTickLevel=function(){var b=c.minorIntervals.length-1,d=Math.abs(this._scale.domain()[1]-this._scale.domain()[0]);d<=this.previousSpan+1&&(b=this.previousIndex);for(var e=b;e>=0;){if(!this.isEnoughSpace(this._minorTickLabels,c.minorIntervals[e])||!this.isEnoughSpace(this._majorTickLabels,c.majorIntervals[e])){e++;break}e--}return e=Math.min(e,c.minorIntervals.length-1),0>e&&(e=0,a.Util.Methods.warn("could not find suitable interval to display labels")),this.previousIndex=Math.max(0,e-1),this.previousSpan=d,e},c.prototype._getTickIntervalValues=function(a){return this._scale.tickInterval(a.timeUnit,a.step)},c.prototype._getTickValues=function(){var a=this.getTickLevel(),b=this._getTickIntervalValues(c.minorIntervals[a]),d=this._getTickIntervalValues(c.majorIntervals[a]);return b.concat(d)},c.prototype._measureTextHeight=function(b){var c=b.append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),d=a.Util.Text.getTextHeight(c.append("text"));return c.remove(),d},c.prototype.renderTickLabels=function(b,c,d){var e=this;b.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).remove();var f=this._scale.tickInterval(c.timeUnit,c.step);f.splice(0,0,this._scale.domain()[0]),f.push(this._scale.domain()[1]);var g=1===c.step,h=[];g?f.map(function(a,b){b+1>=f.length||h.push(new Date((f[b+1].valueOf()-f[b].valueOf())/2+f[b].valueOf()))}):h=f,h=h.filter(function(a){return e.canFitLabelFilter(b,a,d3.time.format(c.formatString)(a),g)});var i=b.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).data(h,function(a){return a.valueOf()}),j=i.enter().append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0);j.append("text");var k=g?0:this.tickLabelPadding(),l="bottom"===this._orientation?this._maxLabelTickLength()/2*d:this.availableHeight-this._maxLabelTickLength()/2*d+2*this.tickLabelPadding(),m=i.selectAll("text");m.size()>0&&a.Util.DOM.translate(m,k,l),i.exit().remove(),i.attr("transform",function(a){return"translate("+e._scale.scale(a)+",0)"});var n=g?"middle":"start";i.selectAll("text").text(function(a){return d3.time.format(c.formatString)(a)}).style("text-anchor",n)},c.prototype.canFitLabelFilter=function(b,c,d,e){var f,g,h=a.Util.Text.getTextWidth(b,d)+this.tickLabelPadding();return e?(f=this._scale.scale(c)+h/2,g=this._scale.scale(c)-h/2):(f=this._scale.scale(c)+h,g=this._scale.scale(c)),f0},c.prototype.adjustTickLength=function(b,c){var d=this._getTickIntervalValues(c),e=this._tickMarkContainer.selectAll("."+a.Abstract.Axis.TICK_MARK_CLASS).filter(function(a){return d.map(function(a){return a.valueOf() +}).indexOf(a.valueOf())>=0});"top"===this._orientation&&(b=this.availableHeight-b),e.attr("y2",b)},c.prototype.generateLabellessTicks=function(b){if(!(0>b)){var d=this._getTickIntervalValues(c.minorIntervals[b]),e=this._getTickValues().concat(d),f=this._tickMarkContainer.selectAll("."+a.Abstract.Axis.TICK_MARK_CLASS).data(e);f.enter().append("line").classed(a.Abstract.Axis.TICK_MARK_CLASS,!0),f.attr(this._generateTickMarkAttrHash()),f.exit().remove(),this.adjustTickLength(this.tickLabelPadding(),c.minorIntervals[b])}},c.prototype._doRender=function(){b.prototype._doRender.call(this);var a=this.getTickLevel();this.renderTickLabels(this._minorTickLabels,c.minorIntervals[a],1),this.renderTickLabels(this._majorTickLabels,c.majorIntervals[a],2);var d=this._scale.domain(),e=this._scale.scale(d[1])-this._scale.scale(d[0]);1.5*this.getIntervalLength(c.minorIntervals[a])>=e&&this.generateLabellessTicks(a-1),this.adjustTickLength(this._maxLabelTickLength()/2,c.minorIntervals[a]),this.adjustTickLength(this._maxLabelTickLength(),c.majorIntervals[a])},c.minorIntervals=[{timeUnit:d3.time.second,step:1,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:5,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:10,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:15,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:30,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.minute,step:1,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:5,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:10,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:15,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:30,formatString:"%I:%M %p"},{timeUnit:d3.time.hour,step:1,formatString:"%I %p"},{timeUnit:d3.time.hour,step:3,formatString:"%I %p"},{timeUnit:d3.time.hour,step:6,formatString:"%I %p"},{timeUnit:d3.time.hour,step:12,formatString:"%I %p"},{timeUnit:d3.time.day,step:1,formatString:"%a %e"},{timeUnit:d3.time.day,step:1,formatString:"%e"},{timeUnit:d3.time.month,step:1,formatString:"%B"},{timeUnit:d3.time.month,step:1,formatString:"%b"},{timeUnit:d3.time.month,step:3,formatString:"%B"},{timeUnit:d3.time.month,step:6,formatString:"%B"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%y"},{timeUnit:d3.time.year,step:5,formatString:"%Y"},{timeUnit:d3.time.year,step:25,formatString:"%Y"},{timeUnit:d3.time.year,step:50,formatString:"%Y"},{timeUnit:d3.time.year,step:100,formatString:"%Y"},{timeUnit:d3.time.year,step:200,formatString:"%Y"},{timeUnit:d3.time.year,step:500,formatString:"%Y"},{timeUnit:d3.time.year,step:1e3,formatString:"%Y"}],c.majorIntervals=[{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""}],c}(a.Abstract.Axis);b.Time=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){"undefined"==typeof e&&(e=a.Formatters.general(3,!1)),b.call(this,c,d,e),this.tickLabelPositioning="center",this.showFirstTickLabel=!1,this.showLastTickLabel=!1}return __extends(c,b),c.prototype._computeWidth=function(){var b=this,c=this._getTickValues(),d=this._tickLabelContainer.append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),e=a.Util.Text.getTextMeasure(d),f=c.map(function(a){var c=b._formatter(a);return e(c).width});d.remove();var g=d3.max(f);return this._computedWidth="center"===this.tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+g:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+g),this._computedWidth},c.prototype._computeHeight=function(){var b=this._tickLabelContainer.append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),c=a.Util.Text.getTextMeasure(b),d=c("test").height;return b.remove(),this._computedHeight="center"===this.tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+d:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+d),this._computedHeight},c.prototype._getTickValues=function(){return this._scale.ticks()},c.prototype._doRender=function(){b.prototype._doRender.call(this);var c={x:0,y:0,dx:"0em",dy:"0.3em"},d=this._maxLabelTickLength(),e=this.tickLabelPadding(),f="middle",g=0,h=0,i=0,j=0;if(this._isHorizontal())switch(this.tickLabelPositioning){case"left":f="end",g=-e,j=e;break;case"center":j=d+e;break;case"right":f="start",g=e,j=e}else switch(this.tickLabelPositioning){case"top":c.dy="-0.3em",i=e,h=-e;break;case"center":i=d+e;break;case"bottom":c.dy="1em",i=e,h=e}var k=this._generateTickMarkAttrHash();switch(this._orientation){case"bottom":c.x=k.x1,c.dy="0.95em",h=k.y1+j;break;case"top":c.x=k.x1,c.dy="-.25em",h=k.y1-j;break;case"left":f="end",g=k.x1-i,c.y=k.y1;break;case"right":f="start",g=k.x1+i,c.y=k.y1}var l=this._getTickValues(),m=this._tickLabelContainer.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).data(l);m.enter().append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),m.exit().remove(),m.style("text-anchor",f).style("visibility","visible").attr(c).text(this._formatter);var n="translate("+g+", "+h+")";this._tickLabelContainer.attr("transform",n),this.showEndTickLabels()||this._hideEndTickLabels(),this._hideOverlappingTickLabels()},c.prototype.tickLabelPosition=function(a){if(null==a)return this.tickLabelPositioning;var b=a.toLowerCase();if(this._isHorizontal()){if("left"!==b&&"center"!==b&&"right"!==b)throw new Error(b+" is not a valid tick label position for a horizontal NumericAxis")}else if("top"!==b&&"center"!==b&&"bottom"!==b)throw new Error(b+" is not a valid tick label position for a vertical NumericAxis");return this.tickLabelPositioning=b,this._invalidateLayout(),this},c.prototype.showEndTickLabel=function(a,b){if(this._isHorizontal()&&"left"===a||!this._isHorizontal()&&"bottom"===a)return void 0===b?this.showFirstTickLabel:(this.showFirstTickLabel=b,this._render(),this);if(this._isHorizontal()&&"right"===a||!this._isHorizontal()&&"top"===a)return void 0===b?this.showLastTickLabel:(this.showLastTickLabel=b,this._render(),this);throw new Error("Attempt to show "+a+" tick label on a "+(this._isHorizontal()?"horizontal":"vertical")+" axis")},c}(a.Abstract.Axis);b.Numeric=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){"undefined"==typeof d&&(d="bottom"),"undefined"==typeof e&&(e=a.Formatters.identity());var f=this;if(b.call(this,c,d,e),this.classed("category-axis",!0),"bands"!==c.rangeType())throw new Error("Only rangeBands category axes are implemented");this._scale.broadcaster.registerListener(this,function(){return f._invalidateLayout()})}return __extends(c,b),c.prototype._setup=function(){b.prototype._setup.call(this),this.measurer=new a.Util.Text.CachingCharacterMeasurer(this._tickLabelContainer)},c.prototype._requestedSpace=function(a,b){var c=this._isHorizontal()?0:this._maxLabelTickLength()+this.tickLabelPadding(),d=this._isHorizontal()?this._maxLabelTickLength()+this.tickLabelPadding():0;if(0===this._scale.domain().length)return{width:0,height:0,wantsWidth:!1,wantsHeight:!1};var e=this._scale.copy();e.range(this._isHorizontal()?[0,a]:[b,0]);var f=this.measureTicks(a,b,e,this._scale.domain());return{width:f.usedWidth+c,height:f.usedHeight+d,wantsWidth:!f.textFits,wantsHeight:!f.textFits}},c.prototype._getTickValues=function(){return this._scale.domain()},c.prototype.measureTicks=function(b,c,d,e){var f="string"!=typeof e[0],g=this,h=[],i=function(a){return g.measurer.measure(a)},j=f?function(a){return e.each(a)}:function(a){return e.forEach(a)};j(function(e){var j,k=d.fullBandStartAndWidth(e)[1],l=g._isHorizontal()?k:b-g._maxLabelTickLength()-g.tickLabelPadding(),m=g._isHorizontal()?c-g._maxLabelTickLength()-g.tickLabelPadding():k,n=g._formatter;if(f){var o=d3.select(this),p={left:"right",right:"left",top:"center",bottom:"center"},q={left:"center",right:"center",top:"bottom",bottom:"top"};j=a.Util.Text.writeText(n(e),l,m,i,!0,{g:o,xAlign:p[g._orientation],yAlign:q[g._orientation]})}else j=a.Util.Text.writeText(n(e),l,m,i,!0);h.push(j)});var k=this._isHorizontal()?d3.sum:d3.max,l=this._isHorizontal()?d3.max:d3.sum;return{textFits:h.every(function(a){return a.textFits}),usedWidth:k(h,function(a){return a.usedWidth}),usedHeight:l(h,function(a){return a.usedHeight})}},c.prototype._doRender=function(){var c=this;b.prototype._doRender.call(this);var d=this._tickLabelContainer.selectAll("."+a.Abstract.Axis.TICK_LABEL_CLASS).data(this._scale.domain(),function(a){return a}),e=function(a){var b=c._scale.fullBandStartAndWidth(a),d=b[0],e=c._isHorizontal()?d:0,f=c._isHorizontal()?0:d;return"translate("+e+","+f+")"};d.enter().append("g").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0),d.exit().remove(),d.attr("transform",e),d.text(""),this.measureTicks(this.availableWidth,this.availableHeight,this._scale,d);var f=this._isHorizontal()?[this._scale.rangeBand()/2,0]:[0,this._scale.rangeBand()/2],g="right"===this._orientation?this._maxLabelTickLength()+this.tickLabelPadding():0,h="bottom"===this._orientation?this._maxLabelTickLength()+this.tickLabelPadding():0;a.Util.DOM.translate(this._tickLabelContainer,g,h),a.Util.DOM.translate(this._tickMarkContainer,f[0],f[1])},c.prototype._computeLayout=function(a,c,d,e){return this.measurer.clear(),b.prototype._computeLayout.call(this,a,c,d,e)},c}(a.Abstract.Axis);b.Category=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,c){if("undefined"==typeof a&&(a=""),"undefined"==typeof c&&(c="horizontal"),b.call(this),this.classed("label",!0),this.text(a),c=c.toLowerCase(),"vertical-left"===c&&(c="left"),"vertical-right"===c&&(c="right"),"horizontal"!==c&&"left"!==c&&"right"!==c)throw new Error(c+" is not a valid orientation for LabelComponent");this.orientation=c,this.xAlign("center").yAlign("center"),this._fixedHeightFlag=!0,this._fixedWidthFlag=!0}return __extends(c,b),c.prototype.xAlign=function(a){var c=a.toLowerCase();return b.prototype.xAlign.call(this,c),this.xAlignment=c,this},c.prototype.yAlign=function(a){var c=a.toLowerCase();return b.prototype.yAlign.call(this,c),this.yAlignment=c,this},c.prototype._requestedSpace=function(a,b){var c=this.measurer(this._text),d="horizontal"===this.orientation?c.width:c.height,e="horizontal"===this.orientation?c.height:c.width;return{width:d,height:e,wantsWidth:d>a,wantsHeight:e>b}},c.prototype._setup=function(){b.prototype._setup.call(this),this.textContainer=this.content.append("g"),this.measurer=a.Util.Text.getTextMeasure(this.textContainer),this.text(this._text)},c.prototype.text=function(a){return void 0===a?this._text:(this._text=a,this._invalidateLayout(),this)},c.prototype._doRender=function(){b.prototype._doRender.call(this),this.textContainer.text("");var c="horizontal"===this.orientation?this.availableWidth:this.availableHeight,d=a.Util.Text.getTruncatedText(this._text,c,this.measurer);"horizontal"===this.orientation?a.Util.Text.writeLineHorizontally(d,this.textContainer,this.availableWidth,this.availableHeight,this.xAlignment,this.yAlignment):a.Util.Text.writeLineVertically(d,this.textContainer,this.availableWidth,this.availableHeight,this.xAlignment,this.yAlignment,this.orientation)},c.prototype._computeLayout=function(c,d,e,f){return b.prototype._computeLayout.call(this,c,d,e,f),this.measurer=a.Util.Text.getTextMeasure(this.textContainer),this},c}(a.Abstract.Component);b.Label=c;var d=function(a){function b(b,c){a.call(this,b,c),this.classed("title-label",!0)}return __extends(b,a),b}(c);b.TitleLabel=d;var e=function(a){function b(b,c){a.call(this,b,c),this.classed("axis-label",!0)}return __extends(b,a),b}(c);b.AxisLabel=e}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a){b.call(this),this.classed("legend",!0),this.scale(a),this.xAlign("RIGHT").yAlign("TOP"),this.xOffset(5).yOffset(5),this._fixedWidthFlag=!0,this._fixedHeightFlag=!0}return __extends(c,b),c.prototype.remove=function(){b.prototype.remove.call(this),null!=this.colorScale&&this.colorScale.broadcaster.deregisterListener(this)},c.prototype.toggleCallback=function(a){return void 0!==a?(this._toggleCallback=a,this.isOff=d3.set(),this.updateListeners(),this.updateClasses(),this):this._toggleCallback},c.prototype.hoverCallback=function(a){return void 0!==a?(this._hoverCallback=a,this.datumCurrentlyFocusedOn=void 0,this.updateListeners(),this.updateClasses(),this):this._hoverCallback},c.prototype.scale=function(a){var b=this;return null!=a?(null!=this.colorScale&&this.colorScale.broadcaster.deregisterListener(this),this.colorScale=a,this.colorScale.broadcaster.registerListener(this,function(){return b.updateDomain()}),this.updateDomain(),this):this.colorScale},c.prototype.updateDomain=function(){null!=this._toggleCallback&&(this.isOff=a.Util.Methods.intersection(this.isOff,d3.set(this.scale().domain()))),null!=this._hoverCallback&&(this.datumCurrentlyFocusedOn=this.scale().domain().indexOf(this.datumCurrentlyFocusedOn)>=0?this.datumCurrentlyFocusedOn:void 0),this._invalidateLayout()},c.prototype._computeLayout=function(a,c,d,e){b.prototype._computeLayout.call(this,a,c,d,e);var f=this.measureTextHeight(),g=this.colorScale.domain().length;this.nRowsDrawn=Math.min(g,Math.floor(this.availableHeight/f))},c.prototype._requestedSpace=function(b,d){var e=this.measureTextHeight(),f=this.colorScale.domain().length,g=Math.min(f,Math.floor((d-2*c.MARGIN)/e)),h=this.content.append("g").classed(c.SUBELEMENT_CLASS,!0),i=h.append("text"),j=d3.max(this.colorScale.domain(),function(b){return a.Util.Text.getTextWidth(i,b)});h.remove(),j=void 0===j?0:j;var k=0===g?0:j+e+2*c.MARGIN,l=0===g?0:f*e+2*c.MARGIN;return{width:k,height:l,wantsWidth:k>b,wantsHeight:l>d}},c.prototype.measureTextHeight=function(){var b=this.content.append("g").classed(c.SUBELEMENT_CLASS,!0),d=a.Util.Text.getTextHeight(b.append("text"));return 0===d&&(d=1),b.remove(),d},c.prototype._doRender=function(){b.prototype._doRender.call(this);var d=this.colorScale.domain().slice(0,this.nRowsDrawn),e=this.measureTextHeight(),f=this.availableWidth-e-c.MARGIN,g=.3*e,h=this.content.selectAll("."+c.SUBELEMENT_CLASS).data(d,function(a){return a}),i=h.enter().append("g").classed(c.SUBELEMENT_CLASS,!0);i.append("circle"),i.append("g").classed("text-container",!0),h.exit().remove(),h.selectAll("circle").attr("cx",e/2).attr("cy",e/2).attr("r",g).attr("fill",this.colorScale._d3Scale),h.selectAll("g.text-container").text("").attr("transform","translate("+e+", 0)").each(function(b){var c=d3.select(this),d=a.Util.Text.getTextMeasure(c),e=a.Util.Text.getTruncatedText(b,f,d),g=d(e);a.Util.Text.writeLineHorizontally(e,c,g.width,g.height)}),h.attr("transform",function(a){return"translate("+c.MARGIN+","+(d.indexOf(a)*e+c.MARGIN)+")"}),this.updateClasses(),this.updateListeners()},c.prototype.updateListeners=function(){var a=this;if(this._isSetup){var b=this.content.selectAll("."+c.SUBELEMENT_CLASS);if(null!=this._hoverCallback){var d=function(b){return function(c){a.datumCurrentlyFocusedOn=b?c:void 0,a._hoverCallback(a.datumCurrentlyFocusedOn),a.updateClasses()}};b.on("mouseover",d(!0)),b.on("mouseout",d(!1))}else b.on("mouseover",null),b.on("mouseout",null);null!=this._toggleCallback?b.on("click",function(b){var c=a.isOff.has(b);c?a.isOff.remove(b):a.isOff.add(b),a._toggleCallback(b,c),a.updateClasses()}):b.on("click",null)}},c.prototype.updateClasses=function(){var a=this;if(this._isSetup){var b=this.content.selectAll("."+c.SUBELEMENT_CLASS);null!=this._hoverCallback?(b.classed("focus",function(b){return a.datumCurrentlyFocusedOn===b}),b.classed("hover",void 0!==this.datumCurrentlyFocusedOn)):(b.classed("hover",!1),b.classed("focus",!1)),null!=this._toggleCallback?(b.classed("toggled-on",function(b){return!a.isOff.has(b)}),b.classed("toggled-off",function(b){return a.isOff.has(b)})):(b.classed("toggled-on",!1),b.classed("toggled-off",!1))}},c.SUBELEMENT_CLASS="legend-row",c.MARGIN=5,c}(a.Abstract.Component);b.Legend=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c){var d=this;if(a.call(this),null==b&&null==c)throw new Error("Gridlines must have at least one scale");this.classed("gridlines",!0),this.xScale=b,this.yScale=c,null!=this.xScale&&this.xScale.broadcaster.registerListener(this,function(){return d._render()}),null!=this.yScale&&this.yScale.broadcaster.registerListener(this,function(){return d._render()})}return __extends(b,a),b.prototype.remove=function(){return a.prototype.remove.call(this),null!=this.xScale&&this.xScale.broadcaster.deregisterListener(this),null!=this.yScale&&this.yScale.broadcaster.deregisterListener(this),this},b.prototype._setup=function(){a.prototype._setup.call(this),this.xLinesContainer=this.content.append("g").classed("x-gridlines",!0),this.yLinesContainer=this.content.append("g").classed("y-gridlines",!0)},b.prototype._doRender=function(){a.prototype._doRender.call(this),this.redrawXLines(),this.redrawYLines()},b.prototype.redrawXLines=function(){var a=this;if(null!=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.availableHeight).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},b.prototype.redrawYLines=function(){var a=this;if(null!=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.availableWidth).attr("y2",c).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},b}(a.Abstract.Component);b.Gridlines=c}(a.Component||(a.Component={}));a.Component}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(b){function c(a,c,d){if(b.call(this,a),null==c||null==d)throw new Error("XYPlots require an xScale and yScale");this.classed("xy-plot",!0),this.project("x","x",c),this.project("y","y",d)}return __extends(c,b),c.prototype.project=function(a,c,d){return"x"===a&&null!=d&&(this.xScale=d,this._updateXDomainer()),"y"===a&&null!=d&&(this.yScale=d,this._updateYDomainer()),b.prototype.project.call(this,a,c,d),this},c.prototype._computeLayout=function(a,c,d,e){b.prototype._computeLayout.call(this,a,c,d,e),this.xScale.range([0,this.availableWidth]),this.yScale.range([this.availableHeight,0])},c.prototype._updateXDomainer=function(){if(this.xScale instanceof a.QuantitativeScale){var b=this.xScale;b._userSetDomainer||b.domainer().pad().nice()}},c.prototype._updateYDomainer=function(){if(this.yScale instanceof a.QuantitativeScale){var b=this.yScale;b._userSetDomainer||b.domainer().pad().nice()}},c}(a.Plot);a.XYPlot=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._animators={"circles-reset":new a.Animator.Null,circles:(new a.Animator.IterativeDelay).duration(250).delay(5)},this.classed("scatter-plot",!0),this.project("r",3),this.project("opacity",.6),this.project("fill",function(){return a.Core.Colors.INDIGO})}return __extends(c,b),c.prototype.project=function(a,c,d){return a="cx"===a?"x":a,a="cy"===a?"y":a,b.prototype.project.call(this,a,c,d),this},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector();a.cx=a.x,a.cy=a.y,delete a.x,delete a.y;var c=this.renderArea.selectAll("circle").data(this._dataSource.data());if(c.enter().append("circle"),this._dataChanged){var d=a.r;a.r=function(){return 0},this._applyAnimatedAttributes(c,"circles-reset",a),a.r=d}this._applyAnimatedAttributes(c,"circles",a),c.exit().remove()},c}(a.Abstract.XYPlot);b.Scatter=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e,f){b.call(this,c,d,e),this._animators={cells:new a.Animator.Null},this.classed("grid-plot",!0),this.xScale.rangeType("bands",0,0),this.yScale.rangeType("bands",0,0),this.colorScale=f,this.project("fill","value",f)}return __extends(c,b),c.prototype.project=function(a,c,d){return b.prototype.project.call(this,a,c,d),"fill"===a&&(this.colorScale=this._projectors.fill.scale),this},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this.renderArea.selectAll("rect").data(this._dataSource.data());a.enter().append("rect");var c=this.xScale.rangeBand(),d=this.yScale.rangeBand(),e=this._generateAttrToProjector();e.width=function(){return c},e.height=function(){return d},this._applyAnimatedAttributes(a,"cells",e),a.exit().remove()},c}(a.Abstract.XYPlot);b.Grid=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(c){function d(b,d,e){c.call(this,b,d,e),this._baselineValue=0,this._barAlignmentFactor=0,this._animators={"bars-reset":new a.Animator.Null,bars:new a.Animator.IterativeDelay,baseline:new a.Animator.Null},this.classed("bar-plot",!0),this.project("fill",function(){return a.Core.Colors.INDIGO}),this.baseline(this._baselineValue)}return __extends(d,c),d.prototype._setup=function(){c.prototype._setup.call(this),this._baseline=this.renderArea.append("line").classed("baseline",!0),this._bars=this.renderArea.selectAll("rect").data([])},d.prototype._paint=function(){c.prototype._paint.call(this),this._bars=this.renderArea.selectAll("rect").data(this._dataSource.data()),this._bars.enter().append("rect");var a=this._isVertical?this.yScale:this.xScale,b=a.scale(this._baselineValue),d=this._isVertical?"y":"x",e=this._isVertical?"height":"width";if(this._dataChanged&&this._animate){var f=this._generateAttrToProjector();f[d]=function(){return b},f[e]=function(){return 0},this._applyAnimatedAttributes(this._bars,"bars-reset",f)}var g=this._generateAttrToProjector();null!=g.fill&&this._bars.attr("fill",g.fill),this._applyAnimatedAttributes(this._bars,"bars",g),this._bars.exit().remove();var h={x1:this._isVertical?0:b,y1:this._isVertical?b:0,x2:this._isVertical?this.availableWidth:b,y2:this._isVertical?b:this.availableHeight};this._applyAnimatedAttributes(this._baseline,"baseline",h)},d.prototype.baseline=function(a){return this._baselineValue=a,this._updateXDomainer(),this._updateYDomainer(),this._render(),this},d.prototype.barAlignment=function(a){var b=a.toLowerCase(),c=this.constructor._BarAlignmentToFactor;if(void 0===c[b])throw new Error("unsupported bar alignment");return this._barAlignmentFactor=c[b],this._render(),this},d.prototype.parseExtent=function(a){if("number"==typeof a)return{min:a,max:a};if(a instanceof Object&&"min"in a&&"max"in a)return a;throw new Error("input '"+a+"' can't be parsed as an IExtent")},d.prototype.selectBar=function(a,b,c){if("undefined"==typeof c&&(c=!0),!this._isSetup)return null;var d=[],e=this.parseExtent(a),f=this.parseExtent(b),g=.5;if(this._bars.each(function(){var a=this.getBBox();a.x+a.width>=e.min-g&&a.x<=e.max+g&&a.y+a.height>=f.min-g&&a.y<=f.max+g&&d.push(this)}),d.length>0){var h=d3.selectAll(d);return h.classed("selected",c),h}return null},d.prototype.deselectAll=function(){return this._isSetup&&this._bars.classed("selected",!1),this},d.prototype._updateDomainer=function(a){if(a instanceof b.QuantitativeScale){var c=a;c._userSetDomainer||(null!=this._baselineValue?c.domainer().addPaddingException(this._baselineValue,"BAR_PLOT+"+this._plottableID).addIncludedValue(this._baselineValue,"BAR_PLOT+"+this._plottableID):c.domainer().removePaddingException("BAR_PLOT+"+this._plottableID).removeIncludedValue("BAR_PLOT+"+this._plottableID),c.domainer().pad()),c._autoDomainIfAutomaticMode()}},d.prototype._generateAttrToProjector=function(){var b=this,e=c.prototype._generateAttrToProjector.call(this),f=this._isVertical?this.yScale:this.xScale,g=this._isVertical?this.xScale:this.yScale,h=this._isVertical?"y":"x",i=this._isVertical?"x":"y",j=g instanceof a.Scale.Ordinal&&"bands"===g.rangeType(),k=f.scale(this._baselineValue);if(null==e.width){var l=j?g.rangeBand():d.DEFAULT_WIDTH;e.width=function(){return l}}var m=e[i],n=e.width;if(j){var o=g.rangeBand();e[i]=function(a,b){return m(a,b)-n(a,b)/2+o/2}}else e[i]=function(a,c){return m(a,c)-n(a,c)*b._barAlignmentFactor};var p=e[h];return e[h]=function(a,b){var c=p(a,b);return c>k?k:c},e.height=function(a,b){return Math.abs(k-p(a,b))},e},d.DEFAULT_WIDTH=10,d._BarAlignmentToFactor={},d}(b.XYPlot);b.BarPlot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c,d){a.call(this,b,c,d),this._isVertical=!0}return __extends(b,a),b.prototype._updateYDomainer=function(){this._updateDomainer(this.yScale)},b._BarAlignmentToFactor={left:0,center:.5,right:1},b}(a.Abstract.BarPlot);b.VerticalBar=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b,c,d){a.call(this,b,c,d),this.isVertical=!1}return __extends(b,a),b.prototype._updateXDomainer=function(){this._updateDomainer(this.xScale)},b.prototype._generateAttrToProjector=function(){var b=a.prototype._generateAttrToProjector.call(this),c=b.width;return b.width=b.height,b.height=c,b},b._BarAlignmentToFactor={top:0,center:.5,bottom:1},b}(a.Abstract.BarPlot);b.HorizontalBar=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._animators={"line-reset":new a.Animator.Null,line:(new a.Animator.Default).duration(600).easing("exp-in-out")},this.classed("line-plot",!0),this.project("stroke",function(){return a.Core.Colors.INDIGO}),this.project("stroke-width",function(){return"2px"})}return __extends(c,b),c.prototype._setup=function(){b.prototype._setup.call(this),this.linePath=this.renderArea.append("path").classed("line",!0)},c.prototype._getResetYFunction=function(){var a=this.yScale.domain(),b=Math.max(a[0],a[1]),c=Math.min(a[0],a[1]),d=0;0>b?d=b:c>0&&(d=c);var e=this.yScale.scale(d);return function(){return e}},c.prototype._generateAttrToProjector=function(){function a(a){return-1===d.indexOf(a)}var c=b.prototype._generateAttrToProjector.call(this),d=this._wholeDatumAttributes(),e=d3.keys(c).filter(a);return e.forEach(function(a){var b=c[a];c[a]=function(a,c){return a.length>0?b(a[0],c):null}}),c},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector(),c=a.x,d=a.y;delete a.x,delete a.y,this.linePath.datum(this._dataSource.data()),this._dataChanged&&(a.d=d3.svg.line().x(c).y(this._getResetYFunction()),this._applyAnimatedAttributes(this.linePath,"line-reset",a)),a.d=d3.svg.line().x(c).y(d),this._applyAnimatedAttributes(this.linePath,"line",a)},c.prototype._wholeDatumAttributes=function(){return["x","y"]},c}(a.Abstract.XYPlot);b.Line=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this.classed("area-plot",!0),this.project("y0",0,e),this.project("fill",function(){return a.Core.Colors.INDIGO}),this.project("fill-opacity",function(){return.25}),this.project("stroke",function(){return a.Core.Colors.INDIGO}),this._animators["area-reset"]=new a.Animator.Null,this._animators.area=(new a.Animator.Default).duration(600).easing("exp-in-out")}return __extends(c,b),c.prototype._setup=function(){b.prototype._setup.call(this),this.areaPath=this.renderArea.append("path").classed("area",!0)},c.prototype._onDataSourceUpdate=function(){b.prototype._onDataSourceUpdate.call(this),null!=this.yScale&&this._updateYDomainer()},c.prototype._updateYDomainer=function(){b.prototype._updateYDomainer.call(this);var a=this.yScale,c=this._projectors.y0,d=null!=c?c.accessor:null,e=null!=d?this.dataSource()._getExtent(d):[],f=2===e.length&&e[0]===e[1]?e[0]:null;a._userSetDomainer||(null!=f?a.domainer().addPaddingException(f,"AREA_PLOT+"+this._plottableID):a.domainer().removePaddingException("AREA_PLOT+"+this._plottableID),a._autoDomainIfAutomaticMode())},c.prototype.project=function(a,c,d){return b.prototype.project.call(this,a,c,d),"y0"===a&&this._updateYDomainer(),this},c.prototype._getResetYFunction=function(){return this._generateAttrToProjector().y0},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector(),c=a.x,d=a.y0,e=a.y;delete a.x,delete a.y0,delete a.y,this.areaPath.datum(this._dataSource.data()),this._dataChanged&&(a.d=d3.svg.area().x(c).y0(d).y1(this._getResetYFunction()),this._applyAnimatedAttributes(this.areaPath,"area-reset",a)),a.d=d3.svg.area().x(c).y0(d).y1(e),this._applyAnimatedAttributes(this.areaPath,"area",a) +},c.prototype._wholeDatumAttributes=function(){var a=b.prototype._wholeDatumAttributes.call(this);return a.push("y0"),a},c}(b.Line);b.Area=c}(a.Plot||(a.Plot={}));a.Plot}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){}return a.prototype.animate=function(a,b){return a.attr(b)},a}();a.Null=b}(a.Animator||(a.Animator={}));a.Animator}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){this._durationMsec=300,this._delayMsec=0,this._easing="exp-out"}return a.prototype.animate=function(a,b){return a.transition().ease(this._easing).duration(this._durationMsec).delay(this._delayMsec).attr(b)},a.prototype.duration=function(a){return void 0===a?this._durationMsec:(this._durationMsec=a,this)},a.prototype.delay=function(a){return void 0===a?this._delayMsec:(this._delayMsec=a,this)},a.prototype.easing=function(a){return void 0===a?this._easing:(this._easing=a,this)},a}();a.Default=b}(a.Animator||(a.Animator={}));a.Animator}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(a){function b(){a.apply(this,arguments),this._delayMsec=15}return __extends(b,a),b.prototype.animate=function(a,b){var c=this;return a.transition().ease(this._easing).duration(this._durationMsec).delay(function(a,b){return b*c._delayMsec}).attr(b)},b}(a.Default);a.IterativeDelay=b}(a.Animator||(a.Animator={}));a.Animator}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){!function(a){function b(){e||(d3.select(document).on("keydown",d),e=!0)}function c(a,c){e||b(),null==f[a]&&(f[a]=[]),f[a].push(c)}function d(){null!=f[d3.event.keyCode]&&f[d3.event.keyCode].forEach(function(a){a(d3.event)})}var e=!1,f=[];a.initialize=b,a.addCallback=c}(a.KeyEventListener||(a.KeyEventListener={}));a.KeyEventListener}(a.Core||(a.Core={}));a.Core}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(a){if(null==a)throw new Error("Interactions require a component to listen to");this.componentToListenTo=a}return a.prototype._anchor=function(a){this.hitBox=a},a.prototype.registerWithComponent=function(){return this.componentToListenTo.registerInteraction(this),this},a}();a.Interaction=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,b)}return __extends(b,a),b.prototype._anchor=function(b){var c=this;a.prototype._anchor.call(this,b),b.on(this._listenTo(),function(){var a=d3.mouse(b.node()),d=a[0],e=a[1];c._callback(d,e)})},b.prototype._listenTo=function(){return"click"},b.prototype.callback=function(a){return this._callback=a,this},b}(a.Abstract.Interaction);b.Click=c;var d=function(a){function b(b){a.call(this,b)}return __extends(b,a),b.prototype._listenTo=function(){return"dblclick"},b}(c);b.DoubleClick=d}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){a.call(this,b)}return __extends(b,a),b.prototype._anchor=function(b){var c=this;a.prototype._anchor.call(this,b),b.on("mousemove",function(){var a=d3.mouse(b.node()),d=a[0],e=a[1];c.mousemove(d,e)})},b.prototype.mousemove=function(){},b}(a.Abstract.Interaction);b.Mousemove=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(a,c){b.call(this,a),this.activated=!1,this.keyCode=c}return __extends(c,b),c.prototype._anchor=function(c){var d=this;b.prototype._anchor.call(this,c),c.on("mouseover",function(){d.activated=!0}),c.on("mouseout",function(){d.activated=!1}),a.Core.KeyEventListener.addCallback(this.keyCode,function(){d.activated&&null!=d._callback&&d._callback()})},c.prototype.callback=function(a){return this._callback=a,this},c}(a.Abstract.Interaction);b.Key=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){var f=this;b.call(this,c),null==d&&(d=new a.Scale.Linear),null==e&&(e=new a.Scale.Linear),this.xScale=d,this.yScale=e,this.zoom=d3.behavior.zoom(),this.zoom.x(this.xScale._d3Scale),this.zoom.y(this.yScale._d3Scale),this.zoom.on("zoom",function(){return f.rerenderZoomed()})}return __extends(c,b),c.prototype.resetZoom=function(){var a=this;this.zoom=d3.behavior.zoom(),this.zoom.x(this.xScale._d3Scale),this.zoom.y(this.yScale._d3Scale),this.zoom.on("zoom",function(){return a.rerenderZoomed()}),this.zoom(this.hitBox)},c.prototype._anchor=function(a){b.prototype._anchor.call(this,a),this.zoom(a)},c.prototype.rerenderZoomed=function(){var a=this.xScale._d3Scale.domain(),b=this.yScale._d3Scale.domain();this.xScale.domain(a),this.yScale.domain(b)},c}(a.Abstract.Interaction);b.PanZoom=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){var c=this;a.call(this,b),this.dragInitialized=!1,this.origin=[0,0],this.location=[0,0],this.dragBehavior=d3.behavior.drag(),this.dragBehavior.on("dragstart",function(){return c._dragstart()}),this.dragBehavior.on("drag",function(){return c._drag()}),this.dragBehavior.on("dragend",function(){return c._dragend()})}return __extends(b,a),b.prototype.callback=function(a){return this.callbackToCall=a,this},b.prototype._dragstart=function(){var a=this.componentToListenTo.availableWidth,b=this.componentToListenTo.availableHeight,c=function(a,b){return function(c){return Math.min(Math.max(c,a),b)}};this.constrainX=c(0,a),this.constrainY=c(0,b)},b.prototype._drag=function(){this.dragInitialized||(this.origin=[d3.event.x,d3.event.y],this.dragInitialized=!0),this.location=[this.constrainX(d3.event.x),this.constrainY(d3.event.y)]},b.prototype._dragend=function(){this.dragInitialized&&(this.dragInitialized=!1,this._doDragend())},b.prototype._doDragend=function(){null!=this.callbackToCall&&this.callbackToCall([this.origin,this.location])},b.prototype._anchor=function(b){return a.prototype._anchor.call(this,b),b.call(this.dragBehavior),this},b.prototype.setupZoomCallback=function(a,b){function c(c){return null==c?(f&&(null!=a&&a.domain(d),null!=b&&b.domain(e)),void(f=!f)):(f=!1,null!=a&&a.domain([a.invert(c.xMin),a.invert(c.xMax)]),null!=b&&b.domain([b.invert(c.yMax),b.invert(c.yMin)]),void this.clearBox())}var d=null!=a?a.domain():null,e=null!=b?b.domain():null,f=!1;return this.callback(c),this},b}(a.Abstract.Interaction);b.Drag=c}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(a){function b(){a.apply(this,arguments),this.boxIsDrawn=!1}return __extends(b,a),b.prototype._dragstart=function(){a.prototype._dragstart.call(this),null!=this.callbackToCall&&this.callbackToCall(null),this.clearBox()},b.prototype.clearBox=function(){return null!=this.dragBox?(this.dragBox.attr("height",0).attr("width",0),this.boxIsDrawn=!1,this):void 0},b.prototype.setBox=function(a,b,c,d){if(null!=this.dragBox){var e=Math.abs(a-b),f=Math.abs(c-d),g=Math.min(a,b),h=Math.min(c,d);return this.dragBox.attr({x:g,y:h,width:e,height:f}),this.boxIsDrawn=e>0&&f>0,this}},b.prototype._anchor=function(c){a.prototype._anchor.call(this,c);var d=b.CLASS_DRAG_BOX,e=this.componentToListenTo.backgroundContainer;return this.dragBox=e.append("rect").classed(d,!0).attr("x",0).attr("y",0),this},b.CLASS_DRAG_BOX="drag-box",b}(a.Drag);a.DragBox=b}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype._drag=function(){a.prototype._drag.call(this),this.setBox(this.origin[0],this.location[0])},b.prototype._doDragend=function(){if(null!=this.callbackToCall){var a=Math.min(this.origin[0],this.location[0]),b=Math.max(this.origin[0],this.location[0]),c={xMin:a,xMax:b};this.callbackToCall(c)}},b.prototype.setBox=function(b,c){return a.prototype.setBox.call(this,b,c,0,this.componentToListenTo.availableHeight),this},b}(a.DragBox);a.XDragBox=b}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype._drag=function(){a.prototype._drag.call(this),this.setBox(this.origin[0],this.location[0],this.origin[1],this.location[1])},b.prototype._doDragend=function(){if(null!=this.callbackToCall){var a=Math.min(this.origin[0],this.location[0]),b=Math.max(this.origin[0],this.location[0]),c=Math.min(this.origin[1],this.location[1]),d=Math.max(this.origin[1],this.location[1]),e={xMin:a,xMax:b,yMin:c,yMax:d};this.callbackToCall(e)}},b}(a.DragBox);a.XYDragBox=b}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype._drag=function(){a.prototype._drag.call(this),this.setBox(this.origin[1],this.location[1])},b.prototype._doDragend=function(){if(null!=this.callbackToCall){var a=Math.min(this.origin[1],this.location[1]),b=Math.max(this.origin[1],this.location[1]),c={yMin:a,yMax:b};this.callbackToCall(c)}},b.prototype.setBox=function(b,c){return a.prototype.setBox.call(this,0,this.componentToListenTo.availableWidth,b,c),this},b}(a.DragBox);a.YDragBox=b}(a.Interaction||(a.Interaction={}));a.Interaction}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(a){var b=function(a){function b(b){a.call(this),this._event2Callback={},this.connected=!1,this._target=b}return __extends(b,a),b.prototype.target=function(a){if(null==a)return this._target;var b=this.connected;return this.disconnect(),this._target=a,b&&this.connect(),this},b.prototype.getEventString=function(a){return a+".dispatcher"+this._plottableID},b.prototype.connect=function(){var a=this;if(this.connected)throw new Error("Can't connect dispatcher twice!");return this.connected=!0,Object.keys(this._event2Callback).forEach(function(b){var c=a._event2Callback[b];a._target.on(a.getEventString(b),c)}),this},b.prototype.disconnect=function(){var a=this;return this.connected=!1,Object.keys(this._event2Callback).forEach(function(b){a._target.on(a.getEventString(b),null)}),this},b}(a.PlottableObject);a.Dispatcher=b}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(a){function b(b){var c=this;a.call(this,b),this._event2Callback.mouseover=function(){null!=c._mouseover&&c._mouseover(c.getMousePosition())},this._event2Callback.mousemove=function(){null!=c._mousemove&&c._mousemove(c.getMousePosition())},this._event2Callback.mouseout=function(){null!=c._mouseout&&c._mouseout(c.getMousePosition())}}return __extends(b,a),b.prototype.getMousePosition=function(){var a=d3.mouse(this._target.node());return{x:a[0],y:a[1]}},b.prototype.mouseover=function(a){return void 0===a?this._mouseover:(this._mouseover=a,this)},b.prototype.mousemove=function(a){return void 0===a?this._mousemove:(this._mousemove=a,this)},b.prototype.mouseout=function(a){return void 0===a?this._mouseout:(this._mouseout=a,this)},b}(a.Abstract.Dispatcher);b.Mouse=c}(a.Dispatcher||(a.Dispatcher={}));a.Dispatcher}(Plottable||(Plottable={}));var __extends=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},Plottable;!function(a){!function(b){var c=function(b){function c(){b.call(this),this.xTable=new a.Component.Table,this.yTable=new a.Component.Table,this.centerComponent=new a.Component.Group,this.xyTable=(new a.Component.Table).addComponent(0,0,this.yTable).addComponent(1,1,this.xTable).addComponent(0,1,this.centerComponent),this.addComponent(1,0,this.xyTable)}return __extends(c,b),c.prototype.yAxis=function(a){if(null!=a){if(null!=this._yAxis)throw new Error("yAxis already assigned!");return this._yAxis=a,this.yTable.addComponent(0,1,this._yAxis),this}return this._yAxis},c.prototype.xAxis=function(a){if(null!=a){if(null!=this._xAxis)throw new Error("xAxis already assigned!");return this._xAxis=a,this.xTable.addComponent(0,0,this._xAxis),this}return this._xAxis},c.prototype.yLabel=function(b){if(null!=b){if(null!=this._yLabel){if("string"==typeof b)return this._yLabel.text(b),this;throw new Error("yLabel already assigned!")}return"string"==typeof b&&(b=new a.Component.AxisLabel(b,"vertical-left")),this._yLabel=b,this.yTable.addComponent(0,0,this._yLabel),this}return this._yLabel},c.prototype.xLabel=function(b){if(null!=b){if(null!=this._xLabel){if("string"==typeof b)return this._xLabel.text(b),this;throw new Error("xLabel already assigned!")}return"string"==typeof b&&(b=new a.Component.AxisLabel(b,"horizontal")),this._xLabel=b,this.xTable.addComponent(1,0,this._xLabel),this}return this._xLabel},c.prototype.titleLabel=function(b){if(null!=b){if(null!=this._titleLabel){if("string"==typeof b)return this._titleLabel.text(b),this;throw new Error("titleLabel already assigned!")}return"string"==typeof b&&(b=new a.Component.TitleLabel(b,"horizontal")),this._titleLabel=b,this.addComponent(0,0,this._titleLabel),this}return this._titleLabel},c.prototype.center=function(a){return this.centerComponent.merge(a),this},c}(a.Component.Table);b.StandardChart=c}(a.Template||(a.Template={}));a.Template}(Plottable||(Plottable={})); \ No newline at end of file diff --git a/plottable.zip b/plottable.zip index f4098b5b4297edcbed03ef417c8cd495d17e8c6a..f64ce99418c6142677ec8d4a140687cf306ddca0 100644 GIT binary patch literal 125003 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 z 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