From abe25b878fbfa4c8ef5d735bd2875c13b68d2e48 Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Mon, 18 Aug 2014 20:54:47 -0700 Subject: [PATCH] Release version 0.25.0 --- bower.json | 2 +- package.json | 2 +- plottable.d.ts | 2299 ++++++++++++++++++++++++++++----- plottable.js | 3224 +++++++++++++++++++++++++++++++++++++++------- plottable.min.js | 8 +- plottable.zip | Bin 125003 -> 133915 bytes 6 files changed, 4704 insertions(+), 831 deletions(-) diff --git a/bower.json b/bower.json index df937e9add..236ac8b910 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "plottable", "description": "A library for creating charts out of D3", - "version": "0.24.0", + "version": "0.25.0", "main": ["plottable.js", "plottable.css"], "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index ac01b42cbd..58f889a659 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plottable.js", - "version": "0.24.0", + "version": "0.25.0", "description": "Build flexible, performant, interactive charts using D3", "repository": { "type": "git", diff --git a/plottable.d.ts b/plottable.d.ts index be37db8c79..f38fdfb02d 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -2,16 +2,71 @@ 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; + /** + * 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 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; } } @@ -21,6 +76,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; } @@ -31,9 +122,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; } } } @@ -41,14 +132,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; } } } @@ -57,9 +197,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; } } } @@ -76,12 +243,45 @@ 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 + * in the given text selection + * + * @param {D3.Selection} selection: A temporary text selection that the string will be placed into for measurement. + * Will be removed on function creation and appended only for measurement. + * @returns {Dimensions} width and height of the text + */ function getTextMeasurer(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} textSelection 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(textSelection: 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; function writeLineHorizontally(line: string, g: D3.Selection, width: number, height: number, xAlign?: string, yAlign?: string): { width: number; @@ -101,6 +301,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; } } @@ -115,7 +321,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; } } @@ -124,6 +339,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; @@ -144,13 +364,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; } } @@ -190,32 +473,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; } } @@ -223,29 +593,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; } } } @@ -254,10 +702,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; } } } @@ -265,9 +729,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; } } } @@ -283,12 +753,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; } } } @@ -296,18 +803,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(plotProvidedKey: string, attr: string, extent: any[]): Scale; - removeExtent(plotProvidedKey: string, 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(plotProvidedKey: string, attr: string, extent: any[]): Scale; + public removeExtent(plotProvidedKey: string, attr: string): Scale; } } } @@ -316,19 +882,55 @@ declare module Plottable { declare module Plottable { module Abstract { 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; } } } @@ -337,10 +939,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; } } } @@ -349,20 +959,52 @@ declare module Plottable { declare module Plottable { interface DatasetDrawerKey { dataset: DataSource; - drawer: Plottable.Abstract._Drawer; + drawer: Abstract._Drawer; key: string; } module Abstract { class NewStylePlot extends XYPlot { + /** + * Creates a NewStylePlot. + * + * @constructor + * @param [Scale] xScale The x scale to use + * @param [Scale] yScale The y scale to use + */ constructor(xScale?: Scale, yScale?: Scale); - remove(): void; - addDataset(key: string, dataset: DataSource): NewStylePlot; - addDataset(key: string, dataset: any[]): NewStylePlot; - addDataset(dataset: DataSource): NewStylePlot; - addDataset(dataset: any[]): NewStylePlot; - datasetOrder(): string[]; - datasetOrder(order: string[]): NewStylePlot; - removeDataset(key: string): NewStylePlot; + public remove(): void; + /** + * Adds a dataset to this plot. Identify this dataset with a key. + * + * A key is automatically generated if not supplied. + * + * @param {string} [key] The key of the dataset. + * @param {any[]|DataSource} dataset dataset to add. + * @return {NewStylePlot} The calling NewStylePlot. + */ + public addDataset(key: string, dataset: DataSource): NewStylePlot; + public addDataset(key: string, dataset: any[]): NewStylePlot; + public addDataset(dataset: DataSource): NewStylePlot; + public addDataset(dataset: any[]): NewStylePlot; + /** + * Gets the dataset order by key + * + * @return {string[]} a string array of the keys in order + */ + public datasetOrder(): string[]; + /** + * Sets the dataset order by key + * + * @param {string[]} order A string array which represents the order of the keys. This must be a permutation of existing keys. + */ + public datasetOrder(order: string[]): NewStylePlot; + /** + * Removes a dataset + * + * @param {string} key The key of the dataset + * @return {NewStylePlot} The calling NewStylePlot. + */ + public removeDataset(key: string): NewStylePlot; } } } @@ -376,13 +1018,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; } } } @@ -392,10 +1034,32 @@ 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 { 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; } } @@ -404,11 +1068,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; } } } @@ -417,7 +1111,18 @@ declare module Plottable { declare module Plottable { module Animator { interface IPlotAnimator { - animate(selection: any, attrToProjector: 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 {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: IAttributeToProjector, plot: Abstract.Plot): any; } interface IPlotAnimatorMap { [animatorKey: string]: IPlotAnimator; @@ -442,7 +1147,7 @@ declare module Plottable { } interface _IProjector { accessor: IAccessor; - scale?: Plottable.Abstract.Scale; + scale?: Abstract.Scale; attribute: string; } interface IAttributeToProjector { @@ -477,14 +1182,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; } } @@ -492,20 +1277,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; } } } @@ -513,10 +1367,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; } } } @@ -524,10 +1389,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; } } } @@ -535,14 +1417,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; } } } @@ -550,18 +1469,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; } } } @@ -569,7 +1542,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); } } @@ -578,13 +1559,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; } } } @@ -592,13 +1584,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; } } } @@ -607,8 +1644,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; } } } @@ -617,11 +1660,26 @@ declare module Plottable { declare module Plottable { module Abstract { class _Drawer { - renderArea: D3.Selection; - key: string; + public renderArea: D3.Selection; + public key: string; + /** + * Creates a Drawer + * + * @constructor + * @param{string} key The key associated with this Drawer + */ constructor(key: string); - remove(): void; - draw(data: any[][], attrToProjector: IAttributeToProjector): void; + /** + * Removes the Drawer and its renderArea + */ + public remove(): void; + /** + * Draws the data into the renderArea using the attrHash for attributes + * + * @param{any[][]} data The data to be drawn + * @param{attrHash} IAttributeToProjector The list of attributes to set on the data + */ + public draw(data: any[][], attrToProjector: IAttributeToProjector): void; } } } @@ -629,8 +1687,8 @@ declare module Plottable { declare module Plottable { module _Drawer { - class Rect extends Plottable.Abstract._Drawer { - draw(data: any[][], attrToProjector: IAttributeToProjector): void; + class Rect extends Abstract._Drawer { + public draw(data: any[][], attrToProjector: IAttributeToProjector): void; } } } @@ -639,29 +1697,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; } } } @@ -674,10 +1841,17 @@ 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); + /** + * 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); } } } @@ -685,12 +1859,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; } } } @@ -698,8 +1914,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); } } } @@ -707,12 +1934,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); @@ -732,16 +1977,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; } } } @@ -749,9 +2033,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; } } } @@ -759,9 +2050,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; } } } @@ -769,12 +2068,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; } } } @@ -783,14 +2092,51 @@ declare module Plottable { declare module Plottable { module Abstract { class BarPlot extends XYPlot { + /** + * 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; } } } @@ -798,8 +2144,25 @@ declare module Plottable { declare module Plottable { module Plot { - class VerticalBar extends Plottable.Abstract.BarPlot { - constructor(dataset: any, xScale: Plottable.Abstract.Scale, yScale: Plottable.Abstract.QuantitativeScale); + /** + * 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 { + /** + * 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); } } } @@ -807,9 +2170,26 @@ declare module Plottable { declare module Plottable { module Plot { - class HorizontalBar extends Plottable.Abstract.BarPlot { - isVertical: boolean; - constructor(dataset: any, xScale: Plottable.Abstract.QuantitativeScale, yScale: Plottable.Abstract.Scale); + /** + * 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 { + 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); } } } @@ -817,8 +2197,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); } } } @@ -826,9 +2214,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; } } } @@ -838,8 +2237,21 @@ declare module Plottable { module Abstract { class NewStyleBarPlot extends NewStylePlot { static DEFAULT_WIDTH: number; + /** + * Creates an NewStyleBarPlot. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(xScale: Scale, yScale: Scale); - baseline(value: number): any; + /** + * Sets the baseline for the bars to the specified value. + * + * @param {number} value The value to position the baseline at. + * @return {NewStyleBarPlot} The calling NewStyleBarPlot. + */ + public baseline(value: number): any; } } } @@ -847,9 +2259,9 @@ declare module Plottable { declare module Plottable { module Plot { - class ClusteredBar extends Plottable.Abstract.NewStyleBarPlot { + class ClusteredBar extends Abstract.NewStyleBarPlot { static DEFAULT_WIDTH: number; - constructor(xScale: Plottable.Abstract.Scale, yScale: Plottable.Abstract.QuantitativeScale); + constructor(xScale: Abstract.Scale, yScale: Abstract.QuantitativeScale); } } } @@ -857,9 +2269,9 @@ declare module Plottable { declare module Plottable { module Plot { - class StackedBar extends Plottable.Abstract.NewStyleBarPlot { - stackedData: any[][]; - constructor(xScale?: Plottable.Abstract.Scale, yScale?: Plottable.Abstract.Scale); + class StackedBar extends Abstract.NewStyleBarPlot { + public stackedData: any[][]; + constructor(xScale?: Abstract.Scale, yScale?: Abstract.Scale); } } } @@ -867,8 +2279,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: IAttributeToProjector, plot: Plottable.Abstract.Plot): any; + public animate(selection: any, attrToProjector: IAttributeToProjector, plot: Abstract.Plot): any; } } } @@ -876,14 +2292,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: 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: 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; } } } @@ -891,8 +2343,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: IAttributeToProjector, plot: Plottable.Abstract.Plot): any; + public animate(selection: any, attrToProjector: IAttributeToProjector, plot: Abstract.Plot): any; } } } @@ -914,10 +2372,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; } } } @@ -925,12 +2393,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); } } } @@ -938,9 +2423,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; } } } @@ -948,9 +2433,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; } } } @@ -958,11 +2455,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; } } } @@ -970,13 +2475,47 @@ declare module Plottable { declare module Plottable { module Interaction { - class BarHover extends Plottable.Abstract.Interaction { - componentToListenTo: Plottable.Abstract.BarPlot; - constructor(barPlot: Plottable.Abstract.BarPlot); - hoverMode(): string; - hoverMode(mode: string): BarHover; - onHover(callback: (datum: any, bar: D3.Selection) => any): BarHover; - onUnhover(callback: (datum: any, bar: D3.Selection) => any): BarHover; + class BarHover extends Abstract.Interaction { + public componentToListenTo: Abstract.BarPlot; + /** + * Creates a new BarHover Interaction. + * + * @param {Abstract.BarPlot} barPlot The Bar Plot to listen for hover events on. + */ + constructor(barPlot: Abstract.BarPlot); + /** + * Gets the current hover mode. + * + * @return {string} The current hover mode. + */ + public hoverMode(): string; + /** + * Sets the hover mode for the interaction. There are two modes: + * - "point": Selects the bar under the mouse cursor (default). + * - "line" : Selects any bar that would be hit by a line extending + * in the same direction as the bar and passing through + * the cursor. + * + * @param {string} mode The desired hover mode. + * @return {BarHover} The calling Interaction.BarHover. + */ + public hoverMode(mode: string): BarHover; + /** + * Attaches an callback to be called when the user mouses over a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} The callback to be called. + * The callback will be passed the data from the hovered-over bar. + * @return {BarHover} The calling Interaction.BarHover. + */ + public onHover(callback: (datum: any, bar: D3.Selection) => any): BarHover; + /** + * Attaches a callback to be called when the user mouses off of a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} The callback to be called. + * The callback will be passed the data from the last-hovered bar. + * @return {BarHover} The calling Interaction.BarHover. + */ + public onUnhover(callback: (datum: any, bar: D3.Selection) => any): BarHover; } } } @@ -984,17 +2523,55 @@ declare module Plottable { declare module Plottable { module Interaction { - class Drag extends Plottable.Abstract.Interaction { - origin: number[]; - location: number[]; - constructor(componentToListenTo: Plottable.Abstract.Component); - dragstart(): (startLocation: Point) => void; - dragstart(cb: (startLocation: Point) => any): Drag; - drag(): (startLocation: Point, endLocation: Point) => void; - drag(cb: (startLocation: Point, endLocation: Point) => any): Drag; - dragend(): (startLocation: Point, endLocation: Point) => void; - dragend(cb: (startLocation: Point, endLocation: Point) => any): Drag; - setupZoomCallback(xScale?: Plottable.Abstract.QuantitativeScale, yScale?: Plottable.Abstract.QuantitativeScale): Drag; + class Drag extends Abstract.Interaction { + public origin: number[]; + public location: number[]; + /** + * Creates a Drag. + * + * @param {Component} componentToListenTo The component to listen for interactions on. + */ + constructor(componentToListenTo: Abstract.Component); + /** + * Gets the callback that is called when dragging starts. + * + * @returns {(startLocation: Point) => void} + */ + public dragstart(): (startLocation: Point) => void; + /** + * Sets the callback to be called when dragging starts. + * + * @param {(startLocation: Point) => any} cb The function to be called. + * @returns {Drag} + */ + public dragstart(cb: (startLocation: Point) => any): Drag; + /** + * Gets the callback that is called during dragging. + * + * @returns {(startLocation: Point, endLocation: Point) => void} + */ + public drag(): (startLocation: Point, endLocation: Point) => void; + /** + * Adds a callback to be called during dragging. + * + * @param {(startLocation: Point, endLocation: Point) => any} cb The function to be called. + * @returns {Drag} + */ + public drag(cb: (startLocation: Point, endLocation: Point) => any): Drag; + /** + * Gets the callback that is called when dragging ends. + * + * @returns {(startLocation: Point, endLocation: Point) => void} + */ + public dragend(): (startLocation: Point, endLocation: Point) => void; + /** + * Adds a callback to be called when the dragging ends. + * + * @param {(startLocation: Point, endLocation: Point) => any} cb The function to be called. Takes in a SelectionArea in pixels. + * @returns {Drag} The calling Drag. + */ + public dragend(cb: (startLocation: Point, endLocation: Point) => any): Drag; + public setupZoomCallback(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale): Drag; } } } @@ -1003,10 +2580,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; } } } @@ -1015,7 +2597,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; } } } @@ -1032,7 +2614,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; } } } @@ -1041,11 +2623,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; } } } @@ -1053,14 +2661,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; } } } @@ -1068,22 +2717,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 566ac80409..12b3e0d431 100644 --- a/plottable.js +++ b/plottable.js @@ -1,35 +1,68 @@ /*! -Plottable 0.24.0 (https://github.com/palantir/plottable) +Plottable 0.25.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,13 +476,25 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { (function (Text) { Text.HEIGHT_TEXT = "bqpdl"; + ; + ; + + /** + * Returns a quasi-pure function of typesignature (t: string) => Dimensions which measures height and width of text + * in the given text selection + * + * @param {D3.Selection} selection: A temporary text selection that the string will be placed into for measurement. + * Will be removed on function creation and appended only for measurement. + * @returns {Dimensions} width and height of the text + */ function getTextMeasurer(selection) { var parentNode = selection.node().parentNode; selection.remove(); @@ -304,19 +510,45 @@ var Plottable; }; } Text.getTextMeasurer = getTextMeasurer; + + /** + * @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)) { @@ -329,21 +561,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} textSelection 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(textSelection) { var _this = this; this.cache = new Util.Cache(getTextMeasurer(textSelection), 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; @@ -351,18 +602,33 @@ 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; + + /** + * 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) { @@ -380,9 +646,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) { @@ -409,10 +676,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); } @@ -426,12 +694,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 = getTextMeasurer(g.append("text"))(Text.HEIGHT_TEXT).height; var maxWidth = 0; var blockG = g.append("g"); @@ -449,10 +719,11 @@ var Plottable; Util.DOM.translate(blockG, 0, freeSpace * translator[yAlign]); return { width: maxWidth, height: usedSpace }; } + 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 = getTextMeasurer(g.append("text"))(Text.HEIGHT_TEXT).height; var maxHeight = 0; var blockG = g.append("g"); @@ -468,31 +739,49 @@ 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 }; } + ; + + /** + * @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; @@ -502,6 +791,7 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Util) { @@ -509,9 +799,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); @@ -519,12 +817,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"); @@ -532,13 +837,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); @@ -546,6 +856,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); @@ -557,8 +874,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; } @@ -573,6 +892,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]; @@ -587,8 +915,7 @@ var Plottable; while (i < nextToken.length) { if (widthMeasure(curLine + nextToken[i] + "-") <= width) { curLine += nextToken[i++]; - } - else { + } else { break; } } @@ -599,6 +926,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 = ""; @@ -607,8 +943,7 @@ var Plottable; var curChar = text[i]; if (token === "" || isTokenizedTogether(token[0], curChar, lastChar)) { token += curChar; - } - else { + } else { ret.push(token); token = curChar; } @@ -619,17 +954,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)) { @@ -647,20 +996,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); @@ -669,6 +1024,8 @@ var Plottable; } return parsedValue; } + + // function isSelectionRemovedFromSVG(selection) { var n = selection.node(); while (n !== null && n.nodeName !== "svg") { @@ -677,20 +1034,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) { @@ -700,20 +1062,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; @@ -722,6 +1084,7 @@ var Plottable; } } DOM.translate = translate; + function boxesOverlap(boxA, boxB) { if (boxA.right < boxB.left) { return false; @@ -744,17 +1107,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)); @@ -764,10 +1139,10 @@ var Plottable; if (formattedValue !== "") { if (prefix) { formattedValue = symbol + formattedValue; - } - else { + } else { formattedValue += symbol; } + if (d < 0) { formattedValue = "-" + formattedValue; } @@ -775,9 +1150,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); @@ -787,9 +1171,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") { @@ -799,26 +1193,44 @@ 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 valToFormat = d * 100; + + // Account for float imprecision var valString = d.toString(); var integerPowerTen = Math.pow(10, valString.length - (valString.indexOf(".") + 1)); valToFormat = parseInt((valToFormat * integerPowerTen).toString(), 10) / integerPowerTen; + var formattedValue = fixedFormatter(valToFormat); if (onlyShowUnchanged && Formatters._valueChanged(valToFormat, formattedValue)) { return ""; @@ -829,48 +1241,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)) { @@ -879,20 +1327,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); }; @@ -901,11 +1361,13 @@ var Plottable; Plottable.Formatters = Formatters; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { - Plottable.version = "0.24.0"; + Plottable.version = "0.25.0"; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { @@ -922,6 +1384,7 @@ var Plottable; Colors.CERISE_RED = "#db2e65"; Colors.BRIGHT_SUN = "#ffe43d"; Colors.JACARTA = "#2c2b6f"; + Colors.PLOTTABLE_COLORS = [ Colors.CORAL_RED, Colors.INDIGO, @@ -941,6 +1404,7 @@ var Plottable; var Core = Plottable.Core; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Abstract) { @@ -956,6 +1420,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; } @@ -965,30 +1430,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(); }; @@ -999,6 +1513,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; } @@ -1009,9 +1524,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; @@ -1021,25 +1543,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) { @@ -1048,20 +1570,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; } } @@ -1071,6 +1591,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; } @@ -1099,25 +1620,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) { @@ -1127,45 +1664,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"); } } @@ -1173,51 +1732,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); @@ -1226,6 +1805,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"); @@ -1236,59 +1822,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"); @@ -1305,37 +1923,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; } @@ -1343,23 +1970,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) { @@ -1369,12 +2020,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(); @@ -1386,6 +2042,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(); @@ -1399,6 +2060,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; } @@ -1412,16 +2074,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) { @@ -1429,15 +2101,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; @@ -1447,19 +2120,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); @@ -1468,6 +2167,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; } @@ -1479,27 +2179,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); @@ -1508,11 +2232,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); @@ -1521,6 +2251,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; } @@ -1531,12 +2262,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 = []; @@ -1551,24 +2290,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; @@ -1577,24 +2327,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); @@ -1602,46 +2391,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); @@ -1652,35 +2463,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]); } @@ -1689,29 +2516,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) { @@ -1730,28 +2590,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; @@ -1761,6 +2636,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; } @@ -1772,6 +2648,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; @@ -1782,56 +2664,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 (plotProvidedKey, attr, extent) { this._rendererAttrID2Extent[plotProvidedKey + attr] = extent; this._autoDomainIfAutomaticMode(); return this; }; + Scale.prototype.removeExtent = function (plotProvidedKey, attr) { delete this._rendererAttrID2Extent[plotProvidedKey + attr]; this._autoDomainIfAutomaticMode(); @@ -1844,6 +2763,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; } @@ -1865,16 +2785,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); @@ -1885,10 +2804,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]; @@ -1897,6 +2819,7 @@ var Plottable; } }); }; + Plot.prototype.dataSource = function (source) { var _this = this; if (source == null) { @@ -1907,34 +2830,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.toString(), 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, attribute: attrToSet }; 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 = {}; @@ -1942,11 +2874,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(); @@ -1954,50 +2889,83 @@ 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); + }); }; + 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.toString(), attr); - } - else { + } else { projector.scale.updateExtent(this._plottableID.toString(), attr, extent); } } }; + + /** + * 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 {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; } @@ -2009,6 +2977,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; } @@ -2020,32 +2989,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; @@ -2054,6 +3039,7 @@ var Plottable; } } }; + XYPlot.prototype._updateYDomainer = function () { if (this.yScale instanceof Abstract.QuantitativeScale) { var scale = this.yScale; @@ -2069,6 +3055,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; } @@ -2080,7 +3067,15 @@ var Plottable; (function (Abstract) { var NewStylePlot = (function (_super) { __extends(NewStylePlot, _super); + /** + * Creates a NewStylePlot. + * + * @constructor + * @param [Scale] xScale The x scale to use + * @param [Scale] yScale The y scale to use + */ function NewStylePlot(xScale, yScale) { + // make a dummy dataSource to satisfy the base Plot (HACKHACK) _super.call(this, new Plottable.DataSource(), xScale, yScale); this.nextSeriesIndex = 0; this._key2DatasetDrawerKey = {}; @@ -2089,13 +3084,19 @@ var Plottable; NewStylePlot.prototype._setup = function () { var _this = this; _super.prototype._setup.call(this); - this._getDrawersInOrder().forEach(function (d) { return d.renderArea = _this.renderArea.append("g"); }); + this._getDrawersInOrder().forEach(function (d) { + return d.renderArea = _this.renderArea.append("g"); + }); }; + NewStylePlot.prototype.remove = function () { var _this = this; _super.prototype.remove.call(this); - this._datasetKeysInOrder.forEach(function (k) { return _this.removeDataset(k); }); + this._datasetKeysInOrder.forEach(function (k) { + return _this.removeDataset(k); + }); }; + NewStylePlot.prototype.addDataset = function (keyOrDataset, dataset) { if (typeof (keyOrDataset) !== "string" && dataset !== undefined) { throw new Error("invalid input to addDataset"); @@ -2106,9 +3107,11 @@ var Plottable; var key = typeof (keyOrDataset) === "string" ? keyOrDataset : "_" + this.nextSeriesIndex++; var data = typeof (keyOrDataset) !== "string" ? keyOrDataset : dataset; var dataset = (data instanceof Plottable.DataSource) ? data : new Plottable.DataSource(data); + this._addDataset(key, dataset); return this; }; + NewStylePlot.prototype._addDataset = function (key, dataset) { var _this = this; if (this._key2DatasetDrawerKey[key] != null) { @@ -2119,15 +3122,20 @@ var Plottable; var ddk = { drawer: drawer, dataset: dataset, key: key }; this._datasetKeysInOrder.push(key); this._key2DatasetDrawerKey[key] = ddk; + if (this._isSetup) { drawer.renderArea = this.renderArea.append("g"); } - dataset.broadcaster.registerListener(this, function () { return _this._onDataSourceUpdate(); }); + dataset.broadcaster.registerListener(this, function () { + return _this._onDataSourceUpdate(); + }); this._onDataSourceUpdate(); }; + NewStylePlot.prototype._getDrawer = function (key) { throw new Error("Abstract Method Not Implemented"); }; + NewStylePlot.prototype._updateProjector = function (attr) { var _this = this; var projector = this._projectors[attr]; @@ -2137,13 +3145,13 @@ var Plottable; var scaleKey = _this._plottableID.toString() + "_" + ddk.key; if (extent.length === 0 || !_this._isAnchored) { projector.scale.removeExtent(scaleKey, attr); - } - else { + } else { projector.scale.updateExtent(scaleKey, attr, extent); } }); } }; + NewStylePlot.prototype.datasetOrder = function (order) { if (order === undefined) { return this._datasetKeysInOrder; @@ -2156,16 +3164,23 @@ var Plottable; if (isPermutation(order, this._datasetKeysInOrder)) { this._datasetKeysInOrder = order; this._onDataSourceUpdate(); - } - else { + } else { Plottable.Util.Methods.warn("Attempted to change datasetOrder, but new order is not permutation of old. Ignoring."); } return this; }; + + /** + * Removes a dataset + * + * @param {string} key The key of the dataset + * @return {NewStylePlot} The calling NewStylePlot. + */ NewStylePlot.prototype.removeDataset = function (key) { if (this._key2DatasetDrawerKey[key] != null) { var ddk = this._key2DatasetDrawerKey[key]; ddk.drawer.remove(); + var projectors = d3.values(this._projectors); var scaleKey = this._plottableID.toString() + "_" + key; projectors.forEach(function (p) { @@ -2173,6 +3188,7 @@ var Plottable; p.scale.removeExtent(scaleKey, p.attribute); } }); + ddk.dataset.broadcaster.deregisterListener(this); this._datasetKeysInOrder.splice(this._datasetKeysInOrder.indexOf(key), 1); delete this._key2DatasetDrawerKey[key]; @@ -2180,13 +3196,19 @@ var Plottable; } return this; }; + NewStylePlot.prototype._getDatasetsInOrder = function () { var _this = this; - return this._datasetKeysInOrder.map(function (k) { return _this._key2DatasetDrawerKey[k].dataset; }); + return this._datasetKeysInOrder.map(function (k) { + return _this._key2DatasetDrawerKey[k].dataset; + }); }; + NewStylePlot.prototype._getDrawersInOrder = function () { var _this = this; - return this._datasetKeysInOrder.map(function (k) { return _this._key2DatasetDrawerKey[k].drawer; }); + return this._datasetKeysInOrder.map(function (k) { + return _this._key2DatasetDrawerKey[k].drawer; + }); }; return NewStylePlot; })(Abstract.XYPlot); @@ -2195,6 +3217,7 @@ var Plottable; var Abstract = Plottable.Abstract; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Core) { @@ -2209,6 +3232,7 @@ var Plottable; return Immediate; })(); RenderPolicy.Immediate = Immediate; + var AnimationFrame = (function () { function AnimationFrame() { } @@ -2218,6 +3242,7 @@ var Plottable; return AnimationFrame; })(); RenderPolicy.AnimationFrame = AnimationFrame; + var Timeout = (function () { function Timeout() { this._timeoutMsec = Plottable.Util.DOM.POLYFILL_TIMEOUT_MSEC; @@ -2236,19 +3261,38 @@ 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; var _isCurrentlyFlushing = 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) { if (_isCurrentlyFlushing) { Plottable.Util.Methods.warn("Registered to render while other components are flushing: request may be ignored"); @@ -2257,42 +3301,69 @@ var Plottable; 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(); + }); + + // now we are flushing _isCurrentlyFlushing = true; + + // 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; _isCurrentlyFlushing = false; } + + // Reset resize flag regardless of queue'd components Core.ResizeBroadcaster.clearResizing(); } RenderController.flush = flush; @@ -2302,35 +3373,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); @@ -2343,94 +3453,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]; @@ -2438,15 +3640,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()); @@ -2459,17 +3666,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; @@ -2478,6 +3688,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; } @@ -2489,6 +3700,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; @@ -2499,23 +3716,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(); @@ -2523,10 +3758,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(); @@ -2534,29 +3776,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]; }; @@ -2567,6 +3830,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; } @@ -2581,6 +3845,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()); }; @@ -2591,6 +3860,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; } @@ -2609,9 +3879,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]; }; @@ -2623,6 +3899,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; } @@ -2634,8 +3911,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; @@ -2646,61 +3948,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); @@ -2713,12 +4065,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)); @@ -2728,17 +4096,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; } }; @@ -2749,6 +4119,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; } @@ -2760,10 +4131,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) { @@ -2774,31 +4151,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) { @@ -2807,16 +4192,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); } @@ -2831,6 +4217,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()); }; @@ -2841,6 +4233,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; } @@ -2852,6 +4245,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) { @@ -2884,6 +4285,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 = []; @@ -2899,6 +4301,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; } @@ -2911,28 +4314,40 @@ 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); } 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()); }; + Time.prototype._defaultExtent = function () { var endTime = new Date().valueOf(); var startTime = endTime - Plottable.MILLISECONDS_IN_ONE_DAY; @@ -2945,6 +4360,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; } @@ -2955,15 +4371,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) { @@ -2985,6 +4429,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."); @@ -2992,15 +4448,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; @@ -3009,6 +4471,7 @@ var Plottable; this._resetScale(); return this; }; + InterpolatedColor.prototype.scaleType = function (scaleType) { if (scaleType == null) { return this._scaleType; @@ -3017,26 +4480,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; }; @@ -3090,18 +4559,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) { @@ -3109,7 +4593,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; @@ -3119,18 +4605,35 @@ var Plottable; var Util = Plottable.Util; })(Plottable || (Plottable = {})); +/// var Plottable; (function (Plottable) { (function (Abstract) { var _Drawer = (function () { + /** + * Creates a Drawer + * + * @constructor + * @param{string} key The key associated with this Drawer + */ function _Drawer(key) { this.key = key; } + /** + * Removes the Drawer and its renderArea + */ _Drawer.prototype.remove = function () { if (this.renderArea != null) { this.renderArea.remove(); } }; + + /** + * Draws the data into the renderArea using the attrHash for attributes + * + * @param{any[][]} data The data to be drawn + * @param{attrHash} IAttributeToProjector The list of attributes to set on the data + */ _Drawer.prototype.draw = function (data, attrToProjector) { throw new Error("Abstract Method Not Implemented"); }; @@ -3141,6 +4644,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; } @@ -3158,6 +4662,7 @@ var Plottable; Rect.prototype.draw = function (data, attrToProjector) { var svgElement = "rect"; var dataElements = this.renderArea.selectAll(svgElement).data(data); + dataElements.enter().append(svgElement); dataElements.attr(attrToProjector); dataElements.exit().remove(); @@ -3169,6 +4674,7 @@ var Plottable; var _Drawer = Plottable._Drawer; })(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; } @@ -3181,9 +4687,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; @@ -3196,34 +4702,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._render(); }); + + this._scale.broadcaster.registerListener(this, function () { + return _this._render(); + }); } 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) { @@ -3232,8 +4749,7 @@ var Plottable; requestedHeight = this._computedHeight + this._gutter; } requestedWidth = 0; - } - else { + } else { if (this._width === "auto") { if (this._computedWidth == null) { this._computeWidth(); @@ -3242,6 +4758,7 @@ var Plottable; } requestedHeight = 0; } + return { width: requestedWidth, height: requestedHeight, @@ -3249,30 +4766,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); @@ -3283,6 +4809,7 @@ var Plottable; tickMarks.exit().remove(); this._baseline.attr(this._generateBaselineAttrHash()); }; + Axis.prototype._generateBaselineAttrHash = function () { var baselineAttrHash = { x1: 0, @@ -3290,73 +4817,88 @@ 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._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"); } @@ -3368,11 +4910,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"); } @@ -3384,6 +4926,7 @@ var Plottable; return this; } }; + Axis.prototype.formatter = function (formatter) { if (formatter === undefined) { return this._formatter; @@ -3392,11 +4935,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"); } @@ -3405,11 +4948,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"); } @@ -3418,19 +4961,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"); } @@ -3439,11 +4982,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"); } @@ -3452,11 +4995,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"); @@ -3466,6 +5009,7 @@ var Plottable; return this; } }; + Axis.prototype.showEndTickLabels = function (show) { if (show == null) { return this._showEndTickLabels; @@ -3474,12 +5018,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; @@ -3493,25 +5040,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); @@ -3520,6 +5070,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; } @@ -3530,8 +5081,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") { @@ -3551,30 +5110,43 @@ 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 this.measurer(d3.time.format(format)(longDate)).width; }; + Time.prototype.getIntervalLength = function (interval) { var startDate = this._scale.domain()[0]; var endDate = interval.timeUnit.offset(startDate, interval.step); if (endDate > this._scale.domain()[1]) { + // this offset is too large, so just return available width return this.availableWidth; } + + // measure how much space one date can get var stepLength = Math.abs(this._scale.scale(endDate) - this._scale.scale(startDate)); 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); this.measurer = Plottable.Util.Text.getTextMeasurer(this._majorTickLabels.append("text")); }; + + // returns a number to index into the major/minor intervals Time.prototype.getTickLevel = function () { for (var i = 0; i < Time.minorIntervals.length; i++) { if (this.isEnoughSpace(this._minorTickLabels, Time.minorIntervals[i]) && this.isEnoughSpace(this._majorTickLabels, Time.majorIntervals[i])) { @@ -3587,21 +5159,25 @@ var Plottable; } 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 = this.measurer(Plottable.Util.Text.HEIGHT_TEXT).height; fakeTickLabel.remove(); return textHeight; }; + Time.prototype.renderTickLabels = function (container, interval, height) { var _this = this; container.selectAll("." + Plottable.Abstract.Axis.TICK_LABEL_CLASS).remove(); @@ -3609,6 +5185,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) { @@ -3617,12 +5195,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(); @@ -3632,10 +5213,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; @@ -3643,33 +5229,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(); @@ -3680,7 +5275,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 = [ @@ -3714,6 +5313,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" }, @@ -3752,6 +5352,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; } @@ -3763,10 +5364,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; } @@ -3774,6 +5385,7 @@ var Plottable; _super.prototype._setup.call(this); this.measurer = Plottable.Util.Text.getTextMeasurer(this._tickLabelContainer.append("text").classed(Plottable.Abstract.Axis.TICK_LABEL_CLASS, true)); }; + Numeric.prototype._computeWidth = function () { var _this = this; var tickValues = this._getTickValues(); @@ -3781,39 +5393,49 @@ var Plottable; var formattedValue = _this._formatter(v); return _this.measurer(formattedValue).width; }); + 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 textHeight = this.measurer(Plottable.Util.Text.HEIGHT_TEXT).height; + 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; @@ -3834,8 +5456,7 @@ var Plottable; labelGroupShiftY = tickLabelPadding; break; } - } - else { + } else { switch (this.tickLabelPositioning) { case "top": tickLabelAttrHash["dy"] = "-0.3em"; @@ -3852,6 +5473,7 @@ var Plottable; break; } } + var tickMarkAttrHash = this._generateTickMarkAttrHash(); switch (this._orientation) { case "bottom": @@ -3859,46 +5481,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"); } @@ -3908,28 +5537,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"); } }; @@ -3940,6 +5566,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; } @@ -3951,35 +5578,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.append("text")); }; + Category.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var widthRequiredByTicks = this._isHorizontal() ? 0 : this._maxLabelTickLength() + this.tickLabelPadding() + this.gutter(); var heightRequiredByTicks = this._isHorizontal() ? this._maxLabelTickLength() + this.tickLabelPadding() + this.gutter() : 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, @@ -3987,19 +5630,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) { @@ -4011,24 +5664,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]; @@ -4039,15 +5703,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); }; @@ -4058,6 +5729,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; } @@ -4069,9 +5741,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); @@ -4084,8 +5763,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"); @@ -4104,10 +5782,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, @@ -4115,22 +5795,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.getTextMeasurer(this.textContainer.append("text")); 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(""); @@ -4138,19 +5820,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) { - this.measurer = Plottable.Util.Text.getTextMeasurer(this.textContainer.append("text")); + this.measurer = Plottable.Util.Text.getTextMeasurer(this.textContainer.append("text")); // reset it in case fonts have changed _super.prototype._computeLayout.call(this, xOffset, yOffset, availableWidth, availableHeight); return this; }; return Label; })(Plottable.Abstract.Component); Component.Label = Label; + var TitleLabel = (function (_super) { __extends(TitleLabel, _super); function TitleLabel(text, orientation) { @@ -4160,6 +5843,7 @@ var Plottable; return TitleLabel; })(Label); Component.TitleLabel = TitleLabel; + var AxisLabel = (function (_super) { __extends(AxisLabel, _super); function AxisLabel(text, orientation) { @@ -4173,6 +5857,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; } @@ -4184,6 +5869,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); @@ -4199,6 +5895,7 @@ var Plottable; this.colorScale.broadcaster.deregisterListener(this); } }; + Legend.prototype.toggleCallback = function (callback) { if (callback !== undefined) { this._toggleCallback = callback; @@ -4206,11 +5903,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; @@ -4218,11 +5915,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) { @@ -4230,14 +5927,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())); @@ -4247,19 +5946,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 measure = Plottable.Util.Text.getTextMeasurer(fakeLegendEl.append("text")); - var maxWidth = d3.max(this.colorScale.domain(), function (d) { return measure(d).width; }); + var maxWidth = d3.max(this.colorScale.domain(), function (d) { + return measure(d).width; + }); fakeLegendEl.remove(); maxWidth = maxWidth === undefined ? 0 : maxWidth; var desiredWidth = rowsICanFit === 0 ? 0 : maxWidth + textHeight + 2 * Legend.MARGIN; @@ -4271,26 +5974,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.getTextMeasurer(fakeLegendEl.append("text"))(Plottable.Util.Text.HEIGHT_TEXT).height; + + // 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); @@ -4299,12 +6012,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) { @@ -4312,35 +6028,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) { @@ -4348,18 +6069,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); } @@ -4373,6 +6098,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; } @@ -4384,9 +6110,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"); } @@ -4394,10 +6127,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 () { @@ -4410,35 +6147,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(); } }; @@ -4449,6 +6198,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; } @@ -4460,6 +6210,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 = { @@ -4467,9 +6225,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; @@ -4477,21 +6237,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(); }; @@ -4502,6 +6269,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; } @@ -4513,16 +6281,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); @@ -4531,15 +6312,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(); }; @@ -4550,6 +6340,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; } @@ -4559,8 +6350,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; @@ -4571,7 +6374,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 () { @@ -4579,34 +6388,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(); @@ -4614,6 +6441,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; @@ -4621,83 +6457,103 @@ 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._updateYDomainer = function () { if (this._isVertical) { this._updateDomainer(this.yScale); - } - else { + } else { _super.prototype._updateYDomainer.call(this); } }; + BarPlot.prototype._updateXDomainer = function () { if (!this._isVertical) { this._updateDomainer(this.xScale); - } - else { + } else { _super.prototype._updateXDomainer.call(this); } }; + 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; @@ -4707,28 +6563,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); @@ -4737,6 +6607,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; } @@ -4746,8 +6617,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; @@ -4763,6 +6651,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; } @@ -4772,8 +6661,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; @@ -4781,8 +6687,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; @@ -4796,6 +6706,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; } @@ -4807,6 +6718,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 = { @@ -4814,27 +6733,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(); @@ -4847,14 +6777,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(); @@ -4862,14 +6792,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"]; }; @@ -4880,6 +6814,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; } @@ -4889,15 +6824,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"); } @@ -4905,29 +6857,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") { @@ -4935,9 +6893,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(); @@ -4947,14 +6907,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"); @@ -4967,6 +6931,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; } @@ -4978,6 +6943,13 @@ var Plottable; (function (Abstract) { var NewStyleBarPlot = (function (_super) { __extends(NewStyleBarPlot, _super); + /** + * Creates an NewStyleBarPlot. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function NewStyleBarPlot(xScale, yScale) { _super.call(this, xScale, yScale); this._baselineValue = 0; @@ -4988,18 +6960,25 @@ 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; + }); + + // super() doesn't set baseline this.baseline(this._baselineValue); } NewStyleBarPlot.prototype._getDrawer = function (key) { return new Plottable._Drawer.Rect(key); }; + NewStyleBarPlot.prototype._setup = function () { _super.prototype._setup.call(this); this._baseline = this.renderArea.append("line").classed("baseline", true); }; + NewStyleBarPlot.prototype._paint = function () { _super.prototype._paint.call(this); + var primaryScale = this._isVertical ? this.yScale : this.xScale; var scaledBaseline = primaryScale.scale(this._baselineValue); var baselineAttr = { @@ -5010,15 +6989,25 @@ var Plottable; }; 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 {NewStyleBarPlot} The calling NewStyleBarPlot. + */ NewStyleBarPlot.prototype.baseline = function (value) { return Abstract.BarPlot.prototype.baseline.apply(this, [value]); }; + NewStyleBarPlot.prototype._updateDomainer = function (scale) { return Abstract.BarPlot.prototype._updateDomainer.apply(this, [scale]); }; + NewStyleBarPlot.prototype._generateAttrToProjector = function () { return Abstract.BarPlot.prototype._generateAttrToProjector.apply(this); }; + NewStyleBarPlot.prototype._updateXDomainer = function () { return Abstract.BarPlot.prototype._updateXDomainer.apply(this); }; @@ -5034,6 +7023,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; } @@ -5053,23 +7043,35 @@ var Plottable; ClusteredBar.prototype._generateAttrToProjector = function () { var _this = this; var attrToProjector = _super.prototype._generateAttrToProjector.call(this); + + // the width is constant, so set the inner scale range to that var widthF = attrToProjector["width"]; this.innerScale.range([0, widthF(null, 0)]); - attrToProjector["width"] = function (d, i) { return _this.innerScale.rangeBand(); }; - attrToProjector["x"] = function (d) { return d._PLOTTABLE_PROTECTED_FIELD_X; }; + attrToProjector["width"] = function (d, i) { + return _this.innerScale.rangeBand(); + }; + attrToProjector["x"] = function (d) { + return d._PLOTTABLE_PROTECTED_FIELD_X; + }; return attrToProjector; }; + ClusteredBar.prototype.cluster = function (accessor) { var _this = this; this.innerScale.domain(this._datasetKeysInOrder); - var lengths = this._getDatasetsInOrder().map(function (d) { return d.data().length; }); + var lengths = this._getDatasetsInOrder().map(function (d) { + return d.data().length; + }); if (Plottable.Util.Methods.uniqNumbers(lengths).length > 1) { Plottable.Util.Methods.warn("Warning: Attempting to cluster data when datasets are of unequal length"); } var clusters = {}; this._datasetKeysInOrder.forEach(function (key) { var data = _this._key2DatasetDrawerKey[key].dataset.data(); - var vals = data.map(function (d) { return accessor(d); }); + var vals = data.map(function (d) { + return accessor(d); + }); + clusters[key] = data.map(function (d, i) { d["_PLOTTABLE_PROTECTED_FIELD_X"] = _this.xScale.scale(vals[i]) + _this.innerScale.scale(key); return d; @@ -5077,12 +7079,15 @@ var Plottable; }); return clusters; }; + ClusteredBar.prototype._paint = function () { _super.prototype._paint.call(this); var accessor = this._projectors["x"].accessor; var attrHash = this._generateAttrToProjector(); var clusteredData = this.cluster(accessor); - this._getDrawersInOrder().forEach(function (d) { return d.draw(clusteredData[d.key], attrHash); }); + this._getDrawersInOrder().forEach(function (d) { + return d.draw(clusteredData[d.key], attrHash); + }); }; ClusteredBar.DEFAULT_WIDTH = 10; return ClusteredBar; @@ -5092,6 +7097,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; } @@ -5114,6 +7120,7 @@ var Plottable; _super.prototype._addDataset.call(this, key, dataset); this.stackedData = this.stack(this._projectors["y"].accessor); }; + StackedBar.prototype._updateAllProjectors = function () { _super.prototype._updateAllProjectors.call(this); if (this.yScale == null) { @@ -5121,23 +7128,34 @@ var Plottable; } if (this._isAnchored && this.stackedExtent.length > 0) { this.yScale.updateExtent(this._plottableID.toString(), "_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT", this.stackedExtent); - } - else { + } else { this.yScale.removeExtent(this._plottableID.toString(), "_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT"); } }; + StackedBar.prototype._generateAttrToProjector = function () { var attrToProjector = _super.prototype._generateAttrToProjector.call(this); var primaryScale = this._isVertical ? this.yScale : this.xScale; - var getY0 = function (d) { return primaryScale.scale(d._PLOTTABLE_PROTECTED_FIELD_Y0); }; - var getY = function (d) { return primaryScale.scale(d._PLOTTABLE_PROTECTED_FIELD_Y); }; - attrToProjector["height"] = function (d) { return Math.abs(getY(d) - getY0(d)); }; - attrToProjector["y"] = function (d) { return getY(d); }; + var getY0 = function (d) { + return primaryScale.scale(d._PLOTTABLE_PROTECTED_FIELD_Y0); + }; + var getY = function (d) { + return primaryScale.scale(d._PLOTTABLE_PROTECTED_FIELD_Y); + }; + attrToProjector["height"] = function (d) { + return Math.abs(getY(d) - getY0(d)); + }; + attrToProjector["y"] = function (d) { + return getY(d); + }; return attrToProjector; }; + StackedBar.prototype.stack = function (accessor) { var datasets = d3.values(this._key2DatasetDrawerKey); - var lengths = datasets.map(function (d) { return d.dataset.data().length; }); + var lengths = datasets.map(function (d) { + return d.dataset.data().length; + }); if (Plottable.Util.Methods.uniqNumbers(lengths).length > 1) { Plottable.Util.Methods.warn("Warning: Attempting to stack data when datasets are of unequal length"); } @@ -5146,10 +7164,13 @@ var Plottable; var data = dataset.data(); var base = currentBase.slice(); var vals = data.map(accessor); - if (vals.some(function (x) { return x < 0; })) { + if (vals.some(function (x) { + return x < 0; + })) { Plottable.Util.Methods.warn("Warning: Behavior for stacked bars undefined when data includes negative values"); } currentBase = Plottable.Util.Methods.addArrays(base, vals); + return data.map(function (d, i) { d["_PLOTTABLE_PROTECTED_FIELD_Y0"] = base[i]; d["_PLOTTABLE_PROTECTED_FIELD_Y"] = currentBase[i]; @@ -5160,10 +7181,13 @@ var Plottable; this._onDataSourceUpdate(); return stacks; }; + StackedBar.prototype._paint = function () { var _this = this; var attrHash = this._generateAttrToProjector(); - this._getDrawersInOrder().forEach(function (d, i) { return d.draw(_this.stackedData[i], attrHash); }); + this._getDrawersInOrder().forEach(function (d, i) { + return d.draw(_this.stackedData[i], attrHash); + }); }; return StackedBar; })(Plottable.Abstract.NewStyleBarPlot); @@ -5172,9 +7196,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() { } @@ -5188,9 +7217,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; @@ -5200,29 +7233,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; } @@ -5234,6 +7267,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; } @@ -5243,6 +7277,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() { @@ -5251,7 +7291,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); @@ -5260,12 +7302,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; @@ -5274,20 +7318,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); }); @@ -5298,10 +7347,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"); @@ -5311,6 +7367,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; @@ -5322,6 +7383,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; } @@ -5333,6 +7395,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); } @@ -5346,9 +7414,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; @@ -5356,8 +7431,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); } @@ -5371,6 +7453,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; } @@ -5395,6 +7478,7 @@ var Plottable; _this.mousemove(x, y); }); }; + Mousemove.prototype.mousemove = function (x, y) { return; }; @@ -5405,6 +7489,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; } @@ -5416,6 +7501,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; @@ -5430,12 +7522,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; @@ -5447,6 +7546,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; } @@ -5458,9 +7558,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(); } @@ -5472,21 +7580,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); @@ -5499,6 +7616,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; } @@ -5510,6 +7628,11 @@ var Plottable; (function (Interaction) { var BarHover = (function (_super) { __extends(BarHover, _super); + /** + * Creates a new BarHover Interaction. + * + * @param {Abstract.BarPlot} barPlot The Bar Plot to listen for hover events on. + */ function BarHover(barPlot) { _super.call(this, barPlot); this.plotIsVertical = true; @@ -5520,65 +7643,92 @@ var Plottable; BarHover.prototype._anchor = function (hitBox) { var _this = this; this.dispatcher = new Plottable.Dispatcher.Mouse(hitBox); + this.dispatcher.mousemove(function (p) { var selectedBar = _this.getHoveredBar(p); + if (selectedBar == null) { _this._hoverOut(); - } - else { + } else { if (_this.currentBar != null) { if (_this.currentBar.node() === selectedBar.node()) { return; - } - else { + } else { _this._hoverOut(); } } + _this.componentToListenTo._bars.classed("not-hovered", true).classed("hovered", false); selectedBar.classed("not-hovered", false).classed("hovered", true); if (_this.hoverCallback != null) { _this.hoverCallback(selectedBar.data()[0], selectedBar); } } + _this.currentBar = selectedBar; }); - this.dispatcher.mouseout(function (p) { return _this._hoverOut(); }); + + this.dispatcher.mouseout(function (p) { + return _this._hoverOut(); + }); + this.dispatcher.connect(); }; + BarHover.prototype._hoverOut = function () { this.componentToListenTo._bars.classed("not-hovered hovered", false); if (this.unhoverCallback != null && this.currentBar != null) { - this.unhoverCallback(this.currentBar.data()[0], this.currentBar); + this.unhoverCallback(this.currentBar.data()[0], this.currentBar); // last known information } this.currentBar = null; }; + BarHover.prototype.getHoveredBar = function (p) { if (this._hoverMode === "point") { return this.componentToListenTo.selectBar(p.x, p.y, false); } + var maxExtent = { min: -Infinity, max: Infinity }; if (this.plotIsVertical) { return this.componentToListenTo.selectBar(p.x, maxExtent, false); - } - else { + } else { return this.componentToListenTo.selectBar(maxExtent, p.y, false); } }; + BarHover.prototype.hoverMode = function (mode) { if (mode == null) { return this._hoverMode; } + var modeLC = mode.toLowerCase(); if (modeLC !== "point" && modeLC !== "line") { throw new Error(mode + " is not a valid hover mode for Interaction.BarHover"); } + this._hoverMode = modeLC; return this; }; + + /** + * Attaches an callback to be called when the user mouses over a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} The callback to be called. + * The callback will be passed the data from the hovered-over bar. + * @return {BarHover} The calling Interaction.BarHover. + */ BarHover.prototype.onHover = function (callback) { this.hoverCallback = callback; return this; }; + + /** + * Attaches a callback to be called when the user mouses off of a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} The callback to be called. + * The callback will be passed the data from the last-hovered bar. + * @return {BarHover} The calling Interaction.BarHover. + */ BarHover.prototype.onUnhover = function (callback) { this.unhoverCallback = callback; return this; @@ -5590,6 +7740,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; } @@ -5601,65 +7752,86 @@ 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(); + }); } Drag.prototype.dragstart = function (cb) { if (cb === undefined) { return this.ondragstart; - } - else { + } else { this.ondragstart = cb; return this; } }; + Drag.prototype.drag = function (cb) { if (cb === undefined) { return this.ondrag; - } - else { + } else { this.ondrag = cb; return this; } }; + Drag.prototype.dragend = function (cb) { if (cb === undefined) { return this.ondragend; - } - else { + } else { this.ondragend = 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._doDragstart = function () { if (this.ondragstart != null) { this.ondragstart({ x: this.origin[0], y: this.origin[1] }); } }; + Drag.prototype._drag = function () { if (!this.dragInitialized) { this.origin = [d3.event.x, d3.event.y]; this.dragInitialized = true; this._doDragstart(); } + this.location = [this.constrainX(d3.event.x), this.constrainY(d3.event.y)]; this._doDrag(); }; + Drag.prototype._doDrag = function () { if (this.ondrag != null) { var startLocation = { x: this.origin[0], y: this.origin[1] }; @@ -5667,6 +7839,7 @@ var Plottable; this.ondrag(startLocation, endLocation); } }; + Drag.prototype._dragend = function () { if (!this.dragInitialized) { return; @@ -5674,6 +7847,7 @@ var Plottable; this.dragInitialized = false; this._doDragend(); }; + Drag.prototype._doDragend = function () { if (this.ondragend != null) { var startLocation = { x: this.origin[0], y: this.origin[1] }; @@ -5681,11 +7855,13 @@ var Plottable; this.ondragend(startLocation, endLocation); } }; + 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; @@ -5724,6 +7900,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; } @@ -5743,6 +7920,12 @@ var Plottable; _super.prototype._dragstart.call(this); 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; @@ -5751,6 +7934,7 @@ var Plottable; this.boxIsDrawn = false; return this; }; + DragBox.prototype.setBox = function (x0, x1, y0, y1) { if (this.dragBox == null) { return; @@ -5763,6 +7947,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; @@ -5778,6 +7963,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; } @@ -5796,6 +7982,7 @@ var Plottable; _super.prototype._drag.call(this); this.setBox(this.origin[0], this.location[0]); }; + XDragBox.prototype.setBox = function (x0, x1) { _super.prototype.setBox.call(this, x0, x1, 0, this.componentToListenTo.availableHeight); return this; @@ -5807,6 +7994,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; } @@ -5832,6 +8020,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; } @@ -5850,6 +8039,7 @@ var Plottable; _super.prototype._drag.call(this); this.setBox(this.origin[1], this.location[1]); }; + YDragBox.prototype.setBox = function (y0, y1) { _super.prototype.setBox.call(this, 0, this.componentToListenTo.availableWidth, y0, y1); return this; @@ -5861,6 +8051,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; } @@ -5872,6 +8063,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 = {}; @@ -5886,13 +8082,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) { @@ -5903,8 +8110,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; @@ -5920,6 +8134,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; } @@ -5931,19 +8146,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()); @@ -5957,6 +8180,7 @@ var Plottable; y: xy[1] }; }; + Mouse.prototype.mouseover = function (callback) { if (callback === undefined) { return this._mouseover; @@ -5964,6 +8188,7 @@ var Plottable; this._mouseover = callback; return this; }; + Mouse.prototype.mousemove = function (callback) { if (callback === undefined) { return this._mousemove; @@ -5971,6 +8196,7 @@ var Plottable; this._mousemove = callback; return this; }; + Mouse.prototype.mouseout = function (callback) { if (callback === undefined) { return this._mouseout; @@ -5985,6 +8211,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; } @@ -6012,11 +8239,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) { @@ -6025,19 +8252,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!"); } } @@ -6047,19 +8273,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!"); } } @@ -6069,19 +8294,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!"); } } @@ -6091,11 +8315,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 4fce561909..51a173e545 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){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 +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 i(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 j(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,j={left:"bottom",right:"top",center:"center",top:"left",bottom:"right"},k={left:"top",right:"bottom",center:"center",top:"right",bottom:"left"},l=h?j:k,m=b.append("g"),n=i(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 k(d,e,f,g,h,j){"undefined"==typeof h&&(h="left"),"undefined"==typeof j&&(j="top");var k=c(e.append("text"))(b.HEIGHT_TEXT).height,l=0,m=e.append("g");d.forEach(function(b,c){var d=m.append("g");a.DOM.translate(d,0,c*k);var e=i(b,d,f,k,h,j);e.width>l&&(l=e.width)});var n=k*d.length,o=g-n,p={center:.5,top:0,bottom:1};return a.DOM.translate(m,0,o*p[j]),{width:l,height:n}}function l(d,e,f,g,h,i,k){"undefined"==typeof h&&(h="left"),"undefined"==typeof i&&(i="top"),"undefined"==typeof k&&(k="left");var l=c(e.append("text"))(b.HEIGHT_TEXT).height,m=0,n=e.append("g");d.forEach(function(b,c){var d=n.append("g");a.DOM.translate(d,c*l,0);var e=j(b,d,l,g,h,i,k);e.height>m&&(m=e.height)});var o=l*d.length,p=f-o,q={center:.5,left:0,right:1};return a.DOM.translate(n,p*q[h],0),{width:o,height:m}}function m(b,c,d,e,f,g){var h=null!=f?f:1.1*c>d,i=h?c:d,j=h?d:c,m=a.WordWrap.breakTextToFitRect(b,i,j,e);if(0===m.lines.length)return{textFits:m.textFits,usedWidth:0,usedHeight:0};var n,o;if(null==g){var p=h?d3.max:d3.sum,q=h?d3.sum:d3.max;n=p(m.lines,function(a){return e(a).width}),o=q(m.lines,function(a){return e(a).height})}else{var r=g.g.append("g").classed("writeText-inner-g",!0),s=h?k:l,t=s(m.lines,r,c,d,g.xAlign,g.yAlign);n=t.width,o=t.height}return{textFits:m.textFits,usedWidth:n,usedHeight:o}}b.HEIGHT_TEXT="bqpdl",b.getTextMeasurer=c;var n="a",o=function(){function b(b){var g=this;this.cache=new a.Cache(c(b),n,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=o,b.getTruncatedText=g,b._addEllipsesToLine=h,b.writeLineHorizontally=i,b.writeLineVertically=j,b.writeText=m}(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=100*a,f=a.toString(),g=Math.pow(10,f.length-(f.indexOf(".")+1));e=parseInt((e*g).toString(),10)/g;var h=d(e);return c&&b._valueChanged(e,h)?"":(""!==h&&(h+="%"),h)}},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.25.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.toString(),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,attribute:b},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;d3.keys(this._projectors).forEach(function(b){return a._updateProjector(b)})},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.toString(),a,c):b.scale.removeExtent(this._plottableID.toString(),a)}},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 __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){b.call(this,new a.DataSource,c,d),this.nextSeriesIndex=0,this._key2DatasetDrawerKey={},this._datasetKeysInOrder=[]}return __extends(c,b),c.prototype._setup=function(){var a=this;b.prototype._setup.call(this),this._getDrawersInOrder().forEach(function(b){return b.renderArea=a.renderArea.append("g")})},c.prototype.remove=function(){var a=this;b.prototype.remove.call(this),this._datasetKeysInOrder.forEach(function(b){return a.removeDataset(b)})},c.prototype.addDataset=function(b,c){if("string"!=typeof b&&void 0!==c)throw new Error("invalid input to addDataset");"string"==typeof b&&"_"===b[0]&&a.Util.Methods.warn("Warning: Using _named series keys may produce collisions with unlabeled data sources");var d="string"==typeof b?b:"_"+this.nextSeriesIndex++,e="string"!=typeof b?b:c,c=e instanceof a.DataSource?e:new a.DataSource(e);return this._addDataset(d,c),this},c.prototype._addDataset=function(a,b){var c=this;null!=this._key2DatasetDrawerKey[a]&&this.removeDataset(a);var d=this._getDrawer(a),e={drawer:d,dataset:b,key:a};this._datasetKeysInOrder.push(a),this._key2DatasetDrawerKey[a]=e,this._isSetup&&(d.renderArea=this.renderArea.append("g")),b.broadcaster.registerListener(this,function(){return c._onDataSourceUpdate()}),this._onDataSourceUpdate()},c.prototype._getDrawer=function(){throw new Error("Abstract Method Not Implemented")},c.prototype._updateProjector=function(a){var b=this,c=this._projectors[a];null!=c.scale&&d3.values(this._key2DatasetDrawerKey).forEach(function(d){var e=d.dataset._getExtent(c.accessor),f=b._plottableID.toString()+"_"+d.key;0!==e.length&&b._isAnchored?c.scale.updateExtent(f,a,e):c.scale.removeExtent(f,a)})},c.prototype.datasetOrder=function(b){function c(b,c){var d=a.Util.Methods.intersection(d3.set(b),d3.set(c)),e=d.size();return e===b.length&&e===c.length}return void 0===b?this._datasetKeysInOrder:(c(b,this._datasetKeysInOrder)?(this._datasetKeysInOrder=b,this._onDataSourceUpdate()):a.Util.Methods.warn("Attempted to change datasetOrder, but new order is not permutation of old. Ignoring."),this)},c.prototype.removeDataset=function(a){if(null!=this._key2DatasetDrawerKey[a]){var b=this._key2DatasetDrawerKey[a];b.drawer.remove();var c=d3.values(this._projectors),d=this._plottableID.toString()+"_"+a;c.forEach(function(a){null!=a.scale&&a.scale.removeExtent(d,a.attribute)}),b.dataset.broadcaster.deregisterListener(this),this._datasetKeysInOrder.splice(this._datasetKeysInOrder.indexOf(a),1),delete this._key2DatasetDrawerKey[a],this._onDataSourceUpdate()}return this},c.prototype._getDatasetsInOrder=function(){var a=this;return this._datasetKeysInOrder.map(function(b){return a._key2DatasetDrawerKey[b].dataset})},c.prototype._getDrawersInOrder=function(){var a=this;return this._datasetKeysInOrder.map(function(b){return a._key2DatasetDrawerKey[b].drawer})},c}(b.XYPlot);b.NewStylePlot=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(b){!function(c){function d(a){c._renderPolicy=a}function e(b){l&&a.Util.Methods.warn("Registered to render while other components are flushing: request may be ignored"),i[b._plottableID]=b,g()}function f(a){j[a._plottableID]=a,i[a._plottableID]=a,g()}function g(){k||(k=!0,c._renderPolicy.render())}function h(){if(k){var a=d3.values(j);a.forEach(function(a){return a._computeLayout()});var c=d3.values(i);c.forEach(function(a){return a._render()}),l=!0;var d={};Object.keys(i).forEach(function(a){try{i[a]._doRender()}catch(b){setTimeout(function(){throw b},0),d[a]=i[a]}}),j={},i=d,k=!1,l=!1}b.ResizeBroadcaster.clearResizing()}var i={},j={},k=!1,l=!1;c._renderPolicy=new c.RenderPolicy.AnimationFrame,c.setRenderPolicy=d,c.registerToRender=e,c.registerToComputeLayout=f,c.flush=h}(b.RenderController||(b.RenderController={}));b.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(b){function c(a){b.call(this,null==a?d3.time.scale():a)}return __extends(c,b),c.prototype.tickInterval=function(a,b){var c=d3.time.scale();return c.domain(this.domain()),c.range(this.range()),c.ticks(a.range,b)},c.prototype.domain=function(a){return null==a?b.prototype.domain.call(this):("string"==typeof a[0]&&(a=a.map(function(a){return new Date(a)})),b.prototype.domain.call(this,a))},c.prototype.copy=function(){return new c(this._d3Scale.copy())},c.prototype._defaultExtent=function(){var b=(new Date).valueOf(),c=b-a.MILLISECONDS_IN_ONE_DAY;return[c,b]},c}(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 Plottable;!function(a){!function(a){var b=function(){function a(a){this.key=a}return a.prototype.remove=function(){null!=this.renderArea&&this.renderArea.remove()},a.prototype.draw=function(){throw new Error("Abstract Method Not Implemented")},a}();a._Drawer=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.apply(this,arguments)}return __extends(b,a),b.prototype.draw=function(a,b){var c="rect",d=this.renderArea.selectAll(c).data(a);d.enter().append(c),d.attr(b),d.exit().remove()},b}(a.Abstract._Drawer);b.Rect=c}(a._Drawer||(a._Drawer={}));a._Drawer}(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._render()})}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._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,c){if(c=c.toLowerCase(),"top"!==c&&"bottom"!==c)throw new Error("unsupported orientation: "+c);b.call(this,a,c),this.classed("time-axis",!0),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(a,b){var c=new Date(9999,8,29,12,59,9999);return this.measurer(d3.time.format(b)(c)).width},c.prototype.getIntervalLength=function(a){var b=this._scale.domain()[0],c=a.timeUnit.offset(b,a.step);if(c>this._scale.domain()[1])return this.availableWidth;var d=Math.abs(this._scale.scale(c)-this._scale.scale(b));return d},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),this.measurer=a.Util.Text.getTextMeasurer(this._majorTickLabels.append("text"))},c.prototype.getTickLevel=function(){for(var b=0;b=c.minorIntervals.length&&(a.Util.Methods.warn("zoomed out too far: could not find suitable interval to display labels"),b=c.minorIntervals.length-1),b},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=this.measurer(a.Util.Text.HEIGHT_TEXT).height;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(a,b,c,d){var e,f,g=this.measurer(c).width+this.tickLabelPadding();return d?(e=this._scale.scale(b)+g/2,f=this._scale.scale(b)-g/2):(e=this._scale.scale(b)+g,f=this._scale.scale(b)),e0},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._setup=function(){b.prototype._setup.call(this),this.measurer=a.Util.Text.getTextMeasurer(this._tickLabelContainer.append("text").classed(a.Abstract.Axis.TICK_LABEL_CLASS,!0))},c.prototype._computeWidth=function(){var a=this,b=this._getTickValues(),c=b.map(function(b){var c=a._formatter(b);return a.measurer(c).width}),d=d3.max(c);return this._computedWidth="center"===this.tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+d:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+d),this._computedWidth},c.prototype._computeHeight=function(){var b=this.measurer(a.Util.Text.HEIGHT_TEXT).height;return this._computedHeight="center"===this.tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+b:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+b),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.append("text"))},c.prototype._requestedSpace=function(a,b){var c=this._isHorizontal()?0:this._maxLabelTickLength()+this.tickLabelPadding()+this.gutter(),d=this._isHorizontal()?this._maxLabelTickLength()+this.tickLabelPadding()+this.gutter():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.getTextMeasurer(this.textContainer.append("text")),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 this.measurer=a.Util.Text.getTextMeasurer(this.textContainer.append("text")),b.prototype._computeLayout.call(this,c,d,e,f),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=a.Util.Text.getTextMeasurer(h.append("text")),j=d3.max(this.colorScale.domain(),function(a){return i(a).width});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.getTextMeasurer(b.append("text"))(a.Util.Text.HEIGHT_TEXT).height;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.getTextMeasurer(c.append("text")),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(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._updateYDomainer=function(){this._isVertical?this._updateDomainer(this.yScale):c.prototype._updateYDomainer.call(this)},d.prototype._updateXDomainer=function(){this._isVertical?c.prototype._updateXDomainer.call(this):this._updateDomainer(this.xScale)},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 __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){c.call(this,b,d),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._getDrawer=function(b){return new a._Drawer.Rect(b)},d.prototype._setup=function(){c.prototype._setup.call(this),this._baseline=this.renderArea.append("line").classed("baseline",!0)},d.prototype._paint=function(){c.prototype._paint.call(this);var a=this._isVertical?this.yScale:this.xScale,b=a.scale(this._baselineValue),d={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",d)},d.prototype.baseline=function(a){return b.BarPlot.prototype.baseline.apply(this,[a])},d.prototype._updateDomainer=function(a){return b.BarPlot.prototype._updateDomainer.apply(this,[a])},d.prototype._generateAttrToProjector=function(){return b.BarPlot.prototype._generateAttrToProjector.apply(this)},d.prototype._updateXDomainer=function(){return b.BarPlot.prototype._updateXDomainer.apply(this)},d.prototype._updateYDomainer=function(){return b.BarPlot.prototype._updateYDomainer.apply(this)},d._barAlignmentToFactor={},d.DEFAULT_WIDTH=10,d}(b.NewStylePlot);b.NewStyleBarPlot=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){b.call(this,c,d),this._isVertical=!0,this.innerScale=new a.Scale.Ordinal}return __extends(c,b),c.prototype._generateAttrToProjector=function(){var a=this,c=b.prototype._generateAttrToProjector.call(this),d=c.width;return this.innerScale.range([0,d(null,0)]),c.width=function(){return a.innerScale.rangeBand()},c.x=function(a){return a._PLOTTABLE_PROTECTED_FIELD_X},c},c.prototype.cluster=function(b){var c=this;this.innerScale.domain(this._datasetKeysInOrder);var d=this._getDatasetsInOrder().map(function(a){return a.data().length});a.Util.Methods.uniqNumbers(d).length>1&&a.Util.Methods.warn("Warning: Attempting to cluster data when datasets are of unequal length");var e={};return this._datasetKeysInOrder.forEach(function(a){var d=c._key2DatasetDrawerKey[a].dataset.data(),f=d.map(function(a){return b(a)});e[a]=d.map(function(b,d){return b._PLOTTABLE_PROTECTED_FIELD_X=c.xScale.scale(f[d])+c.innerScale.scale(a),b})}),e},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._projectors.x.accessor,c=this._generateAttrToProjector(),d=this.cluster(a);this._getDrawersInOrder().forEach(function(a){return a.draw(d[a.key],c)})},c.DEFAULT_WIDTH=10,c}(a.Abstract.NewStyleBarPlot);b.ClusteredBar=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(a,c){b.call(this,a,c),this.stackedData=[],this._isVertical=!0,this._baselineValue=0,this.stackedExtent=[]}return __extends(c,b),c.prototype._addDataset=function(a,c){b.prototype._addDataset.call(this,a,c),this.stackedData=this.stack(this._projectors.y.accessor)},c.prototype._updateAllProjectors=function(){b.prototype._updateAllProjectors.call(this),null!=this.yScale&&(this._isAnchored&&this.stackedExtent.length>0?this.yScale.updateExtent(this._plottableID.toString(),"_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT",this.stackedExtent):this.yScale.removeExtent(this._plottableID.toString(),"_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT"))},c.prototype._generateAttrToProjector=function(){var a=b.prototype._generateAttrToProjector.call(this),c=this._isVertical?this.yScale:this.xScale,d=function(a){return c.scale(a._PLOTTABLE_PROTECTED_FIELD_Y0)},e=function(a){return c.scale(a._PLOTTABLE_PROTECTED_FIELD_Y)};return a.height=function(a){return Math.abs(e(a)-d(a))},a.y=function(a){return e(a)},a},c.prototype.stack=function(b){var c=d3.values(this._key2DatasetDrawerKey),d=c.map(function(a){return a.dataset.data().length});a.Util.Methods.uniqNumbers(d).length>1&&a.Util.Methods.warn("Warning: Attempting to stack data when datasets are of unequal length");var e=a.Util.Methods.createFilledArray(0,d[0]),f=this._getDatasetsInOrder().map(function(c){var d=c.data(),f=e.slice(),g=d.map(b);return g.some(function(a){return 0>a})&&a.Util.Methods.warn("Warning: Behavior for stacked bars undefined when data includes negative values"),e=a.Util.Methods.addArrays(f,g),d.map(function(a,b){return a._PLOTTABLE_PROTECTED_FIELD_Y0=f[b],a._PLOTTABLE_PROTECTED_FIELD_Y=e[b],a})});return this.stackedExtent=[0,d3.max(e)],this._onDataSourceUpdate(),f},c.prototype._paint=function(){var a=this,b=this._generateAttrToProjector();this._getDrawersInOrder().forEach(function(c,d){return c.draw(a.stackedData[d],b)})},c}(a.Abstract.NewStyleBarPlot);b.StackedBar=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(b){function c(c){b.call(this,c),this.plotIsVertical=!0,this.currentBar=null,this._hoverMode="point",this.plotIsVertical=a.Plot.VerticalBar.prototype.isPrototypeOf(this.componentToListenTo)}return __extends(c,b),c.prototype._anchor=function(b){var c=this;this.dispatcher=new a.Dispatcher.Mouse(b),this.dispatcher.mousemove(function(a){var b=c.getHoveredBar(a);if(null==b)c._hoverOut();else{if(null!=c.currentBar){if(c.currentBar.node()===b.node())return;c._hoverOut()}c.componentToListenTo._bars.classed("not-hovered",!0).classed("hovered",!1),b.classed("not-hovered",!1).classed("hovered",!0),null!=c.hoverCallback&&c.hoverCallback(b.data()[0],b)}c.currentBar=b}),this.dispatcher.mouseout(function(){return c._hoverOut()}),this.dispatcher.connect()},c.prototype._hoverOut=function(){this.componentToListenTo._bars.classed("not-hovered hovered",!1),null!=this.unhoverCallback&&null!=this.currentBar&&this.unhoverCallback(this.currentBar.data()[0],this.currentBar),this.currentBar=null},c.prototype.getHoveredBar=function(a){if("point"===this._hoverMode)return this.componentToListenTo.selectBar(a.x,a.y,!1);var b={min:-1/0,max:1/0};return this.plotIsVertical?this.componentToListenTo.selectBar(a.x,b,!1):this.componentToListenTo.selectBar(b,a.y,!1)},c.prototype.hoverMode=function(a){if(null==a)return this._hoverMode;var b=a.toLowerCase();if("point"!==b&&"line"!==b)throw new Error(a+" is not a valid hover mode for Interaction.BarHover");return this._hoverMode=b,this},c.prototype.onHover=function(a){return this.hoverCallback=a,this},c.prototype.onUnhover=function(a){return this.unhoverCallback=a,this},c}(a.Abstract.Interaction);b.BarHover=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.dragstart=function(a){return void 0===a?this.ondragstart:(this.ondragstart=a,this)},b.prototype.drag=function(a){return void 0===a?this.ondrag:(this.ondrag=a,this)},b.prototype.dragend=function(a){return void 0===a?this.ondragend:(this.ondragend=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._doDragstart=function(){null!=this.ondragstart&&this.ondragstart({x:this.origin[0],y:this.origin[1]})},b.prototype._drag=function(){this.dragInitialized||(this.origin=[d3.event.x,d3.event.y],this.dragInitialized=!0,this._doDragstart()),this.location=[this.constrainX(d3.event.x),this.constrainY(d3.event.y)],this._doDrag()},b.prototype._doDrag=function(){if(null!=this.ondrag){var a={x:this.origin[0],y:this.origin[1]},b={x:this.location[0],y:this.location[1]};this.ondrag(a,b)}},b.prototype._dragend=function(){this.dragInitialized&&(this.dragInitialized=!1,this._doDragend())},b.prototype._doDragend=function(){if(null!=this.ondragend){var a={x:this.origin[0],y:this.origin[1]},b={x:this.location[0],y:this.location[1]};this.ondragend(a,b)}},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,g){return null==c||null==g?(f&&(null!=a&&a.domain(d),null!=b&&b.domain(e)),void(f=!f)):(f=!1,null!=a&&a.domain([a.invert(c.x),a.invert(g.x)]),null!=b&&b.domain([b.invert(g.y),b.invert(c.y)]),void this.clearBox())}var d=null!=a?a.domain():null,e=null!=b?b.domain():null,f=!1;return this.drag(c),this.dragend(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),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.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}(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.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 f64ce99418c6142677ec8d4a140687cf306ddca0..40f0b2988fd90405023e18a48617cda6978e5b53 100644 GIT binary patch delta 132667 zcmV(%K;pm4&|^WpqraoX)qF1N0FquzKvoNis&((9k> zPOg7$r^EA$dG+wYXa82cFh#1Px_>dAj3(#9diKeaVZR>F>Or*_59(?4bpL2Y_*yuBmwzhshtO=Pw?)i`EX<(C$FB?^NYz~7QSVPt$X(b z2*2}luiCw+`>$u!@T|J2hO_Flo?qAXxaw8C@t`{G#--z5)pu9DY45UnJ6>F#*3)-@ zaCA{uZ+fFeUCk%eyq?VocsQ=6z43Y7QoAR$PwVsHcsv}RSCg}94se~}xIbFVhHroB z^_9S!3YdC4xC@MFJzq@6)!Wm_WK{RY@2ZyAT*IzFYq)YV2L~%M5ncv|N1+ zk_!%BeG-+!=vObM!|@!$d)=D~l`ntm*{pZ2;{|H>C*v7Nup#4y(VJDhH@)GAGPfEp z%;sp|{GAMfX=6raxMI5zHjod}!hRh6SgT{ImWa1?ubR(BfVMpt&WPCdc(Q5mt`eXG z4i4;G566SaHPnOjuKM)rYP=XlvSZOG*XRv0QJbHy4Y3@T6} zqDvrH6{6iB4m(hzNu}xh+bv3T9tG(%TGVQGO=JWdUYL3|v!VCn0fm@90 zzb<;CN}E_qR28Ac48tdeT8i6c?<$zpPN006&$9@NKq>BkO!s>Ii-1wyl;E*ExgK>Mb}xFf&YSh7Vg_^2X&D&s?&Y(A6Tta?fK*RjGtmi#E=_QaGnC8UxY53oD$9^x39fx;*dsSo3 z2+Dm8&9-KdSu54!=vf6~$QKWn46mP+8`@9;uhCGmSROxkC7N~ZH*F1D1VJj031ZQN zXn^eC*tYX3$5(%F&L11&;%zjhEX$7}!u#N2G09sb;CK1sSOi!oE)&1EA`vOMDYXjDwfgnVQ)0LtuXWA zUnp16*j)Sn>#U**olO?gevKbir$&OEta_Yap9s7iqwJir+^FapDQO*{TShcL6OiDw0VE?4G7U}&au$6o-IbS`i={8TCYH~3%}AJE$$%8x zc+(nI8fQDd<}^#bKldk#@%+ylSP73tSifCk1~E=LOduW5Pd#?@^;DMS*EjTOC$ZgP zwd2+=z47fk1BPpE=K^GtT*n)v*fi}{%<@S`YHk@hkD#$Y_5)d}P=~7Ngf>p^M%dtYcu!xrORqCd08f zBh)>VI47&`>=*;`yK3)EJ;mfI&KN9H;BCdqw-13C<9~WI6bM(mWY)=){(pRv2^mY_ z1bPFHoQ>!tfit%>d5&8;U74pl$FCp>E9q*}6liX~wNhIA{8WFI zfzz!ASCqPLu(IRyhJ~d39?ox9>#~q^@2|#x{WjyNt*uJ7ScZL?Hyh%06_bZsEN3!; zL_)y8W}i$l2vqMqFt}FzpZ}>&?T-?b13qRY__|_VE_1%L5qZd3ykllC&w6m+uF^nB z+Iyyrr2;RQQRKyMhc8W?4m#d|Rk?rbv2X`aa(g2#YW0BO0C1xD*2;-i=4H<4RnOId z0d?KyR#eqHr$-9T2AK#N*fE}XP8)$>j)9_W021-qJ*zTi!7dQIwa^04afRdu}5lxL57EYV~P_&NB!`P+69sp~1t3Q8o<7|fc z843@+8|-CbVNeg6AWD7k_-c|0yqC!7FCk@|?by*B@QMz)8mPVXE*x1!$Dgh8eNyFg zc@?EK+mZIVv48n>lMETD?j64_*rX-i_Z@#HMOC}wy5H{oYG*@WlhTXIdc58Zk%bp(tfmbl9 z?c0uhmWY`}fO-|X`P6?BO{8E^r8_%!pM9~l!@o-%x-4jh2S6GCWMJb7oiL1&0Xi{^ zxTI%BQQU^jK(m19;`;uVRVf~Z*DAp?E5SsHAC7(WT6Bwlq78&9;n$>Ih`m#C?;YJk zDEp6gx#)#S0x599-bs1Oy>aEUBBbgZIu9!l3ovzE#iQ;(1*?A-cxfNiXFc`gxJEm} zL5dJtqb!6i9#fQzbd}1d7;5>Fc8U>&11@6q65@y{n#ztR=-7t0;Ou+K-g$l|lKdFS zxqm!EJN%=i`QT@&~3^D^5yZ{nt?0ji@IsL_Zi6(GIQ@Fm~VnHzmTvy)#Mtru{95`AELtg^>$U$Kcj7< z0AjlselQL^~Op&5O%VtSbnrb*T5jT2S@V8Wit!F_| z&w9@gVsR_Z0Z7t5fRRYeY6GSA^=cAl^4vh+TGKuE(4;xLRtRrbcX%WKI7o=@~ZGi4{2%Q*9 zf^|?;+_!kA-XaRs84NfClX#Enhn1vs%5PwhUk{5~M$6kGFK~Wy`;O)_SxuJs!}Li&akL&<_*O6O>Z|6o&uMRWmf=9 zt!SWDeRDM$_J?y!wSRWK{quWpI8`7!P3E}5HmIC}z%CsO55Xou<~!33KXKSFeC^P+ z=+?{Lyf0>ofDqVX&Y-6;y!V_sXqkkog1>(ohA&14P#fi}oIf$7e=ikzprgwaZ@==SU(=B_*bOqxPNz)K`X#`&*3&$h9h2@|E+{&S|#!L-jphH5Db7D zOqQ|YkP%8It#)NnpgAb~!KfX=`f#)ssJ|SgAAAr>@7>h>#hjtF+{EPCLpPNWjI0k@ z%yKwyB94=w4i$e=4%`nY*IF=JL3lI-MUGiuGvtbkJW8m8HNgT*o=~Uq zEF78AeiDD|a)UOo!O>ErNc*QH*;rMuUcWJM#U&s_)d1?Bc3!`MHH*!WH;^@3=|jle zBSaqvBVhC@XA9y-sMxxd5luVOlhCZd*-IzE`5mTG4moR!S$K(Yiidy3tIF)?S`SN; zXr?3rVl0BI1|S!qCA*97sY3@!m{78Tb7`P{J!WEIDKVqjQ+E)S{aK=qttbS1_VX4p zhFQzgZK1X0Lg$&g;0Ie?6%x9A~r}=Mh5U0-n_|}aW;RbZ(mjWXI9s2aLF;Q z`Z(7*g`*1QJ+*#4NLK=e=_nSeu1pxhw8r5|L3Yq3SVmzfid?;n{}quMJTTn9;Gx%M zsGMv_VCfZuDH!2EoSM7Vd9z&|0e$={bD`64$6~YX{qk8SU07x#Y>E3F3|10AtkT<`!r?dZJz2V;rw*u!D*7x&)EEGkWNaz)E)g z`2O8jh1G+oP91+vIkv_4ih{y4#XMUAD;~S`+KMgkqa}?5(^<=<)n!9W?6q__FB}Ku~IA=X4xl5B;dT! zaulrXve>BCUx`U-Fs9flUvypvn-U~jVxWqI1$JoW!72?W8Q{}kJfYjrPN^hY3<|=J z-g%u2G%DsS77rz%7~ub5LI_7f$j#_8nEa6lKfoD9`@ z4SLP8P#u3sND>(C!qzZfOc!IBDu|I8JuyWY+{TS3I;Q+CfWteTk-(sCwveg9cQIk8 zls^q&-wG%E{^%R!GR}Jx1LcpnPOPj`4${^`omyfHvQVZ1M6o(W!e9sGGNY4h1x$@y z4t`c2f%y8&@P1xk1tx`>#Bq!UHNBKCGgc(u+K+!Bvrx+yESR8D0!RcU|FI3qz=%Am zZ?dCSeAfMOZ~uoMk4}#E{__Z=Sv&pf)nK%i#4arVnNJ4?;)$c*7yF&F;pWu>eqd(_ z@O%V<&S%4O#J%%PXTELD3yXpE2s^H0S~7Ms_p&ENh0Ov;t3Z00B z$WDJe>bd57>@tq-dJNuF;9+?4b-UU@YnNA(X%AuiFK4m{xuDUx}aHTm&G;1HpEIh|OHls?7b1r3XR^!$G* z_5JtXPi}lW4K;lO%~WO!DM3z8yCSTfE_h;?3PuI1grDS5Oe%5|5e_*EeMz1q>MGYy zhUKfbAsl2%0e54Y$cQLCk&tPb`{z7&1#4jhGXHhK{iDP;>3SgcA<}ojSIamTM56%a z6?A~^$Rm*C9I>fu)mkF`4N?SK^Avwe$CnOFXMS1Y#?{%|l$>9J$)~lbr_R=Y&F*iV zZxF4b$rz8)yEw2dC+~q%|71l=PbH_*@jT%*1l7m!G!}@HBH1A_q-u&-+iV%M>WMVN&As|{p zfCl|Z1V5niq;0VEfB$QC?_ajMoGUQRE)%p+{A0Oyt3D$2 zqh}4;#L`<~y#!HY^DT$jQomIz*@ldEvg)PUtR5nc@cP0wZA^lQ)ok7HuhlRBq+gfT zD5wJqtaNb7zFVnROZ9(k<954kf`3gjH*Ff1WtVAPzPEId^>n6r?}kpB?p1sm3Ex2U z){`QJ95h54xGuK+1dXN2Jy+XD+(zh+5Ywb~oSEWv@rGDquYbfG@ivGzBye6h>N<`L z(eyz22C8=`Wv+?_ZpjLdlhKU`C&gh>*=>l6P?xc}1S~dnVf}wBRckVPp(a{(Hp)}8 zz=DDZmir~8l9Go6^%1s@nETBwdTF@1pW;`=JDDTAQ7ot7#lpi$*_sEvWSJXvOWWYT z_|VlGsQGX(y3)pMemi1lH`e-`j<|3&@SB0s6J^ii8)ID~UZv(~%~3KfCA(KdDX|6l z$f;(!iAt32M8tn7QJP>lRwsfSv@CFpIhQ5);hU~933err=TOcJh=Zz=tZI^GH)6%V z5uJ1F$`Q&2v640|@nxGMSz?%Xp&^{iqmD++%V_q_h`5kJdnw+k4qC$Z)InbCsND^KQDn$Cw#YbJp zWPy}Y(JW`QCe5ae%lWG&??z=jdKgBljZhMHDOQr$c^XW6*E0Sbd)@d`YLI0&>rEp~m>1>S}m{T)PdxV*P9Sr?7-)ZI5NS z0sO20Tc%FIDks3J7j_bM7|YKtcrI5Gmt>@BFr=xB?BJ10L>u8KuT9G=U1zREan(*s zT9L-HeJ|D5)e>Tw=@?F_b|?*KKjvhQ{8J&RAU7%XTIEGE6Zhm05~!?9L?(xP=sb$2aL)Erp;@waEAbJVEV(R?4ntV9 z$NbIVhilQUr+COIwQme}s7Tg=0-aY=c)o^+lOPoM=jpiDMIEh3@`96O&h-`)M3wYy8B%S8bI zxC4|o+IpFtAnVSn z>`yS@KTf8@|7J329M2Ttg2{lWBMQCUeb}gOc1GBF+^BBlZ;1^^VUyZS3ztHi?3-$B zRG-b)N&!j%9Br%w$G)l7=98-;7z*jl^RqKVS3HJ?9E&34B|w_{f)&vC=|M?nOZcQFF)I)udQy04OgR zhc3obq`*HP!yAZsk7Fq7(VOixaJ?A~FdPO}o|xf{d5?f&{^Ju82Dg3G(;q4@d*|bFEm$&7#azQf?6J|m=wYzC~S6P3AsZ>xz zgdi^=%ET%QhJ{?Ht&|)lCicAbKvX@XSKL$*WE5-su25a>?_?D{a5G( z=^xSu8zVWEEM(Nn%KNP4VeXCluzhzYW2`^8*W@K>Z8k^#Td62pP-I@S?}t*TRdR{ki`13G?v0X+;^ViHl7)B6(Z7IWDlAdeS-Mn z-vSS$<9}^6`ZjnrF}&ijKLWbl;v7NJm*$SviRO>s9!(~=;xq#$n!tZj#frBiR>4GJ zrxl!mPGV~9n~y)?1n5|-OEZ^$SFMSN6lX62b0vAQ-IQgvu=u&mqb2f)j!16;iKYV! zNL7vfRp6qSGYFVsIGi0wVA0neBMJO4y^0omwvN0zGCUm3$!j`$28x3-d!SfU!{CX` zy=p(;_7pScTKXhBZQFk(mCDU(D}op3;E-_oENNCd7qlz%PesW#D-&+it|i*Hsvm=Q z+hUyf2W2&Mml^k(6J1eMjr>^^qWaL;dfk)n&g4)If=DLwjLVJ2y}pRy#v&9eSFabt@$yfXDprDuEcnyu zZQ{ELeL`>$6p zZau*Zsn2P-!i|5~q@YEQS|eH;bcS)!k|z2~i~+1{hOlcc3PNT(zOq&j!GXPyE&g(X z61Et{CNKu(u%&NP&soKmA=@tvsfneBRZBb5BqklbhY~pkGY^yq21k7kIr6M_Hmz${ zP2*)ZJ*;vat8dISW@ijpQQGyPot}zI%fdJ+3v6(O>QR5f=Bb-8tuihQaBAyW>UxvU z6DOG_lX#!lM?ksq%BbTh+OA*z(G576{7X&@^3+GtT0bg#{zIuP(OKa70#{SmNzGVo z1^j3?Z5U`74~p@=6S9&5(S#5=*S6bo<-KaEOKct~%a-$yM$1E3P+jZOi^y zHCy0o7Ig0ZYHoDbE$l_< z*4PEo|6VSzH7p#oWu$>8%s3QDgAKc$LQpnswh65vA&LvML?ANUNzUhtbq5Jw5;F=u zO2R=Fnz%3*Iw1g@_ms1#>sTa2&$peA=(Fx;&PA7tCz}C9FL6S}o#sFzg_gfH5bf%r z3`>9Sb6f?Qp|3%-42@AFSM`7d1yW)(yhPL|g95v!2(f?7H%Aj}B^}_nj-h$l9bV#y zxZ6R96o&#DH{xNkuV_NwXqOsxW)jrNn(RSotXR{TAakGugl6bi0LVT?!ZR?_OPb%J zVfagB8b3>G>BK%^Qyen~MFA>^oQT>Vuo!=kH;nQ&>$HU_%=(zOK^2EzLkF>X#FyFP zGH=Yn(UDyW2=x^ZR9YF3>mblEh;>4O%E*Kv?0nEPIK<2h5W)wgWRruNMN1YopZmcA zQnr^L7Au8XCP@jcr9lj26z4S&P1E&jN35|BN`y$qdeB*OdTUe4Z=TcHgv4AW86kfq zka?a86qoLB69m$wsps|PqLCWybb2sz3lz*`h9vZI0ViuAUj%ks#ok9Ncpz<7=S9Xu zOEU48HbT&|tGYkLE&>A#lw)lO0;LUVZGx?8oM$tE25dPBpuYjE%z1z6M4;+(f7nS;@ri$ZoOq2gEw#UPTiGAxtnvXmbuUq6wy=7?64( zO@ZMV)Zc7)3Y8~^dZ~ugJeGfHO=_!fCv7yCn2mOifU}DQ7g_M8prEL>lFyGTDw3z(}V*w8epPp znpO#8{DekcF(gT=RhaBtJ4+DJh^83aHyUJSZOB+uNKsm7pAtN3H&K6GW&}`7{>p(s zr2AsPQ;2y1F$+H`hs8jn5z7jgaGzs^CfZbHXV?gHXmZy5AggD?J zp$-o;o0v^!qT-AK?7$Y2V`Yq(#z-+-6k`i@WsVuU^DHP}GVN4DBrs6@6_E;_Src4p zLO9oPB!f8^`MmdLf=gjUz-f}Hn#AH8Ih8g^J9)D?nQm(Ahi`vYb+KSBsR*PX6*v?v zP)acXr|BEHgs(asA}Cz33WH0z>?fTj*DL0_x|?Pyob{(#0Uu#h)6Dr40={LM`g6=7 za@Ln4XV3Zm*SNGzNGsaky9qwTiK4FqAU=mWB02GL>Fs<``wE|k8BpVK$NT?StiBxv66{hBsbz%{=nkOix3j3+7N7! zro>jL4k4znFnXhNsIB=0{7fR~qKpMRl!Tfe+#=OG|FC}v^%}ALE-;&l8>DASgE>p# zKyfXZ^6Hy@ou=I65qjK+VG^q(=rouv$W%tV>7{n=dol#n!%G@bOJ@GU7?XnqMcNVa z1wnoSqQEUIEF9$u&*Uh5#AWg5k{4Lb?jxZU^?qoOa_KyhVH8&bXB4D?7;wyT>^TX7 zqfU*4LDPRr-nLE=J6=i1X>EI8g(fQJ3$v`ImL5-dpiHK=WH_rI%!L7gsH$eh>|z;9 zD(d8e#4LaoNhZ$ng0pzs3LaV^OxL6&u=XdjYk3n?Yz#Tao`4aoVS5b6$PTB|g_53U zwuFC8njid-vhEyB(y0a>ZB$bPR@P7r45|cao&taF#K8T<^a&@A`?6W_9DQgZxTA0)Jb$OT*S<{xZElB7N&dsnHwkNbk zF6V!o+!i_RFwx3RsxZfT#P7BdQra}akhnGyT5h>7$^)pCF)0(zkpakAJj?Zol`YZ4 zBkY0d6q$?-W(75EyJ~SSb2>}qXy;FaU@9|Bn5~3W4%sMrsU4H0)h3V`&)Mswvog5& z0IcQCR3KE^VwXd|V%V|k7IDQrp3>5TRhEBR&IbW?=k#D#z8Zujb6*06Iu}RNE`$FjzKuh`akbW(o` zH3`Mf#o$xhSu5zR4WWO5>RqX;RPPPbote)#g*hUwFpISj4hthjsBa>(TN?$bp&aRX zM&Hc6%Ox)4Qp-*h2hmY{#ka6RFiJ1FB|T_oF8;!=Y=GAP7+B#pb5{i zf}gKfVjQYX?!75k+W}i>&^4TJf(K#kEB&*vmLdtwp}`%gBS`zoYr2qVLri~c*!E(o zBNrTU+@b5736qwSB)bi!w#*D};Z{(dAm;H9N6TR~@|@by1i`-GqK=f2>p%=(_+l1RWmHzJ(dn9gf z7Y)1&Vw@6$VhkDt)6U`KzzlLhtz3-}Et#6|Lmi;=7zZzyA`O`QS~1g7A{5OK}@J-c2w~~K|ZCLL~DLL!vOOx_Tp>g+QaF4$#9CD)B%Fkc*rg2nkS&*3ZISN1)cS<(vi+3Vp2T@eM(vp^B9tj zZomqI@_a1!ubvWOL4mGqZ)-7RAxWbJ8`=IS*Tdj(wK%BV10{c4&^}a6pNbcfrV|Z6 z)@fANg-dj(zjF0NxVkm2IRsTK(M0&LwK*%a#q0J=7*V+;cyQjQr91U6j4zOg0qv@t zBi89g3d?8=f)-k}>nkJFNGd-zHnPOJaEYJBnz$!8D*P_YPepqqco{`As*3!jBTb0W zixG|y_7I)$)hB;JIym>#s{h~}5x0-Yu)!-F(+%J7ZN4+|15-Oucb@VFSk9KGlN+i| zxFU@AA=L-p(eZqVgyT`pIa4^%UVc72{NoP?^*}FC2-`}aH)sQBT1j(lT1orGz8OBT zNSn;#wqjy6dEQ~wAdxogA5$f9{;|x9=TH9hc>l?hlcRtAr+d$TIy!lJxVMWMpFMc+ z0C5RlCLUiG!olP_*vQ!#Bea)M-H$=P`o&~)dj>sRocJ+faSh6UBOTCsK>^m+=xbuP^0Ru zUge_P-I2O6_CXJq$-Vu^;k48%$Eg3H8rWefDsGIZh(y<_Og;bj#`c9QZs3RGDWRzDnV^D zI%CNRQVf@?(cwk-nqx(tGOQ@m))9Et>tcWYuaQ@!v-VqzBbDGL9GGv56ex%QbbZVGtX`vJ?mSkrhm0XJmdzL8E+*f0^yp8Q((nlVgeYmI+8^dNbZ$NJ&$0J)?HR*{pxGti@l(+whGRQZc_Hg^kHS! zgKI%H)4$OMq_q-0KdS|u9Bn5sxqk2#029&XLL+VLL$zS2N{@5Q%{eQebvJ*y;D+$0 zuWG$H;2rPC;g6CJN1u!P245A(FYUS6+S>a4v_7jbz2c^*tKR(LYvl3Va*w+6*;=*r z%_r1V&X=>?!{dr|pTgg;4>!Z}XO9j~_Me?R$I+ihJAVQ(9{wBhihTLN{zE5(kt#L> zuPvMn@TxP=GVlt8qwZ9#FN}X%)84u{zz<;PIJ#Hu@bD-kRogvXfNFe4gTMuv_U(sV;EP>Q-8G9lF}6|sqJbYR5hOtS0+ zFRO=XK9m56;esSO60Lt4)F3k8h$R3N^9B^qCjbzAn3#kC3fWMXfE5ZA;ZoqyYCUj+ z00i9kSy$e{d1VAGaYor`(Op0`Na@cpkT#6CJ2zL{Xy++(U$=KU>kL9)J8Sd9-se5S zvLe9rL|7VIHN4&-goo4RQR9s}Ii@$IAOx?^6d^?^hO53NEVqBW8nlINA9V1WO0ZM{ z63ai~cr29TH-6F!+gNHx7QiFGK;bulYhGy%U~n`pVGAuuz|yL{a7xDZEhoR_yl7pO9o%bTGvJDYtFw8zf&w;7>T)#Pds_nO!S>R{8m})#oh}OePt>0^R>J zXjq&WL|s5NIm3U$>!gn~3w*vriDwl5IV$+EwS;C}tX_s^w=b-=^?m$sdUt>Y+hZ#H zM&J~>yDMCz7>YI2hf%X1UCtHh83J@KPigX6TM@@-E^&b&LnOw5R4>s2)ed6sCJg&B zR;+||s8Nah7Gdt8k7L#TJ?aUNAHH#ETUuvG2h7FMhiN?>{{(0t&S4%j9hd>TF zhu2`pC}w}n>pYq3+W;12S!2!S^ls&=uPpyn- zFpSW#!WENns=#ND#0rv90kPY^4X*zFIQsv=-=Uq@M&Baa1OpN>j#Ek>$s&C4OId`! z)S?^{E{;%&`3VW6GL|hPXYNqx@Pk|;JN-U1w%&iuiF=+9Hj0z#)=teTumb?Dx{RQM zU4mRKvNXa}5idJ^fwSn-Bgu*o%{LC13FyZS7L1P32K;6xZpXqJ^Rto*A?~YeZ0(Qd z9YS$5xR;`VtDW5L#s-MP87jdvSXnBuR`YiR%@#EM-6y#K-p4V-iBdejwfH-d!f-V} z1?GQ)pHHY(-+zpyJ=G0Jg_t^xeRiw-(5{~$%_$So^~mqTb0k*q!TLC}38jws=UH{Q z&+T3b%WIf8!DS40Z1(^ZT67B$=ZcNYdna;mG_=jn>@<+oeg~))b?a<+$UA-LhxAjj zlk{|M4$MkdrnD9gURK${`tiqF02@w1&If;G#?D%oR}y(-a29a3who_T%$M(NEyP}r z0k=8=df#=-<_MeIB9Ik_j^(3aOGk@}7R;#h=I+jaB-%^!L1KHuY?L518uq3tCU6)d zo%`ex`7>NE%*=2xpI^X9)$4t5CYXeXih3|n0csVPKP#M&(2BZ3Q1m#y|CsBi!F@WY{g_@S_V$Y6pc zSpRl^`?pU&9NtfdV=1u9Z{XN2 zHZG~=xt&fkcbu0!4dNMYQmH6=dP0Bhjrt4rAcbv>aA({$1gn(VRZr7996Ua)N76_A2G6|> zrqJw_I&wVQu2p=0kW0?-XXJ}fhG=$maZE_OyO?E`s8ptrdFBQRi4iOfc{CB-N|`pW zvt6x{ogKV{d6IBq0K~Od0usFRQAbVTL`xdcVJU=4m=`?mpP;y!qM(13m{2uvDt885 zS?VDAc^!TNM-pAU8(vK;eoClmI|Ljo|FLcmv}5%gSa_kK`nYjL6ET2Wh?Iugz2r_i z!`b|UZ>opIy>}m!e84D(z3CM9aj!XK0tlB2oEpX<=+k(%6aZACu!x0kKV8*EJJdiugSlyMRg>82-nk)+kr1-eW zT?<3@;+2ADC6?Ag-QDL0J5Npy_8yT4zd0Lx{_mgHpaM(Sk12n-|LoEJ56`987oYw6 zzxV>QfJ9s9AzI=Fk`Xxuew#&b! z?eBj&c((uShZ7+C><5K;cJ}YT`}}w1;s?+Fgiigqw{!HPfd1W=55M^Gi*i{+XYKA{Y3)`yL*2Jh~;#Y8k|0?n?Qblu>Zr4M<<6rX~)ja>VNyZq4)pK&hE~^(T=qK zu>bJ%%QIkEqQHwM&yS9FzJIcJvitnW^MgawIF8B%)N*5*FQ}riYXYW7Sy3j8XG@H#Ut${FpQrF=G)?^;OJ{M(ZgR{VRX3^>h@bbytgEl)|#1Zb1n+ zc6i#|X+3>pRUbjA=%d`%fgQk#zXm`D85Dy^hmmq`rvAKkz2M~5|I-B+#yV2MM?40lr8LypJY(xaP{ z&yiFJ5jTI>$_Yof$0=6?FI;n7`|!ha$H@uEihyZJ{VSv39)N}2Aa-DLoZ2CV8KJ95 zW=!T|n!l%AB)orqJ+^1FJ6BjA4vw$5az4c$C5;1kazaMXfrsZ047cdxgd7SFtmS%g z(#6s4`Gi5n1mb@wtbu=k*T~FU5hzIX)m@_c0~UWy=V!04{kM2=$z|F1(@Ag8N9rlW za>#W-%x#2(FjyR6vl=NI_Mae!d_86g31oo37$Q+SY_d5s!82zhvf1#xCg;JCTl=A_Gt;N81a9jo{)RqQQ-`=^uf zWHB4v26g>D4)tF+(vj{v!DWE;)QShy5jmi}E%7$e_w&HJ`=deP76CJL5 zH4^M#%Yci1_PdR`HfJ5qoCt|QFW)(7#tpSL`duK3=_}(43Ah=K0>|0HAs(O2iB1t_ z(3$Pab8I;3IZB@9#K|d)fQGo}!U|MMb5>CTBV{=9cyMAVEJ$U(d0pQ=w0v(Ah}VC( za(d|yVO9P4-d`8E+m=-zJ60r|NUCVS4ImxuS*kvLd^q6TK`WMOAVtB-_#0X7XYdN7?%PAtu zY?6%1VFK3^nGqU}qR28PudWnBLkWMQ@yblFEG!=Cp%D%%4WJx-&j3V-3t=>R1lj^% zB+IUL)3t5c8b^Iby?z+|$zkwbC;3%#k9*?|gT6{MYiB9-_DPzoO~MWsmMYIedQ+YCgqw|ppvjiwQA?(PA*nubsUnW^yWT{E2#e%?| z7<-JBc7lN+0(1*gNa?Q0pTWkDoW9j)M~i<@rmIAYuf(pQ z#)Fda8a=5Ugt-J7;b&?Q-&&I%DUC=zv;(Agz@{VmQW%2|L~m*k9dRC0U=)(2K7M8M zQfz$3LLUG6$b{V)jVx`sdRs348D&v}OQxS?@jyFMAnnHtN5Dk>eQ`~kE~tYc=31;9 zKmxkKFNGVy{FQlKobi7T#D(_$!T*kRHK!Bo%k>TsvVjx$E$bymosO?lSSp3ne|Y4b zoa`%l{pM{!OyZ@rjhoxw;{K@PSMRu;+jC4Ey?saPy2tm`&e&L2*x;3meQ9+t85a`? zVx7vX)Ope$zXDvm@#RF-p%e50#N5hXo96JZ3 zoPetwji;)#Tn>M_8jqr4Uk`PCh6>}*<~Lmq+;ZR=~a3^h0$Wc+!O#s{4o=lV~1J8i*WYjt(%mI13w0EV!%EX zXZNg22TlMnC47_Yk|wet!r21R?fShL5D{S?w4B6Et5V^1k9o+514AAHlwj!q~d z8Yf5u zdIoimV#yA(>($9^dy$)+5e`Oi=M=7YjazC4cZaf)+C%fQJ|6YX+d3n~Uo!FW3Z?tA z*)A?0m|l>1MysEGF=W$NACcK4mvooilhSx#|R# z+zB*^P`M$BoU5RoSUyv~`jlS#6)1nYUI&Yq6H_~Xw51K~P{FV|KQev8n~Y5Z8H-XG zmh<70CUSDO$4g(PH50yR-OlJC_MY);~OH!2M zR2Gr|i~yOs8E_(L z-dVoV82DXk2bt5l@%zHOw$yqP3R=`1_jI+D&KeTyFX5yU%sPv!(waKfe2&(!Ud?G7 zE-+XrSD7xuq<3@~?CB}I3y~m+J!2G;13pZEtt_iuqiNq zxDgEOg<4u6&`8ojpEAB0QRj?kscvy0TQrFGs^^fDDH36DYZ})usn9{jnI&@ahA#r2 zoyD)TtGj~Ul;Pmi=90yfxR8d~@?AK`(-<$AE=yoIK5Dt=9MUlSe!4Dgl9{=@sV&_U zv)pc#mj&rG7tsnor7bdHdRtR$2fD$33R+JJazp-H658ylqg7msq2Pq#;?=6Jw`n}I z^%P3UXxI=(epj5(fLhD#;0Y6DTOdL|*YAV8ueUPtFof?&pvg@McqBk1jbq2el5XM@ zp`GTDn%BF=`d&>-HSqvs^!v$8XU$$vw297AHDf#om>QSTytkNR$u#3-p-$~~cYZp0ez14A|Nrfs zeE+ADM|+QVetL3L!oEyPtAc=S`+VVBbwQim6LU=vF8sMdpiZP7dvAKUk`M-sEI6<{ zw7+$|QtGT3nYWrmf4f4qtc!Yocz!XLuh&Q_F%w`ofzF%na7jHMDLnJ63Va`=`U!Ii4(Yk*%-I!^x-u`FIgFQ1O#5e;zYsXZE2qF$m_88~ z#mFlp1Oq?-<<#eFVF{U%MTJrvA{M80J$*WwNSp7Qdp2h zY(il6<3^(7v$2KT*sxF|DBuSpP4&^1>LQw#$o2GFjsWj0ak>EJ2NvfeuH4{RUrb@O z;$BwBC&;Qtc_*=KSycEJ4b5uw78ya15ajy$x_kY3cQQTSIy%^Y!W#AAXIofrEfA;J zy_jE)eselPj*v|oAF0>-Eb9bS&Z@A7V_wYafor!Lp}V0s>*V;xoi;YMG?2Ny1OY2e zQoD)&SU4Q4r-oBp<2sS-(p zeBjLDM%rF>)7c7tAb*qz7Z`cBzrE-ofT^XLu0SK6OIOA$kSQY?Obo^|CjfACg5rg6 zXnz*qB+^M(M8X%>gA|T8o$6>}l$=TOCo%|Ldzf!I(WIPLAm&?Mj^lgt!Wa{FkQ<@0 z^le(&!Oob7#WV9uFiWhmPRuUB6sV(EGPOO{NIsSTz`^i;xZSQO=XE$;wfWTBof9Sk zZz`!5JumBI7}ly}UzVA()0mtBn)FdkrvW^VqJ9w{e=(e6QGpC}c8$SXP&5#b&K}&K zp%xmnHC>djvFP#5NKUqmiHSj#nMis63NBC21rha)XlCTU5RvutzfE=! z@;0Lel>TOa7b7p5(cj2^;{Z4c8GK75(pMRcOiywo3PcjLU0cSSN`@x~6xVVXIym~I zp`LY+z{QB<0RECI%mVI?r4G}i1^ms+y745Sc(t}(Qc{8$*b;fqV16Z0&hBU)Sup&V zCDUm%>tbs!?x#>^-IP%x!?%$X(yo_QkIA$4HPr!s4jgjX6RmQR#mEYFJ>(K#AY;p& zZXt)dttI4P5*pYwZj&ADr#T5>Q_SgWnNDB~Pu*z=ZdekVQeYbgB%V!D67AaEvv4bB z#?ZCJsOHP^@}-3IFVx!zsSnucfuUpTsBUeIC!3S2NC~e*R_xPZ$&M(O(t_}VQ`8N| z9albo%A7?OD7n*w#o!>vr1mx3I=mHJ z51Ad-aDO#w&qwgGC*CQ+qj}@=|5<6f6#Ha7vwO-dGyD(hS9VXSfb0Sp*nlupD8ww$ zMmChcdh0r%*QRq#EN70K1jp#Nt1)f#XcBRMyg{mo9WBl+8(y>l-9^v&q(zDff8u~O z_L0S0Cu?v!)Wly|&037WVtsyG6X=4$tlU_u(H}xW^p*a!cqP+}ww-EL`&4;d9T>rl z*g0M?Gqbu@?T1>oBpX^xN3ZnWOuZ}?x0-6HTwr#4+!rTvI&P!$0A{Bmg?vfk%Hpzr z9sa&)@4CzLm1ZI2)<|%GBDE$;h@I;^DBP?@Cb1FDu`)Y-!s#*l+S8Lh)2=gx#AtX` z!Q3b0YjMDsXau+CV%cG3plW2iGCSJchBQdJ z4ezvBp6M3+6R3uDfQP|&dC%-IWOrBM8RNe;D@(7AY=!ccL`SubY?`bup(YK0D4z?_9{gddF(QT`cPAD(2jk>Gl8 zdrC&5x_Mx=Vb`$fcLAIu=;&pCaCr-$Y!yA(dwjIDyZ7v9?_f*PT?JQPu!Atcw2wG+ z?y!n&A@?{zww-^}H5BoVBSndU+)Gq(-;rAI2`@X?g^Q=8Zpd}6FnqiSGv{5xjV6vN zveavZ77H<&!G1^51n)UP5JIUJBx`dc-7jMEfu)<9k(-e3-byJ4@iN(e$!55p#wK$F zH!v;tt~QeD^r2*9+bzX8Y{B}Wq43UF7g>i;%Z_z6ZSNqK7pDkh zU%>`;sMCaxx$2Q?!+E}e3k60m)PvQgbvmD-4xpFGZ*x@cTeW_FfP@cX+>XoU!b9-f zrAvUicu?-ql@KM#9Ep)2x$y`v?JP9lf=XSb#yHY^4VTt-_e;GFl~Zaz(JVmhP_ zu##Y;F{F`*l=_E%eO=BMj8g^cAQ(ti@W|}_28K5l?;71Jk#Y8zg0MK&Tz%_)L9hUWgpgrL88uDDBYqYcJ|r{K6mSkeJVs5M1Oec8^y=FXUg4DBr9@`w zxsVjoq#naa^cxcbx>j9E5)`j>B zr#0j#B9-fDJ`D!2 zYY*WB=q8##;4JqKG%|(GdqI08*cs+4`_;UP@K%;Nu@cQ8_6!Q*od$zlp2sUm6-Lh6Zya5~bxpLlo$Z|UBLUm){f{CzBV}FU`CxFmCvob6c(6Xq(Ad4`zx%O& z(T=?L;Fy(WXqm1yI$DvLCGI*rPwVNqWNLsv!cFgx6)f_4*j6Viy2p$er37$o*Yl5m zz#-DBq|aOh;A9CFU07)>n1u?-EVdKwcYv|7a^JU|n59i9R&W$wc*$Up#Y~PNXD5^$ zM8U7z1f?t~=Q8cP=jML4EEl$~83LDo)_f;cYXM8?E5=6+QZhOuvQ8xJAQT^Y8k6GM zmuuLuR+C7rW}+nn^c{Rkyb9V?N0x0_-}Nm#s?JNY5XK?J{X3&Ye06C(*6sJ&RhPmK zg`!`Q3NaKC{^#W7j1C))%Hv@&k>kORNrzGbs52iX2qA5hTm$1ZgX;sHJ4FtEc}+Y; zu=K_;K%0kM4$|wYY*p_bF%CD-O#n+*$QMMh4redy9Uing8>7Pe%udsfH3K`xPyZZC z5*XP5yMzvoc^-@DZu!xgHx>mJoonsCQ93`(BOqgX&N37dEEj>aqP{~mf zXc>RDlc#tRMt5s|X7f*2J!;#3&FV9SV1gKZU*pp4{Ew4o%&HLzK#5&LK5u7hEFrBy zXLH2l3=)ef2j4fM?&dbHsLGj^<&kA(vT>AHJ@O+JR}zC(T#jJ2h@U<8?A{ z#Bh@i@$k1=FWu5^XC5VaEAt51v@DZ8FrsLA%nxYK zM(oFtw|vsRh@=@;SJgvA(mk8Zts&JO+jT`81T^EmE3{(zzJFdoMe?~l!e8SBRCa7b z)k%}V4X@h}z?i>JQa@Ktf933cuEvK*^S2c{>Ny_B#D;)JbKzX6qq3Bz#;K8+>T1S2 zkL&74F5jSc*^x#J57;!b3mEiBfnf6RAlPS~+(o0!?(^6-*3*p39WawlQ6+!MOE`mX!NpWYZW=) zvK}t$>$Y5>u{6dwo%NOz&K%@uGexZ;l@r*KAKL zX@+5WUcj6KnF<^|Zj+-@D1Q4FIMba zzJvbK3P8ajmQvx7Z)TRhCvbGepwf+Jf(8 z`86-fQ!|M)2=vHuet*vyDNtNGhOOhC*~MDVo5hLVB7z^3HkQ}ouCkewHc**-Y(Iuf zIT3uZ(5>Lg1s$@BPFzxMoVZTpK)C#&LjI?VVLHG4yS(Gt401U8aN!{9XAJlq+zL{q z!IO}iKQ4W+=PBJRh!{GXG5Yo%!ZlrlxAGF6b4!zJS~Qc5fbfa=H_y2Tig+?P`sww9 z?T1J2J=D7{=i^%>)d(5R#(zUT9 zL-$wR2VKUEHh%%<7nj$>*XUa;HDc6w8l(}OoYtvUCum|gobAzyMMq^2#bzwIu?-q; zBZ(joek6!w+rj#_dQffiE}P5V4c7Ncf{nnJV4jtzrT|^HO-W7YmG_FJ->t{#Ni778 zI{2tqX%lxtD@+<|iT|w$p4rA|E4Ac0B&QUR0C-6VmVX(VY1e~pLa94L;AX&eH!HwR zLg_7eo5&tz!2K8P|5Z;=!rJG zVppu<<6lD)k#|4Z#T80nkrP-XyViEpSP#%3fEmGaC6irM|NLv*qPlKib7~LYguBqj z9RKGfX&>{FG)MeUCWE}r93b6Oywd_ms=UVnNPp_Jc*^dy?va%b!-QYqs;GyXkBqk{ zJ%ue%#8)Gx;x}udIX6-hOe7%1o*!Z)5w|knI;!E$YVfl*ET5#G9pV+z-HL9oaFPgT z$;1(Fv*`1WzF0ytFEHWL(^kytAv0KiGHNg65zed?0fP50B^_&NYnX(wO|4LBe89Ny zW`BgoyOYtf_il+OOwhbAWS%bJSOvArgz(|v;PihDC`FdIXtKL8eax^(a5-Z)JltwKA20+9t77NZ#<|KYdLVrOF z{g@r&pI2~wjb4>mpQOv`x15gDo|8%ph&7?bI;J80IZ>EI>~u#IcswtjkR~35O>RXGBNz7{jOF+?r$sE@1Q8hIaq-k#PPsV^ z6pc9Ap-|F``SMHM|88W%1(=5vqkl)-$rb25uA?cx13whs;TDv78Xt5ZIF3b!Fo!a! z;Lq;^+4!m&-oIb!PE_?TTJMzYzS=~vtjOFmv@n3jlaxjuj?XogIN(Hn% z%qgKI^k1b2%Kc?|xl`nae_aWknhWO4#76R`1?FXk4bD7M=Zv1Fenx_hF@F_V=U;TC z96lVQ(ZbZdO;Y5hEBfOQ88=a^1{F>MPkyE5Th7^Myc5x#oaKy(K*hy&o3_HiIbxg zZ!^e~>M{6VPVNkbP)0M}nSZ%ay{_vkn9aDC82oTnt(`A0c_Wj6xzY+&lbNrf#N-g# zrsNoPVmrh6KA>Vei8T^UraS7|_!{O(bNg>^B)4Tb(6G5rYj*BjXb6IYWk?4gN z_N?uM4a)R!O@SD+C{6`?ZLCg{NMWAa{fftrJQ9T#NqUg`dNReCMSomx-n+cQ#xqs} zOpVFAc1|%qy75f#Gvuog1#+R64Rou=!|7};)4B`~Pg!}|A?i}WG?9Za&!)KXMjHb{ zmI);1fE{$6W|RpB<%gIeCnIAw%gKnbBqYMVb3Mfc4D}Co=rF9}Z}9{}kF$CAp50VH zH<=@ZY=-z!MTnexiGTfgGp;y?kN)>ACkw3z)Wr&b7#X8Q2;>H0E?L&3ZXbz0*^pe61fQj zMcLlAX{T;EEacIr`2u;wKOn{>LXOCZyu!X|#=}hSArvt_c(|5g>-sd9!W5fQK+`LmLnk4Xz?Xyc7xN9l^p}{R@Vc z`0O2EZ;3yFE`MRe&dOBSFec4I>^xV2j){ zDb3V``qs7sth06wXi8{18CBR2>UeLAE(0K;{ariTnwPqy^M%d2 z4iCUhe)F)+v+rYu*XdjKj(+XPD(>-M>{dtID>a$4KMc;INSaX2h>f_nqls8KU|z_h z9`dNpCzC-1d6`PY8#qud-z3KyH7JMIBmSqQr2^ikQ~?dD z34guKK(E@cCtJ{Pu6)pPvCrND5UHSN*6#z!9ePiZR%0@NGL$RLAA|qu0m3tTx7_uV zC7|fUhOT+|iqrcwfKF1a7kl7LgM3X)PUmZFx}pAf-`WigZfT8fHM!~EW;j?zj)Hxb zbQ5kWA>XW%(MCMi87CAdo3zj(=#?yR_(VW)Efb3oDr@?g%`_Tp&oW%SpqlGJ^$iScq~7z|g1`K0y6ml<6)dr!!W^ODg@t6fzO#yrJ-zL1=iG#91EGUGYk*z<&z9fS?UCaChiL z)JQ`|WIYNQ_}d1CksBms|A8LVh?z5FRL(@s57?Fv%vKCRW0YL|rH6lJ48xI-wpS@b zGfGF_G}uUNxYZPAp#(E`UnBfP7cwLx24Aw2-5P3auy75>iBMI6f{nqTP0_XlaRyaukm=m+c4tI*Ctl zb6xT$r>wH_9e^`1qQjC7xrQ?IiY;ZOf~NG{lC}aBAl>o^qpc+`VIRh$=a{Hjx&m;D zm*@1jvFvTJH7!+cuCzEVJzHuLne6C8Q(W!;WsH>~v2d@w; ze0BWUs~qFRre-y^17pGPCz@)oK)tii@HQ%Cdkh;!RDT1hv5cQ1!#4k9gen(64mKe zB=mBEbci61BW2Zr*{u%vPC`a6hUbjhGoDSVt(vw+=tpHLc?QbK`XFgL=I`ui(oinO zA%8RLH*`katx&QpH5DO=p)_C7B?P|l4lE;K=wJrr!*V2Acq!}ZXx5jmFzyJXn=fNU ztvfrG3XIv;DlubFn+Z4mO85&xfr#gnuw@q0vW;A}E1>?Cj8^Wt$UcZrN?^0G3uT<=&0dq1-E|b=$X`6dg_dJ zvLnXvP|u9Do~2?};#xdk9?e25Vn4R1)8Wl$u2>~LcV&UN{srgbgc$FAG;XDCvVVDt zKh%Mqt7|wgW>GD7Ab*-akxt&JgKhu=rDcx(t<*p1TT*vP_i~iuCuIgN#d=4~4NJr@ z2TfCR23-<|P(p_{NI<{SN38#BQcN6$HR8UrhPKcfYw%s;fJ%MC%kzf3#RtuB=Z9zC zB#|)B2;h*MnCcn#dZ1=bBQWk~7k>esFMu84=^;8=W-i0m>^6w!Fd%MB0|DEe5g{lh|sbpRDvX9o*hmgqgRy?>4Bw5hYi z%k-ni5S7z%TkpU($e-M>hPMDLGMX>$vm8|03R$N+ic98#isVIyp0a^>2AQi%{Ud?2 zDkl@66Wi+|*-tm{Oe)x-}M-?3I(MX4F~j>et$M-~&o1pSmUzpxO1 z6vQC>5Ph7gU0hl7HR^~XM_X?o;C|QH4125`N{p1F<3-ei6P+WR6d`I;PTAfhoimU` zRDC;9YO5vrfCFrI?L^lVSfEb;GlJ(z{xen9D)VBb9Y-26Dj$$p-( zrO{JrGwTfiTyrSkp!^W4HJYb7VqhF z(i`BmQk48Pp8p6<-&)BQ&e_c(BKz*lHjHY`v92HykQ7hBa*Kaesfbz!iE@R%AzV2!Icw zChk>N^^|$0xF;;u`amvZ#UWpuiP!FIi|?v~YzG@iPk>ViSKO)O!mO9T`hORQ>)??_ zLKFH(a0x7Y9B;;XVqEA4sX%@J)*V;RnM?wSDJVaQR8}uMTH83GjM?!NW#bL-VC7%m|{zVdIx}%v>uCRI?!IcTG>q` z%a^}{IG$jkqB3k)6nw73(Me}xGN<8dwwFjx!c%EyPCRz|XAVE`8P)P~E~ag~tb-*L zMqHCRMK4h_e(iE`U~a*ozC|V#9Ay{r2HQ+A?pKqs&3{_bGx<)8^hl{>@S~>PHk!hF ziyPhEfgQu@ScUF!NrLX#rTAdm$XkuHQ5 zjN)B+CpQ#!<+L|vJGq?4?2HPJ>CUVu8s=9ra#G7lRB6f_Ox(O>t}G}m;B}5v12TV) z_yyPeB)LDb$OG*Pl%6z5g&AT&W0c0Ra(pDN$))J2ObC>4%$G=mv-i#XX-AVVvMDqb zi=3b@=_Bodlj~_7e+=UIzI!eq3n?Nh%FVb;H3c`On}BB+j?uuLEu!}{rWS}nyBH5~pMmVa!}deAs3{FJ zqT^_V8{;|uCK!|F!w;))(3FY^MsDw4O~`jhkTXYiWmMspe<66bHu=m9;h7Yz?w)t6 zwHxF-Tf2S0f2V5+4tB2=e9mmgW&jD+V`AoaLonnm*1S}+g4McwR$g4e)U4Hri?r+2 zXflU)^UV;+PybNg!e&OFfW9o8N-VCr#nLxgXB{WN5T-0Y{_u-Jf&*>bO}9(I_7uhE<7d!?2QrHREVr?|h*}Z}-2P~I^`bYw*c&r# z6iKkOaBqgpk)5?GP#@Ec*&fTt#bGC1)qRn-%*BxzyS69;Jtsfp{u+{S+5|r=E;E8}Q z;qDVPUv@@JvZbc&EHw?%**~F&PW}-&N~}rwf4Jl64~6Urm5dTuNA-jsQ@`}Ar#Mn< zS2<725=T}I0Fwz0f*^cp>^4s>C5T~0b1+X!$-Y20!O6;vcywJS`|j)d*7}~k>MCIE z>lSW2FfVUQL}Zsu<7OT5wF!zp@eLkZ2(NN}A^@rvSGp@*Y|}`rmQ-n@w2XD3?*tXg zf0sN-O1AKvAMl9pX5u<75w4y4NENMrC+C&NBqw&>O`6HRM=cXu8VNv9iz!Qf2WPR z{|H1nlzqC+x_TmHSPH_Q19slrrBf>Fg`Yw~08z0*yOxd#hkO{tL6lfno!?v6+6(G; zq;n4QNDIB6uHhJ8klfIFq)_-lq(Rx%E7)_rQu74H1{_7ukeS@vBPgVTBC<6t6QQE3 z(X|hAjBPa$t*DMXX|8a_d}pSXZt5X1p=}4*3H{s+-)v*7Et@xEtimn-e>zF%NZkUH zv0j1xe0%}&0JXDmj(bUnP3sqNX~2#KH=W7{lLPBe@Et7;D0Q34&~Uah?qA^W+n`jA zm>cm%B+tAwU-=?5E?fOHu6WrZXz=dDwrLv~5E~-FKFetU4KSW;POc(~wtefV|G*Veo4emgC`i4+Pw@9QCj?I-O{ zzNe&KC4}0*A2ghC_Qi&sxTs)uBpVxPRW9|FOwm|=NS622-Pmm7r51M{daV}?e|?7Ro z>1{y>kAEi>I?!gWeO8aI#s0dT_%A88+D)7QVF?qqEE+F79Ov1!Q!0a z=XRZgTP$ZbW%$9UJMWKt85VwI}T}9^v=~ z)dC1N4OdvNG+?*XcU)>#`C{c|lH0J&hlkMPX*7S5vQw@Xe|ESu5ZheLbOat~0OJf! zVXQFPri^`@wz888F9xzRhJ;VT#2gJ7M#(*#$rKmQz-nbFcL%8)6HD|8+1TKMd9dQz zg>h@{wkQj(TRrEb#4}m~2EFjb6PUxx%X)waQl>V!TL&c?!1YjW+Th_dJ1-4zWd>Fj z+~>xcLoQU)e>uD@n#G*wX4to-G=jeER|!J!zYzOieDpFt%0tQAn+G!(vSagKz>)Th zkp{>seyNvz@1qAD^bN@DLCg+InDj1%eiO)EX(;FgECwMK6a+ zl^&pze;3FI$r|=!YLcA3W*9EwPCNzEn++=HvKo-{wST2yBHixRv_8XT8?Gtq&Sz`Y z);FJs*=LXUpc85-xCbyE{DKdQe|K(GPKJxYL<<;?Daof@gxfv89)qE|=XTq`Oi8lnz)a^$m~cCUQcU_Z1DrVlW8}aD9wunH`Sg%3<9F4K{1x~&#vuhu z0@>JG>fQQ!I2kYQ=VHBhzH-c@B(pIM8wL$zLKLtieV2yeY}g2lK*p_tAa|RNnUHx# ze|;I0TY~847sxdf-ngx(G8^Py7ekt2V@otzg9>!5fJCgqh?+>NbBf&DZeBqZd51{E zF|PcTZmx7RHj@FG+OzeqxEvqUXFb>y&UM%V;}+G|_>ZA;JB+v&hSPzQ$uDlOgT`<} zYo^J=6}P9*iI=z=bqw=|`95)AN|U#df4I1bv)-g33U{~gmjd)1#;p&0aTu=3xk zu5g@xWV0S-#6Vkzxc8Rf$+&U=hXy#9AS^vVAd9wvwTbwL#QJ>(48#)VxhYt~CNWto z92_gM9E}9o0MeKuz=a8#Kq;lgc{ywz52OH8qLRM)e@A-A?9&nIlzFnh4w?#K_BVtXH{WHR)_T zbGXuYV04@*@A`gcH8lG=WZ>QKetaSs<7v@!#6ar~!sK=iQkuXLU9 z&qc<#>Tn<>ro#$yuyC-WYG08*s5hR~*N5}lQGNHNMp*Oi3y!Ga*b>Q3f0wmpXgEHk z?f%M|v~*L&>ww6Ja+_(kn$Z@l7B2(hY7MJ^kPgORccy6}=+|yP;l$SB^71weqJ{;i z*U#&LepjVYWt@Q; z*&g8f=Tq~-FX0QqE@qw{*XV?m*5Nn)x?0n-jk0_hs1V8XRwrn-yf?X|;TOY|2(prN zh_AM)Z$^|Cg@=fS-Qax$^8Tdp$cdYiy3ys-*S+buv-T4IVqv;n{WRnH^kj_l$w(R^ zs)zegGwjsga(9r~f9!Ci7{`cb*!D6hfEVLY4=K!1gTymY$FtS?ORazgs1u6A6ZQIA z7Ig!Tz^1j6H5{`n=}KN38L}zAvn|1}sj-L`vc?Q&G{c1up&#Og0t2{pgs1!?kVoUn z*Abv4s36i5CvQtd1P&x9>xSxYFA-#D&-^)hD=%6bRMd%Ye<~F|-)uqV+7-TAd=;m! zWAv+aUq^_cN|e;a5Re=t#gox7r<5>=%p>GSiR^GQO9NP`GI)*hZ>xb+#pO2g*U<(K z6tfMo@3yczmRu=!YI~;WAN;i3y;{sJ8d}#nfSS$yN<17a8@w*CkSF|bcF5VgNxN%T z;(5`K+|HCOf74>tPt(KypS^eOZtFPGg}=|Q*ygOf0TmGvT~%FOU0r=Qp~KPaQwZuW zEs4`9hy$U7>^^glE|r@^#<5K*F(pE0vxr?IRIdNXi-(rsm_uT3MwtAdu*1kxo zZ{&?VL>8e&S6&IXZXsp~<5+{^)5?u|q9Ob5a(*Wdx>Eg)I3Ws26M2|eloI0?4Zm@t z`NF|x4_rVF1V&DBLX+Go6vqM-KMlkf6fx0Gmv&VcMfzj@(piiRqeD5N2$3HWOwlxH zOM@UEf73+2C?5h#C?B6pu(+#xw4h80fuGiGZ!MBHrEF-Td*Y@#B6+0AOrglr0+O-Y ztEZ3{?PM23ejj4aB~nR3I4tr~hNIJD3}$1b4AO}KY+@HK`S8cxU}qgtlO>Y1U0kgs zJKJEojjN#^l~80QGC2Z-kwQj8mcWWECjf3Va5BF8y(x{V_#_WPq!9yHsAg!gHeJ~B`H(1#-ulSalzgEvY_f}`r?w?v~X8wnj33qye6+=!yZczT9?Y5Sa>ri3!C$nV;Ief ze{+k&YVT||U%>DmrZbCRm!iOl@MD8g);Zj0QlCEe278Ea`5LK(&9ljkiVB_rP zTPt`b8f{miL84#wGcH)1A5*+(M!b~hEeZQ;=sJPqN?V>b(K|FcZg-TA;G4A7aLHQ- zYQuf`oHLY*j9#A#=iaZj8~PRH|7qmmGV86S5;KG7QWE}HDHVdSElPbYm(+zq^p@!2e*+#biuzYMFjg^1fg))k0EzR z77rubjnmDxKo;z(Y#7!BcZ5F`)W6c+oU<{0_iur#+T5xm>QxjFloR1IEfnAk2( zt}Ngq%jfO-8TUnX*vBD!W#ax-wlsCbn;T*umVVJTxmLVwSl|)UYPGm=pBg@hDZ0s zf|)7Tqjp?*O_IlzZ%=o}uB|WYB+D_RdM4=_Y|QBL2B+2+^V#H| zc;e*go{3OJ_$e|8>rr@wVN5mKze63{cIGm(;MkR4ao?+6j&7h#e|Qkug24gl6J%xK zW)?D}GQ4$UCyI(K@Uo2njlp{?Byf3aQSovq<^udS{faxpVDGd73h0BzMo--Iuf0O2 zaU~m1&8D=ovn*U80X}ebAPC?B5x7FdaZV=^mb;uhFBPEV9RPvVk+zvyA!J7hx}48& z1Z(+ijl*=aGpz;Ae@|0Xl#BDM2{P*HP&CzYgYZ^oIJkh|f5=lmN)wai?iEt;&v575 z3z{PAaa>R{k89z@#fokG+OJcN;KKikF z)LdTf=Z1ehc8zpvnQQYQk1F*W`5cH2aKGAj!#5Gy5&J}M5-tj4T$WCjc?;fbL{Glv zDVxO=t_8yOsZOyfc|2fqI$1#MOlM-nLg}D-_`;m^f5fuWO=L~#p->dPDkn`P{7j^x zc>@AQ#adcI$C8PDeqRcB!p+~`FuZYvsx1Qg#%XrPn`$SU+n7CVIQ9?UOsF~avaSEYlH^9CWHAoU?q z8ezi{e`yV1^GQJ6d5sIOPN4b6s13VR=GK*&i8Qxav0t=Z_dAl>;=L$dd>-SwYaGYV#rta(|^>~;dk%gx3^YI!+;YAOsCNb zS&#)oKbrOV&Ck|c#G&1<5%1tpm`g#)-U8OsvvG8Q7uosQi1_;_eLC(BVcd0t5jouzv!CSUV+()6>C1C{iFKXLKd{X2Y27Iy}MXV>yP=R}QsblLdssBAI;(rk}$>re$1AxgIW21AhP! z{Z6ndjhcFH7~$q@W-sGH-(*zee!F0FbsK;RR4hcCD4HWl=J3cIEka@zT`^)DsHM;2 zbeVx}M)mUv%vMo;c7e`@9AcukGS3bMB06*wB9uv#CR z(<-r}Z;d+;P%$5_yzwk{C!%{vPJfiUz?K%*PL6!$E?8l@lVI?JU7!+M9)x9;hi3C? zI>!~iT%{n9$@iE;51kPt+}U>i5GZbW+o8uCyw1Mlz43lPU?qPskk} zWCMTnm~a%T{+kc4Zvg}Be|Wy}c5*UXh8wf#t8mMdEz>5*+D3zAb6*?(xqt4>N(!@{ z#_~_LD@=mh%pRa~VBCdl7tSSKM9hJYC2j`bMVW{1Hmk3`*6*^RgR9xiy_SBld(U#& z-YJfGU^zU))gBD!@TQ)%hiSc5$9l@$p$Pl+qQ;%2PHG)MZoN{6=qVJFK8gM)(+u?h z&VMoofS(ycGu>deQ*r-9Hh*P!z^uApB1_oL#FDqvFY2izTah)0!o$fB+$ox)G@hJF zR=XA4BJ-2)po(zeeZ^o8UgQeQ*bpZ??5c_ag#XZ>@9%_l9n=YvJsMSqxMTJ{aJ+tp zEK-xjkWd10n}rV69d5fm$BuNQT?3-&WmPy^F$b0E9QxkMrr!dZSbw67z61lG0$Vs~%}I~G%CSG@i#(E5R)=gce11cSJ&M;W0OBC zt%_A%v8ugD_Ak6-y??nGcu$g&GwkKds9*^>0!v(i8?pSr64K)$>por}kM1%Vm}F+X znr-RX1zyiPhU%4u88%TN)WY$LBWVb5Pt$~tJFpd^#G?gL#}9%T#I;%0H%80gREk`I zyA&DXik$3ZpMgC=2zV-S7+g-DK;|)m(}Kp(DxutFMq!p+34bYmsX-j3j`#O5EVv(7 zG95u@0I4yT+ExL85>y`J`Vua7e5E#e3H><2QJ9zTx8?w`YG*)})i4w&XPpB^;P6iqln$F+b}1fU|7XnjplH1E8k$uTqv6Q>fW zg8X~$E3gt9gn!Us@Tugwboy=6@I1SsUoPWEkQKP~oPqkQiqG zrD|&(ib;=3hH47X(+#1vj?H5owO=DRjWVjhInB=@7h=GSsxz!d;1QwkGLRDo%9~WP ztBd1$fpnS6v}#y#U8q+hR!TLMs83C95|tC@>4rNn%*-uhXU~Udf}HfbBsNJT zIV~9d_R>VwFkNRg|DsvUcE+$4iHOXhwKdByS*iWP!CL7k@;s@`lEO)NT2C;_j0Ta- zPJfQL3P(WKU{Ic84-~{HG)CiE*%Lsozmn9FkZ$If^y3c{sR8ui<9FdU>*3a;AvkmU zA^wCM!N|RlB;Y^;I92#P1c}#Lnf{1XqizF821kZ+4-{}J3q7XztYBhe8;wRFb`vg; zV|H?~99DzZSa!T$OmGYL0}z~tT)D17J%67m>|WHmoW(6+p#9d?;HY(tRD)dziJ(aE zqV~j~3|a_?`$uzj78VJuIb&SwnkXGxk`d2>QL>4h)q1Too5%silaxSdYxjy&d+0*4 z2#jGqD`3(-LwISQDR0z195Psu*b0GJ0}S6N=FZ@cgwUZOc~(kNNaS0L7Asisa(_h5 zzoRB|6BsHc(_f=yApk?0KE;1IM2BD#G{AMkc?&Vtlh!5Sf+SC;bL^zZy3|fzW-jG% z5@C5^t!i`zLm?PYhmm1s!yl~1gbox zoCpaa-e-JV;dwyHKi;8~DAiI%iv%Ucza%J8E-u$o_@06sWNAI}XoCbPPCQ;5(CrR| zs26-k?^_7d4(CM1o1ILrXf(+XCo`ffNWto^kU2HMq3<;dD&Isr3GIN^;(s~taWo0m z*Owwyb{>Rr1RI!>u-H_GwsgSO(KPhGXcAQV9$+}!5IIo=p+gE8aql(zDU44&^X-M+ zph%jf{g0aREIIxn?kPXt3FKRgX@v1opc+(*a6d*o->Sh?lF;%@N8`)%nsTx-I-8T- zCz|r4&p+mLXBxCqo&GG&s(+61evK?fW2~;la>FC>gcYWxIrFzY6iKv)~CjjGDSe$11TZU0jmWYU;=@8^ReuB^3Iv$i+{Ux_-oe}P#&4#5P0vuu1ylv%!v}PL&|HZ~ z>yu33EM{9_X!;1dD%h8JhRC84L>71BUu`+>>+tor&ySw%{2e}F~5x+8Yxb8vYNw_Roh4Dq0P6gbWa z72B8x-1H|3Tg)J)Ja+>k0LEfuGR1#G`J6Fn$&4>Y$^?#!gkO9Ccc?OxhjFM{L_#H4{Iz`FESyHZf!yc-HhW0j?nhL4cGZdtZ&t z6lW?A%YPZK;Pa5ZTde{0Yb)Ka^d0tI&AV;)F5n;n!+|D4ortseil1jPqt}aJ+tdNF zZTs4;ikTJp7MoO1P``2iJo>dSZ@Ocv=?etk8P;);ZbMrF0PWYik8eA2SAp7ulkUOi zyFtMa6q+o01tStLuwH4Ba;_unAgg|h3w*d-%75Val@nRl$Kc7YKKF+{!=>At>xUU= z6Q3iix@TYJO;?O>vbzge?F2Eu%}UIiZqBOd#Gew9b@GdML?I{ImL)}<^eGz@h{zC5S09nM46|XF64|uw-<;OXwcXQ$#xq>EQ2sh(*RN z>IkP(e}p!u3LlGUWUg5v#8S4RX}DI5u#>Cq7b8TXYq^A_B9k?DO2~}#1O}{psZJO3 z3o%rM+u;cjzzIm3P9uF&0_lKVVox?Cef+RxoLy{}>4Lo+4CK%tm&`W=IHckY;X62O~${J1Go-Lw}TH ze3va;kzKTS5p#&}wG2y+`=M~K3GCJHTQ*dlIXf-b)uefxT`H#?o+93t;d@VW|1 zvkws`kZt)f3hP>~Y`W%A2)I|^J#kRnlP&uw=6wPI$@wSza0M`l5mJZj66WP5+i7@< zRelq$UZ+PX_mf+gGP*92fndf>3x9-#*A-~QJ!RV&jW9KQAY&)pQv$!%xjEzHM^Qln+R{1#LQ|=AL2d)Z8Du& z2|lMqb9IYlPSK#{_+={P`PAql9#wUknE#AB#Bl?0(;3v$k#PqIkp2?+y??$hjgYpeD{OSlo|_8ofb^JZa1hjYxdWwQd>}qhQ3*m#RK818v#x97JJ!y z7&7t(W)!Ylzn}xoYbAM7Vmk7sDSivil$y8UNv)_@#q72g5prJq6K7_~CYTI1vtfy3 z8jVzFZh0Mw*Rf$cXpTb@+J8aC$N~nMJ6dH zDk)(y4raJWtm)MJ<> zLLN7-h*idLMurX{iv>pCSPw|KHLs$LUKGQ*JDem()}n-{O2*rZUf?l}$Yk-8-u5Pw z8q#(HMq!w1(G`$=)qf!#ZR%g4g3H1gz&gYRJH$;qqvxa*Q9)-LoY;;WR8+r}e4@Dq(n zX*7&@6?eX4v`opYZC?sbS$BM07S{n=xffY|pqM>Vn9&Jq3x6QVfbAZKN4mLe3SRgH zhJEBtCD%_jX8`3joG6knpxmF64Ftxcitr(`(R~CFfa88&RU*et<&KCbyKmH zTH6_Fbq{Zy#nzzsb*F+PvWPs<9n^q%6Yz zJe$Dt32#@Z@PAuW3mHlQ^mOx(()MGNj@FMfjbqE973$n89}J(6f2eSPc?d94GdfK0 zV+4u!^;xQ5>{E}3Jo&6zetgw}sEhUV3NuZbZ79!F>2XGY(}QUObVOlUt5GZuF5tkRyJ`FfF(T}NY!Y@LUK&cG08l#+Q;h0jeFk6{^uCL=*?s;WWgdB|JD= zjK(<7j^p*mNK12p=ToslnX3o!iF!_5BEzwPn1A57q}7Vd8?#@ouxVS5B!vp+6kZv_ z)BkMXAvZ>l$P~G5SA3*C3TDDXLNNHr6PUOe7kRIdLK;G6y8V8Bg)4F6a`CU~oB4a} zS0k$k8XV8j3F3{VG0u?~B$=-qN5N{OCOIJ<=&*K_1XZtg0@IQTalM?G*r)e6TwI}@ zn}2F~0h(DaJmM&E$lv07Uy7PIddy-eSZ3!peN>)cPfbGV_Fn$cC0)%fEU~8{mAY`q z9gmjvyQFEOLAg)P*LK4gm=CLG_2~#XpWsWLBOnR~>99R)&(D2bZMP$40K+GyfPep0 zb&ZSxWRC$h32}uqrj+X-=K?FFn;ZdE(3jz@wHmn;>*8z)K0cA4OTR^rWy+1_V;_-(!%-T34e^a z1MUD|+zZn)D@rAU4FC9vIs$t+`5qgrCep2?99*#2Z(2eHqIva#*;=s~Qrf=J4wU`& zfKm!UBBcd;@cDLWD723Y|QgAz6WrFz1laBT@{_ zpd(C&4%domzo4k0XCJ}~wY3emQxGU?CGontN4FejZ(A!l*1(b!2|^NS61i=Xi|guF zu)KUZ92Wqx4}zMxHb@S4uzx|G*O4${omv3E{c_p`>M9x&tyky{UxXjCgh(Uc6L94b z(TJ{kyz?^|8Aqtg`FkZhRnC17J?Rb!u+A{Xqj-R*JD8TT}6sOoT%jyS&_m^1d}Bm3bqmPi{07G z8cmqSRSeS_yYH#F(vP5@B7P!^IFm-gU^Cs(%}HMnbevh+AKh@3WRn|mdOh62ISi9b zigvxcRtpesx0A_{gnt7Zu^Qgjzr;%NY%Y-yh^}J(T4$kPdeC?j4J&3NoZ;~|Ka~i8 zX3d~9lt5&Z4A(@?wn+fnQUyH8eHW84E_#VL94jPbF#2an%-B04YKNxSyWtXPOoMX_ zqx;oyQ{ABc2uk@l9~PGQVe>FO>MD=((%J(#L#z21h1m--Sbtz|sVhgyu$*AN#Wm~N zk$j0IK0Qj=X*c4`Mr^@9U*f_nDM*s@_?+YnzF%!g%W9mI`)CK(x0QhC4Z$J7V|1Aj z5~2&s&90UNI`~R{54NHX0e$;hu-gPJF9UWc8hj*;;iIj@nBl7*Hj&i;?u=zIN`Odu zf;1rM3t)6`RezbW{H6O1%%CC`_4%m0ek^Q_TE%*3i6JfdhJ`loHisg>%4%4ezCxIq z61A-wOc!KU47dchX_;9-nC9IO*VJQ;y9U+4d=;G`JTngSSk8~iTK z7S!;FsrU2}ms2AkT0Lz(dxlIFQ&CcwU#_Tx65mcV4ENN(DlRQe8P0q2P?MQA;F3fh z!yAYbq<=~-2NTsGz5={M35<|TXbH@9+6M;!&=OZJVUz(?nQe3m4##MZ5Y>j)f}f4- zG)2JE8_2o^$HHQ{5znIcG&b$<5d`N;{68EHtKZsLUHrIo!r~$pt$x2kNh#{eYT<{e z>(bXn%stP;8wfo}?3`$EUu+LZZ1Du}i=nJuWPgm767s^d0KMS6fY9(Hx7;U=O7K-k z0HfoE1g$g>I#reodNzW*hZ5uF^ftf5Y_RoON{~lz(kR zT0J88)nTY9-{DGwWxe>m{zE)L#J_YdgbEE;y6-W|*sR&e49S)59%i2JK&41A(_xLZ z>Sj8>?qR~<7rrkkExzbpZQLLNgm4D=%5p852LB$TZbVPc5d0tv}Hi&@*@k-X8MW}5H z(hjIE&5AUGD;@5r{AaUD%_{3G6*DiD2C0O-dw+M!!1hi-Z8;hWUgCzeCD?!e9yD%1 zPC4Jq$1<4(E#4CgW7yvc?{9OLeWmNhEd@~g{FU@HRRcktU{~d1&p~Loe}6oN{aP+B zghOd!iINo2RO34vSX?SYKC+_%Yq7z+i1B8f9w!`{5a;s(z(~D-G;GCw42Hqb`1er+ z)*69a0WjK|K8{d9M_^@l_H$qtZ-`&MNd>_tAmPs}u!wuG z^qqtV&y{kmVZt*0M`{RtrPn*W^D=4WHYjy~;~f}_jbqSbxsexz1Ipw>=c*gmP56n; z9I0Mjj!x*%Kdx8rd9kjlRLp|BuPY)Fo7bi%GaOg7a2cxeW!|!uM1QJ_xa8x!Bo%4_ z?$@TV5JZ!%U7aT}AYmmRUiB410s_pD@f88l)#w__dLf`(ZpG`#pu9)R`D}DNy;(O- z#IQ^_$@Nb_L)*h7GsUPXQIb?MIsJ?pZ&=81F%}$hh}ML5kz<-nm&@r)ns?1GOE_&d z?3cf=|H zr-$s>{zStP2TG69Yb}FBnurNZXgv%Ni<~x^gRn>`_eyEiQt)eSTw?QZwPcK3L=x7q zAFXF2;-&r@sb#u}TbJMk&{Cn8E7iwe8t*yNg)qo+g-fKEn|~8JuGpmMu~$L~#;RG@ zMEEJyvBOt!4ONfX?Kq0@FXLBy8W@-P2*jSil--*A?hH9Yknv=UyMD~vphHax3~|90 ze6bkw$ynE~o=ni5oPXg`H`7qZB&@h6`J{YP7KH_(r7$XCJKQWOw-L|ZxuOy%92KZl zFIA;c4Jhj~4}ZAoU6BHL%i*whHctId6oq3{FQzS0OvtQbw*yo?D)ocqOkWDg-C`DD zSvHNG2B!EB|J&$zsk5>~^9;t=!e+)WraREVKXJJ1nuyRVoA^*6_>rWd*B<=x;);e{t#V?{Z z{baxuV2F(~XB$&VvAN9T`}53PK?@I`fU8!(^GUUVk#gV*>?*hym8|M*R~MY*zUSR1 z81^z8iGQ{mw^*JZZ6vDoRWzLCrg8x$Fd`5Ret!g_TCttH4g%5}7gvS#nEPJRV?;U7 zw|PTxFH{Vj?gR2!9=w&quKTmApT@^C=G8tmXTWD!1_b zNIm7ISW@C&Ej}H4k>dxO>F99DgHoKm-iadM{6JIpM0zDJX~pv7!YVzlK0Egy*R$3Zk+V&MtiwO51Zb1 zbmQcf-7xntl_h~~w%Xq!o}$0R2=Dfx5~A_OLHws;wwQyQiA={PA^dF5u8=E1+bA~G_CGkGK~j6y1edU=9~MO8pynmbc2VsWy1gRZl_7)@5jhBRYYub9N#KY#Rn*S_*- zkvYmE6oE#C1s#>cF57z^M4m|~74F}vm-Nd^H1Ftgl97h`kZr4+ib)s}!Yc)pe}>4J-KyYFkQq{o3Ns^tB{<#}QEtR71)byVPNkjL%xTXLRl8mWySQ(zvmE zMuldZTj@SqfikT=Jn#g=CVww3#n+Ea*|7Y_n6cvZ2r=M?_;P`T^_9U}Qpa~)HL8{A zj^_R|xK_U;QKXFtv}|=l17-!_<$i;4p|iGZX=>xUShj5GzSM2FM<55BGD%;r7MV$9 zQyRW}}wtuwu?UA`KD^?}s8^e0Kl|X>VP^|d8iwl=+ zD%SAjBAdvWRN>qu%oWIu{2rQ)cwiAAWysIQ)xU~y6`WZM^^Q3-g z&FX3~V|(ZIHH;J{HV?opn9FbpjN~LTT>1h0v7+eJk57MeuX=g|Q%&+O@dT1RZpC&| zBc@)=c={*+<24wCde8T0Y*!q?VoWFBREzkCxU71Etr`vrRe!*}%5QOGFjPPtouqvH ztG~DO|0>aW1qSXefYHE!$-fwa~$Ga)f?G%M~slUIgxA%ZELz2p~0=$R6q+@aZQ0n4NE=P zfOKv=*ngmW;t#}iV>7ArM?aZ_)(uzkGG+-`V-XC;Us$n$Eh6Jl3Ev@@Vi}U7a_(Gj z^Tm>)*;Omu1cuo;@Vsd&Ae~zcB>OroGC%T1G$-S`Mtdy(Q4Nxl)@YBX71!@ytQtsr zs#h~ySYotX>Xo_QuV&xP=I>|GB@1SwNkoQWFn?Z0yYfofmshWG4X~w|%WakUIQMO`fpFvtZSm+;SJ=HvRB5kVT5>ZYR0YLDqA%h6% zg@PMHE^C*xb&pKQkkNTpGs$QNzZJ7%k4z%bX#!9wQ|-?gam6w`&=1F!?>^F(&T)($ z9)C1z^is<)q)m;U1fUQZF=EKNiBqT594SKt2+m-v=R)~#WAlo_w zmaGf;-hLM`ke1hf8A~a#q0BCXW3&1l$3=0HeMRAJtcmuXu??Ip;<|4I)sA$^4{p)v5Frq_ZpqVktnun{A

(|RBdFGt6QMu!t#1+Nr7oFII6 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 DGefrv delta 123658 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˻r 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

N*^(}nSHk5-On+Sy_5~x?(zmVWtYXVhm^%Z; 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%0A%_Z2E#dXA1{zXwAC>GBYW^%&X0Av}M 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

4*6_=eZ#^0}l%s&o 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

n7CDV|HJ9SW_TMB5Uz1Sw(EA)e;%s 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

4hEBd=?rbP>&*^#7y`l1 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