diff --git a/Gruntfile.js b/Gruntfile.js index 4f1e35eee3..c1f0ee9aaa 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -35,16 +35,6 @@ module.exports = function(grunt) { } }; - // poor man's deep copy - var deepCopy = function(x) { - return JSON.parse(JSON.stringify(x)); - }; - - tsJSON.dev_release = deepCopy(tsJSON.dev); - delete tsJSON.dev_release.options.compiler; - tsJSON.test_release = deepCopy(tsJSON.test); - delete tsJSON.test_release.options.compiler; - var bumpJSON = { options: { files: ['package.json', 'bower.json'], @@ -58,7 +48,6 @@ module.exports = function(grunt) { var FILES_TO_COMMIT = ['plottable.js', 'plottable.min.js', 'plottable.d.ts', - 'examples/exampleUtil.js', 'test/tests.js', "plottable.css", "plottable.zip", @@ -336,11 +325,10 @@ module.exports = function(grunt) { "concat:tests", ]); grunt.registerTask("default", "launch"); - function makeDevCompile(release) { - return [ + var compile_task = [ "update_ts_files", "update_test_ts_files", - release ? "ts:dev_release" : "ts:dev", + "ts:dev", "concat:plottable", "concat:definitions", "sed:definitions", @@ -355,18 +343,16 @@ module.exports = function(grunt) { "concat:plottable_multifile", "sed:plottable_multifile", "clean:tscommand" - ]; - } + ]; - grunt.registerTask("dev-compile", makeDevCompile(false)); - grunt.registerTask("release-compile", makeDevCompile(true)); + grunt.registerTask("dev-compile", compile_task); grunt.registerTask("release:patch", ["bump:patch", "dist-compile", "gitcommit:version"]); grunt.registerTask("release:minor", ["bump:minor", "dist-compile", "gitcommit:version"]); grunt.registerTask("release:major", ["bump:major", "dist-compile", "gitcommit:version"]); grunt.registerTask("dist-compile", [ - "release-compile", + "dev-compile", "blanket_mocha", "tslint", "ts:verify_d_ts", diff --git a/Rakefile b/Rakefile index 1fe9600109..dd3dd3cf86 100644 --- a/Rakefile +++ b/Rakefile @@ -105,7 +105,7 @@ def get_template padding: 20px; } - + @@ -122,5 +122,6 @@ def get_template
-} + +} end diff --git a/bower.json b/bower.json index ab85a5cd5c..f09ece7a26 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "plottable", "description": "A library for creating charts out of D3", - "version": "0.31.0", + "version": "0.32.0", "main": ["plottable.js", "plottable.css"], "license": "MIT", "ignore": [ diff --git a/package.json b/package.json index 7dc9618055..b44cb6a0e4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "plottable.js", "description": "A library for creating charts out of D3", - "version": "0.31.0", + "version": "0.32.0", "repository": { "type": "git", "url": "https://github.com/palantir/plottable.git" @@ -15,7 +15,7 @@ "grunt-cli": "0.1.6", "grunt-contrib-watch": "~0.5.3", "load-grunt-tasks": "~0.2.0", - "grunt-ts": "~1.11.6", + "grunt-ts": "~1.12.1", "grunt-tslint": "~0.4.0", "grunt-contrib-concat": "~0.3.0", "grunt-mocha-phantomjs": "~0.4.0", diff --git a/plottable-dev.d.ts b/plottable-dev.d.ts index 11c94f1c0d..35f28a2994 100644 --- a/plottable-dev.d.ts +++ b/plottable-dev.d.ts @@ -3,98 +3,98 @@ 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] - */ + * 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 - */ + * + * @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] - */ + * 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 - * - * Due to the fact that D3.Sets store strings internally, return type is always a string set - * - * @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 - */ + * Takes two sets and returns the intersection + * + * Due to the fact that D3.Sets store strings internally, return type is always a string set + * + * @param {D3.Set} set1 The first set + * @param {D3.Set} set2 The second set + * @return {D3.Set} A set that contains elements that appear in both set1 and set2 + */ function intersection(set1: D3.Set, set2: D3.Set): D3.Set; /** - * Take an accessor object (may be a string to be made into a key, or a value, or a color code) - * and "activate" it by turning it into a function in (datum, index, metadata) - */ + * Take an accessor object (may be a string to be made into a key, or a value, or a color code) + * and "activate" it by turning it into a function in (datum, index, metadata) + */ function accessorize(accessor: any): _IAccessor; /** - * Takes two sets and returns the union - * - * Due to the fact that D3.Sets store strings internally, return type is always a string set - * - * @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 - */ + * Takes two sets and returns the union + * + * Due to the fact that D3.Sets store strings internally, return type is always a string set + * + * @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; /** - * Populates a map from an array of keys and a transformation function. - * - * @param {string[]} keys The array of keys. - * @param {(string) => T} transform A transformation function to apply to the keys. - * @return {D3.Map} A map mapping keys to their transformed values. - */ - function populateMap(keys: string[], transform: (key: string) => T): D3.Map; + * Populates a map from an array of keys and a transformation function. + * + * @param {string[]} keys The array of keys. + * @param {(string, number) => T} transform A transformation function to apply to the keys. + * @return {D3.Map} A map mapping keys to their transformed values. + */ + function populateMap(keys: string[], transform: (key: string, index: number) => T): D3.Map; /** - * Take an accessor object, activate it, and partially apply it to a Plot's datasource's metadata - */ + * Take an accessor object, activate it, and partially apply it to a Plot's datasource's metadata + */ function _applyAccessor(accessor: _IAccessor, plot: Abstract.Plot): (d: any, i: number) => any; /** - * Take an array of values, and return the unique values. - * Will work iff ∀ a, b, a.toString() == b.toString() => a == b; will break on Object inputs - * - * @param {T[]} values The values to find uniqueness for - * @return {T[]} The unique values - */ + * Take an array of values, and return the unique values. + * Will work iff ∀ a, b, a.toString() == b.toString() => a == b; will break on Object inputs + * + * @param {T[]} values The values to find uniqueness for + * @return {T[]} The unique values + */ function uniq(arr: T[]): T[]; /** - * 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 (called with index as arg) - * @param {number} count The length of the array to generate - * @return {any[]} - */ + * 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 (called with index as arg) + * @param {number} count The length of the array to generate + * @return {any[]} + */ function createFilledArray(value: T, count: number): T[]; function createFilledArray(func: (index?: number) => T, count: number): T[]; /** - * @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. - */ + * @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. - */ + * 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 ===. - */ + * @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; function max(arr: number[], default_val?: number): number; function max(arr: T[], acc: (x: T) => number, default_val?: number): number; @@ -109,41 +109,41 @@ 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. - */ + * 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; } @@ -154,9 +154,9 @@ declare module Plottable { declare module Plottable { module _Util { class IDCounter { - public increment(id: any): number; - public decrement(id: any): number; - public get(id: any): number; + increment(id: any): number; + decrement(id: any): number; + get(id: any): number; } } } @@ -165,62 +165,62 @@ 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... - */ + * 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 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; + * 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 + */ + 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 + */ + 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 + */ + has(key: any): boolean; + /** + * Return an array of the values in the key-value store + * + * @return {any[]} The values in the store + */ + values(): any[]; + /** + * Return an array of keys in the key-value store + * + * @return {any[]} The keys in the store + */ + 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 + */ + 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 + */ + delete(key: any): boolean; } } } @@ -230,35 +230,35 @@ 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 + * + * @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); /** - * 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; + * 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). + */ + 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; + * 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. + */ + clear(): Cache; } } } @@ -276,49 +276,49 @@ declare module Plottable { (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 - */ + * 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. - */ + * 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 { /** - * @param {string} s The string to be measured. - * @return {Dimensions} The width and height of the measured text. - */ - public measure: TextMeasurer; + * @param {string} s The string to be measured. + * @return {Dimensions} The width and height of the measured text. + */ + 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. - */ + * @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 the cache, if it seems that the text has changed size. - */ - public clear(): CachingCharacterMeasurer; + * Clear the cache, if it seems that the text has changed size. + */ + 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 - */ + * 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; /** - * 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. - */ + * Takes a line, a width to fit it in, and a text measurer. Will attempt to add ellipses to the end of the line, + * shortening the line as required to ensure that it fits within width. + */ function addEllipsesToLine(line: string, width: number, measureText: TextMeasurer): string; function writeLineHorizontally(line: string, g: D3.Selection, width: number, height: number, xAlign?: string, yAlign?: string): { width: number; @@ -339,12 +339,12 @@ declare module Plottable { 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; + * @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, orientation?: string, write?: IWriteOptions): IWriteTextResult; } } } @@ -359,15 +359,15 @@ declare module Plottable { 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. - */ + * 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. - */ + * 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; } } @@ -377,10 +377,10 @@ declare module Plottable { module _Util { module DOM { /** - * Gets the bounding box of an element. - * @param {D3.Selection} element - * @returns {SVGRed} The bounding box. - */ + * 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; @@ -402,75 +402,75 @@ declare module Plottable { var MILLISECONDS_IN_ONE_DAY: number; module 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. - */ + * 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. + */ function 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. - */ + * 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. + */ function 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. - */ + * 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. + */ function general(precision?: number, onlyShowUnchanged?: boolean): (d: any) => string; /** - * Creates a formatter that stringifies its input. - * - * @returns {Formatter} A formatter that stringifies its input. - */ + * Creates a formatter that stringifies its input. + * + * @returns {Formatter} A formatter that stringifies its input. + */ function 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. - */ + * 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. + */ function 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. - */ + * 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. + */ function siSuffix(precision?: number): (d: any) => string; /** - * Creates a formatter that displays dates. - * - * @returns {Formatter} A formatter for time/date values. - */ + * Creates a formatter that displays dates. + * + * @returns {Formatter} A formatter for time/date values. + */ function 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. - */ + * 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. + */ function relativeDate(baseValue?: number, increment?: number, label?: string): (d: any) => string; } } @@ -484,8 +484,8 @@ declare module Plottable { declare module Plottable { module Core { /** - * Colors we use as defaults on a number of graphs. - */ + * Colors we use as defaults on a number of graphs. + */ class Colors { static CORAL_RED: string; static INDIGO: string; @@ -506,11 +506,11 @@ declare module Plottable { declare module Plottable { module Abstract { /** - * A class most other Plottable classes inherit from, in order to have a - * unique ID. - */ + * A class most other Plottable classes inherit from, in order to have a + * unique ID. + */ class PlottableObject { - public _plottableID: number; + _plottableID: number; } } } @@ -519,76 +519,76 @@ 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) - */ + * 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. - */ + * 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; } /** - * 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. - */ + * 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; + listenable: IListenable; /** - * Constructs 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. - */ + * Constructs 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); /** - * 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; + * 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 + */ + 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; + * Call all listening callbacks, optionally with arguments passed through. + * + * @param ...args A variable number of optional arguments + * @returns {Broadcaster} this object + */ + 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 the callback associated with a key. + * + * @param key The key to deregister. + * @returns {Broadcaster} this object + */ + deregisterListener(key: any): Broadcaster; /** - * Deregisters all listeners and callbacks associated with the broadcaster. - * - * @returns {Broadcaster} this object - */ - public deregisterAllListeners(): void; + * Deregisters all listeners and callbacks associated with the broadcaster. + * + * @returns {Broadcaster} this object + */ + deregisterAllListeners(): void; } } } @@ -596,46 +596,46 @@ declare module Plottable { declare module Plottable { class Dataset extends Abstract.PlottableObject implements Core.IListenable { - public broadcaster: Core.Broadcaster; + broadcaster: any; /** - * Constructs a new set. - * - * A Dataset is mostly just a wrapper around an any[], Dataset is the - * data you're going to plot. - * - * @constructor - * @param {any[]} data The data for this DataSource (default = []). - * @param {any} metadata An object containing additional information (default = {}). - */ + * Constructs a new set. + * + * A Dataset is mostly just a wrapper around an any[], Dataset is the + * data you're going to plot. + * + * @constructor + * @param {any[]} data The data for this DataSource (default = []). + * @param {any} metadata An object containing additional information (default = {}). + */ constructor(data?: any[], metadata?: any); /** - * Gets the data. - * - * @returns {DataSource|any[]} The calling DataSource, or the current data. - */ - public data(): any[]; + * Gets the data. + * + * @returns {DataSource|any[]} The calling DataSource, or the current data. + */ + data(): any[]; /** - * Sets the data. - * - * @param {any[]} data The new data. - * @returns {Dataset} The calling Dataset. - */ - public data(data: any[]): Dataset; + * Sets the data. + * + * @param {any[]} data The new data. + * @returns {Dataset} The calling Dataset. + */ + data(data: any[]): Dataset; /** - * Get the metadata. - * - * @returns {any} the current - * metadata. - */ - public metadata(): any; + * Get the metadata. + * + * @returns {any} the current + * metadata. + */ + metadata(): any; /** - * Set the metadata. - * - * @param {any} metadata The new metadata. - * @returns {Dataset} The calling Dataset. - */ - public metadata(metadata: any): Dataset; - public _getExtent(accessor: _IAccessor, typeCoercer: (d: any) => any): any[]; + * Set the metadata. + * + * @param {any} metadata The new metadata. + * @returns {Dataset} The calling Dataset. + */ + metadata(metadata: any): Dataset; + _getExtent(accessor: _IAccessor, typeCoercer: (d: any) => any): any[]; } } @@ -645,33 +645,33 @@ declare module Plottable { module RenderController { module RenderPolicy { /** - * A policy to render components. - */ + * A policy to render components. + */ interface IRenderPolicy { render(): any; } /** - * Never queue anything, render everything immediately. Useful for - * debugging, horrible for performance. - */ + * Never queue anything, render everything immediately. Useful for + * debugging, horrible for performance. + */ class Immediate implements IRenderPolicy { - public render(): void; + render(): void; } /** - * The default way to render, which only tries to render every frame - * (usually, 1/60th of a second). - */ + * The default way to render, which only tries to render every frame + * (usually, 1/60th of a second). + */ class AnimationFrame implements IRenderPolicy { - public render(): void; + render(): void; } /** - * Renders with `setTimeout`. This is generally an inferior way to render - * compared to `requestAnimationFrame`, but it's still there if you want - * it. - */ + * Renders with `setTimeout`. This is generally an inferior way to render + * compared to `requestAnimationFrame`, but it's still there if you want + * it. + */ class Timeout implements IRenderPolicy { - public _timeoutMsec: number; - public render(): void; + _timeoutMsec: number; + render(): void; } } } @@ -682,47 +682,47 @@ 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. - * - * If you want to always have immediate rendering (useful for debugging), - * call - * ```typescript - * Plottable.Core.RenderController.setRenderPolicy( - * new Plottable.Core.RenderController.RenderPolicy.Immediate() - * ); - * ``` - */ + * 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. + * + * If you want to always have immediate rendering (useful for debugging), + * call + * ```typescript + * Plottable.Core.RenderController.setRenderPolicy( + * new Plottable.Core.RenderController.RenderPolicy.Immediate() + * ); + * ``` + */ module RenderController { var _renderPolicy: RenderPolicy.IRenderPolicy; function setRenderPolicy(policy: string): void; function setRenderPolicy(policy: RenderPolicy.IRenderPolicy): void; /** - * If the RenderController is enabled, we enqueue the component for - * render. Otherwise, it is rendered immediately. - * - * @param {Abstract.Component} component Any Plottable component. - */ + * 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. - */ + * 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; /** - * Render everything that is waiting to be rendered right now, instead of - * waiting until the next frame. - * - * Useful to call when debugging. - */ + * Render everything that is waiting to be rendered right now, instead of + * waiting until the next frame. + * + * Useful to call when debugging. + */ function flush(): void; } } @@ -732,47 +732,47 @@ 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. - */ + * 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 { /** - * Checks if the window has been resized and the RenderController - * has not yet been flushed. - * - * @returns {boolean} If the window has been resized/RenderController - * has not yet been flushed. - */ + * Checks if the window has been resized and the RenderController + * has not yet been flushed. + * + * @returns {boolean} If the window has been resized/RenderController + * has not yet been flushed. + */ function resizing(): boolean; /** - * Sets that it is not resizing anymore. Good if it stubbornly thinks - * it is still resizing, or for cancelling the effects of resizing - * prematurely. - */ + * Sets that it is not resizing anymore. Good if it stubbornly thinks + * it is still resizing, or for cancelling the effects of resizing + * prematurely. + */ function clearResizing(): void; /** - * Registers a component. - * - * When the window is resized, ._invalidateLayout() is invoked on the - * component, which will enqueue the component for layout and rendering - * with the RenderController. - * - * @param {Component} component Any Plottable component. - */ + * Registers a component. + * + * When the window is resized, ._invalidateLayout() is invoked on the + * component, which will enqueue the component for layout and rendering + * with the RenderController. + * + * @param {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 {Component} component Any Plottable component. - */ + * Deregisters the components. + * + * The component will no longer receive updates on window resize. + * + * @param {Component} component Any Plottable component. + */ function deregister(c: Abstract.Component): void; } } @@ -791,14 +791,14 @@ declare module Plottable { (datum: any, index?: number, metadata?: any): any; } /** - * A function to map across the data in a DataSource. For example, if your - * data looked like `{foo: 5, bar: 6}`, then a popular function might be - * `function(d) { return d.foo; }`. - * - * Index, if used, will be the index of the datum in the array. - */ + * A function to map across the data in a DataSource. For example, if your + * data looked like `{foo: 5, bar: 6}`, then a popular function might be + * `function(d) { return d.foo; }`. + * + * Index, if used, will be the index of the datum in the array. + */ interface IAppliedAccessor { - (datum: any, index: number): any; + (datum?: any, index?: number): any; } interface _IProjector { accessor: _IAccessor; @@ -806,19 +806,19 @@ declare module Plottable { attribute: string; } /** - * A mapping from attributes ("x", "fill", etc.) to the functions that get - * that information out of the data. - * - * So if my data looks like `{foo: 5, bar: 6}` and I want the radius to scale - * with both `foo` and `bar`, an entry in this type might be `{"r": - * function(d) { return foo + bar; }`. - */ + * A mapping from attributes ("x", "fill", etc.) to the functions that get + * that information out of the data. + * + * So if my data looks like `{foo: 5, bar: 6}` and I want the radius to scale + * with both `foo` and `bar`, an entry in this type might be `{"r": + * function(d) { return foo + bar; }`. + */ interface IAttributeToProjector { [attrToSet: string]: IAppliedAccessor; } /** - * A simple bounding box. - */ + * A simple bounding box. + */ interface SelectionArea { xMin: number; xMax: number; @@ -838,26 +838,26 @@ declare module Plottable { yMax: number; } /** - * The range of your current data. For example, [1, 2, 6, -5] has the IExtent - * `{min: -5, max: 6}`. - * - * The point of this type is to hopefully replace the less-elegant `[min, - * max]` extents produced by d3. - */ + * The range of your current data. For example, [1, 2, 6, -5] has the IExtent + * `{min: -5, max: 6}`. + * + * The point of this type is to hopefully replace the less-elegant `[min, + * max]` extents produced by d3. + */ interface IExtent { min: number; max: number; } /** - * A simple location on the screen. - */ + * A simple location on the screen. + */ interface Point { x: number; y: number; } /** - * A key that is also coupled with a dataset and a drawer. - */ + * A key that is also coupled with a dataset and a drawer. + */ interface DatasetDrawerKey { dataset: Dataset; drawer: Abstract._Drawer; @@ -869,96 +869,96 @@ declare module Plottable { declare module Plottable { class Domainer { /** - * Constructs a new Domainer. - * - * @constructor - * @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. - */ + * Constructs a new Domainer. + * + * @constructor + * @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[]); /** - * @param {any[][]} extents The list of extents to be reduced to a single - * extent. - * @param {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. - * @returns {any[]} The domain, as a merging of all exents, as a [min, max] - * pair. - */ - public computeDomain(extents: any[][], scale: Abstract.QuantitativeScale): any[]; + * @param {any[][]} extents The list of extents to be reduced to a single + * extent. + * @param {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. + * @returns {any[]} The domain, as a merging of all exents, as a [min, max] + * pair. + */ + 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]. - * - * @returns {Domainer} The calling Domainer. - */ - public pad(padProportion?: number): Domainer; + * 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]. + * + * @returns {Domainer} The calling Domainer. + */ + pad(padProportion?: number): Domainer; /** - * Adds 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. - * @returns {Domainer} The calling domainer - */ - public addPaddingException(exception: any, key?: string): Domainer; + * Adds 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. + * @returns {Domainer} The calling domainer + */ + addPaddingException(exception: any, key?: string): Domainer; /** - * Removes 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; + * Removes 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 + */ + removePaddingException(keyOrException: any): Domainer; /** - * Adds 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. - * @returns {Domainer} The calling domainer - */ - public addIncludedValue(value: any, key?: string): Domainer; + * Adds 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. + * @returns {Domainer} The calling domainer + */ + 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; + * 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 + */ + 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; + * 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. + */ + nice(count?: number): Domainer; } } @@ -966,109 +966,109 @@ declare module Plottable { declare module Plottable { module Abstract { class Scale extends PlottableObject implements Core.IListenable { - public _d3Scale: D3.Scale.Scale; - public _autoDomainAutomatically: boolean; - public broadcaster: Core.Broadcaster; - public _rendererAttrID2Extent: { - [rendererAttrID: string]: D[]; + _d3Scale: D3.Scale.Scale; + _autoDomainAutomatically: boolean; + broadcaster: any; + _rendererAttrID2Extent: { + [x: string]: D[]; }; - public _typeCoercer: (d: any) => any; - /** - * Constructs a new Scale. - * - * A Scale is a wrapper around a D3.Scale.Scale. A Scale is really just a - * function. Scales have a domain (input), a range (output), and a function - * from domain to range. - * - * @constructor - * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. - */ + _typeCoercer: (d: any) => any; + /** + * Constructs a new Scale. + * + * A Scale is a wrapper around a D3.Scale.Scale. A Scale is really just a + * function. Scales have a domain (input), a range (output), and a function + * from domain to range. + * + * @constructor + * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. + */ constructor(scale: D3.Scale.Scale); - public _getAllExtents(): D[][]; - public _getExtent(): D[]; - /** - * Modifies the domain on the scale so that it includes the extent of all - * perspectives it depends on. This will normally happen automatically, but - * if you set domain explicitly with `plot.domain(x)`, you will need to - * call this function if you want the domain to neccessarily include all - * the data. - * - * Extent: The [min, max] pair for a Scale.Quantitative, all covered - * strings for a Scale.Ordinal. - * - * Perspective: A combination of a Dataset and an Accessor that - * represents a view in to the data. - * - * @returns {Scale} The calling Scale. - */ - public autoDomain(): Scale; - public _autoDomainIfAutomaticMode(): void; - /** - * Computes the range value corresponding to a given domain value. In other - * words, apply the function to value. - * - * @param {R} value A domain value to be scaled. - * @returns {R} The range value corresponding to the supplied domain value. - */ - public scale(value: D): R; - /** - * Gets the domain. - * - * @returns {D[]} The current domain. - */ - public domain(): D[]; - /** - * Sets the domain. - * - * @param {D[]} values If provided, the new value for the domain. On - * a QuantitativeScale, this is a [min, max] pair, or a [max, min] pair to - * make the function decreasing. On Scale.Ordinal, this is an array of all - * input values. - * @returns {Scale} The calling Scale. - */ - public domain(values: D[]): Scale; - public _getDomain(): any[]; - public _setDomain(values: D[]): void; - /** - * Gets the range. - * - * In the case of having a numeric range, it will be a [min, max] pair. In - * the case of string range (e.g. Scale.InterpolatedColor), it will be a - * list of all possible outputs. - * - * @returns {R[]} The current range. - */ - public range(): R[]; - /** - * Sets the range. - * - * In the case of having a numeric range, it will be a [min, max] pair. In - * the case of string range (e.g. Scale.InterpolatedColor), it will be a - * list of all possible outputs. - * - * @param {R[]} values If provided, the new values for the range. - * @returns {Scale} The calling Scale. - */ - public range(values: R[]): Scale; - /** - * Constructs 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 {D[]} extent The new extent to be included in the scale. - */ - public _updateExtent(plotProvidedKey: string, attr: string, extent: D[]): Scale; - public _removeExtent(plotProvidedKey: string, attr: string): Scale; + _getAllExtents(): D[][]; + _getExtent(): D[]; + /** + * Modifies the domain on the scale so that it includes the extent of all + * perspectives it depends on. This will normally happen automatically, but + * if you set domain explicitly with `plot.domain(x)`, you will need to + * call this function if you want the domain to neccessarily include all + * the data. + * + * Extent: The [min, max] pair for a Scale.Quantitative, all covered + * strings for a Scale.Ordinal. + * + * Perspective: A combination of a Dataset and an Accessor that + * represents a view in to the data. + * + * @returns {Scale} The calling Scale. + */ + autoDomain(): Scale; + _autoDomainIfAutomaticMode(): void; + /** + * Computes the range value corresponding to a given domain value. In other + * words, apply the function to value. + * + * @param {R} value A domain value to be scaled. + * @returns {R} The range value corresponding to the supplied domain value. + */ + scale(value: D): R; + /** + * Gets the domain. + * + * @returns {D[]} The current domain. + */ + domain(): D[]; + /** + * Sets the domain. + * + * @param {D[]} values If provided, the new value for the domain. On + * a QuantitativeScale, this is a [min, max] pair, or a [max, min] pair to + * make the function decreasing. On Scale.Ordinal, this is an array of all + * input values. + * @returns {Scale} The calling Scale. + */ + domain(values: D[]): Scale; + _getDomain(): any[]; + _setDomain(values: D[]): void; + /** + * Gets the range. + * + * In the case of having a numeric range, it will be a [min, max] pair. In + * the case of string range (e.g. Scale.InterpolatedColor), it will be a + * list of all possible outputs. + * + * @returns {R[]} The current range. + */ + range(): R[]; + /** + * Sets the range. + * + * In the case of having a numeric range, it will be a [min, max] pair. In + * the case of string range (e.g. Scale.InterpolatedColor), it will be a + * list of all possible outputs. + * + * @param {R[]} values If provided, the new values for the range. + * @returns {Scale} The calling Scale. + */ + range(values: R[]): Scale; + /** + * Constructs a copy of the Scale with the same domain and range but without + * any registered listeners. + * + * @returns {Scale} A copy of the calling Scale. + */ + 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 {D[]} extent The new extent to be included in the scale. + */ + _updateExtent(plotProvidedKey: string, attr: string, extent: D[]): Scale; + _removeExtent(plotProvidedKey: string, attr: string): Scale; } } } @@ -1077,114 +1077,114 @@ declare module Plottable { declare module Plottable { module Abstract { class QuantitativeScale extends Scale { - public _d3Scale: D3.Scale.QuantitativeScale; - public _numTicks: number; - public _PADDING_FOR_IDENTICAL_DOMAIN: number; - public _userSetDomainer: boolean; - public _domainer: Domainer; - public _typeCoercer: (d: any) => number; - /** - * Constructs a new QuantitativeScale. - * - * A QuantitativeScale is a Scale that maps anys to numbers. It - * is invertible and continuous. - * - * @constructor - * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale - * backing the QuantitativeScale. - */ + _d3Scale: D3.Scale.QuantitativeScale; + _numTicks: number; + _PADDING_FOR_IDENTICAL_DOMAIN: number; + _userSetDomainer: boolean; + _domainer: Domainer; + _typeCoercer: (d: any) => number; + /** + * Constructs a new QuantitativeScale. + * + * A QuantitativeScale is a Scale that maps anys to numbers. It + * is invertible and continuous. + * + * @constructor + * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale + * backing the QuantitativeScale. + */ constructor(scale: D3.Scale.QuantitativeScale); - public _getExtent(): D[]; - /** - * Retrieves the domain value corresponding to a supplied range value. - * - * @param {number} value: A value from the Scale's range. - * @returns {D} The domain value corresponding to the supplied range value. - */ - public invert(value: number): D; - /** - * 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(): D[]; - public domain(values: D[]): QuantitativeScale; - public _setDomain(values: D[]): void; - /** - * 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; - /** - * Gets a set of tick values spanning the domain. - * - * @param {number} [count] The approximate number of ticks to generate. - * If not supplied, the number specified by - * numTicks() is used instead. - * @returns {any[]} The generated ticks. - */ - public ticks(count?: number): any[]; - /** - * Gets the default number of ticks. - * - * @returns {number} The default number of ticks. - */ - public numTicks(): number; - /** - * Sets the default number of ticks to generate. - * - * @param {number} count The new default number of ticks. - * @returns {Scale} The calling Scale. - */ - public numTicks(count: number): QuantitativeScale; - /** - * Given a domain, expands its domain onto "nice" values, e.g. whole - * numbers. - */ - public _niceDomain(domain: any[], count?: number): any[]; - /** - * Gets a Domainer of a scale. A Domainer is responsible for combining - * multiple extents into a single domain. - * - * @return {Domainer} 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 If provided, the new domainer. - * @return {QuanitativeScale} The calling QuantitativeScale. - */ - public domainer(domainer: Domainer): QuantitativeScale; - public _defaultExtent(): any[]; + _getExtent(): D[]; + /** + * Retrieves the domain value corresponding to a supplied range value. + * + * @param {number} value: A value from the Scale's range. + * @returns {D} The domain value corresponding to the supplied range value. + */ + invert(value: number): D; + /** + * 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. + */ + copy(): QuantitativeScale; + domain(): D[]; + domain(values: D[]): QuantitativeScale; + _setDomain(values: D[]): void; + /** + * 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. + */ + interpolate(): D3.Transition.Interpolate; + 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. + */ + 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. + */ + 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. + */ + clamp(clamp: boolean): QuantitativeScale; + /** + * Gets a set of tick values spanning the domain. + * + * @param {number} [count] The approximate number of ticks to generate. + * If not supplied, the number specified by + * numTicks() is used instead. + * @returns {any[]} The generated ticks. + */ + ticks(count?: number): any[]; + /** + * Gets the default number of ticks. + * + * @returns {number} The default number of ticks. + */ + numTicks(): number; + /** + * Sets the default number of ticks to generate. + * + * @param {number} count The new default number of ticks. + * @returns {Scale} The calling Scale. + */ + numTicks(count: number): QuantitativeScale; + /** + * Given a domain, expands its domain onto "nice" values, e.g. whole + * numbers. + */ + _niceDomain(domain: any[], count?: number): any[]; + /** + * Gets a Domainer of a scale. A Domainer is responsible for combining + * multiple extents into a single domain. + * + * @return {Domainer} The scale's current domainer. + */ + 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 If provided, the new domainer. + * @return {QuanitativeScale} The calling QuantitativeScale. + */ + domainer(domainer: Domainer): QuantitativeScale; + _defaultExtent(): any[]; } } } @@ -1194,23 +1194,23 @@ declare module Plottable { module Scale { class Linear extends Abstract.QuantitativeScale { /** - * Constructs a new LinearScale. - * - * This scale maps from domain to range with a simple `mx + b` formula. - * - * @constructor - * @param {D3.Scale.LinearScale} [scale] The D3 LinearScale backing the - * LinearScale. If not supplied, uses a default scale. - */ + * Constructs a new LinearScale. + * + * This scale maps from domain to range with a simple `mx + b` formula. + * + * @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); /** - * Constructs a copy of the Scale.Linear with the same domain and range but - * without any registered listeners. - * - * @returns {Linear} A copy of the calling Scale.Linear. - */ - public copy(): Linear; + * Constructs a copy of the Scale.Linear with the same domain and range but + * without any registered listeners. + * + * @returns {Linear} A copy of the calling Scale.Linear. + */ + copy(): Linear; } } } @@ -1220,26 +1220,26 @@ declare module Plottable { module Scale { class Log extends Abstract.QuantitativeScale { /** - * Constructs 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. - */ + * Constructs 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); /** - * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. - * - * @returns {Log} A copy of the calling Log. - */ - public copy(): Log; - public _defaultExtent(): number[]; + * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. + * + * @returns {Log} A copy of the calling Log. + */ + copy(): Log; + _defaultExtent(): number[]; } } } @@ -1249,54 +1249,54 @@ declare module Plottable { module Scale { 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). - */ + * 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); - public scale(x: number): number; - public invert(x: number): number; - public _getDomain(): number[]; - public _setDomain(values: number[]): void; - public ticks(count?: number): number[]; - public copy(): ModifiedLog; - public _niceDomain(domain: any[], count?: number): any[]; + scale(x: number): number; + invert(x: number): number; + _getDomain(): number[]; + _setDomain(values: number[]): void; + ticks(count?: number): number[]; + copy(): ModifiedLog; + _niceDomain(domain: any[], count?: number): any[]; /** - * Gets 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]. - * @returns {boolean} the current setting. - */ - public showIntermediateTicks(): boolean; + * Gets 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]. + * @returns {boolean} the current setting. + */ + showIntermediateTicks(): boolean; /** - * Sets whether or not to return ticks values other than powers or base. - * - * @param {boolean} show If provided, the desired setting. - * @returns {ModifiedLog} The calling ModifiedLog. - */ - public showIntermediateTicks(show: boolean): ModifiedLog; + * Sets whether or not to return ticks values other than powers or base. + * + * @param {boolean} show If provided, the desired setting. + * @returns {ModifiedLog} The calling ModifiedLog. + */ + showIntermediateTicks(show: boolean): ModifiedLog; } } } @@ -1305,51 +1305,51 @@ declare module Plottable { declare module Plottable { module Scale { class Ordinal extends Abstract.Scale { - public _d3Scale: D3.Scale.OrdinalScale; - public _typeCoercer: (d: any) => any; - /** - * Creates an OrdinalScale. - * - * An OrdinalScale maps strings to numbers. A common use is to map the - * labels of a bar plot (strings) to their pixel locations (numbers). - * - * @constructor - */ + _d3Scale: D3.Scale.OrdinalScale; + _typeCoercer: (d: any) => any; + /** + * Creates an OrdinalScale. + * + * An OrdinalScale maps strings to numbers. A common use is to map the + * labels of a bar plot (strings) to their pixel locations (numbers). + * + * @constructor + */ constructor(scale?: D3.Scale.OrdinalScale); - public _getExtent(): string[]; - public domain(): string[]; - public domain(values: string[]): Ordinal; - public _setDomain(values: string[]): void; - public range(): number[]; - 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: string): number[]; - /** - * Get the range type. - * - * @returns {string} The current range type. - */ - public rangeType(): string; - /** - * Set the range type. - * - * @param {string} rangeType If provided, either "points" or "bands" indicating the - * d3 method used to generate range bounds. - * @param {number} [outerPadding] If provided, the padding outside the range, - * proportional to the range step. - * @param {number} [innerPadding] If provided, 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. - */ - public rangeType(rangeType: string, outerPadding?: number, innerPadding?: number): Ordinal; - public copy(): Ordinal; + _getExtent(): string[]; + domain(): string[]; + domain(values: string[]): Ordinal; + _setDomain(values: string[]): void; + range(): number[]; + 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". + */ + rangeBand(): number; + innerPadding(): number; + fullBandStartAndWidth(v: string): number[]; + /** + * Get the range type. + * + * @returns {string} The current range type. + */ + rangeType(): string; + /** + * Set the range type. + * + * @param {string} rangeType If provided, either "points" or "bands" indicating the + * d3 method used to generate range bounds. + * @param {number} [outerPadding] If provided, the padding outside the range, + * proportional to the range step. + * @param {number} [innerPadding] If provided, 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. + */ + rangeType(rangeType: string, outerPadding?: number, innerPadding?: number): Ordinal; + copy(): Ordinal; } } } @@ -1359,15 +1359,15 @@ declare module Plottable { module Scale { class Color extends Abstract.Scale { /** - * Constructs 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 - */ + * Constructs 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); - public _getExtent(): string[]; + _getExtent(): string[]; } } } @@ -1376,21 +1376,21 @@ declare module Plottable { declare module Plottable { module Scale { class Time extends Abstract.QuantitativeScale { - public _typeCoercer: (d: any) => any; - /** - * Constructs a TimeScale. - * - * A TimeScale maps Date objects to numbers. - * - * @constructor - * @param {D3.Scale.Time} scale The D3 LinearScale backing the Scale.Time. If not supplied, uses a default scale. - */ + _typeCoercer: (d: any) => any; + /** + * Constructs a TimeScale. + * + * A TimeScale maps Date objects to numbers. + * + * @constructor + * @param {D3.Scale.Time} scale The D3 LinearScale backing the Scale.Time. If not supplied, uses a default scale. + */ constructor(); constructor(scale: D3.Scale.LinearScale); - public _tickInterval(interval: D3.Time.Interval, step?: number): any[]; - public _setDomain(values: any[]): void; - public copy(): Time; - public _defaultExtent(): any[]; + _tickInterval(interval: D3.Time.Interval, step?: number): any[]; + _setDomain(values: any[]): void; + copy(): Time; + _defaultExtent(): any[]; } } } @@ -1399,58 +1399,58 @@ declare module Plottable { declare module Plottable { module 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. - */ + * 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.Scale { /** - * Constructs an InterpolatedColorScale. - * - * An InterpolatedColorScale maps numbers evenly to color strings. - * - * @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. - */ + * Constructs an InterpolatedColorScale. + * + * An InterpolatedColorScale maps numbers evenly to color strings. + * + * @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); /** - * Gets the color range. - * - * @returns {string[]} the current color values for the range as strings. - */ - public colorRange(): string[]; + * Gets the color range. + * + * @returns {string[]} the current color values for the range as strings. + */ + colorRange(): string[]; /** - * Sets the color range. - * - * @param {string|string[]} [colorRange]. If provided and 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. - */ - public colorRange(colorRange: any): InterpolatedColor; + * Sets the color range. + * + * @param {string|string[]} [colorRange]. If provided and 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. + */ + colorRange(colorRange: any): InterpolatedColor; /** - * Gets the internal scale type. - * - * @returns {string} The current scale type. - */ - public scaleType(): string; + * Gets the internal scale type. + * + * @returns {string} The current scale type. + */ + scaleType(): string; /** - * Sets the internal scale type. - * - * @param {string} scaleType If provided, the type of d3 scale to use internally. (linear/log/sqrt/pow). - * @returns {InterpolatedColor} The calling InterpolatedColor. - */ - public scaleType(scaleType: string): InterpolatedColor; - public autoDomain(): InterpolatedColor; + * Sets the internal scale type. + * + * @param {string} scaleType If provided, the type of d3 scale to use internally. (linear/log/sqrt/pow). + * @returns {InterpolatedColor} The calling InterpolatedColor. + */ + scaleType(scaleType: string): InterpolatedColor; + autoDomain(): InterpolatedColor; } } } @@ -1460,13 +1460,13 @@ declare module Plottable { module _Util { class ScaleDomainCoordinator { /** - * Constructs a ScaleDomainCoordinator. - * - * @constructor - * @param {Scale[]} scales A list of scales whose domains should be linked. - */ + * Constructs 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; + rescale(scale: Abstract.Scale): void; } } } @@ -1475,26 +1475,26 @@ declare module Plottable { declare module Plottable { module Abstract { class _Drawer { - public _renderArea: D3.Selection; - public key: string; - /** - * Constructs a Drawer - * - * @constructor - * @param{string} key The key associated with this Drawer - */ + _renderArea: D3.Selection; + key: string; + /** + * Constructs a Drawer + * + * @constructor + * @param{string} key The key associated with this Drawer + */ constructor(key: string); /** - * Removes the Drawer and its renderArea - */ - public remove(): void; + * Removes the Drawer and its renderArea + */ + 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, animator?: Animator.Null): 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 + */ + draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; } } } @@ -1503,7 +1503,7 @@ declare module Plottable { declare module Plottable { module _Drawer { class Arc extends Abstract._Drawer { - public draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; + draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; } } } @@ -1512,7 +1512,7 @@ declare module Plottable { declare module Plottable { module _Drawer { class Area extends Abstract._Drawer { - public draw(data: any[], attrToProjector: IAttributeToProjector): void; + draw(data: any[], attrToProjector: IAttributeToProjector): void; } } } @@ -1521,7 +1521,7 @@ declare module Plottable { declare module Plottable { module _Drawer { class Rect extends Abstract._Drawer { - public draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; + draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; } } } @@ -1531,188 +1531,188 @@ declare module Plottable { module Abstract { class Component extends PlottableObject { static AUTORESIZE_BY_DEFAULT: boolean; - public _element: D3.Selection; - public _content: D3.Selection; - public _backgroundContainer: D3.Selection; - public _foregroundContainer: D3.Selection; - public clipPathEnabled: boolean; - public _parent: ComponentContainer; - public _xAlignProportion: number; - public _yAlignProportion: number; - public _fixedHeightFlag: boolean; - public _fixedWidthFlag: boolean; - public _isSetup: boolean; - public _isAnchored: boolean; - /** - * 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. - */ - public _anchor(element: D3.Selection): void; - /** - * 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. - */ - public _setup(): void; - public _requestedSpace(availableWidth: number, availableHeight: number): _ISpaceRequest; - /** - * 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 x-coordinate of the origin of the component - * @param {number} yOrigin y-coordinate of the origin of the component - * @param {number} availableWidth available width for the component to render in - * @param {number} availableHeight available height for the component to render in - */ - public _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): void; - public _render(): void; - public _scheduleComputeLayout(): void; - public _doRender(): void; - public _invalidateLayout(): void; - /** - * Renders the Component into a given DOM element. The element must be as . - * - * @param {String|D3.Selection} element A D3 selection or a selector for getting the element to render into. - * @returns {Component} The calling component. - */ - public renderTo(selector: String): Component; - public renderTo(element: D3.Selection): Component; - /** - * Causes the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. - * - * This function should be called when CSS changes could influence the size - * of the components, e.g. changing the font size. - * - * @param {number} [availableWidth] - the width of the container element - * @param {number} [availableHeight] - the height of the container element - * @returns {Component} The calling component. - */ - public resize(width?: number, height?: number): Component; - /** - * Enables or disables resize on window resizes. - * - * 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 Enable (true) or disable (false) auto-resize. - * @returns {Component} The calling component. - */ - public autoResize(flag: boolean): Component; - /** - * Sets the x alignment of the Component. This will be used if the - * Component is given more space than it needs. - * - * For example, you may want to make a Legend postition itself it the top - * right, so you would call `legend.xAlign("right")` and - * `legend.yAlign("top")`. - * - * @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. This will be used if the - * Component is given more space than it needs. - * - * For example, you may want to make a Legend postition itself it the top - * right, so you would call `legend.xAlign("right")` and - * `legend.yAlign("top")`. - * - * @param {string} alignment The x 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. This will be used if the Component - * is given more space than it needs. - * - * @param {number} offset The desired x offset, in pixels, from the left - * side of the container. - * @returns {Component} The calling Component. - */ - public xOffset(offset: number): Component; - /** - * Sets the y offset of the Component. This will be used if the Component - * is given more space than it needs. - * - * @param {number} offset The desired y offset, in pixels, from the top - * side of the container. - * @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. - * @returns {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. - * @returns {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; - /** - * 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. - * - * @returns {boolean} Whether the component has a fixed width. - */ - public _isFixedWidth(): boolean; - /** - * 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. - * - * @returns {boolean} Whether the component has a fixed height. - */ - public _isFixedHeight(): boolean; - /** - * Merges this Component with another Component, returning a - * ComponentGroup. This is used to layer Components on top of each other. - * - * 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. - * @returns {ComponentGroup} The relevant ComponentGroup out of the above four cases. - */ - public merge(c: Component): Component.Group; - /** - * Detaches a Component from the DOM. The component can be reused. - * - * This should only be used if you plan on reusing the calling - * Components. Otherwise, use remove(). - * - * @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; - /** - * Return the width of the component - * - * @return {number} width of the component - */ - public width(): number; - /** - * Return the height of the component - * - * @return {number} height of the component - */ - public height(): number; + _element: D3.Selection; + _content: D3.Selection; + _backgroundContainer: D3.Selection; + _foregroundContainer: D3.Selection; + clipPathEnabled: boolean; + _parent: ComponentContainer; + _xAlignProportion: number; + _yAlignProportion: number; + _fixedHeightFlag: boolean; + _fixedWidthFlag: boolean; + _isSetup: boolean; + _isAnchored: boolean; + /** + * 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. + */ + _anchor(element: D3.Selection): void; + /** + * 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. + */ + _setup(): void; + _requestedSpace(availableWidth: number, availableHeight: number): _ISpaceRequest; + /** + * 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 x-coordinate of the origin of the component + * @param {number} yOrigin y-coordinate of the origin of the component + * @param {number} availableWidth available width for the component to render in + * @param {number} availableHeight available height for the component to render in + */ + _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): void; + _render(): void; + _scheduleComputeLayout(): void; + _doRender(): void; + _invalidateLayout(): void; + /** + * Renders the Component into a given DOM element. The element must be as . + * + * @param {String|D3.Selection} element A D3 selection or a selector for getting the element to render into. + * @returns {Component} The calling component. + */ + renderTo(selector: String): Component; + renderTo(element: D3.Selection): Component; + /** + * Causes the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. + * + * This function should be called when CSS changes could influence the size + * of the components, e.g. changing the font size. + * + * @param {number} [availableWidth] - the width of the container element + * @param {number} [availableHeight] - the height of the container element + * @returns {Component} The calling component. + */ + resize(width?: number, height?: number): Component; + /** + * Enables or disables resize on window resizes. + * + * 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 Enable (true) or disable (false) auto-resize. + * @returns {Component} The calling component. + */ + autoResize(flag: boolean): Component; + /** + * Sets the x alignment of the Component. This will be used if the + * Component is given more space than it needs. + * + * For example, you may want to make a Legend postition itself it the top + * right, so you would call `legend.xAlign("right")` and + * `legend.yAlign("top")`. + * + * @param {string} alignment The x alignment of the Component (one of ["left", "center", "right"]). + * @returns {Component} The calling Component. + */ + xAlign(alignment: string): Component; + /** + * Sets the y alignment of the Component. This will be used if the + * Component is given more space than it needs. + * + * For example, you may want to make a Legend postition itself it the top + * right, so you would call `legend.xAlign("right")` and + * `legend.yAlign("top")`. + * + * @param {string} alignment The x alignment of the Component (one of ["top", "center", "bottom"]). + * @returns {Component} The calling Component. + */ + yAlign(alignment: string): Component; + /** + * Sets the x offset of the Component. This will be used if the Component + * is given more space than it needs. + * + * @param {number} offset The desired x offset, in pixels, from the left + * side of the container. + * @returns {Component} The calling Component. + */ + xOffset(offset: number): Component; + /** + * Sets the y offset of the Component. This will be used if the Component + * is given more space than it needs. + * + * @param {number} offset The desired y offset, in pixels, from the top + * side of the container. + * @returns {Component} The calling Component. + */ + 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. + * @returns {Component} The calling Component. + */ + 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. + * @returns {boolean|Component} Whether the Component has the given CSS class, or the calling Component (if addClass is supplied). + */ + classed(cssClass: string): boolean; + classed(cssClass: string, addClass: boolean): Component; + /** + * 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. + * + * @returns {boolean} Whether the component has a fixed width. + */ + _isFixedWidth(): boolean; + /** + * 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. + * + * @returns {boolean} Whether the component has a fixed height. + */ + _isFixedHeight(): boolean; + /** + * Merges this Component with another Component, returning a + * ComponentGroup. This is used to layer Components on top of each other. + * + * 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. + * @returns {ComponentGroup} The relevant ComponentGroup out of the above four cases. + */ + merge(c: Component): Component.Group; + /** + * Detaches a Component from the DOM. The component can be reused. + * + * This should only be used if you plan on reusing the calling + * Components. Otherwise, use remove(). + * + * @returns The calling Component. + */ + detach(): Component; + /** + * Removes a Component from the DOM and disconnects it from everything it's + * listening to (effectively destroying it). + */ + remove(): void; + /** + * Return the width of the component + * + * @return {number} width of the component + */ + width(): number; + /** + * Return the height of the component + * + * @return {number} height of the component + */ + height(): number; } } } @@ -1721,31 +1721,31 @@ declare module Plottable { declare module Plottable { module Abstract { class ComponentContainer extends Component { - public _components: Component[]; - public _anchor(element: D3.Selection): void; - public _render(): void; - public _removeComponent(c: Component): void; - public _addComponent(c: Component, prepend?: boolean): boolean; + _components: Component[]; + _anchor(element: D3.Selection): void; + _render(): void; + _removeComponent(c: Component): void; + _addComponent(c: Component, prepend?: boolean): boolean; /** - * Returns a list of components in the ComponentContainer. - * - * @returns {Component[]} the contained Components - */ - public components(): Component[]; + * Returns a list of components in the ComponentContainer. + * + * @returns {Component[]} the contained Components + */ + components(): Component[]; /** - * Returns true iff the ComponentContainer is empty. - * - * @returns {boolean} Whether the calling ComponentContainer is empty. - */ - public empty(): boolean; + * Returns true iff the ComponentContainer is empty. + * + * @returns {boolean} Whether the calling ComponentContainer is empty. + */ + empty(): boolean; /** - * Detaches all components contained in the ComponentContainer, and - * empties the ComponentContainer. - * - * @returns {ComponentContainer} The calling ComponentContainer - */ - public detachAll(): ComponentContainer; - public remove(): void; + * Detaches all components contained in the ComponentContainer, and + * empties the ComponentContainer. + * + * @returns {ComponentContainer} The calling ComponentContainer + */ + detachAll(): ComponentContainer; + remove(): void; } } } @@ -1755,21 +1755,21 @@ declare module Plottable { module Component { class Group extends Abstract.ComponentContainer { /** - * Constructs a GroupComponent. - * - * A GroupComponent is a set of Components that will be rendered on top of - * each other. When you call Component.merge(Component), it creates and - * returns a GroupComponent. - * - * @constructor - * @param {Component[]} components The Components in the Group (default = []). - */ + * Constructs a GroupComponent. + * + * A GroupComponent is a set of Components that will be rendered on top of + * each other. When you call Component.merge(Component), it creates and + * returns a GroupComponent. + * + * @constructor + * @param {Component[]} components The Components in the Group (default = []). + */ constructor(components?: Abstract.Component[]); - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public merge(c: Abstract.Component): Group; - public _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): Group; - public _isFixedWidth(): boolean; - public _isFixedHeight(): boolean; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + merge(c: Abstract.Component): Group; + _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): Group; + _isFixedWidth(): boolean; + _isFixedHeight(): boolean; } } } @@ -1779,168 +1779,169 @@ declare module Plottable { module Abstract { class Axis extends Component { /** - * The css class applied to each end tick mark (the line on the end tick). - */ + * 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). - */ + * 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). - */ + * The css class applied to each tick label (the text associated with the tick). + */ static TICK_LABEL_CLASS: string; - public _tickMarkContainer: D3.Selection; - public _tickLabelContainer: D3.Selection; - public _baseline: D3.Selection; - public _scale: Scale; - public _formatter: Formatter; - public _orientation: string; - public _computedWidth: number; - public _computedHeight: number; - /** - * Constructs an axis. An axis is a wrapper around a scale for rendering. - * - * @constructor - * @param {Scale} scale The scale for this axis to render. - * @param {string} orientation One of ["top", "left", "bottom", "right"]; - * on which side the axis will appear. On most axes, this is either "left" - * or "bottom". - * @param {Formatter} Data is passed through this formatter before being - * displayed. - */ + _tickMarkContainer: D3.Selection; + _tickLabelContainer: D3.Selection; + _baseline: D3.Selection; + _scale: Scale; + _formatter: Formatter; + _orientation: string; + _computedWidth: number; + _computedHeight: number; + /** + * Constructs an axis. An axis is a wrapper around a scale for rendering. + * + * @constructor + * @param {Scale} scale The scale for this axis to render. + * @param {string} orientation One of ["top", "left", "bottom", "right"]; + * on which side the axis will appear. On most axes, this is either "left" + * or "bottom". + * @param {Formatter} Data is passed through this formatter before being + * displayed. + */ constructor(scale: Scale, orientation: string, formatter?: (d: any) => string); - public remove(): void; - public _isHorizontal(): boolean; - public _computeWidth(): number; - public _computeHeight(): number; - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public _isFixedHeight(): boolean; - public _isFixedWidth(): boolean; - public _rescale(): void; - public _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; - public _setup(): void; - public _getTickValues(): any[]; - public _doRender(): void; - public _generateBaselineAttrHash(): { + remove(): void; + _isHorizontal(): boolean; + _computeWidth(): number; + _computeHeight(): number; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + _isFixedHeight(): boolean; + _isFixedWidth(): boolean; + _rescale(): void; + _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; + _setup(): void; + _getTickValues(): any[]; + _doRender(): void; + _generateBaselineAttrHash(): { x1: number; y1: number; x2: number; y2: number; }; - public _generateTickMarkAttrHash(isEndTickMark?: boolean): { + _generateTickMarkAttrHash(isEndTickMark?: boolean): { x1: any; y1: any; x2: any; y2: any; }; - public _invalidateLayout(): void; - /** - * Gets the current formatter on the axis. Data is passed through the - * formatter before being displayed. - * - * @returns {Formatter} The calling Axis, or the current - * Formatter. - */ - public formatter(): Formatter; - /** - * Sets the current formatter on the axis. Data is passed through the - * formatter before being displayed. - * - * @param {Formatter} formatter If provided, data will be passed though `formatter(data)`. - * @returns {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 current tick mark length. - * - * @param {number} length If provided, length of each tick. - * @returns {Axis} 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 If provided, the length of the end ticks. - * @returns {BaseAxis} The calling Axis. - */ - public endTickLength(length: number): Axis; - public _maxLabelTickLength(): number; - /** - * Gets the padding between each tick mark and its associated label. - * - * @returns {number} the current padding. - * length. - */ - public tickLabelPadding(): number; - /** - * Sets the padding between each tick mark and its associated label. - * - * @param {number} padding If provided, the desired padding. - * @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 gutter. - * length. - */ - 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 If provided, the desired gutter. - * @returns {Axis} The calling Axis. - */ - public gutter(size: number): Axis; - /** - * Gets the orientation of the Axis. - * - * @returns {number} the current orientation. - */ - public orient(): string; - /** - * Sets the orientation of the Axis. - * - * @param {number} newOrientation If provided, the desired orientation - * (top/bottom/left/right). - * @returns {Axis} The calling Axis. - */ - public orient(newOrientation: string): Axis; - /** - * Gets whether the Axis is currently set to show the first and last - * tick labels. - * - * @returns {boolean} whether or not the last - * tick labels are showing. - */ - public showEndTickLabels(): boolean; - /** - * Sets whether the Axis is currently set 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; - public _hideEndTickLabels(): void; - public _hideOverlappingTickLabels(): void; + _invalidateLayout(): void; + _setDefaultAlignment(): void; + /** + * Gets the current formatter on the axis. Data is passed through the + * formatter before being displayed. + * + * @returns {Formatter} The calling Axis, or the current + * Formatter. + */ + formatter(): Formatter; + /** + * Sets the current formatter on the axis. Data is passed through the + * formatter before being displayed. + * + * @param {Formatter} formatter If provided, data will be passed though `formatter(data)`. + * @returns {Axis} The calling Axis. + */ + formatter(formatter: Formatter): Axis; + /** + * Gets the current tick mark length. + * + * @returns {number} the current tick mark length. + */ + tickLength(): number; + /** + * Sets the current tick mark length. + * + * @param {number} length If provided, length of each tick. + * @returns {Axis} The calling Axis. + */ + tickLength(length: number): Axis; + /** + * Gets the current end tick mark length. + * + * @returns {number} The current end tick mark length. + */ + endTickLength(): number; + /** + * Sets the end tick mark length. + * + * @param {number} length If provided, the length of the end ticks. + * @returns {BaseAxis} The calling Axis. + */ + endTickLength(length: number): Axis; + _maxLabelTickLength(): number; + /** + * Gets the padding between each tick mark and its associated label. + * + * @returns {number} the current padding. + * length. + */ + tickLabelPadding(): number; + /** + * Sets the padding between each tick mark and its associated label. + * + * @param {number} padding If provided, the desired padding. + * @returns {Axis} The calling Axis. + */ + 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 gutter. + * length. + */ + 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 If provided, the desired gutter. + * @returns {Axis} The calling Axis. + */ + gutter(size: number): Axis; + /** + * Gets the orientation of the Axis. + * + * @returns {number} the current orientation. + */ + orient(): string; + /** + * Sets the orientation of the Axis. + * + * @param {number} newOrientation If provided, the desired orientation + * (top/bottom/left/right). + * @returns {Axis} The calling Axis. + */ + orient(newOrientation: string): Axis; + /** + * Gets whether the Axis is currently set to show the first and last + * tick labels. + * + * @returns {boolean} whether or not the last + * tick labels are showing. + */ + showEndTickLabels(): boolean; + /** + * Sets whether the Axis is currently set 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. + */ + showEndTickLabels(show: boolean): Axis; + _hideEndTickLabels(): void; + _hideOverlappingTickLabels(): void; } } } @@ -1954,27 +1955,27 @@ declare module Plottable { formatString: string; } class Time extends Abstract.Axis { - public _majorTickLabels: D3.Selection; - public _minorTickLabels: D3.Selection; - public _scale: Scale.Time; + _majorTickLabels: D3.Selection; + _minorTickLabels: D3.Selection; + _scale: Scale.Time; static _minorIntervals: _ITimeInterval[]; static _majorIntervals: _ITimeInterval[]; /** - * Constructs a TimeAxis. - * - * A TimeAxis is used for rendering a TimeScale. - * - * @constructor - * @param {TimeScale} scale The scale to base the Axis on. - * @param {string} orientation The orientation of the Axis (top/bottom) - */ + * Constructs a TimeAxis. + * + * A TimeAxis is used for rendering a TimeScale. + * + * @constructor + * @param {TimeScale} scale The scale to base the Axis on. + * @param {string} orientation The orientation of the Axis (top/bottom) + */ constructor(scale: Scale.Time, orientation: string); - public _computeHeight(): number; - public _setup(): void; - public _getTickIntervalValues(interval: _ITimeInterval): any[]; - public _getTickValues(): any[]; - public _measureTextHeight(container: D3.Selection): number; - public _doRender(): Time; + _computeHeight(): number; + _setup(): void; + _getTickIntervalValues(interval: _ITimeInterval): any[]; + _getTickValues(): any[]; + _measureTextHeight(container: D3.Selection): number; + _doRender(): Time; } } } @@ -1983,65 +1984,65 @@ declare module Plottable { declare module Plottable { module Axis { class Numeric extends Abstract.Axis { - public _scale: Abstract.QuantitativeScale; - /** - * Constructs a NumericAxis. - * - * Just as an CategoryAxis is for rendering an OrdinalScale, a NumericAxis - * is for rendering a QuantitativeScale. - * - * @constructor - * @param {QuantitativeScale} scale The QuantitativeScale to base the axis 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)). - */ + _scale: Abstract.QuantitativeScale; + /** + * Constructs a NumericAxis. + * + * Just as an CategoryAxis is for rendering an OrdinalScale, a NumericAxis + * is for rendering a QuantitativeScale. + * + * @constructor + * @param {QuantitativeScale} scale The QuantitativeScale to base the axis 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); - public _setup(): void; - public _computeWidth(): number; - public _computeHeight(): number; - public _getTickValues(): any[]; - public _rescale(): void; - public _doRender(): void; - /** - * 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 If provided, the relative position of the tick label. - * [top/center/bottom] for a vertical NumericAxis, - * [left/center/right] for a horizontal NumericAxis. - * Defaults to center. - * @returns {Numeric} The calling Axis.Numeric. - */ - public tickLabelPosition(position: string): Numeric; - /** - * Gets 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; - /** - * Sets whether or not the tick labels at the end of the graph are - * displayed when partially cut off. - * - * @param {string} orientation If provided, 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 NumericAxis. - */ - public showEndTickLabel(orientation: string, show: boolean): Numeric; + _setup(): void; + _computeWidth(): number; + _computeHeight(): number; + _getTickValues(): any[]; + _rescale(): void; + _doRender(): void; + /** + * Gets the tick label position relative to the tick marks. + * + * @returns {string} The current tick label position. + */ + tickLabelPosition(): string; + /** + * Sets the tick label position relative to the tick marks. + * + * @param {string} position If provided, the relative position of the tick label. + * [top/center/bottom] for a vertical NumericAxis, + * [left/center/right] for a horizontal NumericAxis. + * Defaults to center. + * @returns {Numeric} The calling Axis.Numeric. + */ + tickLabelPosition(position: string): Numeric; + /** + * Gets 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. + */ + showEndTickLabel(orientation: string): boolean; + /** + * Sets whether or not the tick labels at the end of the graph are + * displayed when partially cut off. + * + * @param {string} orientation If provided, 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 NumericAxis. + */ + showEndTickLabel(orientation: string, show: boolean): Numeric; } } } @@ -2050,26 +2051,40 @@ declare module Plottable { declare module Plottable { module Axis { class Category extends Abstract.Axis { - public _scale: Scale.Ordinal; - /** - * Constructs 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) (default = "bottom"). - * @param {Formatter} formatter The Formatter for the Axis (default Formatters.identity()) - */ + _scale: Scale.Ordinal; + /** + * Constructs 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) (default = "bottom"). + * @param {Formatter} formatter The Formatter for the Axis (default Formatters.identity()) + */ constructor(scale: Scale.Ordinal, orientation?: string, formatter?: (d: any) => string); - public _setup(): void; - public _rescale(): void; - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public _getTickValues(): string[]; - public _doRender(): Category; - public _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): void; + _setup(): void; + _rescale(): void; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + _getTickValues(): string[]; + /** + * Sets the angle for the tick labels. Right now vertical-left (-90), horizontal (0), and vertical-right (90) are the only options. + * @param {number} angle The angle for the ticks + * @returns {Category} The calling Category Axis. + * + * Warning - this is not currently well supported and is likely to behave badly unless all the tick labels are short. + * See tracking at https://github.com/palantir/plottable/issues/504 + */ + tickLabelAngle(angle: number): Category; + /** + * Gets the tick label angle + * @returns {number} the tick label angle + */ + tickLabelAngle(): number; + _doRender(): Category; + _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): void; } } } @@ -2079,78 +2094,78 @@ declare module Plottable { module Component { class Label extends Abstract.Component { /** - * Creates a Label. - * - * A label is component that renders just text. The most common use of - * labels is to create a title or axis labels. - * - * @constructor - * @param {string} displayText The text of the Label (default = ""). - * @param {string} orientation The orientation of the Label (horizontal/vertical-left/vertical-right) (default = "horizontal"). - */ + * Creates a Label. + * + * A label is component that renders just text. The most common use of + * labels is to create a title or axis labels. + * + * @constructor + * @param {string} displayText The text of the Label (default = ""). + * @param {string} orientation The orientation of the Label (horizontal/left/right) (default = "horizontal"). + */ constructor(displayText?: string, orientation?: string); /** - * Sets the horizontal side the label will go to given the label is given more space that it needs - * - * @param {string} alignment The new setting, one of `["left", "center", - * "right"]`. Defaults to `"center"`. - * @returns {Label} The calling Label. - */ - public xAlign(alignment: string): Label; - /** - * Sets the vertical side the label will go to given the label is given more space that it needs - * - * @param {string} alignment The new setting, one of `["top", "center", - * "bottom"]`. Defaults to `"center"`. - * @returns {Label} The calling Label. - */ - public yAlign(alignment: string): Label; - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public _setup(): void; - /** - * Gets the current text on the Label. - * - * @returns {string} the text on the label. - */ - public text(): string; - /** - * Sets the current text on the Label. - * - * @param {string} displayText If provided, the new text for the Label. - * @returns {Label} The calling Label. - */ - public text(displayText: string): Label; - /** - * Gets the orientation of the Label. - * - * @returns {string} the current orientation. - */ - public orient(): string; - /** - * Sets the orientation of the Label. - * - * @param {string} newOrientation If provided, the desired orientation - * (horizontal/vertical-left/vertical-right). - * @returns {Label} The calling Label. - */ - public orient(newOrientation: string): Label; - public _doRender(): void; - public _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): Label; + * Sets the horizontal side the label will go to given the label is given more space that it needs + * + * @param {string} alignment The new setting, one of `["left", "center", + * "right"]`. Defaults to `"center"`. + * @returns {Label} The calling Label. + */ + xAlign(alignment: string): Label; + /** + * Sets the vertical side the label will go to given the label is given more space that it needs + * + * @param {string} alignment The new setting, one of `["top", "center", + * "bottom"]`. Defaults to `"center"`. + * @returns {Label} The calling Label. + */ + yAlign(alignment: string): Label; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + _setup(): void; + /** + * Gets the current text on the Label. + * + * @returns {string} the text on the label. + */ + text(): string; + /** + * Sets the current text on the Label. + * + * @param {string} displayText If provided, the new text for the Label. + * @returns {Label} The calling Label. + */ + text(displayText: string): Label; + /** + * Gets the orientation of the Label. + * + * @returns {string} the current orientation. + */ + orient(): string; + /** + * Sets the orientation of the Label. + * + * @param {string} newOrientation If provided, the desired orientation + * (horizontal/left/right). + * @returns {Label} The calling Label. + */ + orient(newOrientation: string): Label; + _doRender(): void; + _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): Label; } class TitleLabel extends Label { /** - * Creates a TitleLabel, a type of label made for rendering titles. - * - * @constructor - */ + * Creates a TitleLabel, a type of label made for rendering titles. + * + * @constructor + */ constructor(text?: string, orientation?: string); } class AxisLabel extends Label { /** - * Creates a AxisLabel, a type of label made for rendering axis labels. - * - * @constructor - */ + * Creates a AxisLabel, a type of label made for rendering axis labels. + * + * @constructor + */ constructor(text?: string, orientation?: string); } } @@ -2167,84 +2182,84 @@ declare module Plottable { } class Legend extends Abstract.Component { /** - * The css class applied to each legend row - */ + * The css class applied to each legend row + */ static SUBELEMENT_CLASS: string; /** - * Constructs 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 {ColorScale} colorScale - */ + * Constructs 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 {ColorScale} colorScale + */ constructor(colorScale?: Scale.Color); - public remove(): void; - /** - * Gets the toggle callback from 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. - * - * @returns {ToggleCallback} The current toggle callback. - */ - public toggleCallback(): ToggleCallback; - /** - * Assigns a toggle 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. - * @returns {Legend} The calling Legend. - */ - public toggleCallback(callback: ToggleCallback): Legend; - /** - * Gets the hover callback from 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. - * - * @returns {HoverCallback} The new current hover callback. - */ - public hoverCallback(): HoverCallback; - /** - * Assigns a hover 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 If provided, the new callback function. - * @returns {Legend} The calling Legend. - */ - public hoverCallback(callback: HoverCallback): Legend; - /** - * Gets the current color scale from the Legend. - * - * @returns {ColorScale} The current color scale. - */ - public scale(): Scale.Color; - /** - * Assigns a new color scale to the Legend. - * - * @param {Scale.Color} scale If provided, the new scale. - * @returns {Legend} The calling Legend. - */ - public scale(scale: Scale.Color): Legend; - public _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): void; - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public _doRender(): void; + remove(): void; + /** + * Gets the toggle callback from 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. + * + * @returns {ToggleCallback} The current toggle callback. + */ + toggleCallback(): ToggleCallback; + /** + * Assigns a toggle 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. + * @returns {Legend} The calling Legend. + */ + toggleCallback(callback: ToggleCallback): Legend; + /** + * Gets the hover callback from 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. + * + * @returns {HoverCallback} The new current hover callback. + */ + hoverCallback(): HoverCallback; + /** + * Assigns a hover 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 If provided, the new callback function. + * @returns {Legend} The calling Legend. + */ + hoverCallback(callback: HoverCallback): Legend; + /** + * Gets the current color scale from the Legend. + * + * @returns {ColorScale} The current color scale. + */ + scale(): Scale.Color; + /** + * Assigns a new color scale to the Legend. + * + * @param {Scale.Color} scale If provided, the new scale. + * @returns {Legend} The calling Legend. + */ + scale(scale: Scale.Color): Legend; + _computeLayout(xOrigin?: number, yOrigin?: number, availableWidth?: number, availableHeight?: number): void; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + _doRender(): void; } } } @@ -2254,26 +2269,26 @@ declare module Plottable { module Component { class HorizontalLegend extends Abstract.Component { /** - * The css class applied to each legend row - */ + * The css class applied to each legend row + */ static LEGEND_ROW_CLASS: string; /** - * The css class applied to each legend entry - */ + * The css class applied to each legend entry + */ static LEGEND_ENTRY_CLASS: string; /** - * Creates a Horizontal Legend. - * - * The legend consists of a series of legend entries, each with a color and label taken from the `colorScale`. - * The entries will be displayed in the order of the `colorScale` domain. - * - * @constructor - * @param {Scale.Color} colorScale - */ + * Creates a Horizontal Legend. + * + * The legend consists of a series of legend entries, each with a color and label taken from the `colorScale`. + * The entries will be displayed in the order of the `colorScale` domain. + * + * @constructor + * @param {Scale.Color} colorScale + */ constructor(colorScale: Scale.Color); - public remove(): void; - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public _doRender(): void; + remove(): void; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + _doRender(): void; } } } @@ -2283,16 +2298,16 @@ declare module Plottable { module Component { 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. - */ + * 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; - public _setup(): void; - public _doRender(): void; + remove(): Gridlines; + _setup(): void; + _doRender(): void; } } } @@ -2310,75 +2325,75 @@ declare module Plottable { } class Table extends Abstract.ComponentContainer { /** - * Constructs a Table. - * - * A Table is used to combine multiple Components in the form of a grid. A - * common case is combining a y-axis, x-axis, and the plotted data via - * ```typescript - * new Table([[yAxis, plot], - * [null, xAxis]]); - * ``` - * - * @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. (default = []) - */ + * Constructs a Table. + * + * A Table is used to combine multiple Components in the form of a grid. A + * common case is combining a y-axis, x-axis, and the plotted data via + * ```typescript + * new Table([[yAxis, plot], + * [null, xAxis]]); + * ``` + * + * @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. (default = []) + */ constructor(rows?: Abstract.Component[][]); /** - * Adds a Component in the specified cell. The cell must be unoccupied. - * - * For example, instead of calling `new Table([[a, b], [null, c]])`, you - * could call - * ```typescript - * var table = new Table(); - * table.addComponent(0, 0, a); - * table.addComponent(0, 1, b); - * table.addComponent(1, 1, c); - * ``` - * - * @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. - * @returns {Table} The calling Table. - */ - public addComponent(row: number, col: number, component: Abstract.Component): Table; - public _removeComponent(component: Abstract.Component): void; - public _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; - public _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; - /** - * 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. - * - * A common case would be to have one graph take up 2/3rds of the space, - * and the other graph take up 1/3rd. - * - * @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. - * - * A common case would be to have one graph take up 2/3rds of the space, - * and the other graph take up 1/3rd. - * - * @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; - public _isFixedWidth(): boolean; - public _isFixedHeight(): boolean; + * Adds a Component in the specified cell. The cell must be unoccupied. + * + * For example, instead of calling `new Table([[a, b], [null, c]])`, you + * could call + * ```typescript + * var table = new Table(); + * table.addComponent(0, 0, a); + * table.addComponent(0, 1, b); + * table.addComponent(1, 1, c); + * ``` + * + * @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. + * @returns {Table} The calling Table. + */ + addComponent(row: number, col: number, component: Abstract.Component): Table; + _removeComponent(component: Abstract.Component): void; + _requestedSpace(offeredWidth: number, offeredHeight: number): _ISpaceRequest; + _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; + /** + * 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. + */ + 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. + * + * A common case would be to have one graph take up 2/3rds of the space, + * and the other graph take up 1/3rd. + * + * @param {number} index The index of the row. + * @param {number} weight The weight to be set on the row. + * @returns {Table} The calling Table. + */ + 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. + * + * A common case would be to have one graph take up 2/3rds of the space, + * and the other graph take up 1/3rd. + * + * @param {number} index The index of the column. + * @param {number} weight The weight to be set on the column. + * @returns {Table} The calling Table. + */ + colWeight(index: number, weight: number): Table; + _isFixedWidth(): boolean; + _isFixedHeight(): boolean; } } } @@ -2387,120 +2402,120 @@ declare module Plottable { declare module Plottable { module Abstract { class Plot extends Component { - public _dataset: Dataset; - public _dataChanged: boolean; - public _renderArea: D3.Selection; - public _animate: boolean; - public _animators: Animator.IPlotAnimatorMap; - public _ANIMATION_DURATION: number; - public _projectors: { - [attrToSet: string]: _IProjector; + _dataset: Dataset; + _dataChanged: boolean; + _renderArea: D3.Selection; + _animate: boolean; + _animators: Animator.IPlotAnimatorMap; + _ANIMATION_DURATION: number; + _projectors: { + [x: string]: _IProjector; }; /** - * Constructs a Plot. - * - * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. - * - * A bare Plot has a DataSource and any number of projectors, which take - * data and "project" it onto the Plot, such as "x", "y", "fill", "r". - * - * @constructor - * @param {any[]|Dataset} [dataset] If provided, the data or Dataset to be associated with this Plot. - */ + * Constructs a Plot. + * + * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. + * + * A bare Plot has a DataSource and any number of projectors, which take + * data and "project" it onto the Plot, such as "x", "y", "fill", "r". + * + * @constructor + * @param {any[]|Dataset} [dataset] If provided, the data or Dataset to be associated with this Plot. + */ constructor(); constructor(data: any[]); constructor(dataset: Dataset); - public _anchor(element: D3.Selection): void; - public remove(): void; - /** - * Gets the Plot's Dataset. - * - * @returns {Dataset} The current Dataset. - */ - public dataset(): Dataset; - /** - * Sets the Plot's Dataset. - * - * @param {Dataset} dataset If provided, the Dataset the Plot should use. - * @returns {Plot} The calling Plot. - */ - public dataset(dataset: Dataset): Plot; - public _onDatasetUpdate(): void; - /** - * Sets an attribute of every data point. - * - * Here's a common use case: - * ```typescript - * plot.attr("r", function(d) { return d.foo; }); - * ``` - * This will set the radius of each datum `d` to be `d.foo`. - * - * @param {string} attrToSet The attribute to set across each data - * point. Popular examples include "x", "y", "r". Scales that inherit from - * Plot define their meaning. - * - * @param {Function|string|any} accessor Function to apply to each element - * of the dataSource. If a Function, use `accessor(d, i)`. If a string, - * `d[accessor]` is used. If anything else, use `accessor` as a constant - * across all data points. - * - * @param {Abstract.Scale} scale If provided, the result of the accessor - * is passed through the scale, such as `scale.scale(accessor(d, i))`. - * - * @returns {Plot} The calling Plot. - */ - public attr(attrToSet: string, accessor: any, scale?: Scale): Plot; - /** - * Identical to plot.attr - */ - public project(attrToSet: string, accessor: any, scale?: Scale): Plot; - public _generateAttrToProjector(): IAttributeToProjector; - public _doRender(): void; - public _paint(): void; - public _setup(): void; - /** - * Enables or disables animation. - * - * @param {boolean} enabled Whether or not to animate. - */ - public animate(enabled: boolean): Plot; - public detach(): Plot; - /** - * 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. - */ - public _updateScaleExtents(): void; - public _updateScaleExtent(attr: string): void; - /** - * Applies 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. - * @returns {D3.Selection} The resulting selection (potentially after the transition) - */ - public _applyAnimatedAttributes(selection: any, animatorKey: string, attrToProjector: IAttributeToProjector): any; - /** - * Get the animator associated with the specified Animator key. - * - * @return {IPlotAnimator} The Animator for the specified key. - */ - public animator(animatorKey: string): Animator.IPlotAnimator; - /** - * Set the animator associated with the specified Animator key. - * - * @param {string} animatorKey The key for the Animator. - * @param {IPlotAnimator} animator An Animator to be assigned to - * the specified key. - * @returns {Plot} The calling Plot. - */ - public animator(animatorKey: string, animator: Animator.IPlotAnimator): Plot; + _anchor(element: D3.Selection): void; + remove(): void; + /** + * Gets the Plot's Dataset. + * + * @returns {Dataset} The current Dataset. + */ + dataset(): Dataset; + /** + * Sets the Plot's Dataset. + * + * @param {Dataset} dataset If provided, the Dataset the Plot should use. + * @returns {Plot} The calling Plot. + */ + dataset(dataset: Dataset): Plot; + _onDatasetUpdate(): void; + /** + * Sets an attribute of every data point. + * + * Here's a common use case: + * ```typescript + * plot.attr("r", function(d) { return d.foo; }); + * ``` + * This will set the radius of each datum `d` to be `d.foo`. + * + * @param {string} attrToSet The attribute to set across each data + * point. Popular examples include "x", "y", "r". Scales that inherit from + * Plot define their meaning. + * + * @param {Function|string|any} accessor Function to apply to each element + * of the dataSource. If a Function, use `accessor(d, i)`. If a string, + * `d[accessor]` is used. If anything else, use `accessor` as a constant + * across all data points. + * + * @param {Abstract.Scale} scale If provided, the result of the accessor + * is passed through the scale, such as `scale.scale(accessor(d, i))`. + * + * @returns {Plot} The calling Plot. + */ + attr(attrToSet: string, accessor: any, scale?: Scale): Plot; + /** + * Identical to plot.attr + */ + project(attrToSet: string, accessor: any, scale?: Scale): Plot; + _generateAttrToProjector(): IAttributeToProjector; + _doRender(): void; + _paint(): void; + _setup(): void; + /** + * Enables or disables animation. + * + * @param {boolean} enabled Whether or not to animate. + */ + animate(enabled: boolean): Plot; + detach(): Plot; + /** + * 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. + */ + _updateScaleExtents(): void; + _updateScaleExtent(attr: string): void; + /** + * Applies 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. + * @returns {D3.Selection} The resulting selection (potentially after the transition) + */ + _applyAnimatedAttributes(selection: any, animatorKey: string, attrToProjector: IAttributeToProjector): any; + /** + * Get the animator associated with the specified Animator key. + * + * @return {IPlotAnimator} The Animator for the specified key. + */ + animator(animatorKey: string): Animator.IPlotAnimator; + /** + * Set the animator associated with the specified Animator key. + * + * @param {string} animatorKey The key for the Animator. + * @param {IPlotAnimator} animator An Animator to be assigned to + * the specified key. + * @returns {Plot} The calling Plot. + */ + animator(animatorKey: string, animator: Animator.IPlotAnimator): Plot; } } } @@ -2509,44 +2524,44 @@ declare module Plottable { declare module Plottable { module Plot { class Pie extends Abstract.Plot { - public _key2DatasetDrawerKey: D3.Map; - public _datasetKeysInOrder: string[]; + _key2DatasetDrawerKey: D3.Map; + _datasetKeysInOrder: string[]; /** - * Constructs a PiePlot. - * - * @constructor - */ + * Constructs a PiePlot. + * + * @constructor + */ constructor(); - public _setup(): void; - public _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; - /** - * Adds a dataset to this plot. Only one dataset can be added to a PiePlot. - * - * A key is automatically generated if not supplied. - * - * @param {string} [key] The key of the dataset. - * @param {any[]|Dataset} dataset dataset to add. - * @returns {Pie} The calling PiePlot. - */ - public addDataset(key: string, dataset: Dataset): Pie; - public addDataset(key: string, dataset: any[]): Pie; - public addDataset(dataset: Dataset): Pie; - public addDataset(dataset: any[]): Pie; - public _addDataset(key: string, dataset: Dataset): void; - /** - * Removes a dataset - * - * @param {string} key The key of the dataset - * @returns {Pie} The calling PiePlot. - */ - public removeDataset(key: string): Pie; - public _generateAttrToProjector(): IAttributeToProjector; - public _getAnimator(drawer: Abstract._Drawer, index: number): Animator.IPlotAnimator; - public _getDrawer(key: string): Abstract._Drawer; - public _getDatasetsInOrder(): Dataset[]; - public _getDrawersInOrder(): Abstract._Drawer[]; - public _updateScaleExtent(attr: string): void; - public _paint(): void; + _setup(): void; + _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; + /** + * Adds a dataset to this plot. Only one dataset can be added to a PiePlot. + * + * A key is automatically generated if not supplied. + * + * @param {string} [key] The key of the dataset. + * @param {any[]|Dataset} dataset dataset to add. + * @returns {Pie} The calling PiePlot. + */ + addDataset(key: string, dataset: Dataset): Pie; + addDataset(key: string, dataset: any[]): Pie; + addDataset(dataset: Dataset): Pie; + addDataset(dataset: any[]): Pie; + _addDataset(key: string, dataset: Dataset): void; + /** + * Removes a dataset + * + * @param {string} key The key of the dataset + * @returns {Pie} The calling PiePlot. + */ + removeDataset(key: string): Pie; + _generateAttrToProjector(): IAttributeToProjector; + _getAnimator(drawer: Abstract._Drawer, index: number): Animator.IPlotAnimator; + _getDrawer(key: string): Abstract._Drawer; + _getDatasetsInOrder(): Dataset[]; + _getDrawersInOrder(): Abstract._Drawer[]; + _updateScaleExtent(attr: string): void; + _paint(): void; } } } @@ -2555,28 +2570,28 @@ declare module Plottable { declare module Plottable { module Abstract { class XYPlot extends Plot { - public _xScale: Scale; - public _yScale: Scale; - /** - * Constructs an XYPlot. - * - * An XYPlot is a plot from drawing 2-dimensional data. Common examples - * include Scale.Line and Scale.Bar. - * - * @constructor - * @param {any[]|Dataset} [dataset] The data or Dataset to be associated with this Renderer. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + _xScale: Scale; + _yScale: Scale; + /** + * Constructs an XYPlot. + * + * An XYPlot is a plot from drawing 2-dimensional data. Common examples + * include Scale.Line and Scale.Bar. + * + * @constructor + * @param {any[]|Dataset} [dataset] The data or Dataset 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); /** - * @param {string} attrToSet One of ["x", "y"] which determines the point's - * x and y position in the Plot. - */ - public project(attrToSet: string, accessor: any, scale?: Scale): XYPlot; - public _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; - public _updateXDomainer(): void; - public _updateYDomainer(): void; + * @param {string} attrToSet One of ["x", "y"] which determines the point's + * x and y position in the Plot. + */ + project(attrToSet: string, accessor: any, scale?: Scale): XYPlot; + _computeLayout(xOffset?: number, yOffset?: number, availableWidth?: number, availableHeight?: number): void; + _updateXDomainer(): void; + _updateYDomainer(): void; } } } @@ -2585,65 +2600,65 @@ declare module Plottable { declare module Plottable { module Abstract { class NewStylePlot extends XYPlot { - public _key2DatasetDrawerKey: D3.Map; - public _datasetKeysInOrder: string[]; - /** - * Constructs a NewStylePlot. - * - * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. - * - * A bare Plot has a DataSource and any number of projectors, which take - * data and "project" it onto the Plot, such as "x", "y", "fill", "r". - * - * @constructor - * @param [Scale] xScale The x scale to use - * @param [Scale] yScale The y scale to use - */ + _key2DatasetDrawerKey: D3.Map; + _datasetKeysInOrder: string[]; + /** + * Constructs a NewStylePlot. + * + * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. + * + * A bare Plot has a DataSource and any number of projectors, which take + * data and "project" it onto the Plot, such as "x", "y", "fill", "r". + * + * @constructor + * @param [Scale] xScale The x scale to use + * @param [Scale] yScale The y scale to use + */ constructor(xScale?: Scale, yScale?: Scale); - public _setup(): void; - 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[]|Dataset} dataset dataset to add. - * @returns {NewStylePlot} The calling NewStylePlot. - */ - public addDataset(key: string, dataset: Dataset): NewStylePlot; - public addDataset(key: string, dataset: any[]): NewStylePlot; - public addDataset(dataset: Dataset): NewStylePlot; - public addDataset(dataset: any[]): NewStylePlot; - public _addDataset(key: string, dataset: Dataset): void; - public _getDrawer(key: string): _Drawer; - public _getAnimator(drawer: _Drawer, index: number): Animator.IPlotAnimator; - public _updateScaleExtent(attr: string): void; - /** - * Gets the dataset order by key - * - * @returns {string[]} A string array of the keys in order - */ - public datasetOrder(): string[]; - /** - * Sets the dataset order by key - * - * @param {string[]} order If provided, a string array which represents the order of the keys. - * This must be a permutation of existing keys. - * - * @returns {NewStylePlot} The calling NewStylePlot. - */ - 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; - public _getDatasetsInOrder(): Dataset[]; - public _getDrawersInOrder(): _Drawer[]; - public _paint(): void; + _setup(): void; + 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[]|Dataset} dataset dataset to add. + * @returns {NewStylePlot} The calling NewStylePlot. + */ + addDataset(key: string, dataset: Dataset): NewStylePlot; + addDataset(key: string, dataset: any[]): NewStylePlot; + addDataset(dataset: Dataset): NewStylePlot; + addDataset(dataset: any[]): NewStylePlot; + _addDataset(key: string, dataset: Dataset): void; + _getDrawer(key: string): _Drawer; + _getAnimator(drawer: _Drawer, index: number): Animator.IPlotAnimator; + _updateScaleExtent(attr: string): void; + /** + * Gets the dataset order by key + * + * @returns {string[]} A string array of the keys in order + */ + datasetOrder(): string[]; + /** + * Sets the dataset order by key + * + * @param {string[]} order If provided, a string array which represents the order of the keys. + * This must be a permutation of existing keys. + * + * @returns {NewStylePlot} The calling NewStylePlot. + */ + datasetOrder(order: string[]): NewStylePlot; + /** + * Removes a dataset + * + * @param {string} key The key of the dataset + * @return {NewStylePlot} The calling NewStylePlot. + */ + removeDataset(key: string): NewStylePlot; + _getDatasetsInOrder(): Dataset[]; + _getDrawersInOrder(): _Drawer[]; + _paint(): void; } } } @@ -2652,23 +2667,23 @@ declare module Plottable { declare module Plottable { module Plot { class Scatter extends Abstract.XYPlot { - public _animators: Animator.IPlotAnimatorMap; - /** - * Constructs a ScatterPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + _animators: Animator.IPlotAnimatorMap; + /** + * Constructs a ScatterPlot. + * + * @constructor + * @param {IDataset | any} 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); /** - * @param {string} attrToSet One of ["x", "y", "cx", "cy", "r", - * "fill"]. "cx" and "cy" are aliases for "x" and "y". "r" is the datum's - * radius, and "fill" is the CSS color of the datum. - */ - public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Scatter; - public _paint(): void; + * @param {string} attrToSet One of ["x", "y", "cx", "cy", "r", + * "fill"]. "cx" and "cy" are aliases for "x" and "y". "r" is the datum's + * radius, and "fill" is the CSS color of the datum. + */ + project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Scatter; + _paint(): void; } } } @@ -2677,30 +2692,30 @@ declare module Plottable { declare module Plottable { module Plot { class Grid extends Abstract.XYPlot { - public _colorScale: Abstract.Scale; - public _xScale: Scale.Ordinal; - public _yScale: Scale.Ordinal; - public _animators: Animator.IPlotAnimatorMap; - /** - * Constructs a GridPlot. - * - * A GridPlot is used to shade a grid of data. Each datum is a cell on the - * grid, and the datum can control what color it is. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale.Ordinal} xScale The x scale to use. - * @param {Scale.Ordinal} yScale The y scale to use. - * @param {Scale.Color|Scale.InterpolatedColor} colorScale The color scale - * to use for each grid cell. - */ + _colorScale: Abstract.Scale; + _xScale: Scale.Ordinal; + _yScale: Scale.Ordinal; + _animators: Animator.IPlotAnimatorMap; + /** + * Constructs a GridPlot. + * + * A GridPlot is used to shade a grid of data. Each datum is a cell on the + * grid, and the datum can control what color it is. + * + * @constructor + * @param {IDataset | any} dataset The dataset to render. + * @param {Scale.Ordinal} xScale The x scale to use. + * @param {Scale.Ordinal} yScale The y scale to use. + * @param {Scale.Color|Scale.InterpolatedColor} colorScale The color scale + * to use for each grid cell. + */ constructor(dataset: any, xScale: Scale.Ordinal, yScale: Scale.Ordinal, colorScale: Abstract.Scale); /** - * @param {string} attrToSet One of ["x", "y", "fill"]. If "fill" is used, - * the data should return a valid CSS color. - */ - public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Grid; - public _paint(): void; + * @param {string} attrToSet One of ["x", "y", "fill"]. If "fill" is used, + * the data should return a valid CSS color. + */ + project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Grid; + _paint(): void; } } } @@ -2709,68 +2724,68 @@ declare module Plottable { declare module Plottable { module Abstract { class BarPlot extends XYPlot { - public _bars: D3.UpdateSelection; - public _baseline: D3.Selection; - public _baselineValue: number; - public _barAlignmentFactor: number; + _bars: D3.UpdateSelection; + _baseline: D3.Selection; + _baselineValue: number; + _barAlignmentFactor: number; static _BarAlignmentToFactor: { - [alignment: string]: number; + [x: string]: number; }; - public _isVertical: boolean; - public _animators: Animator.IPlotAnimatorMap; - /** - * Constructs an AbstractBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + _isVertical: boolean; + _animators: Animator.IPlotAnimatorMap; + /** + * Constructs an AbstractBarPlot. + * + * @constructor + * @param {IDataset | any} 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); - public _setup(): void; - public _paint(): void; - /** - * Sets the baseline for the bars to the specified value. - * - * The baseline is the line that the bars are drawn from, defaulting to 0. - * - * @param {number} value The value to position the baseline at. - * @returns {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. - * @returns {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"); - * @returns {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. - * @returns {AbstractBarPlot} The calling AbstractBarPlot. - */ - public deselectAll(): BarPlot; - public _updateDomainer(scale: Scale): void; - public _updateYDomainer(): void; - public _updateXDomainer(): void; - public _generateAttrToProjector(): IAttributeToProjector; + _setup(): void; + _paint(): void; + /** + * Sets the baseline for the bars to the specified value. + * + * The baseline is the line that the bars are drawn from, defaulting to 0. + * + * @param {number} value The value to position the baseline at. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ + 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. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ + 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"); + * @returns {D3.Selection} The selected bar, or null if no bar was selected. + */ + 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; + /** + * Deselects all bars. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ + deselectAll(): BarPlot; + _updateDomainer(scale: Scale): void; + _updateYDomainer(): void; + _updateXDomainer(): void; + _generateAttrToProjector(): IAttributeToProjector; } } } @@ -2779,28 +2794,28 @@ declare module Plottable { declare module Plottable { module 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 - */ + * A VerticalBarPlot draws bars vertically. + * Key projected attributes: + * - "width" - the horizontal width of a bar. + * - if an ordinal scale is attached, this defaults to ordinalScale.rangeBand() + * - if a quantitative scale is attached, this defaults to 10 + * - "x" - the horizontal position of a bar + * - "y" - the vertical height of a bar + */ class VerticalBar extends Abstract.BarPlot { static _BarAlignmentToFactor: { - [alignment: string]: number; + [x: string]: number; }; /** - * Constructs a VerticalBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a VerticalBarPlot. + * + * @constructor + * @param {IDataset | any} 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); - public _updateYDomainer(): void; + _updateYDomainer(): void; } } } @@ -2809,29 +2824,29 @@ declare module Plottable { declare module Plottable { module 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 - */ + * A HorizontalBarPlot draws bars horizontally. + * Key projected attributes: + * - "width" - the vertical height of a bar (since the bar is rotated horizontally) + * - if an ordinal scale is attached, this defaults to ordinalScale.rangeBand() + * - if a quantitative scale is attached, this defaults to 10 + * - "x" - the horizontal length of a bar + * - "y" - the vertical position of a bar + */ class HorizontalBar extends Abstract.BarPlot { static _BarAlignmentToFactor: { - [alignment: string]: number; + [x: string]: number; }; /** - * Constructs a HorizontalBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a HorizontalBarPlot. + * + * @constructor + * @param {IDataset | any} 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); - public _updateXDomainer(): void; - public _generateAttrToProjector(): IAttributeToProjector; + _updateXDomainer(): void; + _generateAttrToProjector(): IAttributeToProjector; } } } @@ -2840,23 +2855,24 @@ declare module Plottable { declare module Plottable { module Plot { class Line extends Abstract.XYPlot { - public _yScale: Abstract.QuantitativeScale; - public _animators: Animator.IPlotAnimatorMap; - /** - * Constructs a LinePlot. - * - * @constructor - * @param {any | IDataset} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + _yScale: Abstract.QuantitativeScale; + _animators: Animator.IPlotAnimatorMap; + /** + * Constructs a LinePlot. + * + * @constructor + * @param {any | IDataset} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ constructor(dataset: any, xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); - public _setup(): void; - public _appendPath(): void; - public _getResetYFunction(): (d: any, i: number) => number; - public _generateAttrToProjector(): IAttributeToProjector; - public _paint(): void; - public _wholeDatumAttributes(): string[]; + _setup(): void; + _appendPath(): void; + _getResetYFunction(): (d: any, i: number) => number; + _generateAttrToProjector(): IAttributeToProjector; + _rejectNullsAndNaNs(d: any, i: number, projector: IAppliedAccessor): boolean; + _paint(): void; + _wholeDatumAttributes(): string[]; } } } @@ -2865,25 +2881,25 @@ 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. - */ + * An AreaPlot draws a filled region (area) between the plot's projected "y" and projected "y0" values. + */ class Area extends Line { /** - * Constructs an AreaPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs an AreaPlot. + * + * @constructor + * @param {IDataset | any} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ constructor(dataset: any, xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); - public _appendPath(): void; - public _onDatasetUpdate(): void; - public _updateYDomainer(): void; - public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Area; - public _getResetYFunction(): IAppliedAccessor; - public _paint(): void; - public _wholeDatumAttributes(): string[]; + _appendPath(): void; + _onDatasetUpdate(): void; + _updateYDomainer(): void; + project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Area; + _getResetYFunction(): IAppliedAccessor; + _paint(): void; + _wholeDatumAttributes(): string[]; } } } @@ -2893,37 +2909,37 @@ declare module Plottable { module Abstract { class NewStyleBarPlot extends NewStylePlot { static _barAlignmentToFactor: { - [alignment: string]: number; + [x: string]: number; }; - public _baseline: D3.Selection; - public _baselineValue: number; - public _barAlignmentFactor: number; - public _isVertical: boolean; - public _animators: Animator.IPlotAnimatorMap; - /** - * Constructs a NewStyleBarPlot. - * - * @constructor - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + _baseline: D3.Selection; + _baselineValue: number; + _barAlignmentFactor: number; + _isVertical: boolean; + _animators: Animator.IPlotAnimatorMap; + /** + * Constructs a NewStyleBarPlot. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(xScale: Scale, yScale: Scale); - public _getDrawer(key: string): _Drawer.Rect; - public _setup(): void; - public _paint(): void; + _getDrawer(key: string): _Drawer.Rect; + _setup(): void; + _paint(): void; /** - * Sets the baseline for the bars to the specified value. - * - * The baseline is the line that the bars are drawn from, defaulting to 0. - * - * @param {number} value The value to position the baseline at. - * @returns {NewStyleBarPlot} The calling NewStyleBarPlot. - */ - public baseline(value: number): any; - public _updateDomainer(scale: Scale): any; - public _generateAttrToProjector(): IAttributeToProjector; - public _updateXDomainer(): any; - public _updateYDomainer(): any; + * Sets the baseline for the bars to the specified value. + * + * The baseline is the line that the bars are drawn from, defaulting to 0. + * + * @param {number} value The value to position the baseline at. + * @returns {NewStyleBarPlot} The calling NewStyleBarPlot. + */ + baseline(value: number): any; + _updateDomainer(scale: Scale): any; + _generateAttrToProjector(): IAttributeToProjector; + _updateXDomainer(): any; + _updateYDomainer(): any; } } } @@ -2933,19 +2949,19 @@ declare module Plottable { module Plot { class ClusteredBar extends Abstract.NewStyleBarPlot { /** - * Creates a ClusteredBarPlot. - * - * A ClusteredBarPlot is a plot that plots several bar plots next to each - * other. For example, when plotting life expectancy across each country, - * you would want each country to have a "male" and "female" bar. - * - * @constructor - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Creates a ClusteredBarPlot. + * + * A ClusteredBarPlot is a plot that plots several bar plots next to each + * other. For example, when plotting life expectancy across each country, + * you would want each country to have a "male" and "female" bar. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(xScale: Abstract.Scale, yScale: Abstract.Scale, isVertical?: boolean); - public _generateAttrToProjector(): IAttributeToProjector; - public _paint(): void; + _generateAttrToProjector(): IAttributeToProjector; + _paint(): void; } } } @@ -2954,9 +2970,9 @@ declare module Plottable { declare module Plottable { module Abstract { class Stacked extends NewStylePlot { - public _isVertical: boolean; - public _onDatasetUpdate(): void; - public _updateScaleExtents(): void; + _isVertical: boolean; + _onDatasetUpdate(): void; + _updateScaleExtents(): void; } } } @@ -2965,22 +2981,22 @@ declare module Plottable { declare module Plottable { module Plot { class StackedArea extends Abstract.Stacked { - public _baseline: D3.Selection; - public _baselineValue: number; - /** - * Constructs a StackedArea plot. - * - * @constructor - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + _baseline: D3.Selection; + _baselineValue: number; + /** + * Constructs a StackedArea plot. + * + * @constructor + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ constructor(xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); - public _getDrawer(key: string): _Drawer.Area; - public _setup(): void; - public _paint(): void; - public _updateYDomainer(): void; - public _onDatasetUpdate(): void; - public _generateAttrToProjector(): IAttributeToProjector; + _getDrawer(key: string): _Drawer.Area; + _setup(): void; + _paint(): void; + _updateYDomainer(): void; + _onDatasetUpdate(): void; + _generateAttrToProjector(): IAttributeToProjector; } } } @@ -2989,28 +3005,28 @@ declare module Plottable { declare module Plottable { module Plot { class StackedBar extends Abstract.Stacked { - public _baselineValue: number; - public _baseline: D3.Selection; - public _barAlignmentFactor: number; - /** - * Constructs a StackedBar plot. - * A StackedBarPlot is a plot that plots several bar plots stacking on top of each - * other. - * @constructor - * @param {Scale} xScale the x scale of the plot. - * @param {Scale} yScale the y scale of the plot. - * @param {boolean} isVertical if the plot if vertical. - */ + _baselineValue: number; + _baseline: D3.Selection; + _barAlignmentFactor: number; + /** + * Constructs a StackedBar plot. + * A StackedBarPlot is a plot that plots several bar plots stacking on top of each + * other. + * @constructor + * @param {Scale} xScale the x scale of the plot. + * @param {Scale} yScale the y scale of the plot. + * @param {boolean} isVertical if the plot if vertical. + */ constructor(xScale?: Abstract.Scale, yScale?: Abstract.Scale, isVertical?: boolean); - public _setup(): void; - public _getAnimator(drawer: Abstract._Drawer, index: number): Animator.Rect; - public _getDrawer(key: string): any; - public _generateAttrToProjector(): any; - public _paint(): void; - public baseline(value: number): any; - public _updateDomainer(scale: Abstract.Scale): any; - public _updateXDomainer(): any; - public _updateYDomainer(): any; + _setup(): void; + _getAnimator(drawer: Abstract._Drawer, index: number): Animator.Rect; + _getDrawer(key: string): any; + _generateAttrToProjector(): any; + _paint(): void; + baseline(value: number): any; + _updateDomainer(scale: Abstract.Scale): any; + _updateXDomainer(): any; + _updateYDomainer(): any; } } } @@ -3020,15 +3036,15 @@ declare module Plottable { module Animator { interface IPlotAnimator { /** - * 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. - * @return {D3.Selection} Animators should return the selection or - * transition object so that plots may chain the transitions between - * animators. - */ + * 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. + * @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): D3.Selection; } interface IPlotAnimatorMap { @@ -3041,11 +3057,11 @@ declare module Plottable { declare module Plottable { module Animator { /** - * An animator implementation with no animation. The attributes are - * immediately set on the selection. - */ + * An animator implementation with no animation. The attributes are + * immediately set on the selection. + */ class Null implements IPlotAnimator { - public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; } } } @@ -3054,67 +3070,67 @@ declare module Plottable { declare module Plottable { module Animator { /** - * The base animator implementation with easing, duration, and delay. - */ + * The base animator implementation with easing, duration, and delay. + */ class Base implements IPlotAnimator { /** - * The default duration of the animation in milliseconds - */ + * The default duration of the animation in milliseconds + */ static DEFAULT_DURATION_MILLISECONDS: number; /** - * The default starting delay of the animation in milliseconds - */ + * The default starting delay of the animation in milliseconds + */ static DEFAULT_DELAY_MILLISECONDS: number; /** - * The default easing of the animation - */ + * The default easing of the animation + */ static DEFAULT_EASING: string; /** - * Constructs the default animator - * - * @constructor - */ + * Constructs the default animator + * + * @constructor + */ constructor(); - public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; /** - * Gets the duration of the animation in milliseconds. - * - * @returns {number} The current duration. - */ - public duration(): number; + * Gets the duration of the animation in milliseconds. + * + * @returns {number} The current duration. + */ + 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): Base; + * Sets the duration of the animation in milliseconds. + * + * @param {number} duration The duration in milliseconds. + * @returns {Default} The calling Default Animator. + */ + duration(duration: number): Base; /** - * Gets the delay of the animation in milliseconds. - * - * @returns {number} The current delay. - */ - public delay(): number; + * Gets the delay of the animation in milliseconds. + * + * @returns {number} The current delay. + */ + 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): Base; + * Sets the delay of the animation in milliseconds. + * + * @param {number} delay The delay in milliseconds. + * @returns {Default} The calling Default Animator. + */ + delay(delay: number): Base; /** - * Gets the current easing of the animation. - * - * @returns {string} the current easing mode. - */ - public easing(): string; + * Gets the current easing of the animation. + * + * @returns {string} the current easing mode. + */ + 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): Base; + * Sets the easing mode of the animation. + * + * @param {string} easing The desired easing mode. + * @returns {Default} The calling Default Animator. + */ + easing(easing: string): Base; } } } @@ -3123,36 +3139,60 @@ 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. - */ + * An animator that delays the animation of the attributes using the index + * of the selection data. + * + * The maximum delay between animations can be configured with maxIterativeDelay. + * + * The maximum total animation duration can be configured with maxTotalDuration. + * maxTotalDuration does not set actual total animation duration. + * + * The actual interval delay is calculated by following formula: + * min(maxIterativeDelay(), + * max(totalDurationLimit() - duration(), 0) / ) + */ class IterativeDelay extends Base { /** - * The start delay between each start of an animation - */ - static DEFAULT_ITERATIVE_DELAY_MILLISECONDS: number; + * The default maximum start delay between each start of an animation + */ + static DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS: number; /** - * Constructs an animator with a start delay between each selection animation - * - * @constructor - */ + * The default maximum total animation duration + */ + static DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS: number; + /** + * Constructs an animator with a start delay between each selection animation + * + * @constructor + */ constructor(); - public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + /** + * Gets the maximum start delay between animations in milliseconds. + * + * @returns {number} The current maximum iterative delay. + */ + maxIterativeDelay(): number; + /** + * Sets the maximum start delay between animations in milliseconds. + * + * @param {number} maxIterDelay The maximum iterative delay in milliseconds. + * @returns {IterativeDelay} The calling IterativeDelay Animator. + */ + maxIterativeDelay(maxIterDelay: number): IterativeDelay; /** - * Gets the start delay between animations in milliseconds. - * - * @returns {number} The current iterative delay. - */ - public iterativeDelay(): number; + * Gets the maximum total animation duration in milliseconds. + * + * @returns {number} The current maximum total animation duration. + */ + maxTotalDuration(): number; /** - * Sets the start delay between animations in milliseconds. - * - * @param {number} iterDelay The iterative delay in milliseconds. - * @returns {IterativeDelay} The calling IterativeDelay Animator. - */ - public iterativeDelay(iterDelay: number): IterativeDelay; + * Sets the maximum total animation duration in miliseconds. + * + * @param {number} maxDuration The maximum total animation duration in milliseconds. + * @returns {IterativeDelay} The calling IterativeDelay Animator. + */ + maxTotalDuration(maxDuration: number): IterativeDelay; } } } @@ -3161,15 +3201,15 @@ declare module Plottable { declare module Plottable { module Animator { /** - * The default animator implementation with easing, duration, and delay. - */ + * The default animator implementation with easing, duration, and delay. + */ class Rect extends Base { static ANIMATED_ATTRIBUTES: string[]; - public isVertical: boolean; - public isReverse: boolean; + isVertical: boolean; + isReverse: boolean; constructor(isVertical?: boolean, isReverse?: boolean); - public animate(selection: any, attrToProjector: IAttributeToProjector): any; - public _startMovingProjector(attrToProjector: IAttributeToProjector): IAppliedAccessor; + animate(selection: any, attrToProjector: IAttributeToProjector): any; + _startMovingProjector(attrToProjector: IAttributeToProjector): IAppliedAccessor; } } } @@ -3178,27 +3218,27 @@ declare module Plottable { declare module Plottable { module Core { /** - * A function to be called when an event occurs. The argument is the d3 event - * generated by the event. - */ + * A function to be called when an event occurs. The argument is the d3 event + * generated by the event. + */ interface IKeyEventListenerCallback { (e: D3.D3Event): any; } /** - * A module for listening to keypresses on the document. - */ + * A module for listening to keypresses on the document. + */ module KeyEventListener { /** - * Turns on key listening. - */ + * Turns on key listening. + */ function initialize(): void; /** - * When a key event occurs with the key corresponding te keyCod, call cb. - * - * @param {number} keyCode The javascript key code to call cb on. - * @param {IKeyEventListener} cb Will be called when keyCode key event - * occurs. - */ + * When a key event occurs with the key corresponding te keyCod, call cb. + * + * @param {number} keyCode The javascript key code to call cb on. + * @param {IKeyEventListener} cb Will be called when keyCode key event + * occurs. + */ function addCallback(keyCode: number, cb: IKeyEventListenerCallback): void; } } @@ -3209,15 +3249,15 @@ declare module Plottable { module Abstract { class Interaction extends PlottableObject { /** - * It maintains a 'hitBox' which is where all event listeners are - * attached. Due to cross- browser weirdness, the hitbox needs to be an - * opaque but invisible rectangle. TODO: We should give the interaction - * "foreground" and "background" elements where it can draw things, - * e.g. crosshairs. - */ - public _hitBox: D3.Selection; - public _componentToListenTo: Component; - public _anchor(component: Component, hitBox: D3.Selection): void; + * It maintains a 'hitBox' which is where all event listeners are + * attached. Due to cross- browser weirdness, the hitbox needs to be an + * opaque but invisible rectangle. TODO: We should give the interaction + * "foreground" and "background" elements where it can draw things, + * e.g. crosshairs. + */ + _hitBox: D3.Selection; + _componentToListenTo: Component; + _anchor(component: Component, hitBox: D3.Selection): void; } } } @@ -3226,17 +3266,17 @@ declare module Plottable { declare module Plottable { module Interaction { class Click extends Abstract.Interaction { - public _anchor(component: Abstract.Component, hitBox: D3.Selection): void; - public _listenTo(): string; + _anchor(component: Abstract.Component, hitBox: D3.Selection): void; + _listenTo(): string; /** - * Sets a callback to be called when a click is received. - * - * @param {(p: Point) => any} cb Callback that takes the pixel position of the click event. - */ - public callback(cb: (p: Point) => any): Click; + * Sets a callback to be called when a click is received. + * + * @param {(p: Point) => any} cb Callback that takes the pixel position of the click event. + */ + callback(cb: (p: Point) => any): Click; } class DoubleClick extends Click { - public _listenTo(): string; + _listenTo(): string; } } } @@ -3246,24 +3286,24 @@ declare module Plottable { module Interaction { class Key extends Abstract.Interaction { /** - * Creates a KeyInteraction. - * - * KeyInteraction listens to key events that occur while the component is - * moused over. - * - * @constructor - * @param {number} keyCode The key code to listen for. - */ + * Creates a KeyInteraction. + * + * KeyInteraction listens to key events that occur while the component is + * moused over. + * + * @constructor + * @param {number} keyCode The key code to listen for. + */ constructor(keyCode: number); - public _anchor(component: Abstract.Component, hitBox: D3.Selection): void; + _anchor(component: Abstract.Component, hitBox: D3.Selection): void; /** - * Sets a callback to be called when the designated key is pressed and the - * user is moused over the component. - * - * @param {() => any} cb Callback to be called. - * @returns The calling Key. - */ - public callback(cb: () => any): Key; + * Sets a callback to be called when the designated key is pressed and the + * user is moused over the component. + * + * @param {() => any} cb Callback to be called. + * @returns The calling Key. + */ + callback(cb: () => any): Key; } } } @@ -3272,24 +3312,24 @@ declare module Plottable { declare module Plottable { module Interaction { class PanZoom extends Abstract.Interaction { - public _xScale: Abstract.QuantitativeScale; - public _yScale: Abstract.QuantitativeScale; - /** - * Creates a PanZoomInteraction. - * - * The allows you to move around and zoom in on a plot, interactively. It - * does so by changing the xScale and yScales' domains repeatedly. - * - * @constructor - * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. - * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. - */ + _xScale: Abstract.QuantitativeScale; + _yScale: Abstract.QuantitativeScale; + /** + * Creates a PanZoomInteraction. + * + * The allows you to move around and zoom in on a plot, interactively. It + * does so by changing the xScale and yScales' domains repeatedly. + * + * @constructor + * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. + * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. + */ constructor(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale); /** - * Sets the scales back to their original domains. - */ - public resetZoom(): void; - public _anchor(component: Abstract.Component, hitBox: D3.Selection): void; + * Sets the scales back to their original domains. + */ + resetZoom(): void; + _anchor(component: Abstract.Component, hitBox: D3.Selection): void; } } } @@ -3298,41 +3338,41 @@ declare module Plottable { declare module Plottable { module Interaction { class BarHover extends Abstract.Interaction { - public _componentToListenTo: Abstract.BarPlot; - public _anchor(barPlot: Abstract.BarPlot, hitBox: D3.Selection): void; + _componentToListenTo: Abstract.BarPlot; + _anchor(barPlot: Abstract.BarPlot, hitBox: D3.Selection): void; /** - * Gets the current hover mode. - * - * @return {string} The current hover mode. - */ - public hoverMode(): string; + * Gets the current hover mode. + * + * @return {string} The current hover mode. + */ + 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 If provided, the desired hover mode. - * @return {BarHover} The calling BarHover. - */ - public hoverMode(mode: string): BarHover; + * 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 If provided, the desired hover mode. + * @return {BarHover} The calling BarHover. + */ + hoverMode(mode: string): BarHover; /** - * Attaches an callback to be called when the user mouses over a bar. - * - * @param {(datum: any, bar: D3.Selection) => any} callback The callback to be called. - * The callback will be passed the data from the hovered-over bar. - * @return {BarHover} The calling BarHover. - */ - public onHover(callback: (datum: any, bar: D3.Selection) => any): BarHover; + * Attaches an callback to be called when the user mouses over a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} callback The callback to be called. + * The callback will be passed the data from the hovered-over bar. + * @return {BarHover} The calling BarHover. + */ + 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} callback The callback to be called. - * The callback will be passed the data from the last-hovered bar. - * @return {BarHover} The calling BarHover. - */ - public onUnhover(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} callback The callback to be called. + * The callback will be passed the data from the last-hovered bar. + * @return {BarHover} The calling BarHover. + */ + onUnhover(callback: (datum: any, bar: D3.Selection) => any): BarHover; } } } @@ -3341,67 +3381,67 @@ declare module Plottable { declare module Plottable { module Interaction { class Drag extends Abstract.Interaction { - public _origin: number[]; - public _location: number[]; + _origin: number[]; + _location: number[]; /** - * Constructs a Drag. A Drag will signal its callbacks on mouse drag. - */ + * Constructs a Drag. A Drag will signal its callbacks on mouse drag. + */ constructor(); /** - * Gets the callback that is called when dragging starts. - * - * @returns {(startLocation: Point) => void} The callback called when dragging starts. - */ - public dragstart(): (startLocation: Point) => void; - /** - * Sets the callback to be called when dragging starts. - * - * @param {(startLocation: Point) => any} cb If provided, the function to be called. Takes in a Point in pixels. - * @returns {Drag} The calling Drag. - */ - public dragstart(cb: (startLocation: Point) => any): Drag; - /** - * Gets the callback that is called during dragging. - * - * @returns {(startLocation: Point, endLocation: Point) => void} The callback called during dragging. - */ - public drag(): (startLocation: Point, endLocation: Point) => void; - /** - * Adds a callback to be called during dragging. - * - * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. - * @returns {Drag} The calling 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} The callback called when dragging ends. - */ - public dragend(): (startLocation: Point, endLocation: Point) => void; - /** - * Adds a callback to be called when the dragging ends. - * - * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. - * @returns {Drag} The calling Drag. - */ - public dragend(cb: (startLocation: Point, endLocation: Point) => any): Drag; - public _dragstart(): void; - public _doDragstart(): void; - public _drag(): void; - public _doDrag(): void; - public _dragend(): void; - public _doDragend(): void; - public _anchor(component: Abstract.Component, hitBox: D3.Selection): Drag; - /** - * Sets up so that the xScale and yScale that are passed have their - * domains automatically changed as you zoom. - * - * @param {QuantitativeScale} xScale The scale along the x-axis. - * @param {QuantitativeScale} yScale The scale along the y-axis. - * @returns {Drag} The calling Drag. - */ - public setupZoomCallback(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale): Drag; + * Gets the callback that is called when dragging starts. + * + * @returns {(startLocation: Point) => void} The callback called when dragging starts. + */ + dragstart(): (startLocation: Point) => void; + /** + * Sets the callback to be called when dragging starts. + * + * @param {(startLocation: Point) => any} cb If provided, the function to be called. Takes in a Point in pixels. + * @returns {Drag} The calling Drag. + */ + dragstart(cb: (startLocation: Point) => any): Drag; + /** + * Gets the callback that is called during dragging. + * + * @returns {(startLocation: Point, endLocation: Point) => void} The callback called during dragging. + */ + drag(): (startLocation: Point, endLocation: Point) => void; + /** + * Adds a callback to be called during dragging. + * + * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. + * @returns {Drag} The calling Drag. + */ + drag(cb: (startLocation: Point, endLocation: Point) => any): Drag; + /** + * Gets the callback that is called when dragging ends. + * + * @returns {(startLocation: Point, endLocation: Point) => void} The callback called when dragging ends. + */ + dragend(): (startLocation: Point, endLocation: Point) => void; + /** + * Adds a callback to be called when the dragging ends. + * + * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. + * @returns {Drag} The calling Drag. + */ + dragend(cb: (startLocation: Point, endLocation: Point) => any): Drag; + _dragstart(): void; + _doDragstart(): void; + _drag(): void; + _doDrag(): void; + _dragend(): void; + _doDragend(): void; + _anchor(component: Abstract.Component, hitBox: D3.Selection): Drag; + /** + * Sets up so that the xScale and yScale that are passed have their + * domains automatically changed as you zoom. + * + * @param {QuantitativeScale} xScale The scale along the x-axis. + * @param {QuantitativeScale} yScale The scale along the y-axis. + * @returns {Drag} The calling Drag. + */ + setupZoomCallback(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale): Drag; } } } @@ -3410,38 +3450,38 @@ declare module Plottable { declare module Plottable { module Interaction { /** - * A DragBox is an interaction that automatically draws a box across the - * element you attach it to when you drag. - */ + * A DragBox is an interaction that automatically draws a box across the + * element you attach it to when you drag. + */ class DragBox extends Drag { /** - * The DOM element of the box that is drawn. When no box is drawn, it is - * null. - */ - public dragBox: D3.Selection; + * The DOM element of the box that is drawn. When no box is drawn, it is + * null. + */ + dragBox: D3.Selection; /** - * Whether or not dragBox has been rendered in a visible area. - */ - public boxIsDrawn: boolean; - public _dragstart(): void; + * Whether or not dragBox has been rendered in a visible area. + */ + boxIsDrawn: boolean; + _dragstart(): void; /** - * Clears the highlighted drag-selection box drawn by the DragBox. - * - * @returns {DragBox} The calling DragBox. - */ - public clearBox(): DragBox; + * Clears the highlighted drag-selection box drawn by the DragBox. + * + * @returns {DragBox} The calling DragBox. + */ + clearBox(): DragBox; /** - * Set where the box is draw explicitly. - * - * @param {number} x0 Left. - * @param {number} x1 Right. - * @param {number} y0 Top. - * @param {number} y1 Bottom. - * - * @returns {DragBox} The calling DragBox. - */ - public setBox(x0: number, x1: number, y0: number, y1: number): DragBox; - public _anchor(component: Abstract.Component, hitBox: D3.Selection): DragBox; + * Set where the box is draw explicitly. + * + * @param {number} x0 Left. + * @param {number} x1 Right. + * @param {number} y0 Top. + * @param {number} y1 Bottom. + * + * @returns {DragBox} The calling DragBox. + */ + setBox(x0: number, x1: number, y0: number, y1: number): DragBox; + _anchor(component: Abstract.Component, hitBox: D3.Selection): DragBox; } } } @@ -3450,8 +3490,8 @@ declare module Plottable { declare module Plottable { module Interaction { class XDragBox extends DragBox { - public _drag(): void; - public setBox(x0: number, x1: number): XDragBox; + _drag(): void; + setBox(x0: number, x1: number): XDragBox; } } } @@ -3460,7 +3500,7 @@ declare module Plottable { declare module Plottable { module Interaction { class XYDragBox extends DragBox { - public _drag(): void; + _drag(): void; } } } @@ -3469,8 +3509,8 @@ declare module Plottable { declare module Plottable { module Interaction { class YDragBox extends DragBox { - public _drag(): void; - public setBox(y0: number, y1: number): YDragBox; + _drag(): void; + setBox(y0: number, y1: number): YDragBox; } } } @@ -3479,41 +3519,41 @@ declare module Plottable { declare module Plottable { module Abstract { class Dispatcher extends PlottableObject { - public _target: D3.Selection; - public _event2Callback: { - [eventName: string]: () => any; + _target: D3.Selection; + _event2Callback: { + [x: string]: () => any; }; /** - * Constructs a Dispatcher with the specified target. - * - * @param {D3.Selection} target The selection to listen for events on. - */ + * Constructs a Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ constructor(target: D3.Selection); /** - * Gets the target of the Dispatcher. - * - * @returns {D3.Selection} The Dispatcher's current target. - */ - public target(): D3.Selection; + * Gets the target of the Dispatcher. + * + * @returns {D3.Selection} The Dispatcher's current target. + */ + 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; + * Sets the target of the Dispatcher. + * + * @param {D3.Selection} target The element to listen for updates on. + * @returns {Dispatcher} The calling Dispatcher. + */ + target(targetElement: D3.Selection): Dispatcher; /** - * Attaches the Dispatcher's listeners to the Dispatcher's target element. - * - * @returns {Dispatcher} The calling Dispatcher. - */ - public connect(): Dispatcher; + * Attaches the Dispatcher's listeners to the Dispatcher's target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ + connect(): Dispatcher; /** - * Detaches the Dispatcher's listeners from the Dispatchers' target element. - * - * @returns {Dispatcher} The calling Dispatcher. - */ - public disconnect(): Dispatcher; + * Detaches the Dispatcher's listeners from the Dispatchers' target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ + disconnect(): Dispatcher; } } } @@ -3523,53 +3563,53 @@ declare module Plottable { module Dispatcher { class Mouse extends Abstract.Dispatcher { /** - * Constructs a Mouse Dispatcher with the specified target. - * - * @param {D3.Selection} target The selection to listen for events on. - */ + * Constructs a Mouse Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ constructor(target: D3.Selection); /** - * 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; + * Gets the current callback to be called on mouseover. + * + * @return {(location: Point) => any} The current mouseover callback. + */ + 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. + */ + mouseover(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mousemove. + * + * @return {(location: Point) => any} The current mousemove callback. + */ + 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. + */ + mousemove(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mouseout. + * + * @return {(location: Point) => any} The current mouseout callback. + */ + 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. + */ + mouseout(callback: (location: Point) => any): Mouse; } } } diff --git a/plottable.d.ts b/plottable.d.ts index 5bb71f7c84..e1f02bf209 100644 --- a/plottable.d.ts +++ b/plottable.d.ts @@ -3,94 +3,94 @@ 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] - */ + * 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 - */ + * + * @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] - */ + * 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 - * - * Due to the fact that D3.Sets store strings internally, return type is always a string set - * - * @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 - */ + * Takes two sets and returns the intersection + * + * Due to the fact that D3.Sets store strings internally, return type is always a string set + * + * @param {D3.Set} set1 The first set + * @param {D3.Set} set2 The second set + * @return {D3.Set} A set that contains elements that appear in both set1 and set2 + */ function intersection(set1: D3.Set, set2: D3.Set): D3.Set; /** - * Take an accessor object (may be a string to be made into a key, or a value, or a color code) - * and "activate" it by turning it into a function in (datum, index, metadata) - */ + * Take an accessor object (may be a string to be made into a key, or a value, or a color code) + * and "activate" it by turning it into a function in (datum, index, metadata) + */ function accessorize(accessor: any): _IAccessor; /** - * Takes two sets and returns the union - * - * Due to the fact that D3.Sets store strings internally, return type is always a string set - * - * @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 - */ + * Takes two sets and returns the union + * + * Due to the fact that D3.Sets store strings internally, return type is always a string set + * + * @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; /** - * Populates a map from an array of keys and a transformation function. - * - * @param {string[]} keys The array of keys. - * @param {(string) => T} transform A transformation function to apply to the keys. - * @return {D3.Map} A map mapping keys to their transformed values. - */ - function populateMap(keys: string[], transform: (key: string) => T): D3.Map; - /** - * Take an array of values, and return the unique values. - * Will work iff ∀ a, b, a.toString() == b.toString() => a == b; will break on Object inputs - * - * @param {T[]} values The values to find uniqueness for - * @return {T[]} The unique values - */ + * Populates a map from an array of keys and a transformation function. + * + * @param {string[]} keys The array of keys. + * @param {(string, number) => T} transform A transformation function to apply to the keys. + * @return {D3.Map} A map mapping keys to their transformed values. + */ + function populateMap(keys: string[], transform: (key: string, index: number) => T): D3.Map; + /** + * Take an array of values, and return the unique values. + * Will work iff ∀ a, b, a.toString() == b.toString() => a == b; will break on Object inputs + * + * @param {T[]} values The values to find uniqueness for + * @return {T[]} The unique values + */ function uniq(arr: T[]): T[]; /** - * 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 (called with index as arg) - * @param {number} count The length of the array to generate - * @return {any[]} - */ + * 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 (called with index as arg) + * @param {number} count The length of the array to generate + * @return {any[]} + */ function createFilledArray(value: T, count: number): T[]; function createFilledArray(func: (index?: number) => T, count: number): T[]; /** - * @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. - */ + * @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. - */ + * 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 ===. - */ + * @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; function max(arr: number[], default_val?: number): number; function max(arr: T[], acc: (x: T) => number, default_val?: number): number; @@ -105,41 +105,41 @@ 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. - */ + * 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; } @@ -150,9 +150,9 @@ declare module Plottable { declare module Plottable { module _Util { class IDCounter { - public increment(id: any): number; - public decrement(id: any): number; - public get(id: any): number; + increment(id: any): number; + decrement(id: any): number; + get(id: any): number; } } } @@ -161,62 +161,62 @@ 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... - */ + * 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 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; + * 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 + */ + 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 + */ + 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 + */ + has(key: any): boolean; + /** + * Return an array of the values in the key-value store + * + * @return {any[]} The values in the store + */ + values(): any[]; + /** + * Return an array of keys in the key-value store + * + * @return {any[]} The keys in the store + */ + 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 + */ + 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 + */ + delete(key: any): boolean; } } } @@ -226,35 +226,35 @@ 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 + * + * @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); /** - * 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; + * 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). + */ + 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; + * 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. + */ + clear(): Cache; } } } @@ -272,49 +272,49 @@ declare module Plottable { (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 - */ + * 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. - */ + * 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 { /** - * @param {string} s The string to be measured. - * @return {Dimensions} The width and height of the measured text. - */ - public measure: TextMeasurer; + * @param {string} s The string to be measured. + * @return {Dimensions} The width and height of the measured text. + */ + 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. - */ + * @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 the cache, if it seems that the text has changed size. - */ - public clear(): CachingCharacterMeasurer; + * Clear the cache, if it seems that the text has changed size. + */ + 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 - */ + * 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; /** - * 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. - */ + * Takes a line, a width to fit it in, and a text measurer. Will attempt to add ellipses to the end of the line, + * shortening the line as required to ensure that it fits within width. + */ function addEllipsesToLine(line: string, width: number, measureText: TextMeasurer): string; function writeLineHorizontally(line: string, g: D3.Selection, width: number, height: number, xAlign?: string, yAlign?: string): { width: number; @@ -335,12 +335,12 @@ declare module Plottable { 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; + * @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, orientation?: string, write?: IWriteOptions): IWriteTextResult; } } } @@ -355,15 +355,15 @@ declare module Plottable { 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. - */ + * 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. - */ + * 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; } } @@ -373,10 +373,10 @@ declare module Plottable { module _Util { module DOM { /** - * Gets the bounding box of an element. - * @param {D3.Selection} element - * @returns {SVGRed} The bounding box. - */ + * 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; @@ -398,75 +398,75 @@ declare module Plottable { var MILLISECONDS_IN_ONE_DAY: number; module 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. - */ + * 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. + */ function 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. - */ + * 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. + */ function 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. - */ + * 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. + */ function general(precision?: number, onlyShowUnchanged?: boolean): (d: any) => string; /** - * Creates a formatter that stringifies its input. - * - * @returns {Formatter} A formatter that stringifies its input. - */ + * Creates a formatter that stringifies its input. + * + * @returns {Formatter} A formatter that stringifies its input. + */ function 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. - */ + * 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. + */ function 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. - */ + * 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. + */ function siSuffix(precision?: number): (d: any) => string; /** - * Creates a formatter that displays dates. - * - * @returns {Formatter} A formatter for time/date values. - */ + * Creates a formatter that displays dates. + * + * @returns {Formatter} A formatter for time/date values. + */ function 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. - */ + * 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. + */ function relativeDate(baseValue?: number, increment?: number, label?: string): (d: any) => string; } } @@ -480,8 +480,8 @@ declare module Plottable { declare module Plottable { module Core { /** - * Colors we use as defaults on a number of graphs. - */ + * Colors we use as defaults on a number of graphs. + */ class Colors { static CORAL_RED: string; static INDIGO: string; @@ -502,9 +502,9 @@ declare module Plottable { declare module Plottable { module Abstract { /** - * A class most other Plottable classes inherit from, in order to have a - * unique ID. - */ + * A class most other Plottable classes inherit from, in order to have a + * unique ID. + */ class PlottableObject { } } @@ -514,76 +514,76 @@ 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) - */ + * 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. - */ + * 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; } /** - * 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. - */ + * 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; + listenable: IListenable; /** - * Constructs 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. - */ + * Constructs 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); /** - * 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; + * 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 + */ + 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; + * Call all listening callbacks, optionally with arguments passed through. + * + * @param ...args A variable number of optional arguments + * @returns {Broadcaster} this object + */ + 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 the callback associated with a key. + * + * @param key The key to deregister. + * @returns {Broadcaster} this object + */ + deregisterListener(key: any): Broadcaster; /** - * Deregisters all listeners and callbacks associated with the broadcaster. - * - * @returns {Broadcaster} this object - */ - public deregisterAllListeners(): void; + * Deregisters all listeners and callbacks associated with the broadcaster. + * + * @returns {Broadcaster} this object + */ + deregisterAllListeners(): void; } } } @@ -591,46 +591,46 @@ declare module Plottable { declare module Plottable { class Dataset extends Abstract.PlottableObject implements Core.IListenable { - public broadcaster: Core.Broadcaster; + broadcaster: any; /** - * Constructs a new set. - * - * A Dataset is mostly just a wrapper around an any[], Dataset is the - * data you're going to plot. - * - * @constructor - * @param {any[]} data The data for this DataSource (default = []). - * @param {any} metadata An object containing additional information (default = {}). - */ + * Constructs a new set. + * + * A Dataset is mostly just a wrapper around an any[], Dataset is the + * data you're going to plot. + * + * @constructor + * @param {any[]} data The data for this DataSource (default = []). + * @param {any} metadata An object containing additional information (default = {}). + */ constructor(data?: any[], metadata?: any); /** - * Gets the data. - * - * @returns {DataSource|any[]} The calling DataSource, or the current data. - */ - public data(): any[]; + * Gets the data. + * + * @returns {DataSource|any[]} The calling DataSource, or the current data. + */ + data(): any[]; /** - * Sets the data. - * - * @param {any[]} data The new data. - * @returns {Dataset} The calling Dataset. - */ - public data(data: any[]): Dataset; + * Sets the data. + * + * @param {any[]} data The new data. + * @returns {Dataset} The calling Dataset. + */ + data(data: any[]): Dataset; /** - * Get the metadata. - * - * @returns {any} the current - * metadata. - */ - public metadata(): any; + * Get the metadata. + * + * @returns {any} the current + * metadata. + */ + metadata(): any; /** - * Set the metadata. - * - * @param {any} metadata The new metadata. - * @returns {Dataset} The calling Dataset. - */ - public metadata(metadata: any): Dataset; - public _getExtent(accessor: _IAccessor, typeCoercer: (d: any) => any): any[]; + * Set the metadata. + * + * @param {any} metadata The new metadata. + * @returns {Dataset} The calling Dataset. + */ + metadata(metadata: any): Dataset; + _getExtent(accessor: _IAccessor, typeCoercer: (d: any) => any): any[]; } } @@ -640,32 +640,32 @@ declare module Plottable { module RenderController { module RenderPolicy { /** - * A policy to render components. - */ + * A policy to render components. + */ interface IRenderPolicy { render(): any; } /** - * Never queue anything, render everything immediately. Useful for - * debugging, horrible for performance. - */ + * Never queue anything, render everything immediately. Useful for + * debugging, horrible for performance. + */ class Immediate implements IRenderPolicy { - public render(): void; + render(): void; } /** - * The default way to render, which only tries to render every frame - * (usually, 1/60th of a second). - */ + * The default way to render, which only tries to render every frame + * (usually, 1/60th of a second). + */ class AnimationFrame implements IRenderPolicy { - public render(): void; + render(): void; } /** - * Renders with `setTimeout`. This is generally an inferior way to render - * compared to `requestAnimationFrame`, but it's still there if you want - * it. - */ + * Renders with `setTimeout`. This is generally an inferior way to render + * compared to `requestAnimationFrame`, but it's still there if you want + * it. + */ class Timeout implements IRenderPolicy { - public render(): void; + render(): void; } } } @@ -676,46 +676,46 @@ 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. - * - * If you want to always have immediate rendering (useful for debugging), - * call - * ```typescript - * Plottable.Core.RenderController.setRenderPolicy( - * new Plottable.Core.RenderController.RenderPolicy.Immediate() - * ); - * ``` - */ + * 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. + * + * If you want to always have immediate rendering (useful for debugging), + * call + * ```typescript + * Plottable.Core.RenderController.setRenderPolicy( + * new Plottable.Core.RenderController.RenderPolicy.Immediate() + * ); + * ``` + */ module RenderController { function setRenderPolicy(policy: string): void; function setRenderPolicy(policy: RenderPolicy.IRenderPolicy): void; /** - * If the RenderController is enabled, we enqueue the component for - * render. Otherwise, it is rendered immediately. - * - * @param {Abstract.Component} component Any Plottable component. - */ + * 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. - */ + * 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; /** - * Render everything that is waiting to be rendered right now, instead of - * waiting until the next frame. - * - * Useful to call when debugging. - */ + * Render everything that is waiting to be rendered right now, instead of + * waiting until the next frame. + * + * Useful to call when debugging. + */ function flush(): void; } } @@ -725,47 +725,47 @@ 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. - */ + * 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 { /** - * Checks if the window has been resized and the RenderController - * has not yet been flushed. - * - * @returns {boolean} If the window has been resized/RenderController - * has not yet been flushed. - */ + * Checks if the window has been resized and the RenderController + * has not yet been flushed. + * + * @returns {boolean} If the window has been resized/RenderController + * has not yet been flushed. + */ function resizing(): boolean; /** - * Sets that it is not resizing anymore. Good if it stubbornly thinks - * it is still resizing, or for cancelling the effects of resizing - * prematurely. - */ + * Sets that it is not resizing anymore. Good if it stubbornly thinks + * it is still resizing, or for cancelling the effects of resizing + * prematurely. + */ function clearResizing(): void; /** - * Registers a component. - * - * When the window is resized, ._invalidateLayout() is invoked on the - * component, which will enqueue the component for layout and rendering - * with the RenderController. - * - * @param {Component} component Any Plottable component. - */ + * Registers a component. + * + * When the window is resized, ._invalidateLayout() is invoked on the + * component, which will enqueue the component for layout and rendering + * with the RenderController. + * + * @param {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 {Component} component Any Plottable component. - */ + * Deregisters the components. + * + * The component will no longer receive updates on window resize. + * + * @param {Component} component Any Plottable component. + */ function deregister(c: Abstract.Component): void; } } @@ -784,14 +784,14 @@ declare module Plottable { (datum: any, index?: number, metadata?: any): any; } /** - * A function to map across the data in a DataSource. For example, if your - * data looked like `{foo: 5, bar: 6}`, then a popular function might be - * `function(d) { return d.foo; }`. - * - * Index, if used, will be the index of the datum in the array. - */ + * A function to map across the data in a DataSource. For example, if your + * data looked like `{foo: 5, bar: 6}`, then a popular function might be + * `function(d) { return d.foo; }`. + * + * Index, if used, will be the index of the datum in the array. + */ interface IAppliedAccessor { - (datum: any, index: number): any; + (datum?: any, index?: number): any; } interface _IProjector { accessor: _IAccessor; @@ -799,19 +799,19 @@ declare module Plottable { attribute: string; } /** - * A mapping from attributes ("x", "fill", etc.) to the functions that get - * that information out of the data. - * - * So if my data looks like `{foo: 5, bar: 6}` and I want the radius to scale - * with both `foo` and `bar`, an entry in this type might be `{"r": - * function(d) { return foo + bar; }`. - */ + * A mapping from attributes ("x", "fill", etc.) to the functions that get + * that information out of the data. + * + * So if my data looks like `{foo: 5, bar: 6}` and I want the radius to scale + * with both `foo` and `bar`, an entry in this type might be `{"r": + * function(d) { return foo + bar; }`. + */ interface IAttributeToProjector { [attrToSet: string]: IAppliedAccessor; } /** - * A simple bounding box. - */ + * A simple bounding box. + */ interface SelectionArea { xMin: number; xMax: number; @@ -831,26 +831,26 @@ declare module Plottable { yMax: number; } /** - * The range of your current data. For example, [1, 2, 6, -5] has the IExtent - * `{min: -5, max: 6}`. - * - * The point of this type is to hopefully replace the less-elegant `[min, - * max]` extents produced by d3. - */ + * The range of your current data. For example, [1, 2, 6, -5] has the IExtent + * `{min: -5, max: 6}`. + * + * The point of this type is to hopefully replace the less-elegant `[min, + * max]` extents produced by d3. + */ interface IExtent { min: number; max: number; } /** - * A simple location on the screen. - */ + * A simple location on the screen. + */ interface Point { x: number; y: number; } /** - * A key that is also coupled with a dataset and a drawer. - */ + * A key that is also coupled with a dataset and a drawer. + */ interface DatasetDrawerKey { dataset: Dataset; drawer: Abstract._Drawer; @@ -862,96 +862,96 @@ declare module Plottable { declare module Plottable { class Domainer { /** - * Constructs a new Domainer. - * - * @constructor - * @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. - */ + * Constructs a new Domainer. + * + * @constructor + * @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[]); /** - * @param {any[][]} extents The list of extents to be reduced to a single - * extent. - * @param {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. - * @returns {any[]} The domain, as a merging of all exents, as a [min, max] - * pair. - */ - public computeDomain(extents: any[][], scale: Abstract.QuantitativeScale): any[]; + * @param {any[][]} extents The list of extents to be reduced to a single + * extent. + * @param {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. + * @returns {any[]} The domain, as a merging of all exents, as a [min, max] + * pair. + */ + 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]. - * - * @returns {Domainer} The calling Domainer. - */ - public pad(padProportion?: number): Domainer; + * 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]. + * + * @returns {Domainer} The calling Domainer. + */ + pad(padProportion?: number): Domainer; /** - * Adds 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. - * @returns {Domainer} The calling domainer - */ - public addPaddingException(exception: any, key?: string): Domainer; + * Adds 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. + * @returns {Domainer} The calling domainer + */ + addPaddingException(exception: any, key?: string): Domainer; /** - * Removes 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; + * Removes 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 + */ + removePaddingException(keyOrException: any): Domainer; /** - * Adds 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. - * @returns {Domainer} The calling domainer - */ - public addIncludedValue(value: any, key?: string): Domainer; + * Adds 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. + * @returns {Domainer} The calling domainer + */ + 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; + * 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 + */ + 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; + * 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. + */ + nice(count?: number): Domainer; } } @@ -959,86 +959,86 @@ declare module Plottable { declare module Plottable { module Abstract { class Scale extends PlottableObject implements Core.IListenable { - public broadcaster: Core.Broadcaster; - /** - * Constructs a new Scale. - * - * A Scale is a wrapper around a D3.Scale.Scale. A Scale is really just a - * function. Scales have a domain (input), a range (output), and a function - * from domain to range. - * - * @constructor - * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. - */ + broadcaster: any; + /** + * Constructs a new Scale. + * + * A Scale is a wrapper around a D3.Scale.Scale. A Scale is really just a + * function. Scales have a domain (input), a range (output), and a function + * from domain to range. + * + * @constructor + * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. + */ constructor(scale: D3.Scale.Scale); /** - * Modifies the domain on the scale so that it includes the extent of all - * perspectives it depends on. This will normally happen automatically, but - * if you set domain explicitly with `plot.domain(x)`, you will need to - * call this function if you want the domain to neccessarily include all - * the data. - * - * Extent: The [min, max] pair for a Scale.Quantitative, all covered - * strings for a Scale.Ordinal. - * - * Perspective: A combination of a Dataset and an Accessor that - * represents a view in to the data. - * - * @returns {Scale} The calling Scale. - */ - public autoDomain(): Scale; - /** - * Computes the range value corresponding to a given domain value. In other - * words, apply the function to value. - * - * @param {R} value A domain value to be scaled. - * @returns {R} The range value corresponding to the supplied domain value. - */ - public scale(value: D): R; - /** - * Gets the domain. - * - * @returns {D[]} The current domain. - */ - public domain(): D[]; - /** - * Sets the domain. - * - * @param {D[]} values If provided, the new value for the domain. On - * a QuantitativeScale, this is a [min, max] pair, or a [max, min] pair to - * make the function decreasing. On Scale.Ordinal, this is an array of all - * input values. - * @returns {Scale} The calling Scale. - */ - public domain(values: D[]): Scale; - /** - * Gets the range. - * - * In the case of having a numeric range, it will be a [min, max] pair. In - * the case of string range (e.g. Scale.InterpolatedColor), it will be a - * list of all possible outputs. - * - * @returns {R[]} The current range. - */ - public range(): R[]; - /** - * Sets the range. - * - * In the case of having a numeric range, it will be a [min, max] pair. In - * the case of string range (e.g. Scale.InterpolatedColor), it will be a - * list of all possible outputs. - * - * @param {R[]} values If provided, the new values for the range. - * @returns {Scale} The calling Scale. - */ - public range(values: R[]): Scale; - /** - * Constructs 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; + * Modifies the domain on the scale so that it includes the extent of all + * perspectives it depends on. This will normally happen automatically, but + * if you set domain explicitly with `plot.domain(x)`, you will need to + * call this function if you want the domain to neccessarily include all + * the data. + * + * Extent: The [min, max] pair for a Scale.Quantitative, all covered + * strings for a Scale.Ordinal. + * + * Perspective: A combination of a Dataset and an Accessor that + * represents a view in to the data. + * + * @returns {Scale} The calling Scale. + */ + autoDomain(): Scale; + /** + * Computes the range value corresponding to a given domain value. In other + * words, apply the function to value. + * + * @param {R} value A domain value to be scaled. + * @returns {R} The range value corresponding to the supplied domain value. + */ + scale(value: D): R; + /** + * Gets the domain. + * + * @returns {D[]} The current domain. + */ + domain(): D[]; + /** + * Sets the domain. + * + * @param {D[]} values If provided, the new value for the domain. On + * a QuantitativeScale, this is a [min, max] pair, or a [max, min] pair to + * make the function decreasing. On Scale.Ordinal, this is an array of all + * input values. + * @returns {Scale} The calling Scale. + */ + domain(values: D[]): Scale; + /** + * Gets the range. + * + * In the case of having a numeric range, it will be a [min, max] pair. In + * the case of string range (e.g. Scale.InterpolatedColor), it will be a + * list of all possible outputs. + * + * @returns {R[]} The current range. + */ + range(): R[]; + /** + * Sets the range. + * + * In the case of having a numeric range, it will be a [min, max] pair. In + * the case of string range (e.g. Scale.InterpolatedColor), it will be a + * list of all possible outputs. + * + * @param {R[]} values If provided, the new values for the range. + * @returns {Scale} The calling Scale. + */ + range(values: R[]): Scale; + /** + * Constructs a copy of the Scale with the same domain and range but without + * any registered listeners. + * + * @returns {Scale} A copy of the calling Scale. + */ + copy(): Scale; } } } @@ -1048,99 +1048,99 @@ declare module Plottable { module Abstract { class QuantitativeScale extends Scale { /** - * Constructs a new QuantitativeScale. - * - * A QuantitativeScale is a Scale that maps anys to numbers. It - * is invertible and continuous. - * - * @constructor - * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale - * backing the QuantitativeScale. - */ + * Constructs a new QuantitativeScale. + * + * A QuantitativeScale is a Scale that maps anys to numbers. It + * is invertible and continuous. + * + * @constructor + * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale + * backing the QuantitativeScale. + */ constructor(scale: D3.Scale.QuantitativeScale); /** - * Retrieves the domain value corresponding to a supplied range value. - * - * @param {number} value: A value from the Scale's range. - * @returns {D} The domain value corresponding to the supplied range value. - */ - public invert(value: number): D; - /** - * 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(): D[]; - public domain(values: D[]): 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; - /** - * Gets a set of tick values spanning the domain. - * - * @param {number} [count] The approximate number of ticks to generate. - * If not supplied, the number specified by - * numTicks() is used instead. - * @returns {any[]} The generated ticks. - */ - public ticks(count?: number): any[]; - /** - * Gets the default number of ticks. - * - * @returns {number} The default number of ticks. - */ - public numTicks(): number; - /** - * Sets the default number of ticks to generate. - * - * @param {number} count The new default number of ticks. - * @returns {Scale} The calling Scale. - */ - public numTicks(count: number): QuantitativeScale; - /** - * Gets a Domainer of a scale. A Domainer is responsible for combining - * multiple extents into a single domain. - * - * @return {Domainer} 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 If provided, the new domainer. - * @return {QuanitativeScale} The calling QuantitativeScale. - */ - public 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 {D} The domain value corresponding to the supplied range value. + */ + invert(value: number): D; + /** + * 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. + */ + copy(): QuantitativeScale; + domain(): D[]; + domain(values: D[]): 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. + */ + interpolate(): D3.Transition.Interpolate; + 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. + */ + 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. + */ + 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. + */ + clamp(clamp: boolean): QuantitativeScale; + /** + * Gets a set of tick values spanning the domain. + * + * @param {number} [count] The approximate number of ticks to generate. + * If not supplied, the number specified by + * numTicks() is used instead. + * @returns {any[]} The generated ticks. + */ + ticks(count?: number): any[]; + /** + * Gets the default number of ticks. + * + * @returns {number} The default number of ticks. + */ + numTicks(): number; + /** + * Sets the default number of ticks to generate. + * + * @param {number} count The new default number of ticks. + * @returns {Scale} The calling Scale. + */ + numTicks(count: number): QuantitativeScale; + /** + * Gets a Domainer of a scale. A Domainer is responsible for combining + * multiple extents into a single domain. + * + * @return {Domainer} The scale's current domainer. + */ + 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 If provided, the new domainer. + * @return {QuanitativeScale} The calling QuantitativeScale. + */ + domainer(domainer: Domainer): QuantitativeScale; } } } @@ -1150,23 +1150,23 @@ declare module Plottable { module Scale { class Linear extends Abstract.QuantitativeScale { /** - * Constructs a new LinearScale. - * - * This scale maps from domain to range with a simple `mx + b` formula. - * - * @constructor - * @param {D3.Scale.LinearScale} [scale] The D3 LinearScale backing the - * LinearScale. If not supplied, uses a default scale. - */ + * Constructs a new LinearScale. + * + * This scale maps from domain to range with a simple `mx + b` formula. + * + * @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); /** - * Constructs a copy of the Scale.Linear with the same domain and range but - * without any registered listeners. - * - * @returns {Linear} A copy of the calling Scale.Linear. - */ - public copy(): Linear; + * Constructs a copy of the Scale.Linear with the same domain and range but + * without any registered listeners. + * + * @returns {Linear} A copy of the calling Scale.Linear. + */ + copy(): Linear; } } } @@ -1176,25 +1176,25 @@ declare module Plottable { module Scale { class Log extends Abstract.QuantitativeScale { /** - * Constructs 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. - */ + * Constructs 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); /** - * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. - * - * @returns {Log} A copy of the calling Log. - */ - public copy(): Log; + * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. + * + * @returns {Log} A copy of the calling Log. + */ + copy(): Log; } } } @@ -1204,51 +1204,51 @@ declare module Plottable { module Scale { 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). - */ + * 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); - public scale(x: number): number; - public invert(x: number): number; - public ticks(count?: number): number[]; - public copy(): ModifiedLog; + scale(x: number): number; + invert(x: number): number; + ticks(count?: number): number[]; + copy(): ModifiedLog; /** - * Gets 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]. - * @returns {boolean} the current setting. - */ - public showIntermediateTicks(): boolean; + * Gets 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]. + * @returns {boolean} the current setting. + */ + showIntermediateTicks(): boolean; /** - * Sets whether or not to return ticks values other than powers or base. - * - * @param {boolean} show If provided, the desired setting. - * @returns {ModifiedLog} The calling ModifiedLog. - */ - public showIntermediateTicks(show: boolean): ModifiedLog; + * Sets whether or not to return ticks values other than powers or base. + * + * @param {boolean} show If provided, the desired setting. + * @returns {ModifiedLog} The calling ModifiedLog. + */ + showIntermediateTicks(show: boolean): ModifiedLog; } } } @@ -1258,46 +1258,46 @@ declare module Plottable { module Scale { class Ordinal extends Abstract.Scale { /** - * Creates an OrdinalScale. - * - * An OrdinalScale maps strings to numbers. A common use is to map the - * labels of a bar plot (strings) to their pixel locations (numbers). - * - * @constructor - */ + * Creates an OrdinalScale. + * + * An OrdinalScale maps strings to numbers. A common use is to map the + * labels of a bar plot (strings) to their pixel locations (numbers). + * + * @constructor + */ constructor(scale?: D3.Scale.OrdinalScale); - public domain(): string[]; - public domain(values: string[]): Ordinal; - public range(): number[]; - public range(values: number[]): Ordinal; + domain(): string[]; + domain(values: string[]): Ordinal; + range(): number[]; + 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: string): number[]; + * 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". + */ + rangeBand(): number; + innerPadding(): number; + fullBandStartAndWidth(v: string): number[]; /** - * Get the range type. - * - * @returns {string} The current range type. - */ - public rangeType(): string; + * Get the range type. + * + * @returns {string} The current range type. + */ + rangeType(): string; /** - * Set the range type. - * - * @param {string} rangeType If provided, either "points" or "bands" indicating the - * d3 method used to generate range bounds. - * @param {number} [outerPadding] If provided, the padding outside the range, - * proportional to the range step. - * @param {number} [innerPadding] If provided, 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. - */ - public rangeType(rangeType: string, outerPadding?: number, innerPadding?: number): Ordinal; - public copy(): Ordinal; + * Set the range type. + * + * @param {string} rangeType If provided, either "points" or "bands" indicating the + * d3 method used to generate range bounds. + * @param {number} [outerPadding] If provided, the padding outside the range, + * proportional to the range step. + * @param {number} [innerPadding] If provided, 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. + */ + rangeType(rangeType: string, outerPadding?: number, innerPadding?: number): Ordinal; + copy(): Ordinal; } } } @@ -1307,13 +1307,13 @@ declare module Plottable { module Scale { class Color extends Abstract.Scale { /** - * Constructs 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 - */ + * Constructs 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); } } @@ -1324,16 +1324,16 @@ declare module Plottable { module Scale { class Time extends Abstract.QuantitativeScale { /** - * Constructs a TimeScale. - * - * A TimeScale maps Date objects to numbers. - * - * @constructor - * @param {D3.Scale.Time} scale The D3 LinearScale backing the Scale.Time. If not supplied, uses a default scale. - */ + * Constructs a TimeScale. + * + * A TimeScale maps Date objects to numbers. + * + * @constructor + * @param {D3.Scale.Time} scale The D3 LinearScale backing the Scale.Time. If not supplied, uses a default scale. + */ constructor(); constructor(scale: D3.Scale.LinearScale); - public copy(): Time; + copy(): Time; } } } @@ -1342,58 +1342,58 @@ declare module Plottable { declare module Plottable { module 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. - */ + * 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.Scale { /** - * Constructs an InterpolatedColorScale. - * - * An InterpolatedColorScale maps numbers evenly to color strings. - * - * @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. - */ + * Constructs an InterpolatedColorScale. + * + * An InterpolatedColorScale maps numbers evenly to color strings. + * + * @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); /** - * Gets the color range. - * - * @returns {string[]} the current color values for the range as strings. - */ - public colorRange(): string[]; + * Gets the color range. + * + * @returns {string[]} the current color values for the range as strings. + */ + colorRange(): string[]; /** - * Sets the color range. - * - * @param {string|string[]} [colorRange]. If provided and 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. - */ - public colorRange(colorRange: any): InterpolatedColor; + * Sets the color range. + * + * @param {string|string[]} [colorRange]. If provided and 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. + */ + colorRange(colorRange: any): InterpolatedColor; /** - * Gets the internal scale type. - * - * @returns {string} The current scale type. - */ - public scaleType(): string; + * Gets the internal scale type. + * + * @returns {string} The current scale type. + */ + scaleType(): string; /** - * Sets the internal scale type. - * - * @param {string} scaleType If provided, the type of d3 scale to use internally. (linear/log/sqrt/pow). - * @returns {InterpolatedColor} The calling InterpolatedColor. - */ - public scaleType(scaleType: string): InterpolatedColor; - public autoDomain(): InterpolatedColor; + * Sets the internal scale type. + * + * @param {string} scaleType If provided, the type of d3 scale to use internally. (linear/log/sqrt/pow). + * @returns {InterpolatedColor} The calling InterpolatedColor. + */ + scaleType(scaleType: string): InterpolatedColor; + autoDomain(): InterpolatedColor; } } } @@ -1403,13 +1403,13 @@ declare module Plottable { module _Util { class ScaleDomainCoordinator { /** - * Constructs a ScaleDomainCoordinator. - * - * @constructor - * @param {Scale[]} scales A list of scales whose domains should be linked. - */ + * Constructs 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; + rescale(scale: Abstract.Scale): void; } } } @@ -1418,25 +1418,25 @@ declare module Plottable { declare module Plottable { module Abstract { class _Drawer { - public key: string; + key: string; /** - * Constructs a Drawer - * - * @constructor - * @param{string} key The key associated with this Drawer - */ + * Constructs a Drawer + * + * @constructor + * @param{string} key The key associated with this Drawer + */ constructor(key: string); /** - * Removes the Drawer and its renderArea - */ - public remove(): void; + * Removes the Drawer and its renderArea + */ + 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, animator?: Animator.Null): 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 + */ + draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; } } } @@ -1445,7 +1445,7 @@ declare module Plottable { declare module Plottable { module _Drawer { class Arc extends Abstract._Drawer { - public draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; + draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; } } } @@ -1454,7 +1454,7 @@ declare module Plottable { declare module Plottable { module _Drawer { class Area extends Abstract._Drawer { - public draw(data: any[], attrToProjector: IAttributeToProjector): void; + draw(data: any[], attrToProjector: IAttributeToProjector): void; } } } @@ -1463,7 +1463,7 @@ declare module Plottable { declare module Plottable { module _Drawer { class Rect extends Abstract._Drawer { - public draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; + draw(data: any[], attrToProjector: IAttributeToProjector, animator?: Animator.Null): void; } } } @@ -1473,135 +1473,135 @@ declare module Plottable { module Abstract { class Component extends PlottableObject { static AUTORESIZE_BY_DEFAULT: boolean; - public clipPathEnabled: boolean; - /** - * Renders the Component into a given DOM element. The element must be as . - * - * @param {String|D3.Selection} element A D3 selection or a selector for getting the element to render into. - * @returns {Component} The calling component. - */ - public renderTo(selector: String): Component; - public renderTo(element: D3.Selection): Component; - /** - * Causes the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. - * - * This function should be called when CSS changes could influence the size - * of the components, e.g. changing the font size. - * - * @param {number} [availableWidth] - the width of the container element - * @param {number} [availableHeight] - the height of the container element - * @returns {Component} The calling component. - */ - public resize(width?: number, height?: number): Component; - /** - * Enables or disables resize on window resizes. - * - * 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 Enable (true) or disable (false) auto-resize. - * @returns {Component} The calling component. - */ - public autoResize(flag: boolean): Component; - /** - * Sets the x alignment of the Component. This will be used if the - * Component is given more space than it needs. - * - * For example, you may want to make a Legend postition itself it the top - * right, so you would call `legend.xAlign("right")` and - * `legend.yAlign("top")`. - * - * @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. This will be used if the - * Component is given more space than it needs. - * - * For example, you may want to make a Legend postition itself it the top - * right, so you would call `legend.xAlign("right")` and - * `legend.yAlign("top")`. - * - * @param {string} alignment The x 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. This will be used if the Component - * is given more space than it needs. - * - * @param {number} offset The desired x offset, in pixels, from the left - * side of the container. - * @returns {Component} The calling Component. - */ - public xOffset(offset: number): Component; - /** - * Sets the y offset of the Component. This will be used if the Component - * is given more space than it needs. - * - * @param {number} offset The desired y offset, in pixels, from the top - * side of the container. - * @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. - * @returns {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. - * @returns {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. This is used to layer Components on top of each other. - * - * 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. - * @returns {ComponentGroup} The relevant ComponentGroup out of the above four cases. - */ - public merge(c: Component): Component.Group; - /** - * Detaches a Component from the DOM. The component can be reused. - * - * This should only be used if you plan on reusing the calling - * Components. Otherwise, use remove(). - * - * @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; - /** - * Return the width of the component - * - * @return {number} width of the component - */ - public width(): number; - /** - * Return the height of the component - * - * @return {number} height of the component - */ - public height(): number; + clipPathEnabled: boolean; + /** + * Renders the Component into a given DOM element. The element must be as . + * + * @param {String|D3.Selection} element A D3 selection or a selector for getting the element to render into. + * @returns {Component} The calling component. + */ + renderTo(selector: String): Component; + renderTo(element: D3.Selection): Component; + /** + * Causes the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. + * + * This function should be called when CSS changes could influence the size + * of the components, e.g. changing the font size. + * + * @param {number} [availableWidth] - the width of the container element + * @param {number} [availableHeight] - the height of the container element + * @returns {Component} The calling component. + */ + resize(width?: number, height?: number): Component; + /** + * Enables or disables resize on window resizes. + * + * 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 Enable (true) or disable (false) auto-resize. + * @returns {Component} The calling component. + */ + autoResize(flag: boolean): Component; + /** + * Sets the x alignment of the Component. This will be used if the + * Component is given more space than it needs. + * + * For example, you may want to make a Legend postition itself it the top + * right, so you would call `legend.xAlign("right")` and + * `legend.yAlign("top")`. + * + * @param {string} alignment The x alignment of the Component (one of ["left", "center", "right"]). + * @returns {Component} The calling Component. + */ + xAlign(alignment: string): Component; + /** + * Sets the y alignment of the Component. This will be used if the + * Component is given more space than it needs. + * + * For example, you may want to make a Legend postition itself it the top + * right, so you would call `legend.xAlign("right")` and + * `legend.yAlign("top")`. + * + * @param {string} alignment The x alignment of the Component (one of ["top", "center", "bottom"]). + * @returns {Component} The calling Component. + */ + yAlign(alignment: string): Component; + /** + * Sets the x offset of the Component. This will be used if the Component + * is given more space than it needs. + * + * @param {number} offset The desired x offset, in pixels, from the left + * side of the container. + * @returns {Component} The calling Component. + */ + xOffset(offset: number): Component; + /** + * Sets the y offset of the Component. This will be used if the Component + * is given more space than it needs. + * + * @param {number} offset The desired y offset, in pixels, from the top + * side of the container. + * @returns {Component} The calling Component. + */ + 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. + * @returns {Component} The calling Component. + */ + 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. + * @returns {boolean|Component} Whether the Component has the given CSS class, or the calling Component (if addClass is supplied). + */ + classed(cssClass: string): boolean; + classed(cssClass: string, addClass: boolean): Component; + /** + * Merges this Component with another Component, returning a + * ComponentGroup. This is used to layer Components on top of each other. + * + * 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. + * @returns {ComponentGroup} The relevant ComponentGroup out of the above four cases. + */ + merge(c: Component): Component.Group; + /** + * Detaches a Component from the DOM. The component can be reused. + * + * This should only be used if you plan on reusing the calling + * Components. Otherwise, use remove(). + * + * @returns The calling Component. + */ + detach(): Component; + /** + * Removes a Component from the DOM and disconnects it from everything it's + * listening to (effectively destroying it). + */ + remove(): void; + /** + * Return the width of the component + * + * @return {number} width of the component + */ + width(): number; + /** + * Return the height of the component + * + * @return {number} height of the component + */ + height(): number; } } } @@ -1611,25 +1611,25 @@ declare module Plottable { module Abstract { class ComponentContainer extends Component { /** - * Returns a list of components in the ComponentContainer. - * - * @returns {Component[]} the contained Components - */ - public components(): Component[]; + * Returns a list of components in the ComponentContainer. + * + * @returns {Component[]} the contained Components + */ + components(): Component[]; /** - * Returns true iff the ComponentContainer is empty. - * - * @returns {boolean} Whether the calling ComponentContainer is empty. - */ - public empty(): boolean; + * Returns true iff the ComponentContainer is empty. + * + * @returns {boolean} Whether the calling ComponentContainer is empty. + */ + empty(): boolean; /** - * Detaches all components contained in the ComponentContainer, and - * empties the ComponentContainer. - * - * @returns {ComponentContainer} The calling ComponentContainer - */ - public detachAll(): ComponentContainer; - public remove(): void; + * Detaches all components contained in the ComponentContainer, and + * empties the ComponentContainer. + * + * @returns {ComponentContainer} The calling ComponentContainer + */ + detachAll(): ComponentContainer; + remove(): void; } } } @@ -1639,17 +1639,17 @@ declare module Plottable { module Component { class Group extends Abstract.ComponentContainer { /** - * Constructs a GroupComponent. - * - * A GroupComponent is a set of Components that will be rendered on top of - * each other. When you call Component.merge(Component), it creates and - * returns a GroupComponent. - * - * @constructor - * @param {Component[]} components The Components in the Group (default = []). - */ + * Constructs a GroupComponent. + * + * A GroupComponent is a set of Components that will be rendered on top of + * each other. When you call Component.merge(Component), it creates and + * returns a GroupComponent. + * + * @constructor + * @param {Component[]} components The Components in the Group (default = []). + */ constructor(components?: Abstract.Component[]); - public merge(c: Abstract.Component): Group; + merge(c: Abstract.Component): Group; } } } @@ -1659,133 +1659,133 @@ declare module Plottable { module Abstract { class Axis extends Component { /** - * The css class applied to each end tick mark (the line on the end tick). - */ + * 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). - */ + * 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). - */ + * The css class applied to each tick label (the text associated with the tick). + */ static TICK_LABEL_CLASS: string; /** - * Constructs an axis. An axis is a wrapper around a scale for rendering. - * - * @constructor - * @param {Scale} scale The scale for this axis to render. - * @param {string} orientation One of ["top", "left", "bottom", "right"]; - * on which side the axis will appear. On most axes, this is either "left" - * or "bottom". - * @param {Formatter} Data is passed through this formatter before being - * displayed. - */ + * Constructs an axis. An axis is a wrapper around a scale for rendering. + * + * @constructor + * @param {Scale} scale The scale for this axis to render. + * @param {string} orientation One of ["top", "left", "bottom", "right"]; + * on which side the axis will appear. On most axes, this is either "left" + * or "bottom". + * @param {Formatter} Data is passed through this formatter before being + * displayed. + */ constructor(scale: Scale, orientation: string, formatter?: (d: any) => string); - public remove(): void; - /** - * Gets the current formatter on the axis. Data is passed through the - * formatter before being displayed. - * - * @returns {Formatter} The calling Axis, or the current - * Formatter. - */ - public formatter(): Formatter; - /** - * Sets the current formatter on the axis. Data is passed through the - * formatter before being displayed. - * - * @param {Formatter} formatter If provided, data will be passed though `formatter(data)`. - * @returns {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 current tick mark length. - * - * @param {number} length If provided, length of each tick. - * @returns {Axis} 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 If provided, 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. - * length. - */ - public tickLabelPadding(): number; - /** - * Sets the padding between each tick mark and its associated label. - * - * @param {number} padding If provided, the desired padding. - * @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 gutter. - * length. - */ - 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 If provided, the desired gutter. - * @returns {Axis} The calling Axis. - */ - public gutter(size: number): Axis; - /** - * Gets the orientation of the Axis. - * - * @returns {number} the current orientation. - */ - public orient(): string; - /** - * Sets the orientation of the Axis. - * - * @param {number} newOrientation If provided, the desired orientation - * (top/bottom/left/right). - * @returns {Axis} The calling Axis. - */ - public orient(newOrientation: string): Axis; - /** - * Gets whether the Axis is currently set to show the first and last - * tick labels. - * - * @returns {boolean} whether or not the last - * tick labels are showing. - */ - public showEndTickLabels(): boolean; - /** - * Sets whether the Axis is currently set 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; + remove(): void; + /** + * Gets the current formatter on the axis. Data is passed through the + * formatter before being displayed. + * + * @returns {Formatter} The calling Axis, or the current + * Formatter. + */ + formatter(): Formatter; + /** + * Sets the current formatter on the axis. Data is passed through the + * formatter before being displayed. + * + * @param {Formatter} formatter If provided, data will be passed though `formatter(data)`. + * @returns {Axis} The calling Axis. + */ + formatter(formatter: Formatter): Axis; + /** + * Gets the current tick mark length. + * + * @returns {number} the current tick mark length. + */ + tickLength(): number; + /** + * Sets the current tick mark length. + * + * @param {number} length If provided, length of each tick. + * @returns {Axis} The calling Axis. + */ + tickLength(length: number): Axis; + /** + * Gets the current end tick mark length. + * + * @returns {number} The current end tick mark length. + */ + endTickLength(): number; + /** + * Sets the end tick mark length. + * + * @param {number} length If provided, the length of the end ticks. + * @returns {BaseAxis} The calling Axis. + */ + endTickLength(length: number): Axis; + /** + * Gets the padding between each tick mark and its associated label. + * + * @returns {number} the current padding. + * length. + */ + tickLabelPadding(): number; + /** + * Sets the padding between each tick mark and its associated label. + * + * @param {number} padding If provided, the desired padding. + * @returns {Axis} The calling Axis. + */ + 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 gutter. + * length. + */ + 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 If provided, the desired gutter. + * @returns {Axis} The calling Axis. + */ + gutter(size: number): Axis; + /** + * Gets the orientation of the Axis. + * + * @returns {number} the current orientation. + */ + orient(): string; + /** + * Sets the orientation of the Axis. + * + * @param {number} newOrientation If provided, the desired orientation + * (top/bottom/left/right). + * @returns {Axis} The calling Axis. + */ + orient(newOrientation: string): Axis; + /** + * Gets whether the Axis is currently set to show the first and last + * tick labels. + * + * @returns {boolean} whether or not the last + * tick labels are showing. + */ + showEndTickLabels(): boolean; + /** + * Sets whether the Axis is currently set 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. + */ + showEndTickLabels(show: boolean): Axis; } } } @@ -1800,14 +1800,14 @@ declare module Plottable { } class Time extends Abstract.Axis { /** - * Constructs a TimeAxis. - * - * A TimeAxis is used for rendering a TimeScale. - * - * @constructor - * @param {TimeScale} scale The scale to base the Axis on. - * @param {string} orientation The orientation of the Axis (top/bottom) - */ + * Constructs a TimeAxis. + * + * A TimeAxis is used for rendering a TimeScale. + * + * @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); } } @@ -1818,57 +1818,57 @@ declare module Plottable { module Axis { class Numeric extends Abstract.Axis { /** - * Constructs a NumericAxis. - * - * Just as an CategoryAxis is for rendering an OrdinalScale, a NumericAxis - * is for rendering a QuantitativeScale. - * - * @constructor - * @param {QuantitativeScale} scale The QuantitativeScale to base the axis 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)). - */ + * Constructs a NumericAxis. + * + * Just as an CategoryAxis is for rendering an OrdinalScale, a NumericAxis + * is for rendering a QuantitativeScale. + * + * @constructor + * @param {QuantitativeScale} scale The QuantitativeScale to base the axis 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 If provided, the relative position of the tick label. - * [top/center/bottom] for a vertical NumericAxis, - * [left/center/right] for a horizontal NumericAxis. - * Defaults to center. - * @returns {Numeric} The calling Axis.Numeric. - */ - public tickLabelPosition(position: string): Numeric; - /** - * Gets 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; - /** - * Sets whether or not the tick labels at the end of the graph are - * displayed when partially cut off. - * - * @param {string} orientation If provided, 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 NumericAxis. - */ - public showEndTickLabel(orientation: string, show: boolean): Numeric; + * Gets the tick label position relative to the tick marks. + * + * @returns {string} The current tick label position. + */ + tickLabelPosition(): string; + /** + * Sets the tick label position relative to the tick marks. + * + * @param {string} position If provided, the relative position of the tick label. + * [top/center/bottom] for a vertical NumericAxis, + * [left/center/right] for a horizontal NumericAxis. + * Defaults to center. + * @returns {Numeric} The calling Axis.Numeric. + */ + tickLabelPosition(position: string): Numeric; + /** + * Gets 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. + */ + showEndTickLabel(orientation: string): boolean; + /** + * Sets whether or not the tick labels at the end of the graph are + * displayed when partially cut off. + * + * @param {string} orientation If provided, 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 NumericAxis. + */ + showEndTickLabel(orientation: string, show: boolean): Numeric; } } } @@ -1878,18 +1878,32 @@ declare module Plottable { module Axis { class Category extends Abstract.Axis { /** - * Constructs 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) (default = "bottom"). - * @param {Formatter} formatter The Formatter for the Axis (default Formatters.identity()) - */ + * Constructs 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) (default = "bottom"). + * @param {Formatter} formatter The Formatter for the Axis (default Formatters.identity()) + */ constructor(scale: Scale.Ordinal, orientation?: string, formatter?: (d: any) => string); + /** + * Sets the angle for the tick labels. Right now vertical-left (-90), horizontal (0), and vertical-right (90) are the only options. + * @param {number} angle The angle for the ticks + * @returns {Category} The calling Category Axis. + * + * Warning - this is not currently well supported and is likely to behave badly unless all the tick labels are short. + * See tracking at https://github.com/palantir/plottable/issues/504 + */ + tickLabelAngle(angle: number): Category; + /** + * Gets the tick label angle + * @returns {number} the tick label angle + */ + tickLabelAngle(): number; } } } @@ -1899,74 +1913,74 @@ declare module Plottable { module Component { class Label extends Abstract.Component { /** - * Creates a Label. - * - * A label is component that renders just text. The most common use of - * labels is to create a title or axis labels. - * - * @constructor - * @param {string} displayText The text of the Label (default = ""). - * @param {string} orientation The orientation of the Label (horizontal/vertical-left/vertical-right) (default = "horizontal"). - */ + * Creates a Label. + * + * A label is component that renders just text. The most common use of + * labels is to create a title or axis labels. + * + * @constructor + * @param {string} displayText The text of the Label (default = ""). + * @param {string} orientation The orientation of the Label (horizontal/left/right) (default = "horizontal"). + */ constructor(displayText?: string, orientation?: string); /** - * Sets the horizontal side the label will go to given the label is given more space that it needs - * - * @param {string} alignment The new setting, one of `["left", "center", - * "right"]`. Defaults to `"center"`. - * @returns {Label} The calling Label. - */ - public xAlign(alignment: string): Label; - /** - * Sets the vertical side the label will go to given the label is given more space that it needs - * - * @param {string} alignment The new setting, one of `["top", "center", - * "bottom"]`. Defaults to `"center"`. - * @returns {Label} The calling Label. - */ - public yAlign(alignment: string): Label; - /** - * Gets the current text on the Label. - * - * @returns {string} the text on the label. - */ - public text(): string; - /** - * Sets the current text on the Label. - * - * @param {string} displayText If provided, the new text for the Label. - * @returns {Label} The calling Label. - */ - public text(displayText: string): Label; - /** - * Gets the orientation of the Label. - * - * @returns {string} the current orientation. - */ - public orient(): string; - /** - * Sets the orientation of the Label. - * - * @param {string} newOrientation If provided, the desired orientation - * (horizontal/vertical-left/vertical-right). - * @returns {Label} The calling Label. - */ - public orient(newOrientation: string): Label; + * Sets the horizontal side the label will go to given the label is given more space that it needs + * + * @param {string} alignment The new setting, one of `["left", "center", + * "right"]`. Defaults to `"center"`. + * @returns {Label} The calling Label. + */ + xAlign(alignment: string): Label; + /** + * Sets the vertical side the label will go to given the label is given more space that it needs + * + * @param {string} alignment The new setting, one of `["top", "center", + * "bottom"]`. Defaults to `"center"`. + * @returns {Label} The calling Label. + */ + yAlign(alignment: string): Label; + /** + * Gets the current text on the Label. + * + * @returns {string} the text on the label. + */ + text(): string; + /** + * Sets the current text on the Label. + * + * @param {string} displayText If provided, the new text for the Label. + * @returns {Label} The calling Label. + */ + text(displayText: string): Label; + /** + * Gets the orientation of the Label. + * + * @returns {string} the current orientation. + */ + orient(): string; + /** + * Sets the orientation of the Label. + * + * @param {string} newOrientation If provided, the desired orientation + * (horizontal/left/right). + * @returns {Label} The calling Label. + */ + orient(newOrientation: string): Label; } class TitleLabel extends Label { /** - * Creates a TitleLabel, a type of label made for rendering titles. - * - * @constructor - */ + * Creates a TitleLabel, a type of label made for rendering titles. + * + * @constructor + */ constructor(text?: string, orientation?: string); } class AxisLabel extends Label { /** - * Creates a AxisLabel, a type of label made for rendering axis labels. - * - * @constructor - */ + * Creates a AxisLabel, a type of label made for rendering axis labels. + * + * @constructor + */ constructor(text?: string, orientation?: string); } } @@ -1983,81 +1997,81 @@ declare module Plottable { } class Legend extends Abstract.Component { /** - * The css class applied to each legend row - */ + * The css class applied to each legend row + */ static SUBELEMENT_CLASS: string; /** - * Constructs 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 {ColorScale} colorScale - */ + * Constructs 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 {ColorScale} colorScale + */ constructor(colorScale?: Scale.Color); - public remove(): void; - /** - * Gets the toggle callback from 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. - * - * @returns {ToggleCallback} The current toggle callback. - */ - public toggleCallback(): ToggleCallback; - /** - * Assigns a toggle 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. - * @returns {Legend} The calling Legend. - */ - public toggleCallback(callback: ToggleCallback): Legend; - /** - * Gets the hover callback from 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. - * - * @returns {HoverCallback} The new current hover callback. - */ - public hoverCallback(): HoverCallback; - /** - * Assigns a hover 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 If provided, the new callback function. - * @returns {Legend} The calling Legend. - */ - public hoverCallback(callback: HoverCallback): Legend; - /** - * Gets the current color scale from the Legend. - * - * @returns {ColorScale} The current color scale. - */ - public scale(): Scale.Color; - /** - * Assigns a new color scale to the Legend. - * - * @param {Scale.Color} scale If provided, the new scale. - * @returns {Legend} The calling Legend. - */ - public scale(scale: Scale.Color): Legend; + remove(): void; + /** + * Gets the toggle callback from 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. + * + * @returns {ToggleCallback} The current toggle callback. + */ + toggleCallback(): ToggleCallback; + /** + * Assigns a toggle 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. + * @returns {Legend} The calling Legend. + */ + toggleCallback(callback: ToggleCallback): Legend; + /** + * Gets the hover callback from 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. + * + * @returns {HoverCallback} The new current hover callback. + */ + hoverCallback(): HoverCallback; + /** + * Assigns a hover 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 If provided, the new callback function. + * @returns {Legend} The calling Legend. + */ + hoverCallback(callback: HoverCallback): Legend; + /** + * Gets the current color scale from the Legend. + * + * @returns {ColorScale} The current color scale. + */ + scale(): Scale.Color; + /** + * Assigns a new color scale to the Legend. + * + * @param {Scale.Color} scale If provided, the new scale. + * @returns {Legend} The calling Legend. + */ + scale(scale: Scale.Color): Legend; } } } @@ -2067,24 +2081,24 @@ declare module Plottable { module Component { class HorizontalLegend extends Abstract.Component { /** - * The css class applied to each legend row - */ + * The css class applied to each legend row + */ static LEGEND_ROW_CLASS: string; /** - * The css class applied to each legend entry - */ + * The css class applied to each legend entry + */ static LEGEND_ENTRY_CLASS: string; /** - * Creates a Horizontal Legend. - * - * The legend consists of a series of legend entries, each with a color and label taken from the `colorScale`. - * The entries will be displayed in the order of the `colorScale` domain. - * - * @constructor - * @param {Scale.Color} colorScale - */ + * Creates a Horizontal Legend. + * + * The legend consists of a series of legend entries, each with a color and label taken from the `colorScale`. + * The entries will be displayed in the order of the `colorScale` domain. + * + * @constructor + * @param {Scale.Color} colorScale + */ constructor(colorScale: Scale.Color); - public remove(): void; + remove(): void; } } } @@ -2094,14 +2108,14 @@ declare module Plottable { module Component { 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. - */ + * 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; + remove(): Gridlines; } } } @@ -2119,70 +2133,70 @@ declare module Plottable { } class Table extends Abstract.ComponentContainer { /** - * Constructs a Table. - * - * A Table is used to combine multiple Components in the form of a grid. A - * common case is combining a y-axis, x-axis, and the plotted data via - * ```typescript - * new Table([[yAxis, plot], - * [null, xAxis]]); - * ``` - * - * @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. (default = []) - */ + * Constructs a Table. + * + * A Table is used to combine multiple Components in the form of a grid. A + * common case is combining a y-axis, x-axis, and the plotted data via + * ```typescript + * new Table([[yAxis, plot], + * [null, xAxis]]); + * ``` + * + * @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. (default = []) + */ constructor(rows?: Abstract.Component[][]); /** - * Adds a Component in the specified cell. The cell must be unoccupied. - * - * For example, instead of calling `new Table([[a, b], [null, c]])`, you - * could call - * ```typescript - * var table = new Table(); - * table.addComponent(0, 0, a); - * table.addComponent(0, 1, b); - * table.addComponent(1, 1, c); - * ``` - * - * @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. - * @returns {Table} The calling Table. - */ - 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. - * - * A common case would be to have one graph take up 2/3rds of the space, - * and the other graph take up 1/3rd. - * - * @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. - * - * A common case would be to have one graph take up 2/3rds of the space, - * and the other graph take up 1/3rd. - * - * @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; + * Adds a Component in the specified cell. The cell must be unoccupied. + * + * For example, instead of calling `new Table([[a, b], [null, c]])`, you + * could call + * ```typescript + * var table = new Table(); + * table.addComponent(0, 0, a); + * table.addComponent(0, 1, b); + * table.addComponent(1, 1, c); + * ``` + * + * @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. + * @returns {Table} The calling Table. + */ + 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. + */ + 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. + * + * A common case would be to have one graph take up 2/3rds of the space, + * and the other graph take up 1/3rd. + * + * @param {number} index The index of the row. + * @param {number} weight The weight to be set on the row. + * @returns {Table} The calling Table. + */ + 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. + * + * A common case would be to have one graph take up 2/3rds of the space, + * and the other graph take up 1/3rd. + * + * @param {number} index The index of the column. + * @param {number} weight The weight to be set on the column. + * @returns {Table} The calling Table. + */ + colWeight(index: number, weight: number): Table; } } } @@ -2192,83 +2206,83 @@ declare module Plottable { module Abstract { class Plot extends Component { /** - * Constructs a Plot. - * - * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. - * - * A bare Plot has a DataSource and any number of projectors, which take - * data and "project" it onto the Plot, such as "x", "y", "fill", "r". - * - * @constructor - * @param {any[]|Dataset} [dataset] If provided, the data or Dataset to be associated with this Plot. - */ + * Constructs a Plot. + * + * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. + * + * A bare Plot has a DataSource and any number of projectors, which take + * data and "project" it onto the Plot, such as "x", "y", "fill", "r". + * + * @constructor + * @param {any[]|Dataset} [dataset] If provided, the data or Dataset to be associated with this Plot. + */ constructor(); constructor(data: any[]); constructor(dataset: Dataset); - public remove(): void; - /** - * Gets the Plot's Dataset. - * - * @returns {Dataset} The current Dataset. - */ - public dataset(): Dataset; - /** - * Sets the Plot's Dataset. - * - * @param {Dataset} dataset If provided, the Dataset the Plot should use. - * @returns {Plot} The calling Plot. - */ - public dataset(dataset: Dataset): Plot; - /** - * Sets an attribute of every data point. - * - * Here's a common use case: - * ```typescript - * plot.attr("r", function(d) { return d.foo; }); - * ``` - * This will set the radius of each datum `d` to be `d.foo`. - * - * @param {string} attrToSet The attribute to set across each data - * point. Popular examples include "x", "y", "r". Scales that inherit from - * Plot define their meaning. - * - * @param {Function|string|any} accessor Function to apply to each element - * of the dataSource. If a Function, use `accessor(d, i)`. If a string, - * `d[accessor]` is used. If anything else, use `accessor` as a constant - * across all data points. - * - * @param {Abstract.Scale} scale If provided, the result of the accessor - * is passed through the scale, such as `scale.scale(accessor(d, i))`. - * - * @returns {Plot} The calling Plot. - */ - public attr(attrToSet: string, accessor: any, scale?: Scale): Plot; - /** - * Identical to plot.attr - */ - 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; - /** - * Get the animator associated with the specified Animator key. - * - * @return {IPlotAnimator} The Animator for the specified key. - */ - public animator(animatorKey: string): Animator.IPlotAnimator; - /** - * Set the animator associated with the specified Animator key. - * - * @param {string} animatorKey The key for the Animator. - * @param {IPlotAnimator} animator An Animator to be assigned to - * the specified key. - * @returns {Plot} The calling Plot. - */ - public animator(animatorKey: string, animator: Animator.IPlotAnimator): Plot; + remove(): void; + /** + * Gets the Plot's Dataset. + * + * @returns {Dataset} The current Dataset. + */ + dataset(): Dataset; + /** + * Sets the Plot's Dataset. + * + * @param {Dataset} dataset If provided, the Dataset the Plot should use. + * @returns {Plot} The calling Plot. + */ + dataset(dataset: Dataset): Plot; + /** + * Sets an attribute of every data point. + * + * Here's a common use case: + * ```typescript + * plot.attr("r", function(d) { return d.foo; }); + * ``` + * This will set the radius of each datum `d` to be `d.foo`. + * + * @param {string} attrToSet The attribute to set across each data + * point. Popular examples include "x", "y", "r". Scales that inherit from + * Plot define their meaning. + * + * @param {Function|string|any} accessor Function to apply to each element + * of the dataSource. If a Function, use `accessor(d, i)`. If a string, + * `d[accessor]` is used. If anything else, use `accessor` as a constant + * across all data points. + * + * @param {Abstract.Scale} scale If provided, the result of the accessor + * is passed through the scale, such as `scale.scale(accessor(d, i))`. + * + * @returns {Plot} The calling Plot. + */ + attr(attrToSet: string, accessor: any, scale?: Scale): Plot; + /** + * Identical to plot.attr + */ + project(attrToSet: string, accessor: any, scale?: Scale): Plot; + /** + * Enables or disables animation. + * + * @param {boolean} enabled Whether or not to animate. + */ + animate(enabled: boolean): Plot; + detach(): Plot; + /** + * Get the animator associated with the specified Animator key. + * + * @return {IPlotAnimator} The Animator for the specified key. + */ + animator(animatorKey: string): Animator.IPlotAnimator; + /** + * Set the animator associated with the specified Animator key. + * + * @param {string} animatorKey The key for the Animator. + * @param {IPlotAnimator} animator An Animator to be assigned to + * the specified key. + * @returns {Plot} The calling Plot. + */ + animator(animatorKey: string, animator: Animator.IPlotAnimator): Plot; } } } @@ -2278,31 +2292,31 @@ declare module Plottable { module Plot { class Pie extends Abstract.Plot { /** - * Constructs a PiePlot. - * - * @constructor - */ + * Constructs a PiePlot. + * + * @constructor + */ constructor(); /** - * Adds a dataset to this plot. Only one dataset can be added to a PiePlot. - * - * A key is automatically generated if not supplied. - * - * @param {string} [key] The key of the dataset. - * @param {any[]|Dataset} dataset dataset to add. - * @returns {Pie} The calling PiePlot. - */ - public addDataset(key: string, dataset: Dataset): Pie; - public addDataset(key: string, dataset: any[]): Pie; - public addDataset(dataset: Dataset): Pie; - public addDataset(dataset: any[]): Pie; + * Adds a dataset to this plot. Only one dataset can be added to a PiePlot. + * + * A key is automatically generated if not supplied. + * + * @param {string} [key] The key of the dataset. + * @param {any[]|Dataset} dataset dataset to add. + * @returns {Pie} The calling PiePlot. + */ + addDataset(key: string, dataset: Dataset): Pie; + addDataset(key: string, dataset: any[]): Pie; + addDataset(dataset: Dataset): Pie; + addDataset(dataset: any[]): Pie; /** - * Removes a dataset - * - * @param {string} key The key of the dataset - * @returns {Pie} The calling PiePlot. - */ - public removeDataset(key: string): Pie; + * Removes a dataset + * + * @param {string} key The key of the dataset + * @returns {Pie} The calling PiePlot. + */ + removeDataset(key: string): Pie; } } } @@ -2312,22 +2326,22 @@ declare module Plottable { module Abstract { class XYPlot extends Plot { /** - * Constructs an XYPlot. - * - * An XYPlot is a plot from drawing 2-dimensional data. Common examples - * include Scale.Line and Scale.Bar. - * - * @constructor - * @param {any[]|Dataset} [dataset] The data or Dataset to be associated with this Renderer. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs an XYPlot. + * + * An XYPlot is a plot from drawing 2-dimensional data. Common examples + * include Scale.Line and Scale.Bar. + * + * @constructor + * @param {any[]|Dataset} [dataset] The data or Dataset 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); /** - * @param {string} attrToSet One of ["x", "y"] which determines the point's - * x and y position in the Plot. - */ - public project(attrToSet: string, accessor: any, scale?: Scale): XYPlot; + * @param {string} attrToSet One of ["x", "y"] which determines the point's + * x and y position in the Plot. + */ + project(attrToSet: string, accessor: any, scale?: Scale): XYPlot; } } } @@ -2337,54 +2351,54 @@ declare module Plottable { module Abstract { class NewStylePlot extends XYPlot { /** - * Constructs a NewStylePlot. - * - * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. - * - * A bare Plot has a DataSource and any number of projectors, which take - * data and "project" it onto the Plot, such as "x", "y", "fill", "r". - * - * @constructor - * @param [Scale] xScale The x scale to use - * @param [Scale] yScale The y scale to use - */ + * Constructs a NewStylePlot. + * + * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. + * + * A bare Plot has a DataSource and any number of projectors, which take + * data and "project" it onto the Plot, such as "x", "y", "fill", "r". + * + * @constructor + * @param [Scale] xScale The x scale to use + * @param [Scale] yScale The y scale to use + */ constructor(xScale?: Scale, yScale?: Scale); - public remove(): void; + 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[]|Dataset} dataset dataset to add. - * @returns {NewStylePlot} The calling NewStylePlot. - */ - public addDataset(key: string, dataset: Dataset): NewStylePlot; - public addDataset(key: string, dataset: any[]): NewStylePlot; - public addDataset(dataset: Dataset): NewStylePlot; - public addDataset(dataset: any[]): NewStylePlot; + * 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[]|Dataset} dataset dataset to add. + * @returns {NewStylePlot} The calling NewStylePlot. + */ + addDataset(key: string, dataset: Dataset): NewStylePlot; + addDataset(key: string, dataset: any[]): NewStylePlot; + addDataset(dataset: Dataset): NewStylePlot; + addDataset(dataset: any[]): NewStylePlot; /** - * Gets the dataset order by key - * - * @returns {string[]} A string array of the keys in order - */ - public datasetOrder(): string[]; + * Gets the dataset order by key + * + * @returns {string[]} A string array of the keys in order + */ + datasetOrder(): string[]; /** - * Sets the dataset order by key - * - * @param {string[]} order If provided, a string array which represents the order of the keys. - * This must be a permutation of existing keys. - * - * @returns {NewStylePlot} The calling NewStylePlot. - */ - public datasetOrder(order: string[]): NewStylePlot; + * Sets the dataset order by key + * + * @param {string[]} order If provided, a string array which represents the order of the keys. + * This must be a permutation of existing keys. + * + * @returns {NewStylePlot} The calling NewStylePlot. + */ + 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; + * Removes a dataset + * + * @param {string} key The key of the dataset + * @return {NewStylePlot} The calling NewStylePlot. + */ + removeDataset(key: string): NewStylePlot; } } } @@ -2394,20 +2408,20 @@ declare module Plottable { module Plot { class Scatter extends Abstract.XYPlot { /** - * Constructs a ScatterPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a ScatterPlot. + * + * @constructor + * @param {IDataset | any} 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); /** - * @param {string} attrToSet One of ["x", "y", "cx", "cy", "r", - * "fill"]. "cx" and "cy" are aliases for "x" and "y". "r" is the datum's - * radius, and "fill" is the CSS color of the datum. - */ - public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Scatter; + * @param {string} attrToSet One of ["x", "y", "cx", "cy", "r", + * "fill"]. "cx" and "cy" are aliases for "x" and "y". "r" is the datum's + * radius, and "fill" is the CSS color of the datum. + */ + project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Scatter; } } } @@ -2417,24 +2431,24 @@ declare module Plottable { module Plot { class Grid extends Abstract.XYPlot { /** - * Constructs a GridPlot. - * - * A GridPlot is used to shade a grid of data. Each datum is a cell on the - * grid, and the datum can control what color it is. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale.Ordinal} xScale The x scale to use. - * @param {Scale.Ordinal} yScale The y scale to use. - * @param {Scale.Color|Scale.InterpolatedColor} colorScale The color scale - * to use for each grid cell. - */ + * Constructs a GridPlot. + * + * A GridPlot is used to shade a grid of data. Each datum is a cell on the + * grid, and the datum can control what color it is. + * + * @constructor + * @param {IDataset | any} dataset The dataset to render. + * @param {Scale.Ordinal} xScale The x scale to use. + * @param {Scale.Ordinal} yScale The y scale to use. + * @param {Scale.Color|Scale.InterpolatedColor} colorScale The color scale + * to use for each grid cell. + */ constructor(dataset: any, xScale: Scale.Ordinal, yScale: Scale.Ordinal, colorScale: Abstract.Scale); /** - * @param {string} attrToSet One of ["x", "y", "fill"]. If "fill" is used, - * the data should return a valid CSS color. - */ - public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Grid; + * @param {string} attrToSet One of ["x", "y", "fill"]. If "fill" is used, + * the data should return a valid CSS color. + */ + project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Grid; } } } @@ -2444,52 +2458,52 @@ declare module Plottable { module Abstract { class BarPlot extends XYPlot { /** - * Constructs an AbstractBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs an AbstractBarPlot. + * + * @constructor + * @param {IDataset | any} 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); /** - * Sets the baseline for the bars to the specified value. - * - * The baseline is the line that the bars are drawn from, defaulting to 0. - * - * @param {number} value The value to position the baseline at. - * @returns {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. - * @returns {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"); - * @returns {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. - * @returns {AbstractBarPlot} The calling AbstractBarPlot. - */ - public deselectAll(): BarPlot; + * Sets the baseline for the bars to the specified value. + * + * The baseline is the line that the bars are drawn from, defaulting to 0. + * + * @param {number} value The value to position the baseline at. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ + 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. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ + 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"); + * @returns {D3.Selection} The selected bar, or null if no bar was selected. + */ + 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; + /** + * Deselects all bars. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ + deselectAll(): BarPlot; } } } @@ -2498,23 +2512,23 @@ declare module Plottable { declare module Plottable { module 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 - */ + * 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 { /** - * Constructs a VerticalBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a VerticalBarPlot. + * + * @constructor + * @param {IDataset | any} 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); } } @@ -2524,23 +2538,23 @@ declare module Plottable { declare module Plottable { module 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 - */ + * 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 { /** - * Constructs a HorizontalBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a HorizontalBarPlot. + * + * @constructor + * @param {IDataset | any} 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); } } @@ -2551,13 +2565,13 @@ declare module Plottable { module Plot { class Line extends Abstract.XYPlot { /** - * Constructs a LinePlot. - * - * @constructor - * @param {any | IDataset} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a LinePlot. + * + * @constructor + * @param {any | IDataset} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ constructor(dataset: any, xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); } } @@ -2567,19 +2581,19 @@ 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. - */ + * An AreaPlot draws a filled region (area) between the plot's projected "y" and projected "y0" values. + */ class Area extends Line { /** - * Constructs an AreaPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs an AreaPlot. + * + * @constructor + * @param {IDataset | any} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ constructor(dataset: any, xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); - public project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Area; + project(attrToSet: string, accessor: any, scale?: Abstract.Scale): Area; } } } @@ -2589,22 +2603,22 @@ declare module Plottable { module Abstract { class NewStyleBarPlot extends NewStylePlot { /** - * Constructs a NewStyleBarPlot. - * - * @constructor - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a NewStyleBarPlot. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(xScale: Scale, yScale: Scale); /** - * Sets the baseline for the bars to the specified value. - * - * The baseline is the line that the bars are drawn from, defaulting to 0. - * - * @param {number} value The value to position the baseline at. - * @returns {NewStyleBarPlot} The calling NewStyleBarPlot. - */ - public baseline(value: number): any; + * Sets the baseline for the bars to the specified value. + * + * The baseline is the line that the bars are drawn from, defaulting to 0. + * + * @param {number} value The value to position the baseline at. + * @returns {NewStyleBarPlot} The calling NewStyleBarPlot. + */ + baseline(value: number): any; } } } @@ -2614,16 +2628,16 @@ declare module Plottable { module Plot { class ClusteredBar extends Abstract.NewStyleBarPlot { /** - * Creates a ClusteredBarPlot. - * - * A ClusteredBarPlot is a plot that plots several bar plots next to each - * other. For example, when plotting life expectancy across each country, - * you would want each country to have a "male" and "female" bar. - * - * @constructor - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Creates a ClusteredBarPlot. + * + * A ClusteredBarPlot is a plot that plots several bar plots next to each + * other. For example, when plotting life expectancy across each country, + * you would want each country to have a "male" and "female" bar. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ constructor(xScale: Abstract.Scale, yScale: Abstract.Scale, isVertical?: boolean); } } @@ -2642,12 +2656,12 @@ declare module Plottable { module Plot { class StackedArea extends Abstract.Stacked { /** - * Constructs a StackedArea plot. - * - * @constructor - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a StackedArea plot. + * + * @constructor + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ constructor(xScale: Abstract.QuantitativeScale, yScale: Abstract.QuantitativeScale); } } @@ -2658,16 +2672,16 @@ declare module Plottable { module Plot { class StackedBar extends Abstract.Stacked { /** - * Constructs a StackedBar plot. - * A StackedBarPlot is a plot that plots several bar plots stacking on top of each - * other. - * @constructor - * @param {Scale} xScale the x scale of the plot. - * @param {Scale} yScale the y scale of the plot. - * @param {boolean} isVertical if the plot if vertical. - */ + * Constructs a StackedBar plot. + * A StackedBarPlot is a plot that plots several bar plots stacking on top of each + * other. + * @constructor + * @param {Scale} xScale the x scale of the plot. + * @param {Scale} yScale the y scale of the plot. + * @param {boolean} isVertical if the plot if vertical. + */ constructor(xScale?: Abstract.Scale, yScale?: Abstract.Scale, isVertical?: boolean); - public baseline(value: number): any; + baseline(value: number): any; } } } @@ -2677,15 +2691,15 @@ declare module Plottable { module Animator { interface IPlotAnimator { /** - * 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. - * @return {D3.Selection} Animators should return the selection or - * transition object so that plots may chain the transitions between - * animators. - */ + * 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. + * @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): D3.Selection; } interface IPlotAnimatorMap { @@ -2698,11 +2712,11 @@ declare module Plottable { declare module Plottable { module Animator { /** - * An animator implementation with no animation. The attributes are - * immediately set on the selection. - */ + * An animator implementation with no animation. The attributes are + * immediately set on the selection. + */ class Null implements IPlotAnimator { - public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; } } } @@ -2711,67 +2725,67 @@ declare module Plottable { declare module Plottable { module Animator { /** - * The base animator implementation with easing, duration, and delay. - */ + * The base animator implementation with easing, duration, and delay. + */ class Base implements IPlotAnimator { /** - * The default duration of the animation in milliseconds - */ + * The default duration of the animation in milliseconds + */ static DEFAULT_DURATION_MILLISECONDS: number; /** - * The default starting delay of the animation in milliseconds - */ + * The default starting delay of the animation in milliseconds + */ static DEFAULT_DELAY_MILLISECONDS: number; /** - * The default easing of the animation - */ + * The default easing of the animation + */ static DEFAULT_EASING: string; /** - * Constructs the default animator - * - * @constructor - */ + * Constructs the default animator + * + * @constructor + */ constructor(); - public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; /** - * Gets the duration of the animation in milliseconds. - * - * @returns {number} The current duration. - */ - public duration(): number; + * Gets the duration of the animation in milliseconds. + * + * @returns {number} The current duration. + */ + 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): Base; + * Sets the duration of the animation in milliseconds. + * + * @param {number} duration The duration in milliseconds. + * @returns {Default} The calling Default Animator. + */ + duration(duration: number): Base; /** - * Gets the delay of the animation in milliseconds. - * - * @returns {number} The current delay. - */ - public delay(): number; + * Gets the delay of the animation in milliseconds. + * + * @returns {number} The current delay. + */ + 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): Base; + * Sets the delay of the animation in milliseconds. + * + * @param {number} delay The delay in milliseconds. + * @returns {Default} The calling Default Animator. + */ + delay(delay: number): Base; /** - * Gets the current easing of the animation. - * - * @returns {string} the current easing mode. - */ - public easing(): string; + * Gets the current easing of the animation. + * + * @returns {string} the current easing mode. + */ + 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): Base; + * Sets the easing mode of the animation. + * + * @param {string} easing The desired easing mode. + * @returns {Default} The calling Default Animator. + */ + easing(easing: string): Base; } } } @@ -2780,36 +2794,60 @@ 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. - */ + * An animator that delays the animation of the attributes using the index + * of the selection data. + * + * The maximum delay between animations can be configured with maxIterativeDelay. + * + * The maximum total animation duration can be configured with maxTotalDuration. + * maxTotalDuration does not set actual total animation duration. + * + * The actual interval delay is calculated by following formula: + * min(maxIterativeDelay(), + * max(totalDurationLimit() - duration(), 0) / ) + */ class IterativeDelay extends Base { /** - * The start delay between each start of an animation - */ - static DEFAULT_ITERATIVE_DELAY_MILLISECONDS: number; + * The default maximum start delay between each start of an animation + */ + static DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS: number; /** - * Constructs an animator with a start delay between each selection animation - * - * @constructor - */ + * The default maximum total animation duration + */ + static DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS: number; + /** + * Constructs an animator with a start delay between each selection animation + * + * @constructor + */ constructor(); - public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection; + /** + * Gets the maximum start delay between animations in milliseconds. + * + * @returns {number} The current maximum iterative delay. + */ + maxIterativeDelay(): number; + /** + * Sets the maximum start delay between animations in milliseconds. + * + * @param {number} maxIterDelay The maximum iterative delay in milliseconds. + * @returns {IterativeDelay} The calling IterativeDelay Animator. + */ + maxIterativeDelay(maxIterDelay: number): IterativeDelay; /** - * Gets the start delay between animations in milliseconds. - * - * @returns {number} The current iterative delay. - */ - public iterativeDelay(): number; + * Gets the maximum total animation duration in milliseconds. + * + * @returns {number} The current maximum total animation duration. + */ + maxTotalDuration(): number; /** - * Sets the start delay between animations in milliseconds. - * - * @param {number} iterDelay The iterative delay in milliseconds. - * @returns {IterativeDelay} The calling IterativeDelay Animator. - */ - public iterativeDelay(iterDelay: number): IterativeDelay; + * Sets the maximum total animation duration in miliseconds. + * + * @param {number} maxDuration The maximum total animation duration in milliseconds. + * @returns {IterativeDelay} The calling IterativeDelay Animator. + */ + maxTotalDuration(maxDuration: number): IterativeDelay; } } } @@ -2818,14 +2856,14 @@ declare module Plottable { declare module Plottable { module Animator { /** - * The default animator implementation with easing, duration, and delay. - */ + * The default animator implementation with easing, duration, and delay. + */ class Rect extends Base { static ANIMATED_ATTRIBUTES: string[]; - public isVertical: boolean; - public isReverse: boolean; + isVertical: boolean; + isReverse: boolean; constructor(isVertical?: boolean, isReverse?: boolean); - public animate(selection: any, attrToProjector: IAttributeToProjector): any; + animate(selection: any, attrToProjector: IAttributeToProjector): any; } } } @@ -2834,27 +2872,27 @@ declare module Plottable { declare module Plottable { module Core { /** - * A function to be called when an event occurs. The argument is the d3 event - * generated by the event. - */ + * A function to be called when an event occurs. The argument is the d3 event + * generated by the event. + */ interface IKeyEventListenerCallback { (e: D3.D3Event): any; } /** - * A module for listening to keypresses on the document. - */ + * A module for listening to keypresses on the document. + */ module KeyEventListener { /** - * Turns on key listening. - */ + * Turns on key listening. + */ function initialize(): void; /** - * When a key event occurs with the key corresponding te keyCod, call cb. - * - * @param {number} keyCode The javascript key code to call cb on. - * @param {IKeyEventListener} cb Will be called when keyCode key event - * occurs. - */ + * When a key event occurs with the key corresponding te keyCod, call cb. + * + * @param {number} keyCode The javascript key code to call cb on. + * @param {IKeyEventListener} cb Will be called when keyCode key event + * occurs. + */ function addCallback(keyCode: number, cb: IKeyEventListenerCallback): void; } } @@ -2873,11 +2911,11 @@ declare module Plottable { module Interaction { class Click extends Abstract.Interaction { /** - * Sets a callback to be called when a click is received. - * - * @param {(p: Point) => any} cb Callback that takes the pixel position of the click event. - */ - public callback(cb: (p: Point) => any): Click; + * Sets a callback to be called when a click is received. + * + * @param {(p: Point) => any} cb Callback that takes the pixel position of the click event. + */ + callback(cb: (p: Point) => any): Click; } class DoubleClick extends Click { } @@ -2889,23 +2927,23 @@ declare module Plottable { module Interaction { class Key extends Abstract.Interaction { /** - * Creates a KeyInteraction. - * - * KeyInteraction listens to key events that occur while the component is - * moused over. - * - * @constructor - * @param {number} keyCode The key code to listen for. - */ + * Creates a KeyInteraction. + * + * KeyInteraction listens to key events that occur while the component is + * moused over. + * + * @constructor + * @param {number} keyCode The key code to listen for. + */ constructor(keyCode: number); /** - * Sets a callback to be called when the designated key is pressed and the - * user is moused over the component. - * - * @param {() => any} cb Callback to be called. - * @returns The calling Key. - */ - public callback(cb: () => any): Key; + * Sets a callback to be called when the designated key is pressed and the + * user is moused over the component. + * + * @param {() => any} cb Callback to be called. + * @returns The calling Key. + */ + callback(cb: () => any): Key; } } } @@ -2915,20 +2953,20 @@ declare module Plottable { module Interaction { class PanZoom extends Abstract.Interaction { /** - * Creates a PanZoomInteraction. - * - * The allows you to move around and zoom in on a plot, interactively. It - * does so by changing the xScale and yScales' domains repeatedly. - * - * @constructor - * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. - * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. - */ + * Creates a PanZoomInteraction. + * + * The allows you to move around and zoom in on a plot, interactively. It + * does so by changing the xScale and yScales' domains repeatedly. + * + * @constructor + * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. + * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. + */ constructor(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale); /** - * Sets the scales back to their original domains. - */ - public resetZoom(): void; + * Sets the scales back to their original domains. + */ + resetZoom(): void; } } } @@ -2938,38 +2976,38 @@ declare module Plottable { module Interaction { class BarHover extends Abstract.Interaction { /** - * Gets the current hover mode. - * - * @return {string} The current hover mode. - */ - public hoverMode(): string; + * Gets the current hover mode. + * + * @return {string} The current hover mode. + */ + 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 If provided, the desired hover mode. - * @return {BarHover} The calling BarHover. - */ - public hoverMode(mode: string): BarHover; + * 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 If provided, the desired hover mode. + * @return {BarHover} The calling BarHover. + */ + hoverMode(mode: string): BarHover; /** - * Attaches an callback to be called when the user mouses over a bar. - * - * @param {(datum: any, bar: D3.Selection) => any} callback The callback to be called. - * The callback will be passed the data from the hovered-over bar. - * @return {BarHover} The calling BarHover. - */ - public onHover(callback: (datum: any, bar: D3.Selection) => any): BarHover; + * Attaches an callback to be called when the user mouses over a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} callback The callback to be called. + * The callback will be passed the data from the hovered-over bar. + * @return {BarHover} The calling BarHover. + */ + 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} callback The callback to be called. - * The callback will be passed the data from the last-hovered bar. - * @return {BarHover} The calling BarHover. - */ - public onUnhover(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} callback The callback to be called. + * The callback will be passed the data from the last-hovered bar. + * @return {BarHover} The calling BarHover. + */ + onUnhover(callback: (datum: any, bar: D3.Selection) => any): BarHover; } } } @@ -2979,57 +3017,57 @@ declare module Plottable { module Interaction { class Drag extends Abstract.Interaction { /** - * Constructs a Drag. A Drag will signal its callbacks on mouse drag. - */ + * Constructs a Drag. A Drag will signal its callbacks on mouse drag. + */ constructor(); /** - * Gets the callback that is called when dragging starts. - * - * @returns {(startLocation: Point) => void} The callback called when dragging starts. - */ - public dragstart(): (startLocation: Point) => void; + * Gets the callback that is called when dragging starts. + * + * @returns {(startLocation: Point) => void} The callback called when dragging starts. + */ + dragstart(): (startLocation: Point) => void; /** - * Sets the callback to be called when dragging starts. - * - * @param {(startLocation: Point) => any} cb If provided, the function to be called. Takes in a Point in pixels. - * @returns {Drag} The calling Drag. - */ - public dragstart(cb: (startLocation: Point) => any): Drag; + * Sets the callback to be called when dragging starts. + * + * @param {(startLocation: Point) => any} cb If provided, the function to be called. Takes in a Point in pixels. + * @returns {Drag} The calling Drag. + */ + dragstart(cb: (startLocation: Point) => any): Drag; /** - * Gets the callback that is called during dragging. - * - * @returns {(startLocation: Point, endLocation: Point) => void} The callback called during dragging. - */ - public drag(): (startLocation: Point, endLocation: Point) => void; + * Gets the callback that is called during dragging. + * + * @returns {(startLocation: Point, endLocation: Point) => void} The callback called during dragging. + */ + drag(): (startLocation: Point, endLocation: Point) => void; /** - * Adds a callback to be called during dragging. - * - * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. - * @returns {Drag} The calling Drag. - */ - public drag(cb: (startLocation: Point, endLocation: Point) => any): Drag; + * Adds a callback to be called during dragging. + * + * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. + * @returns {Drag} The calling Drag. + */ + drag(cb: (startLocation: Point, endLocation: Point) => any): Drag; /** - * Gets the callback that is called when dragging ends. - * - * @returns {(startLocation: Point, endLocation: Point) => void} The callback called when dragging ends. - */ - public dragend(): (startLocation: Point, endLocation: Point) => void; + * Gets the callback that is called when dragging ends. + * + * @returns {(startLocation: Point, endLocation: Point) => void} The callback called when dragging ends. + */ + dragend(): (startLocation: Point, endLocation: Point) => void; /** - * Adds a callback to be called when the dragging ends. - * - * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. - * @returns {Drag} The calling Drag. - */ - public dragend(cb: (startLocation: Point, endLocation: Point) => any): Drag; + * Adds a callback to be called when the dragging ends. + * + * @param {(startLocation: Point, endLocation: Point) => any} cb If provided, the function to be called. Takes in Points in pixels. + * @returns {Drag} The calling Drag. + */ + dragend(cb: (startLocation: Point, endLocation: Point) => any): Drag; /** - * Sets up so that the xScale and yScale that are passed have their - * domains automatically changed as you zoom. - * - * @param {QuantitativeScale} xScale The scale along the x-axis. - * @param {QuantitativeScale} yScale The scale along the y-axis. - * @returns {Drag} The calling Drag. - */ - public setupZoomCallback(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale): Drag; + * Sets up so that the xScale and yScale that are passed have their + * domains automatically changed as you zoom. + * + * @param {QuantitativeScale} xScale The scale along the x-axis. + * @param {QuantitativeScale} yScale The scale along the y-axis. + * @returns {Drag} The calling Drag. + */ + setupZoomCallback(xScale?: Abstract.QuantitativeScale, yScale?: Abstract.QuantitativeScale): Drag; } } } @@ -3038,36 +3076,36 @@ declare module Plottable { declare module Plottable { module Interaction { /** - * A DragBox is an interaction that automatically draws a box across the - * element you attach it to when you drag. - */ + * A DragBox is an interaction that automatically draws a box across the + * element you attach it to when you drag. + */ class DragBox extends Drag { /** - * The DOM element of the box that is drawn. When no box is drawn, it is - * null. - */ - public dragBox: D3.Selection; + * The DOM element of the box that is drawn. When no box is drawn, it is + * null. + */ + dragBox: D3.Selection; /** - * Whether or not dragBox has been rendered in a visible area. - */ - public boxIsDrawn: boolean; + * Whether or not dragBox has been rendered in a visible area. + */ + boxIsDrawn: boolean; /** - * Clears the highlighted drag-selection box drawn by the DragBox. - * - * @returns {DragBox} The calling DragBox. - */ - public clearBox(): DragBox; + * Clears the highlighted drag-selection box drawn by the DragBox. + * + * @returns {DragBox} The calling DragBox. + */ + clearBox(): DragBox; /** - * Set where the box is draw explicitly. - * - * @param {number} x0 Left. - * @param {number} x1 Right. - * @param {number} y0 Top. - * @param {number} y1 Bottom. - * - * @returns {DragBox} The calling DragBox. - */ - public setBox(x0: number, x1: number, y0: number, y1: number): DragBox; + * Set where the box is draw explicitly. + * + * @param {number} x0 Left. + * @param {number} x1 Right. + * @param {number} y0 Top. + * @param {number} y1 Bottom. + * + * @returns {DragBox} The calling DragBox. + */ + setBox(x0: number, x1: number, y0: number, y1: number): DragBox; } } } @@ -3076,7 +3114,7 @@ declare module Plottable { declare module Plottable { module Interaction { class XDragBox extends DragBox { - public setBox(x0: number, x1: number): XDragBox; + setBox(x0: number, x1: number): XDragBox; } } } @@ -3093,7 +3131,7 @@ declare module Plottable { declare module Plottable { module Interaction { class YDragBox extends DragBox { - public setBox(y0: number, y1: number): YDragBox; + setBox(y0: number, y1: number): YDragBox; } } } @@ -3103,36 +3141,36 @@ declare module Plottable { module Abstract { class Dispatcher extends PlottableObject { /** - * Constructs a Dispatcher with the specified target. - * - * @param {D3.Selection} target The selection to listen for events on. - */ + * Constructs a Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ constructor(target: D3.Selection); /** - * Gets the target of the Dispatcher. - * - * @returns {D3.Selection} The Dispatcher's current target. - */ - public target(): D3.Selection; + * Gets the target of the Dispatcher. + * + * @returns {D3.Selection} The Dispatcher's current target. + */ + 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; + * Sets the target of the Dispatcher. + * + * @param {D3.Selection} target The element to listen for updates on. + * @returns {Dispatcher} The calling Dispatcher. + */ + target(targetElement: D3.Selection): Dispatcher; /** - * Attaches the Dispatcher's listeners to the Dispatcher's target element. - * - * @returns {Dispatcher} The calling Dispatcher. - */ - public connect(): Dispatcher; + * Attaches the Dispatcher's listeners to the Dispatcher's target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ + connect(): Dispatcher; /** - * Detaches the Dispatcher's listeners from the Dispatchers' target element. - * - * @returns {Dispatcher} The calling Dispatcher. - */ - public disconnect(): Dispatcher; + * Detaches the Dispatcher's listeners from the Dispatchers' target element. + * + * @returns {Dispatcher} The calling Dispatcher. + */ + disconnect(): Dispatcher; } } } @@ -3142,53 +3180,53 @@ declare module Plottable { module Dispatcher { class Mouse extends Abstract.Dispatcher { /** - * Constructs a Mouse Dispatcher with the specified target. - * - * @param {D3.Selection} target The selection to listen for events on. - */ + * Constructs a Mouse Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ constructor(target: D3.Selection); /** - * 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; + * Gets the current callback to be called on mouseover. + * + * @return {(location: Point) => any} The current mouseover callback. + */ + 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. + */ + mouseover(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mousemove. + * + * @return {(location: Point) => any} The current mousemove callback. + */ + 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. + */ + mousemove(callback: (location: Point) => any): Mouse; + /** + * Gets the current callback to be called on mouseout. + * + * @return {(location: Point) => any} The current mouseout callback. + */ + 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. + */ + mouseout(callback: (location: Point) => any): Mouse; } } } diff --git a/plottable.js b/plottable.js index e7024e58a1..8d50144a06 100644 --- a/plottable.js +++ b/plottable.js @@ -1,5 +1,5 @@ /*! -Plottable 0.31.0 (https://github.com/palantir/plottable) +Plottable 0.32.0 (https://github.com/palantir/plottable) Copyright 2014 Palantir Technologies Licensed under MIT (https://github.com/palantir/plottable/blob/master/LICENSE) */ @@ -10,61 +10,57 @@ var 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] - */ + * 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 - */ + * + * @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] - */ + * 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 - * - * Due to the fact that D3.Sets store strings internally, return type is always a string set - * - * @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 - */ + * Takes two sets and returns the intersection + * + * Due to the fact that D3.Sets store strings internally, return type is always a string set + * + * @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) { @@ -75,82 +71,69 @@ 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) - */ + * 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 - * - * Due to the fact that D3.Sets store strings internally, return type is always a string set - * - * @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 - */ + * Takes two sets and returns the union + * + * Due to the fact that D3.Sets store strings internally, return type is always a string set + * + * @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; - /** - * Populates a map from an array of keys and a transformation function. - * - * @param {string[]} keys The array of keys. - * @param {(string) => T} transform A transformation function to apply to the keys. - * @return {D3.Map} A map mapping keys to their transformed values. - */ + * Populates a map from an array of keys and a transformation function. + * + * @param {string[]} keys The array of keys. + * @param {(string, number) => T} transform A transformation function to apply to the keys. + * @return {D3.Map} A map mapping keys to their transformed values. + */ function populateMap(keys, transform) { var map = d3.map(); - keys.forEach(function (key) { - map.set(key, transform(key)); + keys.forEach(function (key, i) { + map.set(key, transform(key, i)); }); return map; } Methods.populateMap = populateMap; - /** - * Take an accessor object, activate it, and partially apply it to a Plot's datasource's metadata - */ + * 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.dataset().metadata()); - }; + return function (d, i) { return activatedAccessor(d, i, plot.dataset().metadata()); }; } Methods._applyAccessor = _applyAccessor; - /** - * Take an array of values, and return the unique values. - * Will work iff ∀ a, b, a.toString() == b.toString() => a == b; will break on Object inputs - * - * @param {T[]} values The values to find uniqueness for - * @return {T[]} The unique values - */ + * Take an array of values, and return the unique values. + * Will work iff ∀ a, b, a.toString() == b.toString() => a == b; will break on Object inputs + * + * @param {T[]} values The values to find uniqueness for + * @return {T[]} The unique values + */ function uniq(arr) { var seen = d3.set(); var result = []; @@ -163,9 +146,6 @@ var Plottable; return result; } Methods.uniq = uniq; - - - function createFilledArray(value, count) { var out = []; for (var i = 0; i < count; i++) { @@ -174,19 +154,17 @@ 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. - */ + * @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. - */ + * 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) { @@ -203,60 +181,53 @@ 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 ===. - */ + * @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; - function max(arr, one, two) { - if (typeof one === "undefined") { one = 0; } - if (typeof two === "undefined") { two = 0; } + if (one === void 0) { one = 0; } + if (two === void 0) { two = 0; } if (arr.length === 0) { if (typeof (one) === "number") { return one; - } else { + } + else { return two; } } - /* tslint:disable:ban */ var acc = typeof (one) === "function" ? one : typeof (two) === "function" ? two : undefined; return acc === undefined ? d3.max(arr) : d3.max(arr, acc); /* tslint:enable:ban */ } Methods.max = max; - function min(arr, one, two) { - if (typeof one === "undefined") { one = 0; } - if (typeof two === "undefined") { two = 0; } + if (one === void 0) { one = 0; } + if (two === void 0) { two = 0; } if (arr.length === 0) { if (typeof (one) === "number") { return one; - } else { + } + else { return two; } } - /* tslint:disable:ban */ var acc = typeof (one) === "function" ? one : typeof (two) === "function" ? two : undefined; return acc === undefined ? d3.min(arr) : d3.min(arr, acc); @@ -275,20 +246,18 @@ 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; } } @@ -315,17 +284,14 @@ 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]; @@ -342,21 +308,21 @@ 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... - */ + * 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 - */ + * 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"); @@ -370,13 +336,12 @@ 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 - */ + * 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) { @@ -385,16 +350,15 @@ 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 - */ + * 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) { @@ -403,47 +367,39 @@ var Plottable; } return false; }; - /** - * Return an array of the values in the key-value store - * - * @return {any[]} The values in the store - */ + * 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 - */ + * 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 - */ + * 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 - */ + * 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) { @@ -466,20 +422,18 @@ var 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. - */ + * @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 (typeof valueEq === "undefined") { valueEq = function (v, w) { - return v === w; - }; } + if (valueEq === void 0) { valueEq = function (v, w) { return v === w; }; } this.cache = d3.map(); this.canonicalKey = null; this.compute = compute; @@ -490,28 +444,27 @@ var Plottable; } } /** - * 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). - */ + * 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. - */ + * 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(); @@ -531,19 +484,16 @@ var 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 - */ + * 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(); @@ -559,45 +509,35 @@ var Plottable; }; } Text.getTextMeasurer = getTextMeasurer; - /** - * @return {TextMeasurer} A test measurer that will treat all sequences - * of consecutive whitespace as a single " ". - */ + * @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. - */ + * 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: _Util.Methods.max(whs, function (wh) { - return wh.height; - }) + width: d3.sum(whs, function (wh) { return wh.width; }), + height: _Util.Methods.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. - */ + * 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)) { @@ -610,40 +550,34 @@ var Plottable; }; }); return { - width: d3.sum(whs, function (x) { - return x.width; - }), - height: _Util.Methods.max(whs, function (x) { - return x.height; - }) + width: d3.sum(whs, function (x) { return x.width; }), + height: _Util.Methods.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. - */ + * 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. - */ + * @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. - */ + * Clear the cache, if it seems that the text has changed size. + */ CachingCharacterMeasurer.prototype.clear = function () { this.cache.clear(); return this; @@ -651,33 +585,30 @@ 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 - */ + * 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. - */ + * 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 mutatedLine = line.trim(); // Leave original around for debugging utility + var widthMeasure = function (s) { return measureText(s).width; }; var lineWidth = widthMeasure(line); var ellipsesWidth = widthMeasure("..."); if (width < ellipsesWidth) { @@ -695,10 +626,9 @@ var Plottable; return mutatedLine + "..."; } Text.addEllipsesToLine = addEllipsesToLine; - function writeLineHorizontally(line, g, width, height, xAlign, yAlign) { - if (typeof xAlign === "undefined") { xAlign = "left"; } - if (typeof yAlign === "undefined") { yAlign = "top"; } + if (xAlign === void 0) { xAlign = "left"; } + if (yAlign === void 0) { 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) { @@ -725,11 +655,10 @@ var Plottable; return { width: w, height: h }; } Text.writeLineHorizontally = writeLineHorizontally; - function writeLineVertically(line, g, width, height, xAlign, yAlign, rotation) { - if (typeof xAlign === "undefined") { xAlign = "left"; } - if (typeof yAlign === "undefined") { yAlign = "top"; } - if (typeof rotation === "undefined") { rotation = "right"; } + if (xAlign === void 0) { xAlign = "left"; } + if (yAlign === void 0) { yAlign = "top"; } + if (rotation === void 0) { rotation = "right"; } if (rotation !== "right" && rotation !== "left") { throw new Error("unrecognized rotation: " + rotation); } @@ -743,14 +672,13 @@ var Plottable; xForm.rotate = rotation === "right" ? 90 : -90; xForm.translate = [isRight ? width : 0, isRight ? 0 : height]; innerG.attr("transform", xForm.toString()); - + innerG.classed("rotated-" + rotation, true); return wh; } Text.writeLineVertically = writeLineVertically; - function writeTextHorizontally(brokenText, g, width, height, xAlign, yAlign) { - if (typeof xAlign === "undefined") { xAlign = "left"; } - if (typeof yAlign === "undefined") { yAlign = "top"; } + if (xAlign === void 0) { xAlign = "left"; } + if (yAlign === void 0) { yAlign = "top"; } var h = getTextMeasurer(g.append("text"))(Text.HEIGHT_TEXT).height; var maxWidth = 0; var blockG = g.append("g"); @@ -768,11 +696,10 @@ 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 (typeof xAlign === "undefined") { xAlign = "left"; } - if (typeof yAlign === "undefined") { yAlign = "top"; } - if (typeof rotation === "undefined") { rotation = "left"; } + if (xAlign === void 0) { xAlign = "left"; } + if (yAlign === void 0) { yAlign = "top"; } + if (rotation === void 0) { rotation = "left"; } var h = getTextMeasurer(g.append("text"))(Text.HEIGHT_TEXT).height; var maxHeight = 0; var blockG = g.append("g"); @@ -788,49 +715,43 @@ 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; + * @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, orientation, write) { + if (orientation === void 0) { orientation = "horizontal"; } + if (["left", "right", "horizontal"].indexOf(orientation) === -1) { + throw new Error("Unrecognized orientation to writeText: " + orientation); + } + var orientHorizontally = orientation === "horizontal"; 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 ? _Util.Methods.max : d3.sum; var heightFn = orientHorizontally ? d3.sum : _Util.Methods.max; - 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); - + 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); // unleash your inner G // 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); + var wh = writeTextFn.call(this, wrappedText.lines, innerG, width, height, write.xAlign, write.yAlign, orientation); usedWidth = wh.width; usedHeight = wh.height; } - return { textFits: wrappedText.textFits, usedWidth: usedWidth, usedHeight: usedHeight }; } Text.writeText = writeText; @@ -848,17 +769,13 @@ 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. - */ + * 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); @@ -873,12 +790,11 @@ var Plottable; 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. - */ + * 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"); @@ -886,18 +802,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. - */ + * 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); @@ -905,13 +821,12 @@ 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. - */ + * 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); @@ -923,10 +838,8 @@ 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; } @@ -941,15 +854,14 @@ 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. - */ + * 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]; @@ -964,7 +876,8 @@ var Plottable; while (i < nextToken.length) { if (widthMeasure(curLine + nextToken[i] + "-") <= width) { curLine += nextToken[i++]; - } else { + } + else { break; } } @@ -975,15 +888,14 @@ 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) - */ + * 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 = ""; @@ -992,7 +904,8 @@ var Plottable; var curChar = text[i]; if (token === "" || isTokenizedTogether(token[0], curChar, lastChar)) { token += curChar; - } else { + } + else { ret.push(token); token = curChar; } @@ -1003,31 +916,30 @@ 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 - */ + * 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. - */ + * 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)) { @@ -1046,34 +958,36 @@ var Plottable; (function (_Util) { (function (DOM) { /** - * Gets the bounding box of an element. - * @param {D3.Selection} element - * @returns {SVGRed} The bounding box. - */ + * Gets the bounding box of an element. + * @param {D3.Selection} element + * @returns {SVGRed} The bounding box. + */ function getBBox(element) { var bbox; - - try { + try { bbox = element.node().getBBox(); - } catch (err) { + } + catch (err) { bbox = { - x: 0, y: 0, width: 0, height: 0 + x: 0, + y: 0, + width: 0, + height: 0 }; } return bbox; } DOM.getBBox = getBBox; - - DOM.POLYFILL_TIMEOUT_MSEC = 1000 / 60; + DOM.POLYFILL_TIMEOUT_MSEC = 1000 / 60; // 60 fps 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); @@ -1082,7 +996,6 @@ var Plottable; } return parsedValue; } - function isSelectionRemovedFromSVG(selection) { var n = selection.node(); while (n !== null && n.nodeName !== "svg") { @@ -1091,25 +1004,20 @@ 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) { @@ -1119,20 +1027,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; @@ -1141,7 +1049,6 @@ var Plottable; } } DOM.translate = translate; - function boxesOverlap(boxA, boxB) { if (boxA.right < boxB.left) { return false; @@ -1168,23 +1075,22 @@ var Plottable; var Plottable; (function (Plottable) { Plottable.MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000; - (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. - */ + * 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. + */ function currency(precision, symbol, prefix, onlyShowUnchanged) { - if (typeof precision === "undefined") { precision = 2; } - if (typeof symbol === "undefined") { symbol = "$"; } - if (typeof prefix === "undefined") { prefix = true; } - if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } + if (precision === void 0) { precision = 2; } + if (symbol === void 0) { symbol = "$"; } + if (prefix === void 0) { prefix = true; } + if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } var fixedFormatter = Formatters.fixed(precision); return function (d) { var formattedValue = fixedFormatter(Math.abs(d)); @@ -1194,10 +1100,10 @@ var Plottable; if (formattedValue !== "") { if (prefix) { formattedValue = symbol + formattedValue; - } else { + } + else { formattedValue += symbol; } - if (d < 0) { formattedValue = "-" + formattedValue; } @@ -1206,18 +1112,17 @@ var Plottable; }; } Formatters.currency = currency; - /** - * 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. - */ + * 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. + */ function fixed(precision, onlyShowUnchanged) { - if (typeof precision === "undefined") { precision = 3; } - if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } + if (precision === void 0) { precision = 3; } + if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } verifyPrecision(precision); return function (d) { var formattedValue = d.toFixed(precision); @@ -1228,19 +1133,18 @@ var Plottable; }; } Formatters.fixed = fixed; - /** - * 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. - */ + * 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. + */ function general(precision, onlyShowUnchanged) { - if (typeof precision === "undefined") { precision = 3; } - if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } + if (precision === void 0) { precision = 3; } + if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } verifyPrecision(precision); return function (d) { if (typeof d === "number") { @@ -1250,46 +1154,43 @@ var Plottable; return ""; } return formattedValue; - } else { + } + else { return String(d); } }; } Formatters.general = general; - /** - * Creates a formatter that stringifies its input. - * - * @returns {Formatter} A formatter that stringifies its input. - */ + * Creates a formatter that stringifies its input. + * + * @returns {Formatter} A formatter that stringifies its input. + */ function identity() { return function (d) { return String(d); }; } Formatters.identity = identity; - /** - * 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. - */ + * 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. + */ function percentage(precision, onlyShowUnchanged) { - if (typeof precision === "undefined") { precision = 0; } - if (typeof onlyShowUnchanged === "undefined") { onlyShowUnchanged = true; } + if (precision === void 0) { precision = 0; } + if (onlyShowUnchanged === void 0) { onlyShowUnchanged = true; } var fixedFormatter = Formatters.fixed(precision, onlyShowUnchanged); 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 && valueChanged(valToFormat, formattedValue)) { return ""; @@ -1301,85 +1202,64 @@ var Plottable; }; } Formatters.percentage = percentage; - /** - * 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. - */ + * 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. + */ function siSuffix(precision) { - if (typeof precision === "undefined") { precision = 3; } + if (precision === void 0) { precision = 3; } verifyPrecision(precision); return function (d) { return d3.format("." + precision + "s")(d); }; } Formatters.siSuffix = siSuffix; - /** - * Creates a formatter that displays dates. - * - * @returns {Formatter} A formatter for time/date values. - */ + * Creates a formatter that displays dates. + * + * @returns {Formatter} A formatter for time/date values. + */ function time() { 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)) { @@ -1389,33 +1269,30 @@ var Plottable; }; } Formatters.time = time; - /** - * 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. - */ + * 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. + */ function relativeDate(baseValue, increment, label) { - if (typeof baseValue === "undefined") { baseValue = 0; } - if (typeof increment === "undefined") { increment = Plottable.MILLISECONDS_IN_ONE_DAY; } - if (typeof label === "undefined") { label = ""; } + if (baseValue === void 0) { baseValue = 0; } + if (increment === void 0) { increment = Plottable.MILLISECONDS_IN_ONE_DAY; } + if (label === void 0) { label = ""; } return function (d) { var relativeDate = Math.round((d.valueOf() - baseValue) / increment); return relativeDate.toString() + label; }; } Formatters.relativeDate = relativeDate; - function verifyPrecision(precision) { if (precision < 0 || precision > 20) { throw new RangeError("Formatter precision must be between 0 and 20"); } } - function valueChanged(d, formattedValue) { return d !== parseFloat(formattedValue); } @@ -1426,7 +1303,7 @@ var Plottable; /// var Plottable; (function (Plottable) { - Plottable.version = "0.31.0"; + Plottable.version = "0.32.0"; })(Plottable || (Plottable = {})); /// @@ -1434,8 +1311,8 @@ var Plottable; (function (Plottable) { (function (Core) { /** - * Colors we use as defaults on a number of graphs. - */ + * Colors we use as defaults on a number of graphs. + */ var Colors = (function () { function Colors() { } @@ -1449,7 +1326,6 @@ var Plottable; Colors.CERISE_RED = "#db2e65"; Colors.BRIGHT_SUN = "#fad419"; Colors.JACARTA = "#2c2b6f"; - Colors.PLOTTABLE_COLORS = [ Colors.INDIGO, Colors.CORAL_RED, @@ -1460,7 +1336,7 @@ var Plottable; Colors.CERISE_RED, Colors.CONIFER, Colors.ROYAL_HEATH, - Colors.ROBINS_EGG_BLUE + Colors.ROBINS_EGG_BLUE, ]; return Colors; })(); @@ -1474,9 +1350,9 @@ var Plottable; (function (Plottable) { (function (Abstract) { /** - * A class most other Plottable classes inherit from, in order to have a - * unique ID. - */ + * A class most other Plottable classes inherit from, in order to have a + * unique ID. + */ var PlottableObject = (function () { function PlottableObject() { this._plottableID = PlottableObject.nextID++; @@ -1499,79 +1375,70 @@ 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. - */ + * 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); /** - * Constructs 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. - */ + * Constructs 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 - */ + * 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 - */ + * 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 - 0); _i++) { - args[_i] = arguments[_i + 0]; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; } - 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 - */ + * 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 - */ + * Deregisters all listeners and callbacks associated with the broadcaster. + * + * @returns {Broadcaster} this object + */ Broadcaster.prototype.deregisterAllListeners = function () { this.key2callback = new Plottable._Util.StrictEqualityAssociativeArray(); }; @@ -1594,18 +1461,18 @@ var Plottable; var Dataset = (function (_super) { __extends(Dataset, _super); /** - * Constructs a new set. - * - * A Dataset is mostly just a wrapper around an any[], Dataset is the - * data you're going to plot. - * - * @constructor - * @param {any[]} data The data for this DataSource (default = []). - * @param {any} metadata An object containing additional information (default = {}). - */ + * Constructs a new set. + * + * A Dataset is mostly just a wrapper around an any[], Dataset is the + * data you're going to plot. + * + * @constructor + * @param {any[]} data The data for this DataSource (default = []). + * @param {any} metadata An object containing additional information (default = {}). + */ function Dataset(data, metadata) { - if (typeof data === "undefined") { data = []; } - if (typeof metadata === "undefined") { metadata = {}; } + if (data === void 0) { data = []; } + if (metadata === void 0) { metadata = {}; } _super.call(this); this.broadcaster = new Plottable.Core.Broadcaster(this); this._data = data; @@ -1615,25 +1482,25 @@ var Plottable; Dataset.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; } }; - Dataset.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; } }; - Dataset.prototype._getExtent = function (accessor, typeCoercer) { var cachedExtent = this.accessor2cachedExtent.get(accessor); if (cachedExtent === undefined) { @@ -1642,18 +1509,20 @@ var Plottable; } return cachedExtent; }; - Dataset.prototype.computeExtent = function (accessor, typeCoercer) { var mappedData = this._data.map(accessor).map(typeCoercer); 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; } } @@ -1669,12 +1538,10 @@ var Plottable; (function (Core) { (function (RenderController) { (function (RenderPolicy) { - - /** - * Never queue anything, render everything immediately. Useful for - * debugging, horrible for performance. - */ + * Never queue anything, render everything immediately. Useful for + * debugging, horrible for performance. + */ var Immediate = (function () { function Immediate() { } @@ -1684,11 +1551,10 @@ var Plottable; return Immediate; })(); RenderPolicy.Immediate = Immediate; - /** - * The default way to render, which only tries to render every frame - * (usually, 1/60th of a second). - */ + * The default way to render, which only tries to render every frame + * (usually, 1/60th of a second). + */ var AnimationFrame = (function () { function AnimationFrame() { } @@ -1698,12 +1564,11 @@ var Plottable; return AnimationFrame; })(); RenderPolicy.AnimationFrame = AnimationFrame; - /** - * Renders with `setTimeout`. This is generally an inferior way to render - * compared to `requestAnimationFrame`, but it's still there if you want - * it. - */ + * Renders with `setTimeout`. This is generally an inferior way to render + * compared to `requestAnimationFrame`, but it's still there if you want + * it. + */ var Timeout = (function () { function Timeout() { this._timeoutMsec = Plottable._Util.DOM.POLYFILL_TIMEOUT_MSEC; @@ -1727,30 +1592,29 @@ 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. - * - * If you want to always have immediate rendering (useful for debugging), - * call - * ```typescript - * Plottable.Core.RenderController.setRenderPolicy( - * new Plottable.Core.RenderController.RenderPolicy.Immediate() - * ); - * ``` - */ + * 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. + * + * If you want to always have immediate rendering (useful for debugging), + * call + * ```typescript + * Plottable.Core.RenderController.setRenderPolicy( + * new Plottable.Core.RenderController.RenderPolicy.Immediate() + * ); + * ``` + */ (function (RenderController) { var _componentsNeedingRender = {}; var _componentsNeedingComputeLayout = {}; var _animationRequested = false; var _isCurrentlyFlushing = false; RenderController._renderPolicy = new RenderController.RenderPolicy.AnimationFrame(); - function setRenderPolicy(policy) { if (typeof (policy) === "string") { switch (policy.toLowerCase()) { @@ -1771,13 +1635,12 @@ var Plottable; 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. - */ + * 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"); @@ -1786,20 +1649,18 @@ 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. - */ + * 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) { @@ -1807,37 +1668,30 @@ var Plottable; RenderController._renderPolicy.render(); } } - /** - * Render everything that is waiting to be rendered right now, instead of - * waiting until the next frame. - * - * Useful to call when debugging. - */ + * Render everything that is waiting to be rendered right now, instead of + * waiting until the next frame. + * + * Useful to call when debugging. + */ 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 () { @@ -1846,14 +1700,12 @@ var Plottable; failed[k] = _componentsNeedingRender[k]; } }); - // Reset queues _componentsNeedingComputeLayout = {}; _componentsNeedingRender = failed; _animationRequested = false; _isCurrentlyFlushing = false; } - // Reset resize flag regardless of queue'd components Core.ResizeBroadcaster.clearResizing(); } @@ -1869,77 +1721,69 @@ 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. - */ + * 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(); } - /** - * Checks if the window has been resized and the RenderController - * has not yet been flushed. - * - * @returns {boolean} If the window has been resized/RenderController - * has not yet been flushed. - */ + * Checks if the window has been resized and the RenderController + * has not yet been flushed. + * + * @returns {boolean} If the window has been resized/RenderController + * has not yet been flushed. + */ function resizing() { return _resizing; } ResizeBroadcaster.resizing = resizing; - /** - * Sets that it is not resizing anymore. Good if it stubbornly thinks - * it is still resizing, or for cancelling the effects of resizing - * prematurely. - */ + * Sets that it is not resizing anymore. Good if it stubbornly thinks + * it is still resizing, or for cancelling the effects of resizing + * prematurely. + */ function clearResizing() { _resizing = false; } ResizeBroadcaster.clearResizing = clearResizing; - /** - * Registers a component. - * - * When the window is resized, ._invalidateLayout() is invoked on the - * component, which will enqueue the component for layout and rendering - * with the RenderController. - * - * @param {Component} component Any Plottable component. - */ + * Registers a component. + * + * When the window is resized, ._invalidateLayout() is invoked on the + * component, which will enqueue the component for layout and rendering + * with the RenderController. + * + * @param {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 {Component} component Any Plottable component. - */ + * Deregisters the components. + * + * The component will no longer receive updates on window resize. + * + * @param {Component} component Any Plottable component. + */ function deregister(c) { if (broadcaster) { broadcaster.deregisterListener(c._plottableID); @@ -1954,23 +1798,7 @@ var Plottable; var Plottable; (function (Plottable) { - - - - ; - - - - - - - - - - - - })(Plottable || (Plottable = {})); /// @@ -1978,19 +1806,19 @@ var Plottable; (function (Plottable) { var Domainer = (function () { /** - * Constructs a new Domainer. - * - * @constructor - * @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. - */ + * Constructs a new Domainer. + * + * @constructor + * @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; @@ -2002,168 +1830,155 @@ var Plottable; this.combineExtents = combineExtents; } /** - * @param {any[][]} extents The list of extents to be reduced to a single - * extent. - * @param {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. - * @returns {any[]} The domain, as a merging of all exents, as a [min, max] - * pair. - */ + * @param {any[][]} extents The list of extents to be reduced to a single + * extent. + * @param {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. + * @returns {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 = [Plottable._Util.Methods.min(extents, function (e) { - return e[0]; - }), Plottable._Util.Methods.max(extents, function (e) { - return e[1]; - })]; + } + else { + domain = [Plottable._Util.Methods.min(extents, function (e) { return e[0]; }), Plottable._Util.Methods.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]. - * - * @returns {Domainer} The calling Domainer. - */ + * 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]. + * + * @returns {Domainer} The calling Domainer. + */ Domainer.prototype.pad = function (padProportion) { - if (typeof padProportion === "undefined") { padProportion = 0.05; } + if (padProportion === void 0) { padProportion = 0.05; } this.padProportion = padProportion; return this; }; - /** - * Adds 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. - * @returns {Domainer} The calling domainer - */ + * Adds 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. + * @returns {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; }; - /** - * Removes 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 - */ + * Removes 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; }; - /** - * Adds 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. - * @returns {Domainer} The calling domainer - */ + * Adds 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. + * @returns {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 - */ + * 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. - */ + * 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) { - return [Plottable._Util.Methods.min(extents, function (e) { - return e[0]; - }, 0), Plottable._Util.Methods.max(extents, function (e) { - return e[1]; - }, 1)]; + return [Plottable._Util.Methods.min(extents, function (e) { return e[0]; }, 0), Plottable._Util.Methods.max(extents, function (e) { return e[1]; }, 1)]; }; - Domainer.prototype.padDomain = function (scale, domain) { var min = domain[0]; var max = domain[1]; if (min === max && this.padProportion > 0.0) { - var d = min.valueOf(); + var d = min.valueOf(); // valueOf accounts for dates properly 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); @@ -2178,20 +1993,17 @@ 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; @@ -2213,125 +2025,114 @@ var Plottable; var Scale = (function (_super) { __extends(Scale, _super); /** - * Constructs a new Scale. - * - * A Scale is a wrapper around a D3.Scale.Scale. A Scale is really just a - * function. Scales have a domain (input), a range (output), and a function - * from domain to range. - * - * @constructor - * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. - */ + * Constructs a new Scale. + * + * A Scale is a wrapper around a D3.Scale.Scale. A Scale is really just a + * function. Scales have a domain (input), a range (output), and a function + * from domain to range. + * + * @constructor + * @param {D3.Scale.Scale} scale The D3 scale backing the Scale. + */ function Scale(scale) { _super.call(this); this._autoDomainAutomatically = true; this.broadcaster = new Plottable.Core.Broadcaster(this); this._rendererAttrID2Extent = {}; - this._typeCoercer = function (d) { - return d; - }; + this._typeCoercer = function (d) { return d; }; this._d3Scale = scale; } Scale.prototype._getAllExtents = function () { return d3.values(this._rendererAttrID2Extent); }; - Scale.prototype._getExtent = function () { - return []; - }; - - /** - * Modifies the domain on the scale so that it includes the extent of all - * perspectives it depends on. This will normally happen automatically, but - * if you set domain explicitly with `plot.domain(x)`, you will need to - * call this function if you want the domain to neccessarily include all - * the data. - * - * Extent: The [min, max] pair for a Scale.Quantitative, all covered - * strings for a Scale.Ordinal. - * - * Perspective: A combination of a Dataset and an Accessor that - * represents a view in to the data. - * - * @returns {Scale} The calling Scale. - */ + return []; // this should be overwritten + }; + /** + * Modifies the domain on the scale so that it includes the extent of all + * perspectives it depends on. This will normally happen automatically, but + * if you set domain explicitly with `plot.domain(x)`, you will need to + * call this function if you want the domain to neccessarily include all + * the data. + * + * Extent: The [min, max] pair for a Scale.Quantitative, all covered + * strings for a Scale.Ordinal. + * + * Perspective: A combination of a Dataset and an Accessor that + * represents a view in to the data. + * + * @returns {Scale} The calling Scale. + */ Scale.prototype.autoDomain = function () { this._autoDomainAutomatically = true; this._setDomain(this._getExtent()); return this; }; - Scale.prototype._autoDomainIfAutomaticMode = function () { if (this._autoDomainAutomatically) { this.autoDomain(); } }; - /** - * Computes the range value corresponding to a given domain value. In other - * words, apply the function to value. - * - * @param {R} value A domain value to be scaled. - * @returns {R} The range value corresponding to the supplied domain value. - */ + * Computes the range value corresponding to a given domain value. In other + * words, apply the function to value. + * + * @param {R} value A domain value to be scaled. + * @returns {R} 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; } }; - /** - * Constructs a copy of the Scale with the same domain and range but without - * any registered listeners. - * - * @returns {Scale} A copy of the calling Scale. - */ + * Constructs 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 {D[]} extent The new extent to be included in the 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 {D[]} 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(); @@ -2357,63 +2158,54 @@ var Plottable; var QuantitativeScale = (function (_super) { __extends(QuantitativeScale, _super); /** - * Constructs a new QuantitativeScale. - * - * A QuantitativeScale is a Scale that maps anys to numbers. It - * is invertible and continuous. - * - * @constructor - * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale - * backing the QuantitativeScale. - */ + * Constructs a new QuantitativeScale. + * + * A QuantitativeScale is a Scale that maps anys to numbers. It + * is invertible and continuous. + * + * @constructor + * @param {D3.Scale.QuantitativeScale} scale The D3 QuantitativeScale + * backing the QuantitativeScale. + */ function QuantitativeScale(scale) { _super.call(this, scale); this._numTicks = 10; this._PADDING_FOR_IDENTICAL_DOMAIN = 1; this._userSetDomainer = false; this._domainer = new Plottable.Domainer(); - this._typeCoercer = function (d) { - return +d; - }; + this._typeCoercer = function (d) { return +d; }; } 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 {D} The domain value corresponding to the supplied range value. - */ + * Retrieves the domain value corresponding to a supplied range value. + * + * @param {number} value: A value from the Scale's range. + * @returns {D} 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. - */ + * 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); + return _super.prototype.domain.call(this, values); // need to override type sig to enable method chaining :/ }; - 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(); @@ -2421,17 +2213,15 @@ 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. - */ + * 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(); @@ -2439,20 +2229,18 @@ var Plottable; this._d3Scale.clamp(clamp); return this; }; - /** - * Gets a set of tick values spanning the domain. - * - * @param {number} [count] The approximate number of ticks to generate. - * If not supplied, the number specified by - * numTicks() is used instead. - * @returns {any[]} The generated ticks. - */ + * Gets a set of tick values spanning the domain. + * + * @param {number} [count] The approximate number of ticks to generate. + * If not supplied, the number specified by + * numTicks() is used instead. + * @returns {any[]} The generated ticks. + */ QuantitativeScale.prototype.ticks = function (count) { - if (typeof count === "undefined") { count = this.numTicks(); } + if (count === void 0) { count = this.numTicks(); } return this._d3Scale.ticks(count); }; - QuantitativeScale.prototype.numTicks = function (count) { if (count == null) { return this._numTicks; @@ -2460,26 +2248,24 @@ var Plottable; this._numTicks = count; return this; }; - /** - * Given a domain, expands its domain onto "nice" values, e.g. whole - * numbers. - */ + * 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]; }; @@ -2506,11 +2292,11 @@ var Plottable; _super.call(this, scale == null ? d3.scale.linear() : scale); } /** - * Constructs a copy of the Scale.Linear with the same domain and range but - * without any registered listeners. - * - * @returns {Linear} A copy of the calling Scale.Linear. - */ + * Constructs a copy of the Scale.Linear with the same domain and range but + * without any registered listeners. + * + * @returns {Linear} A copy of the calling Scale.Linear. + */ Linear.prototype.copy = function () { return new Linear(this._d3Scale.copy()); }; @@ -2541,14 +2327,13 @@ var Plottable; } } /** - * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. - * - * @returns {Log} A copy of the calling Log. - */ + * Creates a copy of the Scale.Log with the same domain and range but without any registered listeners. + * + * @returns {Log} A copy of the calling Log. + */ Log.prototype.copy = function () { return new Log(this._d3Scale.copy()); }; - Log.prototype._defaultExtent = function () { return [1, 10]; }; @@ -2573,32 +2358,32 @@ var Plottable; 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). - */ + * 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 (typeof base === "undefined") { base = 10; } + if (base === void 0) { base = 10; } _super.call(this, d3.scale.linear()); this._showIntermediateTicks = false; this.base = base; @@ -2610,107 +2395,83 @@ var Plottable; } } /** - * 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. - */ + * 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 (typeof count === "undefined") { count = this.numTicks(); } + if (count === void 0) { count = this.numTicks(); } // 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 middle = function (x, y, z) { return [x, y, z].sort(function (a, b) { return a - b; })[1]; }; var min = Plottable._Util.Methods.min(this.untransformedDomain); var max = Plottable._Util.Methods.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(count); } 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. - */ + * 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); @@ -2723,28 +2484,19 @@ 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.uniq(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. - */ + * 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(Plottable._Util.Methods.min(this.untransformedDomain)); var adjustedMax = this.adjustedLog(Plottable._Util.Methods.max(this.untransformedDomain)); @@ -2754,19 +2506,17 @@ var Plottable; var ticks = Math.ceil(proportion * this._numTicks); 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; } }; @@ -2790,13 +2540,13 @@ var Plottable; var Ordinal = (function (_super) { __extends(Ordinal, _super); /** - * Creates an OrdinalScale. - * - * An OrdinalScale maps strings to numbers. A common use is to map the - * labels of a bar plot (strings) to their pixel locations (numbers). - * - * @constructor - */ + * Creates an OrdinalScale. + * + * An OrdinalScale maps strings to numbers. A common use is to map the + * labels of a bar plot (strings) to their pixel locations (numbers). + * + * @constructor + */ function Ordinal(scale) { _super.call(this, scale == null ? d3.scale.ordinal() : scale); this._range = [0, 1]; @@ -2804,9 +2554,7 @@ var Plottable; // Padding as a proportion of the spacing between domain values this._innerPadding = 0.3; this._outerPadding = 0.5; - this._typeCoercer = function (d) { - return d != null && d.toString ? d.toString() : d; - }; + this._typeCoercer = function (d) { return d != null && d.toString ? d.toString() : d; }; if (this._innerPadding > this._outerPadding) { throw new Error("outerPadding must be >= innerPadding so cat axis bands work out reasonably"); } @@ -2815,39 +2563,36 @@ 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()); // 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); // d3 scale takes total padding - } else if (this._rangeType === "bands") { + } + 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". - */ + * 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) { @@ -2856,17 +2601,16 @@ 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); } @@ -2882,7 +2626,6 @@ var Plottable; return this; } }; - Ordinal.prototype.copy = function () { return new Ordinal(this._d3Scale.copy()); }; @@ -2906,13 +2649,13 @@ var Plottable; var Color = (function (_super) { __extends(Color, _super); /** - * Constructs 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 - */ + * Constructs 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) { @@ -2976,9 +2719,7 @@ var Plottable; function Time(scale) { // need to cast since d3 time scales do not descend from Quantitative scales _super.call(this, scale == null ? d3.time.scale() : scale); - this._typeCoercer = function (d) { - return d && d._isAMomentObject || d instanceof Date ? d : new Date(d); - }; + this._typeCoercer = function (d) { return d && d._isAMomentObject || d instanceof Date ? d : new Date(d); }; } 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 @@ -2987,17 +2728,14 @@ var Plottable; tempScale.range(this.range()); return tempScale.ticks(interval.range, step); }; - Time.prototype._setDomain = function (values) { // attempt to parse dates values = values.map(this._typeCoercer); return _super.prototype._setDomain.call(this, values); }; - 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; @@ -3021,45 +2759,44 @@ 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. - */ + * 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); /** - * Constructs an InterpolatedColorScale. - * - * An InterpolatedColorScale maps numbers evenly to color strings. - * - * @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. - */ + * Constructs an InterpolatedColorScale. + * + * An InterpolatedColorScale maps numbers evenly to color strings. + * + * @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 (typeof colorRange === "undefined") { colorRange = "reds"; } - if (typeof scaleType === "undefined") { scaleType = "linear"; } + if (colorRange === void 0) { colorRange = "reds"; } + if (scaleType === void 0) { 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 {D3.Scale.QuantitativeScale} The converted Quantitative d3 scale. - */ + * 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 {D3.Scale.QuantitativeScale} The converted Quantitative d3 scale. + */ InterpolatedColor.getD3InterpolatedScale = function (colors, scaleType) { var scale; switch (scaleType) { @@ -3081,16 +2818,15 @@ var Plottable; } return scale.range([0, 1]).interpolate(InterpolatedColor.interpolateColors(colors)); }; - /** - * Creates a d3 interpolator given the color array. - * - * This class implements a scale that maps numbers to strings. - * - * @param {string[]} colors an array of strings representing color - * values in hex ("#FFFFFF") or keywords ("white"). - * @returns {D3.Transition.Interpolate} The d3 interpolator for colors. - */ + * Creates a d3 interpolator given the color array. + * + * This class implements a scale that maps numbers to strings. + * + * @param {string[]} colors an array of strings representing color + * values in hex ("#FFFFFF") or keywords ("white"). + * @returns {D3.Transition.Interpolate} The d3 interpolator for colors. + */ InterpolatedColor.interpolateColors = function (colors) { if (colors.length < 2) { throw new Error("Color scale arrays must have at least two elements."); @@ -3100,19 +2836,16 @@ var Plottable; 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; @@ -3121,7 +2854,6 @@ var Plottable; this._resetScale(); return this; }; - InterpolatedColor.prototype.scaleType = function (scaleType) { if (scaleType == null) { return this._scaleType; @@ -3130,32 +2862,27 @@ 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([Plottable._Util.Methods.min(extents, function (x) { - return x[0]; - }), Plottable._Util.Methods.max(extents, function (x) { - return x[1]; - })]); + this._setDomain([Plottable._Util.Methods.min(extents, function (x) { return x[0]; }), Plottable._Util.Methods.max(extents, function (x) { return x[1]; })]); } return this; }; @@ -3215,11 +2942,11 @@ var Plottable; (function (_Util) { var ScaleDomainCoordinator = (function () { /** - * Constructs a ScaleDomainCoordinator. - * - * @constructor - * @param {Scale[]} scales A list of scales whose domains should be linked. - */ + * Constructs 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. @@ -3231,11 +2958,7 @@ var Plottable; 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) { @@ -3243,9 +2966,7 @@ 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; @@ -3261,31 +2982,30 @@ var Plottable; (function (Abstract) { var _Drawer = (function () { /** - * Constructs a Drawer - * - * @constructor - * @param{string} key The key associated with this Drawer - */ + * Constructs a Drawer + * + * @constructor + * @param{string} key The key associated with this Drawer + */ function _Drawer(key) { this.key = key; } /** - * Removes the Drawer and its renderArea - */ + * 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 - */ + * 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, animator) { - if (typeof animator === "undefined") { animator = new Plottable.Animator.Null(); } + if (animator === void 0) { animator = new Plottable.Animator.Null(); } throw new Error("Abstract Method Not Implemented"); }; return _Drawer; @@ -3311,10 +3031,9 @@ var Plottable; _super.apply(this, arguments); } Arc.prototype.draw = function (data, attrToProjector, animator) { - if (typeof animator === "undefined") { animator = new Plottable.Animator.Null(); } + if (animator === void 0) { animator = new Plottable.Animator.Null(); } var svgElement = "path"; var dataElements = this._renderArea.selectAll(svgElement).data(data); - dataElements.enter().append(svgElement); dataElements.classed("arc", true); animator.animate(dataElements, attrToProjector); @@ -3345,7 +3064,6 @@ var Plottable; Area.prototype.draw = function (data, attrToProjector) { var svgElement = "path"; var dataElements = this._renderArea.selectAll(svgElement).data([data]); - dataElements.enter().append(svgElement); dataElements.attr(attrToProjector).classed("area", true); dataElements.exit().remove(); @@ -3373,10 +3091,9 @@ var Plottable; _super.apply(this, arguments); } Rect.prototype.draw = function (data, attrToProjector, animator) { - if (typeof animator === "undefined") { animator = new Plottable.Animator.Null(); } + if (animator === void 0) { animator = new Plottable.Animator.Null(); } var svgElement = "rect"; var dataElements = this._renderArea.selectAll(svgElement).data(data); - dataElements.enter().append(svgElement); animator.animate(dataElements, attrToProjector); dataElements.exit().remove(); @@ -3403,7 +3120,7 @@ var Plottable; function Component() { _super.apply(this, arguments); this.clipPathEnabled = false; - this._xAlignProportion = 0; + this._xAlignProportion = 0; // What % along the free space do we want to position (0 = left, .5 = center, 1 = right) this._yAlignProportion = 0; this._fixedHeightFlag = false; this._fixedWidthFlag = false; @@ -3412,48 +3129,45 @@ var Plottable; this.interactionsToRegister = []; this.boxes = []; this.isTopLevelComponent = false; - this._width = 0; + this._width = 0; // Width and height of the component. Used to size the hitbox, bounding box, etc this._height = 0; - this._xOffset = 0; + this._xOffset = 0; // Offset from Origin, used for alignment and floating positioning this._yOffset = 0; this.cssClasses = ["component"]; 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. - */ + * 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. - */ + * 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) { @@ -3463,53 +3177,45 @@ 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 x-coordinate of the origin of the component - * @param {number} yOrigin y-coordinate of the origin of the component - * @param {number} availableWidth available width for the component to render in - * @param {number} availableHeight available height for the component to render in - */ + * 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 x-coordinate of the origin of the component + * @param {number} yOrigin y-coordinate of the origin of the component + * @param {number} availableWidth available width for the component to render in + * @param {number} availableHeight available height for the component to render in + */ 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 @@ -3519,11 +3225,11 @@ var Plottable; 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"); } } @@ -3531,61 +3237,52 @@ 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()) { + xPosition += (availableWidth - requestedSpace.width) * this._xAlignProportion; // 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()) { + yPosition += (availableHeight - requestedSpace.height) * this._yAlignProportion; availableHeight = Math.min(availableHeight, requestedSpace.height); } - this._width = availableWidth; this._height = availableHeight; this._element.attr("transform", "translate(" + xPosition + "," + yPosition + ")"); - this.boxes.forEach(function (b) { - return b.attr("width", _this.width()).attr("height", _this.height()); - }); + this.boxes.forEach(function (b) { return b.attr("width", _this.width()).attr("height", _this.height()); }); }; - 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 () { }; - Component.prototype._invalidateLayout = function () { if (this._isAnchored && this._isSetup) { if (this.isTopLevelComponent) { this._scheduleComputeLayout(); - } else { + } + else { this._parent._invalidateLayout(); } } }; - Component.prototype.renderTo = function (element) { if (element != null) { var selection; if (typeof (element.node) === "function") { selection = element; - } else { + } + else { selection = d3.select(element); } if (!selection.node() || selection.node().nodeName !== "svg") { @@ -3599,22 +3296,20 @@ var Plottable; } this._computeLayout(); this._render(); - // flush so that consumers can immediately attach to stuff we create in the DOM Plottable.Core.RenderController.flush(); return this; }; - /** - * Causes the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. - * - * This function should be called when CSS changes could influence the size - * of the components, e.g. changing the font size. - * - * @param {number} [availableWidth] - the width of the container element - * @param {number} [availableHeight] - the height of the container element - * @returns {Component} The calling component. - */ + * Causes the Component to recompute layout and redraw. If passed arguments, will resize the root SVG it lives in. + * + * This function should be called when CSS changes could influence the size + * of the components, e.g. changing the font size. + * + * @param {number} [availableWidth] - the width of the container element + * @param {number} [availableHeight] - the height of the container element + * @returns {Component} The calling component. + */ Component.prototype.resize = function (width, height) { if (!this.isTopLevelComponent) { throw new Error("Cannot resize on non top-level component"); @@ -3625,106 +3320,107 @@ var Plottable; this._invalidateLayout(); return this; }; - /** - * Enables or disables resize on window resizes. - * - * 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 Enable (true) or disable (false) auto-resize. - * @returns {Component} The calling component. - */ + * Enables or disables resize on window resizes. + * + * 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 Enable (true) or disable (false) auto-resize. + * @returns {Component} The calling component. + */ 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. This will be used if the - * Component is given more space than it needs. - * - * For example, you may want to make a Legend postition itself it the top - * right, so you would call `legend.xAlign("right")` and - * `legend.yAlign("top")`. - * - * @param {string} alignment The x alignment of the Component (one of ["left", "center", "right"]). - * @returns {Component} The calling Component. - */ + * Sets the x alignment of the Component. This will be used if the + * Component is given more space than it needs. + * + * For example, you may want to make a Legend postition itself it the top + * right, so you would call `legend.xAlign("right")` and + * `legend.yAlign("top")`. + * + * @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. This will be used if the - * Component is given more space than it needs. - * - * For example, you may want to make a Legend postition itself it the top - * right, so you would call `legend.xAlign("right")` and - * `legend.yAlign("top")`. - * - * @param {string} alignment The x alignment of the Component (one of ["top", "center", "bottom"]). - * @returns {Component} The calling Component. - */ + * Sets the y alignment of the Component. This will be used if the + * Component is given more space than it needs. + * + * For example, you may want to make a Legend postition itself it the top + * right, so you would call `legend.xAlign("right")` and + * `legend.yAlign("top")`. + * + * @param {string} alignment The x 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. This will be used if the Component - * is given more space than it needs. - * - * @param {number} offset The desired x offset, in pixels, from the left - * side of the container. - * @returns {Component} The calling Component. - */ + * Sets the x offset of the Component. This will be used if the Component + * is given more space than it needs. + * + * @param {number} offset The desired x offset, in pixels, from the left + * side of the container. + * @returns {Component} The calling Component. + */ Component.prototype.xOffset = function (offset) { this._xOffset = offset; this._invalidateLayout(); return this; }; - /** - * Sets the y offset of the Component. This will be used if the Component - * is given more space than it needs. - * - * @param {number} offset The desired y offset, in pixels, from the top - * side of the container. - * @returns {Component} The calling Component. - */ + * Sets the y offset of the Component. This will be used if the Component + * is given more space than it needs. + * + * @param {number} offset The desired y offset, in pixels, from the top + * side of the container. + * @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"); @@ -3735,14 +3431,12 @@ var Plottable; box.classed(className, true); } ; - this.boxes.push(box); if (this.width() != null && this.height() != null) { box.attr("width", this.width()).attr("height", this.height()); } return box; }; - Component.prototype.generateClipPath = function () { // The clip path will prevent content from overflowing its component space. // HACKHACK: IE <=9 does not respect the HTML base element in SVG. @@ -3752,13 +3446,12 @@ var Plottable; 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. - * @returns {Component} The calling 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. + * @returns {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 @@ -3769,22 +3462,25 @@ var Plottable; this.hitBox.style("fill", "#ffffff").style("opacity", 0); // We need to set these so Chrome will register events } interaction._anchor(this, 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; } @@ -3792,49 +3488,48 @@ 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. - * - * @returns {boolean} Whether the component has a fixed width. - */ + * 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. + * + * @returns {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. - * - * @returns {boolean} Whether the component has a fixed height. - */ + * 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. + * + * @returns {boolean} Whether the component has a fixed height. + */ Component.prototype._isFixedHeight = function () { return this._fixedHeightFlag; }; - /** - * Merges this Component with another Component, returning a - * ComponentGroup. This is used to layer Components on top of each other. - * - * 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. - * @returns {ComponentGroup} The relevant ComponentGroup out of the above four cases. - */ + * Merges this Component with another Component, returning a + * ComponentGroup. This is used to layer Components on top of each other. + * + * 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. + * @returns {ComponentGroup} The relevant ComponentGroup out of the above four cases. + */ Component.prototype.merge = function (c) { var cg; if (this._isSetup || this._isAnchored) { @@ -3844,20 +3539,20 @@ 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. - * - * This should only be used if you plan on reusing the calling - * Components. Otherwise, use remove(). - * - * @returns The calling Component. - */ + * Detaches a Component from the DOM. The component can be reused. + * + * This should only be used if you plan on reusing the calling + * Components. Otherwise, use remove(). + * + * @returns The calling Component. + */ Component.prototype.detach = function () { if (this._isAnchored) { this._element.remove(); @@ -3869,31 +3564,28 @@ 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). - */ + * 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(); Plottable.Core.ResizeBroadcaster.deregister(this); }; - /** - * Return the width of the component - * - * @return {number} width of the component - */ + * Return the width of the component + * + * @return {number} width of the component + */ Component.prototype.width = function () { return this._width; }; - /** - * Return the height of the component - * - * @return {number} height of the component - */ + * Return the height of the component + * + * @return {number} height of the component + */ Component.prototype.height = function () { return this._height; }; @@ -3916,9 +3608,9 @@ var Plottable; (function (Plottable) { (function (Abstract) { /* - * An abstract ComponentContainer class to encapsulate Table and ComponentGroup's shared functionality. - * It will not do anything if instantiated directly. - */ + * An abstract ComponentContainer class to encapsulate Table and ComponentGroup's shared functionality. + * It will not do anything if instantiated directly. + */ var ComponentContainer = (function (_super) { __extends(ComponentContainer, _super); function ComponentContainer() { @@ -3928,17 +3620,11 @@ var Plottable; 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) { @@ -3946,16 +3632,15 @@ var Plottable; this._invalidateLayout(); } }; - ComponentContainer.prototype._addComponent = function (c, prepend) { - if (typeof prepend === "undefined") { prepend = false; } + if (prepend === void 0) { prepend = false; } if (!c || this._components.indexOf(c) >= 0) { return false; } - if (prepend) { this._components.unshift(c); - } else { + } + else { this._components.push(c); } c._parent = this; @@ -3965,45 +3650,37 @@ var Plottable; this._invalidateLayout(); return true; }; - /** - * Returns a list of components in the ComponentContainer. - * - * @returns {Component[]} the contained Components - */ + * Returns a list of components in the ComponentContainer. + * + * @returns {Component[]} the contained Components + */ ComponentContainer.prototype.components = function () { - return this._components.slice(); + return this._components.slice(); // return a shallow copy }; - /** - * Returns true iff the ComponentContainer is empty. - * - * @returns {boolean} Whether the calling ComponentContainer is empty. - */ + * 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 - */ + * Detaches all components contained in the ComponentContainer, and + * empties the ComponentContainer. + * + * @returns {ComponentContainer} The calling ComponentContainer + */ ComponentContainer.prototype.detachAll = function () { // 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(); - }); + 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); @@ -4025,53 +3702,35 @@ var Plottable; var Group = (function (_super) { __extends(Group, _super); /** - * Constructs a GroupComponent. - * - * A GroupComponent is a set of Components that will be rendered on top of - * each other. When you call Component.merge(Component), it creates and - * returns a GroupComponent. - * - * @constructor - * @param {Component[]} components The Components in the Group (default = []). - */ + * Constructs a GroupComponent. + * + * A GroupComponent is a set of Components that will be rendered on top of + * each other. When you call Component.merge(Component), it creates and + * returns a GroupComponent. + * + * @constructor + * @param {Component[]} components The Components in the Group (default = []). + */ function Group(components) { - if (typeof components === "undefined") { components = []; } var _this = this; + if (components === void 0) { components = []; } _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); }); return { - width: Plottable._Util.Methods.max(requests, function (request) { - return request.width; - }), - height: Plottable._Util.Methods.max(requests, function (request) { - return request.height; - }), - wantsWidth: requests.map(function (r) { - return r.wantsWidth; - }).some(function (x) { - return x; - }), - wantsHeight: requests.map(function (r) { - return r.wantsHeight; - }).some(function (x) { - return x; - }) + width: Plottable._Util.Methods.max(requests, function (request) { return request.width; }), + height: Plottable._Util.Methods.max(requests, function (request) { return request.height; }), + wantsWidth: requests.map(function (r) { return r.wantsWidth; }).some(function (x) { return x; }), + wantsHeight: 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); @@ -4080,17 +3739,11 @@ 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); @@ -4112,19 +3765,19 @@ var Plottable; var Axis = (function (_super) { __extends(Axis, _super); /** - * Constructs an axis. An axis is a wrapper around a scale for rendering. - * - * @constructor - * @param {Scale} scale The scale for this axis to render. - * @param {string} orientation One of ["top", "left", "bottom", "right"]; - * on which side the axis will appear. On most axes, this is either "left" - * or "bottom". - * @param {Formatter} Data is passed through this formatter before being - * displayed. - */ + * Constructs an axis. An axis is a wrapper around a scale for rendering. + * + * @constructor + * @param {Scale} scale The scale for this axis to render. + * @param {string} orientation One of ["top", "left", "bottom", "right"]; + * on which side the axis will appear. On most axes, this is either "left" + * or "bottom". + * @param {Formatter} Data is passed through this formatter before being + * displayed. + */ function Axis(scale, orientation, formatter) { - if (typeof formatter === "undefined") { formatter = Plottable.Formatters.identity(); } var _this = this; + if (formatter === void 0) { formatter = Plottable.Formatters.identity(); } _super.call(this); this._endTickLength = 5; this._tickLength = 5; @@ -4136,57 +3789,49 @@ var Plottable; } this._scale = scale; this.orient(orientation); - + this._setDefaultAlignment(); this.classed("axis", true); if (this._isHorizontal()) { this.classed("x-axis", true); - } else { + } + else { this.classed("y-axis", true); } - this.formatter(formatter); - - this._scale.broadcaster.registerListener(this, function () { - return _this._rescale(); - }); + this._scale.broadcaster.registerListener(this, function () { return _this._rescale(); }); } Axis.prototype.remove = function () { _super.prototype.remove.call(this); this._scale.broadcaster.deregisterListener(this); }; - Axis.prototype._isHorizontal = function () { return this._orientation === "top" || this._orientation === "bottom"; }; - Axis.prototype._computeWidth = function () { // to be overridden by subclass logic this._computedWidth = this._maxLabelTickLength(); return this._computedWidth; }; - Axis.prototype._computeHeight = function () { // to be overridden by subclass logic this._computedHeight = this._maxLabelTickLength(); return this._computedHeight; }; - Axis.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var requestedWidth = 0; var requestedHeight = 0; - if (this._isHorizontal()) { if (this._computedHeight == null) { this._computeHeight(); } requestedHeight = this._computedHeight + this._gutter; - } else { + } + else { if (this._computedWidth == null) { this._computeWidth(); } requestedWidth = this._computedWidth + this._gutter; } - return { width: requestedWidth, height: requestedHeight, @@ -4194,44 +3839,38 @@ var Plottable; wantsHeight: this._isHorizontal() && offeredHeight < requestedHeight }; }; - Axis.prototype._isFixedHeight = function () { return this._isHorizontal(); }; - Axis.prototype._isFixedWidth = function () { return !this._isHorizontal(); }; - Axis.prototype._rescale = function () { // default implementation; subclasses may call _invalidateLayout() here this._render(); }; - 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.width()]); - } else { + } + else { this._scale.range([this.height(), 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. - */ + * 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); @@ -4242,7 +3881,6 @@ var Plottable; tickMarks.exit().remove(); this._baseline.attr(this._generateBaselineAttrHash()); }; - Axis.prototype._generateBaselineAttrHash = function () { var baselineAttrHash = { x1: 0, @@ -4250,84 +3888,84 @@ var Plottable; x2: 0, y2: 0 }; - switch (this._orientation) { case "bottom": baselineAttrHash.x2 = this.width(); break; - case "top": baselineAttrHash.x2 = this.width(); baselineAttrHash.y1 = this.height(); baselineAttrHash.y2 = this.height(); break; - case "left": baselineAttrHash.x1 = this.width(); baselineAttrHash.x2 = this.width(); baselineAttrHash.y2 = this.height(); break; - case "right": baselineAttrHash.y2 = this.height(); break; } - return baselineAttrHash; }; - Axis.prototype._generateTickMarkAttrHash = function (isEndTickMark) { var _this = this; - if (typeof isEndTickMark === "undefined") { isEndTickMark = false; } + if (isEndTickMark === void 0) { 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.height(); tickMarkAttrHash["y2"] = this.height() - tickLength; break; - case "left": tickMarkAttrHash["x1"] = this.width(); tickMarkAttrHash["x2"] = this.width() - 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._setDefaultAlignment = function () { + switch (this._orientation) { + case "bottom": + this.yAlign("top"); + break; + case "top": + this.yAlign("bottom"); + break; + case "left": + this.xAlign("right"); + break; + case "right": + this.xAlign("left"); + break; + } + }; Axis.prototype.formatter = function (formatter) { if (formatter === undefined) { return this._formatter; @@ -4336,11 +3974,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"); } @@ -4349,11 +3987,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"); } @@ -4362,19 +4000,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"); } @@ -4383,11 +4021,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"); } @@ -4396,11 +4034,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"); @@ -4410,7 +4048,6 @@ var Plottable; return this; } }; - Axis.prototype.showEndTickLabels = function (show) { if (show == null) { return this._showEndTickLabels; @@ -4419,15 +4056,12 @@ 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.width()) && Math.floor(tickBox.bottom) <= Math.ceil(boundingBox.top + _this.height())); }; - var tickLabels = this._tickLabelContainer.selectAll("." + Abstract.Axis.TICK_LABEL_CLASS); if (tickLabels[0].length === 0) { return; @@ -4441,28 +4075,34 @@ 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"); } }); }; + /** + * The css class applied to each end tick mark (the line on the end tick). + */ Axis.END_TICK_MARK_CLASS = "end-tick-mark"; - + /** + * The css class applied to each tick mark (the line on the tick). + */ Axis.TICK_MARK_CLASS = "tick-mark"; - + /** + * The css class applied to each tick label (the text associated with the tick). + */ Axis.TICK_LABEL_CLASS = "tick-label"; return Axis; })(Abstract.Component); @@ -4482,18 +4122,17 @@ var Plottable; (function (Plottable) { (function (Axis) { ; - var Time = (function (_super) { __extends(Time, _super); /** - * Constructs a TimeAxis. - * - * A TimeAxis is used for rendering a TimeScale. - * - * @constructor - * @param {TimeScale} scale The scale to base the Axis on. - * @param {string} orientation The orientation of the Axis (top/bottom) - */ + * Constructs a TimeAxis. + * + * A TimeAxis is used for rendering a TimeScale. + * + * @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") { @@ -4513,14 +4152,12 @@ 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); @@ -4528,12 +4165,10 @@ var Plottable; // this offset is too large, so just return available width return this.width(); } - // 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 @@ -4541,14 +4176,12 @@ var Plottable; var stepLength = Math.min(this.getIntervalLength(interval), this.width()); 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++) { @@ -4562,25 +4195,21 @@ 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(); @@ -4588,7 +4217,6 @@ 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) { @@ -4598,15 +4226,12 @@ 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(); @@ -4616,15 +4241,10 @@ 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; @@ -4632,42 +4252,33 @@ 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.width() && 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.height() - 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(); @@ -4678,14 +4289,14 @@ 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]); return this; }; + // default intervals + // these are for minor tick labels Time._minorIntervals = [ { timeUnit: d3.time.second, step: 1, formatString: "%I:%M:%S %p" }, { timeUnit: d3.time.second, step: 5, formatString: "%I:%M:%S %p" }, @@ -4717,7 +4328,7 @@ var Plottable; { timeUnit: d3.time.year, step: 500, formatString: "%Y" }, { timeUnit: d3.time.year, step: 1000, formatString: "%Y" } ]; - + // these are for major tick labels Time._majorIntervals = [ { timeUnit: d3.time.day, step: 1, formatString: "%B %e, %Y" }, { timeUnit: d3.time.day, step: 1, formatString: "%B %e, %Y" }, @@ -4769,18 +4380,18 @@ var Plottable; var Numeric = (function (_super) { __extends(Numeric, _super); /** - * Constructs a NumericAxis. - * - * Just as an CategoryAxis is for rendering an OrdinalScale, a NumericAxis - * is for rendering a QuantitativeScale. - * - * @constructor - * @param {QuantitativeScale} scale The QuantitativeScale to base the axis 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)). - */ + * Constructs a NumericAxis. + * + * Just as an CategoryAxis is for rendering an OrdinalScale, a NumericAxis + * is for rendering a QuantitativeScale. + * + * @constructor + * @param {QuantitativeScale} scale The QuantitativeScale to base the axis 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 (typeof formatter === "undefined") { formatter = Plottable.Formatters.general(3, false); } + if (formatter === void 0) { 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 @@ -4792,7 +4403,6 @@ 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(); @@ -4800,39 +4410,32 @@ var Plottable; var formattedValue = _this._formatter(v); return _this.measurer(formattedValue).width; }); - var maxTextLength = Plottable._Util.Methods.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._rescale = function () { if (!this._isSetup) { return; } - if (!this._isHorizontal()) { var reComputedWidth = this._computeWidth(); if (reComputedWidth > this.width() || reComputedWidth < (this.width() - this.gutter())) { @@ -4840,25 +4443,19 @@ var Plottable; return; } } - this._render(); }; - 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; @@ -4879,7 +4476,8 @@ var Plottable; labelGroupShiftY = tickLabelPadding; break; } - } else { + } + else { switch (this.tickLabelPositioning) { case "top": tickLabelAttrHash["dy"] = "-0.3em"; @@ -4896,7 +4494,6 @@ var Plottable; break; } } - var tickMarkAttrHash = this._generateTickMarkAttrHash(); switch (this._orientation) { case "bottom": @@ -4904,53 +4501,46 @@ 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"); } @@ -4960,25 +4550,28 @@ 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"); } }; @@ -5002,48 +4595,45 @@ var Plottable; var Category = (function (_super) { __extends(Category, _super); /** - * Constructs 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) (default = "bottom"). - * @param {Formatter} formatter The Formatter for the Axis (default Formatters.identity()) - */ + * Constructs 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) (default = "bottom"). + * @param {Formatter} formatter The Formatter for the Axis (default Formatters.identity()) + */ function Category(scale, orientation, formatter) { - if (typeof orientation === "undefined") { orientation = "bottom"; } - if (typeof formatter === "undefined") { formatter = Plottable.Formatters.identity(); } + if (orientation === void 0) { orientation = "bottom"; } + if (formatter === void 0) { formatter = Plottable.Formatters.identity(); } _super.call(this, scale, orientation, formatter); + this._tickLabelAngle = 0; this.classed("category-axis", true); } Category.prototype._setup = function () { _super.prototype._setup.call(this); this.measurer = new Plottable._Util.Text.CachingCharacterMeasurer(this._tickLabelContainer.append("text")); }; - Category.prototype._rescale = function () { return this._invalidateLayout(); }; - 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, @@ -5051,86 +4641,86 @@ var Plottable; wantsHeight: !textResult.textFits }; }; - Category.prototype._getTickValues = function () { return this._scale.domain(); }; - + Category.prototype.tickLabelAngle = function (angle) { + if (angle == null) { + return this._tickLabelAngle; + } + if (angle !== 0 && angle !== 90 && angle !== -90) { + throw new Error("Angle " + angle + " not supported; only 0, 90, and -90 are valid values"); + } + this._tickLabelAngle = angle; + this._invalidateLayout(); + return this; + }; + Category.prototype.tickLabelOrientation = function () { + switch (this._tickLabelAngle) { + case 0: + return "horizontal"; + case -90: + return "left"; + case 90: + return "right"; + default: + throw new Error("bad orientation"); + } + }; /** - * Measures the size of the ticks while also writing them to the DOM. - * @param {D3.Selection} ticks The tick elements to be written to. - */ + * Measures the size of the ticks while also writing them to the DOM. + * @param {D3.Selection} ticks The tick elements to be written to. + */ Category.prototype.drawTicks = function (axisWidth, axisHeight, scale, ticks) { return this.drawOrMeasureTicks(axisWidth, axisHeight, scale, ticks, true); }; - /** - * Measures the size of the ticks without making any (permanent) DOM - * changes. - * - * @param {string[]} ticks The strings that will be printed on the ticks. - */ + * Measures the size of the ticks without making any (permanent) DOM + * changes. + * + * @param {string[]} ticks The strings that will be printed on the ticks. + */ Category.prototype.measureTicks = function (axisWidth, axisHeight, scale, ticks) { return this.drawOrMeasureTicks(axisWidth, axisHeight, scale, ticks, false); }; - Category.prototype.drawOrMeasureTicks = function (axisWidth, axisHeight, scale, dataOrTicks, draw) { 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) { var d3this = d3.select(this); var xAlign = { left: "right", right: "left", top: "center", bottom: "center" }; var yAlign = { left: "center", right: "center", top: "bottom", bottom: "top" }; - textWriteResult = Plottable._Util.Text.writeText(formatter(d), width, height, tm, true, { + textWriteResult = Plottable._Util.Text.writeText(formatter(d), width, height, tm, self.tickLabelOrientation(), { g: d3this, xAlign: xAlign[self._orientation], yAlign: yAlign[self._orientation] }); - } else { - textWriteResult = Plottable._Util.Text.writeText(formatter(d), width, height, tm, true); } - + else { + textWriteResult = Plottable._Util.Text.writeText(formatter(d), width, height, tm, self.tickLabelOrientation()); + } textWriteResults.push(textWriteResult); }); - var widthFn = this._isHorizontal() ? d3.sum : Plottable._Util.Methods.max; var heightFn = this._isHorizontal() ? Plottable._Util.Methods.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]; @@ -5141,19 +4731,16 @@ 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.drawTicks(this.width(), this.height(), 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]); return this; }; - 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 @@ -5181,18 +4768,18 @@ var Plottable; var Label = (function (_super) { __extends(Label, _super); /** - * Creates a Label. - * - * A label is component that renders just text. The most common use of - * labels is to create a title or axis labels. - * - * @constructor - * @param {string} displayText The text of the Label (default = ""). - * @param {string} orientation The orientation of the Label (horizontal/vertical-left/vertical-right) (default = "horizontal"). - */ + * Creates a Label. + * + * A label is component that renders just text. The most common use of + * labels is to create a title or axis labels. + * + * @constructor + * @param {string} displayText The text of the Label (default = ""). + * @param {string} orientation The orientation of the Label (horizontal/left/right) (default = "horizontal"). + */ function Label(displayText, orientation) { - if (typeof displayText === "undefined") { displayText = ""; } - if (typeof orientation === "undefined") { orientation = "horizontal"; } + if (displayText === void 0) { displayText = ""; } + if (orientation === void 0) { orientation = "horizontal"; } _super.call(this); this.classed("label", true); this.text(displayText); @@ -5202,38 +4789,35 @@ var Plottable; this._fixedWidthFlag = true; } /** - * Sets the horizontal side the label will go to given the label is given more space that it needs - * - * @param {string} alignment The new setting, one of `["left", "center", - * "right"]`. Defaults to `"center"`. - * @returns {Label} The calling Label. - */ + * Sets the horizontal side the label will go to given the label is given more space that it needs + * + * @param {string} alignment The new setting, one of `["left", "center", + * "right"]`. Defaults to `"center"`. + * @returns {Label} The calling Label. + */ Label.prototype.xAlign = function (alignment) { var alignmentLC = alignment.toLowerCase(); _super.prototype.xAlign.call(this, alignmentLC); this.xAlignment = alignmentLC; return this; }; - /** - * Sets the vertical side the label will go to given the label is given more space that it needs - * - * @param {string} alignment The new setting, one of `["top", "center", - * "bottom"]`. Defaults to `"center"`. - * @returns {Label} The calling Label. - */ + * Sets the vertical side the label will go to given the label is given more space that it needs + * + * @param {string} alignment The new setting, one of `["top", "center", + * "bottom"]`. Defaults to `"center"`. + * @returns {Label} The calling Label. + */ Label.prototype.yAlign = function (alignment) { var alignmentLC = alignment.toLowerCase(); _super.prototype.yAlign.call(this, alignmentLC); 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, @@ -5241,45 +4825,38 @@ 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.orient = function (newOrientation) { if (newOrientation == null) { return this.orientation; - } else { + } + else { newOrientation = newOrientation.toLowerCase(); - if (newOrientation === "vertical-left") { - newOrientation = "left"; - } - if (newOrientation === "vertical-right") { - newOrientation = "right"; - } if (newOrientation === "horizontal" || newOrientation === "left" || newOrientation === "right") { this.orientation = newOrientation; - } else { + } + else { throw new Error(newOrientation + " is not a valid orientation for LabelComponent"); } this._invalidateLayout(); return this; } }; - Label.prototype._doRender = function () { _super.prototype._doRender.call(this); this.textContainer.text(""); @@ -5287,11 +4864,11 @@ 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.width(), this.height(), this.xAlignment, this.yAlignment); - } else { + } + else { Plottable._Util.Text.writeLineVertically(truncatedText, this.textContainer, this.width(), this.height(), this.xAlignment, this.yAlignment, this.orientation); } }; - Label.prototype._computeLayout = function (xOffset, yOffset, availableWidth, availableHeight) { 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); @@ -5300,14 +4877,13 @@ var Plottable; return Label; })(Plottable.Abstract.Component); Component.Label = Label; - var TitleLabel = (function (_super) { __extends(TitleLabel, _super); /** - * Creates a TitleLabel, a type of label made for rendering titles. - * - * @constructor - */ + * Creates a TitleLabel, a type of label made for rendering titles. + * + * @constructor + */ function TitleLabel(text, orientation) { _super.call(this, text, orientation); this.classed("title-label", true); @@ -5315,14 +4891,13 @@ var Plottable; return TitleLabel; })(Label); Component.TitleLabel = TitleLabel; - var AxisLabel = (function (_super) { __extends(AxisLabel, _super); /** - * Creates a AxisLabel, a type of label made for rendering axis labels. - * - * @constructor - */ + * Creates a AxisLabel, a type of label made for rendering axis labels. + * + * @constructor + */ function AxisLabel(text, orientation) { _super.call(this, text, orientation); this.classed("axis-label", true); @@ -5347,16 +4922,16 @@ var Plottable; var Legend = (function (_super) { __extends(Legend, _super); /** - * Constructs 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 {ColorScale} colorScale - */ + * Constructs 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 {ColorScale} colorScale + */ function Legend(colorScale) { _super.call(this); this.classed("legend", true); @@ -5372,7 +4947,6 @@ var Plottable; this.colorScale.broadcaster.deregisterListener(this); } }; - Legend.prototype.toggleCallback = function (callback) { if (callback !== undefined) { this._toggleCallback = callback; @@ -5380,11 +4954,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; @@ -5392,11 +4966,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) { @@ -5404,16 +4978,14 @@ 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())); @@ -5423,23 +4995,19 @@ 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.height() / 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 = Plottable._Util.Methods.max(this.colorScale.domain(), function (d) { - return measure(d).width; - }); + var maxWidth = Plottable._Util.Methods.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; @@ -5451,12 +5019,10 @@ 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; @@ -5464,23 +5030,17 @@ var Plottable; 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.width() - 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); @@ -5489,15 +5049,12 @@ 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) { @@ -5507,38 +5064,37 @@ var Plottable; if (this._hoverCallback != null) { // 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(); - }; - }; + 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) { @@ -5546,26 +5102,25 @@ 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); } }; + /** + * The css class applied to each legend row + */ Legend.SUBELEMENT_CLASS = "legend-row"; Legend.MARGIN = 5; return Legend; @@ -5588,25 +5143,21 @@ var Plottable; var HorizontalLegend = (function (_super) { __extends(HorizontalLegend, _super); /** - * Creates a Horizontal Legend. - * - * The legend consists of a series of legend entries, each with a color and label taken from the `colorScale`. - * The entries will be displayed in the order of the `colorScale` domain. - * - * @constructor - * @param {Scale.Color} colorScale - */ + * Creates a Horizontal Legend. + * + * The legend consists of a series of legend entries, each with a color and label taken from the `colorScale`. + * The entries will be displayed in the order of the `colorScale` domain. + * + * @constructor + * @param {Scale.Color} colorScale + */ function HorizontalLegend(colorScale) { var _this = this; _super.call(this); this.padding = 5; this.classed("legend", true); - this.scale = colorScale; - this.scale.broadcaster.registerListener(this, function () { - return _this._invalidateLayout(); - }); - + this.scale.broadcaster.registerListener(this, function () { return _this._invalidateLayout(); }); this.xAlign("left").yAlign("center"); this._fixedWidthFlag = true; this._fixedHeightFlag = true; @@ -5615,32 +5166,25 @@ var Plottable; _super.prototype.remove.call(this); this.scale.broadcaster.deregisterListener(this); }; - HorizontalLegend.prototype.calculateLayoutInfo = function (availableWidth, availableHeight) { var _this = this; var fakeLegendRow = this._content.append("g").classed(HorizontalLegend.LEGEND_ROW_CLASS, true); var fakeLegendEntry = fakeLegendRow.append("g").classed(HorizontalLegend.LEGEND_ENTRY_CLASS, true); var measure = Plottable._Util.Text.getTextMeasurer(fakeLegendRow.append("text")); - var textHeight = measure(Plottable._Util.Text.HEIGHT_TEXT).height; - var availableWidthForEntries = Math.max(0, (availableWidth - this.padding)); var measureEntry = function (entryText) { var originalEntryLength = (textHeight + measure(entryText).width + _this.padding); return Math.min(originalEntryLength, availableWidthForEntries); }; - var entries = this.scale.domain(); var entryLengths = Plottable._Util.Methods.populateMap(entries, measureEntry); fakeLegendRow.remove(); - var rows = this.packRows(availableWidthForEntries, entries, entryLengths); - var rowsAvailable = Math.floor((availableHeight - 2 * this.padding) / textHeight); if (rowsAvailable !== rowsAvailable) { rowsAvailable = 0; } - return { textHeight: textHeight, entryLengths: entryLengths, @@ -5648,22 +5192,16 @@ var Plottable; numRowsToDraw: Math.max(Math.min(rowsAvailable, rows.length), 0) }; }; - HorizontalLegend.prototype._requestedSpace = function (offeredWidth, offeredHeight) { var estimatedLayout = this.calculateLayoutInfo(offeredWidth, offeredHeight); - var rowLengths = estimatedLayout.rows.map(function (row) { - return d3.sum(row, function (entry) { - return estimatedLayout.entryLengths.get(entry); - }); + return d3.sum(row, function (entry) { return estimatedLayout.entryLengths.get(entry); }); }); var longestRowLength = Plottable._Util.Methods.max(rowLengths); longestRowLength = longestRowLength === undefined ? 0 : longestRowLength; // HACKHACK: #843 var desiredWidth = this.padding + longestRowLength; - var acceptableHeight = estimatedLayout.numRowsToDraw * estimatedLayout.textHeight + 2 * this.padding; var desiredHeight = estimatedLayout.rows.length * estimatedLayout.textHeight + 2 * this.padding; - return { width: desiredWidth, height: acceptableHeight, @@ -5671,7 +5209,6 @@ var Plottable; wantsHeight: offeredHeight < desiredHeight }; }; - HorizontalLegend.prototype.packRows = function (availableWidth, entries, entryLengths) { var rows = [[]]; var currentRow = rows[0]; @@ -5688,30 +5225,20 @@ var Plottable; }); return rows; }; - HorizontalLegend.prototype._doRender = function () { var _this = this; _super.prototype._doRender.call(this); - var layout = this.calculateLayoutInfo(this.width(), this.height()); - var rowsToDraw = layout.rows.slice(0, layout.numRowsToDraw); var rows = this._content.selectAll("g." + HorizontalLegend.LEGEND_ROW_CLASS).data(rowsToDraw); rows.enter().append("g").classed(HorizontalLegend.LEGEND_ROW_CLASS, true); rows.exit().remove(); - - rows.attr("transform", function (d, i) { - return "translate(0, " + (i * layout.textHeight + _this.padding) + ")"; - }); - - var entries = rows.selectAll("g." + HorizontalLegend.LEGEND_ENTRY_CLASS).data(function (d) { - return d; - }); + rows.attr("transform", function (d, i) { return "translate(0, " + (i * layout.textHeight + _this.padding) + ")"; }); + var entries = rows.selectAll("g." + HorizontalLegend.LEGEND_ENTRY_CLASS).data(function (d) { return d; }); var entriesEnter = entries.enter().append("g").classed(HorizontalLegend.LEGEND_ENTRY_CLASS, true); entriesEnter.append("circle"); entriesEnter.append("g").classed("text-container", true); entries.exit().remove(); - var legendPadding = this.padding; rows.each(function (values) { var xShift = legendPadding; @@ -5722,18 +5249,11 @@ var Plottable; return translateString; }); }); - - entries.select("circle").attr("cx", layout.textHeight / 2).attr("cy", layout.textHeight / 2).attr("r", layout.textHeight * 0.3).attr("fill", function (value) { - return _this.scale.scale(value); - }); - + entries.select("circle").attr("cx", layout.textHeight / 2).attr("cy", layout.textHeight / 2).attr("r", layout.textHeight * 0.3).attr("fill", function (value) { return _this.scale.scale(value); }); var padding = this.padding; var textContainers = entries.select("g.text-container"); textContainers.text(""); // clear out previous results - textContainers.append("title").text(function (value) { - return value; - }); - + textContainers.append("title").text(function (value) { return value; }); // HACKHACK (translate vertical shift): #864 textContainers.attr("transform", "translate(" + layout.textHeight + ", " + (layout.textHeight * 0.1) + ")").each(function (value) { var container = d3.select(this); @@ -5744,8 +5264,13 @@ var Plottable; Plottable._Util.Text.writeLineHorizontally(textToWrite, container, textSize.width, textSize.height); }); }; + /** + * The css class applied to each legend row + */ HorizontalLegend.LEGEND_ROW_CLASS = "legend-row"; - + /** + * The css class applied to each legend entry + */ HorizontalLegend.LEGEND_ENTRY_CLASS = "legend-entry"; return HorizontalLegend; })(Plottable.Abstract.Component); @@ -5767,12 +5292,12 @@ var Plottable; 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. - */ + * 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) { var _this = this; _super.call(this); @@ -5780,14 +5305,10 @@ var Plottable; this.xScale = xScale; this.yScale = yScale; if (this.xScale) { - this.xScale.broadcaster.registerListener(this, function () { - return _this._render(); - }); + this.xScale.broadcaster.registerListener(this, function () { return _this._render(); }); } if (this.yScale) { - this.yScale.broadcaster.registerListener(this, function () { - return _this._render(); - }); + this.yScale.broadcaster.registerListener(this, function () { return _this._render(); }); } } Gridlines.prototype.remove = function () { @@ -5800,47 +5321,35 @@ 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) { 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.height()).classed("zeroline", function (t) { - return t === 0; - }); + xLines.attr("x1", getScaledXValue).attr("y1", 0).attr("x2", getScaledXValue).attr("y2", this.height()).classed("zeroline", function (t) { return t === 0; }); xLines.exit().remove(); } }; - Gridlines.prototype.redrawYLines = function () { var _this = this; if (this.yScale) { 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.width()).attr("y2", getScaledYValue).classed("zeroline", function (t) { - return t === 0; - }); + yLines.attr("x1", 0).attr("y1", getScaledYValue).attr("x2", this.width()).attr("y2", getScaledYValue).classed("zeroline", function (t) { return t === 0; }); yLines.exit().remove(); } }; @@ -5862,26 +5371,25 @@ var Plottable; (function (Plottable) { (function (Component) { ; - var Table = (function (_super) { __extends(Table, _super); /** - * Constructs a Table. - * - * A Table is used to combine multiple Components in the form of a grid. A - * common case is combining a y-axis, x-axis, and the plotted data via - * ```typescript - * new Table([[yAxis, plot], - * [null, xAxis]]); - * ``` - * - * @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. (default = []) - */ + * Constructs a Table. + * + * A Table is used to combine multiple Components in the form of a grid. A + * common case is combining a y-axis, x-axis, and the plotted data via + * ```typescript + * new Table([[yAxis, plot], + * [null, xAxis]]); + * ``` + * + * @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. (default = []) + */ function Table(rows) { - if (typeof rows === "undefined") { rows = []; } var _this = this; + if (rows === void 0) { rows = []; } _super.call(this); this.rowPadding = 0; this.colPadding = 0; @@ -5898,44 +5406,40 @@ var Plottable; }); } /** - * Adds a Component in the specified cell. The cell must be unoccupied. - * - * For example, instead of calling `new Table([[a, b], [null, c]])`, you - * could call - * ```typescript - * var table = new Table(); - * table.addComponent(0, 0, a); - * table.addComponent(0, 1, b); - * table.addComponent(1, 1, c); - * ``` - * - * @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. - * @returns {Table} The calling Table. - */ + * Adds a Component in the specified cell. The cell must be unoccupied. + * + * For example, instead of calling `new Table([[a, b], [null, c]])`, you + * could call + * ```typescript + * var table = new Table(); + * table.addComponent(0, 0, a); + * table.addComponent(0, 1, b); + * table.addComponent(1, 1, c); + * ``` + * + * @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. + * @returns {Table} The calling Table. + */ 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) { 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; @@ -5944,63 +5448,47 @@ 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. - * - */ + * 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 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 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); @@ -6008,68 +5496,47 @@ 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); @@ -6080,44 +5547,30 @@ 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.width(), this.height()); - - 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; @@ -6133,68 +5586,58 @@ 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. - */ + * 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. - * - * A common case would be to have one graph take up 2/3rds of the space, - * and the other graph take up 1/3rd. - * - * @param {number} index The index of the row. - * @param {number} weight The weight to be set on the row. - * @returns {Table} The calling 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. + * + * A common case would be to have one graph take up 2/3rds of the space, + * and the other graph take up 1/3rd. + * + * @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. - * - * A common case would be to have one graph take up 2/3rds of the space, - * and the other graph take up 1/3rd. - * - * @param {number} index The index of the column. - * @param {number} weight The weight to be set on the column. - * @returns {Table} The calling 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. + * + * A common case would be to have one graph take up 2/3rds of the space, + * and the other graph take up 1/3rd. + * + * @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) { @@ -6213,7 +5656,6 @@ 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 @@ -6223,33 +5665,22 @@ var Plottable; 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; @@ -6276,20 +5707,21 @@ var Plottable; this._dataChanged = false; this._animate = false; this._animators = {}; - this._ANIMATION_DURATION = 250; + this._ANIMATION_DURATION = 250; // milliseconds this._projectors = {}; this.animateOnNextRender = true; this.clipPathEnabled = true; this.classed("plot", true); - var dataset; if (dataOrDataset) { if (typeof dataOrDataset.data === "function") { dataset = dataOrDataset; - } else { + } + else { dataset = new Plottable.Dataset(dataOrDataset); } - } else { + } + else { dataset = new Plottable.Dataset(); } this.dataset(dataset); @@ -6300,12 +5732,10 @@ var Plottable; this._dataChanged = true; this._updateScaleExtents(); }; - Plot.prototype.remove = function () { var _this = this; _super.prototype.remove.call(this); this._dataset.broadcaster.deregisterListener(this); - // deregister from all scales var properties = Object.keys(this._projectors); properties.forEach(function (property) { @@ -6315,7 +5745,6 @@ var Plottable; } }); }; - Plot.prototype.dataset = function (dataset) { var _this = this; if (!dataset) { @@ -6325,65 +5754,56 @@ var Plottable; this._dataset.broadcaster.deregisterListener(this); } this._dataset = dataset; - this._dataset.broadcaster.registerListener(this, function () { - return _this._onDatasetUpdate(); - }); + this._dataset.broadcaster.registerListener(this, function () { return _this._onDatasetUpdate(); }); this._onDatasetUpdate(); return this; }; - Plot.prototype._onDatasetUpdate = function () { this._updateScaleExtents(); this.animateOnNextRender = true; this._dataChanged = true; this._render(); }; - /** - * Sets an attribute of every data point. - * - * Here's a common use case: - * ```typescript - * plot.attr("r", function(d) { return d.foo; }); - * ``` - * This will set the radius of each datum `d` to be `d.foo`. - * - * @param {string} attrToSet The attribute to set across each data - * point. Popular examples include "x", "y", "r". Scales that inherit from - * Plot define their meaning. - * - * @param {Function|string|any} accessor Function to apply to each element - * of the dataSource. If a Function, use `accessor(d, i)`. If a string, - * `d[accessor]` is used. If anything else, use `accessor` as a constant - * across all data points. - * - * @param {Abstract.Scale} scale If provided, the result of the accessor - * is passed through the scale, such as `scale.scale(accessor(d, i))`. - * - * @returns {Plot} The calling Plot. - */ + * Sets an attribute of every data point. + * + * Here's a common use case: + * ```typescript + * plot.attr("r", function(d) { return d.foo; }); + * ``` + * This will set the radius of each datum `d` to be `d.foo`. + * + * @param {string} attrToSet The attribute to set across each data + * point. Popular examples include "x", "y", "r". Scales that inherit from + * Plot define their meaning. + * + * @param {Function|string|any} accessor Function to apply to each element + * of the dataSource. If a Function, use `accessor(d, i)`. If a string, + * `d[accessor]` is used. If anything else, use `accessor` as a constant + * across all data points. + * + * @param {Abstract.Scale} scale If provided, the result of the accessor + * is passed through the scale, such as `scale.scale(accessor(d, i))`. + * + * @returns {Plot} The calling Plot. + */ Plot.prototype.attr = function (attrToSet, accessor, scale) { return this.project(attrToSet, accessor, scale); }; - /** - * Identical to plot.attr - */ + * Identical to plot.attr + */ Plot.prototype.project = function (attrToSet, accessor, scale) { var _this = this; attrToSet = attrToSet.toLowerCase(); var currentProjection = this._projectors[attrToSet]; var existingScale = currentProjection && currentProjection.scale; - if (existingScale) { existingScale._removeExtent(this._plottableID.toString(), attrToSet); existingScale.broadcaster.deregisterListener(this); } - if (scale) { - 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 }; @@ -6391,7 +5811,6 @@ var Plottable; this._render(); // queue a re-render upon changing projector return this; }; - Plot.prototype._generateAttrToProjector = function () { var _this = this; var h = {}; @@ -6399,14 +5818,11 @@ var Plottable; var projector = _this._projectors[a]; var accessor = projector.accessor; var scale = projector.scale; - var fn = scale ? function (d, i) { - return scale.scale(accessor(d, i)); - } : accessor; + var fn = scale ? function (d, i) { return scale.scale(accessor(d, i)); } : accessor; h[a] = fn; }); return h; }; - Plot.prototype._doRender = function () { if (this._isAnchored) { this._paint(); @@ -6414,83 +5830,75 @@ 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. - */ + * 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._updateScaleExtents(); 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. - */ + * 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._updateScaleExtents = function () { var _this = this; - d3.keys(this._projectors).forEach(function (attr) { - return _this._updateScaleExtent(attr); - }); + d3.keys(this._projectors).forEach(function (attr) { return _this._updateScaleExtent(attr); }); }; - Plot.prototype._updateScaleExtent = function (attr) { var projector = this._projectors[attr]; if (projector.scale) { var extent = this.dataset()._getExtent(projector.accessor, projector.scale._typeCoercer); if (extent.length === 0 || !this._isAnchored) { projector.scale._removeExtent(this._plottableID.toString(), attr); - } else { + } + else { projector.scale._updateExtent(this._plottableID.toString(), attr, extent); } } }; - /** - * Applies 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. - * @returns {D3.Selection} The resulting selection (potentially after the transition) - */ + * Applies 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. + * @returns {D3.Selection} The resulting selection (potentially after the transition) + */ Plot.prototype._applyAnimatedAttributes = function (selection, animatorKey, attrToProjector) { if (this._animate && this.animateOnNextRender && this._animators[animatorKey]) { return this._animators[animatorKey].animate(selection, attrToProjector); - } 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; } @@ -6513,22 +5921,22 @@ var Plottable; (function (Plottable) { (function (Plot) { /* - * A PiePlot is a plot meant to show how much out of a total an attribute's value is. - * One usecase is to show how much funding departments are given out of a total budget. - * - * Primary projection attributes: - * "fill" - Accessor determining the color of each sector - * "inner-radius" - Accessor determining the distance from the center to the inner edge of the sector - * "outer-radius" - Accessor determining the distance from the center to the outer edge of the sector - * "value" - Accessor to extract the value determining the proportion of each slice to the total - */ + * A PiePlot is a plot meant to show how much out of a total an attribute's value is. + * One usecase is to show how much funding departments are given out of a total budget. + * + * Primary projection attributes: + * "fill" - Accessor determining the color of each sector + * "inner-radius" - Accessor determining the distance from the center to the inner edge of the sector + * "outer-radius" - Accessor determining the distance from the center to the outer edge of the sector + * "value" - Accessor to extract the value determining the proportion of each slice to the total + */ var Pie = (function (_super) { __extends(Pie, _super); /** - * Constructs a PiePlot. - * - * @constructor - */ + * Constructs a PiePlot. + * + * @constructor + */ function Pie() { // make a dummy dataset to satisfy the base Plot (HACKHACK) this._key2DatasetDrawerKey = d3.map(); @@ -6540,16 +5948,13 @@ var Plottable; Pie.prototype._setup = function () { Plottable.Abstract.NewStylePlot.prototype._setup.call(this); }; - Pie.prototype._computeLayout = function (xOffset, yOffset, availableWidth, availableHeight) { _super.prototype._computeLayout.call(this, xOffset, yOffset, availableWidth, availableHeight); this._renderArea.attr("transform", "translate(" + this.width() / 2 + "," + this.height() / 2 + ")"); }; - Pie.prototype.addDataset = function (keyOrDataset, dataset) { return Plottable.Abstract.NewStylePlot.prototype.addDataset.call(this, keyOrDataset, dataset); }; - Pie.prototype._addDataset = function (key, dataset) { if (this._datasetKeysInOrder.length === 1) { Plottable._Util.Methods.warn("Only one dataset is supported in pie plots"); @@ -6557,17 +5962,15 @@ var Plottable; } Plottable.Abstract.NewStylePlot.prototype._addDataset.call(this, key, dataset); }; - /** - * Removes a dataset - * - * @param {string} key The key of the dataset - * @returns {Pie} The calling PiePlot. - */ + * Removes a dataset + * + * @param {string} key The key of the dataset + * @returns {Pie} The calling PiePlot. + */ Pie.prototype.removeDataset = function (key) { return Plottable.Abstract.NewStylePlot.prototype.removeDataset.call(this, key); }; - Pie.prototype._generateAttrToProjector = function () { var attrToProjector = this.retargetProjectors(_super.prototype._generateAttrToProjector.call(this)); var innerRadiusF = attrToProjector["inner-radius"] || d3.functor(0); @@ -6575,51 +5978,38 @@ var Plottable; attrToProjector["d"] = d3.svg.arc().innerRadius(innerRadiusF).outerRadius(outerRadiusF); delete attrToProjector["inner-radius"]; delete attrToProjector["outer-radius"]; - if (attrToProjector["fill"] == null) { - attrToProjector["fill"] = function (d, i) { - return Pie.DEFAULT_COLOR_SCALE.scale(String(i)); - }; + attrToProjector["fill"] = function (d, i) { return Pie.DEFAULT_COLOR_SCALE.scale(String(i)); }; } - delete attrToProjector["value"]; return attrToProjector; }; - /** - * Since the data goes through a pie function, which returns an array of ArcDescriptors, - * projectors will need to be retargeted so they point to the data portion of each arc descriptor. - */ + * Since the data goes through a pie function, which returns an array of ArcDescriptors, + * projectors will need to be retargeted so they point to the data portion of each arc descriptor. + */ Pie.prototype.retargetProjectors = function (attrToProjector) { var retargetedAttrToProjector = {}; d3.entries(attrToProjector).forEach(function (entry) { - retargetedAttrToProjector[entry.key] = function (d, i) { - return entry.value(d.data, i); - }; + retargetedAttrToProjector[entry.key] = function (d, i) { return entry.value(d.data, i); }; }); return retargetedAttrToProjector; }; - Pie.prototype._getAnimator = function (drawer, index) { return Plottable.Abstract.NewStylePlot.prototype._getAnimator.call(this, drawer, index); }; - Pie.prototype._getDrawer = function (key) { return new Plottable._Drawer.Arc(key); }; - Pie.prototype._getDatasetsInOrder = function () { return Plottable.Abstract.NewStylePlot.prototype._getDatasetsInOrder.call(this); }; - Pie.prototype._getDrawersInOrder = function () { return Plottable.Abstract.NewStylePlot.prototype._getDrawersInOrder.call(this); }; - Pie.prototype._updateScaleExtent = function (attr) { Plottable.Abstract.NewStylePlot.prototype._updateScaleExtent.call(this, attr); }; - Pie.prototype._paint = function () { var _this = this; var attrHash = this._generateAttrToProjector(); @@ -6630,11 +6020,8 @@ var Plottable; d.draw(pieData, attrHash, animator); }); }; - Pie.prototype.pie = function (d) { - var defaultAccessor = function (d) { - return d.value; - }; + var defaultAccessor = function (d) { return d.value; }; var valueProjector = this._projectors["value"]; var valueAccessor = valueProjector ? valueProjector.accessor : defaultAccessor; return d3.layout.pie().sort(null).value(valueAccessor)(d); @@ -6660,30 +6047,29 @@ var Plottable; var XYPlot = (function (_super) { __extends(XYPlot, _super); /** - * Constructs an XYPlot. - * - * An XYPlot is a plot from drawing 2-dimensional data. Common examples - * include Scale.Line and Scale.Bar. - * - * @constructor - * @param {any[]|Dataset} [dataset] The data or Dataset to be associated with this Renderer. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs an XYPlot. + * + * An XYPlot is a plot from drawing 2-dimensional data. Common examples + * include Scale.Line and Scale.Bar. + * + * @constructor + * @param {any[]|Dataset} [dataset] The data or Dataset 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 || !yScale) { throw new Error("XYPlots require an xScale and yScale"); } this.classed("xy-plot", true); - this.project("x", "x", xScale); // default accessor this.project("y", "y", yScale); // default accessor } /** - * @param {string} attrToSet One of ["x", "y"] which determines the point's - * x and y position in the Plot. - */ + * @param {string} attrToSet One of ["x", "y"] which determines the point's + * x and y position in the Plot. + */ 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. @@ -6691,23 +6077,18 @@ var Plottable; this._xScale = scale; this._updateXDomainer(); } - if (attrToSet === "y" && scale) { 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.width()]); this._yScale.range([this.height(), 0]); }; - XYPlot.prototype._updateXDomainer = function () { if (this._xScale instanceof Abstract.QuantitativeScale) { var scale = this._xScale; @@ -6716,7 +6097,6 @@ var Plottable; } } }; - XYPlot.prototype._updateYDomainer = function () { if (this._yScale instanceof Abstract.QuantitativeScale) { var scale = this._yScale; @@ -6745,17 +6125,17 @@ var Plottable; var NewStylePlot = (function (_super) { __extends(NewStylePlot, _super); /** - * Constructs a NewStylePlot. - * - * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. - * - * A bare Plot has a DataSource and any number of projectors, which take - * data and "project" it onto the Plot, such as "x", "y", "fill", "r". - * - * @constructor - * @param [Scale] xScale The x scale to use - * @param [Scale] yScale The y scale to use - */ + * Constructs a NewStylePlot. + * + * Plots render data. Common example include Plot.Scatter, Plot.Bar, and Plot.Line. + * + * A bare Plot has a DataSource and any number of projectors, which take + * data and "project" it onto the Plot, such as "x", "y", "fill", "r". + * + * @constructor + * @param [Scale] xScale The x scale to use + * @param [Scale] yScale The y scale to use + */ function NewStylePlot(xScale, yScale) { // make a dummy dataset to satisfy the base Plot (HACKHACK) this._key2DatasetDrawerKey = d3.map(); @@ -6766,19 +6146,13 @@ 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"); @@ -6789,11 +6163,9 @@ var Plottable; var key = typeof (keyOrDataset) === "string" ? keyOrDataset : "_" + this.nextSeriesIndex++; var data = typeof (keyOrDataset) !== "string" ? keyOrDataset : dataset; var dataset = (data instanceof Plottable.Dataset) ? data : new Plottable.Dataset(data); - this._addDataset(key, dataset); return this; }; - NewStylePlot.prototype._addDataset = function (key, dataset) { var _this = this; if (this._key2DatasetDrawerKey.has(key)) { @@ -6804,24 +6176,18 @@ var Plottable; var ddk = { drawer: drawer, dataset: dataset, key: key }; this._datasetKeysInOrder.push(key); this._key2DatasetDrawerKey.set(key, ddk); - if (this._isSetup) { drawer._renderArea = this._renderArea.append("g"); } - dataset.broadcaster.registerListener(this, function () { - return _this._onDatasetUpdate(); - }); + dataset.broadcaster.registerListener(this, function () { return _this._onDatasetUpdate(); }); this._onDatasetUpdate(); }; - NewStylePlot.prototype._getDrawer = function (key) { throw new Error("Abstract Method Not Implemented"); }; - NewStylePlot.prototype._getAnimator = function (drawer, index) { return new Plottable.Animator.Null(); }; - NewStylePlot.prototype._updateScaleExtent = function (attr) { var _this = this; var projector = this._projectors[attr]; @@ -6831,42 +6197,41 @@ var Plottable; var scaleKey = _this._plottableID.toString() + "_" + 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; } function isPermutation(l1, l2) { var intersection = Plottable._Util.Methods.intersection(d3.set(l1), d3.set(l2)); - var size = intersection.size(); + var size = intersection.size(); // HACKHACK pending on borisyankov/definitelytyped/ pr #2653 return size === l1.length && size === l2.length; } if (isPermutation(order, this._datasetKeysInOrder)) { this._datasetKeysInOrder = order; this._onDatasetUpdate(); - } 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. - */ + * Removes a dataset + * + * @param {string} key The key of the dataset + * @return {NewStylePlot} The calling NewStylePlot. + */ NewStylePlot.prototype.removeDataset = function (key) { if (this._key2DatasetDrawerKey.has(key)) { var ddk = this._key2DatasetDrawerKey.get(key); ddk.drawer.remove(); - var projectors = d3.values(this._projectors); var scaleKey = this._plottableID.toString() + "_" + key; projectors.forEach(function (p) { @@ -6874,7 +6239,6 @@ var Plottable; p.scale._removeExtent(scaleKey, p.attribute); } }); - ddk.dataset.broadcaster.deregisterListener(this); this._datasetKeysInOrder.splice(this._datasetKeysInOrder.indexOf(key), 1); this._key2DatasetDrawerKey.remove(key); @@ -6882,21 +6246,14 @@ var Plottable; } return this; }; - NewStylePlot.prototype._getDatasetsInOrder = function () { var _this = this; - return this._datasetKeysInOrder.map(function (k) { - return _this._key2DatasetDrawerKey.get(k).dataset; - }); + return this._datasetKeysInOrder.map(function (k) { return _this._key2DatasetDrawerKey.get(k).dataset; }); }; - NewStylePlot.prototype._getDrawersInOrder = function () { var _this = this; - return this._datasetKeysInOrder.map(function (k) { - return _this._key2DatasetDrawerKey.get(k).drawer; - }); + return this._datasetKeysInOrder.map(function (k) { return _this._key2DatasetDrawerKey.get(k).drawer; }); }; - NewStylePlot.prototype._paint = function () { var _this = this; var attrHash = this._generateAttrToProjector(); @@ -6926,13 +6283,13 @@ var Plottable; var Scatter = (function (_super) { __extends(Scatter, _super); /** - * Constructs a ScatterPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a ScatterPlot. + * + * @constructor + * @param {IDataset | any} 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 = { @@ -6942,43 +6299,34 @@ var Plottable; this.classed("scatter-plot", true); this.project("r", 3); // default this.project("opacity", 0.6); // default - this.project("fill", function () { - return Plottable.Core.Colors.INDIGO; - }); // default + this.project("fill", function () { return Plottable.Core.Colors.INDIGO; }); // default } /** - * @param {string} attrToSet One of ["x", "y", "cx", "cy", "r", - * "fill"]. "cx" and "cy" are aliases for "x" and "y". "r" is the datum's - * radius, and "fill" is the CSS color of the datum. - */ + * @param {string} attrToSet One of ["x", "y", "cx", "cy", "r", + * "fill"]. "cx" and "cy" are aliases for "x" and "y". "r" is the datum's + * radius, and "fill" is the CSS color of the datum. + */ Scatter.prototype.project = function (attrToSet, accessor, scale) { attrToSet = attrToSet === "cx" ? "x" : attrToSet; attrToSet = attrToSet === "cy" ? "y" : attrToSet; _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._dataset.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(); }; @@ -7002,36 +6350,34 @@ var Plottable; var Grid = (function (_super) { __extends(Grid, _super); /** - * Constructs a GridPlot. - * - * A GridPlot is used to shade a grid of data. Each datum is a cell on the - * grid, and the datum can control what color it is. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale.Ordinal} xScale The x scale to use. - * @param {Scale.Ordinal} yScale The y scale to use. - * @param {Scale.Color|Scale.InterpolatedColor} colorScale The color scale - * to use for each grid cell. - */ + * Constructs a GridPlot. + * + * A GridPlot is used to shade a grid of data. Each datum is a cell on the + * grid, and the datum can control what color it is. + * + * @constructor + * @param {IDataset | any} dataset The dataset to render. + * @param {Scale.Ordinal} xScale The x scale to use. + * @param {Scale.Ordinal} yScale The y scale to use. + * @param {Scale.Color|Scale.InterpolatedColor} 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); // default } /** - * @param {string} attrToSet One of ["x", "y", "fill"]. If "fill" is used, - * the data should return a valid CSS color. - */ + * @param {string} attrToSet One of ["x", "y", "fill"]. If "fill" is used, + * the data should return a valid CSS color. + */ Grid.prototype.project = function (attrToSet, accessor, scale) { _super.prototype.project.call(this, attrToSet, accessor, scale); if (attrToSet === "fill") { @@ -7039,24 +6385,15 @@ var Plottable; } return this; }; - Grid.prototype._paint = function () { _super.prototype._paint.call(this); - var cells = this._renderArea.selectAll("rect").data(this._dataset.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(); }; @@ -7078,19 +6415,19 @@ 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. - */ + * 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); /** - * Constructs an AbstractBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs an AbstractBarPlot. + * + * @constructor + * @param {IDataset | any} 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; @@ -7101,10 +6438,7 @@ 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. @@ -7115,54 +6449,42 @@ 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._dataset.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"]) { 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.width() : scaledBaseline, "y2": this._isVertical ? scaledBaseline : this.height() }; - this._applyAnimatedAttributes(this._baseline, "baseline", baselineAttr); }; - /** - * Sets the baseline for the bars to the specified value. - * - * The baseline is the line that the bars are drawn from, defaulting to 0. - * - * @param {number} value The value to position the baseline at. - * @returns {AbstractBarPlot} The calling AbstractBarPlot. - */ + * Sets the baseline for the bars to the specified value. + * + * The baseline is the line that the bars are drawn from, defaulting to 0. + * + * @param {number} value The value to position the baseline at. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ BarPlot.prototype.baseline = function (value) { this._baselineValue = value; this._updateXDomainer(); @@ -7170,15 +6492,14 @@ 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. - * @returns {AbstractBarPlot} The calling AbstractBarPlot. - */ + * 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. + * @returns {AbstractBarPlot} The calling AbstractBarPlot. + */ BarPlot.prototype.barAlignment = function (alignment) { var alignmentLC = alignment.toLowerCase(); var align2factor = this.constructor._BarAlignmentToFactor; @@ -7186,38 +6507,33 @@ 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 (typeof select === "undefined") { select = true; } + if (select === void 0) { 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(); @@ -7225,60 +6541,57 @@ var Plottable; 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. - * @returns {AbstractBarPlot} The calling AbstractBarPlot. - */ + * Deselects all bars. + * @returns {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 @@ -7292,42 +6605,31 @@ var Plottable; var scaledBaseline = primaryScale.scale(this._baselineValue); if (!attrToProjector["width"]) { 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); @@ -7347,24 +6649,24 @@ 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 - */ + * 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); /** - * Constructs a VerticalBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {Scale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a VerticalBarPlot. + * + * @constructor + * @param {IDataset | any} 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) { this._isVertical = true; // Has to be set before super() _super.call(this, dataset, xScale, yScale); @@ -7391,34 +6693,32 @@ 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 - */ + * 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); /** - * Constructs a HorizontalBarPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a HorizontalBarPlot. + * + * @constructor + * @param {IDataset | any} 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); } 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"]; @@ -7447,13 +6747,13 @@ var Plottable; var Line = (function (_super) { __extends(Line, _super); /** - * Constructs a LinePlot. - * - * @constructor - * @param {any | IDataset} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a LinePlot. + * + * @constructor + * @param {any | IDataset} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ function Line(dataset, xScale, yScale) { _super.call(this, dataset, xScale, yScale); this._animators = { @@ -7461,72 +6761,61 @@ var Plottable; "line": new Plottable.Animator.Base().duration(600).easing("exp-in-out") }; this.classed("line-plot", true); - this.project("stroke", function () { - return Plottable.Core.Colors.INDIGO; - }); // default - this.project("stroke-width", function () { - return "2px"; - }); // default + 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._appendPath(); }; - Line.prototype._appendPath = function () { 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 = (domainMax < 0 && domainMax) || (domainMin > 0 && domainMin) || 0; 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(); - var isSingleDatumAttr = function (attr) { - return wholeDatumAttributes.indexOf(attr) === -1; - }; + var isSingleDatumAttr = function (attr) { return wholeDatumAttributes.indexOf(attr) === -1; }; var singleDatumAttributes = d3.keys(attrToProjector).filter(isSingleDatumAttr); singleDatumAttributes.forEach(function (attribute) { var projector = attrToProjector[attribute]; - attrToProjector[attribute] = function (data, i) { - return data.length > 0 ? projector(data[0], i) : null; - }; + attrToProjector[attribute] = function (data, i) { return data.length > 0 ? projector(data[0], i) : null; }; }); return attrToProjector; }; - + Line.prototype._rejectNullsAndNaNs = function (d, i, projector) { + var value = projector(d, i); + return value != null && value === value; + }; Line.prototype._paint = function () { + var _this = this; _super.prototype._paint.call(this); var attrToProjector = this._generateAttrToProjector(); var xFunction = attrToProjector["x"]; var yFunction = attrToProjector["y"]; delete attrToProjector["x"]; delete attrToProjector["y"]; - this.linePath.datum(this._dataset.data()); - + var line = d3.svg.line().x(xFunction); + line.defined(function (d, i) { return _this._rejectNullsAndNaNs(d, i, xFunction) && _this._rejectNullsAndNaNs(d, i, yFunction); }); + attrToProjector["d"] = line; if (this._dataChanged) { - attrToProjector["d"] = d3.svg.line().x(xFunction).y(this._getResetYFunction()); + line.y(this._getResetYFunction()); this._applyAnimatedAttributes(this.linePath, "line-reset", attrToProjector); } - - attrToProjector["d"] = d3.svg.line().x(xFunction).y(yFunction); + line.y(yFunction); this._applyAnimatedAttributes(this.linePath, "line", attrToProjector); }; - Line.prototype._wholeDatumAttributes = function () { return ["x", "y"]; }; @@ -7548,31 +6837,25 @@ var Plottable; (function (Plottable) { (function (Plot) { /** - * An AreaPlot draws a filled region (area) between the plot's projected "y" and projected "y0" values. - */ + * An AreaPlot draws a filled region (area) between the plot's projected "y" and projected "y0" values. + */ var Area = (function (_super) { __extends(Area, _super); /** - * Constructs an AreaPlot. - * - * @constructor - * @param {IDataset | any} dataset The dataset to render. - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs an AreaPlot. + * + * @constructor + * @param {IDataset | any} dataset The dataset to render. + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} 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); // 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.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.Base().duration(600).easing("exp-in-out"); } @@ -7580,34 +6863,29 @@ var Plottable; this.areaPath = this._renderArea.append("path").classed("area", true); _super.prototype._appendPath.call(this); }; - Area.prototype._onDatasetUpdate = function () { _super.prototype._onDatasetUpdate.call(this); if (this._yScale != null) { this._updateYDomainer(); } }; - Area.prototype._updateYDomainer = function () { _super.prototype._updateYDomainer.call(this); - var y0Projector = this._projectors["y0"]; var y0Accessor = y0Projector && y0Projector.accessor; var extent = y0Accessor ? this.dataset()._getExtent(y0Accessor, this._yScale._typeCoercer) : []; var constantBaseline = (extent.length === 2 && extent[0] === extent[1]) ? extent[0] : null; - if (!this._yScale._userSetDomainer) { if (constantBaseline != null) { this._yScale.domainer().addPaddingException(constantBaseline, "AREA_PLOT+" + this._plottableID); - } else { + } + else { this._yScale.domainer().removePaddingException("AREA_PLOT+" + this._plottableID); } - // prepending "AREA_PLOT" is unnecessary but reduces likely of user accidentally creating collisions this._yScale._autoDomainIfAutomaticMode(); } }; - Area.prototype.project = function (attrToSet, accessor, scale) { _super.prototype.project.call(this, attrToSet, accessor, scale); if (attrToSet === "y0") { @@ -7615,12 +6893,11 @@ var Plottable; } return this; }; - Area.prototype._getResetYFunction = function () { return this._generateAttrToProjector()["y0"]; }; - Area.prototype._paint = function () { + var _this = this; _super.prototype._paint.call(this); var attrToProjector = this._generateAttrToProjector(); var xFunction = attrToProjector["x"]; @@ -7629,18 +6906,17 @@ var Plottable; delete attrToProjector["x"]; delete attrToProjector["y0"]; delete attrToProjector["y"]; - this.areaPath.datum(this._dataset.data()); - + var area = d3.svg.area().x(xFunction).y0(y0Function); + area.defined(function (d, i) { return _this._rejectNullsAndNaNs(d, i, xFunction) && _this._rejectNullsAndNaNs(d, i, yFunction); }); + attrToProjector["d"] = area; if (this._dataChanged) { - attrToProjector["d"] = d3.svg.area().x(xFunction).y0(y0Function).y1(this._getResetYFunction()); + area.y1(this._getResetYFunction()); this._applyAnimatedAttributes(this.areaPath, "area-reset", attrToProjector); } - - attrToProjector["d"] = d3.svg.area().x(xFunction).y0(y0Function).y1(yFunction); + area.y1(yFunction); this._applyAnimatedAttributes(this.areaPath, "area", attrToProjector); }; - Area.prototype._wholeDatumAttributes = function () { var wholeDatumAttributes = _super.prototype._wholeDatumAttributes.call(this); wholeDatumAttributes.push("y0"); @@ -7666,12 +6942,12 @@ var Plottable; var NewStyleBarPlot = (function (_super) { __extends(NewStyleBarPlot, _super); /** - * Constructs a NewStyleBarPlot. - * - * @constructor - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Constructs a 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; @@ -7682,25 +6958,19 @@ 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 = { @@ -7711,27 +6981,23 @@ var Plottable; }; this._applyAnimatedAttributes(this._baseline, "baseline", baselineAttr); }; - /** - * Sets the baseline for the bars to the specified value. - * - * The baseline is the line that the bars are drawn from, defaulting to 0. - * - * @param {number} value The value to position the baseline at. - * @returns {NewStyleBarPlot} The calling NewStyleBarPlot. - */ + * Sets the baseline for the bars to the specified value. + * + * The baseline is the line that the bars are drawn from, defaulting to 0. + * + * @param {number} value The value to position the baseline at. + * @returns {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); }; @@ -7760,18 +7026,18 @@ var Plottable; var ClusteredBar = (function (_super) { __extends(ClusteredBar, _super); /** - * Creates a ClusteredBarPlot. - * - * A ClusteredBarPlot is a plot that plots several bar plots next to each - * other. For example, when plotting life expectancy across each country, - * you would want each country to have a "male" and "female" bar. - * - * @constructor - * @param {Scale} xScale The x scale to use. - * @param {Scale} yScale The y scale to use. - */ + * Creates a ClusteredBarPlot. + * + * A ClusteredBarPlot is a plot that plots several bar plots next to each + * other. For example, when plotting life expectancy across each country, + * you would want each country to have a "male" and "female" bar. + * + * @constructor + * @param {Scale} xScale The x scale to use. + * @param {Scale} yScale The y scale to use. + */ function ClusteredBar(xScale, yScale, isVertical) { - if (typeof isVertical === "undefined") { isVertical = true; } + if (isVertical === void 0) { isVertical = true; } this._isVertical = isVertical; // Has to be set before super() _super.call(this, xScale, yScale); this.innerScale = new Plottable.Scale.Ordinal(); @@ -7779,40 +7045,24 @@ 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)]); - - var innerWidthF = function (d, i) { - return _this.innerScale.rangeBand(); - }; + var innerWidthF = function (d, i) { return _this.innerScale.rangeBand(); }; var heightF = attrToProjector["height"]; attrToProjector["width"] = this._isVertical ? innerWidthF : heightF; attrToProjector["height"] = this._isVertical ? heightF : innerWidthF; - - var positionF = function (d) { - return d._PLOTTABLE_PROTECTED_FIELD_POSITION; - }; + var positionF = function (d) { return d._PLOTTABLE_PROTECTED_FIELD_POSITION; }; attrToProjector["x"] = this._isVertical ? positionF : attrToProjector["x"]; attrToProjector["y"] = this._isVertical ? attrToProjector["y"] : positionF; - 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; - }); - if (Plottable._Util.Methods.uniq(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.get(key).dataset.data(); - clusters[key] = data.map(function (d, i) { var val = accessor(d, i); var primaryScale = _this._isVertical ? _this._xScale : _this._yScale; @@ -7822,15 +7072,12 @@ var Plottable; }); return clusters; }; - ClusteredBar.prototype._paint = function () { _super.prototype._paint.call(this); var attrHash = this._generateAttrToProjector(); var accessor = this._isVertical ? this._projectors["x"].accessor : this._projectors["y"].accessor; 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); }); }; return ClusteredBar; })(Plottable.Abstract.NewStyleBarPlot); @@ -7857,100 +7104,101 @@ var Plottable; } Stacked.prototype._onDatasetUpdate = function () { _super.prototype._onDatasetUpdate.call(this); - // HACKHACK Caused since onDataSource is called before projectors are set up. Should be fixed by #803 if (this._datasetKeysInOrder && this._projectors["x"] && this._projectors["y"]) { - this.stack(); + this.updateStackOffsets(); } }; - - Stacked.prototype.stack = function () { - var datasets = this._getDatasetsInOrder(); - var keyAccessor = this._isVertical ? this._projectors["x"].accessor : this._projectors["y"].accessor; - var valueAccessor = this._isVertical ? this._projectors["y"].accessor : this._projectors["x"].accessor; - - var dataArray = datasets.map(function (dataset) { - return dataset.data().map(function (datum) { - return { key: keyAccessor(datum), value: valueAccessor(datum) }; - }); - }); - - var positiveDataArray = dataArray.map(function (data) { - return data.map(function (datum) { - return { key: datum.key, value: Math.max(0, datum.value) }; + Stacked.prototype.updateStackOffsets = function () { + var dataMapArray = this.generateDefaultMapArray(); + var domainKeys = this.getDomainKeys(); + var positiveDataMapArray = dataMapArray.map(function (dataMap) { + return Plottable._Util.Methods.populateMap(domainKeys, function (domainKey) { + return { key: domainKey, value: Math.max(0, dataMap.get(domainKey).value) }; }); }); - - var negativeDataArray = dataArray.map(function (data) { - return data.map(function (datum) { - return { key: datum.key, value: Math.min(datum.value, 0) }; + var negativeDataMapArray = dataMapArray.map(function (dataMap) { + return Plottable._Util.Methods.populateMap(domainKeys, function (domainKey) { + return { key: domainKey, value: Math.min(dataMap.get(domainKey).value, 0) }; }); }); - - this.setDatasetStackOffsets(this._stack(positiveDataArray), this._stack(negativeDataArray)); - - var maxStack = Plottable._Util.Methods.max(datasets, function (dataset) { + this.setDatasetStackOffsets(this.stack(positiveDataMapArray), this.stack(negativeDataMapArray)); + this.updateStackExtents(); + }; + Stacked.prototype.updateStackExtents = function () { + var datasets = this._getDatasetsInOrder(); + var valueAccessor = this.valueAccessor(); + var maxStackExtent = Plottable._Util.Methods.max(datasets, function (dataset) { return Plottable._Util.Methods.max(dataset.data(), function (datum) { return valueAccessor(datum) + datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]; }); }); - - var minStack = Plottable._Util.Methods.min(datasets, function (dataset) { + var minStackExtent = Plottable._Util.Methods.min(datasets, function (dataset) { return Plottable._Util.Methods.min(dataset.data(), function (datum) { return valueAccessor(datum) + datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]; }); }); - - this.stackedExtent = [Math.min(minStack, 0), Math.max(0, maxStack)]; + this.stackedExtent = [Math.min(minStackExtent, 0), Math.max(0, maxStackExtent)]; }; - /** - * Feeds the data through d3's stack layout function which will calculate - * the stack offsets and use the the function declared in .out to set the offsets on the data. - */ - Stacked.prototype._stack = function (dataArray) { + * Feeds the data through d3's stack layout function which will calculate + * the stack offsets and use the the function declared in .out to set the offsets on the data. + */ + Stacked.prototype.stack = function (dataArray) { + var _this = this; var outFunction = function (d, y0, y) { d.offset = y0; }; - - d3.layout.stack().x(function (d) { - return d.key; - }).y(function (d) { - return d.value; - }).values(function (d) { - return d; - }).out(outFunction)(dataArray); - + d3.layout.stack().x(function (d) { return d.key; }).y(function (d) { return d.value; }).values(function (d) { return _this.getDomainKeys().map(function (domainKey) { return d.get(domainKey); }); }).out(outFunction)(dataArray); return dataArray; }; - /** - * After the stack offsets have been determined on each separate dataset, the offsets need - * to be determined correctly on the overall datasets - */ - Stacked.prototype.setDatasetStackOffsets = function (positiveDataArray, negativeDataArray) { - var valueAccessor = this._isVertical ? this._projectors["y"].accessor : this._projectors["x"].accessor; - var positiveDataArrayOffsets = positiveDataArray.map(function (data) { - return data.map(function (datum) { - return datum.offset; + * After the stack offsets have been determined on each separate dataset, the offsets need + * to be determined correctly on the overall datasets + */ + Stacked.prototype.setDatasetStackOffsets = function (positiveDataMapArray, negativeDataMapArray) { + var keyAccessor = this.keyAccessor(); + var valueAccessor = this.valueAccessor(); + this._getDatasetsInOrder().forEach(function (dataset, datasetIndex) { + var positiveDataMap = positiveDataMapArray[datasetIndex]; + var negativeDataMap = negativeDataMapArray[datasetIndex]; + dataset.data().forEach(function (datum, datumIndex) { + var positiveOffset = positiveDataMap.get(keyAccessor(datum)).offset; + var negativeOffset = negativeDataMap.get(keyAccessor(datum)).offset; + datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"] = valueAccessor(datum) > 0 ? positiveOffset : negativeOffset; }); }); - var negativeDataArrayOffsets = negativeDataArray.map(function (data) { - return data.map(function (datum) { - return datum.offset; + }; + Stacked.prototype.getDomainKeys = function () { + var keyAccessor = this.keyAccessor(); + var domainKeys = d3.set(); + var datasets = this._getDatasetsInOrder(); + datasets.forEach(function (dataset) { + dataset.data().forEach(function (datum) { + domainKeys.add(keyAccessor(datum)); }); }); - - this._getDatasetsInOrder().forEach(function (dataset, datasetIndex) { - dataset.data().forEach(function (datum, datumIndex) { - var positiveOffset = positiveDataArrayOffsets[datasetIndex][datumIndex]; - var negativeOffset = negativeDataArrayOffsets[datasetIndex][datumIndex]; - - datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"] = valueAccessor(datum) > 0 ? positiveOffset : negativeOffset; + return domainKeys.values(); + }; + Stacked.prototype.generateDefaultMapArray = function () { + var keyAccessor = this.keyAccessor(); + var valueAccessor = this.valueAccessor(); + var datasets = this._getDatasetsInOrder(); + var domainKeys = this.getDomainKeys(); + var dataMapArray = datasets.map(function () { + return Plottable._Util.Methods.populateMap(domainKeys, function (domainKey) { + return { key: domainKey, value: 0 }; + }); + }); + datasets.forEach(function (dataset, datasetIndex) { + dataset.data().forEach(function (datum) { + var key = keyAccessor(datum); + var value = valueAccessor(datum); + dataMapArray[datasetIndex].set(key, { key: key, value: value }); }); }); + return dataMapArray; }; - Stacked.prototype._updateScaleExtents = function () { _super.prototype._updateScaleExtents.call(this); var primaryScale = this._isVertical ? this._yScale : this._xScale; @@ -7959,10 +7207,17 @@ var Plottable; } if (this._isAnchored && this.stackedExtent.length > 0) { primaryScale._updateExtent(this._plottableID.toString(), "_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT", this.stackedExtent); - } else { + } + else { primaryScale._removeExtent(this._plottableID.toString(), "_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT"); } }; + Stacked.prototype.keyAccessor = function () { + return this._isVertical ? this._projectors["x"].accessor : this._projectors["y"].accessor; + }; + Stacked.prototype.valueAccessor = function () { + return this._isVertical ? this._projectors["y"].accessor : this._projectors["x"].accessor; + }; return Stacked; })(Abstract.NewStylePlot); Abstract.Stacked = Stacked; @@ -7983,30 +7238,26 @@ var Plottable; var StackedArea = (function (_super) { __extends(StackedArea, _super); /** - * Constructs a StackedArea plot. - * - * @constructor - * @param {QuantitativeScale} xScale The x scale to use. - * @param {QuantitativeScale} yScale The y scale to use. - */ + * Constructs a StackedArea plot. + * + * @constructor + * @param {QuantitativeScale} xScale The x scale to use. + * @param {QuantitativeScale} yScale The y scale to use. + */ function StackedArea(xScale, yScale) { _super.call(this, xScale, yScale); this._baselineValue = 0; this.classed("area-plot", true); - this.project("fill", function () { - return Plottable.Core.Colors.INDIGO; - }); + this.project("fill", function () { return Plottable.Core.Colors.INDIGO; }); this._isVertical = true; } StackedArea.prototype._getDrawer = function (key) { return new Plottable._Drawer.Area(key); }; - StackedArea.prototype._setup = function () { _super.prototype._setup.call(this); this._baseline = this._renderArea.append("line").classed("baseline", true); }; - StackedArea.prototype._paint = function () { _super.prototype._paint.call(this); var scaledBaseline = this._yScale.scale(this._baselineValue); @@ -8018,46 +7269,32 @@ var Plottable; }; this._applyAnimatedAttributes(this._baseline, "baseline", baselineAttr); }; - StackedArea.prototype._updateYDomainer = function () { _super.prototype._updateYDomainer.call(this); var scale = this._yScale; if (!scale._userSetDomainer) { scale.domainer().addPaddingException(0, "STACKED_AREA_PLOT+" + this._plottableID); - // prepending "AREA_PLOT" is unnecessary but reduces likely of user accidentally creating collisions scale._autoDomainIfAutomaticMode(); } }; - StackedArea.prototype._onDatasetUpdate = function () { _super.prototype._onDatasetUpdate.call(this); Plot.Area.prototype._onDatasetUpdate.apply(this); }; - StackedArea.prototype._generateAttrToProjector = function () { var _this = this; var attrToProjector = _super.prototype._generateAttrToProjector.call(this); var xFunction = attrToProjector["x"]; - var yFunction = function (d) { - return _this._yScale.scale(d.y + d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); - }; - var y0Function = function (d) { - return _this._yScale.scale(d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); - }; - + var yFunction = function (d) { return _this._yScale.scale(d.y + d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); }; + var y0Function = function (d) { return _this._yScale.scale(d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); }; delete attrToProjector["x"]; delete attrToProjector["y0"]; delete attrToProjector["y"]; - attrToProjector["d"] = d3.svg.area().x(xFunction).y0(y0Function).y1(yFunction); - // Align fill with first index var fillProjector = attrToProjector["fill"]; - attrToProjector["fill"] = function (d, i) { - return fillProjector(d[0], i); - }; - + attrToProjector["fill"] = function (d, i) { return fillProjector(d[0], i); }; return attrToProjector; }; return StackedArea; @@ -8080,71 +7317,52 @@ var Plottable; var StackedBar = (function (_super) { __extends(StackedBar, _super); /** - * Constructs a StackedBar plot. - * A StackedBarPlot is a plot that plots several bar plots stacking on top of each - * other. - * @constructor - * @param {Scale} xScale the x scale of the plot. - * @param {Scale} yScale the y scale of the plot. - * @param {boolean} isVertical if the plot if vertical. - */ + * Constructs a StackedBar plot. + * A StackedBarPlot is a plot that plots several bar plots stacking on top of each + * other. + * @constructor + * @param {Scale} xScale the x scale of the plot. + * @param {Scale} yScale the y scale of the plot. + * @param {boolean} isVertical if the plot if vertical. + */ function StackedBar(xScale, yScale, isVertical) { - if (typeof isVertical === "undefined") { isVertical = true; } + if (isVertical === void 0) { isVertical = true; } this._isVertical = isVertical; // Has to be set before super() this._baselineValue = 0; this._barAlignmentFactor = 0.5; _super.call(this, xScale, yScale); this.classed("bar-plot", true); - this.project("fill", function () { - return Plottable.Core.Colors.INDIGO; - }); + this.project("fill", function () { return Plottable.Core.Colors.INDIGO; }); this.baseline(this._baselineValue); this._isVertical = isVertical; } StackedBar.prototype._setup = function () { Plottable.Abstract.NewStyleBarPlot.prototype._setup.call(this); }; - StackedBar.prototype._getAnimator = function (drawer, index) { var animator = new Plottable.Animator.Rect(); animator.delay(animator.duration() * index); return animator; }; - StackedBar.prototype._getDrawer = function (key) { return Plottable.Abstract.NewStyleBarPlot.prototype._getDrawer.apply(this, [key]); }; - StackedBar.prototype._generateAttrToProjector = function () { var _this = this; var attrToProjector = Plottable.Abstract.NewStyleBarPlot.prototype._generateAttrToProjector.apply(this); - var primaryAttr = this._isVertical ? "y" : "x"; var primaryScale = this._isVertical ? this._yScale : this._xScale; var primaryAccessor = this._projectors[primaryAttr].accessor; - var getStart = function (d) { - return primaryScale.scale(d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); - }; - var getEnd = function (d) { - return primaryScale.scale(primaryAccessor(d) + d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); - }; - - var heightF = function (d) { - return Math.abs(getEnd(d) - getStart(d)); - }; + var getStart = function (d) { return primaryScale.scale(d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); }; + var getEnd = function (d) { return primaryScale.scale(primaryAccessor(d) + d["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]); }; + var heightF = function (d) { return Math.abs(getEnd(d) - getStart(d)); }; var widthF = attrToProjector["width"]; attrToProjector["height"] = this._isVertical ? heightF : widthF; attrToProjector["width"] = this._isVertical ? widthF : heightF; - - var attrFunction = function (d) { - return primaryAccessor(d) < 0 ? getStart(d) : getEnd(d); - }; - attrToProjector[primaryAttr] = function (d) { - return _this._isVertical ? attrFunction(d) : attrFunction(d) - heightF(d); - }; + var attrFunction = function (d) { return primaryAccessor(d) < 0 ? getStart(d) : getEnd(d); }; + attrToProjector[primaryAttr] = function (d) { return _this._isVertical ? attrFunction(d) : attrFunction(d) - heightF(d); }; return attrToProjector; }; - StackedBar.prototype._paint = function () { _super.prototype._paint.call(this); var primaryScale = this._isVertical ? this._yScale : this._xScale; @@ -8157,19 +7375,15 @@ var Plottable; }; this._baseline.attr(baselineAttr); }; - StackedBar.prototype.baseline = function (value) { return Plottable.Abstract.NewStyleBarPlot.prototype.baseline.apply(this, [value]); }; - StackedBar.prototype._updateDomainer = function (scale) { return Plottable.Abstract.NewStyleBarPlot.prototype._updateDomainer.apply(this, [scale]); }; - StackedBar.prototype._updateXDomainer = function () { return Plottable.Abstract.NewStyleBarPlot.prototype._updateXDomainer.apply(this); }; - StackedBar.prototype._updateYDomainer = function () { return Plottable.Abstract.NewStyleBarPlot.prototype._updateYDomainer.apply(this); }; @@ -8187,9 +7401,9 @@ var Plottable; (function (Plottable) { (function (Animator) { /** - * An animator implementation with no animation. The attributes are - * immediately set on the selection. - */ + * An animator implementation with no animation. The attributes are + * immediately set on the selection. + */ var Null = (function () { function Null() { } @@ -8208,14 +7422,14 @@ var Plottable; (function (Plottable) { (function (Animator) { /** - * The base animator implementation with easing, duration, and delay. - */ + * The base animator implementation with easing, duration, and delay. + */ var Base = (function () { /** - * Constructs the default animator - * - * @constructor - */ + * Constructs the default animator + * + * @constructor + */ function Base() { this._duration = Base.DEFAULT_DURATION_MILLISECONDS; this._delay = Base.DEFAULT_DELAY_MILLISECONDS; @@ -8224,37 +7438,44 @@ var Plottable; Base.prototype.animate = function (selection, attrToProjector) { return selection.transition().ease(this.easing()).duration(this.duration()).delay(this.delay()).attr(attrToProjector); }; - Base.prototype.duration = function (duration) { if (duration === undefined) { return this._duration; - } else { + } + else { this._duration = duration; return this; } }; - Base.prototype.delay = function (delay) { if (delay === undefined) { return this._delay; - } else { + } + else { this._delay = delay; return this; } }; - Base.prototype.easing = function (easing) { if (easing === undefined) { return this._easing; - } else { + } + else { this._easing = easing; return this; } }; + /** + * The default duration of the animation in milliseconds + */ Base.DEFAULT_DURATION_MILLISECONDS = 300; - + /** + * The default starting delay of the animation in milliseconds + */ Base.DEFAULT_DELAY_MILLISECONDS = 0; - + /** + * The default easing of the animation + */ Base.DEFAULT_EASING = "exp-out"; return Base; })(); @@ -8274,38 +7495,63 @@ 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. - */ + * An animator that delays the animation of the attributes using the index + * of the selection data. + * + * The maximum delay between animations can be configured with maxIterativeDelay. + * + * The maximum total animation duration can be configured with maxTotalDuration. + * maxTotalDuration does not set actual total animation duration. + * + * The actual interval delay is calculated by following formula: + * min(maxIterativeDelay(), + * max(totalDurationLimit() - duration(), 0) / ) + */ var IterativeDelay = (function (_super) { __extends(IterativeDelay, _super); /** - * Constructs an animator with a start delay between each selection animation - * - * @constructor - */ + * Constructs an animator with a start delay between each selection animation + * + * @constructor + */ function IterativeDelay() { _super.call(this); - this._iterativeDelay = IterativeDelay.DEFAULT_ITERATIVE_DELAY_MILLISECONDS; + this._maxIterativeDelay = IterativeDelay.DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS; + this._maxTotalDuration = IterativeDelay.DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS; } IterativeDelay.prototype.animate = function (selection, attrToProjector) { var _this = this; - return selection.transition().ease(this.easing()).duration(this.duration()).delay(function (d, i) { - return _this.delay() + _this.iterativeDelay() * i; - }).attr(attrToProjector); + var numberOfIterations = selection[0].length; + var maxDelayForLastIteration = Math.max(this.maxTotalDuration() - this.duration(), 0); + var adjustedIterativeDelay = Math.min(this.maxIterativeDelay(), maxDelayForLastIteration / numberOfIterations); + return selection.transition().ease(this.easing()).duration(this.duration()).delay(function (d, i) { return _this.delay() + adjustedIterativeDelay * i; }).attr(attrToProjector); }; - - IterativeDelay.prototype.iterativeDelay = function (iterDelay) { - if (iterDelay === undefined) { - return this._iterativeDelay; - } else { - this._iterativeDelay = iterDelay; + IterativeDelay.prototype.maxIterativeDelay = function (maxIterDelay) { + if (maxIterDelay === undefined) { + return this._maxIterativeDelay; + } + else { + this._maxIterativeDelay = maxIterDelay; return this; } }; - IterativeDelay.DEFAULT_ITERATIVE_DELAY_MILLISECONDS = 15; + IterativeDelay.prototype.maxTotalDuration = function (maxDuration) { + if (maxDuration == null) { + return this._maxTotalDuration; + } + else { + this._maxTotalDuration = maxDuration; + return this; + } + }; + /** + * The default maximum start delay between each start of an animation + */ + IterativeDelay.DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS = 15; + /** + * The default maximum total animation duration + */ + IterativeDelay.DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS = 600; return IterativeDelay; })(Animator.Base); Animator.IterativeDelay = IterativeDelay; @@ -8324,47 +7570,36 @@ var Plottable; (function (Plottable) { (function (Animator) { /** - * The default animator implementation with easing, duration, and delay. - */ + * The default animator implementation with easing, duration, and delay. + */ var Rect = (function (_super) { __extends(Rect, _super); function Rect(isVertical, isReverse) { - if (typeof isVertical === "undefined") { isVertical = true; } - if (typeof isReverse === "undefined") { isReverse = false; } + if (isVertical === void 0) { isVertical = true; } + if (isReverse === void 0) { isReverse = false; } _super.call(this); this.isVertical = isVertical; this.isReverse = isReverse; } Rect.prototype.animate = function (selection, attrToProjector) { var startAttrToProjector = {}; - Rect.ANIMATED_ATTRIBUTES.forEach(function (attr) { - return startAttrToProjector[attr] = attrToProjector[attr]; - }); - + Rect.ANIMATED_ATTRIBUTES.forEach(function (attr) { return startAttrToProjector[attr] = attrToProjector[attr]; }); startAttrToProjector[this.getMovingAttr()] = this._startMovingProjector(attrToProjector); - startAttrToProjector[this.getGrowingAttr()] = function () { - return 0; - }; - + startAttrToProjector[this.getGrowingAttr()] = function () { return 0; }; selection.attr(startAttrToProjector); return _super.prototype.animate.call(this, selection, attrToProjector); }; - Rect.prototype._startMovingProjector = function (attrToProjector) { if (this.isVertical === this.isReverse) { return attrToProjector[this.getMovingAttr()]; } var movingAttrProjector = attrToProjector[this.getMovingAttr()]; var growingAttrProjector = attrToProjector[this.getGrowingAttr()]; - return function (d, i) { - return movingAttrProjector(d, i) + growingAttrProjector(d, i); - }; + return function (d, i) { return movingAttrProjector(d, i) + growingAttrProjector(d, i); }; }; - Rect.prototype.getGrowingAttr = function () { return this.isVertical ? "height" : "width"; }; - Rect.prototype.getMovingAttr = function () { return this.isVertical ? "y" : "x"; }; @@ -8380,18 +7615,15 @@ var Plottable; var Plottable; (function (Plottable) { (function (Core) { - - /** - * A module for listening to keypresses on the document. - */ + * A module for listening to keypresses on the document. + */ (function (KeyEventListener) { var _initialized = false; var _callbacks = []; - /** - * Turns on key listening. - */ + * Turns on key listening. + */ function initialize() { if (_initialized) { return; @@ -8400,32 +7632,27 @@ var Plottable; _initialized = true; } KeyEventListener.initialize = initialize; - /** - * When a key event occurs with the key corresponding te keyCod, call cb. - * - * @param {number} keyCode The javascript key code to call cb on. - * @param {IKeyEventListener} cb Will be called when keyCode key event - * occurs. - */ + * When a key event occurs with the key corresponding te keyCod, call cb. + * + * @param {number} keyCode The javascript key code to call cb on. + * @param {IKeyEventListener} cb Will be called when keyCode key event + * occurs. + */ 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); }); @@ -8487,16 +7714,14 @@ var Plottable; _this._callback({ x: x, y: y }); }); }; - Click.prototype._listenTo = function () { return "click"; }; - /** - * Sets a callback to be called when a click is received. - * - * @param {(p: Point) => any} cb Callback that takes the pixel position of the click event. - */ + * Sets a callback to be called when a click is received. + * + * @param {(p: Point) => any} cb Callback that takes the pixel position of the click event. + */ Click.prototype.callback = function (cb) { this._callback = cb; return this; @@ -8504,7 +7729,6 @@ var Plottable; return Click; })(Plottable.Abstract.Interaction); Interaction.Click = Click; - var DoubleClick = (function (_super) { __extends(DoubleClick, _super); function DoubleClick() { @@ -8533,14 +7757,14 @@ var Plottable; var Key = (function (_super) { __extends(Key, _super); /** - * Creates a KeyInteraction. - * - * KeyInteraction listens to key events that occur while the component is - * moused over. - * - * @constructor - * @param {number} keyCode The key code to listen for. - */ + * Creates a KeyInteraction. + * + * KeyInteraction listens to key events that occur while the component is + * moused over. + * + * @constructor + * @param {number} keyCode The key code to listen for. + */ function Key(keyCode) { _super.call(this); this.activated = false; @@ -8555,21 +7779,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 a callback to be called when the designated key is pressed and the - * user is moused over the component. - * - * @param {() => any} cb Callback to be called. - * @returns The calling Key. - */ + * Sets a callback to be called when the designated key is pressed and the + * user is moused over the component. + * + * @param {() => any} cb Callback to be called. + * @returns The calling Key. + */ Key.prototype.callback = function (cb) { this._callback = cb; return this; @@ -8594,15 +7816,15 @@ var Plottable; var PanZoom = (function (_super) { __extends(PanZoom, _super); /** - * Creates a PanZoomInteraction. - * - * The allows you to move around and zoom in on a plot, interactively. It - * does so by changing the xScale and yScales' domains repeatedly. - * - * @constructor - * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. - * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. - */ + * Creates a PanZoomInteraction. + * + * The allows you to move around and zoom in on a plot, interactively. It + * does so by changing the xScale and yScales' domains repeatedly. + * + * @constructor + * @param {QuantitativeScale} [xScale] The X scale to update on panning/zooming. + * @param {QuantitativeScale} [yScale] The Y scale to update on panning/zooming. + */ function PanZoom(xScale, yScale) { var _this = this; _super.call(this); @@ -8617,30 +7839,24 @@ 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(); }); } /** - * Sets the scales back to their original domains. - */ + * Sets the scales back to their original domains. + */ 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 (component, hitBox) { _super.prototype._anchor.call(this, component, 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 @@ -8678,38 +7894,31 @@ var Plottable; _super.prototype._anchor.call(this, barPlot, hitBox); this.plotIsVertical = this._componentToListenTo._isVertical; this.dispatcher = new Plottable.Dispatcher.Mouse(this._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 { + return; // no message if bar is the same + } + 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) { @@ -8717,53 +7926,47 @@ var Plottable; } 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} callback The callback to be called. - * The callback will be passed the data from the hovered-over bar. - * @return {BarHover} The calling BarHover. - */ + * Attaches an callback to be called when the user mouses over a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} callback The callback to be called. + * The callback will be passed the data from the hovered-over bar. + * @return {BarHover} The calling 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} callback The callback to be called. - * The callback will be passed the data from the last-hovered bar. - * @return {BarHover} The calling BarHover. - */ + * Attaches a callback to be called when the user mouses off of a bar. + * + * @param {(datum: any, bar: D3.Selection) => any} callback The callback to be called. + * The callback will be passed the data from the last-hovered bar. + * @return {BarHover} The calling BarHover. + */ BarHover.prototype.onUnhover = function (callback) { this.unhoverCallback = callback; return this; @@ -8788,8 +7991,8 @@ var Plottable; var Drag = (function (_super) { __extends(Drag, _super); /** - * Constructs a Drag. A Drag will signal its callbacks on mouse drag. - */ + * Constructs a Drag. A Drag will signal its callbacks on mouse drag. + */ function Drag() { var _this = this; _super.call(this); @@ -8797,74 +8000,59 @@ var Plottable; 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 width = this._componentToListenTo.width(); var height = this._componentToListenTo.height(); - // 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); - }; - }; + var constraintFunction = function (min, max) { return function (x) { return Math.min(Math.max(x, min), max); }; }; this.constrainX = constraintFunction(0, width); this.constrainY = constraintFunction(0, height); }; - 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] }; @@ -8872,7 +8060,6 @@ var Plottable; this.ondrag(startLocation, endLocation); } }; - Drag.prototype._dragend = function () { if (!this.dragInitialized) { return; @@ -8880,7 +8067,6 @@ 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] }; @@ -8888,26 +8074,23 @@ var Plottable; this.ondragend(startLocation, endLocation); } }; - Drag.prototype._anchor = function (component, hitBox) { _super.prototype._anchor.call(this, component, hitBox); hitBox.call(this.dragBehavior); return this; }; - /** - * Sets up so that the xScale and yScale that are passed have their - * domains automatically changed as you zoom. - * - * @param {QuantitativeScale} xScale The scale along the x-axis. - * @param {QuantitativeScale} yScale The scale along the y-axis. - * @returns {Drag} The calling Drag. - */ + * Sets up so that the xScale and yScale that are passed have their + * domains automatically changed as you zoom. + * + * @param {QuantitativeScale} xScale The scale along the x-axis. + * @param {QuantitativeScale} yScale The scale along the y-axis. + * @returns {Drag} The calling Drag. + */ Drag.prototype.setupZoomCallback = function (xScale, yScale) { var xDomainOriginal = xScale != null ? xScale.domain() : null; var yDomainOriginal = yScale != null ? yScale.domain() : null; var resetOnNextClick = false; - function callback(upperLeft, lowerRight) { if (upperLeft == null || lowerRight == null) { if (resetOnNextClick) { @@ -8953,51 +8136,49 @@ var Plottable; (function (Plottable) { (function (Interaction) { /** - * A DragBox is an interaction that automatically draws a box across the - * element you attach it to when you drag. - */ + * A DragBox is an interaction that automatically draws a box across the + * element you attach it to when you drag. + */ var DragBox = (function (_super) { __extends(DragBox, _super); function DragBox() { _super.apply(this, arguments); /** - * Whether or not dragBox has been rendered in a visible area. - */ + * Whether or not dragBox has been rendered in a visible area. + */ this.boxIsDrawn = false; } DragBox.prototype._dragstart = function () { _super.prototype._dragstart.call(this); this.clearBox(); }; - /** - * Clears the highlighted drag-selection box drawn by the DragBox. - * - * @returns {DragBox} The calling DragBox. - */ + * Clears the highlighted drag-selection box drawn by the DragBox. + * + * @returns {DragBox} The calling DragBox. + */ DragBox.prototype.clearBox = function () { if (this.dragBox == null) { return; - } + } // HACKHACK #593 this.dragBox.attr("height", 0).attr("width", 0); this.boxIsDrawn = false; return this; }; - /** - * Set where the box is draw explicitly. - * - * @param {number} x0 Left. - * @param {number} x1 Right. - * @param {number} y0 Top. - * @param {number} y1 Bottom. - * - * @returns {DragBox} The calling DragBox. - */ + * Set where the box is draw explicitly. + * + * @param {number} x0 Left. + * @param {number} x1 Right. + * @param {number} y0 Top. + * @param {number} y1 Bottom. + * + * @returns {DragBox} The calling DragBox. + */ DragBox.prototype.setBox = function (x0, x1, y0, y1) { if (this.dragBox == null) { return; - } + } // HACKHACK #593 var w = Math.abs(x0 - x1); var h = Math.abs(y0 - y1); var xo = Math.min(x0, x1); @@ -9006,7 +8187,6 @@ var Plottable; this.boxIsDrawn = (w > 0 && h > 0); return this; }; - DragBox.prototype._anchor = function (component, hitBox) { _super.prototype._anchor.call(this, component, hitBox); var cname = DragBox.CLASS_DRAG_BOX; @@ -9041,7 +8221,6 @@ 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.height()); return this; @@ -9098,7 +8277,6 @@ 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.width(), y0, y1); return this; @@ -9123,10 +8301,10 @@ var Plottable; var Dispatcher = (function (_super) { __extends(Dispatcher, _super); /** - * Constructs a Dispatcher with the specified target. - * - * @param {D3.Selection} target The selection to listen for events on. - */ + * Constructs 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 = {}; @@ -9146,19 +8324,17 @@ var Plottable; } return this; }; - /** - * Gets a namespaced version of the event name. - */ + * 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. - */ + * 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) { @@ -9169,15 +8345,13 @@ 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. - */ + * 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; @@ -9206,26 +8380,23 @@ var Plottable; var Mouse = (function (_super) { __extends(Mouse, _super); /** - * Constructs a Mouse Dispatcher with the specified target. - * - * @param {D3.Selection} target The selection to listen for events on. - */ + * Constructs a Mouse Dispatcher with the specified target. + * + * @param {D3.Selection} target The selection to listen for events on. + */ function Mouse(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()); @@ -9239,7 +8410,6 @@ var Plottable; y: xy[1] }; }; - Mouse.prototype.mouseover = function (callback) { if (callback === undefined) { return this._mouseover; @@ -9247,7 +8417,6 @@ var Plottable; this._mouseover = callback; return this; }; - Mouse.prototype.mousemove = function (callback) { if (callback === undefined) { return this._mousemove; @@ -9255,7 +8424,6 @@ var Plottable; this._mousemove = callback; return this; }; - Mouse.prototype.mouseout = function (callback) { if (callback === undefined) { return this._mouseout; diff --git a/plottable.min.js b/plottable.min.js index a975c3165b..2bc82b137b 100644 --- a/plottable.min.js +++ b/plottable.min.js @@ -1,5 +1,5 @@ -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=d3.map();return a.forEach(function(a){c.set(a,b(a))}),c}function i(a,b){var c=f(a);return function(a,d){return c(a,d,b.dataset().metadata())}}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?a.Methods.max:d3.sum,q=h?d3.sum:a.Methods.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(b,c,d){var e=h(b),f=e.map(d),g=a.Methods.max(f);return c>=g}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){var b;try{b=a.node().getBBox()}catch(c){b={x:0,y:0,width:0,height:0}}return b}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,function(b){function c(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 b=f(Math.abs(a));return e&&l(Math.abs(a),b)?"":(""!==b&&(d?b=c+b:b+=c,0>a&&(b="-"+b)),b)}}function d(a,b){return"undefined"==typeof a&&(a=3),"undefined"==typeof b&&(b=!0),k(a),function(c){var d=c.toFixed(a);return b&&l(c,d)?"":d}}function e(a,b){return"undefined"==typeof a&&(a=3),"undefined"==typeof b&&(b=!0),k(a),function(c){if("number"==typeof c){var d=Math.pow(10,a),e=String(Math.round(c*d)/d);return b&&l(c,e)?"":e}return String(c)}}function f(){return function(a){return String(a)}}function g(a,c){"undefined"==typeof a&&(a=0),"undefined"==typeof c&&(c=!0);var d=b.fixed(a,c);return function(a){var b=100*a,e=a.toString(),f=Math.pow(10,e.length-(e.indexOf(".")+1));b=parseInt((b*f).toString(),10)/f;var g=d(b);return c&&l(b,g)?"":(""!==g&&(g+="%"),g)}}function h(a){return"undefined"==typeof a&&(a=3),k(a),function(b){return d3.format("."+a+"s")(b)}}function i(){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)}}function j(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}}function k(a){if(0>a||a>20)throw new RangeError("Formatter precision must be between 0 and 20")}function l(a,b){return a!==parseFloat(b)}b.currency=c,b.fixed=d,b.general=e,b.identity=f,b.percentage=g,b.siSuffix=h,b.time=i,b.relativeDate=j}(a.Formatters||(a.Formatters={}));a.Formatters}(Plottable||(Plottable={}));var Plottable;!function(a){a.version="0.31.0"}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){}return a.CORAL_RED="#fd373e",a.INDIGO="#5279c7",a.ROBINS_EGG_BLUE="#06cccc",a.FERN="#63c261",a.BURNING_ORANGE="#ff7939",a.ROYAL_HEATH="#962565",a.CONIFER="#99ce50",a.CERISE_RED="#db2e65",a.BRIGHT_SUN="#fad419",a.JACARTA="#2c2b6f",a.PLOTTABLE_COLORS=[a.INDIGO,a.CORAL_RED,a.FERN,a.BRIGHT_SUN,a.JACARTA,a.BURNING_ORANGE,a.CERISE_RED,a.CONIFER,a.ROYAL_HEATH,a.ROBINS_EGG_BLUE],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;c0){var f=d.valueOf();return d instanceof Date?[f-b.ONE_DAY,f+b.ONE_DAY]:[f-b.PADDING_FOR_IDENTICAL_DOMAIN,f+b.PADDING_FOR_IDENTICAL_DOMAIN]}if(a.domain()[0]===a.domain()[1])return c;var g=this.padProportion/2,h=a.invert(a.scale(d)-(a.scale(e)-a.scale(d))*g),i=a.invert(a.scale(e)+(a.scale(e)-a.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]},b.prototype.niceDomain=function(a,b){return this.doNice?a._niceDomain(b,this.niceCount):b},b.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)},b.PADDING_FOR_IDENTICAL_DOMAIN=1,b.ONE_DAY=864e5,b}();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),this._autoDomainAutomatically=!0,this.broadcaster=new a.Core.Broadcaster(this),this._rendererAttrID2Extent={},this._typeCoercer=function(a){return a},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,c),this._numTicks=10,this._PADDING_FOR_IDENTICAL_DOMAIN=1,this._userSetDomainer=!1,this._domainer=new a.Domainer,this._typeCoercer=function(a){return+a}}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"undefined"==typeof a&&(a=this.numTicks()),this._d3Scale.ticks(a)},c.prototype.numTicks=function(a){return null==a?this._numTicks:(this._numTicks=a,this)},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._numTicks=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(b)),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.uniq(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(b,c){var d=this.adjustedLog(a._Util.Methods.min(this.untransformedDomain)),e=this.adjustedLog(a._Util.Methods.max(this.untransformedDomain)),f=this.adjustedLog(b),g=this.adjustedLog(c),h=(g-f)/(e-d),i=Math.ceil(h*this._numTicks);return i},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._typeCoercer=function(a){return null!=a&&a.toString?a.toString():a},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.range(this.range()),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),this._typeCoercer=function(a){return a&&a._isAMomentObject||a instanceof Date?a:new Date(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._setDomain=function(a){return a=a.map(this._typeCoercer),b.prototype._setDomain.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(b){function c(a,d){"undefined"==typeof a&&(a="reds"),"undefined"==typeof d&&(d="linear"),this._colorRange=this._resolveColorValues(a),this._scaleType=d,b.call(this,c.getD3InterpolatedScale(this._colorRange,this._scaleType))}return __extends(c,b),c.getD3InterpolatedScale=function(a,b){var d;switch(b){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 "+b);return d.range([0,1]).interpolate(c.interpolateColors(a))},c.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)}}},c.prototype.colorRange=function(a){return null==a?this._colorRange:(this._colorRange=this._resolveColorValues(a),this._resetScale(),this)},c.prototype.scaleType=function(a){return null==a?this._scaleType:(this._scaleType=a,this._resetScale(),this)},c.prototype._resetScale=function(){this._d3Scale=c.getD3InterpolatedScale(this._colorRange,this._scaleType),this._autoDomainIfAutomaticMode(),this.broadcaster.broadcast()},c.prototype._resolveColorValues=function(a){return a instanceof Array?a:null!=c.COLOR_SCALES[a]?c.COLOR_SCALES[a]:c.COLOR_SCALES.reds},c.prototype.autoDomain=function(){var b=this._getAllExtents();return b.length>0&&this._setDomain([a._Util.Methods.min(b,function(a){return a[0]}),a._Util.Methods.max(b,function(a){return a[1]})]),this},c.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"]},c}(a.Abstract.Scale);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(b){var c=function(){function b(a){this.key=a}return b.prototype.remove=function(){null!=this._renderArea&&this._renderArea.remove()},b.prototype.draw=function(b,c,d){throw"undefined"==typeof d&&(d=new a.Animator.Null),new Error("Abstract Method Not Implemented")},b}();b._Drawer=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(){b.apply(this,arguments)}return __extends(c,b),c.prototype.draw=function(b,c,d){"undefined"==typeof d&&(d=new a.Animator.Null);var e="path",f=this._renderArea.selectAll(e).data(b);f.enter().append(e),f.classed("arc",!0),d.animate(f,c),f.exit().remove()},c}(a.Abstract._Drawer);b.Arc=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(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype.draw=function(a,b){var c="path",d=this._renderArea.selectAll(c).data([a]);d.enter().append(c),d.attr(b).classed("area",!0),d.exit().remove()},b}(a.Abstract._Drawer);b.Area=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(b){function c(){b.apply(this,arguments)}return __extends(c,b),c.prototype.draw=function(b,c,d){"undefined"==typeof d&&(d=new a.Animator.Null);var e="rect",f=this._renderArea.selectAll(e).data(b);f.enter().append(e),d.animate(f,c),f.exit().remove()},c}(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(b){function c(){b.apply(this,arguments),this.clipPathEnabled=!1,this._xAlignProportion=0,this._yAlignProportion=0,this._fixedHeightFlag=!1,this._fixedWidthFlag=!1,this._isSetup=!1,this._isAnchored=!1,this.interactionsToRegister=[],this.boxes=[],this.isTopLevelComponent=!1,this._width=0,this._height=0,this._xOffset=0,this._yOffset=0,this.cssClasses=["component"],this.removed=!1}return __extends(c,b),c.prototype._anchor=function(a){if(this.removed)throw new Error("Can't reuse remove()-ed components!");"svg"===a.node().nodeName&&(this.rootSVG=a,this.rootSVG.classed("plottable",!0),this.rootSVG.style("overflow","visible"),this.isTopLevelComponent=!0),null!=this._element?a.node().appendChild(this._element.node()):(this._element=a.append("g"),this._setup()),this._isAnchored=!0},c.prototype._setup=function(){var a=this;this._isSetup||(this.cssClasses.forEach(function(b){a._element.classed(b,!0)}),this.cssClasses=null,this._backgroundContainer=this._element.append("g").classed("background-container",!0),this._content=this._element.append("g").classed("content",!0),this._foregroundContainer=this._element.append("g").classed("foreground-container",!0),this.boxContainer=this._element.append("g").classed("box-container",!0),this.clipPathEnabled&&this.generateClipPath(),this.addBox("bounding-box"),this.interactionsToRegister.forEach(function(b){return a.registerInteraction(b)}),this.interactionsToRegister=null,this.isTopLevelComponent&&this.autoResize(c.AUTORESIZE_BY_DEFAULT),this._isSetup=!0)},c.prototype._requestedSpace=function(){return{width:0,height:0,wantsWidth:!1,wantsHeight:!1}},c.prototype._computeLayout=function(b,c,d,e){var f=this;if(null==b||null==c||null==d||null==e){if(null==this._element)throw new Error("anchor must be called before computeLayout");if(!this.isTopLevelComponent)throw new Error("null arguments cannot be passed to _computeLayout() on a non-root node");b=0,c=0,null==this.rootSVG.attr("width")&&this.rootSVG.attr("width","100%"),null==this.rootSVG.attr("height")&&this.rootSVG.attr("height","100%");var g=this.rootSVG.node();d=a._Util.DOM.getElementWidth(g),e=a._Util.DOM.getElementHeight(g)}this.xOrigin=b,this.yOrigin=c;var h=this.xOrigin,i=this.yOrigin,j=this._requestedSpace(d,e);h+=(d-j.width)*this._xAlignProportion,h+=this._xOffset,this._isFixedWidth()&&(d=Math.min(d,j.width)),i+=(e-j.height)*this._yAlignProportion,i+=this._yOffset,this._isFixedHeight()&&(e=Math.min(e,j.height)),this._width=d,this._height=e,this._element.attr("transform","translate("+h+","+i+")"),this.boxes.forEach(function(a){return a.attr("width",f.width()).attr("height",f.height())})},c.prototype._render=function(){this._isAnchored&&this._isSetup&&a.Core.RenderController.registerToRender(this)},c.prototype._scheduleComputeLayout=function(){this._isAnchored&&this._isSetup&&a.Core.RenderController.registerToComputeLayout(this)},c.prototype._doRender=function(){},c.prototype._invalidateLayout=function(){this._isAnchored&&this._isSetup&&(this.isTopLevelComponent?this._scheduleComputeLayout():this._parent._invalidateLayout())},c.prototype.renderTo=function(b){if(null!=b){var c;if(c="function"==typeof b.node?b:d3.select(b),!c.node()||"svg"!==c.node().nodeName)throw new Error("Plottable requires a valid SVG to renderTo");this._anchor(c)}if(null==this._element)throw new Error("If a component has never been rendered before, then renderTo must be given a node to render to, or a D3.Selection, or a selector string");return this._computeLayout(),this._render(),a.Core.RenderController.flush(),this},c.prototype.resize=function(a,b){if(!this.isTopLevelComponent)throw new Error("Cannot resize on non top-level component");return null!=a&&null!=b&&this._isAnchored&&this.rootSVG.attr({width:a,height:b}),this._invalidateLayout(),this},c.prototype.autoResize=function(b){return b?a.Core.ResizeBroadcaster.register(this):a.Core.ResizeBroadcaster.deregister(this),this},c.prototype.xAlign=function(a){if(a=a.toLowerCase(),"left"===a)this._xAlignProportion=0;else if("center"===a)this._xAlignProportion=.5;else{if("right"!==a)throw new Error("Unsupported alignment");this._xAlignProportion=1}return this._invalidateLayout(),this},c.prototype.yAlign=function(a){if(a=a.toLowerCase(),"top"===a)this._yAlignProportion=0;else if("center"===a)this._yAlignProportion=.5;else{if("bottom"!==a)throw new Error("Unsupported alignment");this._yAlignProportion=1}return this._invalidateLayout(),this},c.prototype.xOffset=function(a){return this._xOffset=a,this._invalidateLayout(),this},c.prototype.yOffset=function(a){return this._yOffset=a,this._invalidateLayout(),this},c.prototype.addBox=function(a,b){if(null==this._element)throw new Error("Adding boxes before anchoring is currently disallowed");var b=null==b?this.boxContainer:b,c=b.append("rect");return null!=a&&c.classed(a,!0),this.boxes.push(c),null!=this.width()&&null!=this.height()&&c.attr("width",this.width()).attr("height",this.height()),c},c.prototype.generateClipPath=function(){var a=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;this._element.attr("clip-path","url("+a+"#clipPath"+this._plottableID+")");var b=this.boxContainer.append("clipPath").attr("id","clipPath"+this._plottableID);this.addBox("clip-rect",b)},c.prototype.registerInteraction=function(a){return this._element?(this.hitBox||(this.hitBox=this.addBox("hit-box"),this.hitBox.style("fill","#ffffff").style("opacity",0)),a._anchor(this,this.hitBox)):this.interactionsToRegister.push(a),this},c.prototype.classed=function(a,b){if(null==b)return null==a?!1:null==this._element?-1!==this.cssClasses.indexOf(a):this._element.classed(a);if(null==a)return this;if(null==this._element){var c=this.cssClasses.indexOf(a);b&&-1===c?this.cssClasses.push(a):b||-1===c||this.cssClasses.splice(c,1)}else this._element.classed(a,b);return this},c.prototype._isFixedWidth=function(){return this._fixedWidthFlag},c.prototype._isFixedHeight=function(){return this._fixedHeightFlag},c.prototype.merge=function(b){var c;if(this._isSetup||this._isAnchored)throw new Error("Can't presently merge a component that's already been anchored");return a.Component.Group.prototype.isPrototypeOf(b)?(c=b,c._addComponent(this,!0),c):c=new a.Component.Group([this,b])},c.prototype.detach=function(){return this._isAnchored&&this._element.remove(),null!=this._parent&&this._parent._removeComponent(this),this._isAnchored=!1,this._parent=null,this},c.prototype.remove=function(){this.removed=!0,this.detach(),a.Core.ResizeBroadcaster.deregister(this)},c.prototype.width=function(){return this._width},c.prototype.height=function(){return this._height},c.AUTORESIZE_BY_DEFAULT=!0,c}(b.PlottableObject);b.Component=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(a){function b(){a.apply(this,arguments),this._components=[]}return __extends(b,a),b.prototype._anchor=function(b){var c=this;a.prototype._anchor.call(this,b),this._components.forEach(function(a){return a._anchor(c._content)})},b.prototype._render=function(){this._components.forEach(function(a){return a._render()})},b.prototype._removeComponent=function(a){var b=this._components.indexOf(a);b>=0&&(this._components.splice(b,1),this._invalidateLayout())},b.prototype._addComponent=function(a,b){return"undefined"==typeof b&&(b=!1),!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(b){function c(a){"undefined"==typeof a&&(a=[]);var c=this;b.call(this),this.classed("component-group",!0),a.forEach(function(a){return c._addComponent(a)})}return __extends(c,b),c.prototype._requestedSpace=function(b,c){var d=this._components.map(function(a){return a._requestedSpace(b,c)});return{width:a._Util.Methods.max(d,function(a){return a.width}),height:a._Util.Methods.max(d,function(a){return a.height}),wantsWidth:d.map(function(a){return a.wantsWidth}).some(function(a){return a}),wantsHeight:d.map(function(a){return a.wantsHeight}).some(function(a){return a})}},c.prototype.merge=function(a){return this._addComponent(a),this},c.prototype._computeLayout=function(a,c,d,e){var f=this;return b.prototype._computeLayout.call(this,a,c,d,e),this._components.forEach(function(a){a._computeLayout(0,0,f.width(),f.height())}),this},c.prototype._isFixedWidth=function(){return this._components.every(function(a){return a._isFixedWidth()})},c.prototype._isFixedHeight=function(){return this._components.every(function(a){return a._isFixedHeight()})},c}(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(c){function d(b,d,e){"undefined"==typeof e&&(e=a.Formatters.identity());var f=this;if(c.call(this),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=0,d=0;return this._isHorizontal()?(null==this._computedHeight&&this._computeHeight(),d=this._computedHeight+this._gutter):(null==this._computedWidth&&this._computeWidth(),c=this._computedWidth+this._gutter),{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._rescale=function(){this._render()},d.prototype._computeLayout=function(a,b,d,e){c.prototype._computeLayout.call(this,a,b,d,e),this._scale.range(this._isHorizontal()?[0,this.width()]:[this.height(),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.width();break;case"top":a.x2=this.width(),a.y1=this.height(),a.y2=this.height();break;case"left":a.x1=this.width(),a.x2=this.width(),a.y2=this.height();break;case"right":a.y2=this.height()}return a},d.prototype._generateTickMarkAttrHash=function(a){var b=this;"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.height(),c.y2=this.height()-e;break;case"left":c.x1=this.width(),c.x2=this.width()-e;break;case"right":c.x2=e}return c},d.prototype._invalidateLayout=function(){this._computedWidth=null,this._computedHeight=null,c.prototype._invalidateLayout.call(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.width())&&Math.floor(b.bottom)<=Math.ceil(c.top+a.height())},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.width();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.width());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.height()-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.height()-b),e.attr("y2",b)},c.prototype.generateLabellessTicks=function(b){if(!(0>b)){var d=this._getTickIntervalValues(c._minorIntervals[b]),e=this._getTickValues().concat(d),f=this._tickMarkContainer.selectAll("."+a.Abstract.Axis.TICK_MARK_CLASS).data(e);f.enter().append("line").classed(a.Abstract.Axis.TICK_MARK_CLASS,!0),f.attr(this._generateTickMarkAttrHash()),f.exit().remove(),this.adjustTickLength(this.tickLabelPadding(),c._minorIntervals[b])}},c.prototype._doRender=function(){b.prototype._doRender.call(this);var a=this.getTickLevel();this.renderTickLabels(this._minorTickLabels,c._minorIntervals[a],1),this.renderTickLabels(this._majorTickLabels,c._majorIntervals[a],2);var d=this._scale.domain(),e=this._scale.scale(d[1])-this._scale.scale(d[0]);return 1.5*this.getIntervalLength(c._minorIntervals[a])>=e&&this.generateLabellessTicks(a-1),this.adjustTickLength(this._maxLabelTickLength()/2,c._minorIntervals[a]),this.adjustTickLength(this._maxLabelTickLength(),c._majorIntervals[a]),this},c._minorIntervals=[{timeUnit:d3.time.second,step:1,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:5,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:10,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:15,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:30,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.minute,step:1,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:5,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:10,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:15,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:30,formatString:"%I:%M %p"},{timeUnit:d3.time.hour,step:1,formatString:"%I %p"},{timeUnit:d3.time.hour,step:3,formatString:"%I %p"},{timeUnit:d3.time.hour,step:6,formatString:"%I %p"},{timeUnit:d3.time.hour,step:12,formatString:"%I %p"},{timeUnit:d3.time.day,step:1,formatString:"%a %e"},{timeUnit:d3.time.day,step:1,formatString:"%e"},{timeUnit:d3.time.month,step:1,formatString:"%B"},{timeUnit:d3.time.month,step:1,formatString:"%b"},{timeUnit:d3.time.month,step:3,formatString:"%B"},{timeUnit:d3.time.month,step:6,formatString:"%B"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%y"},{timeUnit:d3.time.year,step:5,formatString:"%Y"},{timeUnit:d3.time.year,step:25,formatString:"%Y"},{timeUnit:d3.time.year,step:50,formatString:"%Y"},{timeUnit:d3.time.year,step:100,formatString:"%Y"},{timeUnit:d3.time.year,step:200,formatString:"%Y"},{timeUnit:d3.time.year,step:500,formatString:"%Y"},{timeUnit:d3.time.year,step:1e3,formatString:"%Y"}],c._majorIntervals=[{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""}],c}(a.Abstract.Axis);b.Time=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c},Plottable;!function(a){!function(b){var c=function(b){function c(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 b=this,c=this._getTickValues(),d=c.map(function(a){var c=b._formatter(a);return b.measurer(c).width}),e=a._Util.Methods.max(d);return this._computedWidth="center"===this.tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+e:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+e),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._rescale=function(){if(this._isSetup){if(!this._isHorizontal()){var a=this._computeWidth(); -if(a>this.width()||aa,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.orient=function(a){if(null==a)return this.orientation;if(a=a.toLowerCase(),"vertical-left"===a&&(a="left"),"vertical-right"===a&&(a="right"),"horizontal"!==a&&"left"!==a&&"right"!==a)throw new Error(a+" is not a valid orientation for LabelComponent");return this.orientation=a,this._invalidateLayout(),this},c.prototype._doRender=function(){b.prototype._doRender.call(this),this.textContainer.text("");var c="horizontal"===this.orientation?this.width():this.height(),d=a._Util.Text.getTruncatedText(this._text,c,this.measurer);"horizontal"===this.orientation?a._Util.Text.writeLineHorizontally(d,this.textContainer,this.width(),this.height(),this.xAlignment,this.yAlignment):a._Util.Text.writeLineVertically(d,this.textContainer,this.width(),this.height(),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.height()/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=a._Util.Methods.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.width()-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(b){function c(a){var c=this;b.call(this),this.padding=5,this.classed("legend",!0),this.scale=a,this.scale.broadcaster.registerListener(this,function(){return c._invalidateLayout()}),this.xAlign("left").yAlign("center"),this._fixedWidthFlag=!0,this._fixedHeightFlag=!0}return __extends(c,b),c.prototype.remove=function(){b.prototype.remove.call(this),this.scale.broadcaster.deregisterListener(this)},c.prototype.calculateLayoutInfo=function(b,d){var e=this,f=this._content.append("g").classed(c.LEGEND_ROW_CLASS,!0),g=(f.append("g").classed(c.LEGEND_ENTRY_CLASS,!0),a._Util.Text.getTextMeasurer(f.append("text"))),h=g(a._Util.Text.HEIGHT_TEXT).height,i=Math.max(0,b-this.padding),j=function(a){var b=h+g(a).width+e.padding;return Math.min(b,i)},k=this.scale.domain(),l=a._Util.Methods.populateMap(k,j);f.remove();var m=this.packRows(i,k,l),n=Math.floor((d-2*this.padding)/h);return n!==n&&(n=0),{textHeight:h,entryLengths:l,rows:m,numRowsToDraw:Math.max(Math.min(n,m.length),0)}},c.prototype._requestedSpace=function(b,c){var d=this.calculateLayoutInfo(b,c),e=d.rows.map(function(a){return d3.sum(a,function(a){return d.entryLengths.get(a)})}),f=a._Util.Methods.max(e);f=void 0===f?0:f;var g=this.padding+f,h=d.numRowsToDraw*d.textHeight+2*this.padding,i=d.rows.length*d.textHeight+2*this.padding;return{width:g,height:h,wantsWidth:g>b,wantsHeight:i>c}},c.prototype.packRows=function(a,b,c){var d=[[]],e=d[0],f=a;return b.forEach(function(b){var g=c.get(b);g>f&&(e=[],d.push(e),f=a),e.push(b),f-=g}),d},c.prototype._doRender=function(){var d=this;b.prototype._doRender.call(this);var e=this.calculateLayoutInfo(this.width(),this.height()),f=e.rows.slice(0,e.numRowsToDraw),g=this._content.selectAll("g."+c.LEGEND_ROW_CLASS).data(f);g.enter().append("g").classed(c.LEGEND_ROW_CLASS,!0),g.exit().remove(),g.attr("transform",function(a,b){return"translate(0, "+(b*e.textHeight+d.padding)+")"});var h=g.selectAll("g."+c.LEGEND_ENTRY_CLASS).data(function(a){return a}),i=h.enter().append("g").classed(c.LEGEND_ENTRY_CLASS,!0);i.append("circle"),i.append("g").classed("text-container",!0),h.exit().remove();var j=this.padding;g.each(function(){var a=j,b=d3.select(this).selectAll("g."+c.LEGEND_ENTRY_CLASS);b.attr("transform",function(b){var c="translate("+a+", 0)";return a+=e.entryLengths.get(b),c})}),h.select("circle").attr("cx",e.textHeight/2).attr("cy",e.textHeight/2).attr("r",.3*e.textHeight).attr("fill",function(a){return d.scale.scale(a)});var k=this.padding,l=h.select("g.text-container");l.text(""),l.append("title").text(function(a){return a}),l.attr("transform","translate("+e.textHeight+", "+.1*e.textHeight+")").each(function(b){var c=d3.select(this),d=a._Util.Text.getTextMeasurer(c.append("text")),f=e.entryLengths.get(b)-e.textHeight-k,g=a._Util.Text.getTruncatedText(b,f,d),h=d(g);a._Util.Text.writeLineHorizontally(g,c,h.width,h.height)})},c.LEGEND_ROW_CLASS="legend-row",c.LEGEND_ENTRY_CLASS="legend-entry",c}(a.Abstract.Component);b.HorizontalLegend=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;a.call(this),this.classed("gridlines",!0),this.xScale=b,this.yScale=c,this.xScale&&this.xScale.broadcaster.registerListener(this,function(){return d._render()}),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),this.xScale&&this.xScale.broadcaster.deregisterListener(this),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(this.xScale){var b=this.xScale.ticks(),c=function(b){return a.xScale.scale(b)},d=this.xLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",c).attr("y1",0).attr("x2",c).attr("y2",this.height()).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},b.prototype.redrawYLines=function(){var a=this;if(this.yScale){var b=this.yScale.ticks(),c=function(b){return a.yScale.scale(b)},d=this.yLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",0).attr("y1",c).attr("x2",this.width()).attr("y2",c).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},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(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(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.width(),this.height()),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._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=c?"function"==typeof c.data?c:new a.Dataset(c):new a.Dataset,this.dataset(d)}return __extends(c,b),c.prototype._anchor=function(a){b.prototype._anchor.call(this,a),this.animateOnNextRender=!0,this._dataChanged=!0,this._updateScaleExtents()},c.prototype.remove=function(){var a=this;b.prototype.remove.call(this),this._dataset.broadcaster.deregisterListener(this);var c=Object.keys(this._projectors);c.forEach(function(b){var c=a._projectors[b];c.scale&&c.scale.broadcaster.deregisterListener(a)})},c.prototype.dataset=function(a){var b=this;return a?(this._dataset&&this._dataset.broadcaster.deregisterListener(this),this._dataset=a,this._dataset.broadcaster.registerListener(this,function(){return b._onDatasetUpdate()}),this._onDatasetUpdate(),this):this._dataset},c.prototype._onDatasetUpdate=function(){this._updateScaleExtents(),this.animateOnNextRender=!0,this._dataChanged=!0,this._render()},c.prototype.attr=function(a,b,c){return this.project(a,b,c)},c.prototype.project=function(b,c,d){var e=this;b=b.toLowerCase();var f=this._projectors[b],g=f&&f.scale;g&&(g._removeExtent(this._plottableID.toString(),b),g.broadcaster.deregisterListener(this)),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._updateScaleExtent(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=f?function(a,b){return f.scale(e(a,b))}:e;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._updateScaleExtents(),this},c.prototype._updateScaleExtents=function(){var a=this;d3.keys(this._projectors).forEach(function(b){return a._updateScaleExtent(b)})},c.prototype._updateScaleExtent=function(a){var b=this._projectors[a];if(b.scale){var c=this.dataset()._getExtent(b.accessor,b.scale._typeCoercer);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&&this._animators[b]?this._animators[b].animate(a,c):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(b){var c=function(b){function c(){this._key2DatasetDrawerKey=d3.map(),this._datasetKeysInOrder=[],this.nextSeriesIndex=0,b.call(this,new a.Dataset),this.classed("pie-plot",!0)}return __extends(c,b),c.prototype._setup=function(){a.Abstract.NewStylePlot.prototype._setup.call(this)},c.prototype._computeLayout=function(a,c,d,e){b.prototype._computeLayout.call(this,a,c,d,e),this._renderArea.attr("transform","translate("+this.width()/2+","+this.height()/2+")")},c.prototype.addDataset=function(b,c){return a.Abstract.NewStylePlot.prototype.addDataset.call(this,b,c)},c.prototype._addDataset=function(b,c){return 1===this._datasetKeysInOrder.length?void a._Util.Methods.warn("Only one dataset is supported in pie plots"):void a.Abstract.NewStylePlot.prototype._addDataset.call(this,b,c)},c.prototype.removeDataset=function(b){return a.Abstract.NewStylePlot.prototype.removeDataset.call(this,b)},c.prototype._generateAttrToProjector=function(){var a=this.retargetProjectors(b.prototype._generateAttrToProjector.call(this)),d=a["inner-radius"]||d3.functor(0),e=a["outer-radius"]||d3.functor(Math.min(this.width(),this.height())/2);return a.d=d3.svg.arc().innerRadius(d).outerRadius(e),delete a["inner-radius"],delete a["outer-radius"],null==a.fill&&(a.fill=function(a,b){return c.DEFAULT_COLOR_SCALE.scale(String(b))}),delete a.value,a},c.prototype.retargetProjectors=function(a){var b={};return d3.entries(a).forEach(function(a){b[a.key]=function(b,c){return a.value(b.data,c)}}),b},c.prototype._getAnimator=function(b,c){return a.Abstract.NewStylePlot.prototype._getAnimator.call(this,b,c)},c.prototype._getDrawer=function(b){return new a._Drawer.Arc(b)},c.prototype._getDatasetsInOrder=function(){return a.Abstract.NewStylePlot.prototype._getDatasetsInOrder.call(this)},c.prototype._getDrawersInOrder=function(){return a.Abstract.NewStylePlot.prototype._getDrawersInOrder.call(this)},c.prototype._updateScaleExtent=function(b){a.Abstract.NewStylePlot.prototype._updateScaleExtent.call(this,b)},c.prototype._paint=function(){var b=this,c=this._generateAttrToProjector(),d=this._getDatasetsInOrder();this._getDrawersInOrder().forEach(function(e,f){var g=b._animate?b._getAnimator(e,f):new a.Animator.Null,h=b.pie(d[f].data());e.draw(h,c,g)})},c.prototype.pie=function(a){var b=function(a){return a.value},c=this._projectors.value,d=c?c.accessor:b;return d3.layout.pie().sort(null).value(d)(a)},c.DEFAULT_COLOR_SCALE=new a.Scale.Color,c}(a.Abstract.Plot);b.Pie=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(a){var b=function(b){function c(a,c,d){if(b.call(this,a),!c||!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&&d&&(this._xScale=d,this._updateXDomainer()),"y"===a&&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.width()]),this._yScale.range([this.height(),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){this._key2DatasetDrawerKey=d3.map(),this._datasetKeysInOrder=[],this.nextSeriesIndex=0,b.call(this,new a.Dataset,c,d)}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.Dataset?e:new a.Dataset(e);return this._addDataset(d,c),this},c.prototype._addDataset=function(a,b){var c=this;this._key2DatasetDrawerKey.has(a)&&this.removeDataset(a);var d=this._getDrawer(a),e={drawer:d,dataset:b,key:a};this._datasetKeysInOrder.push(a),this._key2DatasetDrawerKey.set(a,e),this._isSetup&&(d._renderArea=this._renderArea.append("g")),b.broadcaster.registerListener(this,function(){return c._onDatasetUpdate()}),this._onDatasetUpdate()},c.prototype._getDrawer=function(){throw new Error("Abstract Method Not Implemented") -},c.prototype._getAnimator=function(){return new a.Animator.Null},c.prototype._updateScaleExtent=function(a){var b=this,c=this._projectors[a];c.scale&&this._key2DatasetDrawerKey.forEach(function(d,e){var f=e.dataset._getExtent(c.accessor,c.scale._typeCoercer),g=b._plottableID.toString()+"_"+d;0!==f.length&&b._isAnchored?c.scale._updateExtent(g,a,f):c.scale._removeExtent(g,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._onDatasetUpdate()):a._Util.Methods.warn("Attempted to change datasetOrder, but new order is not permutation of old. Ignoring."),this)},c.prototype.removeDataset=function(a){if(this._key2DatasetDrawerKey.has(a)){var b=this._key2DatasetDrawerKey.get(a);b.drawer.remove();var c=d3.values(this._projectors),d=this._plottableID.toString()+"_"+a;c.forEach(function(a){a.scale&&a.scale._removeExtent(d,a.attribute)}),b.dataset.broadcaster.deregisterListener(this),this._datasetKeysInOrder.splice(this._datasetKeysInOrder.indexOf(a),1),this._key2DatasetDrawerKey.remove(a),this._onDatasetUpdate()}return this},c.prototype._getDatasetsInOrder=function(){var a=this;return this._datasetKeysInOrder.map(function(b){return a._key2DatasetDrawerKey.get(b).dataset})},c.prototype._getDrawersInOrder=function(){var a=this;return this._datasetKeysInOrder.map(function(b){return a._key2DatasetDrawerKey.get(b).drawer})},c.prototype._paint=function(){var b=this,c=this._generateAttrToProjector(),d=this._getDatasetsInOrder();this._getDrawersInOrder().forEach(function(e,f){var g=b._animate?b._getAnimator(e,f):new a.Animator.Null;e.draw(d[f].data(),c,g)})},c}(b.XYPlot);b.NewStylePlot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._animators={"circles-reset":new a.Animator.Null,circles:(new a.Animator.IterativeDelay).duration(250).delay(5)},this.classed("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._dataset.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._dataset.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._dataset.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();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.width():b,y2:this._isVertical?b:this.height()};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(!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){this._isVertical=!0,a.call(this,b,c,d)}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)}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.Base).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._appendPath()},c.prototype._appendPath=function(){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>b&&b||c>0&&c||0,e=this._yScale.scale(d);return function(){return e}},c.prototype._generateAttrToProjector=function(){var a=b.prototype._generateAttrToProjector.call(this),c=this._wholeDatumAttributes(),d=function(a){return-1===c.indexOf(a)},e=d3.keys(a).filter(d);return e.forEach(function(b){var c=a[b];a[b]=function(a,b){return a.length>0?c(a[0],b):null}}),a},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._dataset.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.Base).duration(600).easing("exp-in-out")}return __extends(c,b),c.prototype._appendPath=function(){this.areaPath=this._renderArea.append("path").classed("area",!0),b.prototype._appendPath.call(this)},c.prototype._onDatasetUpdate=function(){b.prototype._onDatasetUpdate.call(this),null!=this._yScale&&this._updateYDomainer()},c.prototype._updateYDomainer=function(){b.prototype._updateYDomainer.call(this);var a=this._projectors.y0,c=a&&a.accessor,d=c?this.dataset()._getExtent(c,this._yScale._typeCoercer):[],e=2===d.length&&d[0]===d[1]?d[0]:null;this._yScale._userSetDomainer||(null!=e?this._yScale.domainer().addPaddingException(e,"AREA_PLOT+"+this._plottableID):this._yScale.domainer().removePaddingException("AREA_PLOT+"+this._plottableID),this._yScale._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._dataset.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.width():b,y2:this._isVertical?b:this.height()};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,e){"undefined"==typeof e&&(e=!0),this._isVertical=e,b.call(this,c,d),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;this.innerScale.range([0,d(null,0)]);var e=function(){return a.innerScale.rangeBand()},f=c.height;c.width=this._isVertical?e:f,c.height=this._isVertical?f:e;var g=function(a){return a._PLOTTABLE_PROTECTED_FIELD_POSITION};return c.x=this._isVertical?g:c.x,c.y=this._isVertical?c.y:g,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.uniq(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.get(a).dataset.data();e[a]=d.map(function(d,e){var f=b(d,e),g=c._isVertical?c._xScale:c._yScale;return d._PLOTTABLE_PROTECTED_FIELD_POSITION=g.scale(f)+c.innerScale.scale(a),d})}),e},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector(),c=this._isVertical?this._projectors.x.accessor:this._projectors.y.accessor,d=this.cluster(c);this._getDrawersInOrder().forEach(function(b){return b.draw(d[b.key],a)})},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(){b.apply(this,arguments),this.stackedExtent=[0,0]}return __extends(c,b),c.prototype._onDatasetUpdate=function(){b.prototype._onDatasetUpdate.call(this),this._datasetKeysInOrder&&this._projectors.x&&this._projectors.y&&this.stack()},c.prototype.stack=function(){var b=this._getDatasetsInOrder(),c=this._isVertical?this._projectors.x.accessor:this._projectors.y.accessor,d=this._isVertical?this._projectors.y.accessor:this._projectors.x.accessor,e=b.map(function(a){return a.data().map(function(a){return{key:c(a),value:d(a)}})}),f=e.map(function(a){return a.map(function(a){return{key:a.key,value:Math.max(0,a.value)}})}),g=e.map(function(a){return a.map(function(a){return{key:a.key,value:Math.min(a.value,0)}})});this.setDatasetStackOffsets(this._stack(f),this._stack(g));var h=a._Util.Methods.max(b,function(b){return a._Util.Methods.max(b.data(),function(a){return d(a)+a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET})}),i=a._Util.Methods.min(b,function(b){return a._Util.Methods.min(b.data(),function(a){return d(a)+a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET})});this.stackedExtent=[Math.min(i,0),Math.max(0,h)]},c.prototype._stack=function(a){var b=function(a,b){a.offset=b};return d3.layout.stack().x(function(a){return a.key}).y(function(a){return a.value}).values(function(a){return a}).out(b)(a),a},c.prototype.setDatasetStackOffsets=function(a,b){var c=this._isVertical?this._projectors.y.accessor:this._projectors.x.accessor,d=a.map(function(a){return a.map(function(a){return a.offset})}),e=b.map(function(a){return a.map(function(a){return a.offset})});this._getDatasetsInOrder().forEach(function(a,b){a.data().forEach(function(a,f){var g=d[b][f],h=e[b][f];a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET=c(a)>0?g:h})})},c.prototype._updateScaleExtents=function(){b.prototype._updateScaleExtents.call(this);var a=this._isVertical?this._yScale:this._xScale;a&&(this._isAnchored&&this.stackedExtent.length>0?a._updateExtent(this._plottableID.toString(),"_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT",this.stackedExtent):a._removeExtent(this._plottableID.toString(),"_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT"))},c}(b.NewStylePlot);b.Stacked=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(c){function d(b,d){c.call(this,b,d),this._baselineValue=0,this.classed("area-plot",!0),this.project("fill",function(){return a.Core.Colors.INDIGO}),this._isVertical=!0}return __extends(d,c),d.prototype._getDrawer=function(b){return new a._Drawer.Area(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._yScale.scale(this._baselineValue),b={x1:0,y1:a,x2:this.width(),y2:a};this._applyAnimatedAttributes(this._baseline,"baseline",b)},d.prototype._updateYDomainer=function(){c.prototype._updateYDomainer.call(this);var a=this._yScale;a._userSetDomainer||(a.domainer().addPaddingException(0,"STACKED_AREA_PLOT+"+this._plottableID),a._autoDomainIfAutomaticMode())},d.prototype._onDatasetUpdate=function(){c.prototype._onDatasetUpdate.call(this),b.Area.prototype._onDatasetUpdate.apply(this)},d.prototype._generateAttrToProjector=function(){var a=this,b=c.prototype._generateAttrToProjector.call(this),d=b.x,e=function(b){return a._yScale.scale(b.y+b._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)},f=function(b){return a._yScale.scale(b._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)};delete b.x,delete b.y0,delete b.y,b.d=d3.svg.area().x(d).y0(f).y1(e);var g=b.fill;return b.fill=function(a,b){return g(a[0],b)},b},d}(a.Abstract.Stacked);b.StackedArea=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){"undefined"==typeof e&&(e=!0),this._isVertical=e,this._baselineValue=0,this._barAlignmentFactor=.5,b.call(this,c,d),this.classed("bar-plot",!0),this.project("fill",function(){return a.Core.Colors.INDIGO}),this.baseline(this._baselineValue),this._isVertical=e}return __extends(c,b),c.prototype._setup=function(){a.Abstract.NewStyleBarPlot.prototype._setup.call(this)},c.prototype._getAnimator=function(b,c){var d=new a.Animator.Rect;return d.delay(d.duration()*c),d},c.prototype._getDrawer=function(b){return a.Abstract.NewStyleBarPlot.prototype._getDrawer.apply(this,[b])},c.prototype._generateAttrToProjector=function(){var b=this,c=a.Abstract.NewStyleBarPlot.prototype._generateAttrToProjector.apply(this),d=this._isVertical?"y":"x",e=this._isVertical?this._yScale:this._xScale,f=this._projectors[d].accessor,g=function(a){return e.scale(a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)},h=function(a){return e.scale(f(a)+a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)},i=function(a){return Math.abs(h(a)-g(a))},j=c.width;c.height=this._isVertical?i:j,c.width=this._isVertical?j:i;var k=function(a){return f(a)<0?g(a):h(a)};return c[d]=function(a){return b._isVertical?k(a):k(a)-i(a)},c},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._isVertical?this._yScale:this._xScale,c=a.scale(this._baselineValue),d={x1:this._isVertical?0:c,y1:this._isVertical?c:0,x2:this._isVertical?this.width():c,y2:this._isVertical?c:this.height()};this._baseline.attr(d)},c.prototype.baseline=function(b){return a.Abstract.NewStyleBarPlot.prototype.baseline.apply(this,[b])},c.prototype._updateDomainer=function(b){return a.Abstract.NewStyleBarPlot.prototype._updateDomainer.apply(this,[b])},c.prototype._updateXDomainer=function(){return a.Abstract.NewStyleBarPlot.prototype._updateXDomainer.apply(this)},c.prototype._updateYDomainer=function(){return a.Abstract.NewStyleBarPlot.prototype._updateYDomainer.apply(this)},c}(a.Abstract.Stacked);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._duration=a.DEFAULT_DURATION_MILLISECONDS,this._delay=a.DEFAULT_DELAY_MILLISECONDS,this._easing=a.DEFAULT_EASING}return a.prototype.animate=function(a,b){return a.transition().ease(this.easing()).duration(this.duration()).delay(this.delay()).attr(b)},a.prototype.duration=function(a){return void 0===a?this._duration:(this._duration=a,this)},a.prototype.delay=function(a){return void 0===a?this._delay:(this._delay=a,this)},a.prototype.easing=function(a){return void 0===a?this._easing:(this._easing=a,this)},a.DEFAULT_DURATION_MILLISECONDS=300,a.DEFAULT_DELAY_MILLISECONDS=0,a.DEFAULT_EASING="exp-out",a}();a.Base=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.call(this),this._iterativeDelay=b.DEFAULT_ITERATIVE_DELAY_MILLISECONDS}return __extends(b,a),b.prototype.animate=function(a,b){var c=this;return a.transition().ease(this.easing()).duration(this.duration()).delay(function(a,b){return c.delay()+c.iterativeDelay()*b}).attr(b)},b.prototype.iterativeDelay=function(a){return void 0===a?this._iterativeDelay:(this._iterativeDelay=a,this)},b.DEFAULT_ITERATIVE_DELAY_MILLISECONDS=15,b}(a.Base);a.IterativeDelay=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(b,c){"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!1),a.call(this),this.isVertical=b,this.isReverse=c}return __extends(b,a),b.prototype.animate=function(c,d){var e={};return b.ANIMATED_ATTRIBUTES.forEach(function(a){return e[a]=d[a]}),e[this.getMovingAttr()]=this._startMovingProjector(d),e[this.getGrowingAttr()]=function(){return 0},c.attr(e),a.prototype.animate.call(this,c,d)},b.prototype._startMovingProjector=function(a){if(this.isVertical===this.isReverse)return a[this.getMovingAttr()];var b=a[this.getMovingAttr()],c=a[this.getGrowingAttr()];return function(a,d){return b(a,d)+c(a,d)}},b.prototype.getGrowingAttr=function(){return this.isVertical?"height":"width"},b.prototype.getMovingAttr=function(){return this.isVertical?"y":"x"},b.ANIMATED_ATTRIBUTES=["height","width","x","y","fill"],b}(a.Base);a.Rect=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 __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._anchor=function(a,b){this._componentToListenTo=a,this._hitBox=b},b}(a.PlottableObject);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(){a.apply(this,arguments)}return __extends(b,a),b.prototype._anchor=function(b,c){var d=this;a.prototype._anchor.call(this,b,c),c.on(this._listenTo(),function(){var a=d3.mouse(c.node()),b=a[0],e=a[1];d._callback({x:b,y: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(){a.apply(this,arguments)}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(b){function c(a){b.call(this),this.activated=!1,this.keyCode=a}return __extends(c,b),c.prototype._anchor=function(c,d){var e=this;b.prototype._anchor.call(this,c,d),d.on("mouseover",function(){e.activated=!0}),d.on("mouseout",function(){e.activated=!1}),a.Core.KeyEventListener.addCallback(this.keyCode,function(){e.activated&&null!=e._callback&&e._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){var e=this;b.call(this),null==c&&(c=new a.Scale.Linear),null==d&&(d=new a.Scale.Linear),this._xScale=c,this._yScale=d,this.zoom=d3.behavior.zoom(),this.zoom.x(this._xScale._d3Scale),this.zoom.y(this._yScale._d3Scale),this.zoom.on("zoom",function(){return e.rerenderZoomed()})}return __extends(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,c){b.prototype._anchor.call(this,a,c),this.zoom(c)},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(){b.apply(this,arguments),this.currentBar=null,this._hoverMode="point"}return __extends(c,b),c.prototype._anchor=function(c,d){var e=this;b.prototype._anchor.call(this,c,d),this.plotIsVertical=this._componentToListenTo._isVertical,this.dispatcher=new a.Dispatcher.Mouse(this._hitBox),this.dispatcher.mousemove(function(a){var b=e.getHoveredBar(a);if(null==b)e._hoverOut();else{if(null!=e.currentBar){if(e.currentBar.node()===b.node())return;e._hoverOut()}e._componentToListenTo._bars.classed("not-hovered",!0).classed("hovered",!1),b.classed("not-hovered",!1).classed("hovered",!0),null!=e.hoverCallback&&e.hoverCallback(b.data()[0],b)}e.currentBar=b}),this.dispatcher.mouseout(function(){return e._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(){var b=this;a.call(this),this.dragInitialized=!1,this._origin=[0,0],this._location=[0,0],this.dragBehavior=d3.behavior.drag(),this.dragBehavior.on("dragstart",function(){return b._dragstart() -}),this.dragBehavior.on("drag",function(){return b._drag()}),this.dragBehavior.on("dragend",function(){return b._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.width(),b=this._componentToListenTo.height(),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,c){return a.prototype._anchor.call(this,b,c),c.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,d){a.prototype._anchor.call(this,c,d);var e=b.CLASS_DRAG_BOX,f=this._componentToListenTo._backgroundContainer;return this.dragBox=f.append("rect").classed(e,!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.height()),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.width(),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={})); \ 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=d3.map();return a.forEach(function(a,d){c.set(a,b(a,d))}),c}function i(a,b){var c=f(a);return function(a,d){return c(a,d,b.dataset().metadata())}}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){void 0===f&&(f="left"),void 0===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(void 0===e&&(e="left"),void 0===f&&(f="top"),void 0===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()),m.classed("rotated-"+g,!0),n}function k(d,e,f,g,h,j){void 0===h&&(h="left"),void 0===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){void 0===h&&(h="left"),void 0===i&&(i="top"),void 0===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){if(void 0===f&&(f="horizontal"),-1===["left","right","horizontal"].indexOf(f))throw new Error("Unrecognized orientation to writeText: "+f);var h="horizontal"===f,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?a.Methods.max:d3.sum,q=h?d3.sum:a.Methods.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.call(this,m.lines,r,c,d,g.xAlign,g.yAlign,f);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(b,c,d){var e=h(b),f=e.map(d),g=a.Methods.max(f);return c>=g}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){var b;try{b=a.node().getBBox()}catch(c){b={x:0,y:0,width:0,height:0}}return b}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,function(b){function c(a,c,d,e){void 0===a&&(a=2),void 0===c&&(c="$"),void 0===d&&(d=!0),void 0===e&&(e=!0);var f=b.fixed(a);return function(a){var b=f(Math.abs(a));return e&&l(Math.abs(a),b)?"":(""!==b&&(d?b=c+b:b+=c,0>a&&(b="-"+b)),b)}}function d(a,b){return void 0===a&&(a=3),void 0===b&&(b=!0),k(a),function(c){var d=c.toFixed(a);return b&&l(c,d)?"":d}}function e(a,b){return void 0===a&&(a=3),void 0===b&&(b=!0),k(a),function(c){if("number"==typeof c){var d=Math.pow(10,a),e=String(Math.round(c*d)/d);return b&&l(c,e)?"":e}return String(c)}}function f(){return function(a){return String(a)}}function g(a,c){void 0===a&&(a=0),void 0===c&&(c=!0);var d=b.fixed(a,c);return function(a){var b=100*a,e=a.toString(),f=Math.pow(10,e.length-(e.indexOf(".")+1));b=parseInt((b*f).toString(),10)/f;var g=d(b);return c&&l(b,g)?"":(""!==g&&(g+="%"),g)}}function h(a){return void 0===a&&(a=3),k(a),function(b){return d3.format("."+a+"s")(b)}}function i(){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)}}function j(b,c,d){return void 0===b&&(b=0),void 0===c&&(c=a.MILLISECONDS_IN_ONE_DAY),void 0===d&&(d=""),function(a){var e=Math.round((a.valueOf()-b)/c);return e.toString()+d}}function k(a){if(0>a||a>20)throw new RangeError("Formatter precision must be between 0 and 20")}function l(a,b){return a!==parseFloat(b)}b.currency=c,b.fixed=d,b.general=e,b.identity=f,b.percentage=g,b.siSuffix=h,b.time=i,b.relativeDate=j}(a.Formatters||(a.Formatters={}));a.Formatters}(Plottable||(Plottable={}));var Plottable;!function(a){a.version="0.32.0"}(Plottable||(Plottable={}));var Plottable;!function(a){!function(a){var b=function(){function a(){}return a.CORAL_RED="#fd373e",a.INDIGO="#5279c7",a.ROBINS_EGG_BLUE="#06cccc",a.FERN="#63c261",a.BURNING_ORANGE="#ff7939",a.ROYAL_HEATH="#962565",a.CONIFER="#99ce50",a.CERISE_RED="#db2e65",a.BRIGHT_SUN="#fad419",a.JACARTA="#2c2b6f",a.PLOTTABLE_COLORS=[a.INDIGO,a.CORAL_RED,a.FERN,a.BRIGHT_SUN,a.JACARTA,a.BURNING_ORANGE,a.CERISE_RED,a.CONIFER,a.ROYAL_HEATH,a.ROBINS_EGG_BLUE],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;c0){var f=d.valueOf();return d instanceof Date?[f-b.ONE_DAY,f+b.ONE_DAY]:[f-b.PADDING_FOR_IDENTICAL_DOMAIN,f+b.PADDING_FOR_IDENTICAL_DOMAIN]}if(a.domain()[0]===a.domain()[1])return c;var g=this.padProportion/2,h=a.invert(a.scale(d)-(a.scale(e)-a.scale(d))*g),i=a.invert(a.scale(e)+(a.scale(e)-a.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]},b.prototype.niceDomain=function(a,b){return this.doNice?a._niceDomain(b,this.niceCount):b},b.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)},b.PADDING_FOR_IDENTICAL_DOMAIN=1,b.ONE_DAY=864e5,b}();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),this._autoDomainAutomatically=!0,this.broadcaster=new a.Core.Broadcaster(this),this._rendererAttrID2Extent={},this._typeCoercer=function(a){return a},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,c),this._numTicks=10,this._PADDING_FOR_IDENTICAL_DOMAIN=1,this._userSetDomainer=!1,this._domainer=new a.Domainer,this._typeCoercer=function(a){return+a}}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 void 0===a&&(a=this.numTicks()),this._d3Scale.ticks(a)},c.prototype.numTicks=function(a){return null==a?this._numTicks:(this._numTicks=a,this)},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(void 0===a&&(a=10),b.call(this,d3.scale.linear()),this._showIntermediateTicks=!1,this.base=a,this.pivot=this.base,this.untransformedDomain=this._defaultExtent(),this._numTicks=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(b)),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.uniq(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(b,c){var d=this.adjustedLog(a._Util.Methods.min(this.untransformedDomain)),e=this.adjustedLog(a._Util.Methods.max(this.untransformedDomain)),f=this.adjustedLog(b),g=this.adjustedLog(c),h=(g-f)/(e-d),i=Math.ceil(h*this._numTicks);return i},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._typeCoercer=function(a){return null!=a&&a.toString?a.toString():a},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.range(this.range()),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),this._typeCoercer=function(a){return a&&a._isAMomentObject||a instanceof Date?a:new Date(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._setDomain=function(a){return a=a.map(this._typeCoercer),b.prototype._setDomain.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(b){function c(a,d){void 0===a&&(a="reds"),void 0===d&&(d="linear"),this._colorRange=this._resolveColorValues(a),this._scaleType=d,b.call(this,c.getD3InterpolatedScale(this._colorRange,this._scaleType))}return __extends(c,b),c.getD3InterpolatedScale=function(a,b){var d;switch(b){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 "+b);return d.range([0,1]).interpolate(c.interpolateColors(a))},c.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)}}},c.prototype.colorRange=function(a){return null==a?this._colorRange:(this._colorRange=this._resolveColorValues(a),this._resetScale(),this)},c.prototype.scaleType=function(a){return null==a?this._scaleType:(this._scaleType=a,this._resetScale(),this)},c.prototype._resetScale=function(){this._d3Scale=c.getD3InterpolatedScale(this._colorRange,this._scaleType),this._autoDomainIfAutomaticMode(),this.broadcaster.broadcast()},c.prototype._resolveColorValues=function(a){return a instanceof Array?a:null!=c.COLOR_SCALES[a]?c.COLOR_SCALES[a]:c.COLOR_SCALES.reds},c.prototype.autoDomain=function(){var b=this._getAllExtents();return b.length>0&&this._setDomain([a._Util.Methods.min(b,function(a){return a[0]}),a._Util.Methods.max(b,function(a){return a[1]})]),this},c.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"]},c}(a.Abstract.Scale);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(b){var c=function(){function b(a){this.key=a}return b.prototype.remove=function(){null!=this._renderArea&&this._renderArea.remove()},b.prototype.draw=function(b,c,d){throw void 0===d&&(d=new a.Animator.Null),new Error("Abstract Method Not Implemented")},b}();b._Drawer=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(){b.apply(this,arguments)}return __extends(c,b),c.prototype.draw=function(b,c,d){void 0===d&&(d=new a.Animator.Null);var e="path",f=this._renderArea.selectAll(e).data(b);f.enter().append(e),f.classed("arc",!0),d.animate(f,c),f.exit().remove()},c}(a.Abstract._Drawer);b.Arc=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(a){function b(){a.apply(this,arguments)}return __extends(b,a),b.prototype.draw=function(a,b){var c="path",d=this._renderArea.selectAll(c).data([a]);d.enter().append(c),d.attr(b).classed("area",!0),d.exit().remove()},b}(a.Abstract._Drawer);b.Area=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(b){function c(){b.apply(this,arguments)}return __extends(c,b),c.prototype.draw=function(b,c,d){void 0===d&&(d=new a.Animator.Null);var e="rect",f=this._renderArea.selectAll(e).data(b);f.enter().append(e),d.animate(f,c),f.exit().remove()},c}(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(b){function c(){b.apply(this,arguments),this.clipPathEnabled=!1,this._xAlignProportion=0,this._yAlignProportion=0,this._fixedHeightFlag=!1,this._fixedWidthFlag=!1,this._isSetup=!1,this._isAnchored=!1,this.interactionsToRegister=[],this.boxes=[],this.isTopLevelComponent=!1,this._width=0,this._height=0,this._xOffset=0,this._yOffset=0,this.cssClasses=["component"],this.removed=!1}return __extends(c,b),c.prototype._anchor=function(a){if(this.removed)throw new Error("Can't reuse remove()-ed components!");"svg"===a.node().nodeName&&(this.rootSVG=a,this.rootSVG.classed("plottable",!0),this.rootSVG.style("overflow","visible"),this.isTopLevelComponent=!0),null!=this._element?a.node().appendChild(this._element.node()):(this._element=a.append("g"),this._setup()),this._isAnchored=!0},c.prototype._setup=function(){var a=this;this._isSetup||(this.cssClasses.forEach(function(b){a._element.classed(b,!0)}),this.cssClasses=null,this._backgroundContainer=this._element.append("g").classed("background-container",!0),this._content=this._element.append("g").classed("content",!0),this._foregroundContainer=this._element.append("g").classed("foreground-container",!0),this.boxContainer=this._element.append("g").classed("box-container",!0),this.clipPathEnabled&&this.generateClipPath(),this.addBox("bounding-box"),this.interactionsToRegister.forEach(function(b){return a.registerInteraction(b)}),this.interactionsToRegister=null,this.isTopLevelComponent&&this.autoResize(c.AUTORESIZE_BY_DEFAULT),this._isSetup=!0)},c.prototype._requestedSpace=function(){return{width:0,height:0,wantsWidth:!1,wantsHeight:!1}},c.prototype._computeLayout=function(b,c,d,e){var f=this;if(null==b||null==c||null==d||null==e){if(null==this._element)throw new Error("anchor must be called before computeLayout");if(!this.isTopLevelComponent)throw new Error("null arguments cannot be passed to _computeLayout() on a non-root node");b=0,c=0,null==this.rootSVG.attr("width")&&this.rootSVG.attr("width","100%"),null==this.rootSVG.attr("height")&&this.rootSVG.attr("height","100%");var g=this.rootSVG.node();d=a._Util.DOM.getElementWidth(g),e=a._Util.DOM.getElementHeight(g)}this.xOrigin=b,this.yOrigin=c;var h=this.xOrigin,i=this.yOrigin,j=this._requestedSpace(d,e);h+=this._xOffset,this._isFixedWidth()&&(h+=(d-j.width)*this._xAlignProportion,d=Math.min(d,j.width)),i+=this._yOffset,this._isFixedHeight()&&(i+=(e-j.height)*this._yAlignProportion,e=Math.min(e,j.height)),this._width=d,this._height=e,this._element.attr("transform","translate("+h+","+i+")"),this.boxes.forEach(function(a){return a.attr("width",f.width()).attr("height",f.height())})},c.prototype._render=function(){this._isAnchored&&this._isSetup&&a.Core.RenderController.registerToRender(this)},c.prototype._scheduleComputeLayout=function(){this._isAnchored&&this._isSetup&&a.Core.RenderController.registerToComputeLayout(this)},c.prototype._doRender=function(){},c.prototype._invalidateLayout=function(){this._isAnchored&&this._isSetup&&(this.isTopLevelComponent?this._scheduleComputeLayout():this._parent._invalidateLayout())},c.prototype.renderTo=function(b){if(null!=b){var c;if(c="function"==typeof b.node?b:d3.select(b),!c.node()||"svg"!==c.node().nodeName)throw new Error("Plottable requires a valid SVG to renderTo");this._anchor(c)}if(null==this._element)throw new Error("If a component has never been rendered before, then renderTo must be given a node to render to, or a D3.Selection, or a selector string");return this._computeLayout(),this._render(),a.Core.RenderController.flush(),this},c.prototype.resize=function(a,b){if(!this.isTopLevelComponent)throw new Error("Cannot resize on non top-level component");return null!=a&&null!=b&&this._isAnchored&&this.rootSVG.attr({width:a,height:b}),this._invalidateLayout(),this},c.prototype.autoResize=function(b){return b?a.Core.ResizeBroadcaster.register(this):a.Core.ResizeBroadcaster.deregister(this),this},c.prototype.xAlign=function(a){if(a=a.toLowerCase(),"left"===a)this._xAlignProportion=0;else if("center"===a)this._xAlignProportion=.5;else{if("right"!==a)throw new Error("Unsupported alignment");this._xAlignProportion=1}return this._invalidateLayout(),this},c.prototype.yAlign=function(a){if(a=a.toLowerCase(),"top"===a)this._yAlignProportion=0;else if("center"===a)this._yAlignProportion=.5;else{if("bottom"!==a)throw new Error("Unsupported alignment");this._yAlignProportion=1}return this._invalidateLayout(),this},c.prototype.xOffset=function(a){return this._xOffset=a,this._invalidateLayout(),this},c.prototype.yOffset=function(a){return this._yOffset=a,this._invalidateLayout(),this},c.prototype.addBox=function(a,b){if(null==this._element)throw new Error("Adding boxes before anchoring is currently disallowed");var b=null==b?this.boxContainer:b,c=b.append("rect");return null!=a&&c.classed(a,!0),this.boxes.push(c),null!=this.width()&&null!=this.height()&&c.attr("width",this.width()).attr("height",this.height()),c},c.prototype.generateClipPath=function(){var a=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;this._element.attr("clip-path","url("+a+"#clipPath"+this._plottableID+")");var b=this.boxContainer.append("clipPath").attr("id","clipPath"+this._plottableID);this.addBox("clip-rect",b)},c.prototype.registerInteraction=function(a){return this._element?(this.hitBox||(this.hitBox=this.addBox("hit-box"),this.hitBox.style("fill","#ffffff").style("opacity",0)),a._anchor(this,this.hitBox)):this.interactionsToRegister.push(a),this},c.prototype.classed=function(a,b){if(null==b)return null==a?!1:null==this._element?-1!==this.cssClasses.indexOf(a):this._element.classed(a);if(null==a)return this;if(null==this._element){var c=this.cssClasses.indexOf(a);b&&-1===c?this.cssClasses.push(a):b||-1===c||this.cssClasses.splice(c,1)}else this._element.classed(a,b);return this},c.prototype._isFixedWidth=function(){return this._fixedWidthFlag},c.prototype._isFixedHeight=function(){return this._fixedHeightFlag},c.prototype.merge=function(b){var c;if(this._isSetup||this._isAnchored)throw new Error("Can't presently merge a component that's already been anchored");return a.Component.Group.prototype.isPrototypeOf(b)?(c=b,c._addComponent(this,!0),c):c=new a.Component.Group([this,b])},c.prototype.detach=function(){return this._isAnchored&&this._element.remove(),null!=this._parent&&this._parent._removeComponent(this),this._isAnchored=!1,this._parent=null,this},c.prototype.remove=function(){this.removed=!0,this.detach(),a.Core.ResizeBroadcaster.deregister(this)},c.prototype.width=function(){return this._width},c.prototype.height=function(){return this._height},c.AUTORESIZE_BY_DEFAULT=!0,c}(b.PlottableObject);b.Component=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(a){function b(){a.apply(this,arguments),this._components=[]}return __extends(b,a),b.prototype._anchor=function(b){var c=this;a.prototype._anchor.call(this,b),this._components.forEach(function(a){return a._anchor(c._content)})},b.prototype._render=function(){this._components.forEach(function(a){return a._render()})},b.prototype._removeComponent=function(a){var b=this._components.indexOf(a);b>=0&&(this._components.splice(b,1),this._invalidateLayout())},b.prototype._addComponent=function(a,b){return void 0===b&&(b=!1),!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(b){function c(a){var c=this;void 0===a&&(a=[]),b.call(this),this.classed("component-group",!0),a.forEach(function(a){return c._addComponent(a)})}return __extends(c,b),c.prototype._requestedSpace=function(b,c){var d=this._components.map(function(a){return a._requestedSpace(b,c)});return{width:a._Util.Methods.max(d,function(a){return a.width}),height:a._Util.Methods.max(d,function(a){return a.height}),wantsWidth:d.map(function(a){return a.wantsWidth}).some(function(a){return a}),wantsHeight:d.map(function(a){return a.wantsHeight}).some(function(a){return a})}},c.prototype.merge=function(a){return this._addComponent(a),this},c.prototype._computeLayout=function(a,c,d,e){var f=this;return b.prototype._computeLayout.call(this,a,c,d,e),this._components.forEach(function(a){a._computeLayout(0,0,f.width(),f.height())}),this},c.prototype._isFixedWidth=function(){return this._components.every(function(a){return a._isFixedWidth()})},c.prototype._isFixedHeight=function(){return this._components.every(function(a){return a._isFixedHeight()})},c}(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(c){function d(b,d,e){var f=this;if(void 0===e&&(e=a.Formatters.identity()),c.call(this),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._setDefaultAlignment(),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=0,d=0;return this._isHorizontal()?(null==this._computedHeight&&this._computeHeight(),d=this._computedHeight+this._gutter):(null==this._computedWidth&&this._computeWidth(),c=this._computedWidth+this._gutter),{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._rescale=function(){this._render()},d.prototype._computeLayout=function(a,b,d,e){c.prototype._computeLayout.call(this,a,b,d,e),this._scale.range(this._isHorizontal()?[0,this.width()]:[this.height(),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.width();break;case"top":a.x2=this.width(),a.y1=this.height(),a.y2=this.height();break;case"left":a.x1=this.width(),a.x2=this.width(),a.y2=this.height();break;case"right":a.y2=this.height()}return a},d.prototype._generateTickMarkAttrHash=function(a){var b=this;void 0===a&&(a=!1);var c={x1:0,y1:0,x2:0,y2:0},d=function(a){return b._scale.scale(a)};this._isHorizontal()?(c.x1=d,c.x2=d):(c.y1=d,c.y2=d);var e=a?this._endTickLength:this._tickLength;switch(this._orientation){case"bottom":c.y2=e;break;case"top":c.y1=this.height(),c.y2=this.height()-e;break;case"left":c.x1=this.width(),c.x2=this.width()-e;break;case"right":c.x2=e}return c},d.prototype._invalidateLayout=function(){this._computedWidth=null,this._computedHeight=null,c.prototype._invalidateLayout.call(this)},d.prototype._setDefaultAlignment=function(){switch(this._orientation){case"bottom":this.yAlign("top");break;case"top":this.yAlign("bottom");break;case"left":this.xAlign("right");break;case"right":this.xAlign("left")}},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.width())&&Math.floor(b.bottom)<=Math.ceil(c.top+a.height())},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.width();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.width());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.height()-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.height()-b),e.attr("y2",b)},c.prototype.generateLabellessTicks=function(b){if(!(0>b)){var d=this._getTickIntervalValues(c._minorIntervals[b]),e=this._getTickValues().concat(d),f=this._tickMarkContainer.selectAll("."+a.Abstract.Axis.TICK_MARK_CLASS).data(e);f.enter().append("line").classed(a.Abstract.Axis.TICK_MARK_CLASS,!0),f.attr(this._generateTickMarkAttrHash()),f.exit().remove(),this.adjustTickLength(this.tickLabelPadding(),c._minorIntervals[b])}},c.prototype._doRender=function(){b.prototype._doRender.call(this);var a=this.getTickLevel();this.renderTickLabels(this._minorTickLabels,c._minorIntervals[a],1),this.renderTickLabels(this._majorTickLabels,c._majorIntervals[a],2);var d=this._scale.domain(),e=this._scale.scale(d[1])-this._scale.scale(d[0]);return 1.5*this.getIntervalLength(c._minorIntervals[a])>=e&&this.generateLabellessTicks(a-1),this.adjustTickLength(this._maxLabelTickLength()/2,c._minorIntervals[a]),this.adjustTickLength(this._maxLabelTickLength(),c._majorIntervals[a]),this},c._minorIntervals=[{timeUnit:d3.time.second,step:1,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:5,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:10,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:15,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.second,step:30,formatString:"%I:%M:%S %p"},{timeUnit:d3.time.minute,step:1,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:5,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:10,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:15,formatString:"%I:%M %p"},{timeUnit:d3.time.minute,step:30,formatString:"%I:%M %p"},{timeUnit:d3.time.hour,step:1,formatString:"%I %p"},{timeUnit:d3.time.hour,step:3,formatString:"%I %p"},{timeUnit:d3.time.hour,step:6,formatString:"%I %p"},{timeUnit:d3.time.hour,step:12,formatString:"%I %p"},{timeUnit:d3.time.day,step:1,formatString:"%a %e"},{timeUnit:d3.time.day,step:1,formatString:"%e"},{timeUnit:d3.time.month,step:1,formatString:"%B"},{timeUnit:d3.time.month,step:1,formatString:"%b"},{timeUnit:d3.time.month,step:3,formatString:"%B"},{timeUnit:d3.time.month,step:6,formatString:"%B"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%y"},{timeUnit:d3.time.year,step:5,formatString:"%Y"},{timeUnit:d3.time.year,step:25,formatString:"%Y"},{timeUnit:d3.time.year,step:50,formatString:"%Y"},{timeUnit:d3.time.year,step:100,formatString:"%Y"},{timeUnit:d3.time.year,step:200,formatString:"%Y"},{timeUnit:d3.time.year,step:500,formatString:"%Y"},{timeUnit:d3.time.year,step:1e3,formatString:"%Y"}],c._majorIntervals=[{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.day,step:1,formatString:"%B %e, %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.month,step:1,formatString:"%B %Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1,formatString:"%Y"},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""},{timeUnit:d3.time.year,step:1e5,formatString:""}],c}(a.Abstract.Axis);b.Time=c}(a.Axis||(a.Axis={}));a.Axis}(Plottable||(Plottable={}));var __extends=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){void 0===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 b=this,c=this._getTickValues(),d=c.map(function(a){var c=b._formatter(a);return b.measurer(c).width}),e=a._Util.Methods.max(d);return this._computedWidth="center"===this.tickLabelPositioning?this._maxLabelTickLength()+this.tickLabelPadding()+e:Math.max(this._maxLabelTickLength(),this.tickLabelPadding()+e),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._rescale=function(){if(this._isSetup){if(!this._isHorizontal()){var a=this._computeWidth();if(a>this.width()||aa,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.orient=function(a){if(null==a)return this.orientation;if(a=a.toLowerCase(),"horizontal"!==a&&"left"!==a&&"right"!==a)throw new Error(a+" is not a valid orientation for LabelComponent");return this.orientation=a,this._invalidateLayout(),this},c.prototype._doRender=function(){b.prototype._doRender.call(this),this.textContainer.text("");var c="horizontal"===this.orientation?this.width():this.height(),d=a._Util.Text.getTruncatedText(this._text,c,this.measurer);"horizontal"===this.orientation?a._Util.Text.writeLineHorizontally(d,this.textContainer,this.width(),this.height(),this.xAlignment,this.yAlignment):a._Util.Text.writeLineVertically(d,this.textContainer,this.width(),this.height(),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.height()/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=a._Util.Methods.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.width()-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(b){function c(a){var c=this;b.call(this),this.padding=5,this.classed("legend",!0),this.scale=a,this.scale.broadcaster.registerListener(this,function(){return c._invalidateLayout()}),this.xAlign("left").yAlign("center"),this._fixedWidthFlag=!0,this._fixedHeightFlag=!0}return __extends(c,b),c.prototype.remove=function(){b.prototype.remove.call(this),this.scale.broadcaster.deregisterListener(this)},c.prototype.calculateLayoutInfo=function(b,d){var e=this,f=this._content.append("g").classed(c.LEGEND_ROW_CLASS,!0),g=(f.append("g").classed(c.LEGEND_ENTRY_CLASS,!0),a._Util.Text.getTextMeasurer(f.append("text"))),h=g(a._Util.Text.HEIGHT_TEXT).height,i=Math.max(0,b-this.padding),j=function(a){var b=h+g(a).width+e.padding;return Math.min(b,i)},k=this.scale.domain(),l=a._Util.Methods.populateMap(k,j);f.remove();var m=this.packRows(i,k,l),n=Math.floor((d-2*this.padding)/h);return n!==n&&(n=0),{textHeight:h,entryLengths:l,rows:m,numRowsToDraw:Math.max(Math.min(n,m.length),0)}},c.prototype._requestedSpace=function(b,c){var d=this.calculateLayoutInfo(b,c),e=d.rows.map(function(a){return d3.sum(a,function(a){return d.entryLengths.get(a)})}),f=a._Util.Methods.max(e);f=void 0===f?0:f;var g=this.padding+f,h=d.numRowsToDraw*d.textHeight+2*this.padding,i=d.rows.length*d.textHeight+2*this.padding;return{width:g,height:h,wantsWidth:g>b,wantsHeight:i>c}},c.prototype.packRows=function(a,b,c){var d=[[]],e=d[0],f=a;return b.forEach(function(b){var g=c.get(b);g>f&&(e=[],d.push(e),f=a),e.push(b),f-=g}),d},c.prototype._doRender=function(){var d=this;b.prototype._doRender.call(this);var e=this.calculateLayoutInfo(this.width(),this.height()),f=e.rows.slice(0,e.numRowsToDraw),g=this._content.selectAll("g."+c.LEGEND_ROW_CLASS).data(f);g.enter().append("g").classed(c.LEGEND_ROW_CLASS,!0),g.exit().remove(),g.attr("transform",function(a,b){return"translate(0, "+(b*e.textHeight+d.padding)+")"});var h=g.selectAll("g."+c.LEGEND_ENTRY_CLASS).data(function(a){return a}),i=h.enter().append("g").classed(c.LEGEND_ENTRY_CLASS,!0);i.append("circle"),i.append("g").classed("text-container",!0),h.exit().remove();var j=this.padding;g.each(function(){var a=j,b=d3.select(this).selectAll("g."+c.LEGEND_ENTRY_CLASS);b.attr("transform",function(b){var c="translate("+a+", 0)";return a+=e.entryLengths.get(b),c})}),h.select("circle").attr("cx",e.textHeight/2).attr("cy",e.textHeight/2).attr("r",.3*e.textHeight).attr("fill",function(a){return d.scale.scale(a)});var k=this.padding,l=h.select("g.text-container");l.text(""),l.append("title").text(function(a){return a}),l.attr("transform","translate("+e.textHeight+", "+.1*e.textHeight+")").each(function(b){var c=d3.select(this),d=a._Util.Text.getTextMeasurer(c.append("text")),f=e.entryLengths.get(b)-e.textHeight-k,g=a._Util.Text.getTruncatedText(b,f,d),h=d(g);a._Util.Text.writeLineHorizontally(g,c,h.width,h.height)})},c.LEGEND_ROW_CLASS="legend-row",c.LEGEND_ENTRY_CLASS="legend-entry",c}(a.Abstract.Component);b.HorizontalLegend=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;a.call(this),this.classed("gridlines",!0),this.xScale=b,this.yScale=c,this.xScale&&this.xScale.broadcaster.registerListener(this,function(){return d._render()}),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),this.xScale&&this.xScale.broadcaster.deregisterListener(this),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(this.xScale){var b=this.xScale.ticks(),c=function(b){return a.xScale.scale(b)},d=this.xLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",c).attr("y1",0).attr("x2",c).attr("y2",this.height()).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},b.prototype.redrawYLines=function(){var a=this;if(this.yScale){var b=this.yScale.ticks(),c=function(b){return a.yScale.scale(b)},d=this.yLinesContainer.selectAll("line").data(b);d.enter().append("line"),d.attr("x1",0).attr("y1",c).attr("x2",this.width()).attr("y2",c).classed("zeroline",function(a){return 0===a}),d.exit().remove()}},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(a){var c=this;void 0===a&&(a=[]),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(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.width(),this.height()),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._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=c?"function"==typeof c.data?c:new a.Dataset(c):new a.Dataset,this.dataset(d)}return __extends(c,b),c.prototype._anchor=function(a){b.prototype._anchor.call(this,a),this.animateOnNextRender=!0,this._dataChanged=!0,this._updateScaleExtents()},c.prototype.remove=function(){var a=this;b.prototype.remove.call(this),this._dataset.broadcaster.deregisterListener(this);var c=Object.keys(this._projectors);c.forEach(function(b){var c=a._projectors[b];c.scale&&c.scale.broadcaster.deregisterListener(a)})},c.prototype.dataset=function(a){var b=this;return a?(this._dataset&&this._dataset.broadcaster.deregisterListener(this),this._dataset=a,this._dataset.broadcaster.registerListener(this,function(){return b._onDatasetUpdate()}),this._onDatasetUpdate(),this):this._dataset},c.prototype._onDatasetUpdate=function(){this._updateScaleExtents(),this.animateOnNextRender=!0,this._dataChanged=!0,this._render()},c.prototype.attr=function(a,b,c){return this.project(a,b,c)},c.prototype.project=function(b,c,d){var e=this;b=b.toLowerCase();var f=this._projectors[b],g=f&&f.scale;g&&(g._removeExtent(this._plottableID.toString(),b),g.broadcaster.deregisterListener(this)),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._updateScaleExtent(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=f?function(a,b){return f.scale(e(a,b))}:e;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._updateScaleExtents(),this},c.prototype._updateScaleExtents=function(){var a=this;d3.keys(this._projectors).forEach(function(b){return a._updateScaleExtent(b)})},c.prototype._updateScaleExtent=function(a){var b=this._projectors[a];if(b.scale){var c=this.dataset()._getExtent(b.accessor,b.scale._typeCoercer);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&&this._animators[b]?this._animators[b].animate(a,c):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(b){var c=function(b){function c(){this._key2DatasetDrawerKey=d3.map(),this._datasetKeysInOrder=[],this.nextSeriesIndex=0,b.call(this,new a.Dataset),this.classed("pie-plot",!0)}return __extends(c,b),c.prototype._setup=function(){a.Abstract.NewStylePlot.prototype._setup.call(this)},c.prototype._computeLayout=function(a,c,d,e){b.prototype._computeLayout.call(this,a,c,d,e),this._renderArea.attr("transform","translate("+this.width()/2+","+this.height()/2+")")},c.prototype.addDataset=function(b,c){return a.Abstract.NewStylePlot.prototype.addDataset.call(this,b,c)},c.prototype._addDataset=function(b,c){return 1===this._datasetKeysInOrder.length?void a._Util.Methods.warn("Only one dataset is supported in pie plots"):void a.Abstract.NewStylePlot.prototype._addDataset.call(this,b,c)},c.prototype.removeDataset=function(b){return a.Abstract.NewStylePlot.prototype.removeDataset.call(this,b)},c.prototype._generateAttrToProjector=function(){var a=this.retargetProjectors(b.prototype._generateAttrToProjector.call(this)),d=a["inner-radius"]||d3.functor(0),e=a["outer-radius"]||d3.functor(Math.min(this.width(),this.height())/2);return a.d=d3.svg.arc().innerRadius(d).outerRadius(e),delete a["inner-radius"],delete a["outer-radius"],null==a.fill&&(a.fill=function(a,b){return c.DEFAULT_COLOR_SCALE.scale(String(b))}),delete a.value,a},c.prototype.retargetProjectors=function(a){var b={};return d3.entries(a).forEach(function(a){b[a.key]=function(b,c){return a.value(b.data,c)}}),b},c.prototype._getAnimator=function(b,c){return a.Abstract.NewStylePlot.prototype._getAnimator.call(this,b,c)},c.prototype._getDrawer=function(b){return new a._Drawer.Arc(b)},c.prototype._getDatasetsInOrder=function(){return a.Abstract.NewStylePlot.prototype._getDatasetsInOrder.call(this)},c.prototype._getDrawersInOrder=function(){return a.Abstract.NewStylePlot.prototype._getDrawersInOrder.call(this)},c.prototype._updateScaleExtent=function(b){a.Abstract.NewStylePlot.prototype._updateScaleExtent.call(this,b)},c.prototype._paint=function(){var b=this,c=this._generateAttrToProjector(),d=this._getDatasetsInOrder();this._getDrawersInOrder().forEach(function(e,f){var g=b._animate?b._getAnimator(e,f):new a.Animator.Null,h=b.pie(d[f].data());e.draw(h,c,g)})},c.prototype.pie=function(a){var b=function(a){return a.value},c=this._projectors.value,d=c?c.accessor:b;return d3.layout.pie().sort(null).value(d)(a)},c.DEFAULT_COLOR_SCALE=new a.Scale.Color,c}(a.Abstract.Plot);b.Pie=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(a){var b=function(b){function c(a,c,d){if(b.call(this,a),!c||!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&&d&&(this._xScale=d,this._updateXDomainer()),"y"===a&&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.width()]),this._yScale.range([this.height(),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){this._key2DatasetDrawerKey=d3.map(),this._datasetKeysInOrder=[],this.nextSeriesIndex=0,b.call(this,new a.Dataset,c,d)}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.Dataset?e:new a.Dataset(e);return this._addDataset(d,c),this},c.prototype._addDataset=function(a,b){var c=this;this._key2DatasetDrawerKey.has(a)&&this.removeDataset(a);var d=this._getDrawer(a),e={drawer:d,dataset:b,key:a}; +this._datasetKeysInOrder.push(a),this._key2DatasetDrawerKey.set(a,e),this._isSetup&&(d._renderArea=this._renderArea.append("g")),b.broadcaster.registerListener(this,function(){return c._onDatasetUpdate()}),this._onDatasetUpdate()},c.prototype._getDrawer=function(){throw new Error("Abstract Method Not Implemented")},c.prototype._getAnimator=function(){return new a.Animator.Null},c.prototype._updateScaleExtent=function(a){var b=this,c=this._projectors[a];c.scale&&this._key2DatasetDrawerKey.forEach(function(d,e){var f=e.dataset._getExtent(c.accessor,c.scale._typeCoercer),g=b._plottableID.toString()+"_"+d;0!==f.length&&b._isAnchored?c.scale._updateExtent(g,a,f):c.scale._removeExtent(g,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._onDatasetUpdate()):a._Util.Methods.warn("Attempted to change datasetOrder, but new order is not permutation of old. Ignoring."),this)},c.prototype.removeDataset=function(a){if(this._key2DatasetDrawerKey.has(a)){var b=this._key2DatasetDrawerKey.get(a);b.drawer.remove();var c=d3.values(this._projectors),d=this._plottableID.toString()+"_"+a;c.forEach(function(a){a.scale&&a.scale._removeExtent(d,a.attribute)}),b.dataset.broadcaster.deregisterListener(this),this._datasetKeysInOrder.splice(this._datasetKeysInOrder.indexOf(a),1),this._key2DatasetDrawerKey.remove(a),this._onDatasetUpdate()}return this},c.prototype._getDatasetsInOrder=function(){var a=this;return this._datasetKeysInOrder.map(function(b){return a._key2DatasetDrawerKey.get(b).dataset})},c.prototype._getDrawersInOrder=function(){var a=this;return this._datasetKeysInOrder.map(function(b){return a._key2DatasetDrawerKey.get(b).drawer})},c.prototype._paint=function(){var b=this,c=this._generateAttrToProjector(),d=this._getDatasetsInOrder();this._getDrawersInOrder().forEach(function(e,f){var g=b._animate?b._getAnimator(e,f):new a.Animator.Null;e.draw(d[f].data(),c,g)})},c}(b.XYPlot);b.NewStylePlot=c}(a.Abstract||(a.Abstract={}));a.Abstract}(Plottable||(Plottable={}));var __extends=this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c},Plottable;!function(a){!function(b){var c=function(b){function c(c,d,e){b.call(this,c,d,e),this._animators={"circles-reset":new a.Animator.Null,circles:(new a.Animator.IterativeDelay).duration(250).delay(5)},this.classed("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._dataset.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._dataset.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._dataset.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();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.width():b,y2:this._isVertical?b:this.height()};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(void 0===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(!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){this._isVertical=!0,a.call(this,b,c,d)}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)}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.Base).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._appendPath()},c.prototype._appendPath=function(){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>b&&b||c>0&&c||0,e=this._yScale.scale(d);return function(){return e}},c.prototype._generateAttrToProjector=function(){var a=b.prototype._generateAttrToProjector.call(this),c=this._wholeDatumAttributes(),d=function(a){return-1===c.indexOf(a)},e=d3.keys(a).filter(d);return e.forEach(function(b){var c=a[b];a[b]=function(a,b){return a.length>0?c(a[0],b):null}}),a},c.prototype._rejectNullsAndNaNs=function(a,b,c){var d=c(a,b);return null!=d&&d===d},c.prototype._paint=function(){var a=this;b.prototype._paint.call(this);var c=this._generateAttrToProjector(),d=c.x,e=c.y;delete c.x,delete c.y,this.linePath.datum(this._dataset.data());var f=d3.svg.line().x(d);f.defined(function(b,c){return a._rejectNullsAndNaNs(b,c,d)&&a._rejectNullsAndNaNs(b,c,e)}),c.d=f,this._dataChanged&&(f.y(this._getResetYFunction()),this._applyAnimatedAttributes(this.linePath,"line-reset",c)),f.y(e),this._applyAnimatedAttributes(this.linePath,"line",c)},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.Base).duration(600).easing("exp-in-out")}return __extends(c,b),c.prototype._appendPath=function(){this.areaPath=this._renderArea.append("path").classed("area",!0),b.prototype._appendPath.call(this)},c.prototype._onDatasetUpdate=function(){b.prototype._onDatasetUpdate.call(this),null!=this._yScale&&this._updateYDomainer()},c.prototype._updateYDomainer=function(){b.prototype._updateYDomainer.call(this);var a=this._projectors.y0,c=a&&a.accessor,d=c?this.dataset()._getExtent(c,this._yScale._typeCoercer):[],e=2===d.length&&d[0]===d[1]?d[0]:null;this._yScale._userSetDomainer||(null!=e?this._yScale.domainer().addPaddingException(e,"AREA_PLOT+"+this._plottableID):this._yScale.domainer().removePaddingException("AREA_PLOT+"+this._plottableID),this._yScale._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(){var a=this;b.prototype._paint.call(this);var c=this._generateAttrToProjector(),d=c.x,e=c.y0,f=c.y;delete c.x,delete c.y0,delete c.y,this.areaPath.datum(this._dataset.data());var g=d3.svg.area().x(d).y0(e);g.defined(function(b,c){return a._rejectNullsAndNaNs(b,c,d)&&a._rejectNullsAndNaNs(b,c,f)}),c.d=g,this._dataChanged&&(g.y1(this._getResetYFunction()),this._applyAnimatedAttributes(this.areaPath,"area-reset",c)),g.y1(f),this._applyAnimatedAttributes(this.areaPath,"area",c)},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.width():b,y2:this._isVertical?b:this.height()};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,e){void 0===e&&(e=!0),this._isVertical=e,b.call(this,c,d),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;this.innerScale.range([0,d(null,0)]);var e=function(){return a.innerScale.rangeBand()},f=c.height;c.width=this._isVertical?e:f,c.height=this._isVertical?f:e;var g=function(a){return a._PLOTTABLE_PROTECTED_FIELD_POSITION};return c.x=this._isVertical?g:c.x,c.y=this._isVertical?c.y:g,c},c.prototype.cluster=function(a){var b=this;this.innerScale.domain(this._datasetKeysInOrder);var c={};return this._datasetKeysInOrder.forEach(function(d){var e=b._key2DatasetDrawerKey.get(d).dataset.data();c[d]=e.map(function(c,e){var f=a(c,e),g=b._isVertical?b._xScale:b._yScale;return c._PLOTTABLE_PROTECTED_FIELD_POSITION=g.scale(f)+b.innerScale.scale(d),c})}),c},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._generateAttrToProjector(),c=this._isVertical?this._projectors.x.accessor:this._projectors.y.accessor,d=this.cluster(c);this._getDrawersInOrder().forEach(function(b){return b.draw(d[b.key],a)})},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(){b.apply(this,arguments),this.stackedExtent=[0,0]}return __extends(c,b),c.prototype._onDatasetUpdate=function(){b.prototype._onDatasetUpdate.call(this),this._datasetKeysInOrder&&this._projectors.x&&this._projectors.y&&this.updateStackOffsets()},c.prototype.updateStackOffsets=function(){var b=this.generateDefaultMapArray(),c=this.getDomainKeys(),d=b.map(function(b){return a._Util.Methods.populateMap(c,function(a){return{key:a,value:Math.max(0,b.get(a).value)}})}),e=b.map(function(b){return a._Util.Methods.populateMap(c,function(a){return{key:a,value:Math.min(b.get(a).value,0)}})});this.setDatasetStackOffsets(this.stack(d),this.stack(e)),this.updateStackExtents()},c.prototype.updateStackExtents=function(){var b=this._getDatasetsInOrder(),c=this.valueAccessor(),d=a._Util.Methods.max(b,function(b){return a._Util.Methods.max(b.data(),function(a){return c(a)+a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET})}),e=a._Util.Methods.min(b,function(b){return a._Util.Methods.min(b.data(),function(a){return c(a)+a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET})});this.stackedExtent=[Math.min(e,0),Math.max(0,d)]},c.prototype.stack=function(a){var b=this,c=function(a,b){a.offset=b};return d3.layout.stack().x(function(a){return a.key}).y(function(a){return a.value}).values(function(a){return b.getDomainKeys().map(function(b){return a.get(b)})}).out(c)(a),a},c.prototype.setDatasetStackOffsets=function(a,b){var c=this.keyAccessor(),d=this.valueAccessor();this._getDatasetsInOrder().forEach(function(e,f){var g=a[f],h=b[f];e.data().forEach(function(a){var b=g.get(c(a)).offset,e=h.get(c(a)).offset;a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET=d(a)>0?b:e})})},c.prototype.getDomainKeys=function(){var a=this.keyAccessor(),b=d3.set(),c=this._getDatasetsInOrder();return c.forEach(function(c){c.data().forEach(function(c){b.add(a(c))})}),b.values()},c.prototype.generateDefaultMapArray=function(){var b=this.keyAccessor(),c=this.valueAccessor(),d=this._getDatasetsInOrder(),e=this.getDomainKeys(),f=d.map(function(){return a._Util.Methods.populateMap(e,function(a){return{key:a,value:0}})});return d.forEach(function(a,d){a.data().forEach(function(a){var e=b(a),g=c(a);f[d].set(e,{key:e,value:g})})}),f},c.prototype._updateScaleExtents=function(){b.prototype._updateScaleExtents.call(this);var a=this._isVertical?this._yScale:this._xScale;a&&(this._isAnchored&&this.stackedExtent.length>0?a._updateExtent(this._plottableID.toString(),"_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT",this.stackedExtent):a._removeExtent(this._plottableID.toString(),"_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT"))},c.prototype.keyAccessor=function(){return this._isVertical?this._projectors.x.accessor:this._projectors.y.accessor},c.prototype.valueAccessor=function(){return this._isVertical?this._projectors.y.accessor:this._projectors.x.accessor},c}(b.NewStylePlot);b.Stacked=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(c){function d(b,d){c.call(this,b,d),this._baselineValue=0,this.classed("area-plot",!0),this.project("fill",function(){return a.Core.Colors.INDIGO}),this._isVertical=!0}return __extends(d,c),d.prototype._getDrawer=function(b){return new a._Drawer.Area(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._yScale.scale(this._baselineValue),b={x1:0,y1:a,x2:this.width(),y2:a};this._applyAnimatedAttributes(this._baseline,"baseline",b)},d.prototype._updateYDomainer=function(){c.prototype._updateYDomainer.call(this);var a=this._yScale;a._userSetDomainer||(a.domainer().addPaddingException(0,"STACKED_AREA_PLOT+"+this._plottableID),a._autoDomainIfAutomaticMode())},d.prototype._onDatasetUpdate=function(){c.prototype._onDatasetUpdate.call(this),b.Area.prototype._onDatasetUpdate.apply(this)},d.prototype._generateAttrToProjector=function(){var a=this,b=c.prototype._generateAttrToProjector.call(this),d=b.x,e=function(b){return a._yScale.scale(b.y+b._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)},f=function(b){return a._yScale.scale(b._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)};delete b.x,delete b.y0,delete b.y,b.d=d3.svg.area().x(d).y0(f).y1(e);var g=b.fill;return b.fill=function(a,b){return g(a[0],b)},b},d}(a.Abstract.Stacked);b.StackedArea=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){void 0===e&&(e=!0),this._isVertical=e,this._baselineValue=0,this._barAlignmentFactor=.5,b.call(this,c,d),this.classed("bar-plot",!0),this.project("fill",function(){return a.Core.Colors.INDIGO}),this.baseline(this._baselineValue),this._isVertical=e}return __extends(c,b),c.prototype._setup=function(){a.Abstract.NewStyleBarPlot.prototype._setup.call(this)},c.prototype._getAnimator=function(b,c){var d=new a.Animator.Rect;return d.delay(d.duration()*c),d},c.prototype._getDrawer=function(b){return a.Abstract.NewStyleBarPlot.prototype._getDrawer.apply(this,[b])},c.prototype._generateAttrToProjector=function(){var b=this,c=a.Abstract.NewStyleBarPlot.prototype._generateAttrToProjector.apply(this),d=this._isVertical?"y":"x",e=this._isVertical?this._yScale:this._xScale,f=this._projectors[d].accessor,g=function(a){return e.scale(a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)},h=function(a){return e.scale(f(a)+a._PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET)},i=function(a){return Math.abs(h(a)-g(a))},j=c.width;c.height=this._isVertical?i:j,c.width=this._isVertical?j:i;var k=function(a){return f(a)<0?g(a):h(a)};return c[d]=function(a){return b._isVertical?k(a):k(a)-i(a)},c},c.prototype._paint=function(){b.prototype._paint.call(this);var a=this._isVertical?this._yScale:this._xScale,c=a.scale(this._baselineValue),d={x1:this._isVertical?0:c,y1:this._isVertical?c:0,x2:this._isVertical?this.width():c,y2:this._isVertical?c:this.height()};this._baseline.attr(d)},c.prototype.baseline=function(b){return a.Abstract.NewStyleBarPlot.prototype.baseline.apply(this,[b])},c.prototype._updateDomainer=function(b){return a.Abstract.NewStyleBarPlot.prototype._updateDomainer.apply(this,[b])},c.prototype._updateXDomainer=function(){return a.Abstract.NewStyleBarPlot.prototype._updateXDomainer.apply(this)},c.prototype._updateYDomainer=function(){return a.Abstract.NewStyleBarPlot.prototype._updateYDomainer.apply(this)},c}(a.Abstract.Stacked);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._duration=a.DEFAULT_DURATION_MILLISECONDS,this._delay=a.DEFAULT_DELAY_MILLISECONDS,this._easing=a.DEFAULT_EASING}return a.prototype.animate=function(a,b){return a.transition().ease(this.easing()).duration(this.duration()).delay(this.delay()).attr(b)},a.prototype.duration=function(a){return void 0===a?this._duration:(this._duration=a,this)},a.prototype.delay=function(a){return void 0===a?this._delay:(this._delay=a,this)},a.prototype.easing=function(a){return void 0===a?this._easing:(this._easing=a,this)},a.DEFAULT_DURATION_MILLISECONDS=300,a.DEFAULT_DELAY_MILLISECONDS=0,a.DEFAULT_EASING="exp-out",a}();a.Base=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.call(this),this._maxIterativeDelay=b.DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS,this._maxTotalDuration=b.DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS}return __extends(b,a),b.prototype.animate=function(a,b){var c=this,d=a[0].length,e=Math.max(this.maxTotalDuration()-this.duration(),0),f=Math.min(this.maxIterativeDelay(),e/d);return a.transition().ease(this.easing()).duration(this.duration()).delay(function(a,b){return c.delay()+f*b}).attr(b)},b.prototype.maxIterativeDelay=function(a){return void 0===a?this._maxIterativeDelay:(this._maxIterativeDelay=a,this)},b.prototype.maxTotalDuration=function(a){return null==a?this._maxTotalDuration:(this._maxTotalDuration=a,this)},b.DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS=15,b.DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS=600,b}(a.Base);a.IterativeDelay=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(b,c){void 0===b&&(b=!0),void 0===c&&(c=!1),a.call(this),this.isVertical=b,this.isReverse=c}return __extends(b,a),b.prototype.animate=function(c,d){var e={};return b.ANIMATED_ATTRIBUTES.forEach(function(a){return e[a]=d[a]}),e[this.getMovingAttr()]=this._startMovingProjector(d),e[this.getGrowingAttr()]=function(){return 0},c.attr(e),a.prototype.animate.call(this,c,d)},b.prototype._startMovingProjector=function(a){if(this.isVertical===this.isReverse)return a[this.getMovingAttr()];var b=a[this.getMovingAttr()],c=a[this.getGrowingAttr()];return function(a,d){return b(a,d)+c(a,d)}},b.prototype.getGrowingAttr=function(){return this.isVertical?"height":"width"},b.prototype.getMovingAttr=function(){return this.isVertical?"y":"x"},b.ANIMATED_ATTRIBUTES=["height","width","x","y","fill"],b}(a.Base);a.Rect=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 __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._anchor=function(a,b){this._componentToListenTo=a,this._hitBox=b},b}(a.PlottableObject);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(){a.apply(this,arguments)}return __extends(b,a),b.prototype._anchor=function(b,c){var d=this;a.prototype._anchor.call(this,b,c),c.on(this._listenTo(),function(){var a=d3.mouse(c.node()),b=a[0],e=a[1];d._callback({x:b,y: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(){a.apply(this,arguments)}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(b){function c(a){b.call(this),this.activated=!1,this.keyCode=a}return __extends(c,b),c.prototype._anchor=function(c,d){var e=this;b.prototype._anchor.call(this,c,d),d.on("mouseover",function(){e.activated=!0}),d.on("mouseout",function(){e.activated=!1}),a.Core.KeyEventListener.addCallback(this.keyCode,function(){e.activated&&null!=e._callback&&e._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){var e=this;b.call(this),null==c&&(c=new a.Scale.Linear),null==d&&(d=new a.Scale.Linear),this._xScale=c,this._yScale=d,this.zoom=d3.behavior.zoom(),this.zoom.x(this._xScale._d3Scale),this.zoom.y(this._yScale._d3Scale),this.zoom.on("zoom",function(){return e.rerenderZoomed()})}return __extends(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,c){b.prototype._anchor.call(this,a,c),this.zoom(c)},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(){b.apply(this,arguments),this.currentBar=null,this._hoverMode="point"}return __extends(c,b),c.prototype._anchor=function(c,d){var e=this;b.prototype._anchor.call(this,c,d),this.plotIsVertical=this._componentToListenTo._isVertical,this.dispatcher=new a.Dispatcher.Mouse(this._hitBox),this.dispatcher.mousemove(function(a){var b=e.getHoveredBar(a);if(null==b)e._hoverOut();else{if(null!=e.currentBar){if(e.currentBar.node()===b.node())return;e._hoverOut()}e._componentToListenTo._bars.classed("not-hovered",!0).classed("hovered",!1),b.classed("not-hovered",!1).classed("hovered",!0),null!=e.hoverCallback&&e.hoverCallback(b.data()[0],b)}e.currentBar=b}),this.dispatcher.mouseout(function(){return e._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(){var b=this;a.call(this),this.dragInitialized=!1,this._origin=[0,0],this._location=[0,0],this.dragBehavior=d3.behavior.drag(),this.dragBehavior.on("dragstart",function(){return b._dragstart()}),this.dragBehavior.on("drag",function(){return b._drag()}),this.dragBehavior.on("dragend",function(){return b._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.width(),b=this._componentToListenTo.height(),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,c){return a.prototype._anchor.call(this,b,c),c.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,d){a.prototype._anchor.call(this,c,d);var e=b.CLASS_DRAG_BOX,f=this._componentToListenTo._backgroundContainer;return this.dragBox=f.append("rect").classed(e,!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.height()),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.width(),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={})); \ No newline at end of file diff --git a/plottable.zip b/plottable.zip index 5b76e22672..36269cbaed 100644 Binary files a/plottable.zip and b/plottable.zip differ diff --git a/quicktests/html/category_axis_rotated_ticks.html b/quicktests/html/category_axis_rotated_ticks.html new file mode 100644 index 0000000000..320ab97a6d --- /dev/null +++ b/quicktests/html/category_axis_rotated_ticks.html @@ -0,0 +1,32 @@ + + + + Category Axis Rotated Ticks + + + + + + + + + + + +
+ + + diff --git a/quicktests/html/interaction_BarHover.html b/quicktests/html/interaction_BarHover.html index 110b69aad5..cfa66d7b4c 100644 --- a/quicktests/html/interaction_BarHover.html +++ b/quicktests/html/interaction_BarHover.html @@ -1,12 +1,13 @@ - Interaction Bar Hover + Interaction Barhover + + + + + + + + + +
+ + + diff --git a/quicktests/html/missing_stacked_bar.html b/quicktests/html/missing_stacked_bar.html new file mode 100644 index 0000000000..fc315855a1 --- /dev/null +++ b/quicktests/html/missing_stacked_bar.html @@ -0,0 +1,32 @@ + + + + Missing Stacked Bar + + + + + + + + + + + +
+ + + diff --git a/quicktests/html/rainfall_ClusteredBar.html b/quicktests/html/rainfall_ClusteredBar.html index d66b50d6e5..d7f95fa523 100644 --- a/quicktests/html/rainfall_ClusteredBar.html +++ b/quicktests/html/rainfall_ClusteredBar.html @@ -5,28 +5,14 @@ - + @@ -40,9 +26,7 @@ -
-
diff --git a/quicktests/html/rainfall_VerticalBar.html b/quicktests/html/rainfall_VerticalBar.html index c2437c5da7..593f674ae2 100644 --- a/quicktests/html/rainfall_VerticalBar.html +++ b/quicktests/html/rainfall_VerticalBar.html @@ -5,37 +5,14 @@ - + diff --git a/quicktests/html/scatter_plot_project.html b/quicktests/html/scatter_plot_project.html index 30131313e4..d0fb2b151a 100644 --- a/quicktests/html/scatter_plot_project.html +++ b/quicktests/html/scatter_plot_project.html @@ -12,7 +12,7 @@ padding: 20px; } - + @@ -29,4 +29,4 @@
- \ No newline at end of file + diff --git a/quicktests/html/stacked-bar-test.html b/quicktests/html/stacked_bar.html similarity index 92% rename from quicktests/html/stacked-bar-test.html rename to quicktests/html/stacked_bar.html index f6ce635f2c..394b672a60 100644 --- a/quicktests/html/stacked-bar-test.html +++ b/quicktests/html/stacked_bar.html @@ -15,7 +15,7 @@ - + + + + + + + + + +
+ + + diff --git a/quicktests/js/animate_area.js b/quicktests/js/animate_area.js index ac21ef8249..cc3e7504fb 100644 --- a/quicktests/js/animate_area.js +++ b/quicktests/js/animate_area.js @@ -17,7 +17,10 @@ function run(div, data, Plottable) { var yScale = new Plottable.Scale.Linear(); var yAxis = new Plottable.Axis.Numeric(yScale, "left"); - var areaRenderer = new Plottable.Plot.Area(data[0].slice(0, 20), xScale, yScale); + var areaData = data[0].slice(0, 20); + areaData[10].y = NaN; + areaData[13].x = undefined; + var areaRenderer = new Plottable.Plot.Area(areaData, xScale, yScale); areaRenderer.attr("opacity", 0.75); areaRenderer.animate(doAnimate); diff --git a/quicktests/js/animate_line.js b/quicktests/js/animate_line.js index fd280a1e5a..624b35bcc3 100644 --- a/quicktests/js/animate_line.js +++ b/quicktests/js/animate_line.js @@ -16,7 +16,10 @@ function run(div, data, Plottable) { var yScale = new Plottable.Scale.Linear(); var yAxis = new Plottable.Axis.Numeric(yScale, "left"); - var lineRenderer = new Plottable.Plot.Line(data[0].slice(0, 20), xScale, yScale); + var lineData = data[0].slice(0, 20); + lineData[10].y = NaN; + lineData[13].x = undefined; + var lineRenderer = new Plottable.Plot.Line(lineData, xScale, yScale); lineRenderer.attr("opacity", 0.75); lineRenderer.animate(doAnimate); diff --git a/quicktests/js/category_axis_rotated_ticks.js b/quicktests/js/category_axis_rotated_ticks.js new file mode 100644 index 0000000000..2973092b2c --- /dev/null +++ b/quicktests/js/category_axis_rotated_ticks.js @@ -0,0 +1,67 @@ + +function makeData() { + "use strict"; + + var data1 = [ + {date: "2000", y: 100000}, + {date: "2001", y: 120000}, + {date: "2002", y: 130000}, + {date: "2003", y: 150000}, + {date: "2004", y: 110000}, + {date: "2005", y: 20000}, + {date: "2006", y: 200000}, + {date: "2007", y: 250000}, + {date: "2008", y: 220000}, + {date: "2009", y: 300000}, + {date: "2010", y: 100000}, + {date: "2011", y: 120000}, + {date: "2012", y: 130000}, + {date: "2013", y: 150000}, + {date: "2014", y: 110000}, + {date: "2015", y: 20000}, + {date: "2016", y: 200000}, + {date: "2017", y: 250000}, + {date: "2018", y: 220000}, + {date: "2019", y: 300000}, + {date: "2020", y: 100000}, + {date: "2021", y: 120000}, + {date: "2022", y: 130000}, + {date: "2023", y: 150000}, + {date: "2024", y: 110000}, + {date: "2025", y: 20000}, + {date: "2026", y: 200000}, + {date: "2027", y: 250000}, + {date: "2028", y: 220000}, + {date: "2029", y: 300000}, + {date: "2030", y: 100000}, + {date: "2031", y: 120000}, + {date: "2032", y: 130000}, + {date: "2033", y: 150000}, + {date: "2034", y: 110000}, + {date: "2035", y: 20000}, + {date: "2036", y: 200000}, + {date: "2037", y: 250000}, + {date: "2038", y: 220000}, + {date: "2039", y: 300000} + ]; + + return data1; +} + +function run(div, data, Plottable) { + "use strict"; + + var svg = div.append("svg").attr("height", 500); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + + var xAxis1 = new Plottable.Axis.Category(xScale, "bottom").tickLabelAngle(-90); + var xAxis2 = new Plottable.Axis.Category(xScale, "bottom").tickLabelAngle(0); + var xAxis3 = new Plottable.Axis.Category(xScale, "bottom").tickLabelAngle(90); + var yAxis = new Plottable.Axis.Numeric(yScale, "left"); + + var plot = new Plottable.Plot.VerticalBar(data, xScale, yScale) + .project("x", "date", xScale) + .project("y", "y", yScale); + var table = new Plottable.Component.Table([[yAxis, plot], [null, xAxis1], [null, xAxis2], [null, xAxis3]]).renderTo(svg); +} diff --git a/quicktests/js/missing_clustered_bar.js b/quicktests/js/missing_clustered_bar.js new file mode 100644 index 0000000000..84295a9601 --- /dev/null +++ b/quicktests/js/missing_clustered_bar.js @@ -0,0 +1,35 @@ +function makeData() { + "use strict"; + + var data1 = [{name: "jon", y: 1, type: "q1"}, {name: "dan", y: 2, type: "q1"}, {name: "zoo", y: 1, type: "q1"}]; + var data2 = [{name: "jon", y: 2, type: "q2"}, {name: "dan", y: 4, type: "q2"}]; + var data3 = [{name: "dan", y: 15, type: "q3"}, {name: "zoo", y: 15, type: "q3"}]; + return [data1, data2, data3]; +} + +function run(div, data, Plottable) { + "use strict"; + + var svg = div.append("svg").attr("height", 500); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + var colorScale = new Plottable.Scale.Color("10"); + + var xAxis = new Plottable.Axis.Category(xScale, "bottom"); + var yAxis = new Plottable.Axis.Numeric(yScale, "left"); + var clusteredBarRenderer = new Plottable.Plot.ClusteredBar(xScale, yScale) + .addDataset("d1", data[0]) + .addDataset("d2", data[1]) + .addDataset("d3", data[2]) + .attr("x", "name", xScale) + .attr("y", "y", yScale) + .attr("fill", "type", colorScale) + .attr("type", "type") + .attr("yval", "y"); + + var center = clusteredBarRenderer.merge(new Plottable.Component.Legend(colorScale)); + + new Plottable.Component.Table([ + [yAxis, center], [null, xAxis] + ]).renderTo(svg); +} diff --git a/quicktests/js/missing_stacked_bar.js b/quicktests/js/missing_stacked_bar.js new file mode 100644 index 0000000000..c12f41a63b --- /dev/null +++ b/quicktests/js/missing_stacked_bar.js @@ -0,0 +1,36 @@ +function makeData() { + "use strict"; + + var data1 = [{name: "jon", y: 1, type: "q1"}, {name: "dan", y: 2, type: "q1"}, {name: "zoo", y: 1, type: "q1"}]; + var data2 = [{name: "jon", y: 2, type: "q2"}, {name: "dan", y: 4, type: "q2"}]; + var data3 = [{name: "dan", y: 15, type: "q3"}, {name: "zoo", y: 15, type: "q3"}]; + return [data1, data2, data3]; +} + +function run(div, data, Plottable) { + "use strict"; + + var svg = div.append("svg").attr("height", 500); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + var colorScale = new Plottable.Scale.Color("10"); + + var xAxis = new Plottable.Axis.Category(xScale, "bottom"); + var yAxis = new Plottable.Axis.Numeric(yScale, "left"); + var stackedBarPlot = new Plottable.Plot.StackedBar(xScale, yScale) + .attr("x", "name", xScale) + .attr("y", "y", yScale) + .attr("fill", "type", colorScale) + .attr("type", "type") + .attr("yval", "y") + .addDataset("d1", data[0]) + .addDataset("d2", data[1]) + .addDataset("d3", data[2]) + .animate(true); + + var center = stackedBarPlot.merge(new Plottable.Component.Legend(colorScale)); + + var horizChart = new Plottable.Component.Table([ + [yAxis, center], [null, xAxis] + ]).renderTo(svg); +} diff --git a/quicktests/js/rainfall_ClusteredBar.js b/quicktests/js/rainfall_ClusteredBar.js index 6ae01c0291..8423932bdb 100644 --- a/quicktests/js/rainfall_ClusteredBar.js +++ b/quicktests/js/rainfall_ClusteredBar.js @@ -29,7 +29,7 @@ function run(div, data, Plottable){ var legend = new Plottable.Component.HorizontalLegend(colorScale); var title = new Plottable.Component.TitleLabel("Average Rainfall in Different Cities between 2013-2014", "horizontal" ); - var yUnitLabel = new Plottable.Component.AxisLabel("Inches", "vertical-left" ); + var yUnitLabel = new Plottable.Component.AxisLabel("Inches", "left" ); var chart = new Plottable.Component.Table([ [null , null , title ], diff --git a/quicktests/js/rainfall_VerticalBar.js b/quicktests/js/rainfall_VerticalBar.js index 0b11ad3c54..c0b9713e86 100644 --- a/quicktests/js/rainfall_VerticalBar.js +++ b/quicktests/js/rainfall_VerticalBar.js @@ -44,7 +44,7 @@ function run(div, data, Plottable){ var legend = new Plottable.Component.HorizontalLegend(colorScale); var title = new Plottable.Component.TitleLabel("Average Rainfall in Different Cities between 2013-2014", "horizontal" ); - var yUnitLabel = new Plottable.Component.AxisLabel("Inches", "vertical-left" ); + var yUnitLabel = new Plottable.Component.AxisLabel("Inches", "left" ); legend.xAlign("right"); diff --git a/quicktests/js/scatter_plot_project.js b/quicktests/js/scatter_plot_project.js index a29799b2b6..08deafa67c 100644 --- a/quicktests/js/scatter_plot_project.js +++ b/quicktests/js/scatter_plot_project.js @@ -27,7 +27,7 @@ function run(div, data, Plottable) { [subtitleLabel] ]).xAlign("center"); - var yAxisLabel = new Plottable.Component.AxisLabel("Absolute Value of Apparent Visual Magnitude", "vertical-left"); + var yAxisLabel = new Plottable.Component.AxisLabel("Absolute Value of Apparent Visual Magnitude", "left"); var xAxisLabel = new Plottable.Component.AxisLabel("Distance in parsecs"); var plotTable = new Plottable.Component.Table([ [yAxisLabel, yAxis, scatterRenderer], diff --git a/quicktests/js/stacked_bar.js b/quicktests/js/stacked_bar.js index 20ccc4ac53..455cd56e71 100644 --- a/quicktests/js/stacked_bar.js +++ b/quicktests/js/stacked_bar.js @@ -18,14 +18,14 @@ function run(div, data, Plottable) { var xAxis = new Plottable.Axis.Category(xScale, "bottom"); var yAxis = new Plottable.Axis.Numeric(yScale, "left"); var stackedBarPlot = new Plottable.Plot.StackedBar(xScale, yScale) - .addDataset("d1", data[0]) - .addDataset("d2", data[1]) - .addDataset("d3", data[2]) .attr("x", "name", xScale) .attr("y", "y", yScale) .attr("fill", "type", colorScale) .attr("type", "type") .attr("yval", "y") + .addDataset("d1", data[0]) + .addDataset("d2", data[1]) + .addDataset("d3", data[2]) .animate(true); var center = stackedBarPlot.merge(new Plottable.Component.Legend(colorScale)); diff --git a/quicktests/js/timeAxis_area_bar.js b/quicktests/js/timeAxis_area_bar.js new file mode 100644 index 0000000000..03ff786ce8 --- /dev/null +++ b/quicktests/js/timeAxis_area_bar.js @@ -0,0 +1,110 @@ + +function makeData() { + "use strict"; + + var data1 = [ + {date: "1/1/2015", y: 100000, type: "A"}, + {date: "1/1/2016", y: 200000, type: "A"}, + {date: "1/1/2017", y: 250000, type: "A"}, + {date: "1/1/2018", y: 220000, type: "A"}, + {date: "1/1/2019", y: 300000, type: "A"} + ]; + var data2 = [ + {date: "1/1/2015", y: 100000, type: "B"}, + {date: "1/1/2016", y: 200000, type: "B"}, + {date: "1/1/2017", y: 250000, type: "B"}, + {date: "1/1/2018", y: 220000, type: "B"}, + {date: "1/1/2019", y: 300000, type: "B"} + ]; + var data3 = [ + {date: "1/1/2015", y: 100000, type: "C"}, + {date: "1/1/2016", y: 200000, type: "C"}, + {date: "1/1/2017", y: 250000, type: "C"}, + {date: "1/1/2018", y: 220000, type: "C"}, + {date: "1/1/2019", y: 300000, type: "C"} + ]; + var data4 = [ + {date: "1/1/2015", y: 100000, type: "D"}, + {date: "1/1/2016", y: 200000, type: "D"}, + {date: "1/1/2017", y: 250000, type: "D"}, + {date: "1/1/2018", y: 220000, type: "D"}, + {date: "1/1/2019", y: 300000, type: "D"} + ]; + var data5 = [ + {date: "1/1/2015", y: 100000, type: "E"}, + {date: "1/1/2016", y: 200000, type: "E"}, + {date: "1/1/2017", y: 250000, type: "E"}, + {date: "1/1/2018", y: 220000, type: "E"}, + {date: "1/1/2019", y: 300000, type: "E"} + ]; + +return [data1, data2, data3, data4, data5]; + +} + +function run(div, data, Plottable) { + "use strict"; + + var svg = div.append("svg").attr("height", 500); + var formatter = d3.time.format("%Y"); + var xScale = new Plottable.Scale.Time().numTicks(5); + var yScale1 = new Plottable.Scale.Linear(); + var yScale2 = new Plottable.Scale.Linear(); + + var xAxis1 = new Plottable.Axis.Numeric(xScale, "bottom", formatter); + var xAxis2 = new Plottable.Axis.Numeric(xScale, "bottom", formatter); + var xAxis3 = new Plottable.Axis.Numeric(xScale, "bottom", formatter); + var xAxis4 = new Plottable.Axis.Numeric(xScale, "bottom", formatter); + + var yAxis1 = new Plottable.Axis.Numeric(yScale1, "left"); + var yAxis2 = new Plottable.Axis.Numeric(yScale1, "left"); + var yAxis3 = new Plottable.Axis.Numeric(yScale2, "left"); + var yAxis4 = new Plottable.Axis.Numeric(yScale2, "left"); + + var timeFormat = function (data) { return d3.time.format("%m/%d/%Y").parse(data.date);}; + var colorScale = new Plottable.Scale.Color(); + var legend = new Plottable.Component.HorizontalLegend(colorScale).xAlign("center"); + var title = new Plottable.Component.TitleLabel("Area & Bar on Time Axes"); + + var areaPlot = new Plottable.Plot.Area(data[0], xScale, yScale1) + .project("x", timeFormat, xScale); + + var barPlot = new Plottable.Plot.VerticalBar(data[0], xScale, yScale1) + .project("x", timeFormat, xScale) + .project("width", 40) + .barAlignment("center"); + + var stackedArea = new Plottable.Plot.StackedArea(xScale, yScale2) + .project("x", timeFormat, xScale) + .project("fill", "type", colorScale) + .addDataset(data[0]) + .addDataset(data[1]) + .addDataset(data[2]) + .addDataset(data[3]) + .addDataset(data[4]); + + var stackedBar = new Plottable.Plot.StackedBar(xScale, yScale2) + .project("x", timeFormat, xScale) + .project("fill", "type", colorScale) + .project("width", 40) + .addDataset(data[0]) + .addDataset(data[1]) + .addDataset(data[2]) + .addDataset(data[3]) + .addDataset(data[4]); + + var upperChart = new Plottable.Component.Table([ + [yAxis1, areaPlot, yAxis2, barPlot], + [null, xAxis1, null, xAxis2] + ]); + + var lowerChart = new Plottable.Component.Table([ + [yAxis3, stackedArea, yAxis4, stackedBar], + [null, xAxis3, null, xAxis4] + ]); + + var chart = new Plottable.Component.Table([[title], [legend], [upperChart], [lowerChart]]); + + chart.renderTo(svg); + +} diff --git a/quicktests/list_of_quicktests.json b/quicktests/list_of_quicktests.json index dde7dab92a..ecef7dd690 100644 --- a/quicktests/list_of_quicktests.json +++ b/quicktests/list_of_quicktests.json @@ -41,6 +41,9 @@ }, { "name":"category_project", "categories":["Data", "Datasource", "Ordinal Scale", "Category Axis", "Linear Scale", "Numeric Axis", "Vertical Bar Plot", "Project", "Animate", "Title", "Label"] + }, { + "name":"category_axis_rotated_ticks", + "categories":["Data", "Datasource", "Ordinal Scale", "Category Axis", "Linear Scale", "Numeric Axis", "Vertical Bar Plot"] }, { "name":"category_verticalBar", "categories":["Data", "Datasource", "Ordinal Scale", "Category Axis", "Linear Scale", "Numeric Axis", "Vertical Bar Plot", "Project", "Animate"] @@ -77,6 +80,9 @@ }, { "name":"legend_basic", "categories":["Legend", "Title", "Gridlines", "Color Scale", "Axis Label", "Scatter Plot", "Line Plot", "Numeric Axis", "Metadata", "Project", "Merge", "Linear Scale"] + }, { + "name":"missing_stacked_bar", + "categories":["Linear Scale", "Numeric Axis", "Animate", "Legend", "Category Axis", "Linear Scale", "Vertical Bar Plot", "Stacked Plot"] }, { "name":"modifiedLog", "categories":["Datasource", "Metadata", "Modified Log Scale", "Color Scale", "Line Plot", "Numeric Axis", "Accessor", "Project", "Toggle Legend"] @@ -125,10 +131,13 @@ }, { "name":"stacked_bar", "categories":["Linear Scale", "Numeric Axis", "Animate", "Legend", "Category Axis", "Linear Scale", "Vertical Bar Plot", "Stacked Plot"] - }, { + }, { + "name":"timeAxis_area_bar", + "categories":["Linear Scale", "Numeric Axis", "Time Scale", "Time Axis", "Vertical Bar Plot", "Stacked Plot", "Title", "Legend"] + }, { "name":"titleLegend_change", "categories":["Datasource", "Metadata", "Color Scale", "Scatter Plot", "Line Plot", "Area Plot", "Domain", "Linear Scale", "Numeric Axis", "Project", "Accessor", "Title", "Label", "Layout", "Legend", "Click Interaction"] - }, { + }, { "name":"stocks", "categories":["Integration", "Vertical Bar Plot", "Legend", "Layout", "PanZoom Interaction", "Key Interaction"] } diff --git a/src/animators/iterativeDelayAnimator.ts b/src/animators/iterativeDelayAnimator.ts index d837a918c8..88f8c9794e 100644 --- a/src/animators/iterativeDelayAnimator.ts +++ b/src/animators/iterativeDelayAnimator.ts @@ -7,15 +7,28 @@ export 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. + * The maximum delay between animations can be configured with maxIterativeDelay. + * + * The maximum total animation duration can be configured with maxTotalDuration. + * maxTotalDuration does not set actual total animation duration. + * + * The actual interval delay is calculated by following formula: + * min(maxIterativeDelay(), + * max(totalDurationLimit() - duration(), 0) / ) */ export class IterativeDelay extends Base { /** - * The start delay between each start of an animation + * The default maximum start delay between each start of an animation + */ + public static DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS = 15; + + /** + * The default maximum total animation duration */ - public static DEFAULT_ITERATIVE_DELAY_MILLISECONDS = 15; + public static DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS = 600; - private _iterativeDelay: number; + private _maxIterativeDelay: number; + private _maxTotalDuration: number; /** * Constructs an animator with a start delay between each selection animation @@ -24,39 +37,64 @@ export module Animator { */ constructor() { super(); - this._iterativeDelay = IterativeDelay.DEFAULT_ITERATIVE_DELAY_MILLISECONDS; + this._maxIterativeDelay = IterativeDelay.DEFAULT_MAX_ITERATIVE_DELAY_MILLISECONDS; + this._maxTotalDuration = IterativeDelay.DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS; } public animate(selection: any, attrToProjector: IAttributeToProjector): D3.Selection { + var numberOfIterations = selection[0].length; + var maxDelayForLastIteration = Math.max(this.maxTotalDuration() - this.duration(), 0); + var adjustedIterativeDelay = Math.min(this.maxIterativeDelay(), maxDelayForLastIteration / numberOfIterations); return selection.transition() .ease(this.easing()) .duration(this.duration()) - .delay((d: any, i: number) => this.delay() + this.iterativeDelay() * i) + .delay((d: any, i: number) => this.delay() + adjustedIterativeDelay * i) .attr(attrToProjector); } /** - * Gets the start delay between animations in milliseconds. + * Gets the maximum start delay between animations in milliseconds. * - * @returns {number} The current iterative delay. + * @returns {number} The current maximum iterative delay. */ - public iterativeDelay(): number; + public maxIterativeDelay(): number; /** - * Sets the start delay between animations in milliseconds. + * Sets the maximum start delay between animations in milliseconds. * - * @param {number} iterDelay The iterative delay in milliseconds. + * @param {number} maxIterDelay The maximum iterative delay in milliseconds. * @returns {IterativeDelay} The calling IterativeDelay Animator. */ - public iterativeDelay(iterDelay: number): IterativeDelay; - public iterativeDelay(iterDelay?: number): any { - if (iterDelay === undefined) { - return this._iterativeDelay; + public maxIterativeDelay(maxIterDelay: number): IterativeDelay; + public maxIterativeDelay(maxIterDelay?: number): any { + if (maxIterDelay === undefined) { + return this._maxIterativeDelay; } else { - this._iterativeDelay = iterDelay; + this._maxIterativeDelay = maxIterDelay; return this; } } + /** + * Gets the maximum total animation duration in milliseconds. + * + * @returns {number} The current maximum total animation duration. + */ + public maxTotalDuration(): number; + /** + * Sets the maximum total animation duration in miliseconds. + * + * @param {number} maxDuration The maximum total animation duration in milliseconds. + * @returns {IterativeDelay} The calling IterativeDelay Animator. + */ + public maxTotalDuration(maxDuration: number): IterativeDelay; + public maxTotalDuration(maxDuration?: number): any { + if (maxDuration == null) { + return this._maxTotalDuration; + } else { + this._maxTotalDuration = maxDuration; + return this; + } + } } } diff --git a/src/components/axes/baseAxis.ts b/src/components/axes/baseAxis.ts index f51c38b53f..042e180474 100644 --- a/src/components/axes/baseAxis.ts +++ b/src/components/axes/baseAxis.ts @@ -45,7 +45,7 @@ export module Abstract { if (scale == null || orientation == null) {throw new Error("Axis requires a scale and orientation");} this._scale = scale; this.orient(orientation); - + this._setDefaultAlignment(); this.classed("axis", true); if (this._isHorizontal()) { this.classed("x-axis", true); @@ -236,6 +236,26 @@ export module Abstract { super._invalidateLayout(); } + public _setDefaultAlignment() { + switch(this._orientation) { + case "bottom": + this.yAlign("top"); + break; + + case "top": + this.yAlign("bottom"); + break; + + case "left": + this.xAlign("right"); + break; + + case "right": + this.xAlign("left"); + break; + } + } + /** * Gets the current formatter on the axis. Data is passed through the * formatter before being displayed. diff --git a/src/components/axes/categoryAxis.ts b/src/components/axes/categoryAxis.ts index 2b34edd97e..e3d9e626d4 100644 --- a/src/components/axes/categoryAxis.ts +++ b/src/components/axes/categoryAxis.ts @@ -4,6 +4,7 @@ module Plottable { export module Axis { export class Category extends Abstract.Axis { public _scale: Scale.Ordinal; + private _tickLabelAngle = 0; private measurer: _Util.Text.CachingCharacterMeasurer; /** @@ -60,6 +61,44 @@ export module Axis { return this._scale.domain(); } + /** + * Sets the angle for the tick labels. Right now vertical-left (-90), horizontal (0), and vertical-right (90) are the only options. + * @param {number} angle The angle for the ticks + * @returns {Category} The calling Category Axis. + * + * Warning - this is not currently well supported and is likely to behave badly unless all the tick labels are short. + * See tracking at https://github.com/palantir/plottable/issues/504 + */ + public tickLabelAngle(angle: number): Category; + /** + * Gets the tick label angle + * @returns {number} the tick label angle + */ + public tickLabelAngle(): number; + public tickLabelAngle(angle?: number): any { + if (angle == null) { + return this._tickLabelAngle; + } + if (angle !== 0 && angle !== 90 && angle !== -90) { + throw new Error("Angle " + angle + " not supported; only 0, 90, and -90 are valid values"); + } + this._tickLabelAngle = angle; + this._invalidateLayout(); + return this; + } + + private tickLabelOrientation() { + switch(this._tickLabelAngle) { + case 0: + return "horizontal"; + case -90: + return "left"; + case 90: + return "right"; + default: + throw new Error("bad orientation"); + } + } /** * Measures the size of the ticks while also writing them to the DOM. @@ -94,17 +133,18 @@ export module Axis { var textWriteResult: _Util.Text.IWriteTextResult; var formatter = self._formatter; + if (draw) { var d3this = d3.select(this); var xAlign: {[s: string]: string} = {left: "right", right: "left", top: "center", bottom: "center"}; var yAlign: {[s: string]: string} = {left: "center", right: "center", top: "bottom", bottom: "top"}; - textWriteResult = _Util.Text.writeText(formatter(d), width, height, tm, true, { + textWriteResult = _Util.Text.writeText(formatter(d), width, height, tm, self.tickLabelOrientation(), { g: d3this, xAlign: xAlign[self._orientation], yAlign: yAlign[self._orientation] }); } else { - textWriteResult = _Util.Text.writeText(formatter(d), width, height, tm, true); + textWriteResult = _Util.Text.writeText(formatter(d), width, height, tm, self.tickLabelOrientation()); } textWriteResults.push(textWriteResult); diff --git a/src/components/component.ts b/src/components/component.ts index 39f3e33bb9..b07bc62335 100644 --- a/src/components/component.ts +++ b/src/components/component.ts @@ -143,16 +143,17 @@ export module Abstract { var requestedSpace = this._requestedSpace(availableWidth , availableHeight); - xPosition += (availableWidth - requestedSpace.width) * this._xAlignProportion; xPosition += this._xOffset; if (this._isFixedWidth()) { + xPosition += (availableWidth - requestedSpace.width) * this._xAlignProportion; + // 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()) { + yPosition += (availableHeight - requestedSpace.height) * this._yAlignProportion; availableHeight = Math.min(availableHeight, requestedSpace.height); } diff --git a/src/components/label.ts b/src/components/label.ts index c4b2e2d045..f207e53050 100644 --- a/src/components/label.ts +++ b/src/components/label.ts @@ -18,7 +18,7 @@ export module Component { * * @constructor * @param {string} displayText The text of the Label (default = ""). - * @param {string} orientation The orientation of the Label (horizontal/vertical-left/vertical-right) (default = "horizontal"). + * @param {string} orientation The orientation of the Label (horizontal/left/right) (default = "horizontal"). */ constructor(displayText = "", orientation = "horizontal") { super(); @@ -111,7 +111,7 @@ export module Component { * Sets the orientation of the Label. * * @param {string} newOrientation If provided, the desired orientation - * (horizontal/vertical-left/vertical-right). + * (horizontal/left/right). * @returns {Label} The calling Label. */ public orient(newOrientation: string): Label; @@ -120,8 +120,6 @@ export module Component { return this.orientation; } else { newOrientation = newOrientation.toLowerCase(); - if (newOrientation === "vertical-left") { newOrientation = "left" ; } - if (newOrientation === "vertical-right") { newOrientation = "right"; } if (newOrientation === "horizontal" || newOrientation === "left" || newOrientation === "right") { this.orientation = newOrientation; } else { diff --git a/src/components/plots/areaPlot.ts b/src/components/plots/areaPlot.ts index 2b7c7848df..1ab0a87132 100644 --- a/src/components/plots/areaPlot.ts +++ b/src/components/plots/areaPlot.ts @@ -84,18 +84,18 @@ export module Plot { this.areaPath.datum(this._dataset.data()); + var area = d3.svg.area() + .x(xFunction) + .y0(y0Function); + area.defined((d, i) => this._rejectNullsAndNaNs(d, i, xFunction) && this._rejectNullsAndNaNs(d, i, yFunction)); + attrToProjector["d"] = area; + if (this._dataChanged) { - attrToProjector["d"] = d3.svg.area() - .x(xFunction) - .y0(y0Function) - .y1(this._getResetYFunction()); + area.y1(this._getResetYFunction()); this._applyAnimatedAttributes(this.areaPath, "area-reset", attrToProjector); } - attrToProjector["d"] = d3.svg.area() - .x(xFunction) - .y0(y0Function) - .y1(yFunction); + area.y1(yFunction); this._applyAnimatedAttributes(this.areaPath, "area", attrToProjector); } diff --git a/src/components/plots/clusteredBarPlot.ts b/src/components/plots/clusteredBarPlot.ts index 6727e31449..edaa5df3bf 100644 --- a/src/components/plots/clusteredBarPlot.ts +++ b/src/components/plots/clusteredBarPlot.ts @@ -42,10 +42,6 @@ export module Plot { private cluster(accessor: _IAccessor) { this.innerScale.domain(this._datasetKeysInOrder); - var lengths = this._getDatasetsInOrder().map((d) => d.data().length); - if (_Util.Methods.uniq(lengths).length > 1) { - _Util.Methods.warn("Warning: Attempting to cluster data when datasets are of unequal length"); - } var clusters: {[key: string]: any[]} = {}; this._datasetKeysInOrder.forEach((key: string) => { var data = this._key2DatasetDrawerKey.get(key).dataset.data(); diff --git a/src/components/plots/linePlot.ts b/src/components/plots/linePlot.ts index d40a97d4cc..c542da748c 100644 --- a/src/components/plots/linePlot.ts +++ b/src/components/plots/linePlot.ts @@ -61,6 +61,11 @@ export module Plot { return attrToProjector; } + public _rejectNullsAndNaNs(d: any, i: number, projector: IAppliedAccessor) { + var value = projector(d, i); + return value != null && value === value; + } + public _paint() { super._paint(); var attrToProjector = this._generateAttrToProjector(); @@ -71,16 +76,17 @@ export module Plot { this.linePath.datum(this._dataset.data()); + var line = d3.svg.line() + .x(xFunction); + line.defined((d, i) => this._rejectNullsAndNaNs(d, i, xFunction) && this._rejectNullsAndNaNs(d, i, yFunction)); + attrToProjector["d"] = line; + if (this._dataChanged) { - attrToProjector["d"] = d3.svg.line() - .x(xFunction) - .y(this._getResetYFunction()); + line.y(this._getResetYFunction()); this._applyAnimatedAttributes(this.linePath, "line-reset", attrToProjector); } - attrToProjector["d"] = d3.svg.line() - .x(xFunction) - .y(yFunction); + line.y(yFunction); this._applyAnimatedAttributes(this.linePath, "line", attrToProjector); } diff --git a/src/components/plots/stackedPlot.ts b/src/components/plots/stackedPlot.ts index e64f0a64c3..635d42b77f 100644 --- a/src/components/plots/stackedPlot.ts +++ b/src/components/plots/stackedPlot.ts @@ -18,63 +18,61 @@ export module Abstract { super._onDatasetUpdate(); // HACKHACK Caused since onDataSource is called before projectors are set up. Should be fixed by #803 if (this._datasetKeysInOrder && this._projectors["x"] && this._projectors["y"]) { - this.stack(); + this.updateStackOffsets(); } } - private stack() { - var datasets = this._getDatasetsInOrder(); - var keyAccessor = this._isVertical ? this._projectors["x"].accessor : this._projectors["y"].accessor; - var valueAccessor = this._isVertical ? this._projectors["y"].accessor : this._projectors["x"].accessor; - - var dataArray: StackedDatum[][] = datasets.map((dataset) => { - return dataset.data().map((datum) => { - return {key: keyAccessor(datum), value: valueAccessor(datum)}; - }); - }); + private updateStackOffsets() { + var dataMapArray = this.generateDefaultMapArray(); + var domainKeys = this.getDomainKeys(); - var positiveDataArray: StackedDatum[][] = dataArray.map((data) => { - return data.map((datum) => { - return {key: datum.key, value: Math.max(0, datum.value)}; + var positiveDataMapArray: D3.Map[] = dataMapArray.map((dataMap) => { + return _Util.Methods.populateMap(domainKeys, (domainKey) => { + return { key: domainKey, value: Math.max(0, dataMap.get(domainKey).value) }; }); }); - var negativeDataArray: StackedDatum[][] = dataArray.map((data) => { - return data.map((datum) => { - return {key: datum.key, value: Math.min(datum.value, 0)}; + var negativeDataMapArray: D3.Map[] = dataMapArray.map((dataMap) => { + return _Util.Methods.populateMap(domainKeys, (domainKey) => { + return { key: domainKey, value: Math.min(dataMap.get(domainKey).value, 0) }; }); }); - this.setDatasetStackOffsets(this._stack(positiveDataArray), this._stack(negativeDataArray)); + this.setDatasetStackOffsets(this.stack(positiveDataMapArray), this.stack(negativeDataMapArray)); + this.updateStackExtents(); + } - var maxStack = _Util.Methods.max(datasets, (dataset: Dataset) => { + private updateStackExtents() { + var datasets = this._getDatasetsInOrder(); + var valueAccessor = this.valueAccessor(); + var maxStackExtent = _Util.Methods.max(datasets, (dataset: Dataset) => { return _Util.Methods.max(dataset.data(), (datum: any) => { return valueAccessor(datum) + datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]; }); }); - var minStack = _Util.Methods.min(datasets, (dataset: Dataset) => { + var minStackExtent = _Util.Methods.min(datasets, (dataset: Dataset) => { return _Util.Methods.min(dataset.data(), (datum: any) => { return valueAccessor(datum) + datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"]; }); }); - this.stackedExtent = [Math.min(minStack, 0), Math.max(0, maxStack)]; + this.stackedExtent = [Math.min(minStackExtent, 0), Math.max(0, maxStackExtent)]; } /** * Feeds the data through d3's stack layout function which will calculate * the stack offsets and use the the function declared in .out to set the offsets on the data. */ - private _stack(dataArray: StackedDatum[][]): StackedDatum[][] { - var outFunction = (d: any, y0: number, y: number) => { + private stack(dataArray: D3.Map[]): D3.Map[] { + var outFunction = (d: StackedDatum, y0: number, y: number) => { d.offset = y0; }; d3.layout.stack() .x((d) => d.key) .y((d) => d.value) - .values((d) => d) + .values((d) => this.getDomainKeys().map((domainKey) => d.get(domainKey))) .out(outFunction)(dataArray); return dataArray; @@ -84,21 +82,60 @@ export module Abstract { * After the stack offsets have been determined on each separate dataset, the offsets need * to be determined correctly on the overall datasets */ - private setDatasetStackOffsets(positiveDataArray: StackedDatum[][], negativeDataArray: StackedDatum[][]) { - var valueAccessor = this._isVertical ? this._projectors["y"].accessor : this._projectors["x"].accessor; - var positiveDataArrayOffsets = positiveDataArray.map((data) => data.map((datum) => datum.offset)); - var negativeDataArrayOffsets = negativeDataArray.map((data) => data.map((datum) => datum.offset)); + private setDatasetStackOffsets(positiveDataMapArray: D3.Map[], negativeDataMapArray: D3.Map[]) { + var keyAccessor = this.keyAccessor(); + var valueAccessor = this.valueAccessor(); this._getDatasetsInOrder().forEach((dataset, datasetIndex) => { + var positiveDataMap = positiveDataMapArray[datasetIndex]; + var negativeDataMap = negativeDataMapArray[datasetIndex]; + dataset.data().forEach((datum: any, datumIndex: number) => { - var positiveOffset = positiveDataArrayOffsets[datasetIndex][datumIndex]; - var negativeOffset = negativeDataArrayOffsets[datasetIndex][datumIndex]; + var positiveOffset = positiveDataMap.get(keyAccessor(datum)).offset; + var negativeOffset = negativeDataMap.get(keyAccessor(datum)).offset; datum["_PLOTTABLE_PROTECTED_FIELD_STACK_OFFSET"] = valueAccessor(datum) > 0 ? positiveOffset : negativeOffset; }); }); } + private getDomainKeys(): string[] { + var keyAccessor = this.keyAccessor(); + var domainKeys = d3.set(); + var datasets = this._getDatasetsInOrder(); + + datasets.forEach((dataset) => { + dataset.data().forEach((datum) => { + domainKeys.add(keyAccessor(datum)); + }); + }); + + return domainKeys.values(); + } + + private generateDefaultMapArray(): D3.Map[] { + var keyAccessor = this.keyAccessor(); + var valueAccessor = this.valueAccessor(); + var datasets = this._getDatasetsInOrder(); + var domainKeys = this.getDomainKeys(); + + var dataMapArray = datasets.map(() => { + return _Util.Methods.populateMap(domainKeys, (domainKey) => { + return {key: domainKey, value: 0}; + }); + }); + + datasets.forEach((dataset, datasetIndex) => { + dataset.data().forEach((datum) => { + var key = keyAccessor(datum); + var value = valueAccessor(datum); + dataMapArray[datasetIndex].set(key, {key: key, value: value}); + }); + }); + + return dataMapArray; + } + public _updateScaleExtents() { super._updateScaleExtents(); var primaryScale: Abstract.Scale = this._isVertical ? this._yScale : this._xScale; @@ -111,6 +148,14 @@ export module Abstract { primaryScale._removeExtent(this._plottableID.toString(), "_PLOTTABLE_PROTECTED_FIELD_STACK_EXTENT"); } } + + private keyAccessor(): IAppliedAccessor { + return this._isVertical ? this._projectors["x"].accessor : this._projectors["y"].accessor; + } + + private valueAccessor(): IAppliedAccessor { + return this._isVertical ? this._projectors["y"].accessor : this._projectors["x"].accessor; + } } } } diff --git a/src/core/interfaces.ts b/src/core/interfaces.ts index 5143fd128b..1b2e6bfd98 100644 --- a/src/core/interfaces.ts +++ b/src/core/interfaces.ts @@ -25,7 +25,7 @@ module Plottable { * Index, if used, will be the index of the datum in the array. */ export interface IAppliedAccessor { - (datum: any, index: number) : any; + (datum?: any, index?: number) : any; } export interface _IProjector { diff --git a/src/utils/textUtils.ts b/src/utils/textUtils.ts index 57dcb381f1..ab9d71b859 100644 --- a/src/utils/textUtils.ts +++ b/src/utils/textUtils.ts @@ -212,6 +212,7 @@ export module _Util { xForm.rotate = rotation === "right" ? 90 : -90; xForm.translate = [isRight ? width : 0, isRight ? 0 : height]; innerG.attr("transform", xForm.toString()); + innerG.classed("rotated-" + rotation, true); return wh; } @@ -278,10 +279,13 @@ export module _Util { * Returns an IWriteTextResult with info on whether the text fit, and how much width/height was used. */ export function writeText(text: string, width: number, height: number, tm: TextMeasurer, - horizontally?: boolean, + orientation = "horizontal", write?: IWriteOptions): IWriteTextResult { - var orientHorizontally = (horizontally != null) ? horizontally : width * 1.1 > height; + if (["left", "right", "horizontal"].indexOf(orientation) === -1) { + throw new Error("Unrecognized orientation to writeText: " + orientation); + } + var orientHorizontally = orientation === "horizontal"; var primaryDimension = orientHorizontally ? width : height; var secondaryDimension = orientHorizontally ? height : width; var wrappedText = _Util.WordWrap.breakTextToFitRect(text, primaryDimension, secondaryDimension, tm); @@ -301,7 +305,7 @@ export module _Util { // 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); + var wh = writeTextFn.call(this, wrappedText.lines, innerG, width, height, write.xAlign, write.yAlign, orientation); usedWidth = wh.width; usedHeight = wh.height; } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 3c2310638b..bf20e2f34a 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -99,13 +99,13 @@ export module _Util { * Populates a map from an array of keys and a transformation function. * * @param {string[]} keys The array of keys. - * @param {(string) => T} transform A transformation function to apply to the keys. + * @param {(string, number) => T} transform A transformation function to apply to the keys. * @return {D3.Map} A map mapping keys to their transformed values. */ - export function populateMap(keys: string[], transform: (key: string) => T): D3.Map { + export function populateMap(keys: string[], transform: (key: string, index: number) => T): D3.Map { var map: D3.Map = d3.map(); - keys.forEach((key: string) => { - map.set(key, transform(key)); + keys.forEach((key: string, i: number) => { + map.set(key, transform(key, i)); }); return map; } diff --git a/test/components/baseAxisTests.ts b/test/components/baseAxisTests.ts index 00e76d3d5a..1ca0bd0450 100644 --- a/test/components/baseAxisTests.ts +++ b/test/components/baseAxisTests.ts @@ -196,4 +196,16 @@ describe("BaseAxis", () => { svg.remove(); }); + + it("default alignment based on orientation", () => { + var scale = new Plottable.Scale.Linear(); + var baseAxis = new Plottable.Abstract.Axis(scale, "bottom"); + assert.equal(( baseAxis)._yAlignProportion, 0, "yAlignProportion defaults to 0 for bottom axis"); + baseAxis = new Plottable.Abstract.Axis(scale, "top"); + assert.equal(( baseAxis)._yAlignProportion, 1, "yAlignProportion defaults to 1 for top axis"); + baseAxis = new Plottable.Abstract.Axis(scale, "left"); + assert.equal(( baseAxis)._xAlignProportion, 1, "xAlignProportion defaults to 1 for left axis"); + baseAxis = new Plottable.Abstract.Axis(scale, "right"); + assert.equal(( baseAxis)._xAlignProportion, 0, "xAlignProportion defaults to 0 for right axis"); + }); }); diff --git a/test/components/categoryAxisTests.ts b/test/components/categoryAxisTests.ts index 795246624e..959ab70317 100644 --- a/test/components/categoryAxisTests.ts +++ b/test/components/categoryAxisTests.ts @@ -100,4 +100,35 @@ describe("Category Axes", () => { svg.remove(); }); + + it("vertically aligns short words properly", () => { + var SVG_WIDTH = 400; + var svg = generateSVG(SVG_WIDTH, 100); + var years = ["2000", "2001", "2002", "2003"]; + var scale = new Plottable.Scale.Ordinal().domain(years).range([0, SVG_WIDTH]); + var axis = new Plottable.Axis.Category(scale, "bottom"); + axis.renderTo(svg); + + var ticks = axis._content.selectAll("text"); + var text = ticks[0].map((d: any) => d3.select(d).text()); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + + axis.tickLabelAngle(90); + text = ticks[0].map((d: any) => d3.select(d).text()); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + assert.operator(axis._content.selectAll(".rotated-right")[0].length, ">=", 4, "the ticks were rotated right"); + + axis.tickLabelAngle(0); + text = ticks[0].map((d: any) => d3.select(d).text()); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + assert.lengthOf(axis._content.selectAll(".rotated-left")[0], 0, "the ticks were not rotated left"); + assert.lengthOf(axis._content.selectAll(".rotated-right")[0], 0, "the ticks were not rotated right"); + + axis.tickLabelAngle(-90); + text = ticks[0].map((d: any) => d3.select(d).text()); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + assert.operator(axis._content.selectAll(".rotated-left")[0].length, ">=", 4, "the ticks were rotated left"); + + svg.remove(); + }); }); diff --git a/test/components/labelTests.ts b/test/components/labelTests.ts index f29ca92874..c2af2bda0d 100644 --- a/test/components/labelTests.ts +++ b/test/components/labelTests.ts @@ -25,7 +25,7 @@ describe("Labels", () => { it("Left-rotated text is handled properly", () => { var svg = generateSVG(100, 400); - var label = new Plottable.Component.AxisLabel("LEFT-ROTATED LABEL", "vertical-left"); + var label = new Plottable.Component.AxisLabel("LEFT-ROTATED LABEL", "left"); label.renderTo(svg); var content = label._content; var text = content.select("text"); @@ -37,7 +37,7 @@ describe("Labels", () => { it("Right-rotated text is handled properly", () => { var svg = generateSVG(100, 400); - var label = new Plottable.Component.AxisLabel("RIGHT-ROTATED LABEL", "vertical-right"); + var label = new Plottable.Component.AxisLabel("RIGHT-ROTATED LABEL", "right"); label.renderTo(svg); var content = label._content; var text = content.select("text"); @@ -119,7 +119,7 @@ describe("Labels", () => { var bbox = Plottable._Util.DOM.getBBox(text); assert.closeTo(bbox.height, label.height(), 1, "label is in horizontal position"); - label.orient("vertical-right"); + label.orient("right"); text = content.select("text"); bbox = Plottable._Util.DOM.getBBox(text); assertBBoxInclusion(label._element.select(".bounding-box"), text); diff --git a/test/components/plots/areaPlotTests.ts b/test/components/plots/areaPlotTests.ts index 54f4607d97..7e061e0846 100644 --- a/test/components/plots/areaPlotTests.ts +++ b/test/components/plots/areaPlotTests.ts @@ -12,14 +12,12 @@ describe("Plots", () => { var y0Accessor: any; var colorAccessor: any; var fillAccessor: any; + var twoPointData = [{foo: 0, bar: 0}, {foo: 1, bar: 1}]; var simpleDataset: Plottable.Dataset; var areaPlot: Plottable.Plot.Area; var renderArea: D3.Selection; - var verifier: MultiTestVerifier; before(() => { - svg = generateSVG(500, 500); - verifier = new MultiTestVerifier(); xScale = new Plottable.Scale.Linear().domain([0, 1]); yScale = new Plottable.Scale.Linear().domain([0, 1]); xAccessor = (d: any) => d.foo; @@ -27,7 +25,11 @@ describe("Plots", () => { y0Accessor = () => 0; colorAccessor = (d: any, i: number, m: any) => d3.rgb(d.foo, d.bar, i).toString(); fillAccessor = () => "steelblue"; - simpleDataset = new Plottable.Dataset([{foo: 0, bar: 0}, {foo: 1, bar: 1}]); + }); + + beforeEach(() => { + svg = generateSVG(500, 500); + simpleDataset = new Plottable.Dataset(twoPointData); areaPlot = new Plottable.Plot.Area(simpleDataset, xScale, yScale); areaPlot.project("x", xAccessor, xScale) .project("y", yAccessor, yScale) @@ -38,10 +40,6 @@ describe("Plots", () => { renderArea = areaPlot._renderArea; }); - beforeEach(() => { - verifier.start(); - }); - it("draws area and line correctly", () => { var areaPath = renderArea.select(".area"); assert.strictEqual(normalizePath(areaPath.attr("d")), "M0,500L500,0L500,500L0,500Z", "area d was set correctly"); @@ -54,7 +52,7 @@ describe("Plots", () => { assert.strictEqual(linePath.attr("stroke"), "#000000", "line stroke was set correctly"); var lineComputedStyle = window.getComputedStyle(linePath.node()); assert.strictEqual(lineComputedStyle.fill, "none", "line fill renders as \"none\""); - verifier.end(); + svg.remove(); }); it("area fill works for non-zero floor values appropriately, e.g. half the height of the line", () => { @@ -63,7 +61,7 @@ describe("Plots", () => { renderArea = areaPlot._renderArea; var areaPath = renderArea.select(".area"); assert.equal(normalizePath(areaPath.attr("d")), "M0,500L500,0L500,250L0,500Z"); - verifier.end(); + svg.remove(); }); it("area is appended before line", () => { @@ -71,11 +69,42 @@ describe("Plots", () => { var areaSelection = renderArea.select(".area")[0][0]; var lineSelection = renderArea.select(".line")[0][0]; assert.operator(paths.indexOf(areaSelection), "<", paths.indexOf(lineSelection), "area appended before line"); - verifier.end(); + svg.remove(); }); - after(() => { - if (verifier.passed) {svg.remove();}; + it("correctly handles NaN and undefined x and y values", () => { + var areaData = [ + { foo: 0.0, bar: 0.0 }, + { foo: 0.2, bar: 0.2 }, + { foo: 0.4, bar: 0.4 }, + { foo: 0.6, bar: 0.6 }, + { foo: 0.8, bar: 0.8 } + ]; + var expectedPath = "M0,500L100,400L100,500L0,500ZM300,200L400,100L400,500L300,500Z"; + var areaPath = renderArea.select(".area"); + + var dataWithNaN = areaData.slice(); + dataWithNaN[2] = { foo: 0.4, bar: NaN }; + simpleDataset.data(dataWithNaN); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, + "area d was set correctly (y=NaN case)"); + dataWithNaN[2] = { foo: NaN, bar: 0.4 }; + simpleDataset.data(dataWithNaN); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, + "area d was set correctly (x=NaN case)"); + + var dataWithUndefined = areaData.slice(); + dataWithUndefined[2] = { foo: 0.4, bar: undefined }; + simpleDataset.data(dataWithUndefined); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, + "area d was set correctly (y=undefined case)"); + dataWithUndefined[2] = { foo: undefined, bar: 0.4 }; + simpleDataset.data(dataWithUndefined); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, + "area d was set correctly (x=undefined case)"); + + svg.remove(); }); + }); }); diff --git a/test/components/plots/barPlotTests.ts b/test/components/plots/barPlotTests.ts index 21f4f47b73..0e0cc2bfe1 100644 --- a/test/components/plots/barPlotTests.ts +++ b/test/components/plots/barPlotTests.ts @@ -287,8 +287,6 @@ describe("Plots", () => { var axisWidth = 0; var bandWidth = 0; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); yScale = new Plottable.Scale.Ordinal().domain(["A", "B"]); diff --git a/test/components/plots/clusteredBarPlotTests.ts b/test/components/plots/clusteredBarPlotTests.ts index e9511f3b7b..ca74cfc7c8 100644 --- a/test/components/plots/clusteredBarPlotTests.ts +++ b/test/components/plots/clusteredBarPlotTests.ts @@ -16,8 +16,6 @@ describe("Plots", () => { var axisHeight = 0; var bandWidth = 0; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Ordinal(); @@ -106,8 +104,6 @@ describe("Plots", () => { var rendererWidth: number; var bandWidth = 0; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); yScale = new Plottable.Scale.Ordinal(); @@ -183,4 +179,65 @@ describe("Plots", () => { , "y pos correct for bar3"); }); }); + + describe("Clustered Bar Plot Missing Values", () => { + var svg: D3.Selection; + var plot: Plottable.Plot.ClusteredBar; + + var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); + + beforeEach(() => { + var SVG_WIDTH = 600; + var SVG_HEIGHT = 400; + svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + + var data1 = [{x: "A", y: 1}, {x: "B", y: 2}, {x: "C", y: 1}]; + var data2 = [{x: "A", y: 2}, {x: "B", y: 4}]; + var data3 = [{x: "B", y: 15}, {x: "C", y: 15}]; + + plot = new Plottable.Plot.ClusteredBar(xScale, yScale); + plot.addDataset(data1); + plot.addDataset(data2); + plot.addDataset(data3); + plot.baseline(0); + var xAxis = new Plottable.Axis.Category(xScale, "bottom"); + new Plottable.Component.Table([[plot], [xAxis]]).renderTo(svg); + }); + + it("renders correctly", () => { + var bars = plot._renderArea.selectAll("rect"); + + assert.lengthOf(bars[0], 7, "Number of bars should be equivalent to number of datum"); + + var aBar0 = d3.select(bars[0][0]); + var aBar1 = d3.select(bars[0][3]); + + var bBar0 = d3.select(bars[0][1]); + var bBar1 = d3.select(bars[0][4]); + var bBar2 = d3.select(bars[0][5]); + + var cBar0 = d3.select(bars[0][2]); + var cBar1 = d3.select(bars[0][6]); + + // check bars are in domain order + assert.operator(numAttr(aBar0, "x"), "<", numAttr(bBar0, "x"), "first dataset bars ordered correctly"); + assert.operator(numAttr(bBar0, "x"), "<", numAttr(cBar0, "x"), "first dataset bars ordered correctly"); + + assert.operator(numAttr(aBar1, "x"), "<", numAttr(bBar1, "x"), "second dataset bars ordered correctly"); + + assert.operator(numAttr(bBar2, "x"), "<", numAttr(cBar1, "x"), "third dataset bars ordered correctly"); + + // check that clustering is correct + assert.operator(numAttr(aBar0, "x"), "<", numAttr(aBar1, "x"), "A bars clustered in dataset order"); + + assert.operator(numAttr(bBar0, "x"), "<", numAttr(bBar1, "x"), "B bars clustered in dataset order"); + assert.operator(numAttr(bBar1, "x"), "<", numAttr(bBar2, "x"), "B bars clustered in dataset order"); + + assert.operator(numAttr(cBar0, "x"), "<", numAttr(cBar1, "x"), "C bars clustered in dataset order"); + + svg.remove(); + }); + }); }); diff --git a/test/components/plots/linePlotTests.ts b/test/components/plots/linePlotTests.ts index ce5911ed27..0a62241f23 100644 --- a/test/components/plots/linePlotTests.ts +++ b/test/components/plots/linePlotTests.ts @@ -10,20 +10,22 @@ describe("Plots", () => { var xAccessor: any; var yAccessor: any; var colorAccessor: any; + var twoPointData = [{foo: 0, bar: 0}, {foo: 1, bar: 1}]; var simpleDataset: Plottable.Dataset; var linePlot: Plottable.Plot.Line; var renderArea: D3.Selection; - var verifier: MultiTestVerifier; before(() => { - svg = generateSVG(500, 500); - verifier = new MultiTestVerifier(); xScale = new Plottable.Scale.Linear().domain([0, 1]); yScale = new Plottable.Scale.Linear().domain([0, 1]); xAccessor = (d: any) => d.foo; yAccessor = (d: any) => d.bar; colorAccessor = (d: any, i: number, m: any) => d3.rgb(d.foo, d.bar, i).toString(); - simpleDataset = new Plottable.Dataset([{foo: 0, bar: 0}, {foo: 1, bar: 1}]); + }); + + beforeEach(() => { + svg = generateSVG(500, 500); + simpleDataset = new Plottable.Dataset(twoPointData); linePlot = new Plottable.Plot.Line(simpleDataset, xScale, yScale); linePlot.project("x", xAccessor, xScale) .project("y", yAccessor, yScale) @@ -32,22 +34,18 @@ describe("Plots", () => { renderArea = linePlot._renderArea; }); - beforeEach(() => { - verifier.start(); - }); - it("draws a line correctly", () => { var linePath = renderArea.select(".line"); assert.strictEqual(normalizePath(linePath.attr("d")), "M0,500L500,0", "line d was set correctly"); var lineComputedStyle = window.getComputedStyle(linePath.node()); assert.strictEqual(lineComputedStyle.fill, "none", "line fill renders as \"none\""); - verifier.end(); + svg.remove(); }); it("attributes set appropriately from accessor", () => { var areaPath = renderArea.select(".line"); assert.equal(areaPath.attr("stroke"), "#000000", "stroke set correctly"); - verifier.end(); + svg.remove(); }); it("attributes can be changed by projecting new accessor and re-render appropriately", () => { @@ -56,7 +54,7 @@ describe("Plots", () => { linePlot.renderTo(svg); var linePath = renderArea.select(".line"); assert.equal(linePath.attr("stroke"), "pink", "stroke changed correctly"); - verifier.end(); + svg.remove(); }); it("attributes can be changed by projecting attribute accessor (sets to first datum attribute)", () => { @@ -70,11 +68,48 @@ describe("Plots", () => { data[0].stroke = "green"; simpleDataset.data(data); assert.equal(areaPath.attr("stroke"), "green", "stroke set to first datum stroke color"); - verifier.end(); + svg.remove(); }); - after(() => { - if (verifier.passed) {svg.remove();}; + it("correctly handles NaN and undefined x and y values", () => { + var lineData = [ + { foo: 0.0, bar: 0.0 }, + { foo: 0.2, bar: 0.2 }, + { foo: 0.4, bar: 0.4 }, + { foo: 0.6, bar: 0.6 }, + { foo: 0.8, bar: 0.8 } + ]; + simpleDataset.data(lineData); + var linePath = renderArea.select(".line"); + var d_original = normalizePath(linePath.attr("d")); + + function assertCorrectPathSplitting(msgPrefix: string) { + var d = normalizePath(linePath.attr("d")); + var pathSegements = d.split("M").filter((segment) => segment !== ""); + assert.lengthOf(pathSegements, 2, msgPrefix + " split path into two segments"); + var firstSegmentContained = d_original.indexOf(pathSegements[0]) >= 0; + assert.isTrue(firstSegmentContained, "first path segment is a subpath of the original path"); + var secondSegmentContained = d_original.indexOf(pathSegements[1]) >= 0; + assert.isTrue(firstSegmentContained, "second path segment is a subpath of the original path"); + } + + var dataWithNaN = lineData.slice(); + dataWithNaN[2] = { foo: 0.4, bar: NaN }; + simpleDataset.data(dataWithNaN); + assertCorrectPathSplitting("y=NaN"); + dataWithNaN[2] = { foo: NaN, bar: 0.4 }; + simpleDataset.data(dataWithNaN); + assertCorrectPathSplitting("x=NaN"); + + var dataWithUndefined = lineData.slice(); + dataWithUndefined[2] = { foo: 0.4, bar: undefined }; + simpleDataset.data(dataWithUndefined); + assertCorrectPathSplitting("y=undefined"); + dataWithUndefined[2] = { foo: undefined, bar: 0.4 }; + simpleDataset.data(dataWithUndefined); + assertCorrectPathSplitting("x=undefined"); + + svg.remove(); }); }); }); diff --git a/test/components/plots/stackedAreaPlotTests.ts b/test/components/plots/stackedAreaPlotTests.ts index fc4021a301..31464199e8 100644 --- a/test/components/plots/stackedAreaPlotTests.ts +++ b/test/components/plots/stackedAreaPlotTests.ts @@ -14,8 +14,6 @@ describe("Plots", () => { var SVG_WIDTH = 600; var SVG_HEIGHT = 400; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Linear().domain([1, 3]); @@ -81,8 +79,6 @@ describe("Plots", () => { var SVG_WIDTH = 600; var SVG_HEIGHT = 400; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Linear().domain([1, 3]); diff --git a/test/components/plots/stackedBarPlotTests.ts b/test/components/plots/stackedBarPlotTests.ts index 64362fed61..a6f4a54acc 100644 --- a/test/components/plots/stackedBarPlotTests.ts +++ b/test/components/plots/stackedBarPlotTests.ts @@ -16,8 +16,6 @@ describe("Plots", () => { var axisHeight = 0; var bandWidth = 0; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Ordinal(); @@ -99,8 +97,6 @@ describe("Plots", () => { var axisHeight = 0; var bandWidth = 0; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - beforeEach(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Ordinal(); @@ -174,8 +170,6 @@ describe("Plots", () => { var rendererWidth: number; var bandWidth = 0; - var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); - before(() => { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Linear().domain([0, 6]); @@ -250,4 +244,65 @@ describe("Plots", () => { assert.closeTo(numAttr(bar3, "x"), rendererWidth / 3, 0.01, "x is correct for bar3"); }); }); + + describe("Stacked Bar Plot Weird Values", () => { + var svg: D3.Selection; + var plot: Plottable.Plot.StackedBar; + var SVG_WIDTH = 600; + var SVG_HEIGHT = 400; + + var numAttr = (s: D3.Selection, a: string) => parseFloat(s.attr(a)); + + beforeEach(() => { + svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + + var data1 = [ + {x: "A", y: 1, type: "a"}, + {x: "B", y: 2, type: "a"}, + {x: "C", y: 1, type: "a"} + ]; + var data2 = [ + {x: "A", y: 2, type: "b"}, + {x: "B", y: 3, type: "b"} + ]; + var data3 = [ + {x: "B", y: 1, type: "c"}, + {x: "C", y: 7, type: "c"} + ]; + + plot = new Plottable.Plot.StackedBar(xScale, yScale); + plot.addDataset(data1); + plot.addDataset(data2); + plot.addDataset(data3); + var xAxis = new Plottable.Axis.Category(xScale, "bottom"); + var table = new Plottable.Component.Table([[plot], [xAxis]]).renderTo(svg); + }); + + it("renders correctly", () => { + var bars = plot._renderArea.selectAll("rect"); + + assert.lengthOf(bars[0], 7, "draws a bar for each datum"); + + var aBars = [d3.select(bars[0][0]), d3.select(bars[0][3])]; + + var bBars = [d3.select(bars[0][1]), d3.select(bars[0][4]), d3.select(bars[0][5])]; + + var cBars = [d3.select(bars[0][2]), d3.select(bars[0][6])]; + + assert.closeTo(numAttr(aBars[0], "x"), numAttr(aBars[1], "x"), 0.01, "A bars at same x position"); + assert.operator(numAttr(aBars[0], "y"), ">", numAttr(aBars[1], "y"), "first dataset A bar under second"); + + assert.closeTo(numAttr(bBars[0], "x"), numAttr(bBars[1], "x"), 0.01, "B bars at same x position"); + assert.closeTo(numAttr(bBars[1], "x"), numAttr(bBars[2], "x"), 0.01, "B bars at same x position"); + assert.operator(numAttr(bBars[0], "y"), ">", numAttr(bBars[1], "y"), "first dataset B bar under second"); + assert.operator(numAttr(bBars[1], "y"), ">", numAttr(bBars[2], "y"), "second dataset B bar under third"); + + assert.closeTo(numAttr(cBars[0], "x"), numAttr(cBars[1], "x"), 0.01, "C bars at same x position"); + assert.operator(numAttr(cBars[0], "y"), ">", numAttr(cBars[1], "y"), "first dataset C bar under second"); + + svg.remove(); + }); + }); }); diff --git a/test/core/componentTests.ts b/test/core/componentTests.ts index 0cbb8f7dff..5b84ea11d5 100644 --- a/test/core/componentTests.ts +++ b/test/core/componentTests.ts @@ -367,4 +367,22 @@ it("components can be offset relative to their alignment, and throw errors if th c.detach(); // no error thrown svg.remove(); }); + + it("component remains in own cell", () => { + var horizontalComponent = new Plottable.Abstract.Component(); + var verticalComponent = new Plottable.Abstract.Component(); + var placeHolder = new Plottable.Abstract.Component(); + var t = new Plottable.Component.Table().addComponent(0, 0, verticalComponent) + .addComponent(0, 1, new Plottable.Abstract.Component()) + .addComponent(1, 0, placeHolder) + .addComponent(1, 1, horizontalComponent); + t.renderTo(svg); + horizontalComponent.xAlign("center"); + verticalComponent.yAlign("bottom"); + + assertBBoxNonIntersection(verticalComponent._element.select(".bounding-box"), placeHolder._element.select(".bounding-box")); + assertBBoxInclusion(( t).boxContainer.select(".bounding-box"), horizontalComponent._element.select(".bounding-box")); + + svg.remove(); + }); }); diff --git a/test/testUtils.ts b/test/testUtils.ts index e1ff7cbb86..3159adf755 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -65,6 +65,22 @@ function assertBBoxInclusion(outerEl: D3.Selection, innerEl: D3.Selection) { "bounding rect bottom included"); } +function assertBBoxNonIntersection(firstEl: D3.Selection, secondEl: D3.Selection) { + var firstBox = firstEl.node().getBoundingClientRect(); + var secondBox = secondEl.node().getBoundingClientRect(); + + var intersectionBox = { + left: Math.max(firstBox.left, secondBox.left), + right: Math.min(firstBox.right, secondBox.right), + bottom: Math.min(firstBox.bottom, secondBox.bottom), + top: Math.max(firstBox.top, secondBox.top) + }; + + // +1 for inaccuracy in IE + assert.isTrue(intersectionBox.left + 1 >= intersectionBox.right || intersectionBox.bottom + 1 >= intersectionBox.top, + "bounding rects are not intersecting"); +} + function assertXY(el: D3.Selection, xExpected: number, yExpected: number, message: string) { var x = el.attr("x"); var y = el.attr("y"); @@ -113,6 +129,10 @@ function normalizePath(pathString: string) { return pathString.replace(/ *([A-Z]) */g, "$1").replace(/ /g, ","); } +function numAttr(s: D3.Selection, a: string) { + return parseFloat(s.attr(a)); +} + function triggerFakeUIEvent(type: string, target: D3.Selection) { var e = document.createEvent("UIEvents"); e.initUIEvent(type, true, true, window, 1); diff --git a/test/tests.js b/test/tests.js index 9645cb9826..fa92111dad 100644 --- a/test/tests.js +++ b/test/tests.js @@ -55,6 +55,18 @@ function assertBBoxInclusion(outerEl, innerEl) { assert.operator(Math.ceil(outerBox.right) + window.Pixel_CloseTo_Requirement, ">=", Math.floor(innerBox.right), "bounding rect right included"); assert.operator(Math.ceil(outerBox.bottom) + window.Pixel_CloseTo_Requirement, ">=", Math.floor(innerBox.bottom), "bounding rect bottom included"); } +function assertBBoxNonIntersection(firstEl, secondEl) { + var firstBox = firstEl.node().getBoundingClientRect(); + var secondBox = secondEl.node().getBoundingClientRect(); + var intersectionBox = { + left: Math.max(firstBox.left, secondBox.left), + right: Math.min(firstBox.right, secondBox.right), + bottom: Math.min(firstBox.bottom, secondBox.bottom), + top: Math.max(firstBox.top, secondBox.top) + }; + // +1 for inaccuracy in IE + assert.isTrue(intersectionBox.left + 1 >= intersectionBox.right || intersectionBox.bottom + 1 >= intersectionBox.top, "bounding rects are not intersecting"); +} function assertXY(el, xExpected, yExpected, message) { var x = el.attr("x"); var y = el.attr("y"); @@ -96,6 +108,9 @@ var MultiTestVerifier = (function () { function normalizePath(pathString) { return pathString.replace(/ *([A-Z]) */g, "$1").replace(/ /g, ","); } +function numAttr(s, a) { + return parseFloat(s.attr(a)); +} function triggerFakeUIEvent(type, target) { var e = document.createEvent("UIEvents"); e.initUIEvent(type, true, true, window, 1); @@ -296,6 +311,17 @@ describe("BaseAxis", function () { assert.strictEqual(baseAxis.height(), 30 + baseAxis.gutter(), "height should not decrease"); svg.remove(); }); + it("default alignment based on orientation", function () { + var scale = new Plottable.Scale.Linear(); + var baseAxis = new Plottable.Abstract.Axis(scale, "bottom"); + assert.equal(baseAxis._yAlignProportion, 0, "yAlignProportion defaults to 0 for bottom axis"); + baseAxis = new Plottable.Abstract.Axis(scale, "top"); + assert.equal(baseAxis._yAlignProportion, 1, "yAlignProportion defaults to 1 for top axis"); + baseAxis = new Plottable.Abstract.Axis(scale, "left"); + assert.equal(baseAxis._xAlignProportion, 1, "xAlignProportion defaults to 1 for left axis"); + baseAxis = new Plottable.Abstract.Axis(scale, "right"); + assert.equal(baseAxis._xAlignProportion, 0, "xAlignProportion defaults to 0 for right axis"); + }); }); /// @@ -718,6 +744,31 @@ describe("Category Axes", function () { assert.deepEqual(ticksNormalizedPosition, [1, 2, 3]); svg.remove(); }); + it("vertically aligns short words properly", function () { + var SVG_WIDTH = 400; + var svg = generateSVG(SVG_WIDTH, 100); + var years = ["2000", "2001", "2002", "2003"]; + var scale = new Plottable.Scale.Ordinal().domain(years).range([0, SVG_WIDTH]); + var axis = new Plottable.Axis.Category(scale, "bottom"); + axis.renderTo(svg); + var ticks = axis._content.selectAll("text"); + var text = ticks[0].map(function (d) { return d3.select(d).text(); }); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + axis.tickLabelAngle(90); + text = ticks[0].map(function (d) { return d3.select(d).text(); }); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + assert.operator(axis._content.selectAll(".rotated-right")[0].length, ">=", 4, "the ticks were rotated right"); + axis.tickLabelAngle(0); + text = ticks[0].map(function (d) { return d3.select(d).text(); }); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + assert.lengthOf(axis._content.selectAll(".rotated-left")[0], 0, "the ticks were not rotated left"); + assert.lengthOf(axis._content.selectAll(".rotated-right")[0], 0, "the ticks were not rotated right"); + axis.tickLabelAngle(-90); + text = ticks[0].map(function (d) { return d3.select(d).text(); }); + assert.deepEqual(text, years, "text displayed correctly when horizontal"); + assert.operator(axis._content.selectAll(".rotated-left")[0].length, ">=", 4, "the ticks were rotated left"); + svg.remove(); + }); }); /// @@ -784,7 +835,7 @@ describe("Labels", function () { }); it("Left-rotated text is handled properly", function () { var svg = generateSVG(100, 400); - var label = new Plottable.Component.AxisLabel("LEFT-ROTATED LABEL", "vertical-left"); + var label = new Plottable.Component.AxisLabel("LEFT-ROTATED LABEL", "left"); label.renderTo(svg); var content = label._content; var text = content.select("text"); @@ -795,7 +846,7 @@ describe("Labels", function () { }); it("Right-rotated text is handled properly", function () { var svg = generateSVG(100, 400); - var label = new Plottable.Component.AxisLabel("RIGHT-ROTATED LABEL", "vertical-right"); + var label = new Plottable.Component.AxisLabel("RIGHT-ROTATED LABEL", "right"); label.renderTo(svg); var content = label._content; var text = content.select("text"); @@ -867,7 +918,7 @@ describe("Labels", function () { var text = content.select("text"); var bbox = Plottable._Util.DOM.getBBox(text); assert.closeTo(bbox.height, label.height(), 1, "label is in horizontal position"); - label.orient("vertical-right"); + label.orient("right"); text = content.select("text"); bbox = Plottable._Util.DOM.getBBox(text); assertBBoxInclusion(label._element.select(".bounding-box"), text); @@ -1753,37 +1804,35 @@ describe("Plots", function () { var xAccessor; var yAccessor; var colorAccessor; + var twoPointData = [{ foo: 0, bar: 0 }, { foo: 1, bar: 1 }]; var simpleDataset; var linePlot; var renderArea; - var verifier; before(function () { - svg = generateSVG(500, 500); - verifier = new MultiTestVerifier(); xScale = new Plottable.Scale.Linear().domain([0, 1]); yScale = new Plottable.Scale.Linear().domain([0, 1]); xAccessor = function (d) { return d.foo; }; yAccessor = function (d) { return d.bar; }; colorAccessor = function (d, i, m) { return d3.rgb(d.foo, d.bar, i).toString(); }; - simpleDataset = new Plottable.Dataset([{ foo: 0, bar: 0 }, { foo: 1, bar: 1 }]); + }); + beforeEach(function () { + svg = generateSVG(500, 500); + simpleDataset = new Plottable.Dataset(twoPointData); linePlot = new Plottable.Plot.Line(simpleDataset, xScale, yScale); linePlot.project("x", xAccessor, xScale).project("y", yAccessor, yScale).project("stroke", colorAccessor).renderTo(svg); renderArea = linePlot._renderArea; }); - beforeEach(function () { - verifier.start(); - }); it("draws a line correctly", function () { var linePath = renderArea.select(".line"); assert.strictEqual(normalizePath(linePath.attr("d")), "M0,500L500,0", "line d was set correctly"); var lineComputedStyle = window.getComputedStyle(linePath.node()); assert.strictEqual(lineComputedStyle.fill, "none", "line fill renders as \"none\""); - verifier.end(); + svg.remove(); }); it("attributes set appropriately from accessor", function () { var areaPath = renderArea.select(".line"); assert.equal(areaPath.attr("stroke"), "#000000", "stroke set correctly"); - verifier.end(); + svg.remove(); }); it("attributes can be changed by projecting new accessor and re-render appropriately", function () { var newColorAccessor = function () { return "pink"; }; @@ -1791,7 +1840,7 @@ describe("Plots", function () { linePlot.renderTo(svg); var linePath = renderArea.select(".line"); assert.equal(linePath.attr("stroke"), "pink", "stroke changed correctly"); - verifier.end(); + svg.remove(); }); it("attributes can be changed by projecting attribute accessor (sets to first datum attribute)", function () { var data = simpleDataset.data(); @@ -1805,13 +1854,43 @@ describe("Plots", function () { data[0].stroke = "green"; simpleDataset.data(data); assert.equal(areaPath.attr("stroke"), "green", "stroke set to first datum stroke color"); - verifier.end(); + svg.remove(); }); - after(function () { - if (verifier.passed) { - svg.remove(); + it("correctly handles NaN and undefined x and y values", function () { + var lineData = [ + { foo: 0.0, bar: 0.0 }, + { foo: 0.2, bar: 0.2 }, + { foo: 0.4, bar: 0.4 }, + { foo: 0.6, bar: 0.6 }, + { foo: 0.8, bar: 0.8 } + ]; + simpleDataset.data(lineData); + var linePath = renderArea.select(".line"); + var d_original = normalizePath(linePath.attr("d")); + function assertCorrectPathSplitting(msgPrefix) { + var d = normalizePath(linePath.attr("d")); + var pathSegements = d.split("M").filter(function (segment) { return segment !== ""; }); + assert.lengthOf(pathSegements, 2, msgPrefix + " split path into two segments"); + var firstSegmentContained = d_original.indexOf(pathSegements[0]) >= 0; + assert.isTrue(firstSegmentContained, "first path segment is a subpath of the original path"); + var secondSegmentContained = d_original.indexOf(pathSegements[1]) >= 0; + assert.isTrue(firstSegmentContained, "second path segment is a subpath of the original path"); } - ; + var dataWithNaN = lineData.slice(); + dataWithNaN[2] = { foo: 0.4, bar: NaN }; + simpleDataset.data(dataWithNaN); + assertCorrectPathSplitting("y=NaN"); + dataWithNaN[2] = { foo: NaN, bar: 0.4 }; + simpleDataset.data(dataWithNaN); + assertCorrectPathSplitting("x=NaN"); + var dataWithUndefined = lineData.slice(); + dataWithUndefined[2] = { foo: 0.4, bar: undefined }; + simpleDataset.data(dataWithUndefined); + assertCorrectPathSplitting("y=undefined"); + dataWithUndefined[2] = { foo: undefined, bar: 0.4 }; + simpleDataset.data(dataWithUndefined); + assertCorrectPathSplitting("x=undefined"); + svg.remove(); }); }); }); @@ -1828,13 +1907,11 @@ describe("Plots", function () { var y0Accessor; var colorAccessor; var fillAccessor; + var twoPointData = [{ foo: 0, bar: 0 }, { foo: 1, bar: 1 }]; var simpleDataset; var areaPlot; var renderArea; - var verifier; before(function () { - svg = generateSVG(500, 500); - verifier = new MultiTestVerifier(); xScale = new Plottable.Scale.Linear().domain([0, 1]); yScale = new Plottable.Scale.Linear().domain([0, 1]); xAccessor = function (d) { return d.foo; }; @@ -1842,14 +1919,14 @@ describe("Plots", function () { y0Accessor = function () { return 0; }; colorAccessor = function (d, i, m) { return d3.rgb(d.foo, d.bar, i).toString(); }; fillAccessor = function () { return "steelblue"; }; - simpleDataset = new Plottable.Dataset([{ foo: 0, bar: 0 }, { foo: 1, bar: 1 }]); + }); + beforeEach(function () { + svg = generateSVG(500, 500); + simpleDataset = new Plottable.Dataset(twoPointData); areaPlot = new Plottable.Plot.Area(simpleDataset, xScale, yScale); areaPlot.project("x", xAccessor, xScale).project("y", yAccessor, yScale).project("y0", y0Accessor, yScale).project("fill", fillAccessor).project("stroke", colorAccessor).renderTo(svg); renderArea = areaPlot._renderArea; }); - beforeEach(function () { - verifier.start(); - }); it("draws area and line correctly", function () { var areaPath = renderArea.select(".area"); assert.strictEqual(normalizePath(areaPath.attr("d")), "M0,500L500,0L500,500L0,500Z", "area d was set correctly"); @@ -1861,7 +1938,7 @@ describe("Plots", function () { assert.strictEqual(linePath.attr("stroke"), "#000000", "line stroke was set correctly"); var lineComputedStyle = window.getComputedStyle(linePath.node()); assert.strictEqual(lineComputedStyle.fill, "none", "line fill renders as \"none\""); - verifier.end(); + svg.remove(); }); it("area fill works for non-zero floor values appropriately, e.g. half the height of the line", function () { areaPlot.project("y0", function (d) { return d.bar / 2; }, yScale); @@ -1869,20 +1946,40 @@ describe("Plots", function () { renderArea = areaPlot._renderArea; var areaPath = renderArea.select(".area"); assert.equal(normalizePath(areaPath.attr("d")), "M0,500L500,0L500,250L0,500Z"); - verifier.end(); + svg.remove(); }); it("area is appended before line", function () { var paths = renderArea.selectAll("path")[0]; var areaSelection = renderArea.select(".area")[0][0]; var lineSelection = renderArea.select(".line")[0][0]; assert.operator(paths.indexOf(areaSelection), "<", paths.indexOf(lineSelection), "area appended before line"); - verifier.end(); + svg.remove(); }); - after(function () { - if (verifier.passed) { - svg.remove(); - } - ; + it("correctly handles NaN and undefined x and y values", function () { + var areaData = [ + { foo: 0.0, bar: 0.0 }, + { foo: 0.2, bar: 0.2 }, + { foo: 0.4, bar: 0.4 }, + { foo: 0.6, bar: 0.6 }, + { foo: 0.8, bar: 0.8 } + ]; + var expectedPath = "M0,500L100,400L100,500L0,500ZM300,200L400,100L400,500L300,500Z"; + var areaPath = renderArea.select(".area"); + var dataWithNaN = areaData.slice(); + dataWithNaN[2] = { foo: 0.4, bar: NaN }; + simpleDataset.data(dataWithNaN); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, "area d was set correctly (y=NaN case)"); + dataWithNaN[2] = { foo: NaN, bar: 0.4 }; + simpleDataset.data(dataWithNaN); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, "area d was set correctly (x=NaN case)"); + var dataWithUndefined = areaData.slice(); + dataWithUndefined[2] = { foo: 0.4, bar: undefined }; + simpleDataset.data(dataWithUndefined); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, "area d was set correctly (y=undefined case)"); + dataWithUndefined[2] = { foo: undefined, bar: 0.4 }; + simpleDataset.data(dataWithUndefined); + assert.strictEqual(normalizePath(areaPath.attr("d")), expectedPath, "area d was set correctly (x=undefined case)"); + svg.remove(); }); }); }); @@ -2136,7 +2233,6 @@ describe("Plots", function () { var SVG_HEIGHT = 400; var axisWidth = 0; var bandWidth = 0; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); yScale = new Plottable.Scale.Ordinal().domain(["A", "B"]); @@ -2433,7 +2529,6 @@ describe("Plots", function () { var renderer; var SVG_WIDTH = 600; var SVG_HEIGHT = 400; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Linear().domain([1, 3]); @@ -2491,7 +2586,6 @@ describe("Plots", function () { var renderer; var SVG_WIDTH = 600; var SVG_HEIGHT = 400; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Linear().domain([1, 3]); @@ -2658,7 +2752,6 @@ describe("Plots", function () { var SVG_HEIGHT = 400; var axisHeight = 0; var bandWidth = 0; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Ordinal(); @@ -2735,7 +2828,6 @@ describe("Plots", function () { var SVG_HEIGHT = 400; var axisHeight = 0; var bandWidth = 0; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; beforeEach(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Ordinal(); @@ -2801,7 +2893,6 @@ describe("Plots", function () { var SVG_HEIGHT = 400; var rendererWidth; var bandWidth = 0; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Linear().domain([0, 6]); @@ -2871,6 +2962,53 @@ describe("Plots", function () { assert.closeTo(numAttr(bar3, "x"), rendererWidth / 3, 0.01, "x is correct for bar3"); }); }); + describe("Stacked Bar Plot Weird Values", function () { + var svg; + var plot; + var SVG_WIDTH = 600; + var SVG_HEIGHT = 400; + var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; + beforeEach(function () { + svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + var data1 = [ + { x: "A", y: 1, type: "a" }, + { x: "B", y: 2, type: "a" }, + { x: "C", y: 1, type: "a" } + ]; + var data2 = [ + { x: "A", y: 2, type: "b" }, + { x: "B", y: 3, type: "b" } + ]; + var data3 = [ + { x: "B", y: 1, type: "c" }, + { x: "C", y: 7, type: "c" } + ]; + plot = new Plottable.Plot.StackedBar(xScale, yScale); + plot.addDataset(data1); + plot.addDataset(data2); + plot.addDataset(data3); + var xAxis = new Plottable.Axis.Category(xScale, "bottom"); + var table = new Plottable.Component.Table([[plot], [xAxis]]).renderTo(svg); + }); + it("renders correctly", function () { + var bars = plot._renderArea.selectAll("rect"); + assert.lengthOf(bars[0], 7, "draws a bar for each datum"); + var aBars = [d3.select(bars[0][0]), d3.select(bars[0][3])]; + var bBars = [d3.select(bars[0][1]), d3.select(bars[0][4]), d3.select(bars[0][5])]; + var cBars = [d3.select(bars[0][2]), d3.select(bars[0][6])]; + assert.closeTo(numAttr(aBars[0], "x"), numAttr(aBars[1], "x"), 0.01, "A bars at same x position"); + assert.operator(numAttr(aBars[0], "y"), ">", numAttr(aBars[1], "y"), "first dataset A bar under second"); + assert.closeTo(numAttr(bBars[0], "x"), numAttr(bBars[1], "x"), 0.01, "B bars at same x position"); + assert.closeTo(numAttr(bBars[1], "x"), numAttr(bBars[2], "x"), 0.01, "B bars at same x position"); + assert.operator(numAttr(bBars[0], "y"), ">", numAttr(bBars[1], "y"), "first dataset B bar under second"); + assert.operator(numAttr(bBars[1], "y"), ">", numAttr(bBars[2], "y"), "second dataset B bar under third"); + assert.closeTo(numAttr(cBars[0], "x"), numAttr(cBars[1], "x"), 0.01, "C bars at same x position"); + assert.operator(numAttr(cBars[0], "y"), ">", numAttr(cBars[1], "y"), "first dataset C bar under second"); + svg.remove(); + }); + }); }); /// @@ -2888,7 +3026,6 @@ describe("Plots", function () { var SVG_HEIGHT = 400; var axisHeight = 0; var bandWidth = 0; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); xScale = new Plottable.Scale.Ordinal(); @@ -2965,7 +3102,6 @@ describe("Plots", function () { var SVG_HEIGHT = 400; var rendererWidth; var bandWidth = 0; - var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; before(function () { svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); yScale = new Plottable.Scale.Ordinal(); @@ -3030,6 +3166,50 @@ describe("Plots", function () { assert.closeTo(numAttr(bar3, "y") + numAttr(bar3, "height") / 2, yScale.scale(bar3Y) + bandWidth / 2 + off, 0.01, "y pos correct for bar3"); }); }); + describe("Clustered Bar Plot Missing Values", function () { + var svg; + var plot; + var numAttr = function (s, a) { return parseFloat(s.attr(a)); }; + beforeEach(function () { + var SVG_WIDTH = 600; + var SVG_HEIGHT = 400; + svg = generateSVG(SVG_WIDTH, SVG_HEIGHT); + var xScale = new Plottable.Scale.Ordinal(); + var yScale = new Plottable.Scale.Linear(); + var data1 = [{ x: "A", y: 1 }, { x: "B", y: 2 }, { x: "C", y: 1 }]; + var data2 = [{ x: "A", y: 2 }, { x: "B", y: 4 }]; + var data3 = [{ x: "B", y: 15 }, { x: "C", y: 15 }]; + plot = new Plottable.Plot.ClusteredBar(xScale, yScale); + plot.addDataset(data1); + plot.addDataset(data2); + plot.addDataset(data3); + plot.baseline(0); + var xAxis = new Plottable.Axis.Category(xScale, "bottom"); + new Plottable.Component.Table([[plot], [xAxis]]).renderTo(svg); + }); + it("renders correctly", function () { + var bars = plot._renderArea.selectAll("rect"); + assert.lengthOf(bars[0], 7, "Number of bars should be equivalent to number of datum"); + var aBar0 = d3.select(bars[0][0]); + var aBar1 = d3.select(bars[0][3]); + var bBar0 = d3.select(bars[0][1]); + var bBar1 = d3.select(bars[0][4]); + var bBar2 = d3.select(bars[0][5]); + var cBar0 = d3.select(bars[0][2]); + var cBar1 = d3.select(bars[0][6]); + // check bars are in domain order + assert.operator(numAttr(aBar0, "x"), "<", numAttr(bBar0, "x"), "first dataset bars ordered correctly"); + assert.operator(numAttr(bBar0, "x"), "<", numAttr(cBar0, "x"), "first dataset bars ordered correctly"); + assert.operator(numAttr(aBar1, "x"), "<", numAttr(bBar1, "x"), "second dataset bars ordered correctly"); + assert.operator(numAttr(bBar2, "x"), "<", numAttr(cBar1, "x"), "third dataset bars ordered correctly"); + // check that clustering is correct + assert.operator(numAttr(aBar0, "x"), "<", numAttr(aBar1, "x"), "A bars clustered in dataset order"); + assert.operator(numAttr(bBar0, "x"), "<", numAttr(bBar1, "x"), "B bars clustered in dataset order"); + assert.operator(numAttr(bBar1, "x"), "<", numAttr(bBar2, "x"), "B bars clustered in dataset order"); + assert.operator(numAttr(cBar0, "x"), "<", numAttr(cBar1, "x"), "C bars clustered in dataset order"); + svg.remove(); + }); + }); }); /// @@ -3658,6 +3838,18 @@ describe("Component behavior", function () { c.detach(); // no error thrown svg.remove(); }); + it("component remains in own cell", function () { + var horizontalComponent = new Plottable.Abstract.Component(); + var verticalComponent = new Plottable.Abstract.Component(); + var placeHolder = new Plottable.Abstract.Component(); + var t = new Plottable.Component.Table().addComponent(0, 0, verticalComponent).addComponent(0, 1, new Plottable.Abstract.Component()).addComponent(1, 0, placeHolder).addComponent(1, 1, horizontalComponent); + t.renderTo(svg); + horizontalComponent.xAlign("center"); + verticalComponent.yAlign("bottom"); + assertBBoxNonIntersection(verticalComponent._element.select(".bounding-box"), placeHolder._element.select(".bounding-box")); + assertBBoxInclusion(t.boxContainer.select(".bounding-box"), horizontalComponent._element.select(".bounding-box")); + svg.remove(); + }); }); /// @@ -5117,12 +5309,12 @@ describe("_Util.Text", function () { var height = 1; var textSelection = svg.append("text"); var measure = Plottable._Util.Text.getTextMeasurer(textSelection); - var results = Plottable._Util.Text.writeText("hello world", width, height, measure, true); + var results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal"); assert.isFalse(results.textFits, "measurement mode: text doesn't fit"); assert.equal(0, results.usedWidth, "measurement mode: no width used"); assert.equal(0, results.usedHeight, "measurement mode: no height used"); var writeOptions = { g: svg, xAlign: "center", yAlign: "center" }; - results = Plottable._Util.Text.writeText("hello world", width, height, measure, true, writeOptions); + results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal", writeOptions); assert.isFalse(results.textFits, "write mode: text doesn't fit"); assert.equal(0, results.usedWidth, "write mode: no width used"); assert.equal(0, results.usedHeight, "write mode: no height used"); @@ -5136,12 +5328,12 @@ describe("_Util.Text", function () { var height = 1; var textSelection = svg.append("text"); var measure = Plottable._Util.Text.getTextMeasurer(textSelection); - var results = Plottable._Util.Text.writeText("hello world", width, height, measure, true); + var results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal"); assert.isFalse(results.textFits, "measurement mode: text doesn't fit"); assert.equal(0, results.usedWidth, "measurement mode: no width used"); assert.equal(0, results.usedHeight, "measurement mode: no height used"); var writeOptions = { g: svg, xAlign: "center", yAlign: "center" }; - results = Plottable._Util.Text.writeText("hello world", width, height, measure, true, writeOptions); + results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal", writeOptions); assert.isFalse(results.textFits, "write mode: text doesn't fit"); assert.equal(0, results.usedWidth, "write mode: no width used"); assert.equal(0, results.usedHeight, "write mode: no height used"); @@ -5365,6 +5557,20 @@ describe("_Util.Methods", function () { assert.isTrue(Plottable._Util.Methods.objEq({ a: "hello" }, { a: "hello" })); assert.isFalse(Plottable._Util.Methods.objEq({ constructor: {}.constructor }, {}), "using \"constructor\" isn't hidden"); }); + it("populateMap works as expected", function () { + var keys = ["a", "b", "c"]; + var map = Plottable._Util.Methods.populateMap(keys, function (key) { return key + "Value"; }); + assert.strictEqual(map.get("a"), "aValue", "key properly goes through map function"); + assert.strictEqual(map.get("b"), "bValue", "key properly goes through map function"); + assert.strictEqual(map.get("c"), "cValue", "key properly goes through map function"); + var indexMap = Plottable._Util.Methods.populateMap(keys, function (key, i) { return key + i + "Value"; }); + assert.strictEqual(indexMap.get("a"), "a0Value", "key and index properly goes through map function"); + assert.strictEqual(indexMap.get("b"), "b1Value", "key and index properly goes through map function"); + assert.strictEqual(indexMap.get("c"), "c2Value", "key and index properly goes through map function"); + var emptyKeys = []; + var emptyMap = Plottable._Util.Methods.populateMap(emptyKeys, function (key) { return key + "Value"; }); + assert.isTrue(emptyMap.empty(), "no entries in map if no keys in input array"); + }); }); /// diff --git a/test/utils/textUtilsTests.ts b/test/utils/textUtilsTests.ts index 0017bae698..09cd32e099 100644 --- a/test/utils/textUtilsTests.ts +++ b/test/utils/textUtilsTests.ts @@ -70,13 +70,13 @@ describe("_Util.Text", () => { var height = 1; var textSelection = svg.append("text"); var measure = Plottable._Util.Text.getTextMeasurer(textSelection); - var results = Plottable._Util.Text.writeText("hello world", width, height, measure, true); + var results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal"); assert.isFalse(results.textFits, "measurement mode: text doesn't fit"); assert.equal(0, results.usedWidth, "measurement mode: no width used"); assert.equal(0, results.usedHeight, "measurement mode: no height used"); var writeOptions = {g: svg, xAlign: "center", yAlign: "center"}; - results = Plottable._Util.Text.writeText("hello world", width, height, measure, true, writeOptions); + results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal", writeOptions); assert.isFalse(results.textFits, "write mode: text doesn't fit"); assert.equal(0, results.usedWidth, "write mode: no width used"); assert.equal(0, results.usedHeight, "write mode: no height used"); @@ -91,13 +91,13 @@ describe("_Util.Text", () => { var height = 1; var textSelection = svg.append("text"); var measure = Plottable._Util.Text.getTextMeasurer(textSelection); - var results = Plottable._Util.Text.writeText("hello world", width, height, measure, true); + var results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal"); assert.isFalse(results.textFits, "measurement mode: text doesn't fit"); assert.equal(0, results.usedWidth, "measurement mode: no width used"); assert.equal(0, results.usedHeight, "measurement mode: no height used"); var writeOptions = {g: svg, xAlign: "center", yAlign: "center"}; - results = Plottable._Util.Text.writeText("hello world", width, height, measure, true, writeOptions); + results = Plottable._Util.Text.writeText("hello world", width, height, measure, "horizontal", writeOptions); assert.isFalse(results.textFits, "write mode: text doesn't fit"); assert.equal(0, results.usedWidth, "write mode: no width used"); assert.equal(0, results.usedHeight, "write mode: no height used"); diff --git a/test/utils/utilsTests.ts b/test/utils/utilsTests.ts index 2897b4557c..edc5bc6e78 100644 --- a/test/utils/utilsTests.ts +++ b/test/utils/utilsTests.ts @@ -74,4 +74,25 @@ describe("_Util.Methods", () => { assert.isFalse(Plottable._Util.Methods.objEq({constructor: {}.constructor}, {}), "using \"constructor\" isn't hidden"); }); + + it("populateMap works as expected", () => { + var keys = ["a", "b", "c"]; + var map = Plottable._Util.Methods.populateMap(keys, (key) => key + "Value"); + + assert.strictEqual(map.get("a"), "aValue", "key properly goes through map function"); + assert.strictEqual(map.get("b"), "bValue", "key properly goes through map function"); + assert.strictEqual(map.get("c"), "cValue", "key properly goes through map function"); + + var indexMap = Plottable._Util.Methods.populateMap(keys, (key, i) => key + i + "Value"); + + assert.strictEqual(indexMap.get("a"), "a0Value", "key and index properly goes through map function"); + assert.strictEqual(indexMap.get("b"), "b1Value", "key and index properly goes through map function"); + assert.strictEqual(indexMap.get("c"), "c2Value", "key and index properly goes through map function"); + + var emptyKeys: string[] = []; + var emptyMap = Plottable._Util.Methods.populateMap(emptyKeys, (key) => key + "Value"); + + assert.isTrue(emptyMap.empty(), "no entries in map if no keys in input array"); + + }); }); diff --git a/typings/d3/d3.d.ts b/typings/d3/d3.d.ts index 9d29cd1646..42e1c3c316 100644 --- a/typings/d3/d3.d.ts +++ b/typings/d3/d3.d.ts @@ -841,6 +841,11 @@ declare module D3 { entries(values: any[]): NestKeyValue[]; } + export interface MapKeyValue { + key: string; + value: T; + } + export interface Map { has(key: string): boolean; get(key: string): T; @@ -848,7 +853,7 @@ declare module D3 { remove(key: string): boolean; keys(): string[]; values(): T[]; - entries(): any[][]; // Actually of form [key: string, val: T][], but this is inexpressible in Typescript + entries(): MapKeyValue[]; forEach(func: (key: string, value: T) => void ): void; empty(): boolean; size(): number; @@ -1902,13 +1907,13 @@ declare module D3 { /** * Get the accessor function that controls where the line is defined. */ - (): (data: any, index ?: number) => boolean; + (): (data: any, index?: number) => boolean; /** * Set the accessor function that controls where the area is defined. * * @param defined The new accessor function */ - (defined: (data: any) => boolean): Line; + (defined: (data: any, index?: number) => boolean): Line; }; } @@ -2198,13 +2203,13 @@ declare module D3 { /** * Get the accessor function that controls where the area is defined. */ - (): (data: any) => any; + (): (data: any, index?: number) => any; /** * Set the accessor function that controls where the area is defined. * * @param defined The new accessor function */ - (defined: (data: any) => any): Area; + (defined: (data: any, index?: number) => any): Area; }; }