diff --git a/.bmp.yml b/.bmp.yml index 7024cd2f0..12898ba78 100644 --- a/.bmp.yml +++ b/.bmp.yml @@ -1,7 +1,7 @@ --- -version: 0.7.15 +version: 0.7.16 commit: 'chore(version): bump to v%.%.%' files: - src/core.js: 'version: "%.%.%"' + src/core.js: 'version: ''%.%.%''' package.json: '"version": "%.%.%"' component.json: '"version": "%.%.%"' diff --git a/c3.esm.js b/c3.esm.js index b9145bcda..15a8edd9f 100644 --- a/c3.esm.js +++ b/c3.esm.js @@ -1,18 +1,22 @@ -/* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */ +/* @license C3.js v0.7.16 | (c) C3 Team and other contributors | http://c3js.org/ */ import * as d3 from 'd3'; function ChartInternal(api) { - var $$ = this; - // Note: This part will be replaced by rollup-plugin-modify - // When bundling esm output. Beware of changing this line. - // TODO: Maybe we should check that the modification by rollup-plugin-modify - // is valid during unit tests. - $$.d3 = d3; - $$.api = api; - $$.config = $$.getDefaultConfig(); - $$.data = {}; - $$.cache = {}; - $$.axes = {}; + var $$ = this; + // Note: This part will be replaced by rollup-plugin-modify + // When bundling esm output. Beware of changing this line. + // TODO: Maybe we should check that the modification by rollup-plugin-modify + // is valid during unit tests. + $$.d3 = window.d3 + ? window.d3 + : typeof require !== 'undefined' + ? require('d3') + : undefined; + $$.api = api; + $$.config = $$.getDefaultConfig(); + $$.data = {}; + $$.cache = {}; + $$.axes = {}; } /** @@ -21,96 +25,105 @@ function ChartInternal(api) { * The methods of this class is the public APIs of the chart object. */ function Chart(config) { - this.internal = new ChartInternal(this); - this.internal.loadConfig(config); - - this.internal.beforeInit(config); - this.internal.init(); - this.internal.afterInit(config); - - // bind "this" to nested API - (function bindThis(fn, target, argThis) { - Object.keys(fn).forEach(function (key) { - target[key] = fn[key].bind(argThis); - if (Object.keys(fn[key]).length > 0) { - bindThis(fn[key], target[key], argThis); - } - }); - })(Chart.prototype, this, this); + this.internal = new ChartInternal(this); + this.internal.loadConfig(config); + + this.internal.beforeInit(config); + this.internal.init(); + this.internal.afterInit(config) + + // bind "this" to nested API + ;(function bindThis(fn, target, argThis) { + Object.keys(fn).forEach(function(key) { + target[key] = fn[key].bind(argThis); + if (Object.keys(fn[key]).length > 0) { + bindThis(fn[key], target[key], argThis); + } + }); + })(Chart.prototype, this, this); } var asHalfPixel = function(n) { - return Math.ceil(n) + 0.5; + return Math.ceil(n) + 0.5 }; var ceil10 = function(v) { - return Math.ceil(v / 10) * 10; + return Math.ceil(v / 10) * 10 }; var diffDomain = function(d) { - return d[1] - d[0]; + return d[1] - d[0] }; var getOption = function(options, key, defaultValue) { - return isDefined(options[key]) ? options[key] : defaultValue; + return isDefined(options[key]) ? options[key] : defaultValue }; var getPathBox = function(path) { - var box = getBBox(path), - items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], - minX = items[0].x, - minY = Math.min(items[0].y, items[1].y); - return { x: minX, y: minY, width: box.width, height: box.height }; + var box = getBBox(path), + items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], + minX = items[0].x, + minY = Math.min(items[0].y, items[1].y); + return { x: minX, y: minY, width: box.width, height: box.height } }; var getBBox = function(element) { try { - return element.getBBox(); + return element.getBBox() } catch (ignore) { - // Firefox will throw an exception if getBBox() is called whereas the - // element is rendered with display:none - // See https://github.com/c3js/c3/issues/2692 + // Firefox will throw an exception if getBBox() is called whereas the + // element is rendered with display:none + // See https://github.com/c3js/c3/issues/2692 - // The previous code was using `getBoundingClientRect` which was returning - // everything at 0 in this case so let's reproduce this behavior here. + // The previous code was using `getBoundingClientRect` which was returning + // everything at 0 in this case so let's reproduce this behavior here. - return { x: 0, y: 0, width: 0, height: 0 }; + return { x: 0, y: 0, width: 0, height: 0 } } }; var hasValue = function(dict, value) { - var found = false; - Object.keys(dict).forEach(function(key) { - if (dict[key] === value) { found = true; } - }); - return found; + var found = false; + Object.keys(dict).forEach(function(key) { + if (dict[key] === value) { + found = true; + } + }); + return found }; var isArray = function(o) { - return Array.isArray(o); + return Array.isArray(o) }; var isDefined = function(v) { - return typeof v !== 'undefined'; + return typeof v !== 'undefined' }; var isEmpty = function(o) { - return typeof o === 'undefined' || o === null || (isString(o) && o.length === 0) || (typeof o === 'object' && Object.keys(o).length === 0); + return ( + typeof o === 'undefined' || + o === null || + (isString(o) && o.length === 0) || + (typeof o === 'object' && Object.keys(o).length === 0) + ) }; var isFunction = function(o) { - return typeof o === 'function'; + return typeof o === 'function' }; var isNumber = function(o) { - return typeof o === 'number'; + return typeof o === 'number' }; var isString = function(o) { - return typeof o === 'string'; + return typeof o === 'string' }; var isUndefined = function(v) { - return typeof v === 'undefined'; + return typeof v === 'undefined' }; var isValue = function(v) { - return v || v === 0; + return v || v === 0 }; var notEmpty = function(o) { - return !isEmpty(o); + return !isEmpty(o) }; var sanitise = function(str) { - return typeof str === 'string' ? str.replace(//g, '>') : str; + return typeof str === 'string' + ? str.replace(//g, '>') + : str }; var flattenArray = function(arr) { - return Array.isArray(arr) ? [].concat(...arr) : []; + return Array.isArray(arr) ? [].concat(...arr) : [] }; /** * Returns whether the point is within the given box. @@ -120,12 +133,14 @@ var flattenArray = function(arr) { * @param {Number} sensitivity An offset to ease check on very small boxes */ var isWithinBox = function(point, box, sensitivity = 0) { - const xStart = box.x - sensitivity; - const xEnd = box.x + box.width + sensitivity; - const yStart = box.y + box.height + sensitivity; - const yEnd = box.y - sensitivity; + const xStart = box.x - sensitivity; + const xEnd = box.x + box.width + sensitivity; + const yStart = box.y + box.height + sensitivity; + const yEnd = box.y - sensitivity; - return xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart; + return ( + xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart + ) }; /** @@ -134,23 +149,23 @@ var isWithinBox = function(point, box, sensitivity = 0) { * @param string agent Optional parameter to specify user agent */ var getIEVersion = function(agent) { - // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie - if (typeof agent === 'undefined') { - agent = window.navigator.userAgent; - } + // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie + if (typeof agent === 'undefined') { + agent = window.navigator.userAgent; + } - let pos = agent.indexOf('MSIE '); // up to IE10 - if (pos > 0) { - return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10); - } + let pos = agent.indexOf('MSIE '); // up to IE10 + if (pos > 0) { + return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10) + } - pos = agent.indexOf('Trident/'); // IE11 - if (pos > 0) { - pos = agent.indexOf('rv:'); - return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10); - } + pos = agent.indexOf('Trident/'); // IE11 + if (pos > 0) { + pos = agent.indexOf('rv:'); + return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10) + } - return false; + return false }; /** @@ -159,3899 +174,5096 @@ var getIEVersion = function(agent) { * @param {Number} version Optional parameter to specify IE version */ var isIE = function(version) { - const ver = getIEVersion(); + const ver = getIEVersion(); - if (typeof version === 'undefined') { - return !!ver; - } + if (typeof version === 'undefined') { + return !!ver + } - return version === ver; + return version === ver }; function AxisInternal(component, params) { - var internal = this; - internal.component = component; - internal.params = params || {}; - - internal.d3 = component.d3; - internal.scale = internal.d3.scaleLinear(); - internal.range; - internal.orient = "bottom"; - internal.innerTickSize = 6; - internal.outerTickSize = this.params.withOuterTick ? 6 : 0; - internal.tickPadding = 3; - internal.tickValues = null; - internal.tickFormat; - internal.tickArguments; - - internal.tickOffset = 0; - internal.tickCulling = true; - internal.tickCentered; - internal.tickTextCharSize; - internal.tickTextRotate = internal.params.tickTextRotate; - internal.tickLength; - - internal.axis = internal.generateAxis(); + var internal = this; + internal.component = component; + internal.params = params || {}; + + internal.d3 = component.d3; + internal.scale = internal.d3.scaleLinear(); + internal.range; + internal.orient = 'bottom'; + internal.innerTickSize = 6; + internal.outerTickSize = this.params.withOuterTick ? 6 : 0; + internal.tickPadding = 3; + internal.tickValues = null; + internal.tickFormat; + internal.tickArguments; + + internal.tickOffset = 0; + internal.tickCulling = true; + internal.tickCentered; + internal.tickTextCharSize; + internal.tickTextRotate = internal.params.tickTextRotate; + internal.tickLength; + + internal.axis = internal.generateAxis(); } -AxisInternal.prototype.axisX = function (selection, x, tickOffset) { - selection.attr("transform", function (d) { - return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)"; - }); -}; -AxisInternal.prototype.axisY = function (selection, y) { - selection.attr("transform", function (d) { - return "translate(0," + Math.ceil(y(d)) + ")"; - }); -}; -AxisInternal.prototype.scaleExtent = function (domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; -}; -AxisInternal.prototype.generateTicks = function (scale) { - var internal = this; - var i, domain, ticks = []; - if (scale.ticks) { - return scale.ticks.apply(scale, internal.tickArguments); - } - domain = scale.domain(); - for (i = Math.ceil(domain[0]); i < domain[1]; i++) { - ticks.push(i); - } - if (ticks.length > 0 && ticks[0] > 0) { - ticks.unshift(ticks[0] - (ticks[1] - ticks[0])); - } - return ticks; -}; -AxisInternal.prototype.copyScale = function () { - var internal = this; - var newScale = internal.scale.copy(), domain; - if (internal.params.isCategory) { - domain = internal.scale.domain(); - newScale.domain([domain[0], domain[1] - 1]); - } - return newScale; -}; -AxisInternal.prototype.textFormatted = function (v) { - var internal = this, - formatted = internal.tickFormat ? internal.tickFormat(v) : v; - return typeof formatted !== 'undefined' ? formatted : ''; -}; -AxisInternal.prototype.updateRange = function () { - var internal = this; - internal.range = internal.scale.rangeExtent ? internal.scale.rangeExtent() : internal.scaleExtent(internal.scale.range()); - return internal.range; -}; -AxisInternal.prototype.updateTickTextCharSize = function (tick) { - var internal = this; - if (internal.tickTextCharSize) { - return internal.tickTextCharSize; - } - var size = { - h: 11.5, - w: 5.5 - }; - tick.select('text').text(function(d) { return internal.textFormatted(d); }).each(function (d) { - var box = getBBox(this), - text = internal.textFormatted(d), - h = box.height, - w = text ? (box.width / text.length) : undefined; - if (h && w) { - size.h = h; - size.w = w; - } - }).text(''); - internal.tickTextCharSize = size; - return size; -}; -AxisInternal.prototype.isVertical = function () { - return this.orient === 'left' || this.orient === 'right'; -}; -AxisInternal.prototype.tspanData = function (d, i, scale) { - var internal = this; - var splitted = internal.params.tickMultiline ? internal.splitTickText(d, scale) : [].concat(internal.textFormatted(d)); - - if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) { - splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax); - } - - return splitted.map(function (s) { - return { index: i, splitted: s, length: splitted.length }; - }); -}; -AxisInternal.prototype.splitTickText = function (d, scale) { - var internal = this, - tickText = internal.textFormatted(d), - maxWidth = internal.params.tickWidth, - subtext, spaceIndex, textWidth, splitted = []; +AxisInternal.prototype.axisX = function(selection, x, tickOffset) { + selection.attr('transform', function(d) { + return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)' + }); +}; +AxisInternal.prototype.axisY = function(selection, y) { + selection.attr('transform', function(d) { + return 'translate(0,' + Math.ceil(y(d)) + ')' + }); +}; +AxisInternal.prototype.scaleExtent = function(domain) { + var start = domain[0], + stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start] +}; +AxisInternal.prototype.generateTicks = function(scale) { + var internal = this; + var i, + domain, + ticks = []; + if (scale.ticks) { + return scale.ticks.apply(scale, internal.tickArguments) + } + domain = scale.domain(); + for (i = Math.ceil(domain[0]); i < domain[1]; i++) { + ticks.push(i); + } + if (ticks.length > 0 && ticks[0] > 0) { + ticks.unshift(ticks[0] - (ticks[1] - ticks[0])); + } + return ticks +}; +AxisInternal.prototype.copyScale = function() { + var internal = this; + var newScale = internal.scale.copy(), + domain; + if (internal.params.isCategory) { + domain = internal.scale.domain(); + newScale.domain([domain[0], domain[1] - 1]); + } + return newScale +}; +AxisInternal.prototype.textFormatted = function(v) { + var internal = this, + formatted = internal.tickFormat ? internal.tickFormat(v) : v; + return typeof formatted !== 'undefined' ? formatted : '' +}; +AxisInternal.prototype.updateRange = function() { + var internal = this; + internal.range = internal.scale.rangeExtent + ? internal.scale.rangeExtent() + : internal.scaleExtent(internal.scale.range()); + return internal.range +}; +AxisInternal.prototype.updateTickTextCharSize = function(tick) { + var internal = this; + if (internal.tickTextCharSize) { + return internal.tickTextCharSize + } + var size = { + h: 11.5, + w: 5.5 + }; + tick + .select('text') + .text(function(d) { + return internal.textFormatted(d) + }) + .each(function(d) { + var box = getBBox(this), + text = internal.textFormatted(d), + h = box.height, + w = text ? box.width / text.length : undefined; + if (h && w) { + size.h = h; + size.w = w; + } + }) + .text(''); + internal.tickTextCharSize = size; + return size +}; +AxisInternal.prototype.isVertical = function() { + return this.orient === 'left' || this.orient === 'right' +}; +AxisInternal.prototype.tspanData = function(d, i, scale) { + var internal = this; + var splitted = internal.params.tickMultiline + ? internal.splitTickText(d, scale) + : [].concat(internal.textFormatted(d)); + + if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) { + splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax); + } - if (Object.prototype.toString.call(tickText) === "[object Array]") { - return tickText; - } + return splitted.map(function(s) { + return { index: i, splitted: s, length: splitted.length } + }) +}; +AxisInternal.prototype.splitTickText = function(d, scale) { + var internal = this, + tickText = internal.textFormatted(d), + maxWidth = internal.params.tickWidth, + subtext, + spaceIndex, + textWidth, + splitted = []; + + if (Object.prototype.toString.call(tickText) === '[object Array]') { + return tickText + } - if (!maxWidth || maxWidth <= 0) { - maxWidth = internal.isVertical() ? 95 : internal.params.isCategory ? (Math.ceil(scale(1) - scale(0)) - 12) : 110; - } + if (!maxWidth || maxWidth <= 0) { + maxWidth = internal.isVertical() + ? 95 + : internal.params.isCategory + ? Math.ceil(scale(1) - scale(0)) - 12 + : 110; + } - function split(splitted, text) { - spaceIndex = undefined; - for (var i = 1; i < text.length; i++) { - if (text.charAt(i) === ' ') { - spaceIndex = i; - } - subtext = text.substr(0, i + 1); - textWidth = internal.tickTextCharSize.w * subtext.length; - // if text width gets over tick width, split by space index or crrent index - if (maxWidth < textWidth) { - return split( - splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), - text.slice(spaceIndex ? spaceIndex + 1 : i) - ); - } - } - return splitted.concat(text); - } + function split(splitted, text) { + spaceIndex = undefined; + for (var i = 1; i < text.length; i++) { + if (text.charAt(i) === ' ') { + spaceIndex = i; + } + subtext = text.substr(0, i + 1); + textWidth = internal.tickTextCharSize.w * subtext.length; + // if text width gets over tick width, split by space index or crrent index + if (maxWidth < textWidth) { + return split( + splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), + text.slice(spaceIndex ? spaceIndex + 1 : i) + ) + } + } + return splitted.concat(text) + } - return split(splitted, tickText + ""); + return split(splitted, tickText + '') }; AxisInternal.prototype.ellipsify = function(splitted, max) { - if (splitted.length <= max) { - return splitted; - } + if (splitted.length <= max) { + return splitted + } - var ellipsified = splitted.slice(0, max); - var remaining = 3; - for (var i = max-1 ; i >= 0 ; i--) { - var available = ellipsified[i].length; + var ellipsified = splitted.slice(0, max); + var remaining = 3; + for (var i = max - 1; i >= 0; i--) { + var available = ellipsified[i].length; - ellipsified[i] = ellipsified[i].substr(0, available-remaining).padEnd(available, '.'); + ellipsified[i] = ellipsified[i] + .substr(0, available - remaining) + .padEnd(available, '.'); - remaining -= available; + remaining -= available; - if (remaining <= 0) { - break; - } + if (remaining <= 0) { + break } + } - return ellipsified; -}; -AxisInternal.prototype.updateTickLength = function () { - var internal = this; - internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding; -}; -AxisInternal.prototype.lineY2 = function (d) { - var internal = this, - tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset); - return internal.range[0] < tickPosition && tickPosition < internal.range[1] ? internal.innerTickSize : 0; -}; -AxisInternal.prototype.textY = function (){ - var internal = this, rotate = internal.tickTextRotate; - return rotate ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) : internal.tickLength; -}; -AxisInternal.prototype.textTransform = function () { - var internal = this, rotate = internal.tickTextRotate; - return rotate ? "rotate(" + rotate + ")" : ""; -}; -AxisInternal.prototype.textTextAnchor = function () { - var internal = this, rotate = internal.tickTextRotate; - return rotate ? (rotate > 0 ? "start" : "end") : "middle"; -}; -AxisInternal.prototype.tspanDx = function () { - var internal = this, rotate = internal.tickTextRotate; - return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0; -}; -AxisInternal.prototype.tspanDy = function (d, i) { - var internal = this, - dy = internal.tickTextCharSize.h; - if (i === 0) { - if (internal.isVertical()) { - dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); - } else { - dy = ".71em"; - } + return ellipsified +}; +AxisInternal.prototype.updateTickLength = function() { + var internal = this; + internal.tickLength = + Math.max(internal.innerTickSize, 0) + internal.tickPadding; +}; +AxisInternal.prototype.lineY2 = function(d) { + var internal = this, + tickPosition = + internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset); + return internal.range[0] < tickPosition && tickPosition < internal.range[1] + ? internal.innerTickSize + : 0 +}; +AxisInternal.prototype.textY = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate + ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) + : internal.tickLength +}; +AxisInternal.prototype.textTransform = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate ? 'rotate(' + rotate + ')' : '' +}; +AxisInternal.prototype.textTextAnchor = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle' +}; +AxisInternal.prototype.tspanDx = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0 +}; +AxisInternal.prototype.tspanDy = function(d, i) { + var internal = this, + dy = internal.tickTextCharSize.h; + if (i === 0) { + if (internal.isVertical()) { + dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); + } else { + dy = '.71em'; } - return dy; -}; - - -AxisInternal.prototype.generateAxis = function () { - var internal = this, d3 = internal.d3, params = internal.params; - function axis(g, transition) { - var self; - g.each(function () { - var g = axis.g = d3.select(this); - - var scale0 = this.__chart__ || internal.scale, - scale1 = this.__chart__ = internal.copyScale(); - - var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1), - ticks = g.selectAll(".tick").data(ticksValues, scale1), - tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), - // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. - tickExit = ticks.exit().remove(), - tickUpdate = ticks.merge(tickEnter), - tickTransform, tickX, tickY; - - if (params.isCategory) { - internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2); - tickX = internal.tickCentered ? 0 : internal.tickOffset; - tickY = internal.tickCentered ? internal.tickOffset : 0; - } else { - internal.tickOffset = tickX = 0; - } - - internal.updateRange(); - internal.updateTickLength(); - internal.updateTickTextCharSize(g.select('.tick')); - - var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")), - textUpdate = tickUpdate.select("text").merge(tickEnter.append("text")); - - var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) { - return internal.tspanData(d, i, scale1); - }), - tspanEnter = tspans.enter().append('tspan'), - tspanUpdate = tspanEnter.merge(tspans).text(function (d) { return d.splitted; }); - tspans.exit().remove(); - - var path = g.selectAll(".domain").data([ 0 ]), - pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); - - // TODO: each attr should be one function and change its behavior by internal.orient, probably - switch (internal.orient) { - case "bottom": - { - tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX) - .attr("x2", tickX) - .attr("y2", function (d, i) { return internal.lineY2(d, i); }); - textUpdate.attr("x", 0) - .attr("y", function (d, i) { return internal.textY(d, i); }) - .attr("transform", function (d, i) { return internal.textTransform(d, i); }) - .style("text-anchor", function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }) - .attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize); - break; - } - case "top": - { - // TODO: rotated tick text - tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX) - .attr("x2", tickX) - .attr("y2", function (d, i) { return -1 * internal.lineY2(d, i); }); - textUpdate.attr("x", 0) - .attr("y", function (d, i) { return -1 * internal.textY(d, i) - (params.isCategory ? 2 : (internal.tickLength - 2)); }) - .attr("transform", function (d, i) { return internal.textTransform(d, i); }) - .style("text-anchor", function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }) - .attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize); - break; - } - case "left": - { - tickTransform = internal.axisY; - lineUpdate.attr("x2", -internal.innerTickSize) - .attr("y1", tickY) - .attr("y2", tickY); - textUpdate.attr("x", -internal.tickLength) - .attr("y", internal.tickOffset) - .style("text-anchor", "end"); - tspanUpdate.attr('x', -internal.tickLength) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize); - break; - } - case "right": - { - tickTransform = internal.axisY; - lineUpdate.attr("x2", internal.innerTickSize) - .attr("y1", tickY) - .attr("y2", tickY); - textUpdate.attr("x", internal.tickLength) - .attr("y", internal.tickOffset) - .style("text-anchor", "start"); - tspanUpdate.attr('x', internal.tickLength) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize); - break; - } - } - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function (d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; - } else { - tickExit.call(tickTransform, scale1, internal.tickOffset); - } - tickEnter.call(tickTransform, scale0, internal.tickOffset); - self = (transition ? tickUpdate.transition(transition) : tickUpdate) - .style('opacity', 1) - .call(tickTransform, scale1, internal.tickOffset); + } + return dy +}; + +AxisInternal.prototype.generateAxis = function() { + var internal = this, + d3 = internal.d3, + params = internal.params; + function axis(g, transition) { + var self; + g.each(function() { + var g = (axis.g = d3.select(this)); + + var scale0 = this.__chart__ || internal.scale, + scale1 = (this.__chart__ = internal.copyScale()); + + var ticksValues = internal.tickValues + ? internal.tickValues + : internal.generateTicks(scale1), + ticks = g.selectAll('.tick').data(ticksValues, scale1), + tickEnter = ticks + .enter() + .insert('g', '.domain') + .attr('class', 'tick') + .style('opacity', 1e-6), + // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. + tickExit = ticks.exit().remove(), + tickUpdate = ticks.merge(tickEnter), + tickTransform, + tickX, + tickY; + + if (params.isCategory) { + internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2); + tickX = internal.tickCentered ? 0 : internal.tickOffset; + tickY = internal.tickCentered ? internal.tickOffset : 0; + } else { + internal.tickOffset = tickX = 0; + } + + internal.updateRange(); + internal.updateTickLength(); + internal.updateTickTextCharSize(g.select('.tick')); + + var lineUpdate = tickUpdate + .select('line') + .merge(tickEnter.append('line')), + textUpdate = tickUpdate.select('text').merge(tickEnter.append('text')); + + var tspans = tickUpdate + .selectAll('text') + .selectAll('tspan') + .data(function(d, i) { + return internal.tspanData(d, i, scale1) + }), + tspanEnter = tspans.enter().append('tspan'), + tspanUpdate = tspanEnter.merge(tspans).text(function(d) { + return d.splitted }); - return self; - } - axis.scale = function (x) { - if (!arguments.length) { return internal.scale; } - internal.scale = x; - return axis; - }; - axis.orient = function (x) { - if (!arguments.length) { return internal.orient; } - internal.orient = x in {top: 1, right: 1, bottom: 1, left: 1} ? x + "" : "bottom"; - return axis; - }; - axis.tickFormat = function (format) { - if (!arguments.length) { return internal.tickFormat; } - internal.tickFormat = format; - return axis; - }; - axis.tickCentered = function (isCentered) { - if (!arguments.length) { return internal.tickCentered; } - internal.tickCentered = isCentered; - return axis; - }; - axis.tickOffset = function () { - return internal.tickOffset; - }; - axis.tickInterval = function () { - var interval, length; - if (params.isCategory) { - interval = internal.tickOffset * 2; - } - else { - length = axis.g.select('path.domain').node().getTotalLength() - internal.outerTickSize * 2; - interval = length / axis.g.selectAll('line').size(); - } - return interval === Infinity ? 0 : interval; - }; - axis.ticks = function () { - if (!arguments.length) { return internal.tickArguments; } - internal.tickArguments = arguments; - return axis; - }; - axis.tickCulling = function (culling) { - if (!arguments.length) { return internal.tickCulling; } - internal.tickCulling = culling; - return axis; - }; - axis.tickValues = function (x) { - if (typeof x === 'function') { - internal.tickValues = function () { - return x(internal.scale.domain()); - }; - } - else { - if (!arguments.length) { return internal.tickValues; } - internal.tickValues = x; - } - return axis; - }; - return axis; + tspans.exit().remove(); + + var path = g.selectAll('.domain').data([0]), + pathUpdate = path + .enter() + .append('path') + .merge(path) + .attr('class', 'domain'); + + // TODO: each attr should be one function and change its behavior by internal.orient, probably + switch (internal.orient) { + case 'bottom': { + tickTransform = internal.axisX; + lineUpdate + .attr('x1', tickX) + .attr('x2', tickX) + .attr('y2', function(d, i) { + return internal.lineY2(d, i) + }); + textUpdate + .attr('x', 0) + .attr('y', function(d, i) { + return internal.textY(d, i) + }) + .attr('transform', function(d, i) { + return internal.textTransform(d, i) + }) + .style('text-anchor', function(d, i) { + return internal.textTextAnchor(d, i) + }); + tspanUpdate + .attr('x', 0) + .attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }) + .attr('dx', function(d, i) { + return internal.tspanDx(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + internal.range[0] + + ',' + + internal.outerTickSize + + 'V0H' + + internal.range[1] + + 'V' + + internal.outerTickSize + ); + break + } + case 'top': { + // TODO: rotated tick text + tickTransform = internal.axisX; + lineUpdate + .attr('x1', tickX) + .attr('x2', tickX) + .attr('y2', function(d, i) { + return -1 * internal.lineY2(d, i) + }); + textUpdate + .attr('x', 0) + .attr('y', function(d, i) { + return ( + -1 * internal.textY(d, i) - + (params.isCategory ? 2 : internal.tickLength - 2) + ) + }) + .attr('transform', function(d, i) { + return internal.textTransform(d, i) + }) + .style('text-anchor', function(d, i) { + return internal.textTextAnchor(d, i) + }); + tspanUpdate + .attr('x', 0) + .attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }) + .attr('dx', function(d, i) { + return internal.tspanDx(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + internal.range[0] + + ',' + + -internal.outerTickSize + + 'V0H' + + internal.range[1] + + 'V' + + -internal.outerTickSize + ); + break + } + case 'left': { + tickTransform = internal.axisY; + lineUpdate + .attr('x2', -internal.innerTickSize) + .attr('y1', tickY) + .attr('y2', tickY); + textUpdate + .attr('x', -internal.tickLength) + .attr('y', internal.tickOffset) + .style('text-anchor', 'end'); + tspanUpdate + .attr('x', -internal.tickLength) + .attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + -internal.outerTickSize + + ',' + + internal.range[0] + + 'H0V' + + internal.range[1] + + 'H' + + -internal.outerTickSize + ); + break + } + case 'right': { + tickTransform = internal.axisY; + lineUpdate + .attr('x2', internal.innerTickSize) + .attr('y1', tickY) + .attr('y2', tickY); + textUpdate + .attr('x', internal.tickLength) + .attr('y', internal.tickOffset) + .style('text-anchor', 'start'); + tspanUpdate.attr('x', internal.tickLength).attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + internal.outerTickSize + + ',' + + internal.range[0] + + 'H0V' + + internal.range[1] + + 'H' + + internal.outerTickSize + ); + break + } + } + if (scale1.rangeBand) { + var x = scale1, + dx = x.rangeBand() / 2; + scale0 = scale1 = function(d) { + return x(d) + dx + }; + } else if (scale0.rangeBand) { + scale0 = scale1; + } else { + tickExit.call(tickTransform, scale1, internal.tickOffset); + } + tickEnter.call(tickTransform, scale0, internal.tickOffset); + self = (transition ? tickUpdate.transition(transition) : tickUpdate) + .style('opacity', 1) + .call(tickTransform, scale1, internal.tickOffset); + }); + return self + } + axis.scale = function(x) { + if (!arguments.length) { + return internal.scale + } + internal.scale = x; + return axis + }; + axis.orient = function(x) { + if (!arguments.length) { + return internal.orient + } + internal.orient = + x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom'; + return axis + }; + axis.tickFormat = function(format) { + if (!arguments.length) { + return internal.tickFormat + } + internal.tickFormat = format; + return axis + }; + axis.tickCentered = function(isCentered) { + if (!arguments.length) { + return internal.tickCentered + } + internal.tickCentered = isCentered; + return axis + }; + axis.tickOffset = function() { + return internal.tickOffset + }; + axis.tickInterval = function() { + var interval, length; + if (params.isCategory) { + interval = internal.tickOffset * 2; + } else { + length = + axis.g + .select('path.domain') + .node() + .getTotalLength() - + internal.outerTickSize * 2; + interval = length / axis.g.selectAll('line').size(); + } + return interval === Infinity ? 0 : interval + }; + axis.ticks = function() { + if (!arguments.length) { + return internal.tickArguments + } + internal.tickArguments = arguments; + return axis + }; + axis.tickCulling = function(culling) { + if (!arguments.length) { + return internal.tickCulling + } + internal.tickCulling = culling; + return axis + }; + axis.tickValues = function(x) { + if (typeof x === 'function') { + internal.tickValues = function() { + return x(internal.scale.domain()) + }; + } else { + if (!arguments.length) { + return internal.tickValues + } + internal.tickValues = x; + } + return axis + }; + return axis }; var CLASS = { - target: 'c3-target', - chart: 'c3-chart', - chartLine: 'c3-chart-line', - chartLines: 'c3-chart-lines', - chartBar: 'c3-chart-bar', - chartBars: 'c3-chart-bars', - chartText: 'c3-chart-text', - chartTexts: 'c3-chart-texts', - chartArc: 'c3-chart-arc', - chartArcs: 'c3-chart-arcs', - chartArcsTitle: 'c3-chart-arcs-title', - chartArcsBackground: 'c3-chart-arcs-background', - chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit', - chartArcsGaugeMax: 'c3-chart-arcs-gauge-max', - chartArcsGaugeMin: 'c3-chart-arcs-gauge-min', - selectedCircle: 'c3-selected-circle', - selectedCircles: 'c3-selected-circles', - eventRect: 'c3-event-rect', - eventRects: 'c3-event-rects', - eventRectsSingle: 'c3-event-rects-single', - eventRectsMultiple: 'c3-event-rects-multiple', - zoomRect: 'c3-zoom-rect', - brush: 'c3-brush', - dragZoom: 'c3-drag-zoom', - focused: 'c3-focused', - defocused: 'c3-defocused', - region: 'c3-region', - regions: 'c3-regions', - title: 'c3-title', - tooltipContainer: 'c3-tooltip-container', - tooltip: 'c3-tooltip', - tooltipName: 'c3-tooltip-name', - shape: 'c3-shape', - shapes: 'c3-shapes', - line: 'c3-line', - lines: 'c3-lines', - bar: 'c3-bar', - bars: 'c3-bars', - circle: 'c3-circle', - circles: 'c3-circles', - arc: 'c3-arc', - arcLabelLine: 'c3-arc-label-line', - arcs: 'c3-arcs', - area: 'c3-area', - areas: 'c3-areas', - empty: 'c3-empty', - text: 'c3-text', - texts: 'c3-texts', - gaugeValue: 'c3-gauge-value', - grid: 'c3-grid', - gridLines: 'c3-grid-lines', - xgrid: 'c3-xgrid', - xgrids: 'c3-xgrids', - xgridLine: 'c3-xgrid-line', - xgridLines: 'c3-xgrid-lines', - xgridFocus: 'c3-xgrid-focus', - ygrid: 'c3-ygrid', - ygrids: 'c3-ygrids', - ygridLine: 'c3-ygrid-line', - ygridLines: 'c3-ygrid-lines', - colorScale: 'c3-colorscale', - stanfordElements: 'c3-stanford-elements', - stanfordLine: 'c3-stanford-line', - stanfordLines: 'c3-stanford-lines', - stanfordRegion: 'c3-stanford-region', - stanfordRegions: 'c3-stanford-regions', - stanfordText: 'c3-stanford-text', - stanfordTexts: 'c3-stanford-texts', - axis: 'c3-axis', - axisX: 'c3-axis-x', - axisXLabel: 'c3-axis-x-label', - axisY: 'c3-axis-y', - axisYLabel: 'c3-axis-y-label', - axisY2: 'c3-axis-y2', - axisY2Label: 'c3-axis-y2-label', - legendBackground: 'c3-legend-background', - legendItem: 'c3-legend-item', - legendItemEvent: 'c3-legend-item-event', - legendItemTile: 'c3-legend-item-tile', - legendItemHidden: 'c3-legend-item-hidden', - legendItemFocused: 'c3-legend-item-focused', - dragarea: 'c3-dragarea', - EXPANDED: '_expanded_', - SELECTED: '_selected_', - INCLUDED: '_included_' + target: 'c3-target', + chart: 'c3-chart', + chartLine: 'c3-chart-line', + chartLines: 'c3-chart-lines', + chartBar: 'c3-chart-bar', + chartBars: 'c3-chart-bars', + chartText: 'c3-chart-text', + chartTexts: 'c3-chart-texts', + chartArc: 'c3-chart-arc', + chartArcs: 'c3-chart-arcs', + chartArcsTitle: 'c3-chart-arcs-title', + chartArcsBackground: 'c3-chart-arcs-background', + chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit', + chartArcsGaugeMax: 'c3-chart-arcs-gauge-max', + chartArcsGaugeMin: 'c3-chart-arcs-gauge-min', + selectedCircle: 'c3-selected-circle', + selectedCircles: 'c3-selected-circles', + eventRect: 'c3-event-rect', + eventRects: 'c3-event-rects', + eventRectsSingle: 'c3-event-rects-single', + eventRectsMultiple: 'c3-event-rects-multiple', + zoomRect: 'c3-zoom-rect', + brush: 'c3-brush', + dragZoom: 'c3-drag-zoom', + focused: 'c3-focused', + defocused: 'c3-defocused', + region: 'c3-region', + regions: 'c3-regions', + title: 'c3-title', + tooltipContainer: 'c3-tooltip-container', + tooltip: 'c3-tooltip', + tooltipName: 'c3-tooltip-name', + shape: 'c3-shape', + shapes: 'c3-shapes', + line: 'c3-line', + lines: 'c3-lines', + bar: 'c3-bar', + bars: 'c3-bars', + circle: 'c3-circle', + circles: 'c3-circles', + arc: 'c3-arc', + arcLabelLine: 'c3-arc-label-line', + arcs: 'c3-arcs', + area: 'c3-area', + areas: 'c3-areas', + empty: 'c3-empty', + text: 'c3-text', + texts: 'c3-texts', + gaugeValue: 'c3-gauge-value', + grid: 'c3-grid', + gridLines: 'c3-grid-lines', + xgrid: 'c3-xgrid', + xgrids: 'c3-xgrids', + xgridLine: 'c3-xgrid-line', + xgridLines: 'c3-xgrid-lines', + xgridFocus: 'c3-xgrid-focus', + ygrid: 'c3-ygrid', + ygrids: 'c3-ygrids', + ygridLine: 'c3-ygrid-line', + ygridLines: 'c3-ygrid-lines', + colorScale: 'c3-colorscale', + stanfordElements: 'c3-stanford-elements', + stanfordLine: 'c3-stanford-line', + stanfordLines: 'c3-stanford-lines', + stanfordRegion: 'c3-stanford-region', + stanfordRegions: 'c3-stanford-regions', + stanfordText: 'c3-stanford-text', + stanfordTexts: 'c3-stanford-texts', + axis: 'c3-axis', + axisX: 'c3-axis-x', + axisXLabel: 'c3-axis-x-label', + axisY: 'c3-axis-y', + axisYLabel: 'c3-axis-y-label', + axisY2: 'c3-axis-y2', + axisY2Label: 'c3-axis-y2-label', + legendBackground: 'c3-legend-background', + legendItem: 'c3-legend-item', + legendItemEvent: 'c3-legend-item-event', + legendItemTile: 'c3-legend-item-tile', + legendItemHidden: 'c3-legend-item-hidden', + legendItemFocused: 'c3-legend-item-focused', + dragarea: 'c3-dragarea', + EXPANDED: '_expanded_', + SELECTED: '_selected_', + INCLUDED: '_included_' }; class Axis { - constructor(owner) { - this.owner = owner; - this.d3 = owner.d3; - this.internal = AxisInternal; - } + constructor(owner) { + this.owner = owner; + this.d3 = owner.d3; + this.internal = AxisInternal; + } } Axis.prototype.init = function init() { - var $$ = this.owner, - config = $$.config, - main = $$.main; - $$.axes.x = main.append("g") - .attr("class", CLASS.axis + ' ' + CLASS.axisX) - .attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis) - .attr("transform", $$.getTranslate('x')) - .style("visibility", config.axis_x_show ? 'visible' : 'hidden'); - $$.axes.x.append("text") - .attr("class", CLASS.axisXLabel) - .attr("transform", config.axis_rotated ? "rotate(-90)" : "") - .style("text-anchor", this.textAnchorForXAxisLabel.bind(this)); - $$.axes.y = main.append("g") - .attr("class", CLASS.axis + ' ' + CLASS.axisY) - .attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis) - .attr("transform", $$.getTranslate('y')) - .style("visibility", config.axis_y_show ? 'visible' : 'hidden'); - $$.axes.y.append("text") - .attr("class", CLASS.axisYLabel) - .attr("transform", config.axis_rotated ? "" : "rotate(-90)") - .style("text-anchor", this.textAnchorForYAxisLabel.bind(this)); - - $$.axes.y2 = main.append("g") - .attr("class", CLASS.axis + ' ' + CLASS.axisY2) - // clip-path? - .attr("transform", $$.getTranslate('y2')) - .style("visibility", config.axis_y2_show ? 'visible' : 'hidden'); - $$.axes.y2.append("text") - .attr("class", CLASS.axisY2Label) - .attr("transform", config.axis_rotated ? "" : "rotate(-90)") - .style("text-anchor", this.textAnchorForY2AxisLabel.bind(this)); -}; -Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { - var $$ = this.owner, - config = $$.config, - axisParams = { - isCategory: $$.isCategorized(), - withOuterTick: withOuterTick, - tickMultiline: config.axis_x_tick_multiline, - tickMultilineMax: config.axis_x_tick_multiline ? Number(config.axis_x_tick_multilineMax) : 0, - tickWidth: config.axis_x_tick_width, - tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate, - withoutTransition: withoutTransition, - }, - axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); - - if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") { - tickValues = tickValues.map(function (v) { - return $$.parseDate(v); - }); - } + var $$ = this.owner, + config = $$.config, + main = $$.main; + $$.axes.x = main + .append('g') + .attr('class', CLASS.axis + ' ' + CLASS.axisX) + .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis) + .attr('transform', $$.getTranslate('x')) + .style('visibility', config.axis_x_show ? 'visible' : 'hidden'); + $$.axes.x + .append('text') + .attr('class', CLASS.axisXLabel) + .attr('transform', config.axis_rotated ? 'rotate(-90)' : '') + .style('text-anchor', this.textAnchorForXAxisLabel.bind(this)); + $$.axes.y = main + .append('g') + .attr('class', CLASS.axis + ' ' + CLASS.axisY) + .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis) + .attr('transform', $$.getTranslate('y')) + .style('visibility', config.axis_y_show ? 'visible' : 'hidden'); + $$.axes.y + .append('text') + .attr('class', CLASS.axisYLabel) + .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') + .style('text-anchor', this.textAnchorForYAxisLabel.bind(this)); + + $$.axes.y2 = main + .append('g') + .attr('class', CLASS.axis + ' ' + CLASS.axisY2) + // clip-path? + .attr('transform', $$.getTranslate('y2')) + .style('visibility', config.axis_y2_show ? 'visible' : 'hidden'); + $$.axes.y2 + .append('text') + .attr('class', CLASS.axisY2Label) + .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') + .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this)); +}; +Axis.prototype.getXAxis = function getXAxis( + scale, + orient, + tickFormat, + tickValues, + withOuterTick, + withoutTransition, + withoutRotateTickText +) { + var $$ = this.owner, + config = $$.config, + axisParams = { + isCategory: $$.isCategorized(), + withOuterTick: withOuterTick, + tickMultiline: config.axis_x_tick_multiline, + tickMultilineMax: config.axis_x_tick_multiline + ? Number(config.axis_x_tick_multilineMax) + : 0, + tickWidth: config.axis_x_tick_width, + tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate, + withoutTransition: withoutTransition + }, + axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); - // Set tick - axis.tickFormat(tickFormat).tickValues(tickValues); - if ($$.isCategorized()) { - axis.tickCentered(config.axis_x_tick_centered); - if (isEmpty(config.axis_x_tick_culling)) { - config.axis_x_tick_culling = false; - } - } + if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') { + tickValues = tickValues.map(function(v) { + return $$.parseDate(v) + }); + } - return axis; -}; -Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) { - var $$ = this.owner, - config = $$.config, - tickValues; - if (config.axis_x_tick_fit || config.axis_x_tick_count) { - tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries()); - } - if (axis) { - axis.tickValues(tickValues); - } else { - $$.xAxis.tickValues(tickValues); - $$.subXAxis.tickValues(tickValues); + // Set tick + axis.tickFormat(tickFormat).tickValues(tickValues); + if ($$.isCategorized()) { + axis.tickCentered(config.axis_x_tick_centered); + if (isEmpty(config.axis_x_tick_culling)) { + config.axis_x_tick_culling = false; } - return tickValues; -}; -Axis.prototype.getYAxis = function getYAxis(axisId, scale, orient, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { - const $$ = this.owner; - const config = $$.config; + } - let tickFormat = config[`axis_${axisId}_tick_format`]; - if (!tickFormat && $$.isAxisNormalized(axisId)) { - tickFormat = (x) => `${x}%`; - } + return axis +}; +Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues( + targets, + axis +) { + var $$ = this.owner, + config = $$.config, + tickValues; + if (config.axis_x_tick_fit || config.axis_x_tick_count) { + tickValues = this.generateTickValues( + $$.mapTargetsToUniqueXs(targets), + config.axis_x_tick_count, + $$.isTimeSeries() + ); + } + if (axis) { + axis.tickValues(tickValues); + } else { + $$.xAxis.tickValues(tickValues); + $$.subXAxis.tickValues(tickValues); + } + return tickValues +}; +Axis.prototype.getYAxis = function getYAxis( + axisId, + scale, + orient, + tickValues, + withOuterTick, + withoutTransition, + withoutRotateTickText +) { + const $$ = this.owner; + const config = $$.config; + + let tickFormat = config[`axis_${axisId}_tick_format`]; + if (!tickFormat && $$.isAxisNormalized(axisId)) { + tickFormat = x => `${x}%`; + } - const axis = new this.internal(this, { - withOuterTick: withOuterTick, - withoutTransition: withoutTransition, - tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate - }).axis - .scale(scale) - .orient(orient); + const axis = new this.internal(this, { + withOuterTick: withOuterTick, + withoutTransition: withoutTransition, + tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate + }).axis + .scale(scale) + .orient(orient); - if (tickFormat) { - axis.tickFormat(tickFormat); - } + if (tickFormat) { + axis.tickFormat(tickFormat); + } - if ($$.isTimeSeriesY()) { - axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval); - } else { - axis.tickValues(tickValues); - } - return axis; + if ($$.isTimeSeriesY()) { + axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval); + } else { + axis.tickValues(tickValues); + } + return axis }; Axis.prototype.getId = function getId(id) { - var config = this.owner.config; - return id in config.data_axes ? config.data_axes[id] : 'y'; + var config = this.owner.config; + return id in config.data_axes ? config.data_axes[id] : 'y' }; Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() { - // #2251 previously set any negative values to a whole number, - // however both should be truncated according to the users format specification - var $$ = this.owner, - config = $$.config; - let format = ($$.isTimeSeries()) ? $$.defaultAxisTimeFormat : ($$.isCategorized()) ? $$.categoryName : function (v) { - return v; - }; - - if (config.axis_x_tick_format) { - if (isFunction(config.axis_x_tick_format)) { - format = config.axis_x_tick_format; - } else if ($$.isTimeSeries()) { - format = function (date) { - return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ""; - }; - } + // #2251 previously set any negative values to a whole number, + // however both should be truncated according to the users format specification + var $$ = this.owner, + config = $$.config; + let format = $$.isTimeSeries() + ? $$.defaultAxisTimeFormat + : $$.isCategorized() + ? $$.categoryName + : function(v) { + return v + }; + + if (config.axis_x_tick_format) { + if (isFunction(config.axis_x_tick_format)) { + format = config.axis_x_tick_format; + } else if ($$.isTimeSeries()) { + format = function(date) { + return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : '' + }; } - return isFunction(format) ? function (v) { - return format.call($$, v); - } : format; + } + return isFunction(format) + ? function(v) { + return format.call($$, v) + } + : format }; Axis.prototype.getTickValues = function getTickValues(tickValues, axis) { - return tickValues ? tickValues : axis ? axis.tickValues() : undefined; + return tickValues ? tickValues : axis ? axis.tickValues() : undefined }; Axis.prototype.getXAxisTickValues = function getXAxisTickValues() { - return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis); + return this.getTickValues( + this.owner.config.axis_x_tick_values, + this.owner.xAxis + ) }; Axis.prototype.getYAxisTickValues = function getYAxisTickValues() { - return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis); + return this.getTickValues( + this.owner.config.axis_y_tick_values, + this.owner.yAxis + ) }; Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() { - return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis); -}; -Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) { - var $$ = this.owner, - config = $$.config, - option; - if (axisId === 'y') { - option = config.axis_y_label; - } else if (axisId === 'y2') { - option = config.axis_y2_label; - } else if (axisId === 'x') { - option = config.axis_x_label; - } - return option; + return this.getTickValues( + this.owner.config.axis_y2_tick_values, + this.owner.y2Axis + ) +}; +Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId( + axisId +) { + var $$ = this.owner, + config = $$.config, + option; + if (axisId === 'y') { + option = config.axis_y_label; + } else if (axisId === 'y2') { + option = config.axis_y2_label; + } else if (axisId === 'x') { + option = config.axis_x_label; + } + return option }; Axis.prototype.getLabelText = function getLabelText(axisId) { - var option = this.getLabelOptionByAxisId(axisId); - return isString(option) ? option : option ? option.text : null; + var option = this.getLabelOptionByAxisId(axisId); + return isString(option) ? option : option ? option.text : null }; Axis.prototype.setLabelText = function setLabelText(axisId, text) { - var $$ = this.owner, - config = $$.config, - option = this.getLabelOptionByAxisId(axisId); - if (isString(option)) { - if (axisId === 'y') { - config.axis_y_label = text; - } else if (axisId === 'y2') { - config.axis_y2_label = text; - } else if (axisId === 'x') { - config.axis_x_label = text; - } - } else if (option) { - option.text = text; + var $$ = this.owner, + config = $$.config, + option = this.getLabelOptionByAxisId(axisId); + if (isString(option)) { + if (axisId === 'y') { + config.axis_y_label = text; + } else if (axisId === 'y2') { + config.axis_y2_label = text; + } else if (axisId === 'x') { + config.axis_x_label = text; } + } else if (option) { + option.text = text; + } }; -Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) { - var option = this.getLabelOptionByAxisId(axisId), - position = (option && typeof option === 'object' && option.position) ? option.position : defaultPosition; - return { - isInner: position.indexOf('inner') >= 0, - isOuter: position.indexOf('outer') >= 0, - isLeft: position.indexOf('left') >= 0, - isCenter: position.indexOf('center') >= 0, - isRight: position.indexOf('right') >= 0, - isTop: position.indexOf('top') >= 0, - isMiddle: position.indexOf('middle') >= 0, - isBottom: position.indexOf('bottom') >= 0 - }; +Axis.prototype.getLabelPosition = function getLabelPosition( + axisId, + defaultPosition +) { + var option = this.getLabelOptionByAxisId(axisId), + position = + option && typeof option === 'object' && option.position + ? option.position + : defaultPosition; + return { + isInner: position.indexOf('inner') >= 0, + isOuter: position.indexOf('outer') >= 0, + isLeft: position.indexOf('left') >= 0, + isCenter: position.indexOf('center') >= 0, + isRight: position.indexOf('right') >= 0, + isTop: position.indexOf('top') >= 0, + isMiddle: position.indexOf('middle') >= 0, + isBottom: position.indexOf('bottom') >= 0 + } }; Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() { - return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'); + return this.getLabelPosition( + 'x', + this.owner.config.axis_rotated ? 'inner-top' : 'inner-right' + ) }; Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() { - return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'); + return this.getLabelPosition( + 'y', + this.owner.config.axis_rotated ? 'inner-right' : 'inner-top' + ) }; Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() { - return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'); + return this.getLabelPosition( + 'y2', + this.owner.config.axis_rotated ? 'inner-right' : 'inner-top' + ) }; Axis.prototype.getLabelPositionById = function getLabelPositionById(id) { - return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition(); + return id === 'y2' + ? this.getY2AxisLabelPosition() + : id === 'y' + ? this.getYAxisLabelPosition() + : this.getXAxisLabelPosition() }; Axis.prototype.textForXAxisLabel = function textForXAxisLabel() { - return this.getLabelText('x'); + return this.getLabelText('x') }; Axis.prototype.textForYAxisLabel = function textForYAxisLabel() { - return this.getLabelText('y'); + return this.getLabelText('y') }; Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() { - return this.getLabelText('y2'); + return this.getLabelText('y2') }; Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) { - var $$ = this.owner; - if (forHorizontal) { - return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width; - } else { - return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0; - } + var $$ = this.owner; + if (forHorizontal) { + return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width + } else { + return position.isBottom + ? -$$.height + : position.isMiddle + ? -$$.height / 2 + : 0 + } }; -Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) { - if (forHorizontal) { - return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0"; - } else { - return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0"; - } +Axis.prototype.dxForAxisLabel = function dxForAxisLabel( + forHorizontal, + position +) { + if (forHorizontal) { + return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0' + } else { + return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0' + } }; -Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) { - if (forHorizontal) { - return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'; - } else { - return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'; - } +Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel( + forHorizontal, + position +) { + if (forHorizontal) { + return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end' + } else { + return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end' + } }; Axis.prototype.xForXAxisLabel = function xForXAxisLabel() { - return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition()); + return this.xForAxisLabel( + !this.owner.config.axis_rotated, + this.getXAxisLabelPosition() + ) }; Axis.prototype.xForYAxisLabel = function xForYAxisLabel() { - return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition()); + return this.xForAxisLabel( + this.owner.config.axis_rotated, + this.getYAxisLabelPosition() + ) }; Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() { - return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition()); + return this.xForAxisLabel( + this.owner.config.axis_rotated, + this.getY2AxisLabelPosition() + ) }; Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() { - return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition()); + return this.dxForAxisLabel( + !this.owner.config.axis_rotated, + this.getXAxisLabelPosition() + ) }; Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() { - return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition()); + return this.dxForAxisLabel( + this.owner.config.axis_rotated, + this.getYAxisLabelPosition() + ) }; Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() { - return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition()); + return this.dxForAxisLabel( + this.owner.config.axis_rotated, + this.getY2AxisLabelPosition() + ) }; Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() { - var $$ = this.owner, - config = $$.config, - position = this.getXAxisLabelPosition(); - if (config.axis_rotated) { - return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); - } else { - return position.isInner ? "-0.5em" : $$.getHorizontalAxisHeight('x') - 10; - } + var $$ = this.owner, + config = $$.config, + position = this.getXAxisLabelPosition(); + if (config.axis_rotated) { + return position.isInner + ? '1.2em' + : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')) + } else { + return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10 + } }; Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() { - var $$ = this.owner, - position = this.getYAxisLabelPosition(); - if ($$.config.axis_rotated) { - return position.isInner ? "-0.5em" : "3em"; - } else { - return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : (this.getMaxTickWidth('y') + 10)); - } + var $$ = this.owner, + position = this.getYAxisLabelPosition(); + if ($$.config.axis_rotated) { + return position.isInner ? '-0.5em' : '3em' + } else { + return position.isInner + ? '1.2em' + : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10) + } }; Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() { - var $$ = this.owner, - position = this.getY2AxisLabelPosition(); - if ($$.config.axis_rotated) { - return position.isInner ? "1.2em" : "-2.2em"; - } else { - return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : (this.getMaxTickWidth('y2') + 15)); - } + var $$ = this.owner, + position = this.getY2AxisLabelPosition(); + if ($$.config.axis_rotated) { + return position.isInner ? '1.2em' : '-2.2em' + } else { + return position.isInner + ? '-0.5em' + : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15) + } }; Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() { - var $$ = this.owner; - return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition()); + var $$ = this.owner; + return this.textAnchorForAxisLabel( + !$$.config.axis_rotated, + this.getXAxisLabelPosition() + ) }; Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() { - var $$ = this.owner; - return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition()); + var $$ = this.owner; + return this.textAnchorForAxisLabel( + $$.config.axis_rotated, + this.getYAxisLabelPosition() + ) }; Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() { - var $$ = this.owner; - return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition()); -}; -Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) { - var $$ = this.owner, - maxWidth = 0, - targetsToShow, scale, axis, dummy, svg; - if (withoutRecompute && $$.currentMaxTickWidths[id]) { - return $$.currentMaxTickWidths[id]; - } - if ($$.svg) { - targetsToShow = $$.filterTargetsToShow($$.data.targets); - if (id === 'y') { - scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); - axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true); - } else if (id === 'y2') { - scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); - axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true); - } else { - scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); - axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true); - this.updateXAxisTickValues(targetsToShow, axis); - } - dummy = $$.d3.select('body').append('div').classed('c3', true); - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), - svg.append('g').call(axis).each(function () { - $$.d3.select(this).selectAll('text').each(function () { - var box = getBBox(this); - if (maxWidth < box.width) { - maxWidth = box.width; - } - }); - dummy.remove(); + var $$ = this.owner; + return this.textAnchorForAxisLabel( + $$.config.axis_rotated, + this.getY2AxisLabelPosition() + ) +}; +Axis.prototype.getMaxTickWidth = function getMaxTickWidth( + id, + withoutRecompute +) { + var $$ = this.owner, + maxWidth = 0, + targetsToShow, + scale, + axis, + dummy, + svg; + if (withoutRecompute && $$.currentMaxTickWidths[id]) { + return $$.currentMaxTickWidths[id] + } + if ($$.svg) { + targetsToShow = $$.filterTargetsToShow($$.data.targets); + if (id === 'y') { + scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); + axis = this.getYAxis( + id, + scale, + $$.yOrient, + $$.yAxisTickValues, + false, + true, + true + ); + } else if (id === 'y2') { + scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); + axis = this.getYAxis( + id, + scale, + $$.y2Orient, + $$.y2AxisTickValues, + false, + true, + true + ); + } else { + scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); + axis = this.getXAxis( + scale, + $$.xOrient, + $$.xAxisTickFormat, + $$.xAxisTickValues, + false, + true, + true + ); + this.updateXAxisTickValues(targetsToShow, axis); + } + dummy = $$.d3 + .select('body') + .append('div') + .classed('c3', true) + ;(svg = dummy + .append('svg') + .style('visibility', 'hidden') + .style('position', 'fixed') + .style('top', 0) + .style('left', 0)), + svg + .append('g') + .call(axis) + .each(function() { + $$.d3 + .select(this) + .selectAll('text') + .each(function() { + var box = getBBox(this); + if (maxWidth < box.width) { + maxWidth = box.width; + } }); - } - $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth; - return $$.currentMaxTickWidths[id]; + dummy.remove(); + }); + } + $$.currentMaxTickWidths[id] = + maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth; + return $$.currentMaxTickWidths[id] }; Axis.prototype.updateLabels = function updateLabels(withTransition) { - var $$ = this.owner; - var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), - axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), - axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label); - (withTransition ? axisXLabel.transition() : axisXLabel) - .attr("x", this.xForXAxisLabel.bind(this)) - .attr("dx", this.dxForXAxisLabel.bind(this)) - .attr("dy", this.dyForXAxisLabel.bind(this)) - .text(this.textForXAxisLabel.bind(this)); - (withTransition ? axisYLabel.transition() : axisYLabel) - .attr("x", this.xForYAxisLabel.bind(this)) - .attr("dx", this.dxForYAxisLabel.bind(this)) - .attr("dy", this.dyForYAxisLabel.bind(this)) - .text(this.textForYAxisLabel.bind(this)); - (withTransition ? axisY2Label.transition() : axisY2Label) - .attr("x", this.xForY2AxisLabel.bind(this)) - .attr("dx", this.dxForY2AxisLabel.bind(this)) - .attr("dy", this.dyForY2AxisLabel.bind(this)) - .text(this.textForY2AxisLabel.bind(this)); -}; -Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) { - var p = typeof padding === 'number' ? padding : padding[key]; - if (!isValue(p)) { - return defaultValue; - } - if (padding.unit === 'ratio') { - return padding[key] * domainLength; - } - // assume padding is pixels if unit is not specified - return this.convertPixelsToAxisPadding(p, domainLength); -}; -Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) { - var $$ = this.owner, - length = $$.config.axis_rotated ? $$.width : $$.height; - return domainLength * (pixels / length); -}; -Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) { - var tickValues = values, - targetCount, start, end, count, interval, i, tickValue; - if (tickCount) { - targetCount = isFunction(tickCount) ? tickCount() : tickCount; - // compute ticks according to tickCount - if (targetCount === 1) { - tickValues = [values[0]]; - } else if (targetCount === 2) { - tickValues = [values[0], values[values.length - 1]]; - } else if (targetCount > 2) { - count = targetCount - 2; - start = values[0]; - end = values[values.length - 1]; - interval = (end - start) / (count + 1); - // re-construct unique values - tickValues = [start]; - for (i = 0; i < count; i++) { - tickValue = +start + interval * (i + 1); - tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue); - } - tickValues.push(end); - } - } - if (!forTimeSeries) { - tickValues = tickValues.sort(function (a, b) { - return a - b; - }); + var $$ = this.owner; + var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), + axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), + axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label) + ;(withTransition ? axisXLabel.transition() : axisXLabel) + .attr('x', this.xForXAxisLabel.bind(this)) + .attr('dx', this.dxForXAxisLabel.bind(this)) + .attr('dy', this.dyForXAxisLabel.bind(this)) + .text(this.textForXAxisLabel.bind(this)) + ;(withTransition ? axisYLabel.transition() : axisYLabel) + .attr('x', this.xForYAxisLabel.bind(this)) + .attr('dx', this.dxForYAxisLabel.bind(this)) + .attr('dy', this.dyForYAxisLabel.bind(this)) + .text(this.textForYAxisLabel.bind(this)) + ;(withTransition ? axisY2Label.transition() : axisY2Label) + .attr('x', this.xForY2AxisLabel.bind(this)) + .attr('dx', this.dxForY2AxisLabel.bind(this)) + .attr('dy', this.dyForY2AxisLabel.bind(this)) + .text(this.textForY2AxisLabel.bind(this)); +}; +Axis.prototype.getPadding = function getPadding( + padding, + key, + defaultValue, + domainLength +) { + var p = typeof padding === 'number' ? padding : padding[key]; + if (!isValue(p)) { + return defaultValue + } + if (padding.unit === 'ratio') { + return padding[key] * domainLength + } + // assume padding is pixels if unit is not specified + return this.convertPixelsToAxisPadding(p, domainLength) +}; +Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding( + pixels, + domainLength +) { + var $$ = this.owner, + length = $$.config.axis_rotated ? $$.width : $$.height; + return domainLength * (pixels / length) +}; +Axis.prototype.generateTickValues = function generateTickValues( + values, + tickCount, + forTimeSeries +) { + var tickValues = values, + targetCount, + start, + end, + count, + interval, + i, + tickValue; + if (tickCount) { + targetCount = isFunction(tickCount) ? tickCount() : tickCount; + // compute ticks according to tickCount + if (targetCount === 1) { + tickValues = [values[0]]; + } else if (targetCount === 2) { + tickValues = [values[0], values[values.length - 1]]; + } else if (targetCount > 2) { + count = targetCount - 2; + start = values[0]; + end = values[values.length - 1]; + interval = (end - start) / (count + 1); + // re-construct unique values + tickValues = [start]; + for (i = 0; i < count; i++) { + tickValue = +start + interval * (i + 1); + tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue); + } + tickValues.push(end); } - return tickValues; + } + if (!forTimeSeries) { + tickValues = tickValues.sort(function(a, b) { + return a - b + }); + } + return tickValues }; Axis.prototype.generateTransitions = function generateTransitions(duration) { - var $$ = this.owner, - axes = $$.axes; - return { - axisX: duration ? axes.x.transition().duration(duration) : axes.x, - axisY: duration ? axes.y.transition().duration(duration) : axes.y, - axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2, - axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx - }; + var $$ = this.owner, + axes = $$.axes; + return { + axisX: duration ? axes.x.transition().duration(duration) : axes.x, + axisY: duration ? axes.y.transition().duration(duration) : axes.y, + axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2, + axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx + } }; Axis.prototype.redraw = function redraw(duration, isHidden) { - var $$ = this.owner, - transition = duration ? $$.d3.transition().duration(duration) : null; - $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition); - $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition); - $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition); - $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition); + var $$ = this.owner, + transition = duration ? $$.d3.transition().duration(duration) : null; + $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition); + $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition); + $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition); + $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition); }; var c3 = { - version: "0.7.15", - chart: { - fn: Chart.prototype, + version: '0.7.16', + chart: { + fn: Chart.prototype, + internal: { + fn: ChartInternal.prototype, + axis: { + fn: Axis.prototype, internal: { - fn: ChartInternal.prototype, - axis: { - fn: Axis.prototype, - internal: { - fn: AxisInternal.prototype - } - } + fn: AxisInternal.prototype } - }, - generate: function(config) { - return new Chart(config); + } } + }, + generate: function(config) { + return new Chart(config) + } }; ChartInternal.prototype.beforeInit = function() { - // can do something + // can do something }; ChartInternal.prototype.afterInit = function() { - // can do something + // can do something }; ChartInternal.prototype.init = function() { - var $$ = this, - config = $$.config; - - $$.initParams(); - - if (config.data_url) { - $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData); - } else if (config.data_json) { - $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys)); - } else if (config.data_rows) { - $$.initWithData($$.convertRowsToData(config.data_rows)); - } else if (config.data_columns) { - $$.initWithData($$.convertColumnsToData(config.data_columns)); - } else { - throw Error('url or json or rows or columns is required.'); - } + var $$ = this, + config = $$.config; + + $$.initParams(); + + if (config.data_url) { + $$.convertUrlToData( + config.data_url, + config.data_mimeType, + config.data_headers, + config.data_keys, + $$.initWithData + ); + } else if (config.data_json) { + $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys)); + } else if (config.data_rows) { + $$.initWithData($$.convertRowsToData(config.data_rows)); + } else if (config.data_columns) { + $$.initWithData($$.convertColumnsToData(config.data_columns)); + } else { + throw Error('url or json or rows or columns is required.') + } }; ChartInternal.prototype.initParams = function() { - var $$ = this, - d3 = $$.d3, - config = $$.config; - - // MEMO: clipId needs to be unique because it conflicts when multiple charts exist - $$.clipId = "c3-" + (+new Date()) + '-clip'; - $$.clipIdForXAxis = $$.clipId + '-xaxis'; - $$.clipIdForYAxis = $$.clipId + '-yaxis'; - $$.clipIdForGrid = $$.clipId + '-grid'; - $$.clipIdForSubchart = $$.clipId + '-subchart'; - $$.clipPath = $$.getClipPath($$.clipId); - $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis); - $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis); - $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid); - $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart); - - $$.dragStart = null; - $$.dragging = false; - $$.flowing = false; - $$.cancelClick = false; - $$.mouseover = undefined; - $$.transiting = false; - - $$.color = $$.generateColor(); - $$.levelColor = $$.generateLevelColor(); - - $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat); - $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat; - $$.defaultAxisTimeFormat = function(date) { - if (date.getMilliseconds()) { - return d3.timeFormat(".%L")(date); - } - if (date.getSeconds()) { - return d3.timeFormat(":%S")(date); - } - if (date.getMinutes()) { - return d3.timeFormat("%I:%M")(date); - } - if (date.getHours()) { - return d3.timeFormat("%I %p")(date); - } - if (date.getDay() && date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); - } - if (date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); - } - if (date.getMonth()) { - return d3.timeFormat("%-m/%-d")(date); - } - return d3.timeFormat("%Y/%-m/%-d")(date); - }; - $$.hiddenTargetIds = []; - $$.hiddenLegendIds = []; - $$.focusedTargetIds = []; - $$.defocusedTargetIds = []; + var $$ = this, + d3 = $$.d3, + config = $$.config; + + // MEMO: clipId needs to be unique because it conflicts when multiple charts exist + $$.clipId = 'c3-' + new Date().valueOf() + '-clip'; + $$.clipIdForXAxis = $$.clipId + '-xaxis'; + $$.clipIdForYAxis = $$.clipId + '-yaxis'; + $$.clipIdForGrid = $$.clipId + '-grid'; + $$.clipIdForSubchart = $$.clipId + '-subchart'; + $$.clipPath = $$.getClipPath($$.clipId); + $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis); + $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis); + $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid); + $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart); + + $$.dragStart = null; + $$.dragging = false; + $$.flowing = false; + $$.cancelClick = false; + $$.mouseover = undefined; + $$.transiting = false; + + $$.color = $$.generateColor(); + $$.levelColor = $$.generateLevelColor(); + + $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)( + $$.config.data_xFormat + ); + $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat; + $$.defaultAxisTimeFormat = function(date) { + if (date.getMilliseconds()) { + return d3.timeFormat('.%L')(date) + } + if (date.getSeconds()) { + return d3.timeFormat(':%S')(date) + } + if (date.getMinutes()) { + return d3.timeFormat('%I:%M')(date) + } + if (date.getHours()) { + return d3.timeFormat('%I %p')(date) + } + if (date.getDay() && date.getDate() !== 1) { + return d3.timeFormat('%-m/%-d')(date) + } + if (date.getDate() !== 1) { + return d3.timeFormat('%-m/%-d')(date) + } + if (date.getMonth()) { + return d3.timeFormat('%-m/%-d')(date) + } + return d3.timeFormat('%Y/%-m/%-d')(date) + }; + $$.hiddenTargetIds = []; + $$.hiddenLegendIds = []; + $$.focusedTargetIds = []; + $$.defocusedTargetIds = []; + + $$.xOrient = config.axis_rotated + ? config.axis_x_inner + ? 'right' + : 'left' + : config.axis_x_inner + ? 'top' + : 'bottom'; + $$.yOrient = config.axis_rotated + ? config.axis_y_inner + ? 'top' + : 'bottom' + : config.axis_y_inner + ? 'right' + : 'left'; + $$.y2Orient = config.axis_rotated + ? config.axis_y2_inner + ? 'bottom' + : 'top' + : config.axis_y2_inner + ? 'left' + : 'right'; + $$.subXOrient = config.axis_rotated ? 'left' : 'bottom'; + + $$.isLegendRight = config.legend_position === 'right'; + $$.isLegendInset = config.legend_position === 'inset'; + $$.isLegendTop = + config.legend_inset_anchor === 'top-left' || + config.legend_inset_anchor === 'top-right'; + $$.isLegendLeft = + config.legend_inset_anchor === 'top-left' || + config.legend_inset_anchor === 'bottom-left'; + $$.legendStep = 0; + $$.legendItemWidth = 0; + $$.legendItemHeight = 0; + + $$.currentMaxTickWidths = { + x: 0, + y: 0, + y2: 0 + }; + + $$.rotated_padding_left = 30; + $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30; + $$.rotated_padding_top = 5; + + $$.withoutFadeIn = {}; + + $$.intervalForObserveInserted = undefined; + + $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js +}; - $$.xOrient = config.axis_rotated ? (config.axis_x_inner ? "right" : "left") : (config.axis_x_inner ? "top" : "bottom"); - $$.yOrient = config.axis_rotated ? (config.axis_y_inner ? "top" : "bottom") : (config.axis_y_inner ? "right" : "left"); - $$.y2Orient = config.axis_rotated ? (config.axis_y2_inner ? "bottom" : "top") : (config.axis_y2_inner ? "left" : "right"); - $$.subXOrient = config.axis_rotated ? "left" : "bottom"; +ChartInternal.prototype.initChartElements = function() { + if (this.initBar) { + this.initBar(); + } + if (this.initLine) { + this.initLine(); + } + if (this.initArc) { + this.initArc(); + } + if (this.initGauge) { + this.initGauge(); + } + if (this.initText) { + this.initText(); + } +}; - $$.isLegendRight = config.legend_position === 'right'; - $$.isLegendInset = config.legend_position === 'inset'; - $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right'; - $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left'; - $$.legendStep = 0; - $$.legendItemWidth = 0; - $$.legendItemHeight = 0; +ChartInternal.prototype.initWithData = function(data) { + var $$ = this, + d3 = $$.d3, + config = $$.config; + var defs, + main, + binding = true; + + $$.axis = new Axis($$); + + if (!config.bindto) { + $$.selectChart = d3.selectAll([]); + } else if (typeof config.bindto.node === 'function') { + $$.selectChart = config.bindto; + } else { + $$.selectChart = d3.select(config.bindto); + } + if ($$.selectChart.empty()) { + $$.selectChart = d3 + .select(document.createElement('div')) + .style('opacity', 0); + $$.observeInserted($$.selectChart); + binding = false; + } + $$.selectChart.html('').classed('c3', true); - $$.currentMaxTickWidths = { - x: 0, - y: 0, - y2: 0 - }; + // Init data as targets + $$.data.xs = {}; + $$.data.targets = $$.convertDataToTargets(data); - $$.rotated_padding_left = 30; - $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30; - $$.rotated_padding_top = 5; + if (config.data_filter) { + $$.data.targets = $$.data.targets.filter(config.data_filter); + } - $$.withoutFadeIn = {}; + // Set targets to hide if needed + if (config.data_hide) { + $$.addHiddenTargetIds( + config.data_hide === true + ? $$.mapToIds($$.data.targets) + : config.data_hide + ); + } + if (config.legend_hide) { + $$.addHiddenLegendIds( + config.legend_hide === true + ? $$.mapToIds($$.data.targets) + : config.legend_hide + ); + } - $$.intervalForObserveInserted = undefined; + if ($$.isStanfordGraphType()) { + $$.initStanfordData(); + } - $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js -}; + // Init sizes and scales + $$.updateSizes(); + $$.updateScales(); + + // Set domains for each scale + $$.x.domain(d3.extent($$.getXDomain($$.data.targets))); + $$.y.domain($$.getYDomain($$.data.targets, 'y')); + $$.y2.domain($$.getYDomain($$.data.targets, 'y2')); + $$.subX.domain($$.x.domain()); + $$.subY.domain($$.y.domain()); + $$.subY2.domain($$.y2.domain()); + + // Save original x domain for zoom update + $$.orgXDomain = $$.x.domain(); + + /*-- Basic Elements --*/ + + // Define svgs + $$.svg = $$.selectChart + .append('svg') + .style('overflow', 'hidden') + .on('mouseenter', function() { + return config.onmouseover.call($$) + }) + .on('mouseleave', function() { + return config.onmouseout.call($$) + }); -ChartInternal.prototype.initChartElements = function() { - if (this.initBar) { - this.initBar(); - } - if (this.initLine) { - this.initLine(); - } - if (this.initArc) { - this.initArc(); - } - if (this.initGauge) { - this.initGauge(); - } - if (this.initText) { - this.initText(); - } -}; + if ($$.config.svg_classname) { + $$.svg.attr('class', $$.config.svg_classname); + } -ChartInternal.prototype.initWithData = function(data) { - var $$ = this, - d3 = $$.d3, - config = $$.config; - var defs, main, binding = true; + // Define defs + defs = $$.svg.append('defs'); + $$.clipChart = $$.appendClip(defs, $$.clipId); + $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); + $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); + $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid); + $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); + $$.updateSvgSize(); - $$.axis = new Axis($$); + // Define regions + main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main')); - if (!config.bindto) { - $$.selectChart = d3.selectAll([]); - } else if (typeof config.bindto.node === 'function') { - $$.selectChart = config.bindto; - } else { - $$.selectChart = d3.select(config.bindto); - } - if ($$.selectChart.empty()) { - $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0); - $$.observeInserted($$.selectChart); - binding = false; - } - $$.selectChart.html("").classed("c3", true); + if ($$.initPie) { + $$.initPie(); + } + if ($$.initDragZoom) { + $$.initDragZoom(); + } + if (config.subchart_show && $$.initSubchart) { + $$.initSubchart(); + } + if ($$.initTooltip) { + $$.initTooltip(); + } + if ($$.initLegend) { + $$.initLegend(); + } + if ($$.initTitle) { + $$.initTitle(); + } + if ($$.initZoom) { + $$.initZoom(); + } + if ($$.isStanfordGraphType()) { + $$.drawColorScale(); + } - // Init data as targets - $$.data.xs = {}; - $$.data.targets = $$.convertDataToTargets(data); + // Update selection based on size and scale + // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart. + if (config.subchart_show && $$.initSubchartBrush) { + $$.initSubchartBrush(); + } - if (config.data_filter) { - $$.data.targets = $$.data.targets.filter(config.data_filter); - } + /*-- Main Region --*/ - // Set targets to hide if needed - if (config.data_hide) { - $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide); - } - if (config.legend_hide) { - $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide); - } + // text when empty + main + .append('text') + .attr('class', CLASS.text + ' ' + CLASS.empty) + .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers. + .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE. - if($$.isStanfordGraphType()) { - $$.initStanfordData(); - } + // Regions + $$.initRegion(); - // Init sizes and scales - $$.updateSizes(); - $$.updateScales(); + // Grids + $$.initGrid(); - // Set domains for each scale - $$.x.domain(d3.extent($$.getXDomain($$.data.targets))); - $$.y.domain($$.getYDomain($$.data.targets, 'y')); - $$.y2.domain($$.getYDomain($$.data.targets, 'y2')); - $$.subX.domain($$.x.domain()); - $$.subY.domain($$.y.domain()); - $$.subY2.domain($$.y2.domain()); + // Define g for chart area + main + .append('g') + .attr('clip-path', $$.clipPath) + .attr('class', CLASS.chart); - // Save original x domain for zoom update - $$.orgXDomain = $$.x.domain(); + // Grid lines + if (config.grid_lines_front) { + $$.initGridLines(); + } - /*-- Basic Elements --*/ + $$.initStanfordElements(); - // Define svgs - $$.svg = $$.selectChart.append("svg") - .style("overflow", "hidden") - .on('mouseenter', function() { - return config.onmouseover.call($$); - }) - .on('mouseleave', function() { - return config.onmouseout.call($$); - }); + // Cover whole with rects for events + $$.initEventRect(); - if ($$.config.svg_classname) { - $$.svg.attr('class', $$.config.svg_classname); - } + // Define g for chart + $$.initChartElements(); - // Define defs - defs = $$.svg.append("defs"); - $$.clipChart = $$.appendClip(defs, $$.clipId); - $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); - $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); - $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid); - $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); - $$.updateSvgSize(); + // Add Axis + $$.axis.init(); - // Define regions - main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main')); + // Set targets + $$.updateTargets($$.data.targets); - if ($$.initPie) { - $$.initPie(); - } - if ($$.initDragZoom) { - $$.initDragZoom(); - } - if (config.subchart_show && $$.initSubchart) { - $$.initSubchart(); - } - if ($$.initTooltip) { - $$.initTooltip(); - } - if ($$.initLegend) { - $$.initLegend(); - } - if ($$.initTitle) { - $$.initTitle(); - } - if ($$.initZoom) { - $$.initZoom(); - } - if($$.isStanfordGraphType()) { - $$.drawColorScale(); - } - - // Update selection based on size and scale - // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart. - if (config.subchart_show && $$.initSubchartBrush) { - $$.initSubchartBrush(); - } - - /*-- Main Region --*/ - - // text when empty - main.append("text") - .attr("class", CLASS.text + ' ' + CLASS.empty) - .attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers. - .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE. - - // Regions - $$.initRegion(); - - // Grids - $$.initGrid(); - - // Define g for chart area - main.append('g') - .attr("clip-path", $$.clipPath) - .attr('class', CLASS.chart); - - // Grid lines - if (config.grid_lines_front) { - $$.initGridLines(); - } - - $$.initStanfordElements(); - - // Cover whole with rects for events - $$.initEventRect(); - - // Define g for chart - $$.initChartElements(); - - // Add Axis - $$.axis.init(); - - // Set targets - $$.updateTargets($$.data.targets); - - // Set default extent if defined - if (config.axis_x_selection) { - $$.brush.selectionAsValue($$.getDefaultSelection()); - } + // Set default extent if defined + if (config.axis_x_selection) { + $$.brush.selectionAsValue($$.getDefaultSelection()); + } - // Draw with targets - if (binding) { - $$.updateDimension(); - $$.config.oninit.call($$); - $$.redraw({ - withTransition: false, - withTransform: true, - withUpdateXDomain: true, - withUpdateOrgXDomain: true, - withTransitionForAxis: false - }); - } + // Draw with targets + if (binding) { + $$.updateDimension(); + $$.config.oninit.call($$); + $$.redraw({ + withTransition: false, + withTransform: true, + withUpdateXDomain: true, + withUpdateOrgXDomain: true, + withTransitionForAxis: false + }); + } - // Bind to resize event - $$.bindResize(); + // Bind to resize event + $$.bindResize(); - // Bind to window focus event - $$.bindWindowFocus(); + // Bind to window focus event + $$.bindWindowFocus(); - // export element of the chart - $$.api.element = $$.selectChart.node(); + // export element of the chart + $$.api.element = $$.selectChart.node(); }; ChartInternal.prototype.smoothLines = function(el, type) { - var $$ = this; - if (type === 'grid') { - el.each(function() { - var g = $$.d3.select(this), - x1 = g.attr('x1'), - x2 = g.attr('x2'), - y1 = g.attr('y1'), - y2 = g.attr('y2'); - g.attr({ - 'x1': Math.ceil(x1), - 'x2': Math.ceil(x2), - 'y1': Math.ceil(y1), - 'y2': Math.ceil(y2) - }); - }); - } + var $$ = this; + if (type === 'grid') { + el.each(function() { + var g = $$.d3.select(this), + x1 = g.attr('x1'), + x2 = g.attr('x2'), + y1 = g.attr('y1'), + y2 = g.attr('y2'); + g.attr({ + x1: Math.ceil(x1), + x2: Math.ceil(x2), + y1: Math.ceil(y1), + y2: Math.ceil(y2) + }); + }); + } }; ChartInternal.prototype.updateSizes = function() { - var $$ = this, - config = $$.config; - var legendHeight = $$.legend ? $$.getLegendHeight() : 0, - legendWidth = $$.legend ? $$.getLegendWidth() : 0, - legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, - hasArc = $$.hasArcType(), - xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), - subchartHeight = config.subchart_show && !hasArc ? (config.subchart_size_height + xAxisHeight) : 0; - - $$.currentWidth = $$.getCurrentWidth(); - $$.currentHeight = $$.getCurrentHeight(); - - // for main - $$.margin = config.axis_rotated ? { + var $$ = this, + config = $$.config; + var legendHeight = $$.legend ? $$.getLegendHeight() : 0, + legendWidth = $$.legend ? $$.getLegendWidth() : 0, + legendHeightForBottom = + $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, + hasArc = $$.hasArcType(), + xAxisHeight = + config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), + subchartHeight = + config.subchart_show && !hasArc + ? config.subchart_size_height + xAxisHeight + : 0; + + $$.currentWidth = $$.getCurrentWidth(); + $$.currentHeight = $$.getCurrentHeight(); + + // for main + $$.margin = config.axis_rotated + ? { top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(), right: hasArc ? 0 : $$.getCurrentPaddingRight(), - bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(), + bottom: + $$.getHorizontalAxisHeight('y') + + legendHeightForBottom + + $$.getCurrentPaddingBottom(), left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft()) - } : { + } + : { top: 4 + $$.getCurrentPaddingTop(), // for top tick text right: hasArc ? 0 : $$.getCurrentPaddingRight(), - bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(), + bottom: + xAxisHeight + + subchartHeight + + legendHeightForBottom + + $$.getCurrentPaddingBottom(), left: hasArc ? 0 : $$.getCurrentPaddingLeft() - }; + }; - // for subchart - $$.margin2 = config.axis_rotated ? { + // for subchart + $$.margin2 = config.axis_rotated + ? { top: $$.margin.top, right: NaN, bottom: 20 + legendHeightForBottom, left: $$.rotated_padding_left - } : { + } + : { top: $$.currentHeight - subchartHeight - legendHeightForBottom, right: NaN, bottom: xAxisHeight + legendHeightForBottom, left: $$.margin.left - }; - - // for legend - $$.margin3 = { - top: 0, - right: NaN, - bottom: 0, - left: 0 - }; - if ($$.updateSizeForLegend) { - $$.updateSizeForLegend(legendHeight, legendWidth); - } + }; + + // for legend + $$.margin3 = { + top: 0, + right: NaN, + bottom: 0, + left: 0 + }; + if ($$.updateSizeForLegend) { + $$.updateSizeForLegend(legendHeight, legendWidth); + } - $$.width = $$.currentWidth - $$.margin.left - $$.margin.right; - $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom; - if ($$.width < 0) { - $$.width = 0; - } - if ($$.height < 0) { - $$.height = 0; - } + $$.width = $$.currentWidth - $$.margin.left - $$.margin.right; + $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom; + if ($$.width < 0) { + $$.width = 0; + } + if ($$.height < 0) { + $$.height = 0; + } - $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width; - $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom; - if ($$.width2 < 0) { - $$.width2 = 0; - } - if ($$.height2 < 0) { - $$.height2 = 0; - } + $$.width2 = config.axis_rotated + ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right + : $$.width; + $$.height2 = config.axis_rotated + ? $$.height + : $$.currentHeight - $$.margin2.top - $$.margin2.bottom; + if ($$.width2 < 0) { + $$.width2 = 0; + } + if ($$.height2 < 0) { + $$.height2 = 0; + } - // for arc - $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0); - $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10); - if ($$.hasType('gauge') && !config.gauge_fullCircle) { - $$.arcHeight += $$.height - $$.getGaugeLabelHeight(); - } - if ($$.updateRadius) { - $$.updateRadius(); - } + // for arc + $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0); + $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10); + if ($$.hasType('gauge') && !config.gauge_fullCircle) { + $$.arcHeight += $$.height - $$.getGaugeLabelHeight(); + } + if ($$.updateRadius) { + $$.updateRadius(); + } - if ($$.isLegendRight && hasArc) { - $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1; - } + if ($$.isLegendRight && hasArc) { + $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1; + } }; ChartInternal.prototype.updateTargets = function(targets) { - var $$ = this, config = $$.config; + var $$ = this, + config = $$.config; - /*-- Main --*/ + /*-- Main --*/ - //-- Text --// - $$.updateTargetsForText(targets); + //-- Text --// + $$.updateTargetsForText(targets); - //-- Bar --// - $$.updateTargetsForBar(targets); + //-- Bar --// + $$.updateTargetsForBar(targets); - //-- Line --// - $$.updateTargetsForLine(targets); + //-- Line --// + $$.updateTargetsForLine(targets); - //-- Arc --// - if ($$.hasArcType() && $$.updateTargetsForArc) { - $$.updateTargetsForArc(targets); - } + //-- Arc --// + if ($$.hasArcType() && $$.updateTargetsForArc) { + $$.updateTargetsForArc(targets); + } - /*-- Sub --*/ + /*-- Sub --*/ - if (config.subchart_show && $$.updateTargetsForSubchart) { - $$.updateTargetsForSubchart(targets); - } + if (config.subchart_show && $$.updateTargetsForSubchart) { + $$.updateTargetsForSubchart(targets); + } - // Fade-in each chart - $$.showTargets(); + // Fade-in each chart + $$.showTargets(); }; ChartInternal.prototype.showTargets = function() { - var $$ = this; - $$.svg.selectAll('.' + CLASS.target).filter(function(d) { - return $$.isTargetToShow(d.id); - }) - .transition().duration($$.config.transition_duration) - .style("opacity", 1); + var $$ = this; + $$.svg + .selectAll('.' + CLASS.target) + .filter(function(d) { + return $$.isTargetToShow(d.id) + }) + .transition() + .duration($$.config.transition_duration) + .style('opacity', 1); }; ChartInternal.prototype.redraw = function(options, transitions) { - var $$ = this, - main = $$.main, - d3 = $$.d3, - config = $$.config; - var areaIndices = $$.getShapeIndices($$.isAreaType), - barIndices = $$.getShapeIndices($$.isBarType), - lineIndices = $$.getShapeIndices($$.isLineType); - var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, - withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, - withEventRect, withDimension, withUpdateXAxis; - var hideAxis = $$.hasArcType(); - var drawArea, drawBar, drawLine, xForText, yForText; - var duration, durationForExit, durationForAxis; - var transitionsToWait, waitForDraw, flow, transition; - var targetsToShow = $$.filterTargetsToShow($$.data.targets), - tickValues, i, intervalForCulling, xDomainForZoom; - var xv = $$.xv.bind($$), - cx, cy; - - options = options || {}; - withY = getOption(options, "withY", true); - withSubchart = getOption(options, "withSubchart", true); - withTransition = getOption(options, "withTransition", true); - withTransform = getOption(options, "withTransform", false); - withUpdateXDomain = getOption(options, "withUpdateXDomain", false); - withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false); - withTrimXDomain = getOption(options, "withTrimXDomain", true); - withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain); - withLegend = getOption(options, "withLegend", false); - withEventRect = getOption(options, "withEventRect", true); - withDimension = getOption(options, "withDimension", true); - withTransitionForExit = getOption(options, "withTransitionForExit", withTransition); - withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition); - - duration = withTransition ? config.transition_duration : 0; - durationForExit = withTransitionForExit ? duration : 0; - durationForAxis = withTransitionForAxis ? duration : 0; - - transitions = transitions || $$.axis.generateTransitions(durationForAxis); - - // update legend and transform each g - if (withLegend && config.legend_show) { - $$.updateLegend($$.mapToIds($$.data.targets), options, transitions); - } else if (withDimension) { - // need to update dimension (e.g. axis.y.tick.values) because y tick values should change - // no need to update axis in it because they will be updated in redraw() - $$.updateDimension(true); - } - - // MEMO: needed for grids calculation - if ($$.isCategorized() && targetsToShow.length === 0) { - $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]); - } - - if (targetsToShow.length) { - $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain); - if (!config.axis_x_tick_values) { - tickValues = $$.axis.updateXAxisTickValues(targetsToShow); - } - } else { - $$.xAxis.tickValues([]); - $$.subXAxis.tickValues([]); - } - - if (config.zoom_rescale && !options.flow) { - xDomainForZoom = $$.x.orgDomain(); - } - - $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom)); - $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom)); - - if (!config.axis_y_tick_values && config.axis_y_tick_count) { - $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)); - } - if (!config.axis_y2_tick_values && config.axis_y2_tick_count) { - $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)); - } + var $$ = this, + main = $$.main, + d3 = $$.d3, + config = $$.config; + var areaIndices = $$.getShapeIndices($$.isAreaType), + barIndices = $$.getShapeIndices($$.isBarType), + lineIndices = $$.getShapeIndices($$.isLineType); + var withY, + withSubchart, + withTransition, + withTransitionForExit, + withTransitionForAxis, + withTransform, + withUpdateXDomain, + withUpdateOrgXDomain, + withTrimXDomain, + withLegend, + withEventRect, + withDimension, + withUpdateXAxis; + var hideAxis = $$.hasArcType(); + var drawArea, drawBar, drawLine, xForText, yForText; + var duration, durationForExit, durationForAxis; + var transitionsToWait, waitForDraw, flow, transition; + var targetsToShow = $$.filterTargetsToShow($$.data.targets), + tickValues, + i, + intervalForCulling, + xDomainForZoom; + var xv = $$.xv.bind($$), + cx, + cy; + + options = options || {}; + withY = getOption(options, 'withY', true); + withSubchart = getOption(options, 'withSubchart', true); + withTransition = getOption(options, 'withTransition', true); + withTransform = getOption(options, 'withTransform', false); + withUpdateXDomain = getOption(options, 'withUpdateXDomain', false); + withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false); + withTrimXDomain = getOption(options, 'withTrimXDomain', true); + withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain); + withLegend = getOption(options, 'withLegend', false); + withEventRect = getOption(options, 'withEventRect', true); + withDimension = getOption(options, 'withDimension', true); + withTransitionForExit = getOption( + options, + 'withTransitionForExit', + withTransition + ); + withTransitionForAxis = getOption( + options, + 'withTransitionForAxis', + withTransition + ); + + duration = withTransition ? config.transition_duration : 0; + durationForExit = withTransitionForExit ? duration : 0; + durationForAxis = withTransitionForAxis ? duration : 0; + + transitions = transitions || $$.axis.generateTransitions(durationForAxis); + + // update legend and transform each g + if (withLegend && config.legend_show) { + $$.updateLegend($$.mapToIds($$.data.targets), options, transitions); + } else if (withDimension) { + // need to update dimension (e.g. axis.y.tick.values) because y tick values should change + // no need to update axis in it because they will be updated in redraw() + $$.updateDimension(true); + } - // axes - $$.axis.redraw(durationForAxis, hideAxis); + // MEMO: needed for grids calculation + if ($$.isCategorized() && targetsToShow.length === 0) { + $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]); + } - // Update axis label - $$.axis.updateLabels(withTransition); + if (targetsToShow.length) { + $$.updateXDomain( + targetsToShow, + withUpdateXDomain, + withUpdateOrgXDomain, + withTrimXDomain + ); + if (!config.axis_x_tick_values) { + tickValues = $$.axis.updateXAxisTickValues(targetsToShow); + } + } else { + $$.xAxis.tickValues([]); + $$.subXAxis.tickValues([]); + } - // show/hide if manual culling needed - if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) { - if (config.axis_x_tick_culling && tickValues) { - for (i = 1; i < tickValues.length; i++) { - if (tickValues.length / i < config.axis_x_tick_culling_max) { - intervalForCulling = i; - break; - } - } - $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) { - var index = tickValues.indexOf(e); - if (index >= 0) { - d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block'); - } - }); - } else { - $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block'); - } - } + if (config.zoom_rescale && !options.flow) { + xDomainForZoom = $$.x.orgDomain(); + } - // setup drawer - MEMO: these must be called after axis updated - drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined; - drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined; - drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined; - xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true); - yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); + $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom)); + $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom)); - // update circleY based on updated parameters - $$.updateCircleY(); - // generate circle x/y functions depending on updated params - cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$); - cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); + if (!config.axis_y_tick_values && config.axis_y_tick_count) { + $$.yAxis.tickValues( + $$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count) + ); + } + if (!config.axis_y2_tick_values && config.axis_y2_tick_count) { + $$.y2Axis.tickValues( + $$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count) + ); + } - // Update sub domain - if (withY) { - $$.subY.domain($$.getYDomain(targetsToShow, 'y')); - $$.subY2.domain($$.getYDomain(targetsToShow, 'y2')); + // axes + $$.axis.redraw(durationForAxis, hideAxis); + + // Update axis label + $$.axis.updateLabels(withTransition); + + // show/hide if manual culling needed + if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) { + if (config.axis_x_tick_culling && tickValues) { + for (i = 1; i < tickValues.length; i++) { + if (tickValues.length / i < config.axis_x_tick_culling_max) { + intervalForCulling = i; + break + } + } + $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) { + var index = tickValues.indexOf(e); + if (index >= 0) { + d3.select(this).style( + 'display', + index % intervalForCulling ? 'none' : 'block' + ); + } + }); + } else { + $$.svg + .selectAll('.' + CLASS.axisX + ' .tick text') + .style('display', 'block'); } + } - // xgrid focus - $$.updateXgridFocus(); - - // Data empty label positioning and text. - main.select("text." + CLASS.text + '.' + CLASS.empty) - .attr("x", $$.width / 2) - .attr("y", $$.height / 2) - .text(config.data_empty_label_text) - .transition() - .style('opacity', targetsToShow.length ? 0 : 1); - - // event rect - if (withEventRect) { - $$.redrawEventRect(); - } + // setup drawer - MEMO: these must be called after axis updated + drawArea = $$.generateDrawArea + ? $$.generateDrawArea(areaIndices, false) + : undefined; + drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined; + drawLine = $$.generateDrawLine + ? $$.generateDrawLine(lineIndices, false) + : undefined; + xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true); + yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); + + // update circleY based on updated parameters + $$.updateCircleY(); + // generate circle x/y functions depending on updated params + cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$); + cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); + + // Update sub domain + if (withY) { + $$.subY.domain($$.getYDomain(targetsToShow, 'y')); + $$.subY2.domain($$.getYDomain(targetsToShow, 'y2')); + } - // grid - $$.updateGrid(duration); + // xgrid focus + $$.updateXgridFocus(); + + // Data empty label positioning and text. + main + .select('text.' + CLASS.text + '.' + CLASS.empty) + .attr('x', $$.width / 2) + .attr('y', $$.height / 2) + .text(config.data_empty_label_text) + .transition() + .style('opacity', targetsToShow.length ? 0 : 1); + + // event rect + if (withEventRect) { + $$.redrawEventRect(); + } - $$.updateStanfordElements(duration); + // grid + $$.updateGrid(duration); - // rect for regions - $$.updateRegion(duration); + $$.updateStanfordElements(duration); - // bars - $$.updateBar(durationForExit); + // rect for regions + $$.updateRegion(duration); - // lines, areas and circles - $$.updateLine(durationForExit); - $$.updateArea(durationForExit); - $$.updateCircle(cx, cy); + // bars + $$.updateBar(durationForExit); - // text - if ($$.hasDataLabel()) { - $$.updateText(xForText, yForText, durationForExit); - } + // lines, areas and circles + $$.updateLine(durationForExit); + $$.updateArea(durationForExit); + $$.updateCircle(cx, cy); - // title - if ($$.redrawTitle) { - $$.redrawTitle(); - } + // text + if ($$.hasDataLabel()) { + $$.updateText(xForText, yForText, durationForExit); + } - // arc - if ($$.redrawArc) { - $$.redrawArc(duration, durationForExit, withTransform); - } + // title + if ($$.redrawTitle) { + $$.redrawTitle(); + } - // subchart - if (config.subchart_show && $$.redrawSubchart) { - $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices); - } + // arc + if ($$.redrawArc) { + $$.redrawArc(duration, durationForExit, withTransform); + } - if ($$.isStanfordGraphType()) { - $$.drawColorScale(); - } + // subchart + if (config.subchart_show && $$.redrawSubchart) { + $$.redrawSubchart( + withSubchart, + transitions, + duration, + durationForExit, + areaIndices, + barIndices, + lineIndices + ); + } - // circles for select - main.selectAll('.' + CLASS.selectedCircles) - .filter($$.isBarType.bind($$)) - .selectAll('circle') - .remove(); + if ($$.isStanfordGraphType()) { + $$.drawColorScale(); + } - if (options.flow) { - flow = $$.generateFlow({ - targets: targetsToShow, - flow: options.flow, - duration: options.flow.duration, - drawBar: drawBar, - drawLine: drawLine, - drawArea: drawArea, - cx: cx, - cy: cy, - xv: xv, - xForText: xForText, - yForText: yForText - }); - } + // circles for select + main + .selectAll('.' + CLASS.selectedCircles) + .filter($$.isBarType.bind($$)) + .selectAll('circle') + .remove(); + + if (options.flow) { + flow = $$.generateFlow({ + targets: targetsToShow, + flow: options.flow, + duration: options.flow.duration, + drawBar: drawBar, + drawLine: drawLine, + drawArea: drawArea, + cx: cx, + cy: cy, + xv: xv, + xForText: xForText, + yForText: yForText + }); + } - if (duration && $$.isTabVisible()) { // Only use transition if tab visible. See #938. - // transition should be derived from one transition - transition = d3.transition().duration(duration); - transitionsToWait = []; - [ - $$.redrawBar(drawBar, true, transition), - $$.redrawLine(drawLine, true, transition), - $$.redrawArea(drawArea, true, transition), - $$.redrawCircle(cx, cy, true, transition), - $$.redrawText(xForText, yForText, options.flow, true, transition), - $$.redrawRegion(true, transition), - $$.redrawGrid(true, transition), - ].forEach(function(transitions) { - transitions.forEach(function(transition) { - transitionsToWait.push(transition); - }); - }); - // Wait for end of transitions to call flow and onrendered callback - waitForDraw = $$.generateWait(); - transitionsToWait.forEach(function(t) { - waitForDraw.add(t); - }); - waitForDraw(function() { - if (flow) { - flow(); - } - if (config.onrendered) { - config.onrendered.call($$); - } - }); - } else { - $$.redrawBar(drawBar); - $$.redrawLine(drawLine); - $$.redrawArea(drawArea); - $$.redrawCircle(cx, cy); - $$.redrawText(xForText, yForText, options.flow); - $$.redrawRegion(); - $$.redrawGrid(); - if (flow) { - flow(); - } - if (config.onrendered) { - config.onrendered.call($$); - } + if (duration && $$.isTabVisible()) { + // Only use transition if tab visible. See #938. + // transition should be derived from one transition + transition = d3.transition().duration(duration); + transitionsToWait = [] + ;[ + $$.redrawBar(drawBar, true, transition), + $$.redrawLine(drawLine, true, transition), + $$.redrawArea(drawArea, true, transition), + $$.redrawCircle(cx, cy, true, transition), + $$.redrawText(xForText, yForText, options.flow, true, transition), + $$.redrawRegion(true, transition), + $$.redrawGrid(true, transition) + ].forEach(function(transitions) { + transitions.forEach(function(transition) { + transitionsToWait.push(transition); + }); + }); + // Wait for end of transitions to call flow and onrendered callback + waitForDraw = $$.generateWait(); + transitionsToWait.forEach(function(t) { + waitForDraw.add(t); + }); + waitForDraw(function() { + if (flow) { + flow(); + } + if (config.onrendered) { + config.onrendered.call($$); + } + }); + } else { + $$.redrawBar(drawBar); + $$.redrawLine(drawLine); + $$.redrawArea(drawArea); + $$.redrawCircle(cx, cy); + $$.redrawText(xForText, yForText, options.flow); + $$.redrawRegion(); + $$.redrawGrid(); + if (flow) { + flow(); + } + if (config.onrendered) { + config.onrendered.call($$); } + } - // update fadein condition - $$.mapToIds($$.data.targets).forEach(function(id) { - $$.withoutFadeIn[id] = true; - }); + // update fadein condition + $$.mapToIds($$.data.targets).forEach(function(id) { + $$.withoutFadeIn[id] = true; + }); }; ChartInternal.prototype.updateAndRedraw = function(options) { - var $$ = this, - config = $$.config, - transitions; - options = options || {}; - // same with redraw - options.withTransition = getOption(options, "withTransition", true); - options.withTransform = getOption(options, "withTransform", false); - options.withLegend = getOption(options, "withLegend", false); - // NOT same with redraw - options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true); - options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true); - options.withTransitionForExit = false; - options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); - // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) - $$.updateSizes(); - // MEMO: called in updateLegend in redraw if withLegend - if (!(options.withLegend && config.legend_show)) { - transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0); - // Update scales - $$.updateScales(); - $$.updateSvgSize(); - // Update g positions - $$.transformAll(options.withTransitionForTransform, transitions); - } - // Draw with new sizes & scales - $$.redraw(options, transitions); + var $$ = this, + config = $$.config, + transitions; + options = options || {}; + // same with redraw + options.withTransition = getOption(options, 'withTransition', true); + options.withTransform = getOption(options, 'withTransform', false); + options.withLegend = getOption(options, 'withLegend', false); + // NOT same with redraw + options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true); + options.withUpdateOrgXDomain = getOption( + options, + 'withUpdateOrgXDomain', + true + ); + options.withTransitionForExit = false; + options.withTransitionForTransform = getOption( + options, + 'withTransitionForTransform', + options.withTransition + ); + // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) + $$.updateSizes(); + // MEMO: called in updateLegend in redraw if withLegend + if (!(options.withLegend && config.legend_show)) { + transitions = $$.axis.generateTransitions( + options.withTransitionForAxis ? config.transition_duration : 0 + ); + // Update scales + $$.updateScales(); + $$.updateSvgSize(); + // Update g positions + $$.transformAll(options.withTransitionForTransform, transitions); + } + // Draw with new sizes & scales + $$.redraw(options, transitions); }; ChartInternal.prototype.redrawWithoutRescale = function() { - this.redraw({ - withY: false, - withSubchart: false, - withEventRect: false, - withTransitionForAxis: false - }); + this.redraw({ + withY: false, + withSubchart: false, + withEventRect: false, + withTransitionForAxis: false + }); }; ChartInternal.prototype.isTimeSeries = function() { - return this.config.axis_x_type === 'timeseries'; + return this.config.axis_x_type === 'timeseries' }; ChartInternal.prototype.isCategorized = function() { - return this.config.axis_x_type.indexOf('categor') >= 0; + return this.config.axis_x_type.indexOf('categor') >= 0 }; ChartInternal.prototype.isCustomX = function() { - var $$ = this, - config = $$.config; - return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs)); + var $$ = this, + config = $$.config; + return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs)) }; ChartInternal.prototype.isTimeSeriesY = function() { - return this.config.axis_y_type === 'timeseries'; + return this.config.axis_y_type === 'timeseries' }; ChartInternal.prototype.getTranslate = function(target) { - var $$ = this, - config = $$.config, - x, y; - if (target === 'main') { - x = asHalfPixel($$.margin.left); - y = asHalfPixel($$.margin.top); - } else if (target === 'context') { - x = asHalfPixel($$.margin2.left); - y = asHalfPixel($$.margin2.top); - } else if (target === 'legend') { - x = $$.margin3.left; - y = $$.margin3.top; - } else if (target === 'x') { - x = 0; - y = config.axis_rotated ? 0 : $$.height; - } else if (target === 'y') { - x = 0; - y = config.axis_rotated ? $$.height : 0; - } else if (target === 'y2') { - x = config.axis_rotated ? 0 : $$.width; - y = config.axis_rotated ? 1 : 0; - } else if (target === 'subx') { - x = 0; - y = config.axis_rotated ? 0 : $$.height2; - } else if (target === 'arc') { - x = $$.arcWidth / 2; - y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label - } - return "translate(" + x + "," + y + ")"; + var $$ = this, + config = $$.config, + x, + y; + if (target === 'main') { + x = asHalfPixel($$.margin.left); + y = asHalfPixel($$.margin.top); + } else if (target === 'context') { + x = asHalfPixel($$.margin2.left); + y = asHalfPixel($$.margin2.top); + } else if (target === 'legend') { + x = $$.margin3.left; + y = $$.margin3.top; + } else if (target === 'x') { + x = 0; + y = config.axis_rotated ? 0 : $$.height; + } else if (target === 'y') { + x = 0; + y = config.axis_rotated ? $$.height : 0; + } else if (target === 'y2') { + x = config.axis_rotated ? 0 : $$.width; + y = config.axis_rotated ? 1 : 0; + } else if (target === 'subx') { + x = 0; + y = config.axis_rotated ? 0 : $$.height2; + } else if (target === 'arc') { + x = $$.arcWidth / 2; + y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label + } + return 'translate(' + x + ',' + y + ')' }; ChartInternal.prototype.initialOpacity = function(d) { - return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0; + return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0 }; ChartInternal.prototype.initialOpacityForCircle = function(d) { - return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0; + return d.value !== null && this.withoutFadeIn[d.id] + ? this.opacityForCircle(d) + : 0 }; ChartInternal.prototype.opacityForCircle = function(d) { - var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show; - var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0; - return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0; + var isPointShouldBeShown = isFunction(this.config.point_show) + ? this.config.point_show(d) + : this.config.point_show; + var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0; + return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0 }; ChartInternal.prototype.opacityForText = function() { - return this.hasDataLabel() ? 1 : 0; + return this.hasDataLabel() ? 1 : 0 }; ChartInternal.prototype.xx = function(d) { - return d ? this.x(d.x) : null; + return d ? this.x(d.x) : null }; ChartInternal.prototype.xvCustom = function(d, xyValue) { - var $$ = this, - value = xyValue ? d[xyValue] : d.value; - if ($$.isTimeSeries()) { - value = $$.parseDate(d.value); - } else if ($$.isCategorized() && typeof d.value === 'string') { - value = $$.config.axis_x_categories.indexOf(d.value); - } - return Math.ceil($$.x(value)); + var $$ = this, + value = xyValue ? d[xyValue] : d.value; + if ($$.isTimeSeries()) { + value = $$.parseDate(d.value); + } else if ($$.isCategorized() && typeof d.value === 'string') { + value = $$.config.axis_x_categories.indexOf(d.value); + } + return Math.ceil($$.x(value)) }; ChartInternal.prototype.yvCustom = function(d, xyValue) { - var $$ = this, - yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y, - value = xyValue ? d[xyValue] : d.value; - return Math.ceil(yScale(value)); + var $$ = this, + yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y, + value = xyValue ? d[xyValue] : d.value; + return Math.ceil(yScale(value)) }; ChartInternal.prototype.xv = function(d) { - var $$ = this, - value = d.value; - if ($$.isTimeSeries()) { - value = $$.parseDate(d.value); - } else if ($$.isCategorized() && typeof d.value === 'string') { - value = $$.config.axis_x_categories.indexOf(d.value); - } - return Math.ceil($$.x(value)); + var $$ = this, + value = d.value; + if ($$.isTimeSeries()) { + value = $$.parseDate(d.value); + } else if ($$.isCategorized() && typeof d.value === 'string') { + value = $$.config.axis_x_categories.indexOf(d.value); + } + return Math.ceil($$.x(value)) }; ChartInternal.prototype.yv = function(d) { - var $$ = this, - yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y; - return Math.ceil(yScale(d.value)); + var $$ = this, + yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y; + return Math.ceil(yScale(d.value)) }; ChartInternal.prototype.subxx = function(d) { - return d ? this.subX(d.x) : null; + return d ? this.subX(d.x) : null }; ChartInternal.prototype.transformMain = function(withTransition, transitions) { - var $$ = this, - xAxis, yAxis, y2Axis; - if (transitions && transitions.axisX) { - xAxis = transitions.axisX; - } else { - xAxis = $$.main.select('.' + CLASS.axisX); - if (withTransition) { - xAxis = xAxis.transition(); - } + var $$ = this, + xAxis, + yAxis, + y2Axis; + if (transitions && transitions.axisX) { + xAxis = transitions.axisX; + } else { + xAxis = $$.main.select('.' + CLASS.axisX); + if (withTransition) { + xAxis = xAxis.transition(); } - if (transitions && transitions.axisY) { - yAxis = transitions.axisY; - } else { - yAxis = $$.main.select('.' + CLASS.axisY); - if (withTransition) { - yAxis = yAxis.transition(); - } + } + if (transitions && transitions.axisY) { + yAxis = transitions.axisY; + } else { + yAxis = $$.main.select('.' + CLASS.axisY); + if (withTransition) { + yAxis = yAxis.transition(); } - if (transitions && transitions.axisY2) { - y2Axis = transitions.axisY2; - } else { - y2Axis = $$.main.select('.' + CLASS.axisY2); - if (withTransition) { - y2Axis = y2Axis.transition(); - } + } + if (transitions && transitions.axisY2) { + y2Axis = transitions.axisY2; + } else { + y2Axis = $$.main.select('.' + CLASS.axisY2); + if (withTransition) { + y2Axis = y2Axis.transition(); } - (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main')); - xAxis.attr("transform", $$.getTranslate('x')); - yAxis.attr("transform", $$.getTranslate('y')); - y2Axis.attr("transform", $$.getTranslate('y2')); - $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); + } +(withTransition ? $$.main.transition() : $$.main).attr( + 'transform', + $$.getTranslate('main') + ); + xAxis.attr('transform', $$.getTranslate('x')); + yAxis.attr('transform', $$.getTranslate('y')); + y2Axis.attr('transform', $$.getTranslate('y2')); + $$.main + .select('.' + CLASS.chartArcs) + .attr('transform', $$.getTranslate('arc')); }; ChartInternal.prototype.transformAll = function(withTransition, transitions) { - var $$ = this; - $$.transformMain(withTransition, transitions); - if ($$.config.subchart_show) { - $$.transformContext(withTransition, transitions); - } - if ($$.legend) { - $$.transformLegend(withTransition); - } + var $$ = this; + $$.transformMain(withTransition, transitions); + if ($$.config.subchart_show) { + $$.transformContext(withTransition, transitions); + } + if ($$.legend) { + $$.transformLegend(withTransition); + } }; ChartInternal.prototype.updateSvgSize = function() { - var $$ = this, - brush = $$.svg.select(`.${CLASS.brush} .overlay`); - $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight); - $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect') - .attr('width', $$.width) - .attr('height', $$.height); - $$.svg.select('#' + $$.clipIdForXAxis).select('rect') - .attr('x', $$.getXAxisClipX.bind($$)) - .attr('y', $$.getXAxisClipY.bind($$)) - .attr('width', $$.getXAxisClipWidth.bind($$)) - .attr('height', $$.getXAxisClipHeight.bind($$)); - $$.svg.select('#' + $$.clipIdForYAxis).select('rect') - .attr('x', $$.getYAxisClipX.bind($$)) - .attr('y', $$.getYAxisClipY.bind($$)) - .attr('width', $$.getYAxisClipWidth.bind($$)) - .attr('height', $$.getYAxisClipHeight.bind($$)); - $$.svg.select('#' + $$.clipIdForSubchart).select('rect') - .attr('width', $$.width) - .attr('height', brush.size() && brush.attr('height') || 0); - // MEMO: parent div's height will be bigger than svg when - $$.selectChart.style('max-height', $$.currentHeight + "px"); + var $$ = this, + brush = $$.svg.select(`.${CLASS.brush} .overlay`); + $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight); + $$.svg + .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]) + .select('rect') + .attr('width', $$.width) + .attr('height', $$.height); + $$.svg + .select('#' + $$.clipIdForXAxis) + .select('rect') + .attr('x', $$.getXAxisClipX.bind($$)) + .attr('y', $$.getXAxisClipY.bind($$)) + .attr('width', $$.getXAxisClipWidth.bind($$)) + .attr('height', $$.getXAxisClipHeight.bind($$)); + $$.svg + .select('#' + $$.clipIdForYAxis) + .select('rect') + .attr('x', $$.getYAxisClipX.bind($$)) + .attr('y', $$.getYAxisClipY.bind($$)) + .attr('width', $$.getYAxisClipWidth.bind($$)) + .attr('height', $$.getYAxisClipHeight.bind($$)); + $$.svg + .select('#' + $$.clipIdForSubchart) + .select('rect') + .attr('width', $$.width) + .attr('height', (brush.size() && brush.attr('height')) || 0); + // MEMO: parent div's height will be bigger than svg when + $$.selectChart.style('max-height', $$.currentHeight + 'px'); }; ChartInternal.prototype.updateDimension = function(withoutAxis) { - var $$ = this; - if (!withoutAxis) { - if ($$.config.axis_rotated) { - $$.axes.x.call($$.xAxis); - $$.axes.subx.call($$.subXAxis); - } else { - $$.axes.y.call($$.yAxis); - $$.axes.y2.call($$.y2Axis); - } + var $$ = this; + if (!withoutAxis) { + if ($$.config.axis_rotated) { + $$.axes.x.call($$.xAxis); + $$.axes.subx.call($$.subXAxis); + } else { + $$.axes.y.call($$.yAxis); + $$.axes.y2.call($$.y2Axis); } - $$.updateSizes(); - $$.updateScales(); - $$.updateSvgSize(); - $$.transformAll(false); + } + $$.updateSizes(); + $$.updateScales(); + $$.updateSvgSize(); + $$.transformAll(false); }; ChartInternal.prototype.observeInserted = function(selection) { - var $$ = this, - observer; - if (typeof MutationObserver === 'undefined') { - window.console.error("MutationObserver not defined."); - return; - } - observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - if (mutation.type === 'childList' && mutation.previousSibling) { - observer.disconnect(); - // need to wait for completion of load because size calculation requires the actual sizes determined after that completion - $$.intervalForObserveInserted = window.setInterval(function() { - // parentNode will NOT be null when completed - if (selection.node().parentNode) { - window.clearInterval($$.intervalForObserveInserted); - $$.updateDimension(); - if ($$.brush) { - $$.brush.update(); - } - $$.config.oninit.call($$); - $$.redraw({ - withTransform: true, - withUpdateXDomain: true, - withUpdateOrgXDomain: true, - withTransition: false, - withTransitionForTransform: false, - withLegend: true - }); - selection.transition().style('opacity', 1); - } - }, 10); + var $$ = this, + observer; + if (typeof MutationObserver === 'undefined') { + window.console.error('MutationObserver not defined.'); + return + } + observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'childList' && mutation.previousSibling) { + observer.disconnect(); + // need to wait for completion of load because size calculation requires the actual sizes determined after that completion + $$.intervalForObserveInserted = window.setInterval(function() { + // parentNode will NOT be null when completed + if (selection.node().parentNode) { + window.clearInterval($$.intervalForObserveInserted); + $$.updateDimension(); + if ($$.brush) { + $$.brush.update(); } - }); - }); - observer.observe(selection.node(), { - attributes: true, - childList: true, - characterData: true + $$.config.oninit.call($$); + $$.redraw({ + withTransform: true, + withUpdateXDomain: true, + withUpdateOrgXDomain: true, + withTransition: false, + withTransitionForTransform: false, + withLegend: true + }); + selection.transition().style('opacity', 1); + } + }, 10); + } }); + }); + observer.observe(selection.node(), { + attributes: true, + childList: true, + characterData: true + }); }; /** * Binds handlers to the window resize event. */ ChartInternal.prototype.bindResize = function() { - var $$ = this, - config = $$.config; + var $$ = this, + config = $$.config; - $$.resizeFunction = $$.generateResize(); // need to call .remove + $$.resizeFunction = $$.generateResize(); // need to call .remove + $$.resizeFunction.add(function() { + config.onresize.call($$); + }); + if (config.resize_auto) { $$.resizeFunction.add(function() { - config.onresize.call($$); - }); - if (config.resize_auto) { - $$.resizeFunction.add(function() { - if ($$.resizeTimeout !== undefined) { - window.clearTimeout($$.resizeTimeout); - } - $$.resizeTimeout = window.setTimeout(function() { - delete $$.resizeTimeout; - $$.updateAndRedraw({ - withUpdateXDomain: false, - withUpdateOrgXDomain: false, - withTransition: false, - withTransitionForTransform: false, - withLegend: true, - }); - if ($$.brush) { - $$.brush.update(); - } - }, 100); + if ($$.resizeTimeout !== undefined) { + window.clearTimeout($$.resizeTimeout); + } + $$.resizeTimeout = window.setTimeout(function() { + delete $$.resizeTimeout; + $$.updateAndRedraw({ + withUpdateXDomain: false, + withUpdateOrgXDomain: false, + withTransition: false, + withTransitionForTransform: false, + withLegend: true }); - } - $$.resizeFunction.add(function() { - config.onresized.call($$); - }); - - $$.resizeIfElementDisplayed = function() { - // if element not displayed skip it - if ($$.api == null || !$$.api.element.offsetParent) { - return; + if ($$.brush) { + $$.brush.update(); } - - $$.resizeFunction(); + }, 100); + }); + } + $$.resizeFunction.add(function() { + config.onresized.call($$); + }); + + $$.resizeIfElementDisplayed = function() { + // if element not displayed skip it + if ($$.api == null || !$$.api.element.offsetParent) { + return + } + + $$.resizeFunction(); + }; + + if (window.attachEvent) { + window.attachEvent('onresize', $$.resizeIfElementDisplayed); + } else if (window.addEventListener) { + window.addEventListener('resize', $$.resizeIfElementDisplayed, false); + } else { + // fallback to this, if this is a very old browser + var wrapper = window.onresize; + if (!wrapper) { + // create a wrapper that will call all charts + wrapper = $$.generateResize(); + } else if (!wrapper.add || !wrapper.remove) { + // there is already a handler registered, make sure we call it too + wrapper = $$.generateResize(); + wrapper.add(window.onresize); + } + // add this graph to the wrapper, we will be removed if the user calls destroy + wrapper.add($$.resizeFunction); + window.onresize = function() { + // if element not displayed skip it + if (!$$.api.element.offsetParent) { + return + } + + wrapper(); }; - - if (window.attachEvent) { - window.attachEvent('onresize', $$.resizeIfElementDisplayed); - } else if (window.addEventListener) { - window.addEventListener('resize', $$.resizeIfElementDisplayed, false); - } else { - // fallback to this, if this is a very old browser - var wrapper = window.onresize; - if (!wrapper) { - // create a wrapper that will call all charts - wrapper = $$.generateResize(); - } else if (!wrapper.add || !wrapper.remove) { - // there is already a handler registered, make sure we call it too - wrapper = $$.generateResize(); - wrapper.add(window.onresize); - } - // add this graph to the wrapper, we will be removed if the user calls destroy - wrapper.add($$.resizeFunction); - window.onresize = function() { - // if element not displayed skip it - if (!$$.api.element.offsetParent) { - return; - } - - wrapper(); - }; - } + } }; /** * Binds handlers to the window focus event. */ ChartInternal.prototype.bindWindowFocus = function() { - if (this.windowFocusHandler) { - // The handler is already set - return; - } + if (this.windowFocusHandler) { + // The handler is already set + return + } - this.windowFocusHandler = () => { this.redraw(); }; + this.windowFocusHandler = () => { + this.redraw(); + }; - window.addEventListener('focus', this.windowFocusHandler); + window.addEventListener('focus', this.windowFocusHandler); }; /** * Unbinds from the window focus event. */ -ChartInternal.prototype.unbindWindowFocus = function () { - window.removeEventListener('focus', this.windowFocusHandler); - delete this.windowFocusHandler; +ChartInternal.prototype.unbindWindowFocus = function() { + window.removeEventListener('focus', this.windowFocusHandler); + delete this.windowFocusHandler; }; ChartInternal.prototype.generateResize = function() { - var resizeFunctions = []; + var resizeFunctions = []; - function callResizeFunctions() { - resizeFunctions.forEach(function(f) { - f(); - }); + function callResizeFunctions() { + resizeFunctions.forEach(function(f) { + f(); + }); + } + callResizeFunctions.add = function(f) { + resizeFunctions.push(f); + }; + callResizeFunctions.remove = function(f) { + for (var i = 0; i < resizeFunctions.length; i++) { + if (resizeFunctions[i] === f) { + resizeFunctions.splice(i, 1); + break + } } - callResizeFunctions.add = function(f) { - resizeFunctions.push(f); - }; - callResizeFunctions.remove = function(f) { - for (var i = 0; i < resizeFunctions.length; i++) { - if (resizeFunctions[i] === f) { - resizeFunctions.splice(i, 1); - break; - } - } - }; - return callResizeFunctions; + }; + return callResizeFunctions }; ChartInternal.prototype.endall = function(transition, callback) { - var n = 0; - transition - .each(function() { - ++n; - }) - .on("end", function() { - if (!--n) { - callback.apply(this, arguments); - } - }); + var n = 0; + transition + .each(function() { + ++n; + }) + .on('end', function() { + if (!--n) { + callback.apply(this, arguments); + } + }); }; ChartInternal.prototype.generateWait = function() { - var $$ = this; - var transitionsToWait = [], - f = function(callback) { - var timer = setInterval(function() { - if (!$$.isTabVisible()) { - return; - } + var $$ = this; + var transitionsToWait = [], + f = function(callback) { + var timer = setInterval(function() { + if (!$$.isTabVisible()) { + return + } - var done = 0; - transitionsToWait.forEach(function(t) { - if (t.empty()) { - done += 1; - return; - } - try { - t.transition(); - } catch (e) { - done += 1; - } - }); - if (done === transitionsToWait.length) { - clearInterval(timer); - if (callback) { - callback(); - } - } - }, 50); - }; - f.add = function(transition) { - transitionsToWait.push(transition); + var done = 0; + transitionsToWait.forEach(function(t) { + if (t.empty()) { + done += 1; + return + } + try { + t.transition(); + } catch (e) { + done += 1; + } + }); + if (done === transitionsToWait.length) { + clearInterval(timer); + if (callback) { + callback(); + } + } + }, 50); }; - return f; + f.add = function(transition) { + transitionsToWait.push(transition); + }; + return f }; ChartInternal.prototype.parseDate = function(date) { - var $$ = this, - parsedDate; - if (date instanceof Date) { - parsedDate = date; - } else if (typeof date === 'string') { - parsedDate = $$.dataTimeParse(date); - } else if (typeof date === 'object') { - parsedDate = new Date(+date); - } else if (typeof date === 'number' && !isNaN(date)) { - parsedDate = new Date(+date); - } - if (!parsedDate || isNaN(+parsedDate)) { - window.console.error("Failed to parse x '" + date + "' to Date object"); - } - return parsedDate; + var $$ = this, + parsedDate; + if (date instanceof Date) { + parsedDate = date; + } else if (typeof date === 'string') { + parsedDate = $$.dataTimeParse(date); + } else if (typeof date === 'object') { + parsedDate = new Date(+date); + } else if (typeof date === 'number' && !isNaN(date)) { + parsedDate = new Date(+date); + } + if (!parsedDate || isNaN(+parsedDate)) { + window.console.error("Failed to parse x '" + date + "' to Date object"); + } + return parsedDate }; ChartInternal.prototype.isTabVisible = function() { - return !document.hidden; + return !document.hidden }; ChartInternal.prototype.getPathBox = getPathBox; ChartInternal.prototype.CLASS = CLASS; /* jshint ignore:start */ +(function() { + if (!('SVGPathSeg' in window)) { + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg + window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) { + this.pathSegType = type; + this.pathSegTypeAsLetter = typeAsLetter; + this._owningPathSegList = owningPathSegList; + }; -// SVGPathSeg API polyfill -// https://github.com/progers/pathseg -// -// This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from -// SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec -// changes which were implemented in Firefox 43 and Chrome 46. - -(function () { - if (!("SVGPathSeg" in window)) { - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg - window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) { - this.pathSegType = type; - this.pathSegTypeAsLetter = typeAsLetter; - this._owningPathSegList = owningPathSegList; - }; + window.SVGPathSeg.prototype.classname = 'SVGPathSeg'; + + window.SVGPathSeg.PATHSEG_UNKNOWN = 0; + window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; + window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; + window.SVGPathSeg.PATHSEG_MOVETO_REL = 3; + window.SVGPathSeg.PATHSEG_LINETO_ABS = 4; + window.SVGPathSeg.PATHSEG_LINETO_REL = 5; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9; + window.SVGPathSeg.PATHSEG_ARC_ABS = 10; + window.SVGPathSeg.PATHSEG_ARC_REL = 11; + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12; + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13; + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14; + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; + + // Notify owning PathSegList on any changes so they can be synchronized back to the path element. + window.SVGPathSeg.prototype._segmentChanged = function() { + if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this); + }; - window.SVGPathSeg.prototype.classname = "SVGPathSeg"; - - window.SVGPathSeg.PATHSEG_UNKNOWN = 0; - window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; - window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; - window.SVGPathSeg.PATHSEG_MOVETO_REL = 3; - window.SVGPathSeg.PATHSEG_LINETO_ABS = 4; - window.SVGPathSeg.PATHSEG_LINETO_REL = 5; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9; - window.SVGPathSeg.PATHSEG_ARC_ABS = 10; - window.SVGPathSeg.PATHSEG_ARC_REL = 11; - window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12; - window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13; - window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14; - window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; - - // Notify owning PathSegList on any changes so they can be synchronized back to the path element. - window.SVGPathSeg.prototype._segmentChanged = function () { - if (this._owningPathSegList) - this._owningPathSegList.segmentChanged(this); - }; + window.SVGPathSegClosePath = function(owningPathSegList) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CLOSEPATH, + 'z', + owningPathSegList + ); + }; + window.SVGPathSegClosePath.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegClosePath.prototype.toString = function() { + return '[object SVGPathSegClosePath]' + }; + window.SVGPathSegClosePath.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + }; + window.SVGPathSegClosePath.prototype.clone = function() { + return new window.SVGPathSegClosePath(undefined) + }; - window.SVGPathSegClosePath = function (owningPathSegList) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList); - }; - window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegClosePath.prototype.toString = function () { - return "[object SVGPathSegClosePath]"; - }; - window.SVGPathSegClosePath.prototype._asPathString = function () { - return this.pathSegTypeAsLetter; - }; - window.SVGPathSegClosePath.prototype.clone = function () { - return new window.SVGPathSegClosePath(undefined); - }; + window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_MOVETO_ABS, + 'M', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegMovetoAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegMovetoAbs.prototype.toString = function() { + return '[object SVGPathSegMovetoAbs]' + }; + window.SVGPathSegMovetoAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegMovetoAbs.prototype.clone = function() { + return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegMovetoAbs.prototype.toString = function () { - return "[object SVGPathSegMovetoAbs]"; - }; - window.SVGPathSegMovetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegMovetoAbs.prototype.clone = function () { - return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_MOVETO_REL, + 'm', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegMovetoRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegMovetoRel.prototype.toString = function() { + return '[object SVGPathSegMovetoRel]' + }; + window.SVGPathSegMovetoRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegMovetoRel.prototype.clone = function() { + return new window.SVGPathSegMovetoRel(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegMovetoRel.prototype.toString = function () { - return "[object SVGPathSegMovetoRel]"; - }; - window.SVGPathSegMovetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegMovetoRel.prototype.clone = function () { - return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_ABS, + 'L', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegLinetoAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoAbs.prototype.toString = function() { + return '[object SVGPathSegLinetoAbs]' + }; + window.SVGPathSegLinetoAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegLinetoAbs.prototype.clone = function() { + return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoAbs]"; - }; - window.SVGPathSegLinetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegLinetoAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoRel.prototype.toString = function () { - return "[object SVGPathSegLinetoRel]"; - }; - window.SVGPathSegLinetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegLinetoRel.prototype.clone = function () { - return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicAbs]"; - }; - window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicRel]"; - }; - window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - }; - window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticAbs]"; - }; - window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - }; - window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticRel]"; - }; - window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_REL, + 'l', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegLinetoRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoRel.prototype.toString = function() { + return '[object SVGPathSegLinetoRel]' + }; + window.SVGPathSegLinetoRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegLinetoRel.prototype.clone = function() { + return new window.SVGPathSegLinetoRel(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList); - this._x = x; - this._y = y; - this._r1 = r1; - this._r2 = r2; - this._angle = angle; - this._largeArcFlag = largeArcFlag; - this._sweepFlag = sweepFlag; - }; - window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegArcAbs.prototype.toString = function () { - return "[object SVGPathSegArcAbs]"; - }; - window.SVGPathSegArcAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + - this._x + " " + this._y; - }; - window.SVGPathSegArcAbs.prototype.clone = function () { - return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); - }; - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { - get: function () { - return this._r1; - }, - set: function (r1) { - this._r1 = r1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { - get: function () { - return this._r2; - }, - set: function (r2) { - this._r2 = r2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { - get: function () { - return this._angle; - }, - set: function (angle) { - this._angle = angle; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { - get: function () { - return this._largeArcFlag; - }, - set: function (largeArcFlag) { - this._largeArcFlag = largeArcFlag; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { - get: function () { - return this._sweepFlag; - }, - set: function (sweepFlag) { - this._sweepFlag = sweepFlag; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoCubicAbs = function( + owningPathSegList, + x, + y, + x1, + y1, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, + 'C', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicAbs]' + }; + window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicAbs( + undefined, + this._x, + this._y, + this._x1, + this._y1, + this._x2, + this._y2 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList); - this._x = x; - this._y = y; - this._r1 = r1; - this._r2 = r2; - this._angle = angle; - this._largeArcFlag = largeArcFlag; - this._sweepFlag = sweepFlag; - }; - window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegArcRel.prototype.toString = function () { - return "[object SVGPathSegArcRel]"; - }; - window.SVGPathSegArcRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + - this._x + " " + this._y; - }; - window.SVGPathSegArcRel.prototype.clone = function () { - return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); - }; - Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { - get: function () { - return this._r1; - }, - set: function (r1) { - this._r1 = r1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { - get: function () { - return this._r2; - }, - set: function (r2) { - this._r2 = r2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { - get: function () { - return this._angle; - }, - set: function (angle) { - this._angle = angle; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { - get: function () { - return this._largeArcFlag; - }, - set: function (largeArcFlag) { - this._largeArcFlag = largeArcFlag; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { - get: function () { - return this._sweepFlag; - }, - set: function (sweepFlag) { - this._sweepFlag = sweepFlag; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoCubicRel = function( + owningPathSegList, + x, + y, + x1, + y1, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, + 'c', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicRel]' + }; + window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicRel( + undefined, + this._x, + this._y, + this._x1, + this._y1, + this._x2, + this._y2 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList); - this._x = x; - }; - window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalAbs]"; - }; - window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; - }; - window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); - }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoQuadraticAbs = function( + owningPathSegList, + x, + y, + x1, + y1 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, + 'Q', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + }; + window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticAbs]' + }; + window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticAbs( + undefined, + this._x, + this._y, + this._x1, + this._y1 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticAbs.prototype, + 'x1', + { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticAbs.prototype, + 'y1', + { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoQuadraticRel = function( + owningPathSegList, + x, + y, + x1, + y1 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, + 'q', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + }; + window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticRel]' + }; + window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticRel( + undefined, + this._x, + this._y, + this._x1, + this._y1 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticRel.prototype, + 'x1', + { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticRel.prototype, + 'y1', + { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegArcAbs = function( + owningPathSegList, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_ARC_ABS, + 'A', + owningPathSegList + ); + this._x = x; + this._y = y; + this._r1 = r1; + this._r2 = r2; + this._angle = angle; + this._largeArcFlag = largeArcFlag; + this._sweepFlag = sweepFlag; + }; + window.SVGPathSegArcAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegArcAbs.prototype.toString = function() { + return '[object SVGPathSegArcAbs]' + }; + window.SVGPathSegArcAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._r1 + + ' ' + + this._r2 + + ' ' + + this._angle + + ' ' + + (this._largeArcFlag ? '1' : '0') + + ' ' + + (this._sweepFlag ? '1' : '0') + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegArcAbs.prototype.clone = function() { + return new window.SVGPathSegArcAbs( + undefined, + this._x, + this._y, + this._r1, + this._r2, + this._angle, + this._largeArcFlag, + this._sweepFlag + ) + }; + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', { + get: function() { + return this._r1 + }, + set: function(r1) { + this._r1 = r1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', { + get: function() { + return this._r2 + }, + set: function(r2) { + this._r2 = r2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', { + get: function() { + return this._angle + }, + set: function(angle) { + this._angle = angle; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', { + get: function() { + return this._largeArcFlag + }, + set: function(largeArcFlag) { + this._largeArcFlag = largeArcFlag; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', { + get: function() { + return this._sweepFlag + }, + set: function(sweepFlag) { + this._sweepFlag = sweepFlag; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList); - this._x = x; - }; - window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalRel]"; - }; - window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; - }; - window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { - return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); - }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegArcRel = function( + owningPathSegList, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_ARC_REL, + 'a', + owningPathSegList + ); + this._x = x; + this._y = y; + this._r1 = r1; + this._r2 = r2; + this._angle = angle; + this._largeArcFlag = largeArcFlag; + this._sweepFlag = sweepFlag; + }; + window.SVGPathSegArcRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegArcRel.prototype.toString = function() { + return '[object SVGPathSegArcRel]' + }; + window.SVGPathSegArcRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._r1 + + ' ' + + this._r2 + + ' ' + + this._angle + + ' ' + + (this._largeArcFlag ? '1' : '0') + + ' ' + + (this._sweepFlag ? '1' : '0') + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegArcRel.prototype.clone = function() { + return new window.SVGPathSegArcRel( + undefined, + this._x, + this._y, + this._r1, + this._r2, + this._angle, + this._largeArcFlag, + this._sweepFlag + ) + }; + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', { + get: function() { + return this._r1 + }, + set: function(r1) { + this._r1 = r1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', { + get: function() { + return this._r2 + }, + set: function(r2) { + this._r2 = r2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', { + get: function() { + return this._angle + }, + set: function(angle) { + this._angle = angle; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', { + get: function() { + return this._largeArcFlag + }, + set: function(largeArcFlag) { + this._largeArcFlag = largeArcFlag; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', { + get: function() { + return this._sweepFlag + }, + set: function(sweepFlag) { + this._sweepFlag = sweepFlag; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList); - this._y = y; - }; - window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalAbs]"; - }; - window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; - }; - window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, + 'H', + owningPathSegList + ); + this._x = x; + }; + window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() { + return '[object SVGPathSegLinetoHorizontalAbs]' + }; + window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + }; + window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() { + return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x) + }; + Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList); - this._y = y; - }; - window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalRel]"; - }; - window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; - }; - window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { - return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, + 'h', + owningPathSegList + ); + this._x = x; + }; + window.SVGPathSegLinetoHorizontalRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() { + return '[object SVGPathSegLinetoHorizontalRel]' + }; + window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + }; + window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() { + return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x) + }; + Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList); - this._x = x; - this._y = y; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothAbs]"; - }; - window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, + 'V', + owningPathSegList + ); + this._y = y; + }; + window.SVGPathSegLinetoVerticalAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() { + return '[object SVGPathSegLinetoVerticalAbs]' + }; + window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._y + }; + window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() { + return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList); - this._x = x; - this._y = y; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothRel]"; - }; - window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, + 'v', + owningPathSegList + ); + this._y = y; + }; + window.SVGPathSegLinetoVerticalRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoVerticalRel.prototype.toString = function() { + return '[object SVGPathSegLinetoVerticalRel]' + }; + window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._y + }; + window.SVGPathSegLinetoVerticalRel.prototype.clone = function() { + return new window.SVGPathSegLinetoVerticalRel(undefined, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; - }; - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoCubicSmoothAbs = function( + owningPathSegList, + x, + y, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, + 'S', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicSmoothAbs]' + }; + window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicSmoothAbs( + undefined, + this._x, + this._y, + this._x2, + this._y2 + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'x2', + { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'y2', + { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoCubicSmoothRel = function( + owningPathSegList, + x, + y, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, + 's', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicSmoothRel]' + }; + window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicSmoothRel( + undefined, + this._x, + this._y, + this._x2, + this._y2 + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'x2', + { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'y2', + { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoQuadraticSmoothAbs = function( + owningPathSegList, + x, + y + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, + 'T', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticSmoothAbs]' + }; + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticSmoothAbs( + undefined, + this._x, + this._y + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoQuadraticSmoothRel = function( + owningPathSegList, + x, + y + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, + 't', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticSmoothRel]' + }; + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticSmoothRel( + undefined, + this._x, + this._y + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + + // Add createSVGPathSeg* functions to window.SVGPathElement. + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement. + window.SVGPathElement.prototype.createSVGPathSegClosePath = function() { + return new window.SVGPathSegClosePath(undefined) + }; + window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) { + return new window.SVGPathSegMovetoAbs(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) { + return new window.SVGPathSegMovetoRel(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) { + return new window.SVGPathSegLinetoAbs(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) { + return new window.SVGPathSegLinetoRel(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function( + x, + y, + x1, + y1, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicAbs( + undefined, + x, + y, + x1, + y1, + x2, + y2 + ) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function( + x, + y, + x1, + y1, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicRel( + undefined, + x, + y, + x1, + y1, + x2, + y2 + ) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function( + x, + y, + x1, + y1 + ) { + return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function( + x, + y, + x1, + y1 + ) { + return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1) + }; + window.SVGPathElement.prototype.createSVGPathSegArcAbs = function( + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + return new window.SVGPathSegArcAbs( + undefined, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) + }; + window.SVGPathElement.prototype.createSVGPathSegArcRel = function( + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + return new window.SVGPathSegArcRel( + undefined, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function( + x + ) { + return new window.SVGPathSegLinetoHorizontalAbs(undefined, x) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function( + x + ) { + return new window.SVGPathSegLinetoHorizontalRel(undefined, x) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function( + y + ) { + return new window.SVGPathSegLinetoVerticalAbs(undefined, y) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function( + y + ) { + return new window.SVGPathSegLinetoVerticalRel(undefined, y) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function( + x, + y, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function( + x, + y, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function( + x, + y + ) { + return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function( + x, + y + ) { + return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y) + }; - window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; - }; - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) { + // Add getPathSegAtLength to SVGPathElement. + // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength + // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. + window.SVGPathElement.prototype.getPathSegAtLength = function(distance) { + if (distance === undefined || !isFinite(distance)) + throw 'Invalid arguments.' + + var measurementElement = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + measurementElement.setAttribute('d', this.getAttribute('d')); + var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; - // Add createSVGPathSeg* functions to window.SVGPathElement. - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement. - window.SVGPathElement.prototype.createSVGPathSegClosePath = function () { - return new window.SVGPathSegClosePath(undefined); - }; - window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) { - return new window.SVGPathSegMovetoAbs(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) { - return new window.SVGPathSegMovetoRel(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) { - return new window.SVGPathSegLinetoAbs(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) { - return new window.SVGPathSegLinetoRel(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) { - return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) { - return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) { - return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) { - return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); - }; - window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); - }; - window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) { - return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) { - return new window.SVGPathSegLinetoHorizontalRel(undefined, x); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) { - return new window.SVGPathSegLinetoVerticalAbs(undefined, y); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) { - return new window.SVGPathSegLinetoVerticalRel(undefined, y); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) { - return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) { - return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) { - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) { - return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); - }; + // If the path is empty, return 0. + if (lastPathSegment <= 0) return 0 - if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) { - // Add getPathSegAtLength to SVGPathElement. - // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength - // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. - window.SVGPathElement.prototype.getPathSegAtLength = function (distance) { - if (distance === undefined || !isFinite(distance)) - throw "Invalid arguments."; - - var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); - measurementElement.setAttribute("d", this.getAttribute("d")); - var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; - - // If the path is empty, return 0. - if (lastPathSegment <= 0) - return 0; - - do { - measurementElement.pathSegList.removeItem(lastPathSegment); - if (distance > measurementElement.getTotalLength()) - break; - lastPathSegment--; - } while (lastPathSegment > 0); - return lastPathSegment; - }; - } + do { + measurementElement.pathSegList.removeItem(lastPathSegment); + if (distance > measurementElement.getTotalLength()) break + lastPathSegment--; + } while (lastPathSegment > 0) + return lastPathSegment + }; } + } - if (!("SVGPathSegList" in window)) { - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList - window.SVGPathSegList = function (pathElement) { - this._pathElement = pathElement; - this._list = this._parsePath(this._pathElement.getAttribute("d")); - - // Use a MutationObserver to catch changes to the path's "d" attribute. - this._mutationObserverConfig = { - "attributes": true, - "attributeFilter": ["d"] - }; - this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this)); - this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); - }; - - window.SVGPathSegList.prototype.classname = "SVGPathSegList"; - - Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", { - get: function () { - this._checkPathSynchronizedToList(); - return this._list.length; - }, - enumerable: true - }); - - // Add the pathSegList accessors to window.SVGPathElement. - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData - Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", { - get: function () { - if (!this._pathSegList) - this._pathSegList = new window.SVGPathSegList(this); - return this._pathSegList; - }, - enumerable: true - }); - // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. - Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - - // Process any pending mutations to the path element and update the list as needed. - // This should be the first call of all public functions and is needed because - // MutationObservers are not synchronous so we can have pending asynchronous mutations. - window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () { - this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords()); - }; - - window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) { - if (!this._pathElement) - return; - var hasPathMutations = false; - mutationRecords.forEach(function (record) { - if (record.attributeName == "d") - hasPathMutations = true; - }); - if (hasPathMutations) - this._list = this._parsePath(this._pathElement.getAttribute("d")); - }; - - // Serialize the list and update the path's 'd' attribute. - window.SVGPathSegList.prototype._writeListToPath = function () { - this._pathElementMutationObserver.disconnect(); - this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list)); - this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); - }; - - // When a path segment changes the list needs to be synchronized back to the path element. - window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) { - this._writeListToPath(); - }; - - window.SVGPathSegList.prototype.clear = function () { - this._checkPathSynchronizedToList(); - - this._list.forEach(function (pathSeg) { - pathSeg._owningPathSegList = null; - }); - this._list = []; - this._writeListToPath(); - }; - - window.SVGPathSegList.prototype.initialize = function (newItem) { - this._checkPathSynchronizedToList(); - - this._list = [newItem]; - newItem._owningPathSegList = this; - this._writeListToPath(); - return newItem; - }; - - window.SVGPathSegList.prototype._checkValidIndex = function (index) { - if (isNaN(index) || index < 0 || index >= this.numberOfItems) - throw "INDEX_SIZE_ERR"; - }; + if (!('SVGPathSegList' in window)) { + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList + window.SVGPathSegList = function(pathElement) { + this._pathElement = pathElement; + this._list = this._parsePath(this._pathElement.getAttribute('d')); - window.SVGPathSegList.prototype.getItem = function (index) { - this._checkPathSynchronizedToList(); + // Use a MutationObserver to catch changes to the path's "d" attribute. + this._mutationObserverConfig = { + attributes: true, + attributeFilter: ['d'] + }; + this._pathElementMutationObserver = new MutationObserver( + this._updateListFromPathMutations.bind(this) + ); + this._pathElementMutationObserver.observe( + this._pathElement, + this._mutationObserverConfig + ); + }; - this._checkValidIndex(index); - return this._list[index]; - }; + window.SVGPathSegList.prototype.classname = 'SVGPathSegList'; - window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) { - this._checkPathSynchronizedToList(); + Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', { + get: function() { + this._checkPathSynchronizedToList(); + return this._list.length + }, + enumerable: true + }); - // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. - if (index > this.numberOfItems) - index = this.numberOfItems; - if (newItem._owningPathSegList) { - // SVG2 spec says to make a copy. - newItem = newItem.clone(); - } - this._list.splice(index, 0, newItem); - newItem._owningPathSegList = this; - this._writeListToPath(); - return newItem; - }; + // Add the pathSegList accessors to window.SVGPathElement. + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData + Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', { + get: function() { + if (!this._pathSegList) + this._pathSegList = new window.SVGPathSegList(this); + return this._pathSegList + }, + enumerable: true + }); + // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. + Object.defineProperty( + window.SVGPathElement.prototype, + 'normalizedPathSegList', + { + get: function() { + return this.pathSegList + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathElement.prototype, + 'animatedPathSegList', + { + get: function() { + return this.pathSegList + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathElement.prototype, + 'animatedNormalizedPathSegList', + { + get: function() { + return this.pathSegList + }, + enumerable: true + } + ); + + // Process any pending mutations to the path element and update the list as needed. + // This should be the first call of all public functions and is needed because + // MutationObservers are not synchronous so we can have pending asynchronous mutations. + window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() { + this._updateListFromPathMutations( + this._pathElementMutationObserver.takeRecords() + ); + }; - window.SVGPathSegList.prototype.replaceItem = function (newItem, index) { - this._checkPathSynchronizedToList(); + window.SVGPathSegList.prototype._updateListFromPathMutations = function( + mutationRecords + ) { + if (!this._pathElement) return + var hasPathMutations = false; + mutationRecords.forEach(function(record) { + if (record.attributeName == 'd') hasPathMutations = true; + }); + if (hasPathMutations) + this._list = this._parsePath(this._pathElement.getAttribute('d')); + }; - if (newItem._owningPathSegList) { - // SVG2 spec says to make a copy. - newItem = newItem.clone(); - } - this._checkValidIndex(index); - this._list[index] = newItem; - newItem._owningPathSegList = this; - this._writeListToPath(); - return newItem; - }; + // Serialize the list and update the path's 'd' attribute. + window.SVGPathSegList.prototype._writeListToPath = function() { + this._pathElementMutationObserver.disconnect(); + this._pathElement.setAttribute( + 'd', + window.SVGPathSegList._pathSegArrayAsString(this._list) + ); + this._pathElementMutationObserver.observe( + this._pathElement, + this._mutationObserverConfig + ); + }; - window.SVGPathSegList.prototype.removeItem = function (index) { - this._checkPathSynchronizedToList(); + // When a path segment changes the list needs to be synchronized back to the path element. + window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) { + this._writeListToPath(); + }; - this._checkValidIndex(index); - var item = this._list[index]; - this._list.splice(index, 1); - this._writeListToPath(); - return item; - }; + window.SVGPathSegList.prototype.clear = function() { + this._checkPathSynchronizedToList(); - window.SVGPathSegList.prototype.appendItem = function (newItem) { - this._checkPathSynchronizedToList(); + this._list.forEach(function(pathSeg) { + pathSeg._owningPathSegList = null; + }); + this._list = []; + this._writeListToPath(); + }; - if (newItem._owningPathSegList) { - // SVG2 spec says to make a copy. - newItem = newItem.clone(); - } - this._list.push(newItem); - newItem._owningPathSegList = this; - // TODO: Optimize this to just append to the existing attribute. - this._writeListToPath(); - return newItem; - }; + window.SVGPathSegList.prototype.initialize = function(newItem) { + this._checkPathSynchronizedToList(); - window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) { - var string = ""; - var first = true; - pathSegArray.forEach(function (pathSeg) { - if (first) { - first = false; - string += pathSeg._asPathString(); - } else { - string += " " + pathSeg._asPathString(); - } - }); - return string; - }; + this._list = [newItem]; + newItem._owningPathSegList = this; + this._writeListToPath(); + return newItem + }; - // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp. - window.SVGPathSegList.prototype._parsePath = function (string) { - if (!string || string.length == 0) - return []; + window.SVGPathSegList.prototype._checkValidIndex = function(index) { + if (isNaN(index) || index < 0 || index >= this.numberOfItems) + throw 'INDEX_SIZE_ERR' + }; - var owningPathSegList = this; + window.SVGPathSegList.prototype.getItem = function(index) { + this._checkPathSynchronizedToList(); - var Builder = function () { - this.pathSegList = []; - }; + this._checkValidIndex(index); + return this._list[index] + }; - Builder.prototype.appendSegment = function (pathSeg) { - this.pathSegList.push(pathSeg); - }; + window.SVGPathSegList.prototype.insertItemBefore = function( + newItem, + index + ) { + this._checkPathSynchronizedToList(); + + // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. + if (index > this.numberOfItems) index = this.numberOfItems; + if (newItem._owningPathSegList) { + // SVG2 spec says to make a copy. + newItem = newItem.clone(); + } + this._list.splice(index, 0, newItem); + newItem._owningPathSegList = this; + this._writeListToPath(); + return newItem + }; - var Source = function (string) { - this._string = string; - this._currentIndex = 0; - this._endIndex = this._string.length; - this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN; + window.SVGPathSegList.prototype.replaceItem = function(newItem, index) { + this._checkPathSynchronizedToList(); + + if (newItem._owningPathSegList) { + // SVG2 spec says to make a copy. + newItem = newItem.clone(); + } + this._checkValidIndex(index); + this._list[index] = newItem; + newItem._owningPathSegList = this; + this._writeListToPath(); + return newItem + }; - this._skipOptionalSpaces(); - }; + window.SVGPathSegList.prototype.removeItem = function(index) { + this._checkPathSynchronizedToList(); - Source.prototype._isCurrentSpace = function () { - var character = this._string[this._currentIndex]; - return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f"); - }; + this._checkValidIndex(index); + var item = this._list[index]; + this._list.splice(index, 1); + this._writeListToPath(); + return item + }; - Source.prototype._skipOptionalSpaces = function () { - while (this._currentIndex < this._endIndex && this._isCurrentSpace()) - this._currentIndex++; - return this._currentIndex < this._endIndex; - }; + window.SVGPathSegList.prototype.appendItem = function(newItem) { + this._checkPathSynchronizedToList(); + + if (newItem._owningPathSegList) { + // SVG2 spec says to make a copy. + newItem = newItem.clone(); + } + this._list.push(newItem); + newItem._owningPathSegList = this; + // TODO: Optimize this to just append to the existing attribute. + this._writeListToPath(); + return newItem + }; - Source.prototype._skipOptionalSpacesOrDelimiter = function () { - if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") - return false; - if (this._skipOptionalSpaces()) { - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") { - this._currentIndex++; - this._skipOptionalSpaces(); - } - } - return this._currentIndex < this._endIndex; - }; + window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) { + var string = ''; + var first = true; + pathSegArray.forEach(function(pathSeg) { + if (first) { + first = false; + string += pathSeg._asPathString(); + } else { + string += ' ' + pathSeg._asPathString(); + } + }); + return string + }; - Source.prototype.hasMoreData = function () { - return this._currentIndex < this._endIndex; + // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp. + window.SVGPathSegList.prototype._parsePath = function(string) { + if (!string || string.length == 0) return [] + + var owningPathSegList = this; + + var Builder = function() { + this.pathSegList = []; + }; + + Builder.prototype.appendSegment = function(pathSeg) { + this.pathSegList.push(pathSeg); + }; + + var Source = function(string) { + this._string = string; + this._currentIndex = 0; + this._endIndex = this._string.length; + this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN; + + this._skipOptionalSpaces(); + }; + + Source.prototype._isCurrentSpace = function() { + var character = this._string[this._currentIndex]; + return ( + character <= ' ' && + (character == ' ' || + character == '\n' || + character == '\t' || + character == '\r' || + character == '\f') + ) + }; + + Source.prototype._skipOptionalSpaces = function() { + while (this._currentIndex < this._endIndex && this._isCurrentSpace()) + this._currentIndex++; + return this._currentIndex < this._endIndex + }; + + Source.prototype._skipOptionalSpacesOrDelimiter = function() { + if ( + this._currentIndex < this._endIndex && + !this._isCurrentSpace() && + this._string.charAt(this._currentIndex) != ',' + ) + return false + if (this._skipOptionalSpaces()) { + if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == ',' + ) { + this._currentIndex++; + this._skipOptionalSpaces(); + } + } + return this._currentIndex < this._endIndex + }; + + Source.prototype.hasMoreData = function() { + return this._currentIndex < this._endIndex + }; + + Source.prototype.peekSegmentType = function() { + var lookahead = this._string[this._currentIndex]; + return this._pathSegTypeFromChar(lookahead) + }; + + Source.prototype._pathSegTypeFromChar = function(lookahead) { + switch (lookahead) { + case 'Z': + case 'z': + return window.SVGPathSeg.PATHSEG_CLOSEPATH + case 'M': + return window.SVGPathSeg.PATHSEG_MOVETO_ABS + case 'm': + return window.SVGPathSeg.PATHSEG_MOVETO_REL + case 'L': + return window.SVGPathSeg.PATHSEG_LINETO_ABS + case 'l': + return window.SVGPathSeg.PATHSEG_LINETO_REL + case 'C': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS + case 'c': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL + case 'Q': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS + case 'q': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL + case 'A': + return window.SVGPathSeg.PATHSEG_ARC_ABS + case 'a': + return window.SVGPathSeg.PATHSEG_ARC_REL + case 'H': + return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS + case 'h': + return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL + case 'V': + return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS + case 'v': + return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL + case 'S': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS + case 's': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL + case 'T': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS + case 't': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL + default: + return window.SVGPathSeg.PATHSEG_UNKNOWN + } + }; + + Source.prototype._nextCommandHelper = function( + lookahead, + previousCommand + ) { + // Check for remaining coordinates in the current command. + if ( + (lookahead == '+' || + lookahead == '-' || + lookahead == '.' || + (lookahead >= '0' && lookahead <= '9')) && + previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH + ) { + if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) + return window.SVGPathSeg.PATHSEG_LINETO_ABS + if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) + return window.SVGPathSeg.PATHSEG_LINETO_REL + return previousCommand + } + return window.SVGPathSeg.PATHSEG_UNKNOWN + }; + + Source.prototype.initialCommandIsMoveTo = function() { + // If the path is empty it is still valid, so return true. + if (!this.hasMoreData()) return true + var command = this.peekSegmentType(); + // Path must start with moveTo. + return ( + command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || + command == window.SVGPathSeg.PATHSEG_MOVETO_REL + ) + }; + + // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp. + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF + Source.prototype._parseNumber = function() { + var exponent = 0; + var integer = 0; + var frac = 1; + var decimal = 0; + var sign = 1; + var expsign = 1; + + var startIndex = this._currentIndex; + + this._skipOptionalSpaces(); + + // Read the sign. + if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == '+' + ) + this._currentIndex++; + else if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == '-' + ) { + this._currentIndex++; + sign = -1; + } + + if ( + this._currentIndex == this._endIndex || + ((this._string.charAt(this._currentIndex) < '0' || + this._string.charAt(this._currentIndex) > '9') && + this._string.charAt(this._currentIndex) != '.') + ) + // The first character of a number must be one of [0-9+-.]. + return undefined + + // Read the integer part, build right-to-left. + var startIntPartIndex = this._currentIndex; + while ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) >= '0' && + this._string.charAt(this._currentIndex) <= '9' + ) + this._currentIndex++; // Advance to first non-digit. + + if (this._currentIndex != startIntPartIndex) { + var scanIntPartIndex = this._currentIndex - 1; + var multiplier = 1; + while (scanIntPartIndex >= startIntPartIndex) { + integer += + multiplier * (this._string.charAt(scanIntPartIndex--) - '0'); + multiplier *= 10; + } + } + + // Read the decimals. + if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == '.' + ) { + this._currentIndex++; + + // There must be a least one digit following the . + if ( + this._currentIndex >= this._endIndex || + this._string.charAt(this._currentIndex) < '0' || + this._string.charAt(this._currentIndex) > '9' + ) + return undefined + while ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) >= '0' && + this._string.charAt(this._currentIndex) <= '9' + ) { + frac *= 10; + decimal += (this._string.charAt(this._currentIndex) - '0') / frac; + this._currentIndex += 1; + } + } + + // Read the exponent part. + if ( + this._currentIndex != startIndex && + this._currentIndex + 1 < this._endIndex && + (this._string.charAt(this._currentIndex) == 'e' || + this._string.charAt(this._currentIndex) == 'E') && + this._string.charAt(this._currentIndex + 1) != 'x' && + this._string.charAt(this._currentIndex + 1) != 'm' + ) { + this._currentIndex++; + + // Read the sign of the exponent. + if (this._string.charAt(this._currentIndex) == '+') { + this._currentIndex++; + } else if (this._string.charAt(this._currentIndex) == '-') { + this._currentIndex++; + expsign = -1; + } + + // There must be an exponent. + if ( + this._currentIndex >= this._endIndex || + this._string.charAt(this._currentIndex) < '0' || + this._string.charAt(this._currentIndex) > '9' + ) + return undefined + + while ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) >= '0' && + this._string.charAt(this._currentIndex) <= '9' + ) { + exponent *= 10; + exponent += this._string.charAt(this._currentIndex) - '0'; + this._currentIndex++; + } + } + + var number = integer + decimal; + number *= sign; + + if (exponent) number *= Math.pow(10, expsign * exponent); + + if (startIndex == this._currentIndex) return undefined + + this._skipOptionalSpacesOrDelimiter(); + + return number + }; + + Source.prototype._parseArcFlag = function() { + if (this._currentIndex >= this._endIndex) return undefined + var flag = false; + var flagChar = this._string.charAt(this._currentIndex++); + if (flagChar == '0') flag = false; + else if (flagChar == '1') flag = true; + else return undefined + + this._skipOptionalSpacesOrDelimiter(); + return flag + }; + + Source.prototype.parseSegment = function() { + var lookahead = this._string[this._currentIndex]; + var command = this._pathSegTypeFromChar(lookahead); + if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) { + // Possibly an implicit command. Not allowed if this is the first command. + if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) + return null + command = this._nextCommandHelper(lookahead, this._previousCommand); + if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null + } else { + this._currentIndex++; + } + + this._previousCommand = command; + + switch (command) { + case window.SVGPathSeg.PATHSEG_MOVETO_REL: + return new window.SVGPathSegMovetoRel( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_MOVETO_ABS: + return new window.SVGPathSegMovetoAbs( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_REL: + return new window.SVGPathSegLinetoRel( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_ABS: + return new window.SVGPathSegLinetoAbs( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: + return new window.SVGPathSegLinetoHorizontalRel( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: + return new window.SVGPathSegLinetoHorizontalAbs( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: + return new window.SVGPathSegLinetoVerticalRel( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: + return new window.SVGPathSegLinetoVerticalAbs( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_CLOSEPATH: + this._skipOptionalSpaces(); + return new window.SVGPathSegClosePath(owningPathSegList) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype.peekSegmentType = function () { - var lookahead = this._string[this._currentIndex]; - return this._pathSegTypeFromChar(lookahead); + return new window.SVGPathSegCurvetoCubicRel( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype._pathSegTypeFromChar = function (lookahead) { - switch (lookahead) { - case "Z": - case "z": - return window.SVGPathSeg.PATHSEG_CLOSEPATH; - case "M": - return window.SVGPathSeg.PATHSEG_MOVETO_ABS; - case "m": - return window.SVGPathSeg.PATHSEG_MOVETO_REL; - case "L": - return window.SVGPathSeg.PATHSEG_LINETO_ABS; - case "l": - return window.SVGPathSeg.PATHSEG_LINETO_REL; - case "C": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS; - case "c": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL; - case "Q": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS; - case "q": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL; - case "A": - return window.SVGPathSeg.PATHSEG_ARC_ABS; - case "a": - return window.SVGPathSeg.PATHSEG_ARC_REL; - case "H": - return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS; - case "h": - return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL; - case "V": - return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS; - case "v": - return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL; - case "S": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; - case "s": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL; - case "T": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; - case "t": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; - default: - return window.SVGPathSeg.PATHSEG_UNKNOWN; - } + return new window.SVGPathSegCurvetoCubicAbs( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: + var points = { + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype._nextCommandHelper = function (lookahead, previousCommand) { - // Check for remaining coordinates in the current command. - if ((lookahead == "+" || lookahead == "-" || lookahead == "." || (lookahead >= "0" && lookahead <= "9")) && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { - if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) - return window.SVGPathSeg.PATHSEG_LINETO_ABS; - if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) - return window.SVGPathSeg.PATHSEG_LINETO_REL; - return previousCommand; - } - return window.SVGPathSeg.PATHSEG_UNKNOWN; + return new window.SVGPathSegCurvetoCubicSmoothRel( + owningPathSegList, + points.x, + points.y, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + var points = { + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype.initialCommandIsMoveTo = function () { - // If the path is empty it is still valid, so return true. - if (!this.hasMoreData()) - return true; - var command = this.peekSegmentType(); - // Path must start with moveTo. - return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL; + return new window.SVGPathSegCurvetoCubicSmoothAbs( + owningPathSegList, + points.x, + points.y, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp. - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF - Source.prototype._parseNumber = function () { - var exponent = 0; - var integer = 0; - var frac = 1; - var decimal = 0; - var sign = 1; - var expsign = 1; - - var startIndex = this._currentIndex; - - this._skipOptionalSpaces(); - - // Read the sign. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") - this._currentIndex++; - else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") { - this._currentIndex++; - sign = -1; - } - - if (this._currentIndex == this._endIndex || ((this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != - ".")) - // The first character of a number must be one of [0-9+-.]. - return undefined; - - // Read the integer part, build right-to-left. - var startIntPartIndex = this._currentIndex; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") - this._currentIndex++; // Advance to first non-digit. - - if (this._currentIndex != startIntPartIndex) { - var scanIntPartIndex = this._currentIndex - 1; - var multiplier = 1; - while (scanIntPartIndex >= startIntPartIndex) { - integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0"); - multiplier *= 10; - } - } - - // Read the decimals. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") { - this._currentIndex++; - - // There must be a least one digit following the . - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") - return undefined; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { - frac *= 10; - decimal += (this._string.charAt(this._currentIndex) - "0") / frac; - this._currentIndex += 1; - } - } - - // Read the exponent part. - if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == - "E") && (this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m")) { - this._currentIndex++; - - // Read the sign of the exponent. - if (this._string.charAt(this._currentIndex) == "+") { - this._currentIndex++; - } else if (this._string.charAt(this._currentIndex) == "-") { - this._currentIndex++; - expsign = -1; - } - - // There must be an exponent. - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") - return undefined; - - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { - exponent *= 10; - exponent += (this._string.charAt(this._currentIndex) - "0"); - this._currentIndex++; - } - } - - var number = integer + decimal; - number *= sign; - - if (exponent) - number *= Math.pow(10, expsign * exponent); - - if (startIndex == this._currentIndex) - return undefined; - - this._skipOptionalSpacesOrDelimiter(); - - return number; + return new window.SVGPathSegCurvetoQuadraticRel( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype._parseArcFlag = function () { - if (this._currentIndex >= this._endIndex) - return undefined; - var flag = false; - var flagChar = this._string.charAt(this._currentIndex++); - if (flagChar == "0") - flag = false; - else if (flagChar == "1") - flag = true; - else - return undefined; - - this._skipOptionalSpacesOrDelimiter(); - return flag; + return new window.SVGPathSegCurvetoQuadraticAbs( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: + return new window.SVGPathSegCurvetoQuadraticSmoothRel( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + return new window.SVGPathSegCurvetoQuadraticSmoothAbs( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_ARC_REL: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + arcAngle: this._parseNumber(), + arcLarge: this._parseArcFlag(), + arcSweep: this._parseArcFlag(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype.parseSegment = function () { - var lookahead = this._string[this._currentIndex]; - var command = this._pathSegTypeFromChar(lookahead); - if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) { - // Possibly an implicit command. Not allowed if this is the first command. - if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) - return null; - command = this._nextCommandHelper(lookahead, this._previousCommand); - if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) - return null; - } else { - this._currentIndex++; - } - - this._previousCommand = command; - - switch (command) { - case window.SVGPathSeg.PATHSEG_MOVETO_REL: - return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_MOVETO_ABS: - return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_REL: - return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_ABS: - return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: - return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: - return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: - return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: - return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_CLOSEPATH: - this._skipOptionalSpaces(); - return new window.SVGPathSegClosePath(owningPathSegList); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: - var points = { - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: - var points = { - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: - return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_ARC_REL: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - arcAngle: this._parseNumber(), - arcLarge: this._parseArcFlag(), - arcSweep: this._parseArcFlag(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); - case window.SVGPathSeg.PATHSEG_ARC_ABS: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - arcAngle: this._parseNumber(), - arcLarge: this._parseArcFlag(), - arcSweep: this._parseArcFlag(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); - default: - throw "Unknown path seg type." - } + return new window.SVGPathSegArcRel( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.arcAngle, + points.arcLarge, + points.arcSweep + ) + case window.SVGPathSeg.PATHSEG_ARC_ABS: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + arcAngle: this._parseNumber(), + arcLarge: this._parseArcFlag(), + arcSweep: this._parseArcFlag(), + x: this._parseNumber(), + y: this._parseNumber() }; - - var builder = new Builder(); - var source = new Source(string); - - if (!source.initialCommandIsMoveTo()) - return []; - while (source.hasMoreData()) { - var pathSeg = source.parseSegment(); - if (!pathSeg) - return []; - builder.appendSegment(pathSeg); - } - - return builder.pathSegList; - }; - } -}()); + return new window.SVGPathSegArcAbs( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.arcAngle, + points.arcLarge, + points.arcSweep + ) + default: + throw 'Unknown path seg type.' + } + }; + + var builder = new Builder(); + var source = new Source(string); + + if (!source.initialCommandIsMoveTo()) return [] + while (source.hasMoreData()) { + var pathSeg = source.parseSegment(); + if (!pathSeg) return [] + builder.appendSegment(pathSeg); + } + + return builder.pathSegList + }; + } +})(); // String.padEnd polyfill for IE11 // // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd if (!String.prototype.padEnd) { - String.prototype.padEnd = function padEnd(targetLength, padString) { - targetLength = targetLength >> 0; //floor if number or convert non-number to 0; - padString = String((typeof padString !== 'undefined' ? padString : ' ')); - if (this.length > targetLength) { - return String(this); - } else { - targetLength = targetLength - this.length; - if (targetLength > padString.length) { - padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed - } - return String(this) + padString.slice(0, targetLength); - } - }; + String.prototype.padEnd = function padEnd(targetLength, padString) { + targetLength = targetLength >> 0; //floor if number or convert non-number to 0; + padString = String(typeof padString !== 'undefined' ? padString : ' '); + if (this.length > targetLength) { + return String(this) + } else { + targetLength = targetLength - this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed + } + return String(this) + padString.slice(0, targetLength) + } + }; } // Object.assign polyfill for IE11 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill if (typeof Object.assign !== 'function') { - // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { - value: function assign(target, varArgs) { // .length of function is 2 - if (target === null || target === undefined) { - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - - if (nextSource !== null && nextSource !== undefined) { - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } + // Must be writable: true, enumerable: false, configurable: true + Object.defineProperty(Object, 'assign', { + value: function assign(target, varArgs) { + if (target === null || target === undefined) { + throw new TypeError('Cannot convert undefined or null to object') + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource !== null && nextSource !== undefined) { + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; } - return to; - }, - writable: true, - configurable: true - }); + } + } + } + return to + }, + writable: true, + configurable: true + }); } /* jshint ignore:end */ -Chart.prototype.axis = function () {}; -Chart.prototype.axis.labels = function (labels) { - var $$ = this.internal; - if (arguments.length) { - Object.keys(labels).forEach(function (axisId) { - $$.axis.setLabelText(axisId, labels[axisId]); - }); - $$.axis.updateLabels(); - } - // TODO: return some values? -}; -Chart.prototype.axis.max = function (max) { - var $$ = this.internal, config = $$.config; - if (arguments.length) { - if (typeof max === 'object') { - if (isValue(max.x)) { config.axis_x_max = max.x; } - if (isValue(max.y)) { config.axis_y_max = max.y; } - if (isValue(max.y2)) { config.axis_y2_max = max.y2; } - } else { - config.axis_y_max = config.axis_y2_max = max; - } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); +Chart.prototype.axis = function() {}; +Chart.prototype.axis.labels = function(labels) { + var $$ = this.internal; + if (arguments.length) { + Object.keys(labels).forEach(function(axisId) { + $$.axis.setLabelText(axisId, labels[axisId]); + }); + $$.axis.updateLabels(); + } + // TODO: return some values? +}; +Chart.prototype.axis.max = function(max) { + var $$ = this.internal, + config = $$.config; + if (arguments.length) { + if (typeof max === 'object') { + if (isValue(max.x)) { + config.axis_x_max = max.x; + } + if (isValue(max.y)) { + config.axis_y_max = max.y; + } + if (isValue(max.y2)) { + config.axis_y2_max = max.y2; + } } else { - return { - x: config.axis_x_max, - y: config.axis_y_max, - y2: config.axis_y2_max - }; + config.axis_y_max = config.axis_y2_max = max; } + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } else { + return { + x: config.axis_x_max, + y: config.axis_y_max, + y2: config.axis_y2_max + } + } }; -Chart.prototype.axis.min = function (min) { - var $$ = this.internal, config = $$.config; - if (arguments.length) { - if (typeof min === 'object') { - if (isValue(min.x)) { config.axis_x_min = min.x; } - if (isValue(min.y)) { config.axis_y_min = min.y; } - if (isValue(min.y2)) { config.axis_y2_min = min.y2; } - } else { - config.axis_y_min = config.axis_y2_min = min; - } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); +Chart.prototype.axis.min = function(min) { + var $$ = this.internal, + config = $$.config; + if (arguments.length) { + if (typeof min === 'object') { + if (isValue(min.x)) { + config.axis_x_min = min.x; + } + if (isValue(min.y)) { + config.axis_y_min = min.y; + } + if (isValue(min.y2)) { + config.axis_y2_min = min.y2; + } } else { - return { - x: config.axis_x_min, - y: config.axis_y_min, - y2: config.axis_y2_min - }; + config.axis_y_min = config.axis_y2_min = min; + } + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } else { + return { + x: config.axis_x_min, + y: config.axis_y_min, + y2: config.axis_y2_min } + } }; -Chart.prototype.axis.range = function (range) { - if (arguments.length) { - if (isDefined(range.max)) { this.axis.max(range.max); } - if (isDefined(range.min)) { this.axis.min(range.min); } - } else { - return { - max: this.axis.max(), - min: this.axis.min() - }; +Chart.prototype.axis.range = function(range) { + if (arguments.length) { + if (isDefined(range.max)) { + this.axis.max(range.max); + } + if (isDefined(range.min)) { + this.axis.min(range.min); } + } else { + return { + max: this.axis.max(), + min: this.axis.min() + } + } }; -Chart.prototype.axis.types = function (types) { - const $$ = this.internal; - if (types === undefined) { - return { - y: $$.config.axis_y_type, - y2: $$.config.axis_y2_type - }; - } else { - if (isDefined(types.y)) { - $$.config.axis_y_type = types.y; - } - - if (isDefined(types.y2)) { - $$.config.axis_y2_type = types.y2; - } - - $$.updateScales(); - $$.redraw(); +Chart.prototype.axis.types = function(types) { + const $$ = this.internal; + if (types === undefined) { + return { + y: $$.config.axis_y_type, + y2: $$.config.axis_y2_type + } + } else { + if (isDefined(types.y)) { + $$.config.axis_y_type = types.y; } -}; -Chart.prototype.category = function (i, category) { - var $$ = this.internal, config = $$.config; - if (arguments.length > 1) { - config.axis_x_categories[i] = category; - $$.redraw(); + if (isDefined(types.y2)) { + $$.config.axis_y2_type = types.y2; } - return config.axis_x_categories[i]; + + $$.updateScales(); + $$.redraw(); + } }; -Chart.prototype.categories = function (categories) { - var $$ = this.internal, config = $$.config; - if (!arguments.length) { return config.axis_x_categories; } - config.axis_x_categories = categories; + +Chart.prototype.category = function(i, category) { + var $$ = this.internal, + config = $$.config; + if (arguments.length > 1) { + config.axis_x_categories[i] = category; $$.redraw(); - return config.axis_x_categories; + } + return config.axis_x_categories[i] +}; +Chart.prototype.categories = function(categories) { + var $$ = this.internal, + config = $$.config; + if (!arguments.length) { + return config.axis_x_categories + } + config.axis_x_categories = categories; + $$.redraw(); + return config.axis_x_categories }; -Chart.prototype.resize = function (size) { - var $$ = this.internal, config = $$.config; - config.size_width = size ? size.width : null; - config.size_height = size ? size.height : null; - this.flush(); +Chart.prototype.resize = function(size) { + var $$ = this.internal, + config = $$.config; + config.size_width = size ? size.width : null; + config.size_height = size ? size.height : null; + this.flush(); }; -Chart.prototype.flush = function () { - var $$ = this.internal; - $$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false}); +Chart.prototype.flush = function() { + var $$ = this.internal; + $$.updateAndRedraw({ + withLegend: true, + withTransition: false, + withTransitionForTransform: false + }); }; -Chart.prototype.destroy = function () { - var $$ = this.internal; +Chart.prototype.destroy = function() { + var $$ = this.internal; - window.clearInterval($$.intervalForObserveInserted); + window.clearInterval($$.intervalForObserveInserted); - if ($$.resizeTimeout !== undefined) { - window.clearTimeout($$.resizeTimeout); - } + if ($$.resizeTimeout !== undefined) { + window.clearTimeout($$.resizeTimeout); + } - if (window.detachEvent) { - window.detachEvent('onresize', $$.resizeIfElementDisplayed); - } else if (window.removeEventListener) { - window.removeEventListener('resize', $$.resizeIfElementDisplayed); - } else { - var wrapper = window.onresize; - // check if no one else removed our wrapper and remove our resizeFunction from it - if (wrapper && wrapper.add && wrapper.remove) { - wrapper.remove($$.resizeFunction); - } + if (window.detachEvent) { + window.detachEvent('onresize', $$.resizeIfElementDisplayed); + } else if (window.removeEventListener) { + window.removeEventListener('resize', $$.resizeIfElementDisplayed); + } else { + var wrapper = window.onresize; + // check if no one else removed our wrapper and remove our resizeFunction from it + if (wrapper && wrapper.add && wrapper.remove) { + wrapper.remove($$.resizeFunction); } + } - // Removes the inner resize functions - $$.resizeFunction.remove(); + // Removes the inner resize functions + $$.resizeFunction.remove(); - // Unbinds from the window focus event - $$.unbindWindowFocus(); + // Unbinds from the window focus event + $$.unbindWindowFocus(); - $$.selectChart.classed('c3', false).html(""); + $$.selectChart.classed('c3', false).html(''); - // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. - Object.keys($$).forEach(function (key) { - $$[key] = null; - }); + // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. + Object.keys($$).forEach(function(key) { + $$[key] = null; + }); - return null; + return null }; // TODO: fix -Chart.prototype.color = function (id) { - var $$ = this.internal; - return $$.color(id); // more patterns +Chart.prototype.color = function(id) { + var $$ = this.internal; + return $$.color(id) // more patterns }; -Chart.prototype.data = function (targetIds) { - var targets = this.internal.data.targets; - return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) { - return [].concat(targetIds).indexOf(t.id) >= 0; - }); +Chart.prototype.data = function(targetIds) { + var targets = this.internal.data.targets; + return typeof targetIds === 'undefined' + ? targets + : targets.filter(function(t) { + return [].concat(targetIds).indexOf(t.id) >= 0 + }) }; -Chart.prototype.data.shown = function (targetIds) { - return this.internal.filterTargetsToShow(this.data(targetIds)); +Chart.prototype.data.shown = function(targetIds) { + return this.internal.filterTargetsToShow(this.data(targetIds)) }; /** @@ -4061,1421 +5273,1821 @@ Chart.prototype.data.shown = function (targetIds) { * @param flat * @return {Array} Data values */ -Chart.prototype.data.values = function (targetId, flat = true) { - let values = null; - - if (targetId) { - const targets = this.data(targetId); - if (targets && isArray(targets)) { - values = targets.reduce((ret, v) => { - const dataValue = v.values.map(d => d.value); - if (flat) { - ret = ret.concat(dataValue); - } else { - ret.push(dataValue); - } - return ret; - }, []); +Chart.prototype.data.values = function(targetId, flat = true) { + let values = null; + + if (targetId) { + const targets = this.data(targetId); + if (targets && isArray(targets)) { + values = targets.reduce((ret, v) => { + const dataValue = v.values.map(d => d.value); + if (flat) { + ret = ret.concat(dataValue); + } else { + ret.push(dataValue); } + return ret + }, []); } + } - return values; + return values }; -Chart.prototype.data.names = function (names) { - this.internal.clearLegendItemTextBoxCache(); - return this.internal.updateDataAttributes('names', names); +Chart.prototype.data.names = function(names) { + this.internal.clearLegendItemTextBoxCache(); + return this.internal.updateDataAttributes('names', names) }; -Chart.prototype.data.colors = function (colors) { - return this.internal.updateDataAttributes('colors', colors); +Chart.prototype.data.colors = function(colors) { + return this.internal.updateDataAttributes('colors', colors) }; -Chart.prototype.data.axes = function (axes) { - return this.internal.updateDataAttributes('axes', axes); +Chart.prototype.data.axes = function(axes) { + return this.internal.updateDataAttributes('axes', axes) }; -Chart.prototype.data.stackNormalized = function (normalized) { - if (normalized === undefined) { - return this.internal.isStackNormalized(); - } +Chart.prototype.data.stackNormalized = function(normalized) { + if (normalized === undefined) { + return this.internal.isStackNormalized() + } - this.internal.config.data_stack_normalize = !!normalized; - this.internal.redraw(); + this.internal.config.data_stack_normalize = !!normalized; + this.internal.redraw(); }; Chart.prototype.donut = function() {}; -Chart.prototype.donut.padAngle = function (padAngle) { - if (padAngle === undefined) { - return this.internal.config.donut_padAngle; - } - this.internal.config.donut_padAngle = padAngle; - this.flush(); -}; - -Chart.prototype.flow = function (args) { - var $$ = this.internal, - targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(), - dataCount, domain, baseTarget, baseValue, length = 0, tail = 0, diff, to; - - if (args.json) { - data = $$.convertJsonToData(args.json, args.keys); - } - else if (args.rows) { - data = $$.convertRowsToData(args.rows); - } - else if (args.columns) { - data = $$.convertColumnsToData(args.columns); - } - else { - return; - } - targets = $$.convertDataToTargets(data, true); - - // Update/Add data - $$.data.targets.forEach(function (t) { - var found = false, i, j; - for (i = 0; i < targets.length; i++) { - if (t.id === targets[i].id) { - found = true; - - if (t.values[t.values.length - 1]) { - tail = t.values[t.values.length - 1].index + 1; - } - length = targets[i].values.length; - - for (j = 0; j < length; j++) { - targets[i].values[j].index = tail + j; - if (!$$.isTimeSeries()) { - targets[i].values[j].x = tail + j; - } - } - t.values = t.values.concat(targets[i].values); - - targets.splice(i, 1); - break; - } - } - if (!found) { notfoundIds.push(t.id); } +Chart.prototype.donut.padAngle = function(padAngle) { + if (padAngle === undefined) { + return this.internal.config.donut_padAngle + } + this.internal.config.donut_padAngle = padAngle; + this.flush(); +}; + +Chart.prototype.flow = function(args) { + var $$ = this.internal, + targets, + data, + notfoundIds = [], + orgDataCount = $$.getMaxDataCount(), + dataCount, + domain, + baseTarget, + baseValue, + length = 0, + tail = 0, + diff, + to; + + if (args.json) { + data = $$.convertJsonToData(args.json, args.keys); + } else if (args.rows) { + data = $$.convertRowsToData(args.rows); + } else if (args.columns) { + data = $$.convertColumnsToData(args.columns); + } else { + return + } + targets = $$.convertDataToTargets(data, true); + + // Update/Add data + $$.data.targets.forEach(function(t) { + var found = false, + i, + j; + for (i = 0; i < targets.length; i++) { + if (t.id === targets[i].id) { + found = true; + + if (t.values[t.values.length - 1]) { + tail = t.values[t.values.length - 1].index + 1; + } + length = targets[i].values.length; + + for (j = 0; j < length; j++) { + targets[i].values[j].index = tail + j; + if (!$$.isTimeSeries()) { + targets[i].values[j].x = tail + j; + } + } + t.values = t.values.concat(targets[i].values); + + targets.splice(i, 1); + break + } + } + if (!found) { + notfoundIds.push(t.id); + } + }); + + // Append null for not found targets + $$.data.targets.forEach(function(t) { + var i, j; + for (i = 0; i < notfoundIds.length; i++) { + if (t.id === notfoundIds[i]) { + tail = t.values[t.values.length - 1].index + 1; + for (j = 0; j < length; j++) { + t.values.push({ + id: t.id, + index: tail + j, + x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j, + value: null + }); + } + } + } + }); + + // Generate null values for new target + if ($$.data.targets.length) { + targets.forEach(function(t) { + var i, + missing = []; + for (i = $$.data.targets[0].values[0].index; i < tail; i++) { + missing.push({ + id: t.id, + index: i, + x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i, + value: null + }); + } + t.values.forEach(function(v) { + v.index += tail; + if (!$$.isTimeSeries()) { + v.x += tail; + } + }); + t.values = missing.concat(t.values); }); - - // Append null for not found targets - $$.data.targets.forEach(function (t) { - var i, j; - for (i = 0; i < notfoundIds.length; i++) { - if (t.id === notfoundIds[i]) { - tail = t.values[t.values.length - 1].index + 1; - for (j = 0; j < length; j++) { - t.values.push({ - id: t.id, - index: tail + j, - x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j, - value: null - }); - } - } - } + } + $$.data.targets = $$.data.targets.concat(targets); // add remained + + // check data count because behavior needs to change when it's only one + dataCount = $$.getMaxDataCount(); + baseTarget = $$.data.targets[0]; + baseValue = baseTarget.values[0]; + + // Update length to flow if needed + if (isDefined(args.to)) { + length = 0; + to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to; + baseTarget.values.forEach(function(v) { + if (v.x < to) { + length++; + } }); + } else if (isDefined(args.length)) { + length = args.length; + } - // Generate null values for new target - if ($$.data.targets.length) { - targets.forEach(function (t) { - var i, missing = []; - for (i = $$.data.targets[0].values[0].index; i < tail; i++) { - missing.push({ - id: t.id, - index: i, - x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i, - value: null - }); - } - t.values.forEach(function (v) { - v.index += tail; - if (!$$.isTimeSeries()) { - v.x += tail; - } - }); - t.values = missing.concat(t.values); - }); + // If only one data, update the domain to flow from left edge of the chart + if (!orgDataCount) { + if ($$.isTimeSeries()) { + if (baseTarget.values.length > 1) { + diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x; + } else { + diff = baseValue.x - $$.getXDomain($$.data.targets)[0]; + } + } else { + diff = 1; } - $$.data.targets = $$.data.targets.concat(targets); // add remained - - // check data count because behavior needs to change when it's only one - dataCount = $$.getMaxDataCount(); - baseTarget = $$.data.targets[0]; - baseValue = baseTarget.values[0]; - - // Update length to flow if needed - if (isDefined(args.to)) { - length = 0; - to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to; - baseTarget.values.forEach(function (v) { - if (v.x < to) { length++; } - }); - } else if (isDefined(args.length)) { - length = args.length; + domain = [baseValue.x - diff, baseValue.x]; + $$.updateXDomain(null, true, true, false, domain); + } else if (orgDataCount === 1) { + if ($$.isTimeSeries()) { + diff = + (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2; + domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)]; + $$.updateXDomain(null, true, true, false, domain); } + } - // If only one data, update the domain to flow from left edge of the chart - if (!orgDataCount) { + // Set targets + $$.updateTargets($$.data.targets); + + // Redraw with new targets + $$.redraw({ + flow: { + index: baseValue.index, + length: length, + duration: isValue(args.duration) + ? args.duration + : $$.config.transition_duration, + done: args.done, + orgDataCount: orgDataCount + }, + withLegend: true, + withTransition: orgDataCount > 1, + withTrimXDomain: false, + withUpdateXAxis: true + }); +}; + +ChartInternal.prototype.generateFlow = function(args) { + var $$ = this, + config = $$.config, + d3 = $$.d3; + + return function() { + var targets = args.targets, + flow = args.flow, + drawBar = args.drawBar, + drawLine = args.drawLine, + drawArea = args.drawArea, + cx = args.cx, + cy = args.cy, + xv = args.xv, + xForText = args.xForText, + yForText = args.yForText, + duration = args.duration; + + var translateX, + scaleX = 1, + transform, + flowIndex = flow.index, + flowLength = flow.length, + flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), + flowEnd = $$.getValueOnIndex( + $$.data.targets[0].values, + flowIndex + flowLength + ), + orgDomain = $$.x.domain(), + domain, + durationForFlow = flow.duration || duration, + done = flow.done || function() {}, + wait = $$.generateWait(); + + var xgrid, + xgridLines, + mainRegion, + mainText, + mainBar, + mainLine, + mainArea, + mainCircle; + + // set flag + $$.flowing = true; + + // remove head data after rendered + $$.data.targets.forEach(function(d) { + d.values.splice(0, flowLength); + }); + + // update x domain to generate axis elements for flow + domain = $$.updateXDomain(targets, true, true); + // update elements related to x scale + if ($$.updateXGrid) { + $$.updateXGrid(true); + } + + xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid + xgridLines = $$.xgridLines || d3.selectAll([]); + mainRegion = $$.mainRegion || d3.selectAll([]); + mainText = $$.mainText || d3.selectAll([]); + mainBar = $$.mainBar || d3.selectAll([]); + mainLine = $$.mainLine || d3.selectAll([]); + mainArea = $$.mainArea || d3.selectAll([]); + mainCircle = $$.mainCircle || d3.selectAll([]); + + // generate transform to flow + if (!flow.orgDataCount) { + // if empty + if ($$.data.targets[0].values.length !== 1) { + translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); + } else { if ($$.isTimeSeries()) { - if (baseTarget.values.length > 1) { - diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x; - } else { - diff = baseValue.x - $$.getXDomain($$.data.targets)[0]; - } + flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0); + flowEnd = $$.getValueOnIndex( + $$.data.targets[0].values, + $$.data.targets[0].values.length - 1 + ); + translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); } else { - diff = 1; - } - domain = [baseValue.x - diff, baseValue.x]; - $$.updateXDomain(null, true, true, false, domain); - } else if (orgDataCount === 1) { - if ($$.isTimeSeries()) { - diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2; - domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)]; - $$.updateXDomain(null, true, true, false, domain); - } - } + translateX = diffDomain(domain) / 2; + } + } + } else if ( + flow.orgDataCount === 1 || + (flowStart && flowStart.x) === (flowEnd && flowEnd.x) + ) { + translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); + } else { + if ($$.isTimeSeries()) { + translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); + } else { + translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); + } + } + scaleX = diffDomain(orgDomain) / diffDomain(domain); + transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)'; + + $$.hideXGridFocus(); + + var flowTransition = d3 + .transition() + .ease(d3.easeLinear) + .duration(durationForFlow); + wait.add($$.xAxis($$.axes.x, flowTransition)); + wait.add(mainBar.transition(flowTransition).attr('transform', transform)); + wait.add(mainLine.transition(flowTransition).attr('transform', transform)); + wait.add(mainArea.transition(flowTransition).attr('transform', transform)); + wait.add(mainCircle.transition(flowTransition).attr('transform', transform)); + wait.add(mainText.transition(flowTransition).attr('transform', transform)); + wait.add( + mainRegion + .filter($$.isRegionOnX) + .transition(flowTransition) + .attr('transform', transform) + ); + wait.add(xgrid.transition(flowTransition).attr('transform', transform)); + wait.add(xgridLines.transition(flowTransition).attr('transform', transform)); + wait(function() { + var i, + shapes = [], + texts = []; + + // remove flowed elements + if (flowLength) { + for (i = 0; i < flowLength; i++) { + shapes.push('.' + CLASS.shape + '-' + (flowIndex + i)); + texts.push('.' + CLASS.text + '-' + (flowIndex + i)); + } + $$.svg + .selectAll('.' + CLASS.shapes) + .selectAll(shapes) + .remove(); + $$.svg + .selectAll('.' + CLASS.texts) + .selectAll(texts) + .remove(); + $$.svg.select('.' + CLASS.xgrid).remove(); + } + + // draw again for removing flowed elements and reverting attr + xgrid + .attr('transform', null) + .attr('x1', $$.xgridAttr.x1) + .attr('x2', $$.xgridAttr.x2) + .attr('y1', $$.xgridAttr.y1) + .attr('y2', $$.xgridAttr.y2) + .style('opacity', $$.xgridAttr.opacity); + xgridLines.attr('transform', null); + xgridLines + .select('line') + .attr('x1', config.axis_rotated ? 0 : xv) + .attr('x2', config.axis_rotated ? $$.width : xv); + xgridLines + .select('text') + .attr('x', config.axis_rotated ? $$.width : 0) + .attr('y', xv); + mainBar.attr('transform', null).attr('d', drawBar); + mainLine.attr('transform', null).attr('d', drawLine); + mainArea.attr('transform', null).attr('d', drawArea); + mainCircle + .attr('transform', null) + .attr('cx', cx) + .attr('cy', cy); + mainText + .attr('transform', null) + .attr('x', xForText) + .attr('y', yForText) + .style('fill-opacity', $$.opacityForText.bind($$)); + mainRegion.attr('transform', null); + mainRegion + .filter($$.isRegionOnX) + .attr('x', $$.regionX.bind($$)) + .attr('width', $$.regionWidth.bind($$)); - // Set targets - $$.updateTargets($$.data.targets); + // callback for end of flow + done(); - // Redraw with new targets - $$.redraw({ - flow: { - index: baseValue.index, - length: length, - duration: isValue(args.duration) ? args.duration : $$.config.transition_duration, - done: args.done, - orgDataCount: orgDataCount, - }, - withLegend: true, - withTransition: orgDataCount > 1, - withTrimXDomain: false, - withUpdateXAxis: true, + $$.flowing = false; }); + } }; -ChartInternal.prototype.generateFlow = function (args) { - var $$ = this, config = $$.config, d3 = $$.d3; - - return function () { - var targets = args.targets, - flow = args.flow, - drawBar = args.drawBar, - drawLine = args.drawLine, - drawArea = args.drawArea, - cx = args.cx, - cy = args.cy, - xv = args.xv, - xForText = args.xForText, - yForText = args.yForText, - duration = args.duration; - - var translateX, scaleX = 1, transform, - flowIndex = flow.index, - flowLength = flow.length, - flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), - flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength), - orgDomain = $$.x.domain(), domain, - durationForFlow = flow.duration || duration, - done = flow.done || function () {}, - wait = $$.generateWait(); - - var xgrid, - xgridLines, - mainRegion, - mainText, - mainBar, - mainLine, - mainArea, - mainCircle; - - // set flag - $$.flowing = true; - - // remove head data after rendered - $$.data.targets.forEach(function (d) { - d.values.splice(0, flowLength); - }); - - // update x domain to generate axis elements for flow - domain = $$.updateXDomain(targets, true, true); - // update elements related to x scale - if ($$.updateXGrid) { $$.updateXGrid(true); } - - xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid - xgridLines = $$.xgridLines || d3.selectAll([]); - mainRegion = $$.mainRegion || d3.selectAll([]); - mainText = $$.mainText || d3.selectAll([]); - mainBar = $$.mainBar || d3.selectAll([]); - mainLine = $$.mainLine || d3.selectAll([]); - mainArea = $$.mainArea || d3.selectAll([]); - mainCircle = $$.mainCircle || d3.selectAll([]); - - // generate transform to flow - if (!flow.orgDataCount) { // if empty - if ($$.data.targets[0].values.length !== 1) { - translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); - } else { - if ($$.isTimeSeries()) { - flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0); - flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1); - translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); - } else { - translateX = diffDomain(domain) / 2; - } - } - } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) { - translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); - } else { - if ($$.isTimeSeries()) { - translateX = ($$.x(orgDomain[0]) - $$.x(domain[0])); - } else { - translateX = ($$.x(flowStart.x) - $$.x(flowEnd.x)); - } - } - scaleX = (diffDomain(orgDomain) / diffDomain(domain)); - transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)'; - - $$.hideXGridFocus(); - - var flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow); - wait.add($$.xAxis($$.axes.x, flowTransition)); - wait.add(mainBar.transition(flowTransition).attr('transform', transform)); - wait.add(mainLine.transition(flowTransition).attr('transform', transform)); - wait.add(mainArea.transition(flowTransition).attr('transform', transform)); - wait.add(mainCircle.transition(flowTransition).attr('transform', transform)); - wait.add(mainText.transition(flowTransition).attr('transform', transform)); - wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform)); - wait.add(xgrid.transition(flowTransition).attr('transform', transform)); - wait.add(xgridLines.transition(flowTransition).attr('transform', transform)); - wait(function () { - var i, shapes = [], texts = []; - - // remove flowed elements - if (flowLength) { - for (i = 0; i < flowLength; i++) { - shapes.push('.' + CLASS.shape + '-' + (flowIndex + i)); - texts.push('.' + CLASS.text + '-' + (flowIndex + i)); - } - $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove(); - $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove(); - $$.svg.select('.' + CLASS.xgrid).remove(); - } - - // draw again for removing flowed elements and reverting attr - xgrid - .attr('transform', null) - .attr('x1', $$.xgridAttr.x1) - .attr('x2', $$.xgridAttr.x2) - .attr('y1', $$.xgridAttr.y1) - .attr('y2', $$.xgridAttr.y2) - .style("opacity", $$.xgridAttr.opacity); - xgridLines - .attr('transform', null); - xgridLines.select('line') - .attr("x1", config.axis_rotated ? 0 : xv) - .attr("x2", config.axis_rotated ? $$.width : xv); - xgridLines.select('text') - .attr("x", config.axis_rotated ? $$.width : 0) - .attr("y", xv); - mainBar - .attr('transform', null) - .attr("d", drawBar); - mainLine - .attr('transform', null) - .attr("d", drawLine); - mainArea - .attr('transform', null) - .attr("d", drawArea); - mainCircle - .attr('transform', null) - .attr("cx", cx) - .attr("cy", cy); - mainText - .attr('transform', null) - .attr('x', xForText) - .attr('y', yForText) - .style('fill-opacity', $$.opacityForText.bind($$)); - mainRegion - .attr('transform', null); - mainRegion.filter($$.isRegionOnX) - .attr("x", $$.regionX.bind($$)) - .attr("width", $$.regionWidth.bind($$)); - - // callback for end of flow - done(); - - $$.flowing = false; - }); - }; -}; - -Chart.prototype.focus = function (targetIds) { - var $$ = this.internal, candidates; - - targetIds = $$.mapToTargetIds(targetIds); - candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), +Chart.prototype.focus = function(targetIds) { + var $$ = this.internal, + candidates; + targetIds = $$.mapToTargetIds(targetIds) + ;(candidates = $$.svg.selectAll( + $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)) + )), this.revert(); - this.defocus(); - candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false); - if ($$.hasArcType()) { - $$.expandArc(targetIds); - } - $$.toggleFocusLegend(targetIds, true); + this.defocus(); + candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false); + if ($$.hasArcType()) { + $$.expandArc(targetIds); + } + $$.toggleFocusLegend(targetIds, true); - $$.focusedTargetIds = targetIds; - $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); + $$.focusedTargetIds = targetIds; + $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); }; -Chart.prototype.defocus = function (targetIds) { - var $$ = this.internal, candidates; - - targetIds = $$.mapToTargetIds(targetIds); - candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), +Chart.prototype.defocus = function(targetIds) { + var $$ = this.internal, + candidates; + targetIds = $$.mapToTargetIds(targetIds) + ;(candidates = $$.svg.selectAll( + $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)) + )), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true); - if ($$.hasArcType()) { - $$.unexpandArc(targetIds); - } - $$.toggleFocusLegend(targetIds, false); + if ($$.hasArcType()) { + $$.unexpandArc(targetIds); + } + $$.toggleFocusLegend(targetIds, false); - $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); - $$.defocusedTargetIds = targetIds; + $$.focusedTargetIds = $$.focusedTargetIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); + $$.defocusedTargetIds = targetIds; }; -Chart.prototype.revert = function (targetIds) { - var $$ = this.internal, candidates; - - targetIds = $$.mapToTargetIds(targetIds); - candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets +Chart.prototype.revert = function(targetIds) { + var $$ = this.internal, + candidates; - candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false); - if ($$.hasArcType()) { - $$.unexpandArc(targetIds); - } - if ($$.config.legend_show) { - $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); - $$.legend.selectAll($$.selectorLegends(targetIds)) - .filter(function () { - return $$.d3.select(this).classed(CLASS.legendItemFocused); - }) - .classed(CLASS.legendItemFocused, false); - } - - $$.focusedTargetIds = []; - $$.defocusedTargetIds = []; -}; - -Chart.prototype.xgrids = function (grids) { - var $$ = this.internal, config = $$.config; - if (! grids) { return config.grid_x_lines; } - config.grid_x_lines = grids; - $$.redrawWithoutRescale(); - return config.grid_x_lines; -}; -Chart.prototype.xgrids.add = function (grids) { - var $$ = this.internal; - return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : [])); -}; -Chart.prototype.xgrids.remove = function (params) { // TODO: multiple - var $$ = this.internal; - $$.removeGridLines(params, true); -}; + targetIds = $$.mapToTargetIds(targetIds); + candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets -Chart.prototype.ygrids = function (grids) { - var $$ = this.internal, config = $$.config; - if (! grids) { return config.grid_y_lines; } - config.grid_y_lines = grids; - $$.redrawWithoutRescale(); - return config.grid_y_lines; -}; -Chart.prototype.ygrids.add = function (grids) { - var $$ = this.internal; - return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : [])); -}; -Chart.prototype.ygrids.remove = function (params) { // TODO: multiple - var $$ = this.internal; - $$.removeGridLines(params, false); -}; + candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false); + if ($$.hasArcType()) { + $$.unexpandArc(targetIds); + } + if ($$.config.legend_show) { + $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); + $$.legend + .selectAll($$.selectorLegends(targetIds)) + .filter(function() { + return $$.d3.select(this).classed(CLASS.legendItemFocused) + }) + .classed(CLASS.legendItemFocused, false); + } -Chart.prototype.groups = function (groups) { - var $$ = this.internal, config = $$.config; - if (isUndefined(groups)) { return config.data_groups; } - config.data_groups = groups; - $$.redraw(); - return config.data_groups; + $$.focusedTargetIds = []; + $$.defocusedTargetIds = []; }; -Chart.prototype.legend = function () {}; -Chart.prototype.legend.show = function (targetIds) { - var $$ = this.internal; - $$.showLegend($$.mapToTargetIds(targetIds)); - $$.updateAndRedraw({withLegend: true}); -}; -Chart.prototype.legend.hide = function (targetIds) { - var $$ = this.internal; - $$.hideLegend($$.mapToTargetIds(targetIds)); - $$.updateAndRedraw({withLegend: false}); +Chart.prototype.xgrids = function(grids) { + var $$ = this.internal, + config = $$.config; + if (!grids) { + return config.grid_x_lines + } + config.grid_x_lines = grids; + $$.redrawWithoutRescale(); + return config.grid_x_lines }; - -Chart.prototype.load = function (args) { - var $$ = this.internal, config = $$.config; - // update xs if specified - if (args.xs) { - $$.addXs(args.xs); - } - // update names if exists - if ('names' in args) { - Chart.prototype.data.names.bind(this)(args.names); - } - // update classes if exists - if ('classes' in args) { - Object.keys(args.classes).forEach(function (id) { - config.data_classes[id] = args.classes[id]; - }); - } - // update categories if exists - if ('categories' in args && $$.isCategorized()) { - config.axis_x_categories = args.categories; - } - // update axes if exists - if ('axes' in args) { - Object.keys(args.axes).forEach(function (id) { - config.data_axes[id] = args.axes[id]; - }); - } - // update colors if exists - if ('colors' in args) { - Object.keys(args.colors).forEach(function (id) { - config.data_colors[id] = args.colors[id]; - }); - } - // use cache if exists - if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) { - $$.load($$.getCaches(args.cacheIds), args.done); - return; - } - // unload if needed - if (args.unload) { - // TODO: do not unload if target will load (included in url/rows/columns) - $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), function () { - $$.loadFromArgs(args); - }); - } else { - $$.loadFromArgs(args); - } +Chart.prototype.xgrids.add = function(grids) { + var $$ = this.internal; + return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : [])) +}; +Chart.prototype.xgrids.remove = function(params) { + // TODO: multiple + var $$ = this.internal; + $$.removeGridLines(params, true); }; -Chart.prototype.unload = function (args) { - var $$ = this.internal; - args = args || {}; - if (args instanceof Array) { - args = {ids: args}; - } else if (typeof args === 'string') { - args = {ids: [args]}; - } - $$.unload($$.mapToTargetIds(args.ids), function () { - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); - if (args.done) { args.done(); } - }); +Chart.prototype.ygrids = function(grids) { + var $$ = this.internal, + config = $$.config; + if (!grids) { + return config.grid_y_lines + } + config.grid_y_lines = grids; + $$.redrawWithoutRescale(); + return config.grid_y_lines +}; +Chart.prototype.ygrids.add = function(grids) { + var $$ = this.internal; + return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : [])) +}; +Chart.prototype.ygrids.remove = function(params) { + // TODO: multiple + var $$ = this.internal; + $$.removeGridLines(params, false); }; -Chart.prototype.pie = function() {}; +Chart.prototype.groups = function(groups) { + var $$ = this.internal, + config = $$.config; + if (isUndefined(groups)) { + return config.data_groups + } + config.data_groups = groups; + $$.redraw(); + return config.data_groups +}; -Chart.prototype.pie.padAngle = function (padAngle) { - if (padAngle === undefined) { - return this.internal.config.pie_padAngle; - } - this.internal.config.pie_padAngle = padAngle; - this.flush(); +Chart.prototype.legend = function() {}; +Chart.prototype.legend.show = function(targetIds) { + var $$ = this.internal; + $$.showLegend($$.mapToTargetIds(targetIds)); + $$.updateAndRedraw({ withLegend: true }); +}; +Chart.prototype.legend.hide = function(targetIds) { + var $$ = this.internal; + $$.hideLegend($$.mapToTargetIds(targetIds)); + $$.updateAndRedraw({ withLegend: false }); }; -Chart.prototype.regions = function (regions) { - var $$ = this.internal, config = $$.config; - if (!regions) { return config.regions; } - config.regions = regions; - $$.redrawWithoutRescale(); - return config.regions; +Chart.prototype.load = function(args) { + var $$ = this.internal, + config = $$.config; + // update xs if specified + if (args.xs) { + $$.addXs(args.xs); + } + // update names if exists + if ('names' in args) { + Chart.prototype.data.names.bind(this)(args.names); + } + // update classes if exists + if ('classes' in args) { + Object.keys(args.classes).forEach(function(id) { + config.data_classes[id] = args.classes[id]; + }); + } + // update categories if exists + if ('categories' in args && $$.isCategorized()) { + config.axis_x_categories = args.categories; + } + // update axes if exists + if ('axes' in args) { + Object.keys(args.axes).forEach(function(id) { + config.data_axes[id] = args.axes[id]; + }); + } + // update colors if exists + if ('colors' in args) { + Object.keys(args.colors).forEach(function(id) { + config.data_colors[id] = args.colors[id]; + }); + } + // use cache if exists + if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) { + $$.load($$.getCaches(args.cacheIds), args.done); + return + } + // unload if needed + if (args.unload) { + // TODO: do not unload if target will load (included in url/rows/columns) + $$.unload( + $$.mapToTargetIds(args.unload === true ? null : args.unload), + function() { + $$.loadFromArgs(args); + } + ); + } else { + $$.loadFromArgs(args); + } }; -Chart.prototype.regions.add = function (regions) { - var $$ = this.internal, config = $$.config; - if (!regions) { return config.regions; } - config.regions = config.regions.concat(regions); - $$.redrawWithoutRescale(); - return config.regions; + +Chart.prototype.unload = function(args) { + var $$ = this.internal; + args = args || {}; + if (args instanceof Array) { + args = { ids: args }; + } else if (typeof args === 'string') { + args = { ids: [args] }; + } + $$.unload($$.mapToTargetIds(args.ids), function() { + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); + if (args.done) { + args.done(); + } + }); }; -Chart.prototype.regions.remove = function (options) { - var $$ = this.internal, config = $$.config, - duration, classes, regions; - options = options || {}; - duration = getOption(options, "duration", config.transition_duration); - classes = getOption(options, "classes", [CLASS.region]); +Chart.prototype.pie = function() {}; - regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) { return '.' + c; })); - (duration ? regions.transition().duration(duration) : regions) - .style('opacity', 0) - .remove(); +Chart.prototype.pie.padAngle = function(padAngle) { + if (padAngle === undefined) { + return this.internal.config.pie_padAngle + } + this.internal.config.pie_padAngle = padAngle; + this.flush(); +}; - config.regions = config.regions.filter(function (region) { - var found = false; - if (!region['class']) { - return true; - } - region['class'].split(' ').forEach(function (c) { - if (classes.indexOf(c) >= 0) { found = true; } - }); - return !found; +Chart.prototype.regions = function(regions) { + var $$ = this.internal, + config = $$.config; + if (!regions) { + return config.regions + } + config.regions = regions; + $$.redrawWithoutRescale(); + return config.regions +}; +Chart.prototype.regions.add = function(regions) { + var $$ = this.internal, + config = $$.config; + if (!regions) { + return config.regions + } + config.regions = config.regions.concat(regions); + $$.redrawWithoutRescale(); + return config.regions +}; +Chart.prototype.regions.remove = function(options) { + var $$ = this.internal, + config = $$.config, + duration, + classes, + regions; + + options = options || {}; + duration = getOption(options, 'duration', config.transition_duration); + classes = getOption(options, 'classes', [CLASS.region]); + + regions = $$.main.select('.' + CLASS.regions).selectAll( + classes.map(function(c) { + return '.' + c + }) + ) + ;(duration ? regions.transition().duration(duration) : regions) + .style('opacity', 0) + .remove(); + + config.regions = config.regions.filter(function(region) { + var found = false; + if (!region['class']) { + return true + } + region['class'].split(' ').forEach(function(c) { + if (classes.indexOf(c) >= 0) { + found = true; + } }); - - return config.regions; -}; - -Chart.prototype.selected = function (targetId) { - var $$ = this.internal, d3 = $$.d3; - return $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape) - .filter(function () { return d3.select(this).classed(CLASS.SELECTED); }) - .nodes() - .map(function (d) { var data = d.__data__; return data.data ? data.data : data;}); -}; -Chart.prototype.select = function (ids, indices, resetOther) { - var $$ = this.internal, d3 = $$.d3, config = $$.config; - if (! config.data_selection_enabled) { return; } - $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { - var shape = d3.select(this), id = d.data ? d.data.id : d.id, - toggle = $$.getToggle(this, d).bind($$), - isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, - isTargetIndex = !indices || indices.indexOf(i) >= 0, - isSelected = shape.classed(CLASS.SELECTED); - // line/area selection not supported yet - if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { - return; - } - if (isTargetId && isTargetIndex) { - if (config.data_selection_isselectable(d) && !isSelected) { - toggle(true, shape.classed(CLASS.SELECTED, true), d, i); - } - } else if (isDefined(resetOther) && resetOther) { - if (isSelected) { - toggle(false, shape.classed(CLASS.SELECTED, false), d, i); - } - } + return !found + }); + + return config.regions +}; + +Chart.prototype.selected = function(targetId) { + var $$ = this.internal, + d3 = $$.d3; + return $$.main + .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)) + .selectAll('.' + CLASS.shape) + .filter(function() { + return d3.select(this).classed(CLASS.SELECTED) + }) + .nodes() + .map(function(d) { + var data = d.__data__; + return data.data ? data.data : data + }) +}; +Chart.prototype.select = function(ids, indices, resetOther) { + var $$ = this.internal, + d3 = $$.d3, + config = $$.config; + if (!config.data_selection_enabled) { + return + } + $$.main + .selectAll('.' + CLASS.shapes) + .selectAll('.' + CLASS.shape) + .each(function(d, i) { + var shape = d3.select(this), + id = d.data ? d.data.id : d.id, + toggle = $$.getToggle(this, d).bind($$), + isTargetId = + config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, + isTargetIndex = !indices || indices.indexOf(i) >= 0, + isSelected = shape.classed(CLASS.SELECTED); + // line/area selection not supported yet + if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { + return + } + if (isTargetId && isTargetIndex) { + if (config.data_selection_isselectable(d) && !isSelected) { + toggle(true, shape.classed(CLASS.SELECTED, true), d, i); + } + } else if (isDefined(resetOther) && resetOther) { + if (isSelected) { + toggle(false, shape.classed(CLASS.SELECTED, false), d, i); + } + } }); }; -Chart.prototype.unselect = function (ids, indices) { - var $$ = this.internal, d3 = $$.d3, config = $$.config; - if (! config.data_selection_enabled) { return; } - $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { - var shape = d3.select(this), id = d.data ? d.data.id : d.id, - toggle = $$.getToggle(this, d).bind($$), - isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, - isTargetIndex = !indices || indices.indexOf(i) >= 0, - isSelected = shape.classed(CLASS.SELECTED); - // line/area selection not supported yet - if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { - return; - } - if (isTargetId && isTargetIndex) { - if (config.data_selection_isselectable(d)) { - if (isSelected) { - toggle(false, shape.classed(CLASS.SELECTED, false), d, i); - } - } - } +Chart.prototype.unselect = function(ids, indices) { + var $$ = this.internal, + d3 = $$.d3, + config = $$.config; + if (!config.data_selection_enabled) { + return + } + $$.main + .selectAll('.' + CLASS.shapes) + .selectAll('.' + CLASS.shape) + .each(function(d, i) { + var shape = d3.select(this), + id = d.data ? d.data.id : d.id, + toggle = $$.getToggle(this, d).bind($$), + isTargetId = + config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, + isTargetIndex = !indices || indices.indexOf(i) >= 0, + isSelected = shape.classed(CLASS.SELECTED); + // line/area selection not supported yet + if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { + return + } + if (isTargetId && isTargetIndex) { + if (config.data_selection_isselectable(d)) { + if (isSelected) { + toggle(false, shape.classed(CLASS.SELECTED, false), d, i); + } + } + } }); }; -Chart.prototype.show = function (targetIds, options) { - var $$ = this.internal, targets; +Chart.prototype.show = function(targetIds, options) { + var $$ = this.internal, + targets; - targetIds = $$.mapToTargetIds(targetIds); - options = options || {}; + targetIds = $$.mapToTargetIds(targetIds); + options = options || {}; - $$.removeHiddenTargetIds(targetIds); - targets = $$.svg.selectAll($$.selectorTargets(targetIds)); + $$.removeHiddenTargetIds(targetIds); + targets = $$.svg.selectAll($$.selectorTargets(targetIds)); - targets.transition() - .style('display', isIE() ? 'block' : 'initial', 'important') - .style('opacity', 1, 'important') - .call($$.endall, function () { - targets.style('opacity', null).style('opacity', 1); - }); + targets + .transition() + .style('display', isIE() ? 'block' : 'initial', 'important') + .style('opacity', 1, 'important') + .call($$.endall, function() { + targets.style('opacity', null).style('opacity', 1); + }); - if (options.withLegend) { - $$.showLegend(targetIds); - } + if (options.withLegend) { + $$.showLegend(targetIds); + } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); }; -Chart.prototype.hide = function (targetIds, options) { - var $$ = this.internal, targets; +Chart.prototype.hide = function(targetIds, options) { + var $$ = this.internal, + targets; - targetIds = $$.mapToTargetIds(targetIds); - options = options || {}; + targetIds = $$.mapToTargetIds(targetIds); + options = options || {}; - $$.addHiddenTargetIds(targetIds); - targets = $$.svg.selectAll($$.selectorTargets(targetIds)); + $$.addHiddenTargetIds(targetIds); + targets = $$.svg.selectAll($$.selectorTargets(targetIds)); - targets.transition() - .style('opacity', 0, 'important') - .call($$.endall, function () { - targets.style('opacity', null).style('opacity', 0); - targets.style('display', 'none'); - }); + targets + .transition() + .style('opacity', 0, 'important') + .call($$.endall, function() { + targets.style('opacity', null).style('opacity', 0); + targets.style('display', 'none'); + }); - if (options.withLegend) { - $$.hideLegend(targetIds); - } + if (options.withLegend) { + $$.hideLegend(targetIds); + } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); }; -Chart.prototype.toggle = function (targetIds, options) { - var that = this, $$ = this.internal; - $$.mapToTargetIds(targetIds).forEach(function (targetId) { - $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options); - }); +Chart.prototype.toggle = function(targetIds, options) { + var that = this, + $$ = this.internal; + $$.mapToTargetIds(targetIds).forEach(function(targetId) { + $$.isTargetToShow(targetId) + ? that.hide(targetId, options) + : that.show(targetId, options); + }); }; -Chart.prototype.subchart = function () {}; +Chart.prototype.subchart = function() {}; Chart.prototype.subchart.isShown = function() { - const $$ = this.internal; + const $$ = this.internal; - return $$.config.subchart_show; + return $$.config.subchart_show }; -Chart.prototype.subchart.show = function () { - const $$ = this.internal; +Chart.prototype.subchart.show = function() { + const $$ = this.internal; - if ($$.config.subchart_show) { - return; - } + if ($$.config.subchart_show) { + return + } - $$.config.subchart_show = true; + $$.config.subchart_show = true; - // insert DOM - $$.initSubchart(); + // insert DOM + $$.initSubchart(); - // update dimensions with sub chart now visible - $$.updateDimension(); + // update dimensions with sub chart now visible + $$.updateDimension(); - // insert brush (depends on sizes previously updated) - $$.initSubchartBrush(); + // insert brush (depends on sizes previously updated) + $$.initSubchartBrush(); - // attach data - $$.updateTargetsForSubchart($$.getTargets()); + // attach data + $$.updateTargetsForSubchart($$.getTargets()); - // reset fade-in state - $$.mapToIds($$.data.targets).forEach(function(id) { - $$.withoutFadeIn[id] = false; - }); + // reset fade-in state + $$.mapToIds($$.data.targets).forEach(function(id) { + $$.withoutFadeIn[id] = false; + }); - // redraw chart ! - $$.updateAndRedraw(); + // redraw chart ! + $$.updateAndRedraw(); - // update visible targets ! - $$.showTargets(); + // update visible targets ! + $$.showTargets(); }; -Chart.prototype.subchart.hide = function () { - const $$ = this.internal; +Chart.prototype.subchart.hide = function() { + const $$ = this.internal; - if (!$$.config.subchart_show) { - return; - } + if (!$$.config.subchart_show) { + return + } - $$.config.subchart_show = false; + $$.config.subchart_show = false; - // remove DOM - $$.removeSubchart(); + // remove DOM + $$.removeSubchart(); - // re-render chart - $$.redraw(); + // re-render chart + $$.redraw(); }; -Chart.prototype.tooltip = function () {}; -Chart.prototype.tooltip.show = function (args) { - var $$ = this.internal, targets, data, mouse = {}; +Chart.prototype.tooltip = function() {}; +Chart.prototype.tooltip.show = function(args) { + var $$ = this.internal, + targets, + data, + mouse = {}; - // determine mouse position on the chart - if (args.mouse) { - mouse = args.mouse; - } - else { - // determine focus data - if (args.data) { - data = args.data; - } - else if (typeof args.x !== 'undefined') { - if (args.id) { - targets = $$.data.targets.filter(function(t){ return t.id === args.id; }); - } else { - targets = $$.data.targets; - } - data = $$.filterByX(targets, args.x).slice(0,1)[0]; - } - mouse = data ? $$.getMousePosition(data) : null; + // determine mouse position on the chart + if (args.mouse) { + mouse = args.mouse; + } else { + // determine focus data + if (args.data) { + data = args.data; + } else if (typeof args.x !== 'undefined') { + if (args.id) { + targets = $$.data.targets.filter(function(t) { + return t.id === args.id + }); + } else { + targets = $$.data.targets; + } + data = $$.filterByX(targets, args.x).slice(0, 1)[0]; } + mouse = data ? $$.getMousePosition(data) : null; + } - // emulate mouse events to show - $$.dispatchEvent('mousemove', mouse); - - $$.config.tooltip_onshow.call($$, data); -}; -Chart.prototype.tooltip.hide = function () { - // TODO: get target data by checking the state of focus - this.internal.dispatchEvent('mouseout', 0); + // emulate mouse events to show + $$.dispatchEvent('mousemove', mouse); - this.internal.config.tooltip_onhide.call(this); + $$.config.tooltip_onshow.call($$, data); }; +Chart.prototype.tooltip.hide = function() { + // TODO: get target data by checking the state of focus + this.internal.dispatchEvent('mouseout', 0); -Chart.prototype.transform = function (type, targetIds) { - var $$ = this.internal, - options = ['pie', 'donut'].indexOf(type) >= 0 ? {withTransform: true} : null; - $$.transformTo(targetIds, type, options); + this.internal.config.tooltip_onhide.call(this); }; -ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) { - var $$ = this, - withTransitionForAxis = !$$.hasArcType(), - options = optionsForRedraw || {withTransitionForAxis: withTransitionForAxis}; - options.withTransitionForTransform = false; - $$.transiting = false; - $$.setTargetType(targetIds, type); - $$.updateTargets($$.data.targets); // this is needed when transforming to arc - $$.updateAndRedraw(options); +Chart.prototype.transform = function(type, targetIds) { + var $$ = this.internal, + options = + ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null; + $$.transformTo(targetIds, type, options); }; -Chart.prototype.x = function (x) { - var $$ = this.internal; - if (arguments.length) { - $$.updateTargetX($$.data.targets, x); - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); - } - return $$.data.xs; +ChartInternal.prototype.transformTo = function( + targetIds, + type, + optionsForRedraw +) { + var $$ = this, + withTransitionForAxis = !$$.hasArcType(), + options = optionsForRedraw || { + withTransitionForAxis: withTransitionForAxis + }; + options.withTransitionForTransform = false; + $$.transiting = false; + $$.setTargetType(targetIds, type); + $$.updateTargets($$.data.targets); // this is needed when transforming to arc + $$.updateAndRedraw(options); +}; + +Chart.prototype.x = function(x) { + var $$ = this.internal; + if (arguments.length) { + $$.updateTargetX($$.data.targets, x); + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } + return $$.data.xs }; -Chart.prototype.xs = function (xs) { - var $$ = this.internal; - if (arguments.length) { - $$.updateTargetXs($$.data.targets, xs); - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); - } - return $$.data.xs; +Chart.prototype.xs = function(xs) { + var $$ = this.internal; + if (arguments.length) { + $$.updateTargetXs($$.data.targets, xs); + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } + return $$.data.xs }; -Chart.prototype.zoom = function (domain) { - var $$ = this.internal; - if (domain) { - if ($$.isTimeSeries()) { - domain = domain.map(function (x) { return $$.parseDate(x); }); - } - if ($$.config.subchart_show) { - $$.brush.selectionAsValue(domain, true); - } - else { - $$.updateXDomain(null, true, false, false, domain); - $$.redraw({withY: $$.config.zoom_rescale, withSubchart: false}); - } - $$.config.zoom_onzoom.call(this, $$.x.orgDomain()); - return domain; +Chart.prototype.zoom = function(domain) { + var $$ = this.internal; + if (domain) { + if ($$.isTimeSeries()) { + domain = domain.map(function(x) { + return $$.parseDate(x) + }); + } + if ($$.config.subchart_show) { + $$.brush.selectionAsValue(domain, true); } else { - return $$.x.domain(); + $$.updateXDomain(null, true, false, false, domain); + $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false }); } + $$.config.zoom_onzoom.call(this, $$.x.orgDomain()); + return domain + } else { + return $$.x.domain() + } }; -Chart.prototype.zoom.enable = function (enabled) { - var $$ = this.internal; - $$.config.zoom_enabled = enabled; - $$.updateAndRedraw(); +Chart.prototype.zoom.enable = function(enabled) { + var $$ = this.internal; + $$.config.zoom_enabled = enabled; + $$.updateAndRedraw(); +}; +Chart.prototype.unzoom = function() { + var $$ = this.internal; + if ($$.config.subchart_show) { + $$.brush.clear(); + } else { + $$.updateXDomain(null, true, false, false, $$.subX.domain()); + $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false }); + } }; -Chart.prototype.unzoom = function () { - var $$ = this.internal; - if ($$.config.subchart_show) { - $$.brush.clear(); - } - else { - $$.updateXDomain(null, true, false, false, $$.subX.domain()); - $$.redraw({withY: $$.config.zoom_rescale, withSubchart: false}); - } + +Chart.prototype.zoom.max = function(max) { + var $$ = this.internal, + config = $$.config, + d3 = $$.d3; + if (max === 0 || max) { + config.zoom_x_max = d3.max([$$.orgXDomain[1], max]); + } else { + return config.zoom_x_max + } }; -Chart.prototype.zoom.max = function (max) { - var $$ = this.internal, config = $$.config, d3 = $$.d3; - if (max === 0 || max) { - config.zoom_x_max = d3.max([$$.orgXDomain[1], max]); - } - else { - return config.zoom_x_max; - } +Chart.prototype.zoom.min = function(min) { + var $$ = this.internal, + config = $$.config, + d3 = $$.d3; + if (min === 0 || min) { + config.zoom_x_min = d3.min([$$.orgXDomain[0], min]); + } else { + return config.zoom_x_min + } }; -Chart.prototype.zoom.min = function (min) { - var $$ = this.internal, config = $$.config, d3 = $$.d3; - if (min === 0 || min) { - config.zoom_x_min = d3.min([$$.orgXDomain[0], min]); +Chart.prototype.zoom.range = function(range) { + if (arguments.length) { + if (isDefined(range.max)) { + this.domain.max(range.max); } - else { - return config.zoom_x_min; + if (isDefined(range.min)) { + this.domain.min(range.min); } -}; - -Chart.prototype.zoom.range = function (range) { - if (arguments.length) { - if (isDefined(range.max)) { this.domain.max(range.max); } - if (isDefined(range.min)) { this.domain.min(range.min); } - } else { - return { - max: this.domain.max(), - min: this.domain.min() - }; + } else { + return { + max: this.domain.max(), + min: this.domain.min() } + } }; -ChartInternal.prototype.initPie = function () { - var $$ = this, d3 = $$.d3; - $$.pie = d3.pie().padAngle(this.getPadAngle.bind(this)).value(function (d) { - return d.values.reduce(function (a, b) { return a + b.value; }, 0); +ChartInternal.prototype.initPie = function() { + var $$ = this, + d3 = $$.d3; + $$.pie = d3 + .pie() + .padAngle(this.getPadAngle.bind(this)) + .value(function(d) { + return d.values.reduce(function(a, b) { + return a + b.value + }, 0) }); - let orderFct = $$.getOrderFunction(); - - // we need to reverse the returned order if asc or desc to have the slice in expected order. - if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) { - let defaultSort = orderFct; - orderFct = (t1, t2) => defaultSort(t1, t2) * -1; - } + let orderFct = $$.getOrderFunction(); - $$.pie.sort(orderFct || null); -}; + // we need to reverse the returned order if asc or desc to have the slice in expected order. + if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) { + let defaultSort = orderFct; + orderFct = (t1, t2) => defaultSort(t1, t2) * -1; + } -ChartInternal.prototype.updateRadius = function () { - var $$ = this, config = $$.config, - w = config.gauge_width || config.donut_width, - gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth; - $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1); - $$.radius = $$.radiusExpanded * 0.95; - $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6; - $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0; - $$.gaugeArcWidth = w ? w : (gaugeArcWidth <= $$.radius - $$.innerRadius ? $$.radius - $$.innerRadius : (gaugeArcWidth <= $$.radius ? gaugeArcWidth : $$.radius)); + $$.pie.sort(orderFct || null); +}; + +ChartInternal.prototype.updateRadius = function() { + var $$ = this, + config = $$.config, + w = config.gauge_width || config.donut_width, + gaugeArcWidth = + $$.filterTargetsToShow($$.data.targets).length * + $$.config.gauge_arcs_minWidth; + $$.radiusExpanded = + (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1); + $$.radius = $$.radiusExpanded * 0.95; + $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6; + $$.innerRadius = + $$.hasType('donut') || $$.hasType('gauge') + ? $$.radius * $$.innerRadiusRatio + : 0; + $$.gaugeArcWidth = w + ? w + : gaugeArcWidth <= $$.radius - $$.innerRadius + ? $$.radius - $$.innerRadius + : gaugeArcWidth <= $$.radius + ? gaugeArcWidth + : $$.radius; }; ChartInternal.prototype.getPadAngle = function() { - if (this.hasType('pie')) { - return this.config.pie_padAngle || 0; - } else if (this.hasType('donut')) { - return this.config.donut_padAngle || 0; - } else { - return 0; - } + if (this.hasType('pie')) { + return this.config.pie_padAngle || 0 + } else if (this.hasType('donut')) { + return this.config.donut_padAngle || 0 + } else { + return 0 + } }; -ChartInternal.prototype.updateArc = function () { - var $$ = this; - $$.svgArc = $$.getSvgArc(); - $$.svgArcExpanded = $$.getSvgArcExpanded(); - $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98); +ChartInternal.prototype.updateArc = function() { + var $$ = this; + $$.svgArc = $$.getSvgArc(); + $$.svgArcExpanded = $$.getSvgArcExpanded(); + $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98); }; -ChartInternal.prototype.updateAngle = function (d) { - var $$ = this, config = $$.config, - found = false, index = 0, - gMin, gMax, gTic, gValue; +ChartInternal.prototype.updateAngle = function(d) { + var $$ = this, + config = $$.config, + found = false, + index = 0, + gMin, + gMax, + gTic, + gValue; - if (!config) { - return null; - } + if (!config) { + return null + } - $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) { - if (! found && t.data.id === d.data.id) { - found = true; - d = t; - d.index = index; - } - index++; - }); - if (isNaN(d.startAngle)) { - d.startAngle = 0; - } - if (isNaN(d.endAngle)) { - d.endAngle = d.startAngle; - } - if ($$.isGaugeType(d.data)) { - gMin = config.gauge_min; - gMax = config.gauge_max; - gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin); - gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : (gMax - gMin); - d.startAngle = config.gauge_startingAngle; - d.endAngle = d.startAngle + gTic * gValue; - } - return found ? d : null; -}; - -ChartInternal.prototype.getSvgArc = function () { - var $$ = this, hasGaugeType = $$.hasType('gauge'), - singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, - arc = $$.d3.arc().outerRadius(function(d) { - return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius; - }).innerRadius(function(d) { - return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius; - }), - newArc = function (d, withoutUpdate) { - var updated; - if (withoutUpdate) { return arc(d); } // for interpolate - updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; - }; - // TODO: extends all function - newArc.centroid = arc.centroid; - return newArc; -}; - -ChartInternal.prototype.getSvgArcExpanded = function (rate) { - rate = rate || 1; - var $$ = this, hasGaugeType = $$.hasType('gauge'), - singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, - expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100), - arc = $$.d3.arc().outerRadius(function(d){ - return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate; - }).innerRadius(function(d){ - return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius; - }); - return function (d) { - var updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; + $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function(t) { + if (!found && t.data.id === d.data.id) { + found = true; + d = t; + d.index = index; + } + index++; + }); + if (isNaN(d.startAngle)) { + d.startAngle = 0; + } + if (isNaN(d.endAngle)) { + d.endAngle = d.startAngle; + } + if ($$.isGaugeType(d.data)) { + gMin = config.gauge_min; + gMax = config.gauge_max; + gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin); + gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin; + d.startAngle = config.gauge_startingAngle; + d.endAngle = d.startAngle + gTic * gValue; + } + return found ? d : null +}; + +ChartInternal.prototype.getSvgArc = function() { + var $$ = this, + hasGaugeType = $$.hasType('gauge'), + singleArcWidth = + $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, + arc = $$.d3 + .arc() + .outerRadius(function(d) { + return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius + }) + .innerRadius(function(d) { + return hasGaugeType + ? $$.radius - singleArcWidth * (d.index + 1) + : $$.innerRadius + }), + newArc = function(d, withoutUpdate) { + var updated; + if (withoutUpdate) { + return arc(d) + } // for interpolate + updated = $$.updateAngle(d); + return updated ? arc(updated) : 'M 0 0' }; + // TODO: extends all function + newArc.centroid = arc.centroid; + return newArc +}; + +ChartInternal.prototype.getSvgArcExpanded = function(rate) { + rate = rate || 1; + var $$ = this, + hasGaugeType = $$.hasType('gauge'), + singleArcWidth = + $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, + expandWidth = Math.min( + $$.radiusExpanded * rate - $$.radius, + singleArcWidth * 0.8 - (1 - rate) * 100 + ), + arc = $$.d3 + .arc() + .outerRadius(function(d) { + return hasGaugeType + ? $$.radius - singleArcWidth * d.index + expandWidth + : $$.radiusExpanded * rate + }) + .innerRadius(function(d) { + return hasGaugeType + ? $$.radius - singleArcWidth * (d.index + 1) + : $$.innerRadius + }); + return function(d) { + var updated = $$.updateAngle(d); + return updated ? arc(updated) : 'M 0 0' + } }; -ChartInternal.prototype.getArc = function (d, withoutUpdate, force) { - return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0"; -}; - - -ChartInternal.prototype.transformForArcLabel = function (d) { - var $$ = this, config = $$.config, - updated = $$.updateAngle(d), c, x, y, h, ratio, translate = "", hasGauge = $$.hasType('gauge'); - if (updated && !hasGauge) { - c = this.svgArc.centroid(updated); - x = isNaN(c[0]) ? 0 : c[0]; - y = isNaN(c[1]) ? 0 : c[1]; - h = Math.sqrt(x * x + y * y); - if ($$.hasType('donut') && config.donut_label_ratio) { - ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio; - } else if ($$.hasType('pie') && config.pie_label_ratio) { - ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio; - } else { - ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0; - } - translate = "translate(" + (x * ratio) + ',' + (y * ratio) + ")"; - } - else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) { - var y1 = Math.sin(updated.endAngle - Math.PI / 2); - x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); - y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; - translate = "translate(" + x + ',' + y + ")"; - } - return translate; +ChartInternal.prototype.getArc = function(d, withoutUpdate, force) { + return force || this.isArcType(d.data) + ? this.svgArc(d, withoutUpdate) + : 'M 0 0' +}; + +ChartInternal.prototype.transformForArcLabel = function(d) { + var $$ = this, + config = $$.config, + updated = $$.updateAngle(d), + c, + x, + y, + h, + ratio, + translate = '', + hasGauge = $$.hasType('gauge'); + if (updated && !hasGauge) { + c = this.svgArc.centroid(updated); + x = isNaN(c[0]) ? 0 : c[0]; + y = isNaN(c[1]) ? 0 : c[1]; + h = Math.sqrt(x * x + y * y); + if ($$.hasType('donut') && config.donut_label_ratio) { + ratio = isFunction(config.donut_label_ratio) + ? config.donut_label_ratio(d, $$.radius, h) + : config.donut_label_ratio; + } else if ($$.hasType('pie') && config.pie_label_ratio) { + ratio = isFunction(config.pie_label_ratio) + ? config.pie_label_ratio(d, $$.radius, h) + : config.pie_label_ratio; + } else { + ratio = + $$.radius && h + ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * + $$.radius) / + h + : 0; + } + translate = 'translate(' + x * ratio + ',' + y * ratio + ')'; + } else if ( + updated && + hasGauge && + $$.filterTargetsToShow($$.data.targets).length > 1 + ) { + var y1 = Math.sin(updated.endAngle - Math.PI / 2); + x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); + y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; + translate = 'translate(' + x + ',' + y + ')'; + } + return translate }; /** * @deprecated Use `getRatio('arc', d)` instead. */ -ChartInternal.prototype.getArcRatio = function (d) { - return this.getRatio('arc', d); -}; - -ChartInternal.prototype.convertToArcData = function (d) { - return this.addName({ - id: d.data.id, - value: d.value, - ratio: this.getRatio('arc', d), - index: d.index - }); -}; - -ChartInternal.prototype.textForArcLabel = function (d) { - var $$ = this, - updated, value, ratio, id, format; - if (! $$.shouldShowArcLabel()) { return ""; } - updated = $$.updateAngle(d); - value = updated ? updated.value : null; - ratio = $$.getRatio('arc', updated); - id = d.data.id; - if (! $$.hasType('gauge') && ! $$.meetsArcLabelThreshold(ratio)) { return ""; } - format = $$.getArcLabelFormat(); - return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio); +ChartInternal.prototype.getArcRatio = function(d) { + return this.getRatio('arc', d) +}; + +ChartInternal.prototype.convertToArcData = function(d) { + return this.addName({ + id: d.data.id, + value: d.value, + ratio: this.getRatio('arc', d), + index: d.index + }) +}; + +ChartInternal.prototype.textForArcLabel = function(d) { + var $$ = this, + updated, + value, + ratio, + id, + format; + if (!$$.shouldShowArcLabel()) { + return '' + } + updated = $$.updateAngle(d); + value = updated ? updated.value : null; + ratio = $$.getRatio('arc', updated); + id = d.data.id; + if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) { + return '' + } + format = $$.getArcLabelFormat(); + return format + ? format(value, ratio, id) + : $$.defaultArcValueFormat(value, ratio) }; -ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) { - var $$ = this, - format = $$.getGaugeLabelExtents(); +ChartInternal.prototype.textForGaugeMinMax = function(value, isMax) { + var $$ = this, + format = $$.getGaugeLabelExtents(); - return format ? format(value, isMax) : value; + return format ? format(value, isMax) : value }; -ChartInternal.prototype.expandArc = function (targetIds) { - var $$ = this, interval; - - // MEMO: avoid to cancel transition - if ($$.transiting) { - interval = window.setInterval(function () { - if (!$$.transiting) { - window.clearInterval(interval); - if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) { - $$.expandArc(targetIds); - } - } - }, 10); - return; - } +ChartInternal.prototype.expandArc = function(targetIds) { + var $$ = this, + interval; - targetIds = $$.mapToTargetIds(targetIds); + // MEMO: avoid to cancel transition + if ($$.transiting) { + interval = window.setInterval(function() { + if (!$$.transiting) { + window.clearInterval(interval); + if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) { + $$.expandArc(targetIds); + } + } + }, 10); + return + } - $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) { - if (! $$.shouldExpand(d.data.id)) { return; } - $$.d3.select(this).selectAll('path') - .transition().duration($$.expandDuration(d.data.id)) - .attr("d", $$.svgArcExpanded) - .transition().duration($$.expandDuration(d.data.id) * 2) - .attr("d", $$.svgArcExpandedSub) - .each(function (d) { - if ($$.isDonutType(d.data)) ; - }); + targetIds = $$.mapToTargetIds(targetIds); + + $$.svg + .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)) + .each(function(d) { + if (!$$.shouldExpand(d.data.id)) { + return + } + $$.d3 + .select(this) + .selectAll('path') + .transition() + .duration($$.expandDuration(d.data.id)) + .attr('d', $$.svgArcExpanded) + .transition() + .duration($$.expandDuration(d.data.id) * 2) + .attr('d', $$.svgArcExpandedSub) + .each(function(d) { + if ($$.isDonutType(d.data)) ; + }); }); }; -ChartInternal.prototype.unexpandArc = function (targetIds) { - var $$ = this; +ChartInternal.prototype.unexpandArc = function(targetIds) { + var $$ = this; - if ($$.transiting) { return; } - - targetIds = $$.mapToTargetIds(targetIds); + if ($$.transiting) { + return + } - $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path') - .transition().duration(function(d) { - return $$.expandDuration(d.data.id); - }) - .attr("d", $$.svgArc); - $$.svg.selectAll('.' + CLASS.arc); + targetIds = $$.mapToTargetIds(targetIds); + + $$.svg + .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)) + .selectAll('path') + .transition() + .duration(function(d) { + return $$.expandDuration(d.data.id) + }) + .attr('d', $$.svgArc); + $$.svg.selectAll('.' + CLASS.arc); +}; + +ChartInternal.prototype.expandDuration = function(id) { + var $$ = this, + config = $$.config; + + if ($$.isDonutType(id)) { + return config.donut_expand_duration + } else if ($$.isGaugeType(id)) { + return config.gauge_expand_duration + } else if ($$.isPieType(id)) { + return config.pie_expand_duration + } else { + return 50 + } }; -ChartInternal.prototype.expandDuration = function (id) { - var $$ = this, config = $$.config; - - if ($$.isDonutType(id)) { - return config.donut_expand_duration; - } else if ($$.isGaugeType(id)) { - return config.gauge_expand_duration; - } else if ($$.isPieType(id)) { - return config.pie_expand_duration; +ChartInternal.prototype.shouldExpand = function(id) { + var $$ = this, + config = $$.config; + return ( + ($$.isDonutType(id) && config.donut_expand) || + ($$.isGaugeType(id) && config.gauge_expand) || + ($$.isPieType(id) && config.pie_expand) + ) +}; + +ChartInternal.prototype.shouldShowArcLabel = function() { + var $$ = this, + config = $$.config, + shouldShow = true; + if ($$.hasType('donut')) { + shouldShow = config.donut_label_show; + } else if ($$.hasType('pie')) { + shouldShow = config.pie_label_show; + } + // when gauge, always true + return shouldShow +}; + +ChartInternal.prototype.meetsArcLabelThreshold = function(ratio) { + var $$ = this, + config = $$.config, + threshold = $$.hasType('donut') + ? config.donut_label_threshold + : config.pie_label_threshold; + return ratio >= threshold +}; + +ChartInternal.prototype.getArcLabelFormat = function() { + var $$ = this, + config = $$.config, + format = config.pie_label_format; + if ($$.hasType('gauge')) { + format = config.gauge_label_format; + } else if ($$.hasType('donut')) { + format = config.donut_label_format; + } + return format +}; + +ChartInternal.prototype.getGaugeLabelExtents = function() { + var $$ = this, + config = $$.config; + return config.gauge_label_extents +}; + +ChartInternal.prototype.getArcTitle = function() { + var $$ = this; + return $$.hasType('donut') ? $$.config.donut_title : '' +}; + +ChartInternal.prototype.updateTargetsForArc = function(targets) { + var $$ = this, + main = $$.main, + mainPies, + mainPieEnter, + classChartArc = $$.classChartArc.bind($$), + classArcs = $$.classArcs.bind($$), + classFocus = $$.classFocus.bind($$); + mainPies = main + .select('.' + CLASS.chartArcs) + .selectAll('.' + CLASS.chartArc) + .data($$.pie(targets)) + .attr('class', function(d) { + return classChartArc(d) + classFocus(d.data) + }); + mainPieEnter = mainPies + .enter() + .append('g') + .attr('class', classChartArc); + mainPieEnter.append('g').attr('class', classArcs); + mainPieEnter + .append('text') + .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em') + .style('opacity', 0) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + // MEMO: can not keep same color..., but not bad to update color in redraw + //mainPieUpdate.exit().remove(); +}; + +ChartInternal.prototype.initArc = function() { + var $$ = this; + $$.arcs = $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartArcs) + .attr('transform', $$.getTranslate('arc')); + $$.arcs + .append('text') + .attr('class', CLASS.chartArcsTitle) + .style('text-anchor', 'middle') + .text($$.getArcTitle()); +}; + +ChartInternal.prototype.redrawArc = function( + duration, + durationForExit, + withTransform +) { + var $$ = this, + d3 = $$.d3, + config = $$.config, + main = $$.main, + arcs, + mainArc, + arcLabelLines, + mainArcLabelLine, + hasGaugeType = $$.hasType('gauge'); + arcs = main + .selectAll('.' + CLASS.arcs) + .selectAll('.' + CLASS.arc) + .data($$.arcData.bind($$)); + mainArc = arcs + .enter() + .append('path') + .attr('class', $$.classArc.bind($$)) + .style('fill', function(d) { + return $$.color(d.data) + }) + .style('cursor', function(d) { + return config.interaction_enabled && config.data_selection_isselectable(d) + ? 'pointer' + : null + }) + .each(function(d) { + if ($$.isGaugeType(d.data)) { + d.startAngle = d.endAngle = config.gauge_startingAngle; + } + this._current = d; + }) + .merge(arcs); + if (hasGaugeType) { + arcLabelLines = main + .selectAll('.' + CLASS.arcs) + .selectAll('.' + CLASS.arcLabelLine) + .data($$.arcData.bind($$)); + mainArcLabelLine = arcLabelLines + .enter() + .append('rect') + .attr('class', function(d) { + return ( + CLASS.arcLabelLine + + ' ' + + CLASS.target + + ' ' + + CLASS.target + + '-' + + d.data.id + ) + }) + .merge(arcLabelLines); + + if ($$.filterTargetsToShow($$.data.targets).length === 1) { + mainArcLabelLine.style('display', 'none'); } else { - return 50; - } - -}; - -ChartInternal.prototype.shouldExpand = function (id) { - var $$ = this, config = $$.config; - return ($$.isDonutType(id) && config.donut_expand) || - ($$.isGaugeType(id) && config.gauge_expand) || - ($$.isPieType(id) && config.pie_expand); -}; - -ChartInternal.prototype.shouldShowArcLabel = function () { - var $$ = this, config = $$.config, shouldShow = true; - if ($$.hasType('donut')) { - shouldShow = config.donut_label_show; - } else if ($$.hasType('pie')) { - shouldShow = config.pie_label_show; - } - // when gauge, always true - return shouldShow; -}; - -ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) { - var $$ = this, config = $$.config, - threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold; - return ratio >= threshold; -}; - -ChartInternal.prototype.getArcLabelFormat = function () { - var $$ = this, config = $$.config, - format = config.pie_label_format; - if ($$.hasType('gauge')) { - format = config.gauge_label_format; - } else if ($$.hasType('donut')) { - format = config.donut_label_format; - } - return format; -}; - -ChartInternal.prototype.getGaugeLabelExtents = function () { - var $$ = this, config = $$.config; - return config.gauge_label_extents; -}; - -ChartInternal.prototype.getArcTitle = function () { - var $$ = this; - return $$.hasType('donut') ? $$.config.donut_title : ""; -}; - -ChartInternal.prototype.updateTargetsForArc = function (targets) { - var $$ = this, main = $$.main, - mainPies, mainPieEnter, - classChartArc = $$.classChartArc.bind($$), - classArcs = $$.classArcs.bind($$), - classFocus = $$.classFocus.bind($$); - mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc) - .data($$.pie(targets)) - .attr("class", function (d) { return classChartArc(d) + classFocus(d.data); }); - mainPieEnter = mainPies.enter().append("g") - .attr("class", classChartArc); - mainPieEnter.append('g') - .attr('class', classArcs); - mainPieEnter.append("text") - .attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em") - .style("opacity", 0) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - // MEMO: can not keep same color..., but not bad to update color in redraw - //mainPieUpdate.exit().remove(); -}; - -ChartInternal.prototype.initArc = function () { - var $$ = this; - $$.arcs = $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartArcs) - .attr("transform", $$.getTranslate('arc')); - $$.arcs.append('text') - .attr('class', CLASS.chartArcsTitle) - .style("text-anchor", "middle") - .text($$.getArcTitle()); -}; - -ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) { - var $$ = this, d3 = $$.d3, config = $$.config, main = $$.main, - arcs, mainArc, - arcLabelLines, mainArcLabelLine, - hasGaugeType = $$.hasType('gauge'); - arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc) - .data($$.arcData.bind($$)); - mainArc = arcs.enter().append('path') - .attr("class", $$.classArc.bind($$)) - .style("fill", function (d) { return $$.color(d.data); }) - .style("cursor", function (d) { return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null; }) - .each(function (d) { - if ($$.isGaugeType(d.data)) { - d.startAngle = d.endAngle = config.gauge_startingAngle; - } - this._current = d; + mainArcLabelLine + .style('fill', function(d) { + return $$.levelColor + ? $$.levelColor( + d.data.values.reduce(function(total, item) { + return total + item.value + }, 0) + ) + : $$.color(d.data) }) - .merge(arcs); - if (hasGaugeType) { - arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine) - .data($$.arcData.bind($$)); - mainArcLabelLine = arcLabelLines.enter().append('rect') - .attr("class", function (d) { return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id; }) - .merge(arcLabelLines); - - if ($$.filterTargetsToShow($$.data.targets).length === 1) { - mainArcLabelLine.style("display", "none"); - } - else { - mainArcLabelLine - .style("fill", function (d) { - return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data); - }) - .style("display", config.gauge_labelLine_show ? "" : "none") - .each(function (d) { - var lineLength = 0, lineThickness = 2, x = 0, y = 0, transform = ""; - if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { - var updated = $$.updateAngle(d), - innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1), - lineAngle = updated.endAngle - Math.PI / 2, - arcInnerRadius = $$.radius - innerLineLength, - linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : (1 / arcInnerRadius)); - lineLength = $$.radiusExpanded - $$.radius + innerLineLength; - x = Math.cos(linePositioningAngle) * arcInnerRadius; - y = Math.sin(linePositioningAngle) * arcInnerRadius; - transform = "rotate(" + (lineAngle * 180 / Math.PI) + ", " + x + ", " + y + ")"; - } - d3.select(this) - .attr('x', x) - .attr('y', y) - .attr('width', lineLength) - .attr('height', lineThickness) - .attr('transform', transform) - .style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0"); - }); - } + .style('display', config.gauge_labelLine_show ? '' : 'none') + .each(function(d) { + var lineLength = 0, + lineThickness = 2, + x = 0, + y = 0, + transform = ''; + if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { + var updated = $$.updateAngle(d), + innerLineLength = + ($$.gaugeArcWidth / + $$.filterTargetsToShow($$.data.targets).length) * + (updated.index + 1), + lineAngle = updated.endAngle - Math.PI / 2, + arcInnerRadius = $$.radius - innerLineLength, + linePositioningAngle = + lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius); + lineLength = $$.radiusExpanded - $$.radius + innerLineLength; + x = Math.cos(linePositioningAngle) * arcInnerRadius; + y = Math.sin(linePositioningAngle) * arcInnerRadius; + transform = + 'rotate(' + + (lineAngle * 180) / Math.PI + + ', ' + + x + + ', ' + + y + + ')'; + } + d3.select(this) + .attr('x', x) + .attr('y', y) + .attr('width', lineLength) + .attr('height', lineThickness) + .attr('transform', transform) + .style( + 'stroke-dasharray', + '0, ' + (lineLength + lineThickness) + ', 0' + ); + }); } - mainArc - .attr("transform", function (d) { return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : ""; }) - .on('mouseover', config.interaction_enabled ? function (d) { + } + mainArc + .attr('transform', function(d) { + return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : '' + }) + .on( + 'mouseover', + config.interaction_enabled + ? function(d) { var updated, arcData; - if ($$.transiting) { // skip while transiting - return; + if ($$.transiting) { + // skip while transiting + return } updated = $$.updateAngle(d); if (updated) { - arcData = $$.convertToArcData(updated); - // transitions - $$.expandArc(updated.data.id); - $$.api.focus(updated.data.id); - $$.toggleFocusLegend(updated.data.id, true); - $$.config.data_onmouseover(arcData, this); + arcData = $$.convertToArcData(updated); + // transitions + $$.expandArc(updated.data.id); + $$.api.focus(updated.data.id); + $$.toggleFocusLegend(updated.data.id, true); + $$.config.data_onmouseover(arcData, this); } - } : null) - .on('mousemove', config.interaction_enabled ? function (d) { - var updated = $$.updateAngle(d), arcData, selectedData; + } + : null + ) + .on( + 'mousemove', + config.interaction_enabled + ? function(d) { + var updated = $$.updateAngle(d), + arcData, + selectedData; if (updated) { - arcData = $$.convertToArcData(updated), - selectedData = [arcData]; - $$.showTooltip(selectedData, this); +(arcData = $$.convertToArcData(updated)), + (selectedData = [arcData]); + $$.showTooltip(selectedData, this); } - } : null) - .on('mouseout', config.interaction_enabled ? function (d) { + } + : null + ) + .on( + 'mouseout', + config.interaction_enabled + ? function(d) { var updated, arcData; - if ($$.transiting) { // skip while transiting - return; + if ($$.transiting) { + // skip while transiting + return } updated = $$.updateAngle(d); if (updated) { - arcData = $$.convertToArcData(updated); - // transitions - $$.unexpandArc(updated.data.id); - $$.api.revert(); - $$.revertLegend(); - $$.hideTooltip(); - $$.config.data_onmouseout(arcData, this); + arcData = $$.convertToArcData(updated); + // transitions + $$.unexpandArc(updated.data.id); + $$.api.revert(); + $$.revertLegend(); + $$.hideTooltip(); + $$.config.data_onmouseout(arcData, this); } - } : null) - .on('click', config.interaction_enabled ? function (d, i) { - var updated = $$.updateAngle(d), arcData; + } + : null + ) + .on( + 'click', + config.interaction_enabled + ? function(d, i) { + var updated = $$.updateAngle(d), + arcData; if (updated) { - arcData = $$.convertToArcData(updated); - if ($$.toggleShape) { - $$.toggleShape(this, arcData, i); - } - $$.config.data_onclick.call($$.api, arcData, this); - } - } : null) - .each(function () { $$.transiting = true; }) - .transition().duration(duration) - .attrTween("d", function (d) { - var updated = $$.updateAngle(d), interpolate; - if (! updated) { - return function () { return "M 0 0"; }; - } - // if (this._current === d) { - // this._current = { - // startAngle: Math.PI*2, - // endAngle: Math.PI*2, - // }; - // } - if (isNaN(this._current.startAngle)) { - this._current.startAngle = 0; - } - if (isNaN(this._current.endAngle)) { - this._current.endAngle = this._current.startAngle; + arcData = $$.convertToArcData(updated); + if ($$.toggleShape) { + $$.toggleShape(this, arcData, i); + } + $$.config.data_onclick.call($$.api, arcData, this); } - interpolate = d3.interpolate(this._current, updated); - this._current = interpolate(0); - return function (t) { - // prevents crashing the charts once in transition and chart.destroy() has been called - if ($$.config === null) { - return "M 0 0"; - } - var interpolated = interpolate(t); - interpolated.data = d.data; // data.id will be updated by interporator - return $$.getArc(interpolated, true); - }; - }) - .attr("transform", withTransform ? "scale(1)" : "") - .style("fill", function (d) { - return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data.id); - }) // Where gauge reading color would receive customization. - .call($$.endall, function () { - $$.transiting = false; - }); - arcs.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - main.selectAll('.' + CLASS.chartArc).select('text') - .style("opacity", 0) - .attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; }) - .text($$.textForArcLabel.bind($$)) - .attr("transform", $$.transformForArcLabel.bind($$)) - .style('font-size', function (d) { return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : ''; }) - .transition().duration(duration) - .style("opacity", function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; }); - main.select('.' + CLASS.chartArcsTitle) - .style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0); - - if (hasGaugeType) { - let index = 0; - const backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets); - - backgroundArc - .enter() - .append("path") - .attr("class", (d, i) => CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground +'-'+ i) - .merge(backgroundArc) - .attr("d", d1 => { - if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { return "M 0 0"; } - - var d = { - data: [{value: config.gauge_max}], - startAngle: config.gauge_startingAngle, - endAngle: -1 * config.gauge_startingAngle * (config.gauge_fullCircle ? Math.PI : 1), - index: index++ - }; - return $$.getArc(d, true, true); - }); - - backgroundArc - .exit() - .remove(); - - $$.arcs.select('.' + CLASS.chartArcsGaugeUnit) - .attr("dy", ".75em") - .text(config.gauge_label_show ? config.gauge_units : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMin) - .attr("dx", -1 * ($$.innerRadius + (($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2))) + "px") - .attr("dy", "1.2em") - .text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMax) - .attr("dx", $$.innerRadius + (($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px") - .attr("dy", "1.2em") - .text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); - } -}; -ChartInternal.prototype.initGauge = function () { - var arcs = this.arcs; - if (this.hasType('gauge')) { - arcs.append('g') - .attr("class", CLASS.chartArcsBackground); - arcs.append("text") - .attr("class", CLASS.chartArcsGaugeUnit) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - arcs.append("text") - .attr("class", CLASS.chartArcsGaugeMin) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - arcs.append("text") - .attr("class", CLASS.chartArcsGaugeMax) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - } -}; -ChartInternal.prototype.getGaugeLabelHeight = function () { - return this.config.gauge_label_show ? 20 : 0; + } + : null + ) + .each(function() { + $$.transiting = true; + }) + .transition() + .duration(duration) + .attrTween('d', function(d) { + var updated = $$.updateAngle(d), + interpolate; + if (!updated) { + return function() { + return 'M 0 0' + } + } + // if (this._current === d) { + // this._current = { + // startAngle: Math.PI*2, + // endAngle: Math.PI*2, + // }; + // } + if (isNaN(this._current.startAngle)) { + this._current.startAngle = 0; + } + if (isNaN(this._current.endAngle)) { + this._current.endAngle = this._current.startAngle; + } + interpolate = d3.interpolate(this._current, updated); + this._current = interpolate(0); + return function(t) { + // prevents crashing the charts once in transition and chart.destroy() has been called + if ($$.config === null) { + return 'M 0 0' + } + var interpolated = interpolate(t); + interpolated.data = d.data; // data.id will be updated by interporator + return $$.getArc(interpolated, true) + } + }) + .attr('transform', withTransform ? 'scale(1)' : '') + .style('fill', function(d) { + return $$.levelColor + ? $$.levelColor( + d.data.values.reduce(function(total, item) { + return total + item.value + }, 0) + ) + : $$.color(d.data.id) + }) // Where gauge reading color would receive customization. + .call($$.endall, function() { + $$.transiting = false; + }); + arcs + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + main + .selectAll('.' + CLASS.chartArc) + .select('text') + .style('opacity', 0) + .attr('class', function(d) { + return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '' + }) + .text($$.textForArcLabel.bind($$)) + .attr('transform', $$.transformForArcLabel.bind($$)) + .style('font-size', function(d) { + return $$.isGaugeType(d.data) && + $$.filterTargetsToShow($$.data.targets).length === 1 + ? Math.round($$.radius / 5) + 'px' + : '' + }) + .transition() + .duration(duration) + .style('opacity', function(d) { + return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0 + }); + main + .select('.' + CLASS.chartArcsTitle) + .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0); + + if (hasGaugeType) { + let index = 0; + const backgroundArc = $$.arcs + .select('g.' + CLASS.chartArcsBackground) + .selectAll('path.' + CLASS.chartArcsBackground) + .data($$.data.targets); + + backgroundArc + .enter() + .append('path') + .attr( + 'class', + (d, i) => + CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i + ) + .merge(backgroundArc) + .attr('d', d1 => { + if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { + return 'M 0 0' + } + + var d = { + data: [{ value: config.gauge_max }], + startAngle: config.gauge_startingAngle, + endAngle: + -1 * + config.gauge_startingAngle * + (config.gauge_fullCircle ? Math.PI : 1), + index: index++ + }; + return $$.getArc(d, true, true) + }); + + backgroundArc.exit().remove(); + + $$.arcs + .select('.' + CLASS.chartArcsGaugeUnit) + .attr('dy', '.75em') + .text(config.gauge_label_show ? config.gauge_units : ''); + $$.arcs + .select('.' + CLASS.chartArcsGaugeMin) + .attr( + 'dx', + -1 * + ($$.innerRadius + + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + + 'px' + ) + .attr('dy', '1.2em') + .text( + config.gauge_label_show + ? $$.textForGaugeMinMax(config.gauge_min, false) + : '' + ); + $$.arcs + .select('.' + CLASS.chartArcsGaugeMax) + .attr( + 'dx', + $$.innerRadius + + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + + 'px' + ) + .attr('dy', '1.2em') + .text( + config.gauge_label_show + ? $$.textForGaugeMinMax(config.gauge_max, true) + : '' + ); + } +}; +ChartInternal.prototype.initGauge = function() { + var arcs = this.arcs; + if (this.hasType('gauge')) { + arcs.append('g').attr('class', CLASS.chartArcsBackground); + arcs + .append('text') + .attr('class', CLASS.chartArcsGaugeUnit) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + arcs + .append('text') + .attr('class', CLASS.chartArcsGaugeMin) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + arcs + .append('text') + .attr('class', CLASS.chartArcsGaugeMax) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + } +}; +ChartInternal.prototype.getGaugeLabelHeight = function() { + return this.config.gauge_label_show ? 20 : 0 }; /** @@ -5484,8 +7096,8 @@ ChartInternal.prototype.getGaugeLabelHeight = function () { * @param key * @param value */ -ChartInternal.prototype.addToCache = function (key, value) { - this.cache[`$${key}`] = value; +ChartInternal.prototype.addToCache = function(key, value) { + this.cache[`$${key}`] = value; }; /** @@ -5494,614 +7106,688 @@ ChartInternal.prototype.addToCache = function (key, value) { * @param key * @return {*} */ -ChartInternal.prototype.getFromCache = function (key) { - return this.cache[`$${key}`]; +ChartInternal.prototype.getFromCache = function(key) { + return this.cache[`$${key}`] }; /** * Reset cached data */ ChartInternal.prototype.resetCache = function() { - Object.keys(this.cache) - .filter((key) => /^\$/.test(key)) - .forEach((key) => { - delete this.cache[key]; - }); + Object.keys(this.cache) + .filter(key => /^\$/.test(key)) + .forEach(key => { + delete this.cache[key]; + }); }; // Old API that stores Targets -ChartInternal.prototype.hasCaches = function (ids) { - for (var i = 0; i < ids.length; i++) { - if (! (ids[i] in this.cache)) { return false; } +ChartInternal.prototype.hasCaches = function(ids) { + for (var i = 0; i < ids.length; i++) { + if (!(ids[i] in this.cache)) { + return false } - return true; + } + return true }; -ChartInternal.prototype.addCache = function (id, target) { - this.cache[id] = this.cloneTarget(target); +ChartInternal.prototype.addCache = function(id, target) { + this.cache[id] = this.cloneTarget(target); }; -ChartInternal.prototype.getCaches = function (ids) { - var targets = [], i; - for (i = 0; i < ids.length; i++) { - if (ids[i] in this.cache) { targets.push(this.cloneTarget(this.cache[ids[i]])); } +ChartInternal.prototype.getCaches = function(ids) { + var targets = [], + i; + for (i = 0; i < ids.length; i++) { + if (ids[i] in this.cache) { + targets.push(this.cloneTarget(this.cache[ids[i]])); } - return targets; + } + return targets }; -ChartInternal.prototype.categoryName = function (i) { - var config = this.config; - return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i; +ChartInternal.prototype.categoryName = function(i) { + var config = this.config; + return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i }; -ChartInternal.prototype.generateTargetClass = function (targetId) { - return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : ''; -}; -ChartInternal.prototype.generateClass = function (prefix, targetId) { - return " " + prefix + " " + prefix + this.generateTargetClass(targetId); -}; -ChartInternal.prototype.classText = function (d) { - return this.generateClass(CLASS.text, d.index); -}; -ChartInternal.prototype.classTexts = function (d) { - return this.generateClass(CLASS.texts, d.id); -}; -ChartInternal.prototype.classShape = function (d) { - return this.generateClass(CLASS.shape, d.index); -}; -ChartInternal.prototype.classShapes = function (d) { - return this.generateClass(CLASS.shapes, d.id); -}; -ChartInternal.prototype.classLine = function (d) { - return this.classShape(d) + this.generateClass(CLASS.line, d.id); +ChartInternal.prototype.generateTargetClass = function(targetId) { + return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : '' }; -ChartInternal.prototype.classLines = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.lines, d.id); +ChartInternal.prototype.generateClass = function(prefix, targetId) { + return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId) }; -ChartInternal.prototype.classCircle = function (d) { - return this.classShape(d) + this.generateClass(CLASS.circle, d.index); +ChartInternal.prototype.classText = function(d) { + return this.generateClass(CLASS.text, d.index) }; -ChartInternal.prototype.classCircles = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.circles, d.id); +ChartInternal.prototype.classTexts = function(d) { + return this.generateClass(CLASS.texts, d.id) }; -ChartInternal.prototype.classBar = function (d) { - return this.classShape(d) + this.generateClass(CLASS.bar, d.index); +ChartInternal.prototype.classShape = function(d) { + return this.generateClass(CLASS.shape, d.index) }; -ChartInternal.prototype.classBars = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.bars, d.id); +ChartInternal.prototype.classShapes = function(d) { + return this.generateClass(CLASS.shapes, d.id) }; -ChartInternal.prototype.classArc = function (d) { - return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id); -}; -ChartInternal.prototype.classArcs = function (d) { - return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id); -}; -ChartInternal.prototype.classArea = function (d) { - return this.classShape(d) + this.generateClass(CLASS.area, d.id); -}; -ChartInternal.prototype.classAreas = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.areas, d.id); -}; -ChartInternal.prototype.classRegion = function (d, i) { - return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : ''); -}; -ChartInternal.prototype.classEvent = function (d) { - return this.generateClass(CLASS.eventRect, d.index); -}; -ChartInternal.prototype.classTarget = function (id) { - var $$ = this; - var additionalClassSuffix = $$.config.data_classes[id], additionalClass = ''; - if (additionalClassSuffix) { - additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix; - } - return $$.generateClass(CLASS.target, id) + additionalClass; -}; -ChartInternal.prototype.classFocus = function (d) { - return this.classFocused(d) + this.classDefocused(d); -}; -ChartInternal.prototype.classFocused = function (d) { - return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : ''); -}; -ChartInternal.prototype.classDefocused = function (d) { - return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : ''); -}; -ChartInternal.prototype.classChartText = function (d) { - return CLASS.chartText + this.classTarget(d.id); -}; -ChartInternal.prototype.classChartLine = function (d) { - return CLASS.chartLine + this.classTarget(d.id); -}; -ChartInternal.prototype.classChartBar = function (d) { - return CLASS.chartBar + this.classTarget(d.id); -}; -ChartInternal.prototype.classChartArc = function (d) { - return CLASS.chartArc + this.classTarget(d.data.id); -}; -ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) { - const targetClass = this.generateTargetClass(targetId); - if (window.CSS && window.CSS.escape) { - return window.CSS.escape(targetClass); - } - - // fallback on imperfect method for old browsers (does not handles unicode) - return targetClass.replace(/([?!@#$%^&*()=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1'); +ChartInternal.prototype.classLine = function(d) { + return this.classShape(d) + this.generateClass(CLASS.line, d.id) }; -ChartInternal.prototype.selectorTarget = function (id, prefix) { - return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id); +ChartInternal.prototype.classLines = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.lines, d.id) }; -ChartInternal.prototype.selectorTargets = function (ids, prefix) { - var $$ = this; - ids = ids || []; - return ids.length ? ids.map(function (id) { return $$.selectorTarget(id, prefix); }) : null; +ChartInternal.prototype.classCircle = function(d) { + return this.classShape(d) + this.generateClass(CLASS.circle, d.index) }; -ChartInternal.prototype.selectorLegend = function (id) { - return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id); +ChartInternal.prototype.classCircles = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.circles, d.id) }; -ChartInternal.prototype.selectorLegends = function (ids) { - var $$ = this; - return ids && ids.length ? ids.map(function (id) { return $$.selectorLegend(id); }) : null; +ChartInternal.prototype.classBar = function(d) { + return this.classShape(d) + this.generateClass(CLASS.bar, d.index) }; - -ChartInternal.prototype.getClipPath = function (id) { - return "url(" + (isIE(9) ? "" : document.URL.split('#')[0]) + "#" + id + ")"; +ChartInternal.prototype.classBars = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.bars, d.id) }; -ChartInternal.prototype.appendClip = function (parent, id) { - return parent.append("clipPath").attr("id", id).append("rect"); +ChartInternal.prototype.classArc = function(d) { + return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id) }; -ChartInternal.prototype.getAxisClipX = function (forHorizontal) { - // axis line width + padding for left - var left = Math.max(30, this.margin.left); - return forHorizontal ? -(1 + left) : -(left - 1); +ChartInternal.prototype.classArcs = function(d) { + return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id) }; -ChartInternal.prototype.getAxisClipY = function (forHorizontal) { - return forHorizontal ? -20 : -this.margin.top; +ChartInternal.prototype.classArea = function(d) { + return this.classShape(d) + this.generateClass(CLASS.area, d.id) }; -ChartInternal.prototype.getXAxisClipX = function () { - var $$ = this; - return $$.getAxisClipX(!$$.config.axis_rotated); +ChartInternal.prototype.classAreas = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.areas, d.id) }; -ChartInternal.prototype.getXAxisClipY = function () { - var $$ = this; - return $$.getAxisClipY(!$$.config.axis_rotated); +ChartInternal.prototype.classRegion = function(d, i) { + return ( + this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '') + ) }; -ChartInternal.prototype.getYAxisClipX = function () { - var $$ = this; - return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated); +ChartInternal.prototype.classEvent = function(d) { + return this.generateClass(CLASS.eventRect, d.index) }; -ChartInternal.prototype.getYAxisClipY = function () { - var $$ = this; - return $$.getAxisClipY($$.config.axis_rotated); +ChartInternal.prototype.classTarget = function(id) { + var $$ = this; + var additionalClassSuffix = $$.config.data_classes[id], + additionalClass = ''; + if (additionalClassSuffix) { + additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix; + } + return $$.generateClass(CLASS.target, id) + additionalClass }; -ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) { - var $$ = this, - left = Math.max(30, $$.margin.left), - right = Math.max(30, $$.margin.right); - // width + axis line width + padding for left/right - return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20; +ChartInternal.prototype.classFocus = function(d) { + return this.classFocused(d) + this.classDefocused(d) }; -ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) { - // less than 20 is not enough to show the axis label 'outer' without legend - return (forHorizontal ? this.margin.bottom : (this.margin.top + this.height)) + 20; +ChartInternal.prototype.classFocused = function(d) { + return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '') }; -ChartInternal.prototype.getXAxisClipWidth = function () { - var $$ = this; - return $$.getAxisClipWidth(!$$.config.axis_rotated); +ChartInternal.prototype.classDefocused = function(d) { + return ( + ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '') + ) }; -ChartInternal.prototype.getXAxisClipHeight = function () { - var $$ = this; - return $$.getAxisClipHeight(!$$.config.axis_rotated); +ChartInternal.prototype.classChartText = function(d) { + return CLASS.chartText + this.classTarget(d.id) }; -ChartInternal.prototype.getYAxisClipWidth = function () { - var $$ = this; - return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0); +ChartInternal.prototype.classChartLine = function(d) { + return CLASS.chartLine + this.classTarget(d.id) }; -ChartInternal.prototype.getYAxisClipHeight = function () { - var $$ = this; - return $$.getAxisClipHeight($$.config.axis_rotated); +ChartInternal.prototype.classChartBar = function(d) { + return CLASS.chartBar + this.classTarget(d.id) }; - -ChartInternal.prototype.generateColor = function () { - var $$ = this, config = $$.config, d3 = $$.d3, - colors = config.data_colors, - pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.schemeCategory10, - callback = config.data_color, - ids = []; - - return function (d) { - var id = d.id || (d.data && d.data.id) || d, color; - - // if callback function is provided - if (colors[id] instanceof Function) { - color = colors[id](d); - } - // if specified, choose that color - else if (colors[id]) { - color = colors[id]; - } - // if not specified, choose from pattern - else { - if (ids.indexOf(id) < 0) { ids.push(id); } - color = pattern[ids.indexOf(id) % pattern.length]; - colors[id] = color; - } - return callback instanceof Function ? callback(color, d) : color; - }; -}; -ChartInternal.prototype.generateLevelColor = function () { - var $$ = this, config = $$.config, - colors = config.color_pattern, - threshold = config.color_threshold, - asValue = threshold.unit === 'value', - values = threshold.values && threshold.values.length ? threshold.values : [], - max = threshold.max || 100; - return notEmpty(threshold) && notEmpty(colors) ? function (value) { - var i, v, color = colors[colors.length - 1]; - for (i = 0; i < values.length; i++) { - v = asValue ? value : (value * 100 / max); - if (v < values[i]) { - color = colors[i]; - break; - } - } - return color; - } : null; -}; - -ChartInternal.prototype.getDefaultConfig = function () { - var config = { - bindto: '#chart', - svg_classname: undefined, - size_width: undefined, - size_height: undefined, - padding_left: undefined, - padding_right: undefined, - padding_top: undefined, - padding_bottom: undefined, - resize_auto: true, - zoom_enabled: false, - zoom_initialRange: undefined, - zoom_type: 'scroll', - zoom_disableDefaultBehavior: false, - zoom_privileged: false, - zoom_rescale: false, - zoom_onzoom: function () {}, - zoom_onzoomstart: function () {}, - zoom_onzoomend: function () {}, - zoom_x_min: undefined, - zoom_x_max: undefined, - interaction_brighten: true, - interaction_enabled: true, - onmouseover: function () {}, - onmouseout: function () {}, - onresize: function () {}, - onresized: function () {}, - oninit: function () {}, - onrendered: function () {}, - transition_duration: 350, - data_epochs: 'epochs', - data_x: undefined, - data_xs: {}, - data_xFormat: '%Y-%m-%d', - data_xLocaltime: true, - data_xSort: true, - data_idConverter: function (id) { return id; }, - data_names: {}, - data_classes: {}, - data_groups: [], - data_axes: {}, - data_type: undefined, - data_types: {}, - data_labels: {}, - data_order: 'desc', - data_regions: {}, - data_color: undefined, - data_colors: {}, - data_hide: false, - data_filter: undefined, - data_selection_enabled: false, - data_selection_grouped: false, - data_selection_isselectable: function () { return true; }, - data_selection_multiple: true, - data_selection_draggable: false, - data_stack_normalize: false, - data_onclick: function () {}, - data_onmouseover: function () {}, - data_onmouseout: function () {}, - data_onselected: function () {}, - data_onunselected: function () {}, - data_url: undefined, - data_headers: undefined, - data_json: undefined, - data_rows: undefined, - data_columns: undefined, - data_mimeType: undefined, - data_keys: undefined, - // configuration for no plot-able data supplied. - data_empty_label_text: "", - // subchart - subchart_show: false, - subchart_size_height: 60, - subchart_axis_x_show: true, - subchart_onbrush: function () {}, - // color - color_pattern: [], - color_threshold: {}, - // legend - legend_show: true, - legend_hide: false, - legend_position: 'bottom', - legend_inset_anchor: 'top-left', - legend_inset_x: 10, - legend_inset_y: 0, - legend_inset_step: undefined, - legend_item_onclick: undefined, - legend_item_onmouseover: undefined, - legend_item_onmouseout: undefined, - legend_equally: false, - legend_padding: 0, - legend_item_tile_width: 10, - legend_item_tile_height: 10, - // axis - axis_rotated: false, - axis_x_show: true, - axis_x_type: 'indexed', - axis_x_localtime: true, - axis_x_categories: [], - axis_x_tick_centered: false, - axis_x_tick_format: undefined, - axis_x_tick_culling: {}, - axis_x_tick_culling_max: 10, - axis_x_tick_count: undefined, - axis_x_tick_fit: true, - axis_x_tick_values: null, - axis_x_tick_rotate: 0, - axis_x_tick_outer: true, - axis_x_tick_multiline: true, - axis_x_tick_multilineMax: 0, - axis_x_tick_width: null, - axis_x_max: undefined, - axis_x_min: undefined, - axis_x_padding: {}, - axis_x_height: undefined, - axis_x_selection: undefined, - axis_x_label: {}, - axis_x_inner: undefined, - axis_y_show: true, - axis_y_type: 'linear', - axis_y_max: undefined, - axis_y_min: undefined, - axis_y_inverted: false, - axis_y_center: undefined, - axis_y_inner: undefined, - axis_y_label: {}, - axis_y_tick_format: undefined, - axis_y_tick_outer: true, - axis_y_tick_values: null, - axis_y_tick_rotate: 0, - axis_y_tick_count: undefined, - axis_y_tick_time_type: undefined, - axis_y_tick_time_interval: undefined, - axis_y_padding: {}, - axis_y_default: undefined, - axis_y2_show: false, - axis_y2_type: 'linear', - axis_y2_max: undefined, - axis_y2_min: undefined, - axis_y2_inverted: false, - axis_y2_center: undefined, - axis_y2_inner: undefined, - axis_y2_label: {}, - axis_y2_tick_format: undefined, - axis_y2_tick_outer: true, - axis_y2_tick_values: null, - axis_y2_tick_count: undefined, - axis_y2_padding: {}, - axis_y2_default: undefined, - // grid - grid_x_show: false, - grid_x_type: 'tick', - grid_x_lines: [], - grid_y_show: false, - // not used - // grid_y_type: 'tick', - grid_y_lines: [], - grid_y_ticks: 10, - grid_focus_show: true, - grid_lines_front: true, - // point - point of each data - point_show: true, - point_r: 2.5, - point_sensitivity: 10, - point_focus_expand_enabled: true, - point_focus_expand_r: undefined, - point_select_r: undefined, - // line - line_connectNull: false, - line_step_type: 'step', - // bar - bar_width: undefined, - bar_width_ratio: 0.6, - bar_width_max: undefined, - bar_zerobased: true, - bar_space: 0, - // area - area_zerobased: true, - area_above: false, - // pie - pie_label_show: true, - pie_label_format: undefined, - pie_label_threshold: 0.05, - pie_label_ratio: undefined, - pie_expand: {}, - pie_expand_duration: 50, - pie_padAngle: 0, - // gauge - gauge_fullCircle: false, - gauge_label_show: true, - gauge_labelLine_show: true, - gauge_label_format: undefined, - gauge_min: 0, - gauge_max: 100, - gauge_startingAngle: -1 * Math.PI/2, - gauge_label_extents: undefined, - gauge_units: undefined, - gauge_width: undefined, - gauge_arcs_minWidth: 5, - gauge_expand: {}, - gauge_expand_duration: 50, - // donut - donut_label_show: true, - donut_label_format: undefined, - donut_label_threshold: 0.05, - donut_label_ratio: undefined, - donut_width: undefined, - donut_title: "", - donut_expand: {}, - donut_expand_duration: 50, - donut_padAngle: 0, - // spline - spline_interpolation_type: 'cardinal', - // stanford - stanford_lines: [], - stanford_regions: [], - stanford_texts: [], - stanford_scaleMin: undefined, - stanford_scaleMax: undefined, - stanford_scaleWidth: undefined, - stanford_scaleFormat: undefined, - stanford_scaleValues: undefined, - stanford_colors: undefined, - stanford_padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - }, - // region - region to change style - regions: [], - // tooltip - show when mouseover on each data - tooltip_show: true, - tooltip_grouped: true, - tooltip_order: undefined, - tooltip_format_title: undefined, - tooltip_format_name: undefined, - tooltip_format_value: undefined, - tooltip_horizontal: undefined, - tooltip_position: undefined, - tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) { - return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : ''; - }, - tooltip_init_show: false, - tooltip_init_x: 0, - tooltip_init_position: {top: '0px', left: '50px'}, - tooltip_onshow: function () {}, - tooltip_onhide: function () {}, - // title - title_text: undefined, - title_padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - }, - title_position: 'top-center' - }; - - Object.keys(this.additionalConfig).forEach(function (key) { - config[key] = this.additionalConfig[key]; - }, this); - - return config; +ChartInternal.prototype.classChartArc = function(d) { + return CLASS.chartArc + this.classTarget(d.data.id) }; -ChartInternal.prototype.additionalConfig = {}; +ChartInternal.prototype.getTargetSelectorSuffix = function(targetId) { + const targetClass = this.generateTargetClass(targetId); + if (window.CSS && window.CSS.escape) { + return window.CSS.escape(targetClass) + } -ChartInternal.prototype.loadConfig = function (config) { - var this_config = this.config, target, keys, read; - function find() { - var key = keys.shift(); -// console.log("key =>", key, ", target =>", target); - if (key && target && typeof target === 'object' && key in target) { - target = target[key]; - return find(); - } - else if (!key) { - return target; - } - else { - return undefined; - } + // fallback on imperfect method for old browsers (does not handles unicode) + return targetClass.replace(/([?!@#$%^&*()=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1') +}; +ChartInternal.prototype.selectorTarget = function(id, prefix) { + return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id) +}; +ChartInternal.prototype.selectorTargets = function(ids, prefix) { + var $$ = this; + ids = ids || []; + return ids.length + ? ids.map(function(id) { + return $$.selectorTarget(id, prefix) + }) + : null +}; +ChartInternal.prototype.selectorLegend = function(id) { + return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id) +}; +ChartInternal.prototype.selectorLegends = function(ids) { + var $$ = this; + return ids && ids.length + ? ids.map(function(id) { + return $$.selectorLegend(id) + }) + : null +}; + +ChartInternal.prototype.getClipPath = function(id) { + return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')' +}; +ChartInternal.prototype.appendClip = function(parent, id) { + return parent + .append('clipPath') + .attr('id', id) + .append('rect') +}; +ChartInternal.prototype.getAxisClipX = function(forHorizontal) { + // axis line width + padding for left + var left = Math.max(30, this.margin.left); + return forHorizontal ? -(1 + left) : -(left - 1) +}; +ChartInternal.prototype.getAxisClipY = function(forHorizontal) { + return forHorizontal ? -20 : -this.margin.top +}; +ChartInternal.prototype.getXAxisClipX = function() { + var $$ = this; + return $$.getAxisClipX(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getXAxisClipY = function() { + var $$ = this; + return $$.getAxisClipY(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getYAxisClipX = function() { + var $$ = this; + return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated) +}; +ChartInternal.prototype.getYAxisClipY = function() { + var $$ = this; + return $$.getAxisClipY($$.config.axis_rotated) +}; +ChartInternal.prototype.getAxisClipWidth = function(forHorizontal) { + var $$ = this, + left = Math.max(30, $$.margin.left), + right = Math.max(30, $$.margin.right); + // width + axis line width + padding for left/right + return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20 +}; +ChartInternal.prototype.getAxisClipHeight = function(forHorizontal) { + // less than 20 is not enough to show the axis label 'outer' without legend + return ( + (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20 + ) +}; +ChartInternal.prototype.getXAxisClipWidth = function() { + var $$ = this; + return $$.getAxisClipWidth(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getXAxisClipHeight = function() { + var $$ = this; + return $$.getAxisClipHeight(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getYAxisClipWidth = function() { + var $$ = this; + return ( + $$.getAxisClipWidth($$.config.axis_rotated) + + ($$.config.axis_y_inner ? 20 : 0) + ) +}; +ChartInternal.prototype.getYAxisClipHeight = function() { + var $$ = this; + return $$.getAxisClipHeight($$.config.axis_rotated) +}; + +ChartInternal.prototype.generateColor = function() { + var $$ = this, + config = $$.config, + d3 = $$.d3, + colors = config.data_colors, + pattern = notEmpty(config.color_pattern) + ? config.color_pattern + : d3.schemeCategory10, + callback = config.data_color, + ids = []; + + return function(d) { + var id = d.id || (d.data && d.data.id) || d, + color; + + // if callback function is provided + if (colors[id] instanceof Function) { + color = colors[id](d); + } + // if specified, choose that color + else if (colors[id]) { + color = colors[id]; + } + // if not specified, choose from pattern + else { + if (ids.indexOf(id) < 0) { + ids.push(id); + } + color = pattern[ids.indexOf(id) % pattern.length]; + colors[id] = color; } - Object.keys(this_config).forEach(function (key) { - target = config; - keys = key.split('_'); - read = find(); -// console.log("CONFIG : ", key, read); - if (isDefined(read)) { - this_config[key] = read; - } - }); + return callback instanceof Function ? callback(color, d) : color + } }; +ChartInternal.prototype.generateLevelColor = function() { + var $$ = this, + config = $$.config, + colors = config.color_pattern, + threshold = config.color_threshold, + asValue = threshold.unit === 'value', + values = + threshold.values && threshold.values.length ? threshold.values : [], + max = threshold.max || 100; + return notEmpty(threshold) && notEmpty(colors) + ? function(value) { + var i, + v, + color = colors[colors.length - 1]; + for (i = 0; i < values.length; i++) { + v = asValue ? value : (value * 100) / max; + if (v < values[i]) { + color = colors[i]; + break + } + } + return color + } + : null +}; + +ChartInternal.prototype.getDefaultConfig = function() { + var config = { + bindto: '#chart', + svg_classname: undefined, + size_width: undefined, + size_height: undefined, + padding_left: undefined, + padding_right: undefined, + padding_top: undefined, + padding_bottom: undefined, + resize_auto: true, + zoom_enabled: false, + zoom_initialRange: undefined, + zoom_type: 'scroll', + zoom_disableDefaultBehavior: false, + zoom_privileged: false, + zoom_rescale: false, + zoom_onzoom: function() {}, + zoom_onzoomstart: function() {}, + zoom_onzoomend: function() {}, + zoom_x_min: undefined, + zoom_x_max: undefined, + interaction_brighten: true, + interaction_enabled: true, + onmouseover: function() {}, + onmouseout: function() {}, + onresize: function() {}, + onresized: function() {}, + oninit: function() {}, + onrendered: function() {}, + transition_duration: 350, + data_epochs: 'epochs', + data_x: undefined, + data_xs: {}, + data_xFormat: '%Y-%m-%d', + data_xLocaltime: true, + data_xSort: true, + data_idConverter: function(id) { + return id + }, + data_names: {}, + data_classes: {}, + data_groups: [], + data_axes: {}, + data_type: undefined, + data_types: {}, + data_labels: {}, + data_order: 'desc', + data_regions: {}, + data_color: undefined, + data_colors: {}, + data_hide: false, + data_filter: undefined, + data_selection_enabled: false, + data_selection_grouped: false, + data_selection_isselectable: function() { + return true + }, + data_selection_multiple: true, + data_selection_draggable: false, + data_stack_normalize: false, + data_onclick: function() {}, + data_onmouseover: function() {}, + data_onmouseout: function() {}, + data_onselected: function() {}, + data_onunselected: function() {}, + data_url: undefined, + data_headers: undefined, + data_json: undefined, + data_rows: undefined, + data_columns: undefined, + data_mimeType: undefined, + data_keys: undefined, + // configuration for no plot-able data supplied. + data_empty_label_text: '', + // subchart + subchart_show: false, + subchart_size_height: 60, + subchart_axis_x_show: true, + subchart_onbrush: function() {}, + // color + color_pattern: [], + color_threshold: {}, + // legend + legend_show: true, + legend_hide: false, + legend_position: 'bottom', + legend_inset_anchor: 'top-left', + legend_inset_x: 10, + legend_inset_y: 0, + legend_inset_step: undefined, + legend_item_onclick: undefined, + legend_item_onmouseover: undefined, + legend_item_onmouseout: undefined, + legend_equally: false, + legend_padding: 0, + legend_item_tile_width: 10, + legend_item_tile_height: 10, + // axis + axis_rotated: false, + axis_x_show: true, + axis_x_type: 'indexed', + axis_x_localtime: true, + axis_x_categories: [], + axis_x_tick_centered: false, + axis_x_tick_format: undefined, + axis_x_tick_culling: {}, + axis_x_tick_culling_max: 10, + axis_x_tick_count: undefined, + axis_x_tick_fit: true, + axis_x_tick_values: null, + axis_x_tick_rotate: 0, + axis_x_tick_outer: true, + axis_x_tick_multiline: true, + axis_x_tick_multilineMax: 0, + axis_x_tick_width: null, + axis_x_max: undefined, + axis_x_min: undefined, + axis_x_padding: {}, + axis_x_height: undefined, + axis_x_selection: undefined, + axis_x_label: {}, + axis_x_inner: undefined, + axis_y_show: true, + axis_y_type: 'linear', + axis_y_max: undefined, + axis_y_min: undefined, + axis_y_inverted: false, + axis_y_center: undefined, + axis_y_inner: undefined, + axis_y_label: {}, + axis_y_tick_format: undefined, + axis_y_tick_outer: true, + axis_y_tick_values: null, + axis_y_tick_rotate: 0, + axis_y_tick_count: undefined, + axis_y_tick_time_type: undefined, + axis_y_tick_time_interval: undefined, + axis_y_padding: {}, + axis_y_default: undefined, + axis_y2_show: false, + axis_y2_type: 'linear', + axis_y2_max: undefined, + axis_y2_min: undefined, + axis_y2_inverted: false, + axis_y2_center: undefined, + axis_y2_inner: undefined, + axis_y2_label: {}, + axis_y2_tick_format: undefined, + axis_y2_tick_outer: true, + axis_y2_tick_values: null, + axis_y2_tick_count: undefined, + axis_y2_padding: {}, + axis_y2_default: undefined, + // grid + grid_x_show: false, + grid_x_type: 'tick', + grid_x_lines: [], + grid_y_show: false, + // not used + // grid_y_type: 'tick', + grid_y_lines: [], + grid_y_ticks: 10, + grid_focus_show: true, + grid_lines_front: true, + // point - point of each data + point_show: true, + point_r: 2.5, + point_sensitivity: 10, + point_focus_expand_enabled: true, + point_focus_expand_r: undefined, + point_select_r: undefined, + // line + line_connectNull: false, + line_step_type: 'step', + // bar + bar_width: undefined, + bar_width_ratio: 0.6, + bar_width_max: undefined, + bar_zerobased: true, + bar_space: 0, + // area + area_zerobased: true, + area_above: false, + // pie + pie_label_show: true, + pie_label_format: undefined, + pie_label_threshold: 0.05, + pie_label_ratio: undefined, + pie_expand: {}, + pie_expand_duration: 50, + pie_padAngle: 0, + // gauge + gauge_fullCircle: false, + gauge_label_show: true, + gauge_labelLine_show: true, + gauge_label_format: undefined, + gauge_min: 0, + gauge_max: 100, + gauge_startingAngle: (-1 * Math.PI) / 2, + gauge_label_extents: undefined, + gauge_units: undefined, + gauge_width: undefined, + gauge_arcs_minWidth: 5, + gauge_expand: {}, + gauge_expand_duration: 50, + // donut + donut_label_show: true, + donut_label_format: undefined, + donut_label_threshold: 0.05, + donut_label_ratio: undefined, + donut_width: undefined, + donut_title: '', + donut_expand: {}, + donut_expand_duration: 50, + donut_padAngle: 0, + // spline + spline_interpolation_type: 'cardinal', + // stanford + stanford_lines: [], + stanford_regions: [], + stanford_texts: [], + stanford_scaleMin: undefined, + stanford_scaleMax: undefined, + stanford_scaleWidth: undefined, + stanford_scaleFormat: undefined, + stanford_scaleValues: undefined, + stanford_colors: undefined, + stanford_padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + // region - region to change style + regions: [], + // tooltip - show when mouseover on each data + tooltip_show: true, + tooltip_grouped: true, + tooltip_order: undefined, + tooltip_format_title: undefined, + tooltip_format_name: undefined, + tooltip_format_value: undefined, + tooltip_horizontal: undefined, + tooltip_position: undefined, + tooltip_contents: function( + d, + defaultTitleFormat, + defaultValueFormat, + color + ) { + return this.getTooltipContent + ? this.getTooltipContent( + d, + defaultTitleFormat, + defaultValueFormat, + color + ) + : '' + }, + tooltip_init_show: false, + tooltip_init_x: 0, + tooltip_init_position: { top: '0px', left: '50px' }, + tooltip_onshow: function() {}, + tooltip_onhide: function() {}, + // title + title_text: undefined, + title_padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + title_position: 'top-center' + }; -ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) { - var $$ = this, type = mimeType ? mimeType : 'csv', f, converter; + Object.keys(this.additionalConfig).forEach(function(key) { + config[key] = this.additionalConfig[key]; + }, this); - if (type === 'json') { - f = $$.d3.json; - converter = $$.convertJsonToData; - } else if (type === 'tsv') { - f = $$.d3.tsv; - converter = $$.convertXsvToData; + return config +}; +ChartInternal.prototype.additionalConfig = {}; + +ChartInternal.prototype.loadConfig = function(config) { + var this_config = this.config, + target, + keys, + read; + function find() { + var key = keys.shift(); + // console.log("key =>", key, ", target =>", target); + if (key && target && typeof target === 'object' && key in target) { + target = target[key]; + return find() + } else if (!key) { + return target } else { - f = $$.d3.csv; - converter = $$.convertXsvToData; + return undefined } + } + Object.keys(this_config).forEach(function(key) { + target = config; + keys = key.split('_'); + read = find(); + // console.log("CONFIG : ", key, read); + if (isDefined(read)) { + this_config[key] = read; + } + }); +}; + +ChartInternal.prototype.convertUrlToData = function( + url, + mimeType, + headers, + keys, + done +) { + var $$ = this, + type = mimeType ? mimeType : 'csv', + f, + converter; + + if (type === 'json') { + f = $$.d3.json; + converter = $$.convertJsonToData; + } else if (type === 'tsv') { + f = $$.d3.tsv; + converter = $$.convertXsvToData; + } else { + f = $$.d3.csv; + converter = $$.convertXsvToData; + } - f(url, headers).then(function (data) { - done.call($$, converter.call($$, data, keys)); - }).catch(function (error) { - throw error; + f(url, headers) + .then(function(data) { + done.call($$, converter.call($$, data, keys)); + }) + .catch(function(error) { + throw error }); }; -ChartInternal.prototype.convertXsvToData = function (xsv) { - var keys = xsv.columns, rows = xsv; - if (rows.length === 0) { - return { keys, rows: [ keys.reduce((row, key) => Object.assign(row, { [key]: null }), {}) ] }; - } else { - // [].concat() is to convert result into a plain array otherwise - // test is not happy because rows have properties. - return { keys, rows: [].concat(xsv) }; - } -}; -ChartInternal.prototype.convertJsonToData = function (json, keys) { - var $$ = this, - new_rows = [], targetKeys, data; - if (keys) { // when keys specified, json would be an array that includes objects - if (keys.x) { - targetKeys = keys.value.concat(keys.x); - $$.config.data_x = keys.x; - } else { - targetKeys = keys.value; - } - new_rows.push(targetKeys); - json.forEach(function (o) { - var new_row = []; - targetKeys.forEach(function (key) { - // convert undefined to null because undefined data will be removed in convertDataToTargets() - var v = $$.findValueInJson(o, key); - if (isUndefined(v)) { - v = null; - } - new_row.push(v); - }); - new_rows.push(new_row); - }); - data = $$.convertRowsToData(new_rows); - } else { - Object.keys(json).forEach(function (key) { - new_rows.push([key].concat(json[key])); - }); - data = $$.convertColumnsToData(new_rows); +ChartInternal.prototype.convertXsvToData = function(xsv) { + var keys = xsv.columns, + rows = xsv; + if (rows.length === 0) { + return { + keys, + rows: [keys.reduce((row, key) => Object.assign(row, { [key]: null }), {})] } - return data; + } else { + // [].concat() is to convert result into a plain array otherwise + // test is not happy because rows have properties. + return { keys, rows: [].concat(xsv) } + } +}; +ChartInternal.prototype.convertJsonToData = function(json, keys) { + var $$ = this, + new_rows = [], + targetKeys, + data; + if (keys) { + // when keys specified, json would be an array that includes objects + if (keys.x) { + targetKeys = keys.value.concat(keys.x); + $$.config.data_x = keys.x; + } else { + targetKeys = keys.value; + } + new_rows.push(targetKeys); + json.forEach(function(o) { + var new_row = []; + targetKeys.forEach(function(key) { + // convert undefined to null because undefined data will be removed in convertDataToTargets() + var v = $$.findValueInJson(o, key); + if (isUndefined(v)) { + v = null; + } + new_row.push(v); + }); + new_rows.push(new_row); + }); + data = $$.convertRowsToData(new_rows); + } else { + Object.keys(json).forEach(function(key) { + new_rows.push([key].concat(json[key])); + }); + data = $$.convertColumnsToData(new_rows); + } + return data }; /** * Finds value from the given nested object by the given path. @@ -6109,26 +7795,26 @@ ChartInternal.prototype.convertJsonToData = function (json, keys) { * @param {Object} object the object * @param {string} path the path */ -ChartInternal.prototype.findValueInJson = function (object, path) { - if (path in object) { - // If object has a key that contains . or [], return the key's value - // instead of searching for an inner object. - // See https://github.com/c3js/c3/issues/1691 for details. - return object[path]; - } - - path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .) - path = path.replace(/^\./, ''); // strip a leading dot - var pathArray = path.split('.'); - for (var i = 0; i < pathArray.length; ++i) { - var k = pathArray[i]; - if (k in object) { - object = object[k]; - } else { - return; - } +ChartInternal.prototype.findValueInJson = function(object, path) { + if (path in object) { + // If object has a key that contains . or [], return the key's value + // instead of searching for an inner object. + // See https://github.com/c3js/c3/issues/1691 for details. + return object[path] + } + + path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .) + path = path.replace(/^\./, ''); // strip a leading dot + var pathArray = path.split('.'); + for (var i = 0; i < pathArray.length; ++i) { + var k = pathArray[i]; + if (k in object) { + object = object[k]; + } else { + return } - return object; + } + return object }; /** @@ -6136,21 +7822,23 @@ ChartInternal.prototype.findValueInJson = function (object, path) { * @param {any[][]} rows The row data * @return {Object} */ -ChartInternal.prototype.convertRowsToData = (rows) => { - const newRows = []; - const keys = rows[0]; - - for (let i = 1; i < rows.length; i++) { - const newRow = {}; - for (let j = 0; j < rows[i].length; j++) { - if (isUndefined(rows[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); - } - newRow[keys[j]] = rows[i][j]; - } - newRows.push(newRow); - } - return { keys, rows: newRows }; +ChartInternal.prototype.convertRowsToData = rows => { + const newRows = []; + const keys = rows[0]; + + for (let i = 1; i < rows.length; i++) { + const newRow = {}; + for (let j = 0; j < rows[i].length; j++) { + if (isUndefined(rows[i][j])) { + throw new Error( + 'Source data is missing a component at (' + i + ',' + j + ')!' + ) + } + newRow[keys[j]] = rows[i][j]; + } + newRows.push(newRow); + } + return { keys, rows: newRows } }; /** @@ -6158,25 +7846,27 @@ ChartInternal.prototype.convertRowsToData = (rows) => { * @param {any[][]} columns The column data * @return {Object} */ -ChartInternal.prototype.convertColumnsToData = (columns) => { - const newRows = []; - const keys = []; - - for (let i = 0; i < columns.length; i++) { - const key = columns[i][0]; - for (let j = 1; j < columns[i].length; j++) { - if (isUndefined(newRows[j - 1])) { - newRows[j - 1] = {}; - } - if (isUndefined(columns[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); - } - newRows[j - 1][key] = columns[i][j]; - } - keys.push(key); - } +ChartInternal.prototype.convertColumnsToData = columns => { + const newRows = []; + const keys = []; + + for (let i = 0; i < columns.length; i++) { + const key = columns[i][0]; + for (let j = 1; j < columns[i].length; j++) { + if (isUndefined(newRows[j - 1])) { + newRows[j - 1] = {}; + } + if (isUndefined(columns[i][j])) { + throw new Error( + 'Source data is missing a component at (' + i + ',' + j + ')!' + ) + } + newRows[j - 1][key] = columns[i][j]; + } + keys.push(key); + } - return { keys, rows: newRows }; + return { keys, rows: newRows } }; /** @@ -6187,156 +7877,189 @@ ChartInternal.prototype.convertColumnsToData = (columns) => { * @param {boolean} appendXs True to append to $$.data.xs, False to replace. * @return {!Array} */ -ChartInternal.prototype.convertDataToTargets = function (data, appendXs) { - var $$ = this, config = $$.config, targets, ids, xs, keys, epochs; +ChartInternal.prototype.convertDataToTargets = function(data, appendXs) { + var $$ = this, + config = $$.config, + targets, + ids, + xs, + keys, + epochs; + + // handles format where keys are not orderly provided + if (isArray(data)) { + keys = Object.keys(data[0]); + } else { + keys = data.keys; + data = data.rows; + } - // handles format where keys are not orderly provided - if (isArray(data)) { - keys = Object.keys(data[ 0 ]); - } else { - keys = data.keys; - data = data.rows; - } + xs = keys.filter($$.isX, $$); - xs = keys.filter($$.isX, $$); + if (!$$.isStanfordGraphType()) { + ids = keys.filter($$.isNotX, $$); + } else { + epochs = keys.filter($$.isEpochs, $$); + ids = keys.filter($$.isNotXAndNotEpochs, $$); - if(!$$.isStanfordGraphType()) { - ids = keys.filter($$.isNotX, $$); - } else { - epochs = keys.filter($$.isEpochs, $$); - ids = keys.filter($$.isNotXAndNotEpochs, $$); + if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) { + throw new Error( + "You must define the 'x' key name and the 'epochs' for Stanford Diagrams" + ) + } + } - if(xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) { - throw new Error('You must define the \'x\' key name and the \'epochs\' for Stanford Diagrams'); - } + // save x for update data by load when custom x and c3.x API + ids.forEach(function(id) { + var xKey = $$.getXKey(id); + + if ($$.isCustomX() || $$.isTimeSeries()) { + // if included in input data + if (xs.indexOf(xKey) >= 0) { + $$.data.xs[id] = (appendXs && $$.data.xs[id] + ? $$.data.xs[id] + : [] + ).concat( + data + .map(function(d) { + return d[xKey] + }) + .filter(isValue) + .map(function(rawX, i) { + return $$.generateTargetX(rawX, id, i) + }) + ); + } + // if not included in input data, find from preloaded data of other id's x + else if (config.data_x) { + $$.data.xs[id] = $$.getOtherTargetXs(); + } + // if not included in input data, find from preloaded data + else if (notEmpty(config.data_xs)) { + $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets); + } + // MEMO: if no x included, use same x of current will be used + } else { + $$.data.xs[id] = data.map(function(d, i) { + return i + }); } + }); - // save x for update data by load when custom x and c3.x API - ids.forEach(function (id) { - var xKey = $$.getXKey(id); + // check x is defined + ids.forEach(function(id) { + if (!$$.data.xs[id]) { + throw new Error('x is not defined for id = "' + id + '".') + } + }); - if ($$.isCustomX() || $$.isTimeSeries()) { - // if included in input data - if (xs.indexOf(xKey) >= 0) { - $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat( - data.map(function (d) { return d[xKey]; }) - .filter(isValue) - .map(function (rawX, i) { return $$.generateTargetX(rawX, id, i); }) - ); - } - // if not included in input data, find from preloaded data of other id's x - else if (config.data_x) { - $$.data.xs[id] = $$.getOtherTargetXs(); + // convert to target + targets = ids.map(function(id, index) { + var convertedId = config.data_idConverter(id); + return { + id: convertedId, + id_org: id, + values: data + .map(function(d, i) { + var xKey = $$.getXKey(id), + rawX = d[xKey], + value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, + x, + returnData; + // use x as categories if custom x and categorized + if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) { + if (index === 0 && i === 0) { + config.axis_x_categories = []; } - // if not included in input data, find from preloaded data - else if (notEmpty(config.data_xs)) { - $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets); + x = config.axis_x_categories.indexOf(rawX); + if (x === -1) { + x = config.axis_x_categories.length; + config.axis_x_categories.push(rawX); } - // MEMO: if no x included, use same x of current will be used - } else { - $$.data.xs[id] = data.map(function (d, i) { return i; }); - } - }); - - // check x is defined - ids.forEach(function (id) { - if (!$$.data.xs[id]) { - throw new Error('x is not defined for id = "' + id + '".'); - } - }); + } else { + x = $$.generateTargetX(rawX, id, i); + } + // mark as x = undefined if value is undefined and filter to remove after mapped + if (isUndefined(d[id]) || $$.data.xs[id].length <= i) { + x = undefined; + } - // convert to target - targets = ids.map(function (id, index) { - var convertedId = config.data_idConverter(id); - return { - id: convertedId, - id_org: id, - values: data.map(function (d, i) { - var xKey = $$.getXKey(id), rawX = d[xKey], - value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, x, returnData; - // use x as categories if custom x and categorized - if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) { - if (index === 0 && i === 0) { - config.axis_x_categories = []; - } - x = config.axis_x_categories.indexOf(rawX); - if (x === -1) { - x = config.axis_x_categories.length; - config.axis_x_categories.push(rawX); - } - } else { - x = $$.generateTargetX(rawX, id, i); - } - // mark as x = undefined if value is undefined and filter to remove after mapped - if (isUndefined(d[id]) || $$.data.xs[id].length <= i) { - x = undefined; - } + returnData = { x: x, value: value, id: convertedId }; - returnData = {x: x, value: value, id: convertedId}; - - if($$.isStanfordGraphType()) { - returnData.epochs = d[epochs]; - } + if ($$.isStanfordGraphType()) { + returnData.epochs = d[epochs]; + } - return returnData; - }).filter(function (v) { return isDefined(v.x); }) - }; + return returnData + }) + .filter(function(v) { + return isDefined(v.x) + }) + } + }); + + // finish targets + targets.forEach(function(t) { + var i; + // sort values by its x + if (config.data_xSort) { + t.values = t.values.sort(function(v1, v2) { + var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, + x2 = v2.x || v2.x === 0 ? v2.x : Infinity; + return x1 - x2 + }); + } + // indexing each value + i = 0; + t.values.forEach(function(v) { + v.index = i++; }); - - // finish targets - targets.forEach(function (t) { - var i; - // sort values by its x - if (config.data_xSort) { - t.values = t.values.sort(function (v1, v2) { - var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, - x2 = v2.x || v2.x === 0 ? v2.x : Infinity; - return x1 - x2; - }); - } - // indexing each value - i = 0; - t.values.forEach(function (v) { - v.index = i++; - }); - // this needs to be sorted because its index and value.index is identical - $$.data.xs[t.id].sort(function (v1, v2) { - return v1 - v2; - }); + // this needs to be sorted because its index and value.index is identical + $$.data.xs[t.id].sort(function(v1, v2) { + return v1 - v2 }); + }); + + // cache information about values + $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets); + $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); + + // set target types + if (config.data_type) { + $$.setTargetType( + $$.mapToIds(targets).filter(function(id) { + return !(id in config.data_types) + }), + config.data_type + ); + } - // cache information about values - $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets); - $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); - - // set target types - if (config.data_type) { - $$.setTargetType($$.mapToIds(targets).filter(function (id) { return ! (id in config.data_types); }), config.data_type); - } - - // cache as original id keyed - targets.forEach(function (d) { - $$.addCache(d.id_org, d); - }); + // cache as original id keyed + targets.forEach(function(d) { + $$.addCache(d.id_org, d); + }); - return targets; + return targets }; -ChartInternal.prototype.isEpochs = function (key) { - var $$ = this, - config = $$.config; - return (config.data_epochs && key === config.data_epochs); +ChartInternal.prototype.isEpochs = function(key) { + var $$ = this, + config = $$.config; + return config.data_epochs && key === config.data_epochs }; -ChartInternal.prototype.isX = function (key) { - var $$ = this, - config = $$.config; - return (config.data_x && key === config.data_x) || (notEmpty(config.data_xs) && hasValue(config.data_xs, key)); +ChartInternal.prototype.isX = function(key) { + var $$ = this, + config = $$.config; + return ( + (config.data_x && key === config.data_x) || + (notEmpty(config.data_xs) && hasValue(config.data_xs, key)) + ) }; -ChartInternal.prototype.isNotX = function (key) { - return !this.isX(key); +ChartInternal.prototype.isNotX = function(key) { + return !this.isX(key) }; -ChartInternal.prototype.isNotXAndNotEpochs = function (key) { - return !this.isX(key) && !this.isEpochs(key); +ChartInternal.prototype.isNotXAndNotEpochs = function(key) { + return !this.isX(key) && !this.isEpochs(key) }; /** @@ -6347,7 +8070,7 @@ ChartInternal.prototype.isNotXAndNotEpochs = function (key) { * @return {boolean} */ ChartInternal.prototype.isStackNormalized = function() { - return this.config.data_stack_normalize && this.config.data_groups.length > 0; + return this.config.data_stack_normalize && this.config.data_groups.length > 0 }; /** @@ -6360,15 +8083,16 @@ ChartInternal.prototype.isStackNormalized = function() { * @return {Boolean} */ ChartInternal.prototype.isAxisNormalized = function(axisId) { - const $$ = this; + const $$ = this; - if (!$$.isStackNormalized()) { // shortcut - return false; - } + if (!$$.isStackNormalized()) { + // shortcut + return false + } - return $$.data.targets - .filter((target) => $$.axis.getId(target.id) === axisId) - .some((target) => $$.isTargetNormalized(target.id)); + return $$.data.targets + .filter(target => $$.axis.getId(target.id) === axisId) + .some(target => $$.isTargetNormalized(target.id)) }; /** @@ -6381,15 +8105,22 @@ ChartInternal.prototype.isAxisNormalized = function(axisId) { * @return {Boolean} True if the target is normalized, false otherwise. */ ChartInternal.prototype.isTargetNormalized = function(targetId) { - const $$ = this; + const $$ = this; - return $$.isStackNormalized() && $$.config.data_groups.some((group) => group.includes(targetId)); + return ( + $$.isStackNormalized() && + $$.config.data_groups.some(group => group.includes(targetId)) + ) }; -ChartInternal.prototype.getXKey = function (id) { - var $$ = this, - config = $$.config; - return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null; +ChartInternal.prototype.getXKey = function(id) { + var $$ = this, + config = $$.config; + return config.data_x + ? config.data_x + : notEmpty(config.data_xs) + ? config.data_xs[id] + : null }; /** @@ -6402,41 +8133,41 @@ ChartInternal.prototype.getXKey = function (id) { * @return {Array} */ ChartInternal.prototype.getTotalPerIndex = function(axisId) { - const $$ = this; + const $$ = this; - if (!$$.isStackNormalized()) { - return null; - } + if (!$$.isStackNormalized()) { + return null + } - const cached = $$.getFromCache('getTotalPerIndex'); - if (cached !== undefined) { - return cached[axisId]; - } + const cached = $$.getFromCache('getTotalPerIndex'); + if (cached !== undefined) { + return cached[axisId] + } - const sum = { y: [], y2: [] }; + const sum = { y: [], y2: [] }; - $$.data.targets - // keep only target that are normalized - .filter((target) => $$.isTargetNormalized(target.id)) + $$.data.targets + // keep only target that are normalized + .filter(target => $$.isTargetNormalized(target.id)) - // keep only target that are visible - .filter((target) => $$.isTargetToShow(target.id)) + // keep only target that are visible + .filter(target => $$.isTargetToShow(target.id)) - // compute sum per axis - .forEach(target => { - const sumByAxis = sum[$$.axis.getId(target.id)]; + // compute sum per axis + .forEach(target => { + const sumByAxis = sum[$$.axis.getId(target.id)]; - target.values.forEach((v, i) => { - if (!sumByAxis[i]) { - sumByAxis[i] = 0; - } - sumByAxis[i] += isNumber(v.value) ? v.value : 0; - }); - }); + target.values.forEach((v, i) => { + if (!sumByAxis[i]) { + sumByAxis[i] = 0; + } + sumByAxis[i] += isNumber(v.value) ? v.value : 0; + }); + }); - $$.addToCache('getTotalPerIndex', sum); + $$.addToCache('getTotalPerIndex', sum); - return sum[axisId]; + return sum[axisId] }; /** @@ -6449,141 +8180,145 @@ ChartInternal.prototype.getTotalPerIndex = function(axisId) { * @return {Number} */ ChartInternal.prototype.getTotalDataSum = function() { - const $$ = this; - - const cached = $$.getFromCache('getTotalDataSum'); - if (cached !== undefined) { - return cached; - } - - const totalDataSum = flattenArray($$.data.targets - .filter(target => $$.isTargetToShow(target.id)) - .map(target => target.values) - ) - .map(d => d.value) - .reduce((p, c) => p + c, 0); - - $$.addToCache('getTotalDataSum', totalDataSum); + const $$ = this; - return totalDataSum; -}; + const cached = $$.getFromCache('getTotalDataSum'); + if (cached !== undefined) { + return cached + } -ChartInternal.prototype.getXValuesOfXKey = function (key, targets) { - var $$ = this, - xValues, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []; - ids.forEach(function (id) { - if ($$.getXKey(id) === key) { - xValues = $$.data.xs[id]; - } - }); - return xValues; -}; -ChartInternal.prototype.getXValue = function (id, i) { - var $$ = this; - return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i; -}; -ChartInternal.prototype.getOtherTargetXs = function () { - var $$ = this, - idsForX = Object.keys($$.data.xs); - return idsForX.length ? $$.data.xs[idsForX[0]] : null; -}; -ChartInternal.prototype.getOtherTargetX = function (index) { - var xs = this.getOtherTargetXs(); - return xs && index < xs.length ? xs[index] : null; -}; -ChartInternal.prototype.addXs = function (xs) { - var $$ = this; - Object.keys(xs).forEach(function (id) { - $$.config.data_xs[id] = xs[id]; - }); -}; -ChartInternal.prototype.addName = function (data) { - var $$ = this, - name; - if (data) { - name = $$.config.data_names[data.id]; - data.name = name !== undefined ? name : data.id; - } - return data; -}; -ChartInternal.prototype.getValueOnIndex = function (values, index) { - var valueOnIndex = values.filter(function (v) { - return v.index === index; - }); - return valueOnIndex.length ? valueOnIndex[0] : null; -}; -ChartInternal.prototype.updateTargetX = function (targets, x) { - var $$ = this; - targets.forEach(function (t) { - t.values.forEach(function (v, i) { - v.x = $$.generateTargetX(x[i], t.id, i); - }); - $$.data.xs[t.id] = x; - }); -}; -ChartInternal.prototype.updateTargetXs = function (targets, xs) { - var $$ = this; - targets.forEach(function (t) { - if (xs[t.id]) { - $$.updateTargetX([t], xs[t.id]); - } + const totalDataSum = flattenArray( + $$.data.targets + .filter(target => $$.isTargetToShow(target.id)) + .map(target => target.values) + ) + .map(d => d.value) + .reduce((p, c) => p + c, 0); + + $$.addToCache('getTotalDataSum', totalDataSum); + + return totalDataSum +}; + +ChartInternal.prototype.getXValuesOfXKey = function(key, targets) { + var $$ = this, + xValues, + ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []; + ids.forEach(function(id) { + if ($$.getXKey(id) === key) { + xValues = $$.data.xs[id]; + } + }); + return xValues +}; +ChartInternal.prototype.getXValue = function(id, i) { + var $$ = this; + return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) + ? $$.data.xs[id][i] + : i +}; +ChartInternal.prototype.getOtherTargetXs = function() { + var $$ = this, + idsForX = Object.keys($$.data.xs); + return idsForX.length ? $$.data.xs[idsForX[0]] : null +}; +ChartInternal.prototype.getOtherTargetX = function(index) { + var xs = this.getOtherTargetXs(); + return xs && index < xs.length ? xs[index] : null +}; +ChartInternal.prototype.addXs = function(xs) { + var $$ = this; + Object.keys(xs).forEach(function(id) { + $$.config.data_xs[id] = xs[id]; + }); +}; +ChartInternal.prototype.addName = function(data) { + var $$ = this, + name; + if (data) { + name = $$.config.data_names[data.id]; + data.name = name !== undefined ? name : data.id; + } + return data +}; +ChartInternal.prototype.getValueOnIndex = function(values, index) { + var valueOnIndex = values.filter(function(v) { + return v.index === index + }); + return valueOnIndex.length ? valueOnIndex[0] : null +}; +ChartInternal.prototype.updateTargetX = function(targets, x) { + var $$ = this; + targets.forEach(function(t) { + t.values.forEach(function(v, i) { + v.x = $$.generateTargetX(x[i], t.id, i); }); + $$.data.xs[t.id] = x; + }); +}; +ChartInternal.prototype.updateTargetXs = function(targets, xs) { + var $$ = this; + targets.forEach(function(t) { + if (xs[t.id]) { + $$.updateTargetX([t], xs[t.id]); + } + }); +}; +ChartInternal.prototype.generateTargetX = function(rawX, id, index) { + var $$ = this, + x; + if ($$.isTimeSeries()) { + x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index)); + } else if ($$.isCustomX() && !$$.isCategorized()) { + x = isValue(rawX) ? +rawX : $$.getXValue(id, index); + } else { + x = index; + } + return x +}; +ChartInternal.prototype.cloneTarget = function(target) { + return { + id: target.id, + id_org: target.id_org, + values: target.values.map(function(d) { + return { + x: d.x, + value: d.value, + id: d.id + } + }) + } }; -ChartInternal.prototype.generateTargetX = function (rawX, id, index) { - var $$ = this, - x; - if ($$.isTimeSeries()) { - x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index)); - } else if ($$.isCustomX() && !$$.isCategorized()) { - x = isValue(rawX) ? +rawX : $$.getXValue(id, index); - } else { - x = index; - } - return x; -}; -ChartInternal.prototype.cloneTarget = function (target) { - return { - id: target.id, - id_org: target.id_org, - values: target.values.map(function (d) { - return { - x: d.x, - value: d.value, - id: d.id - }; - }) - }; -}; -ChartInternal.prototype.getMaxDataCount = function () { - var $$ = this; - return $$.d3.max($$.data.targets, function (t) { - return t.values.length; - }); +ChartInternal.prototype.getMaxDataCount = function() { + var $$ = this; + return $$.d3.max($$.data.targets, function(t) { + return t.values.length + }) }; -ChartInternal.prototype.mapToIds = function (targets) { - return targets.map(function (d) { - return d.id; - }); +ChartInternal.prototype.mapToIds = function(targets) { + return targets.map(function(d) { + return d.id + }) }; -ChartInternal.prototype.mapToTargetIds = function (ids) { - var $$ = this; - return ids ? [].concat(ids) : $$.mapToIds($$.data.targets); +ChartInternal.prototype.mapToTargetIds = function(ids) { + var $$ = this; + return ids ? [].concat(ids) : $$.mapToIds($$.data.targets) }; -ChartInternal.prototype.hasTarget = function (targets, id) { - var ids = this.mapToIds(targets), - i; - for (i = 0; i < ids.length; i++) { - if (ids[i] === id) { - return true; - } +ChartInternal.prototype.hasTarget = function(targets, id) { + var ids = this.mapToIds(targets), + i; + for (i = 0; i < ids.length; i++) { + if (ids[i] === id) { + return true } - return false; + } + return false }; -ChartInternal.prototype.isTargetToShow = function (targetId) { - return this.hiddenTargetIds.indexOf(targetId) < 0; +ChartInternal.prototype.isTargetToShow = function(targetId) { + return this.hiddenTargetIds.indexOf(targetId) < 0 }; -ChartInternal.prototype.isLegendToShow = function (targetId) { - return this.hiddenLegendIds.indexOf(targetId) < 0; +ChartInternal.prototype.isLegendToShow = function(targetId) { + return this.hiddenLegendIds.indexOf(targetId) < 0 }; /** @@ -6594,15 +8329,15 @@ ChartInternal.prototype.isLegendToShow = function (targetId) { * @return {Array} */ ChartInternal.prototype.getTargetsToShow = function() { - const $$ = this; - return $$.filterTargetsToShow($$.data.targets); + const $$ = this; + return $$.filterTargetsToShow($$.data.targets) }; -ChartInternal.prototype.filterTargetsToShow = function (targets) { - var $$ = this; - return targets.filter(function (t) { - return $$.isTargetToShow(t.id); - }); +ChartInternal.prototype.filterTargetsToShow = function(targets) { + var $$ = this; + return targets.filter(function(t) { + return $$.isTargetToShow(t.id) + }) }; /** @@ -6610,123 +8345,139 @@ ChartInternal.prototype.filterTargetsToShow = function (targets) { */ ChartInternal.prototype.getTargets = function() { const $$ = this; - return $$.data.targets; -}; - -ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) { - var $$ = this; - var xs = $$.d3.set($$.d3.merge(targets.map(function (t) { - return t.values.map(function (v) { - return +v.x; - }); - }))).values(); - xs = $$.isTimeSeries() ? xs.map(function (x) { - return new Date(+x); - }) : xs.map(function (x) { - return +x; - }); - return xs.sort(function (a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - }); -}; -ChartInternal.prototype.addHiddenTargetIds = function (targetIds) { - targetIds = (targetIds instanceof Array) ? targetIds : new Array(targetIds); - for (var i = 0; i < targetIds.length; i++) { - if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) { - this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]); - } + return $$.data.targets +}; + +ChartInternal.prototype.mapTargetsToUniqueXs = function(targets) { + var $$ = this; + var xs = $$.d3 + .set( + $$.d3.merge( + targets.map(function(t) { + return t.values.map(function(v) { + return +v.x + }) + }) + ) + ) + .values(); + xs = $$.isTimeSeries() + ? xs.map(function(x) { + return new Date(+x) + }) + : xs.map(function(x) { + return +x + }); + return xs.sort(function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN + }) +}; +ChartInternal.prototype.addHiddenTargetIds = function(targetIds) { + targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds); + for (var i = 0; i < targetIds.length; i++) { + if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) { + this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]); } - this.resetCache(); + } + this.resetCache(); }; -ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) { - this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); - this.resetCache(); +ChartInternal.prototype.removeHiddenTargetIds = function(targetIds) { + this.hiddenTargetIds = this.hiddenTargetIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); + this.resetCache(); }; -ChartInternal.prototype.addHiddenLegendIds = function (targetIds) { - targetIds = (targetIds instanceof Array) ? targetIds : new Array(targetIds); - for (var i = 0; i < targetIds.length; i++) { - if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) { - this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]); - } +ChartInternal.prototype.addHiddenLegendIds = function(targetIds) { + targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds); + for (var i = 0; i < targetIds.length; i++) { + if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) { + this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]); } + } }; -ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) { - this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); -}; -ChartInternal.prototype.getValuesAsIdKeyed = function (targets) { - var ys = {}; - targets.forEach(function (t) { - ys[t.id] = []; - t.values.forEach(function (v) { - ys[t.id].push(v.value); - }); +ChartInternal.prototype.removeHiddenLegendIds = function(targetIds) { + this.hiddenLegendIds = this.hiddenLegendIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); +}; +ChartInternal.prototype.getValuesAsIdKeyed = function(targets) { + var ys = {}; + targets.forEach(function(t) { + ys[t.id] = []; + t.values.forEach(function(v) { + ys[t.id].push(v.value); }); - return ys; -}; -ChartInternal.prototype.checkValueInTargets = function (targets, checker) { - var ids = Object.keys(targets), - i, j, values; - for (i = 0; i < ids.length; i++) { - values = targets[ids[i]].values; - for (j = 0; j < values.length; j++) { - if (checker(values[j].value)) { - return true; - } - } + }); + return ys +}; +ChartInternal.prototype.checkValueInTargets = function(targets, checker) { + var ids = Object.keys(targets), + i, + j, + values; + for (i = 0; i < ids.length; i++) { + values = targets[ids[i]].values; + for (j = 0; j < values.length; j++) { + if (checker(values[j].value)) { + return true + } } - return false; -}; -ChartInternal.prototype.hasNegativeValueInTargets = function (targets) { - return this.checkValueInTargets(targets, function (v) { - return v < 0; - }); -}; -ChartInternal.prototype.hasPositiveValueInTargets = function (targets) { - return this.checkValueInTargets(targets, function (v) { - return v > 0; - }); -}; -ChartInternal.prototype.isOrderDesc = function () { - var config = this.config; - return typeof (config.data_order) === 'string' && config.data_order.toLowerCase() === 'desc'; -}; -ChartInternal.prototype.isOrderAsc = function () { - var config = this.config; - return typeof (config.data_order) === 'string' && config.data_order.toLowerCase() === 'asc'; -}; -ChartInternal.prototype.getOrderFunction = function () { - var $$ = this, - config = $$.config, - orderAsc = $$.isOrderAsc(), - orderDesc = $$.isOrderDesc(); - if (orderAsc || orderDesc) { - var reducer = function (p, c) { - return p + Math.abs(c.value); - }; - return function (t1, t2) { - var t1Sum = t1.values.reduce(reducer, 0), - t2Sum = t2.values.reduce(reducer, 0); - return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum; - }; - } else if (isFunction(config.data_order)) { - return config.data_order; - } else if (isArray(config.data_order)) { - var order = config.data_order; - return function (t1, t2) { - return order.indexOf(t1.id) - order.indexOf(t2.id); - }; + } + return false +}; +ChartInternal.prototype.hasNegativeValueInTargets = function(targets) { + return this.checkValueInTargets(targets, function(v) { + return v < 0 + }) +}; +ChartInternal.prototype.hasPositiveValueInTargets = function(targets) { + return this.checkValueInTargets(targets, function(v) { + return v > 0 + }) +}; +ChartInternal.prototype.isOrderDesc = function() { + var config = this.config; + return ( + typeof config.data_order === 'string' && + config.data_order.toLowerCase() === 'desc' + ) +}; +ChartInternal.prototype.isOrderAsc = function() { + var config = this.config; + return ( + typeof config.data_order === 'string' && + config.data_order.toLowerCase() === 'asc' + ) +}; +ChartInternal.prototype.getOrderFunction = function() { + var $$ = this, + config = $$.config, + orderAsc = $$.isOrderAsc(), + orderDesc = $$.isOrderDesc(); + if (orderAsc || orderDesc) { + var reducer = function(p, c) { + return p + Math.abs(c.value) + }; + return function(t1, t2) { + var t1Sum = t1.values.reduce(reducer, 0), + t2Sum = t2.values.reduce(reducer, 0); + return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum + } + } else if (isFunction(config.data_order)) { + return config.data_order + } else if (isArray(config.data_order)) { + var order = config.data_order; + return function(t1, t2) { + return order.indexOf(t1.id) - order.indexOf(t2.id) } + } }; -ChartInternal.prototype.orderTargets = function (targets) { - var fct = this.getOrderFunction(); - if (fct) { - targets.sort(fct); - } - return targets; +ChartInternal.prototype.orderTargets = function(targets) { + var fct = this.getOrderFunction(); + if (fct) { + targets.sort(fct); + } + return targets }; /** @@ -6736,65 +8487,77 @@ ChartInternal.prototype.orderTargets = function (targets) { * @param {Number} index * @return {Array} */ -ChartInternal.prototype.filterByIndex = function (targets, index) { - return this.d3.merge(targets.map((t) => t.values.filter((v) => v.index === index))); -}; - -ChartInternal.prototype.filterByX = function (targets, x) { - return this.d3.merge(targets.map(function (t) { - return t.values; - })).filter(function (v) { - return v.x - x === 0; - }); -}; -ChartInternal.prototype.filterRemoveNull = function (data) { - return data.filter(function (d) { - return isValue(d.value); - }); +ChartInternal.prototype.filterByIndex = function(targets, index) { + return this.d3.merge( + targets.map(t => t.values.filter(v => v.index === index)) + ) +}; + +ChartInternal.prototype.filterByX = function(targets, x) { + return this.d3 + .merge( + targets.map(function(t) { + return t.values + }) + ) + .filter(function(v) { + return v.x - x === 0 + }) }; -ChartInternal.prototype.filterByXDomain = function (targets, xDomain) { - return targets.map(function (t) { - return { - id: t.id, - id_org: t.id_org, - values: t.values.filter(function (v) { - return xDomain[0] <= v.x && v.x <= xDomain[1]; - }) - }; - }); +ChartInternal.prototype.filterRemoveNull = function(data) { + return data.filter(function(d) { + return isValue(d.value) + }) }; -ChartInternal.prototype.hasDataLabel = function () { - var config = this.config; - if (typeof config.data_labels === 'boolean' && config.data_labels) { - return true; - } else if (typeof config.data_labels === 'object' && notEmpty(config.data_labels)) { - return true; - } - return false; -}; -ChartInternal.prototype.getDataLabelLength = function (min, max, key) { - var $$ = this, - lengths = [0, 0], - paddingCoef = 1.3; - $$.selectChart.select('svg').selectAll('.dummy') - .data([min, max]) - .enter().append('text') - .text(function (d) { - return $$.dataLabelFormat(d.id)(d); - }) - .each(function (d, i) { - lengths[i] = getBBox(this)[key] * paddingCoef; - }) - .remove(); - return lengths; +ChartInternal.prototype.filterByXDomain = function(targets, xDomain) { + return targets.map(function(t) { + return { + id: t.id, + id_org: t.id_org, + values: t.values.filter(function(v) { + return xDomain[0] <= v.x && v.x <= xDomain[1] + }) + } + }) +}; +ChartInternal.prototype.hasDataLabel = function() { + var config = this.config; + if (typeof config.data_labels === 'boolean' && config.data_labels) { + return true + } else if ( + typeof config.data_labels === 'object' && + notEmpty(config.data_labels) + ) { + return true + } + return false +}; +ChartInternal.prototype.getDataLabelLength = function(min, max, key) { + var $$ = this, + lengths = [0, 0], + paddingCoef = 1.3; + $$.selectChart + .select('svg') + .selectAll('.dummy') + .data([min, max]) + .enter() + .append('text') + .text(function(d) { + return $$.dataLabelFormat(d.id)(d) + }) + .each(function(d, i) { + lengths[i] = getBBox(this)[key] * paddingCoef; + }) + .remove(); + return lengths }; /** * Returns true if the given data point is not arc type, otherwise false. * @param {Object} d The data point * @return {boolean} */ -ChartInternal.prototype.isNoneArc = function (d) { - return this.hasTarget(this.data.targets, d.id); +ChartInternal.prototype.isNoneArc = function(d) { + return this.hasTarget(this.data.targets, d.id) }; /** @@ -6802,8 +8565,8 @@ ChartInternal.prototype.isNoneArc = function (d) { * @param {Object} d The data point * @return {boolean} */ -ChartInternal.prototype.isArc = function (d) { - return 'data' in d && this.hasTarget(this.data.targets, d.data.id); +ChartInternal.prototype.isArc = function(d) { + return 'data' in d && this.hasTarget(this.data.targets, d.data.id) }; /** @@ -6814,22 +8577,31 @@ ChartInternal.prototype.isArc = function (d) { * @param {Array} pos An [x,y] coordinate * @return {Object|undefined} */ -ChartInternal.prototype.findClosestFromTargets = function (targets, pos) { - const $$ = this; - - // for each target, find the closest point - const candidates = targets - .map((t) => $$.findClosest(t.values, pos, $$.config.tooltip_horizontal ? $$.horizontalDistance.bind($$) : $$.dist.bind($$), $$.config.point_sensitivity)) - .filter((v) => v); - - // returns the closest of candidates - if (candidates.length === 0) { - return undefined; - } else if (candidates.length === 1) { - return candidates[0]; - } else { - return $$.findClosest(candidates, pos, $$.dist.bind($$)); - } +ChartInternal.prototype.findClosestFromTargets = function(targets, pos) { + const $$ = this; + + // for each target, find the closest point + const candidates = targets + .map(t => + $$.findClosest( + t.values, + pos, + $$.config.tooltip_horizontal + ? $$.horizontalDistance.bind($$) + : $$.dist.bind($$), + $$.config.point_sensitivity + ) + ) + .filter(v => v); + + // returns the closest of candidates + if (candidates.length === 0) { + return undefined + } else if (candidates.length === 1) { + return candidates[0] + } else { + return $$.findClosest(candidates, pos, $$.dist.bind($$)) + } }; /** @@ -6839,23 +8611,22 @@ ChartInternal.prototype.findClosestFromTargets = function (targets, pos) { * @param {Array} x A value on X axis * @return {Object|undefined} */ -ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) { - let closest; - let diff; - - targets - .forEach((t) => { - t.values.forEach((d) => { - let newDiff = Math.abs(x - d.x); - - if (diff === undefined || newDiff < diff) { - closest = d; - diff = newDiff; - } - }); - }); +ChartInternal.prototype.findClosestFromTargetsByX = function(targets, x) { + let closest; + let diff; + + targets.forEach(t => { + t.values.forEach(d => { + let newDiff = Math.abs(x - d.x); + + if (diff === undefined || newDiff < diff) { + closest = d; + diff = newDiff; + } + }); + }); - return closest; + return closest }; /** @@ -6870,77 +8641,92 @@ ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) { * @param {Number} minDist Minimal distance to satisfy * @return {Object|undefined} Closest data point */ -ChartInternal.prototype.findClosest = function (dataPoints, pos, computeDist, minDist = Infinity) { - const $$ = this; - - let closest; - - // find closest bar - dataPoints - .filter((v) => v && $$.isBarType(v.id)) - .forEach(function (v) { - if (!closest) { - const shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node(); - if ($$.isWithinBar(pos, shape)) { - closest = v; - } - } - }); +ChartInternal.prototype.findClosest = function( + dataPoints, + pos, + computeDist, + minDist = Infinity +) { + const $$ = this; - // find closest point from non-bar - dataPoints - .filter((v) => v && !$$.isBarType(v.id)) - .forEach((v) => { - let d = computeDist(v, pos); - if (d < minDist) { - minDist = d; - closest = v; - } - }); + let closest; + + // find closest bar + dataPoints + .filter(v => v && $$.isBarType(v.id)) + .forEach(function(v) { + if (!closest) { + const shape = $$.main + .select( + '.' + + CLASS.bars + + $$.getTargetSelectorSuffix(v.id) + + ' .' + + CLASS.bar + + '-' + + v.index + ) + .node(); + if ($$.isWithinBar(pos, shape)) { + closest = v; + } + } + }); - return closest; + // find closest point from non-bar + dataPoints + .filter(v => v && !$$.isBarType(v.id)) + .forEach(v => { + let d = computeDist(v, pos); + if (d < minDist) { + minDist = d; + closest = v; + } + }); + + return closest }; -ChartInternal.prototype.dist = function (data, pos) { - var $$ = this, - config = $$.config, - xIndex = config.axis_rotated ? 1 : 0, - yIndex = config.axis_rotated ? 0 : 1, - y = $$.circleY(data, data.index), - x = $$.x(data.x); - return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2)); +ChartInternal.prototype.dist = function(data, pos) { + var $$ = this, + config = $$.config, + xIndex = config.axis_rotated ? 1 : 0, + yIndex = config.axis_rotated ? 0 : 1, + y = $$.circleY(data, data.index), + x = $$.x(data.x); + return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2)) }; ChartInternal.prototype.horizontalDistance = function(data, pos) { - var $$ = this, - config = $$.config, - xIndex = config.axis_rotated ? 1 : 0, - x = $$.x(data.x); + var $$ = this, + config = $$.config, + xIndex = config.axis_rotated ? 1 : 0, + x = $$.x(data.x); - return Math.abs(x - pos[xIndex]); + return Math.abs(x - pos[xIndex]) }; -ChartInternal.prototype.convertValuesToStep = function (values) { - var converted = [].concat(values), - i; +ChartInternal.prototype.convertValuesToStep = function(values) { + var converted = [].concat(values), + i; - if (!this.isCategorized()) { - return values; - } + if (!this.isCategorized()) { + return values + } - for (i = values.length + 1; 0 < i; i--) { - converted[i] = converted[i - 1]; - } + for (i = values.length + 1; 0 < i; i--) { + converted[i] = converted[i - 1]; + } - converted[0] = { - x: converted[0].x - 1, - value: converted[0].value, - id: converted[0].id - }; - converted[values.length + 1] = { - x: converted[values.length].x + 1, - value: converted[values.length].value, - id: converted[values.length].id - }; + converted[0] = { + x: converted[0].x - 1, + value: converted[0].value, + id: converted[0].id + }; + converted[values.length + 1] = { + x: converted[values.length].x + 1, + value: converted[values.length].value, + id: converted[values.length].id + }; - return converted; + return converted }; /** @@ -6953,906 +8739,1292 @@ ChartInternal.prototype.convertValuesToStep = function (values) { * @private */ ChartInternal.prototype.getRatio = function(type, d, asPercent = false) { - const $$ = this; - const api = $$.api; - let ratio = 0; - - if (d && api.data.shown.call(api).length) { - ratio = d.ratio || d.value; - - if (type === "arc") { - if ($$.hasType('gauge')) { - ratio = (d.endAngle - d.startAngle) / (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1)); - } else { - const total = $$.getTotalDataSum(); - - ratio = d.value / total; - } - } else if (type === "index") { - const total = $$.getTotalPerIndex($$.axis.getId(d.id)); - - d.ratio = isNumber(d.value) && total && total[d.index] > 0 ? - d.value / total[d.index] : 0; - - ratio = d.ratio; - } - } - - return asPercent && ratio ? ratio * 100 : ratio; -}; - -ChartInternal.prototype.updateDataAttributes = function (name, attrs) { - var $$ = this, - config = $$.config, - current = config['data_' + name]; - if (typeof attrs === 'undefined') { - return current; - } - Object.keys(attrs).forEach(function (id) { - current[id] = attrs[id]; - }); - $$.redraw({ - withLegend: true - }); - return current; -}; - -ChartInternal.prototype.load = function (targets, args) { - var $$ = this; - if (targets) { - // filter loading targets if needed - if (args.filter) { - targets = targets.filter(args.filter); - } - // set type if args.types || args.type specified - if (args.type || args.types) { - targets.forEach(function (t) { - var type = args.types && args.types[t.id] ? args.types[t.id] : args.type; - $$.setTargetType(t.id, type); - }); - } - // Update/Add data - $$.data.targets.forEach(function (d) { - for (var i = 0; i < targets.length; i++) { - if (d.id === targets[i].id) { - d.values = targets[i].values; - targets.splice(i, 1); - break; - } - } - }); - $$.data.targets = $$.data.targets.concat(targets); // add remained - } - - // Set targets - $$.updateTargets($$.data.targets); - - // Redraw with new targets - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); - - if (args.done) { args.done(); } -}; -ChartInternal.prototype.loadFromArgs = function (args) { - var $$ = this; - - $$.resetCache(); + const $$ = this; + const api = $$.api; + let ratio = 0; - if (args.data) { - $$.load($$.convertDataToTargets(args.data), args); - } - else if (args.url) { - $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) { - $$.load($$.convertDataToTargets(data), args); - }); - } - else if (args.json) { - $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args); - } - else if (args.rows) { - $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args); - } - else if (args.columns) { - $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args); - } - else { - $$.load(null, args); - } -}; -ChartInternal.prototype.unload = function (targetIds, done) { - var $$ = this; + if (d && api.data.shown.call(api).length) { + ratio = d.ratio || d.value; - $$.resetCache(); + if (type === 'arc') { + if ($$.hasType('gauge')) { + ratio = + (d.endAngle - d.startAngle) / + (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1)); + } else { + const total = $$.getTotalDataSum(); - if (!done) { - done = function () {}; - } - // filter existing target - targetIds = targetIds.filter(function (id) { return $$.hasTarget($$.data.targets, id); }); - // If no target, call done and return - if (!targetIds || targetIds.length === 0) { - done(); - return; - } - $$.svg.selectAll(targetIds.map(function (id) { return $$.selectorTarget(id); })) - .transition() - .style('opacity', 0) - .remove() - .call($$.endall, done); - targetIds.forEach(function (id) { - // Reset fadein for future load - $$.withoutFadeIn[id] = false; - // Remove target's elements - if ($$.legend) { - $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove(); - } - // Remove target - $$.data.targets = $$.data.targets.filter(function (t) { - return t.id !== id; - }); - }); -}; + ratio = d.value / total; + } + } else if (type === 'index') { + const total = $$.getTotalPerIndex($$.axis.getId(d.id)); -ChartInternal.prototype.getYDomainMin = function (targets) { - var $$ = this, config = $$.config, - ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), - j, k, baseId, idsInGroup, id, hasNegativeValue; - if (config.data_groups.length > 0) { - hasNegativeValue = $$.hasNegativeValueInTargets(targets); - for (j = 0; j < config.data_groups.length; j++) { - // Determine baseId - idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; }); - if (idsInGroup.length === 0) { continue; } - baseId = idsInGroup[0]; - // Consider negative values - if (hasNegativeValue && ys[baseId]) { - ys[baseId].forEach(function (v, i) { - ys[baseId][i] = v < 0 ? v : 0; - }); - } - // Compute min - for (k = 1; k < idsInGroup.length; k++) { - id = idsInGroup[k]; - if (! ys[id]) { continue; } - ys[id].forEach(function (v, i) { - if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) { - ys[baseId][i] += +v; - } - }); - } - } - } - return $$.d3.min(Object.keys(ys).map(function (key) { return $$.d3.min(ys[key]); })); -}; -ChartInternal.prototype.getYDomainMax = function (targets) { - var $$ = this, config = $$.config, - ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), - j, k, baseId, idsInGroup, id, hasPositiveValue; - if (config.data_groups.length > 0) { - hasPositiveValue = $$.hasPositiveValueInTargets(targets); - for (j = 0; j < config.data_groups.length; j++) { - // Determine baseId - idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; }); - if (idsInGroup.length === 0) { continue; } - baseId = idsInGroup[0]; - // Consider positive values - if (hasPositiveValue && ys[baseId]) { - ys[baseId].forEach(function (v, i) { - ys[baseId][i] = v > 0 ? v : 0; - }); - } - // Compute max - for (k = 1; k < idsInGroup.length; k++) { - id = idsInGroup[k]; - if (! ys[id]) { continue; } - ys[id].forEach(function (v, i) { - if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) { - ys[baseId][i] += +v; - } - }); - } - } + d.ratio = + isNumber(d.value) && total && total[d.index] > 0 + ? d.value / total[d.index] + : 0; + + ratio = d.ratio; } - return $$.d3.max(Object.keys(ys).map(function (key) { return $$.d3.max(ys[key]); })); + } + + return asPercent && ratio ? ratio * 100 : ratio }; -ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) { - var $$ = this, config = $$.config; - if ($$.isAxisNormalized(axisId)) { - return [0, 100]; +ChartInternal.prototype.updateDataAttributes = function(name, attrs) { + var $$ = this, + config = $$.config, + current = config['data_' + name]; + if (typeof attrs === 'undefined') { + return current + } + Object.keys(attrs).forEach(function(id) { + current[id] = attrs[id]; + }); + $$.redraw({ + withLegend: true + }); + return current +}; + +ChartInternal.prototype.load = function(targets, args) { + var $$ = this; + if (targets) { + // filter loading targets if needed + if (args.filter) { + targets = targets.filter(args.filter); + } + // set type if args.types || args.type specified + if (args.type || args.types) { + targets.forEach(function(t) { + var type = args.types && args.types[t.id] ? args.types[t.id] : args.type; + $$.setTargetType(t.id, type); + }); } + // Update/Add data + $$.data.targets.forEach(function(d) { + for (var i = 0; i < targets.length; i++) { + if (d.id === targets[i].id) { + d.values = targets[i].values; + targets.splice(i, 1); + break + } + } + }); + $$.data.targets = $$.data.targets.concat(targets); // add remained + } - var targetsByAxisId = targets.filter(function (t) { return $$.axis.getId(t.id) === axisId; }), - yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId, - yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, - yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, - yDomainMin = $$.getYDomainMin(yTargets), - yDomainMax = $$.getYDomainMax(yTargets), - domain, domainLength, padding_top, padding_bottom, - center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, - yDomainAbs, lengths, diff, ratio, isAllPositive, isAllNegative, - isZeroBased = ($$.hasType('bar', yTargets) && config.bar_zerobased) || ($$.hasType('area', yTargets) && config.area_zerobased), - isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, - showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, - showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; + // Set targets + $$.updateTargets($$.data.targets); - // MEMO: avoid inverting domain unexpectedly - yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? (yDomainMin < yMax ? yDomainMin : yMax - 10) : yDomainMin; - yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? (yMin < yDomainMax ? yDomainMax : yMin + 10) : yDomainMax; + // Redraw with new targets + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); - if (yTargets.length === 0) { // use current domain if target of axisId is none - return axisId === 'y2' ? $$.y2.domain() : $$.y.domain(); - } - if (isNaN(yDomainMin)) { // set minimum to zero when not number - yDomainMin = 0; - } - if (isNaN(yDomainMax)) { // set maximum to have same value as yDomainMin - yDomainMax = yDomainMin; + if (args.done) { + args.done(); + } +}; +ChartInternal.prototype.loadFromArgs = function(args) { + var $$ = this; + + $$.resetCache(); + + if (args.data) { + $$.load($$.convertDataToTargets(args.data), args); + } else if (args.url) { + $$.convertUrlToData( + args.url, + args.mimeType, + args.headers, + args.keys, + function(data) { + $$.load($$.convertDataToTargets(data), args); + } + ); + } else if (args.json) { + $$.load( + $$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), + args + ); + } else if (args.rows) { + $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args); + } else if (args.columns) { + $$.load( + $$.convertDataToTargets($$.convertColumnsToData(args.columns)), + args + ); + } else { + $$.load(null, args); + } +}; +ChartInternal.prototype.unload = function(targetIds, done) { + var $$ = this; + + $$.resetCache(); + + if (!done) { + done = function() {}; + } + // filter existing target + targetIds = targetIds.filter(function(id) { + return $$.hasTarget($$.data.targets, id) + }); + // If no target, call done and return + if (!targetIds || targetIds.length === 0) { + done(); + return + } + $$.svg + .selectAll( + targetIds.map(function(id) { + return $$.selectorTarget(id) + }) + ) + .transition() + .style('opacity', 0) + .remove() + .call($$.endall, done); + targetIds.forEach(function(id) { + // Reset fadein for future load + $$.withoutFadeIn[id] = false; + // Remove target's elements + if ($$.legend) { + $$.legend + .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)) + .remove(); } - if (yDomainMin === yDomainMax) { - yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0; + // Remove target + $$.data.targets = $$.data.targets.filter(function(t) { + return t.id !== id + }); + }); +}; + +ChartInternal.prototype.getYDomainMin = function(targets) { + var $$ = this, + config = $$.config, + ids = $$.mapToIds(targets), + ys = $$.getValuesAsIdKeyed(targets), + j, + k, + baseId, + idsInGroup, + id, + hasNegativeValue; + if (config.data_groups.length > 0) { + hasNegativeValue = $$.hasNegativeValueInTargets(targets); + for (j = 0; j < config.data_groups.length; j++) { + // Determine baseId + idsInGroup = config.data_groups[j].filter(function(id) { + return ids.indexOf(id) >= 0 + }); + if (idsInGroup.length === 0) { + continue + } + baseId = idsInGroup[0]; + // Consider negative values + if (hasNegativeValue && ys[baseId]) { + ys[baseId].forEach(function(v, i) { + ys[baseId][i] = v < 0 ? v : 0; + }); + } + // Compute min + for (k = 1; k < idsInGroup.length; k++) { + id = idsInGroup[k]; + if (!ys[id]) { + continue + } + ys[id].forEach(function(v, i) { + if ( + $$.axis.getId(id) === $$.axis.getId(baseId) && + ys[baseId] && + !(hasNegativeValue && +v > 0) + ) { + ys[baseId][i] += +v; + } + }); + } } - isAllPositive = yDomainMin >= 0 && yDomainMax >= 0; - isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; - - // Cancel zerobased if axis_*_min / axis_*_max specified - if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) { - isZeroBased = false; + } + return $$.d3.min( + Object.keys(ys).map(function(key) { + return $$.d3.min(ys[key]) + }) + ) +}; +ChartInternal.prototype.getYDomainMax = function(targets) { + var $$ = this, + config = $$.config, + ids = $$.mapToIds(targets), + ys = $$.getValuesAsIdKeyed(targets), + j, + k, + baseId, + idsInGroup, + id, + hasPositiveValue; + if (config.data_groups.length > 0) { + hasPositiveValue = $$.hasPositiveValueInTargets(targets); + for (j = 0; j < config.data_groups.length; j++) { + // Determine baseId + idsInGroup = config.data_groups[j].filter(function(id) { + return ids.indexOf(id) >= 0 + }); + if (idsInGroup.length === 0) { + continue + } + baseId = idsInGroup[0]; + // Consider positive values + if (hasPositiveValue && ys[baseId]) { + ys[baseId].forEach(function(v, i) { + ys[baseId][i] = v > 0 ? v : 0; + }); + } + // Compute max + for (k = 1; k < idsInGroup.length; k++) { + id = idsInGroup[k]; + if (!ys[id]) { + continue + } + ys[id].forEach(function(v, i) { + if ( + $$.axis.getId(id) === $$.axis.getId(baseId) && + ys[baseId] && + !(hasPositiveValue && +v < 0) + ) { + ys[baseId][i] += +v; + } + }); + } } + } + return $$.d3.max( + Object.keys(ys).map(function(key) { + return $$.d3.max(ys[key]) + }) + ) +}; +ChartInternal.prototype.getYDomain = function(targets, axisId, xDomain) { + var $$ = this, + config = $$.config; + + if ($$.isAxisNormalized(axisId)) { + return [0, 100] + } - // Bar/Area chart should be 0-based if all positive|negative - if (isZeroBased) { - if (isAllPositive) { yDomainMin = 0; } - if (isAllNegative) { yDomainMax = 0; } - } + var targetsByAxisId = targets.filter(function(t) { + return $$.axis.getId(t.id) === axisId + }), + yTargets = xDomain + ? $$.filterByXDomain(targetsByAxisId, xDomain) + : targetsByAxisId, + yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, + yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, + yDomainMin = $$.getYDomainMin(yTargets), + yDomainMax = $$.getYDomainMax(yTargets), + domain, + domainLength, + padding_top, + padding_bottom, + center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, + yDomainAbs, + lengths, + diff, + ratio, + isAllPositive, + isAllNegative, + isZeroBased = + ($$.hasType('bar', yTargets) && config.bar_zerobased) || + ($$.hasType('area', yTargets) && config.area_zerobased), + isInverted = + axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, + showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, + showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; + + // MEMO: avoid inverting domain unexpectedly + yDomainMin = isValue(yMin) + ? yMin + : isValue(yMax) + ? yDomainMin < yMax + ? yDomainMin + : yMax - 10 + : yDomainMin; + yDomainMax = isValue(yMax) + ? yMax + : isValue(yMin) + ? yMin < yDomainMax + ? yDomainMax + : yMin + 10 + : yDomainMax; + + if (yTargets.length === 0) { + // use current domain if target of axisId is none + return axisId === 'y2' ? $$.y2.domain() : $$.y.domain() + } + if (isNaN(yDomainMin)) { + // set minimum to zero when not number + yDomainMin = 0; + } + if (isNaN(yDomainMax)) { + // set maximum to have same value as yDomainMin + yDomainMax = yDomainMin; + } + if (yDomainMin === yDomainMax) { + yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0); + } + isAllPositive = yDomainMin >= 0 && yDomainMax >= 0; + isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; - domainLength = Math.abs(yDomainMax - yDomainMin); - padding_top = padding_bottom = domainLength * 0.1; + // Cancel zerobased if axis_*_min / axis_*_max specified + if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) { + isZeroBased = false; + } - if (typeof center !== 'undefined') { - yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); - yDomainMax = center + yDomainAbs; - yDomainMin = center - yDomainAbs; + // Bar/Area chart should be 0-based if all positive|negative + if (isZeroBased) { + if (isAllPositive) { + yDomainMin = 0; + } + if (isAllNegative) { + yDomainMax = 0; } - // add padding for data label - if (showHorizontalDataLabel) { - lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width'); - diff = diffDomain($$.y.range()); - ratio = [lengths[0] / diff, lengths[1] / diff]; - padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1])); - padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1])); - } else if (showVerticalDataLabel) { - lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height'); + } - const pixelsToAxisPadding = $$.getY( - config[`axis_${axisId}_type`], - // input domain as pixels - [0, config.axis_rotated ? $$.width : $$.height ], - // output range as axis padding - [ 0, domainLength ] - ); + domainLength = Math.abs(yDomainMax - yDomainMin); + padding_top = padding_bottom = domainLength * 0.1; - padding_top += pixelsToAxisPadding(lengths[1]); - padding_bottom += pixelsToAxisPadding(lengths[0]); - } - if (axisId === 'y' && notEmpty(config.axis_y_padding)) { - padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength); - padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength); - } - if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) { - padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength); - padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength); - } - // Bar/Area chart should be 0-based if all positive|negative - if (isZeroBased) { - if (isAllPositive) { padding_bottom = yDomainMin; } - if (isAllNegative) { padding_top = -yDomainMax; } - } - domain = [yDomainMin - padding_bottom, yDomainMax + padding_top]; - return isInverted ? domain.reverse() : domain; -}; -ChartInternal.prototype.getXDomainMin = function (targets) { - var $$ = this, config = $$.config; - return isDefined(config.axis_x_min) ? - ($$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min) : - $$.d3.min(targets, function (t) { return $$.d3.min(t.values, function (v) { return v.x; }); }); -}; -ChartInternal.prototype.getXDomainMax = function (targets) { - var $$ = this, config = $$.config; - return isDefined(config.axis_x_max) ? - ($$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max) : - $$.d3.max(targets, function (t) { return $$.d3.max(t.values, function (v) { return v.x; }); }); -}; -ChartInternal.prototype.getXDomainPadding = function (domain) { - var $$ = this, config = $$.config, - diff = domain[1] - domain[0], - maxDataCount, padding, paddingLeft, paddingRight; - if ($$.isCategorized()) { - padding = 0; - } else if ($$.hasType('bar')) { - maxDataCount = $$.getMaxDataCount(); - padding = maxDataCount > 1 ? (diff / (maxDataCount - 1)) / 2 : 0.5; - } else { - padding = diff * 0.01; + if (typeof center !== 'undefined') { + yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); + yDomainMax = center + yDomainAbs; + yDomainMin = center - yDomainAbs; + } + // add padding for data label + if (showHorizontalDataLabel) { + lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width'); + diff = diffDomain($$.y.range()); + ratio = [lengths[0] / diff, lengths[1] / diff]; + padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1])); + padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1])); + } else if (showVerticalDataLabel) { + lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height'); + + const pixelsToAxisPadding = $$.getY( + config[`axis_${axisId}_type`], + // input domain as pixels + [0, config.axis_rotated ? $$.width : $$.height], + // output range as axis padding + [0, domainLength] + ); + + padding_top += pixelsToAxisPadding(lengths[1]); + padding_bottom += pixelsToAxisPadding(lengths[0]); + } + if (axisId === 'y' && notEmpty(config.axis_y_padding)) { + padding_top = $$.axis.getPadding( + config.axis_y_padding, + 'top', + padding_top, + domainLength + ); + padding_bottom = $$.axis.getPadding( + config.axis_y_padding, + 'bottom', + padding_bottom, + domainLength + ); + } + if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) { + padding_top = $$.axis.getPadding( + config.axis_y2_padding, + 'top', + padding_top, + domainLength + ); + padding_bottom = $$.axis.getPadding( + config.axis_y2_padding, + 'bottom', + padding_bottom, + domainLength + ); + } + // Bar/Area chart should be 0-based if all positive|negative + if (isZeroBased) { + if (isAllPositive) { + padding_bottom = yDomainMin; + } + if (isAllNegative) { + padding_top = -yDomainMax; } - if (typeof config.axis_x_padding === 'object' && notEmpty(config.axis_x_padding)) { - paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding; - paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding; - } else if (typeof config.axis_x_padding === 'number') { - paddingLeft = paddingRight = config.axis_x_padding; + } + domain = [yDomainMin - padding_bottom, yDomainMax + padding_top]; + return isInverted ? domain.reverse() : domain +}; +ChartInternal.prototype.getXDomainMin = function(targets) { + var $$ = this, + config = $$.config; + return isDefined(config.axis_x_min) + ? $$.isTimeSeries() + ? this.parseDate(config.axis_x_min) + : config.axis_x_min + : $$.d3.min(targets, function(t) { + return $$.d3.min(t.values, function(v) { + return v.x + }) + }) +}; +ChartInternal.prototype.getXDomainMax = function(targets) { + var $$ = this, + config = $$.config; + return isDefined(config.axis_x_max) + ? $$.isTimeSeries() + ? this.parseDate(config.axis_x_max) + : config.axis_x_max + : $$.d3.max(targets, function(t) { + return $$.d3.max(t.values, function(v) { + return v.x + }) + }) +}; +ChartInternal.prototype.getXDomainPadding = function(domain) { + var $$ = this, + config = $$.config, + diff = domain[1] - domain[0], + maxDataCount, + padding, + paddingLeft, + paddingRight; + if ($$.isCategorized()) { + padding = 0; + } else if ($$.hasType('bar')) { + maxDataCount = $$.getMaxDataCount(); + padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5; + } else { + padding = diff * 0.01; + } + if ( + typeof config.axis_x_padding === 'object' && + notEmpty(config.axis_x_padding) + ) { + paddingLeft = isValue(config.axis_x_padding.left) + ? config.axis_x_padding.left + : padding; + paddingRight = isValue(config.axis_x_padding.right) + ? config.axis_x_padding.right + : padding; + } else if (typeof config.axis_x_padding === 'number') { + paddingLeft = paddingRight = config.axis_x_padding; + } else { + paddingLeft = paddingRight = padding; + } + return { left: paddingLeft, right: paddingRight } +}; +ChartInternal.prototype.getXDomain = function(targets) { + var $$ = this, + xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], + firstX = xDomain[0], + lastX = xDomain[1], + padding = $$.getXDomainPadding(xDomain), + min = 0, + max = 0; + // show center of x domain if min and max are the same + if (firstX - lastX === 0 && !$$.isCategorized()) { + if ($$.isTimeSeries()) { + firstX = new Date(firstX.getTime() * 0.5); + lastX = new Date(lastX.getTime() * 1.5); } else { - paddingLeft = paddingRight = padding; - } - return {left: paddingLeft, right: paddingRight}; -}; -ChartInternal.prototype.getXDomain = function (targets) { - var $$ = this, - xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], - firstX = xDomain[0], lastX = xDomain[1], - padding = $$.getXDomainPadding(xDomain), - min = 0, max = 0; - // show center of x domain if min and max are the same - if ((firstX - lastX) === 0 && !$$.isCategorized()) { - if ($$.isTimeSeries()) { - firstX = new Date(firstX.getTime() * 0.5); - lastX = new Date(lastX.getTime() * 1.5); - } else { - firstX = firstX === 0 ? 1 : (firstX * 0.5); - lastX = lastX === 0 ? -1 : (lastX * 1.5); - } + firstX = firstX === 0 ? 1 : firstX * 0.5; + lastX = lastX === 0 ? -1 : lastX * 1.5; } - if (firstX || firstX === 0) { - min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left; - } - if (lastX || lastX === 0) { - max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right; - } - return [min, max]; -}; -ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) { - var $$ = this, config = $$.config; - - if (withUpdateOrgXDomain) { - $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets))); - $$.orgXDomain = $$.x.domain(); - if (config.zoom_enabled) { $$.zoom.update(); } - $$.subX.domain($$.x.domain()); - if ($$.brush) { $$.brush.updateScale($$.subX); } - } - if (withUpdateXDomain) { - $$.x.domain(domain ? domain : (!$$.brush || $$.brush.empty()) ? $$.orgXDomain : $$.brush.selectionAsValue()); - } - - // Trim domain when too big by zoom mousemove event - if (withTrim) { $$.x.domain($$.trimXDomain($$.x.orgDomain())); } - - return $$.x.domain(); -}; -ChartInternal.prototype.trimXDomain = function (domain) { - var zoomDomain = this.getZoomDomain(), - min = zoomDomain[0], max = zoomDomain[1]; - if (domain[0] <= min) { - domain[1] = +domain[1] + (min - domain[0]); - domain[0] = min; - } - if (max <= domain[1]) { - domain[0] = +domain[0] - (domain[1] - max); - domain[1] = max; - } - return domain; -}; - -ChartInternal.prototype.drag = function (mouse) { - var $$ = this, config = $$.config, main = $$.main, d3 = $$.d3; - var sx, sy, mx, my, minX, maxX, minY, maxY; - - if ($$.hasArcType()) { return; } - if (!config.data_selection_enabled) { return; } // do nothing if not selectable - if (!config.data_selection_multiple) { return; } // skip when single selection because drag is used for multiple selection - - sx = $$.dragStart[0]; - sy = $$.dragStart[1]; - mx = mouse[0]; - my = mouse[1]; - minX = Math.min(sx, mx); - maxX = Math.max(sx, mx); - minY = (config.data_selection_grouped) ? $$.margin.top : Math.min(sy, my); - maxY = (config.data_selection_grouped) ? $$.height : Math.max(sy, my); - - main.select('.' + CLASS.dragarea) - .attr('x', minX) - .attr('y', minY) - .attr('width', maxX - minX) - .attr('height', maxY - minY); - // TODO: binary search when multiple xs - main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape) - .filter(function (d) { return config.data_selection_isselectable(d); }) - .each(function (d, i) { - var shape = d3.select(this), - isSelected = shape.classed(CLASS.SELECTED), - isIncluded = shape.classed(CLASS.INCLUDED), - _x, _y, _w, _h, toggle, isWithin = false, box; - if (shape.classed(CLASS.circle)) { - _x = shape.attr("cx") * 1; - _y = shape.attr("cy") * 1; - toggle = $$.togglePoint; - isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; - } - else if (shape.classed(CLASS.bar)) { - box = getPathBox(this); - _x = box.x; - _y = box.y; - _w = box.width; - _h = box.height; - toggle = $$.togglePath; - isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY); - } else { - // line/area selection not supported yet - return; - } - if (isWithin ^ isIncluded) { - shape.classed(CLASS.INCLUDED, !isIncluded); - // TODO: included/unincluded callback here - shape.classed(CLASS.SELECTED, !isSelected); - toggle.call($$, !isSelected, shape, d, i); - } - }); + } + if (firstX || firstX === 0) { + min = $$.isTimeSeries() + ? new Date(firstX.getTime() - padding.left) + : firstX - padding.left; + } + if (lastX || lastX === 0) { + max = $$.isTimeSeries() + ? new Date(lastX.getTime() + padding.right) + : lastX + padding.right; + } + return [min, max] +}; +ChartInternal.prototype.updateXDomain = function( + targets, + withUpdateXDomain, + withUpdateOrgXDomain, + withTrim, + domain +) { + var $$ = this, + config = $$.config; + + if (withUpdateOrgXDomain) { + $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets))); + $$.orgXDomain = $$.x.domain(); + if (config.zoom_enabled) { + $$.zoom.update(); + } + $$.subX.domain($$.x.domain()); + if ($$.brush) { + $$.brush.updateScale($$.subX); + } + } + if (withUpdateXDomain) { + $$.x.domain( + domain + ? domain + : !$$.brush || $$.brush.empty() + ? $$.orgXDomain + : $$.brush.selectionAsValue() + ); + } + + // Trim domain when too big by zoom mousemove event + if (withTrim) { + $$.x.domain($$.trimXDomain($$.x.orgDomain())); + } + + return $$.x.domain() +}; +ChartInternal.prototype.trimXDomain = function(domain) { + var zoomDomain = this.getZoomDomain(), + min = zoomDomain[0], + max = zoomDomain[1]; + if (domain[0] <= min) { + domain[1] = +domain[1] + (min - domain[0]); + domain[0] = min; + } + if (max <= domain[1]) { + domain[0] = +domain[0] - (domain[1] - max); + domain[1] = max; + } + return domain }; -ChartInternal.prototype.dragstart = function (mouse) { - var $$ = this, config = $$.config; - if ($$.hasArcType()) { return; } - if (! config.data_selection_enabled) { return; } // do nothing if not selectable - $$.dragStart = mouse; - $$.main.select('.' + CLASS.chart).append('rect') - .attr('class', CLASS.dragarea) - .style('opacity', 0.1); - $$.dragging = true; -}; - -ChartInternal.prototype.dragend = function () { - var $$ = this, config = $$.config; - if ($$.hasArcType()) { return; } - if (! config.data_selection_enabled) { return; } // do nothing if not selectable - $$.main.select('.' + CLASS.dragarea) - .transition().duration(100) - .style('opacity', 0) - .remove(); - $$.main.selectAll('.' + CLASS.shape) - .classed(CLASS.INCLUDED, false); - $$.dragging = false; -}; - -ChartInternal.prototype.getYFormat = function (forArc) { - var $$ = this, - formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, - formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format; - return function (v, ratio, id) { - var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY; - return format.call($$, v, ratio); - }; -}; -ChartInternal.prototype.yFormat = function (v) { - var $$ = this, config = $$.config, - format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat; - return format(v); -}; -ChartInternal.prototype.y2Format = function (v) { - var $$ = this, config = $$.config, - format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat; - return format(v); -}; -ChartInternal.prototype.defaultValueFormat = function (v) { - return isValue(v) ? +v : ""; -}; -ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) { - return (ratio * 100).toFixed(1) + '%'; -}; -ChartInternal.prototype.dataLabelFormat = function (targetId) { - var $$ = this, data_labels = $$.config.data_labels, - format, defaultFormat = function (v) { return isValue(v) ? +v : ""; }; - // find format according to axis id - if (typeof data_labels.format === 'function') { - format = data_labels.format; - } else if (typeof data_labels.format === 'object') { - if (data_labels.format[targetId]) { - format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId]; - } else { - format = function () { return ''; }; - } - } else { - format = defaultFormat; - } - return format; -}; - -ChartInternal.prototype.initGrid = function () { - var $$ = this, config = $$.config, d3 = $$.d3; - $$.grid = $$.main.append('g') - .attr("clip-path", $$.clipPathForGrid) - .attr('class', CLASS.grid); - if (config.grid_x_show) { - $$.grid.append("g").attr("class", CLASS.xgrids); - } - if (config.grid_y_show) { - $$.grid.append('g').attr('class', CLASS.ygrids); - } - if (config.grid_focus_show) { - $$.grid.append('g') - .attr("class", CLASS.xgridFocus) - .append('line') - .attr('class', CLASS.xgridFocus); - } - $$.xgrid = d3.selectAll([]); - if (!config.grid_lines_front) { $$.initGridLines(); } -}; -ChartInternal.prototype.initGridLines = function () { - var $$ = this, d3 = $$.d3; - $$.gridLines = $$.main.append('g') - .attr("clip-path", $$.clipPathForGrid) - .attr('class', CLASS.grid + ' ' + CLASS.gridLines); - $$.gridLines.append('g').attr("class", CLASS.xgridLines); - $$.gridLines.append('g').attr('class', CLASS.ygridLines); - $$.xgridLines = d3.selectAll([]); -}; -ChartInternal.prototype.updateXGrid = function (withoutUpdate) { - var $$ = this, config = $$.config, d3 = $$.d3, - xgridData = $$.generateGridData(config.grid_x_type, $$.x), - tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; - - $$.xgridAttr = config.axis_rotated ? { - 'x1': 0, - 'x2': $$.width, - 'y1': function (d) { return $$.x(d) - tickOffset; }, - 'y2': function (d) { return $$.x(d) - tickOffset; } - } : { - 'x1': function (d) { return $$.x(d) + tickOffset; }, - 'x2': function (d) { return $$.x(d) + tickOffset; }, - 'y1': 0, - 'y2': $$.height - }; - $$.xgridAttr.opacity = function () { - var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1'); - return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1; - }; - - var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid) - .data(xgridData); - var xgridEnter = xgrid.enter().append('line') - .attr("class", CLASS.xgrid) - .attr('x1', $$.xgridAttr.x1) - .attr('x2', $$.xgridAttr.x2) - .attr('y1', $$.xgridAttr.y1) - .attr('y2', $$.xgridAttr.y2) - .style("opacity", 0); - $$.xgrid = xgridEnter.merge(xgrid); - if (!withoutUpdate) { - $$.xgrid - .attr('x1', $$.xgridAttr.x1) - .attr('x2', $$.xgridAttr.x2) - .attr('y1', $$.xgridAttr.y1) - .attr('y2', $$.xgridAttr.y2) - .style("opacity", $$.xgridAttr.opacity); - } - xgrid.exit().remove(); -}; - -ChartInternal.prototype.updateYGrid = function () { - var $$ = this, config = $$.config, - gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks); - var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid) - .data(gridValues); - var ygridEnter = ygrid.enter().append('line') - // TODO: x1, x2, y1, y2, opacity need to be set here maybe - .attr('class', CLASS.ygrid); - $$.ygrid = ygridEnter.merge(ygrid); - $$.ygrid - .attr("x1", config.axis_rotated ? $$.y : 0) - .attr("x2", config.axis_rotated ? $$.y : $$.width) - .attr("y1", config.axis_rotated ? 0 : $$.y) - .attr("y2", config.axis_rotated ? $$.height : $$.y); - ygrid.exit().remove(); - $$.smoothLines($$.ygrid, 'grid'); -}; - -ChartInternal.prototype.gridTextAnchor = function (d) { - return d.position ? d.position : "end"; -}; -ChartInternal.prototype.gridTextDx = function (d) { - return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4; -}; -ChartInternal.prototype.xGridTextX = function (d) { - return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0; -}; -ChartInternal.prototype.yGridTextX = function (d) { - return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width; -}; -ChartInternal.prototype.updateGrid = function (duration) { - var $$ = this, main = $$.main, config = $$.config, - xgridLine, xgridLineEnter, ygridLine, ygridLineEnter, - xv = $$.xv.bind($$), yv = $$.yv.bind($$), - xGridTextX = $$.xGridTextX.bind($$), yGridTextX = $$.yGridTextX.bind($$); - - // hide if arc type - $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); - - main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); - if (config.grid_x_show) { - $$.updateXGrid(); - } - xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine) - .data(config.grid_x_lines); - // enter - xgridLineEnter = xgridLine.enter().append('g') - .attr("class", function (d) { return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : ''); }); - xgridLineEnter.append('line') - .attr("x1", config.axis_rotated ? 0 : xv) - .attr("x2", config.axis_rotated ? $$.width : xv) - .attr("y1", config.axis_rotated ? xv : 0) - .attr("y2", config.axis_rotated ? xv : $$.height) - .style("opacity", 0); - xgridLineEnter.append('text') - .attr("text-anchor", $$.gridTextAnchor) - .attr("transform", config.axis_rotated ? "" : "rotate(-90)") - .attr("x", config.axis_rotated ? yGridTextX : xGridTextX) - .attr("y", xv) - .attr('dx', $$.gridTextDx) - .attr('dy', -5) - .style("opacity", 0); - // udpate - $$.xgridLines = xgridLineEnter.merge(xgridLine); - // done in d3.transition() of the end of this function - // exit - xgridLine.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); +ChartInternal.prototype.drag = function(mouse) { + var $$ = this, + config = $$.config, + main = $$.main, + d3 = $$.d3; + var sx, sy, mx, my, minX, maxX, minY, maxY; - // Y-Grid - if (config.grid_y_show) { - $$.updateYGrid(); - } - ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine) - .data(config.grid_y_lines); - // enter - ygridLineEnter = ygridLine.enter().append('g') - .attr("class", function (d) { return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : ''); }); - ygridLineEnter.append('line') - .attr("x1", config.axis_rotated ? yv : 0) - .attr("x2", config.axis_rotated ? yv : $$.width) - .attr("y1", config.axis_rotated ? 0 : yv) - .attr("y2", config.axis_rotated ? $$.height : yv) - .style("opacity", 0); - ygridLineEnter.append('text') - .attr("text-anchor", $$.gridTextAnchor) - .attr("transform", config.axis_rotated ? "rotate(-90)" : "") - .attr("x", config.axis_rotated ? xGridTextX : yGridTextX) - .attr("y", yv) - .attr('dx', $$.gridTextDx) - .attr('dy', -5) - .style("opacity", 0); - // update - $$.ygridLines = ygridLineEnter.merge(ygridLine); - $$.ygridLines.select('line') - .transition().duration(duration) - .attr("x1", config.axis_rotated ? yv : 0) - .attr("x2", config.axis_rotated ? yv : $$.width) - .attr("y1", config.axis_rotated ? 0 : yv) - .attr("y2", config.axis_rotated ? $$.height : yv) - .style("opacity", 1); - $$.ygridLines.select('text') - .transition().duration(duration) - .attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)) - .attr("y", yv) - .text(function (d) { return d.text; }) - .style("opacity", 1); - // exit - ygridLine.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); + if ($$.hasArcType()) { + return + } + if (!config.data_selection_enabled) { + return + } // do nothing if not selectable + if (!config.data_selection_multiple) { + return + } // skip when single selection because drag is used for multiple selection + + sx = $$.dragStart[0]; + sy = $$.dragStart[1]; + mx = mouse[0]; + my = mouse[1]; + minX = Math.min(sx, mx); + maxX = Math.max(sx, mx); + minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my); + maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my); + + main + .select('.' + CLASS.dragarea) + .attr('x', minX) + .attr('y', minY) + .attr('width', maxX - minX) + .attr('height', maxY - minY); + // TODO: binary search when multiple xs + main + .selectAll('.' + CLASS.shapes) + .selectAll('.' + CLASS.shape) + .filter(function(d) { + return config.data_selection_isselectable(d) + }) + .each(function(d, i) { + var shape = d3.select(this), + isSelected = shape.classed(CLASS.SELECTED), + isIncluded = shape.classed(CLASS.INCLUDED), + _x, + _y, + _w, + _h, + toggle, + isWithin = false, + box; + if (shape.classed(CLASS.circle)) { + _x = shape.attr('cx') * 1; + _y = shape.attr('cy') * 1; + toggle = $$.togglePoint; + isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; + } else if (shape.classed(CLASS.bar)) { + box = getPathBox(this); + _x = box.x; + _y = box.y; + _w = box.width; + _h = box.height; + toggle = $$.togglePath; + isWithin = + !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY); + } else { + // line/area selection not supported yet + return + } + if (isWithin ^ isIncluded) { + shape.classed(CLASS.INCLUDED, !isIncluded); + // TODO: included/unincluded callback here + shape.classed(CLASS.SELECTED, !isSelected); + toggle.call($$, !isSelected, shape, d, i); + } + }); }; -ChartInternal.prototype.redrawGrid = function (withTransition, transition) { - var $$ = this, config = $$.config, xv = $$.xv.bind($$), - lines = $$.xgridLines.select('line'), - texts = $$.xgridLines.select('text'); - return [ - (withTransition ? lines.transition(transition) : lines) - .attr("x1", config.axis_rotated ? 0 : xv) - .attr("x2", config.axis_rotated ? $$.width : xv) - .attr("y1", config.axis_rotated ? xv : 0) - .attr("y2", config.axis_rotated ? xv : $$.height) - .style("opacity", 1), - (withTransition ? texts.transition(transition) : texts) - .attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)) - .attr("y", xv) - .text(function (d) { return d.text; }) - .style("opacity", 1) - ]; -}; -ChartInternal.prototype.showXGridFocus = function (selectedData) { - var $$ = this, config = $$.config, - dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); }), - focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), - xx = $$.xx.bind($$); - if (! config.tooltip_show) { return; } - // Hide when stanford plot exists - if ($$.hasType('stanford') || $$.hasArcType()) { return; } - focusEl - .style("visibility", "visible") - .data([dataToShow[0]]) - .attr(config.axis_rotated ? 'y1' : 'x1', xx) - .attr(config.axis_rotated ? 'y2' : 'x2', xx); - $$.smoothLines(focusEl, 'grid'); -}; -ChartInternal.prototype.hideXGridFocus = function () { - this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); -}; -ChartInternal.prototype.updateXgridFocus = function () { - var $$ = this, config = $$.config; - $$.main.select('line.' + CLASS.xgridFocus) - .attr("x1", config.axis_rotated ? 0 : -10) - .attr("x2", config.axis_rotated ? $$.width : -10) - .attr("y1", config.axis_rotated ? -10 : 0) - .attr("y2", config.axis_rotated ? -10 : $$.height); -}; -ChartInternal.prototype.generateGridData = function (type, scale) { - var $$ = this, - gridData = [], xDomain, firstYear, lastYear, i, - tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size(); - if (type === 'year') { - xDomain = $$.getXDomain(); - firstYear = xDomain[0].getFullYear(); - lastYear = xDomain[1].getFullYear(); - for (i = firstYear; i <= lastYear; i++) { - gridData.push(new Date(i + '-01-01 00:00:00')); - } - } else { - gridData = scale.ticks(10); - if (gridData.length > tickNum) { // use only int - gridData = gridData.filter(function (d) { return ("" + d).indexOf('.') < 0; }); - } - } - return gridData; + +ChartInternal.prototype.dragstart = function(mouse) { + var $$ = this, + config = $$.config; + if ($$.hasArcType()) { + return + } + if (!config.data_selection_enabled) { + return + } // do nothing if not selectable + $$.dragStart = mouse; + $$.main + .select('.' + CLASS.chart) + .append('rect') + .attr('class', CLASS.dragarea) + .style('opacity', 0.1); + $$.dragging = true; +}; + +ChartInternal.prototype.dragend = function() { + var $$ = this, + config = $$.config; + if ($$.hasArcType()) { + return + } + if (!config.data_selection_enabled) { + return + } // do nothing if not selectable + $$.main + .select('.' + CLASS.dragarea) + .transition() + .duration(100) + .style('opacity', 0) + .remove(); + $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false); + $$.dragging = false; +}; + +ChartInternal.prototype.getYFormat = function(forArc) { + var $$ = this, + formatForY = + forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, + formatForY2 = + forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format; + return function(v, ratio, id) { + var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY; + return format.call($$, v, ratio) + } }; -ChartInternal.prototype.getGridFilterToRemove = function (params) { - return params ? function (line) { - var found = false; - [].concat(params).forEach(function (param) { - if ((('value' in param && line.value === param.value) || ('class' in param && line['class'] === param['class']))) { - found = true; - } - }); - return found; - } : function () { return true; }; -}; -ChartInternal.prototype.removeGridLines = function (params, forX) { - var $$ = this, config = $$.config, - toRemove = $$.getGridFilterToRemove(params), - toShow = function (line) { return !toRemove(line); }, - classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, - classLine = forX ? CLASS.xgridLine : CLASS.ygridLine; - $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove) - .transition().duration(config.transition_duration) - .style('opacity', 0).remove(); - if (forX) { - config.grid_x_lines = config.grid_x_lines.filter(toShow); +ChartInternal.prototype.yFormat = function(v) { + var $$ = this, + config = $$.config, + format = config.axis_y_tick_format + ? config.axis_y_tick_format + : $$.defaultValueFormat; + return format(v) +}; +ChartInternal.prototype.y2Format = function(v) { + var $$ = this, + config = $$.config, + format = config.axis_y2_tick_format + ? config.axis_y2_tick_format + : $$.defaultValueFormat; + return format(v) +}; +ChartInternal.prototype.defaultValueFormat = function(v) { + return isValue(v) ? +v : '' +}; +ChartInternal.prototype.defaultArcValueFormat = function(v, ratio) { + return (ratio * 100).toFixed(1) + '%' +}; +ChartInternal.prototype.dataLabelFormat = function(targetId) { + var $$ = this, + data_labels = $$.config.data_labels, + format, + defaultFormat = function(v) { + return isValue(v) ? +v : '' + }; + // find format according to axis id + if (typeof data_labels.format === 'function') { + format = data_labels.format; + } else if (typeof data_labels.format === 'object') { + if (data_labels.format[targetId]) { + format = + data_labels.format[targetId] === true + ? defaultFormat + : data_labels.format[targetId]; } else { - config.grid_y_lines = config.grid_y_lines.filter(toShow); + format = function() { + return '' + }; } + } else { + format = defaultFormat; + } + return format +}; + +ChartInternal.prototype.initGrid = function() { + var $$ = this, + config = $$.config, + d3 = $$.d3; + $$.grid = $$.main + .append('g') + .attr('clip-path', $$.clipPathForGrid) + .attr('class', CLASS.grid); + if (config.grid_x_show) { + $$.grid.append('g').attr('class', CLASS.xgrids); + } + if (config.grid_y_show) { + $$.grid.append('g').attr('class', CLASS.ygrids); + } + if (config.grid_focus_show) { + $$.grid + .append('g') + .attr('class', CLASS.xgridFocus) + .append('line') + .attr('class', CLASS.xgridFocus); + } + $$.xgrid = d3.selectAll([]); + if (!config.grid_lines_front) { + $$.initGridLines(); + } }; - -ChartInternal.prototype.initEventRect = function () { - var $$ = this, config = $$.config; - - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.eventRects) - .style('fill-opacity', 0); - $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect') - .attr('class', CLASS.eventRect); - - // event rect handle zoom event as well - if (config.zoom_enabled && $$.zoom) { - $$.eventRect.call($$.zoom).on("dblclick.zoom", null); - if (config.zoom_initialRange) { - // WORKAROUND: Add transition to apply transform immediately when no subchart - $$.eventRect.transition().duration(0).call( - $$.zoom.transform, $$.zoomTransform(config.zoom_initialRange) - ); +ChartInternal.prototype.initGridLines = function() { + var $$ = this, + d3 = $$.d3; + $$.gridLines = $$.main + .append('g') + .attr('clip-path', $$.clipPathForGrid) + .attr('class', CLASS.grid + ' ' + CLASS.gridLines); + $$.gridLines.append('g').attr('class', CLASS.xgridLines); + $$.gridLines.append('g').attr('class', CLASS.ygridLines); + $$.xgridLines = d3.selectAll([]); +}; +ChartInternal.prototype.updateXGrid = function(withoutUpdate) { + var $$ = this, + config = $$.config, + d3 = $$.d3, + xgridData = $$.generateGridData(config.grid_x_type, $$.x), + tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; + + $$.xgridAttr = config.axis_rotated + ? { + x1: 0, + x2: $$.width, + y1: function(d) { + return $$.x(d) - tickOffset + }, + y2: function(d) { + return $$.x(d) - tickOffset } + } + : { + x1: function(d) { + return $$.x(d) + tickOffset + }, + x2: function(d) { + return $$.x(d) + tickOffset + }, + y1: 0, + y2: $$.height + }; + $$.xgridAttr.opacity = function() { + var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1'); + return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1 + }; + + var xgrid = $$.main + .select('.' + CLASS.xgrids) + .selectAll('.' + CLASS.xgrid) + .data(xgridData); + var xgridEnter = xgrid + .enter() + .append('line') + .attr('class', CLASS.xgrid) + .attr('x1', $$.xgridAttr.x1) + .attr('x2', $$.xgridAttr.x2) + .attr('y1', $$.xgridAttr.y1) + .attr('y2', $$.xgridAttr.y2) + .style('opacity', 0); + $$.xgrid = xgridEnter.merge(xgrid); + if (!withoutUpdate) { + $$.xgrid + .attr('x1', $$.xgridAttr.x1) + .attr('x2', $$.xgridAttr.x2) + .attr('y1', $$.xgridAttr.y1) + .attr('y2', $$.xgridAttr.y2) + .style('opacity', $$.xgridAttr.opacity); + } + xgrid.exit().remove(); +}; + +ChartInternal.prototype.updateYGrid = function() { + var $$ = this, + config = $$.config, + gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks); + var ygrid = $$.main + .select('.' + CLASS.ygrids) + .selectAll('.' + CLASS.ygrid) + .data(gridValues); + var ygridEnter = ygrid + .enter() + .append('line') + // TODO: x1, x2, y1, y2, opacity need to be set here maybe + .attr('class', CLASS.ygrid); + $$.ygrid = ygridEnter.merge(ygrid); + $$.ygrid + .attr('x1', config.axis_rotated ? $$.y : 0) + .attr('x2', config.axis_rotated ? $$.y : $$.width) + .attr('y1', config.axis_rotated ? 0 : $$.y) + .attr('y2', config.axis_rotated ? $$.height : $$.y); + ygrid.exit().remove(); + $$.smoothLines($$.ygrid, 'grid'); +}; + +ChartInternal.prototype.gridTextAnchor = function(d) { + return d.position ? d.position : 'end' +}; +ChartInternal.prototype.gridTextDx = function(d) { + return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4 +}; +ChartInternal.prototype.xGridTextX = function(d) { + return d.position === 'start' + ? -this.height + : d.position === 'middle' + ? -this.height / 2 + : 0 +}; +ChartInternal.prototype.yGridTextX = function(d) { + return d.position === 'start' + ? 0 + : d.position === 'middle' + ? this.width / 2 + : this.width +}; +ChartInternal.prototype.updateGrid = function(duration) { + var $$ = this, + main = $$.main, + config = $$.config, + xgridLine, + xgridLineEnter, + ygridLine, + ygridLineEnter, + xv = $$.xv.bind($$), + yv = $$.yv.bind($$), + xGridTextX = $$.xGridTextX.bind($$), + yGridTextX = $$.yGridTextX.bind($$); + + // hide if arc type + $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); + + main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); + if (config.grid_x_show) { + $$.updateXGrid(); + } + xgridLine = main + .select('.' + CLASS.xgridLines) + .selectAll('.' + CLASS.xgridLine) + .data(config.grid_x_lines); + // enter + xgridLineEnter = xgridLine + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '') + }); + xgridLineEnter + .append('line') + .attr('x1', config.axis_rotated ? 0 : xv) + .attr('x2', config.axis_rotated ? $$.width : xv) + .attr('y1', config.axis_rotated ? xv : 0) + .attr('y2', config.axis_rotated ? xv : $$.height) + .style('opacity', 0); + xgridLineEnter + .append('text') + .attr('text-anchor', $$.gridTextAnchor) + .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') + .attr('x', config.axis_rotated ? yGridTextX : xGridTextX) + .attr('y', xv) + .attr('dx', $$.gridTextDx) + .attr('dy', -5) + .style('opacity', 0); + // udpate + $$.xgridLines = xgridLineEnter.merge(xgridLine); + // done in d3.transition() of the end of this function + // exit + xgridLine + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); + + // Y-Grid + if (config.grid_y_show) { + $$.updateYGrid(); + } + ygridLine = main + .select('.' + CLASS.ygridLines) + .selectAll('.' + CLASS.ygridLine) + .data(config.grid_y_lines); + // enter + ygridLineEnter = ygridLine + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '') + }); + ygridLineEnter + .append('line') + .attr('x1', config.axis_rotated ? yv : 0) + .attr('x2', config.axis_rotated ? yv : $$.width) + .attr('y1', config.axis_rotated ? 0 : yv) + .attr('y2', config.axis_rotated ? $$.height : yv) + .style('opacity', 0); + ygridLineEnter + .append('text') + .attr('text-anchor', $$.gridTextAnchor) + .attr('transform', config.axis_rotated ? 'rotate(-90)' : '') + .attr('x', config.axis_rotated ? xGridTextX : yGridTextX) + .attr('y', yv) + .attr('dx', $$.gridTextDx) + .attr('dy', -5) + .style('opacity', 0); + // update + $$.ygridLines = ygridLineEnter.merge(ygridLine); + $$.ygridLines + .select('line') + .transition() + .duration(duration) + .attr('x1', config.axis_rotated ? yv : 0) + .attr('x2', config.axis_rotated ? yv : $$.width) + .attr('y1', config.axis_rotated ? 0 : yv) + .attr('y2', config.axis_rotated ? $$.height : yv) + .style('opacity', 1); + $$.ygridLines + .select('text') + .transition() + .duration(duration) + .attr( + 'x', + config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$) + ) + .attr('y', yv) + .text(function(d) { + return d.text + }) + .style('opacity', 1); + // exit + ygridLine + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); +}; +ChartInternal.prototype.redrawGrid = function(withTransition, transition) { + var $$ = this, + config = $$.config, + xv = $$.xv.bind($$), + lines = $$.xgridLines.select('line'), + texts = $$.xgridLines.select('text'); + return [ + (withTransition ? lines.transition(transition) : lines) + .attr('x1', config.axis_rotated ? 0 : xv) + .attr('x2', config.axis_rotated ? $$.width : xv) + .attr('y1', config.axis_rotated ? xv : 0) + .attr('y2', config.axis_rotated ? xv : $$.height) + .style('opacity', 1), + (withTransition ? texts.transition(transition) : texts) + .attr( + 'x', + config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$) + ) + .attr('y', xv) + .text(function(d) { + return d.text + }) + .style('opacity', 1) + ] +}; +ChartInternal.prototype.showXGridFocus = function(selectedData) { + var $$ = this, + config = $$.config, + dataToShow = selectedData.filter(function(d) { + return d && isValue(d.value) + }), + focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), + xx = $$.xx.bind($$); + if (!config.tooltip_show) { + return + } + // Hide when stanford plot exists + if ($$.hasType('stanford') || $$.hasArcType()) { + return + } + focusEl + .style('visibility', 'visible') + .data([dataToShow[0]]) + .attr(config.axis_rotated ? 'y1' : 'x1', xx) + .attr(config.axis_rotated ? 'y2' : 'x2', xx); + $$.smoothLines(focusEl, 'grid'); +}; +ChartInternal.prototype.hideXGridFocus = function() { + this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); +}; +ChartInternal.prototype.updateXgridFocus = function() { + var $$ = this, + config = $$.config; + $$.main + .select('line.' + CLASS.xgridFocus) + .attr('x1', config.axis_rotated ? 0 : -10) + .attr('x2', config.axis_rotated ? $$.width : -10) + .attr('y1', config.axis_rotated ? -10 : 0) + .attr('y2', config.axis_rotated ? -10 : $$.height); +}; +ChartInternal.prototype.generateGridData = function(type, scale) { + var $$ = this, + gridData = [], + xDomain, + firstYear, + lastYear, + i, + tickNum = $$.main + .select('.' + CLASS.axisX) + .selectAll('.tick') + .size(); + if (type === 'year') { + xDomain = $$.getXDomain(); + firstYear = xDomain[0].getFullYear(); + lastYear = xDomain[1].getFullYear(); + for (i = firstYear; i <= lastYear; i++) { + gridData.push(new Date(i + '-01-01 00:00:00')); + } + } else { + gridData = scale.ticks(10); + if (gridData.length > tickNum) { + // use only int + gridData = gridData.filter(function(d) { + return ('' + d).indexOf('.') < 0 + }); } + } + return gridData +}; +ChartInternal.prototype.getGridFilterToRemove = function(params) { + return params + ? function(line) { + var found = false + ;[].concat(params).forEach(function(param) { + if ( + ('value' in param && line.value === param.value) || + ('class' in param && line['class'] === param['class']) + ) { + found = true; + } + }); + return found + } + : function() { + return true + } +}; +ChartInternal.prototype.removeGridLines = function(params, forX) { + var $$ = this, + config = $$.config, + toRemove = $$.getGridFilterToRemove(params), + toShow = function(line) { + return !toRemove(line) + }, + classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, + classLine = forX ? CLASS.xgridLine : CLASS.ygridLine; + $$.main + .select('.' + classLines) + .selectAll('.' + classLine) + .filter(toRemove) + .transition() + .duration(config.transition_duration) + .style('opacity', 0) + .remove(); + if (forX) { + config.grid_x_lines = config.grid_x_lines.filter(toShow); + } else { + config.grid_y_lines = config.grid_y_lines.filter(toShow); + } }; -ChartInternal.prototype.redrawEventRect = function () { - const $$ = this, d3 = $$.d3, config = $$.config; - function mouseout() { - $$.svg.select('.' + CLASS.eventRect).style('cursor', null); - $$.hideXGridFocus(); - $$.hideTooltip(); - $$.unexpandCircles(); - $$.unexpandBars(); +ChartInternal.prototype.initEventRect = function() { + var $$ = this, + config = $$.config; + + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.eventRects) + .style('fill-opacity', 0); + $$.eventRect = $$.main + .select('.' + CLASS.eventRects) + .append('rect') + .attr('class', CLASS.eventRect); + + // event rect handle zoom event as well + if (config.zoom_enabled && $$.zoom) { + $$.eventRect.call($$.zoom).on('dblclick.zoom', null); + if (config.zoom_initialRange) { + // WORKAROUND: Add transition to apply transform immediately when no subchart + $$.eventRect + .transition() + .duration(0) + .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange)); } + } +}; +ChartInternal.prototype.redrawEventRect = function() { + const $$ = this, + d3 = $$.d3, + config = $$.config; + + function mouseout() { + $$.svg.select('.' + CLASS.eventRect).style('cursor', null); + $$.hideXGridFocus(); + $$.hideTooltip(); + $$.unexpandCircles(); + $$.unexpandBars(); + } - const isHoveringDataPoint = (mouse, closest) => - closest && ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity); - - const withName = (d) => - d ? $$.addName(Object.assign({}, d)) : null; - - // rects for mouseover - $$.main.select('.' + CLASS.eventRects) - .style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null); - - $$.eventRect - .attr('x', 0) - .attr('y', 0) - .attr('width', $$.width) - .attr('height', $$.height) - .on('mouseout', config.interaction_enabled ? function () { - if (!config) { return; } // chart is destroyed - if ($$.hasArcType()) { return; } - if ($$.mouseover){ + const isHoveringDataPoint = (mouse, closest) => + closest && + ($$.isBarType(closest.id) || + $$.dist(closest, mouse) < config.point_sensitivity); + + const withName = d => (d ? $$.addName(Object.assign({}, d)) : null); + + // rects for mouseover + $$.main + .select('.' + CLASS.eventRects) + .style( + 'cursor', + config.zoom_enabled + ? config.axis_rotated + ? 'ns-resize' + : 'ew-resize' + : null + ); + + $$.eventRect + .attr('x', 0) + .attr('y', 0) + .attr('width', $$.width) + .attr('height', $$.height) + .on( + 'mouseout', + config.interaction_enabled + ? function() { + if (!config) { + return + } // chart is destroyed + if ($$.hasArcType()) { + return + } + if ($$.mouseover) { config.data_onmouseout.call($$.api, $$.mouseover); $$.mouseover = undefined; } mouseout(); - } : null) - .on('mousemove', config.interaction_enabled ? function () { + } + : null + ) + .on( + 'mousemove', + config.interaction_enabled + ? function() { // do nothing when dragging if ($$.dragging) { - return; + return } const targetsToShow = $$.getTargetsToShow(); // do nothing if arc type if ($$.hasArcType(targetsToShow)) { - return; + return } const mouse = d3.mouse(this); - const closest = withName($$.findClosestFromTargets(targetsToShow, mouse)); + const closest = withName( + $$.findClosestFromTargets(targetsToShow, mouse) + ); const isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest); // ensure onmouseout is always called if mousemove switch between 2 targets - if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id || closest.index !== $$.mouseover.index)) { - config.data_onmouseout.call($$.api, $$.mouseover); - $$.mouseover = undefined; + if ( + $$.mouseover && + (!closest || + closest.id !== $$.mouseover.id || + closest.index !== $$.mouseover.index) + ) { + config.data_onmouseout.call($$.api, $$.mouseover); + $$.mouseover = undefined; } if (closest && !$$.mouseover) { - config.data_onmouseover.call($$.api, closest); - $$.mouseover = closest; + config.data_onmouseover.call($$.api, closest); + $$.mouseover = closest; } // show cursor as pointer if we're hovering a data point close enough - $$.svg.select('.' + CLASS.eventRect).style('cursor', isMouseCloseToDataPoint ? 'pointer' : null); + $$.svg + .select('.' + CLASS.eventRect) + .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null); // if tooltip not grouped, we want to display only data from closest data point - const showSingleDataPoint = !config.tooltip_grouped || $$.hasType('stanford', targetsToShow); + const showSingleDataPoint = + !config.tooltip_grouped || $$.hasType('stanford', targetsToShow); // find data to highlight let selectedData; if (showSingleDataPoint) { - if (closest) { - selectedData = [ closest ]; - } + if (closest) { + selectedData = [closest]; + } } else { - let closestByX; - if (closest) { - // reuse closest value - closestByX = closest; - } else { - // try to find the closest value by X values from the mouse position - const mouseX = config.axis_rotated ? mouse[1] : mouse[0]; - closestByX = $$.findClosestFromTargetsByX(targetsToShow, $$.x.invert(mouseX)); - } + let closestByX; + if (closest) { + // reuse closest value + closestByX = closest; + } else { + // try to find the closest value by X values from the mouse position + const mouseX = config.axis_rotated ? mouse[1] : mouse[0]; + closestByX = $$.findClosestFromTargetsByX( + targetsToShow, + $$.x.invert(mouseX) + ); + } - // highlight all data for this 'x' value - if (closestByX) { - selectedData = $$.filterByX(targetsToShow, closestByX.x); - } + // highlight all data for this 'x' value + if (closestByX) { + selectedData = $$.filterByX(targetsToShow, closestByX.x); + } } // ensure we have data to show if (!selectedData || selectedData.length === 0) { - return mouseout(); + return mouseout() } // inject names for each point @@ -7863,650 +10035,919 @@ ChartInternal.prototype.redrawEventRect = function () { // expand points if (config.point_focus_expand_enabled) { - $$.unexpandCircles(); - selectedData.forEach(function (d) { - $$.expandCircles(d.index, d.id, false); - }); + $$.unexpandCircles(); + selectedData.forEach(function(d) { + $$.expandCircles(d.index, d.id, false); + }); } // expand bars $$.unexpandBars(); - selectedData.forEach(function (d) { - $$.expandBars(d.index, d.id, false); + selectedData.forEach(function(d) { + $$.expandBars(d.index, d.id, false); }); // Show xgrid focus line $$.showXGridFocus(selectedData); - } : null) - .on('click', config.interaction_enabled ? function () { + } + : null + ) + .on( + 'click', + config.interaction_enabled + ? function() { const targetsToShow = $$.getTargetsToShow(); if ($$.hasArcType(targetsToShow)) { - return; + return } const mouse = d3.mouse(this); - const closest = withName($$.findClosestFromTargets(targetsToShow, mouse)); + const closest = withName( + $$.findClosestFromTargets(targetsToShow, mouse) + ); if (!isHoveringDataPoint(mouse, closest)) { - return; + return } // select if selection enabled let sameXData; if (!config.data_selection_grouped || $$.isStanfordType(closest)) { - sameXData = [closest]; + sameXData = [closest]; } else { - sameXData = $$.filterByX(targetsToShow, closest.x); + sameXData = $$.filterByX(targetsToShow, closest.x); } // toggle selected state - sameXData.forEach(function (d) { - $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () { - if (config.data_selection_grouped || $$.isWithinShape(this, d)) { - $$.toggleShape(this, d, d.index); - } + sameXData.forEach(function(d) { + $$.main + .selectAll( + '.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id) + ) + .selectAll('.' + CLASS.shape + '-' + d.index) + .each(function() { + if ( + config.data_selection_grouped || + $$.isWithinShape(this, d) + ) { + $$.toggleShape(this, d, d.index); + } }); }); // call data_onclick on the closest data point if (closest) { - const shape = $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).select('.' + CLASS.shape + '-' + closest.index); - config.data_onclick.call($$.api, closest, shape.node()); + const shape = $$.main + .selectAll( + '.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id) + ) + .select('.' + CLASS.shape + '-' + closest.index); + config.data_onclick.call($$.api, closest, shape.node()); } - - } : null) - .call( - config.interaction_enabled && config.data_selection_draggable && $$.drag ? ( - d3.drag() - .on('drag', function () { $$.drag(d3.mouse(this)); }) - .on('start', function () { $$.dragstart(d3.mouse(this)); }) - .on('end', function () { $$.dragend(); }) - ) : function () {} - ); -}; -ChartInternal.prototype.getMousePosition = function (data) { - var $$ = this; - return [$$.x(data.x), $$.getYScale(data.id)(data.value)]; -}; -ChartInternal.prototype.dispatchEvent = function (type, mouse) { - var $$ = this, - selector = '.' + CLASS.eventRect, - eventRect = $$.main.select(selector).node(), - box = eventRect.getBoundingClientRect(), - x = box.left + (mouse ? mouse[0] : 0), - y = box.top + (mouse ? mouse[1] : 0), - event = document.createEvent("MouseEvents"); - - event.initMouseEvent(type, true, true, window, 0, x, y, x, y, - false, false, false, false, 0, null); - eventRect.dispatchEvent(event); -}; - -ChartInternal.prototype.initLegend = function () { - var $$ = this; - $$.legendItemTextBox = {}; - $$.legendHasRendered = false; - $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend')); - if (!$$.config.legend_show) { - $$.legend.style('visibility', 'hidden'); - $$.hiddenLegendIds = $$.mapToIds($$.data.targets); - return; - } - // MEMO: call here to update legend box and tranlate for all - // MEMO: translate will be updated by this, so transform not needed in updateLegend() - $$.updateLegendWithDefaults(); -}; -ChartInternal.prototype.updateLegendWithDefaults = function () { - var $$ = this; - $$.updateLegend($$.mapToIds($$.data.targets), {withTransform: false, withTransitionForTransform: false, withTransition: false}); -}; -ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) { - var $$ = this, config = $$.config, insetLegendPosition = { - top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y, - left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5 - }; - - $$.margin3 = { - top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight, - right: NaN, - bottom: 0, - left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0 + } + : null + ) + .call( + config.interaction_enabled && config.data_selection_draggable && $$.drag + ? d3 + .drag() + .on('drag', function() { + $$.drag(d3.mouse(this)); + }) + .on('start', function() { + $$.dragstart(d3.mouse(this)); + }) + .on('end', function() { + $$.dragend(); + }) + : function() {} + ); +}; +ChartInternal.prototype.getMousePosition = function(data) { + var $$ = this; + return [$$.x(data.x), $$.getYScale(data.id)(data.value)] +}; +ChartInternal.prototype.dispatchEvent = function(type, mouse) { + var $$ = this, + selector = '.' + CLASS.eventRect, + eventRect = $$.main.select(selector).node(), + box = eventRect.getBoundingClientRect(), + x = box.left + (mouse ? mouse[0] : 0), + y = box.top + (mouse ? mouse[1] : 0), + event = document.createEvent('MouseEvents'); + + event.initMouseEvent( + type, + true, + true, + window, + 0, + x, + y, + x, + y, + false, + false, + false, + false, + 0, + null + ); + eventRect.dispatchEvent(event); +}; + +ChartInternal.prototype.initLegend = function() { + var $$ = this; + $$.legendItemTextBox = {}; + $$.legendHasRendered = false; + $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend')); + if (!$$.config.legend_show) { + $$.legend.style('visibility', 'hidden'); + $$.hiddenLegendIds = $$.mapToIds($$.data.targets); + return + } + // MEMO: call here to update legend box and tranlate for all + // MEMO: translate will be updated by this, so transform not needed in updateLegend() + $$.updateLegendWithDefaults(); +}; +ChartInternal.prototype.updateLegendWithDefaults = function() { + var $$ = this; + $$.updateLegend($$.mapToIds($$.data.targets), { + withTransform: false, + withTransitionForTransform: false, + withTransition: false + }); +}; +ChartInternal.prototype.updateSizeForLegend = function( + legendHeight, + legendWidth +) { + var $$ = this, + config = $$.config, + insetLegendPosition = { + top: $$.isLegendTop + ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 + : $$.currentHeight - + legendHeight - + $$.getCurrentPaddingBottom() - + config.legend_inset_y, + left: $$.isLegendLeft + ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 + : $$.currentWidth - + legendWidth - + $$.getCurrentPaddingRight() - + config.legend_inset_x + + 0.5 }; -}; -ChartInternal.prototype.transformLegend = function (withTransition) { - var $$ = this; - (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend')); -}; -ChartInternal.prototype.updateLegendStep = function (step) { - this.legendStep = step; -}; -ChartInternal.prototype.updateLegendItemWidth = function (w) { - this.legendItemWidth = w; -}; -ChartInternal.prototype.updateLegendItemHeight = function (h) { - this.legendItemHeight = h; -}; -ChartInternal.prototype.getLegendWidth = function () { - var $$ = this; - return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0; -}; -ChartInternal.prototype.getLegendHeight = function () { - var $$ = this, h = 0; - if ($$.config.legend_show) { - if ($$.isLegendRight) { - h = $$.currentHeight; - } else { - h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1); - } + + $$.margin3 = { + top: $$.isLegendRight + ? 0 + : $$.isLegendInset + ? insetLegendPosition.top + : $$.currentHeight - legendHeight, + right: NaN, + bottom: 0, + left: $$.isLegendRight + ? $$.currentWidth - legendWidth + : $$.isLegendInset + ? insetLegendPosition.left + : 0 + }; +}; +ChartInternal.prototype.transformLegend = function(withTransition) { + var $$ = this + ;(withTransition ? $$.legend.transition() : $$.legend).attr( + 'transform', + $$.getTranslate('legend') + ); +}; +ChartInternal.prototype.updateLegendStep = function(step) { + this.legendStep = step; +}; +ChartInternal.prototype.updateLegendItemWidth = function(w) { + this.legendItemWidth = w; +}; +ChartInternal.prototype.updateLegendItemHeight = function(h) { + this.legendItemHeight = h; +}; +ChartInternal.prototype.getLegendWidth = function() { + var $$ = this; + return $$.config.legend_show + ? $$.isLegendRight || $$.isLegendInset + ? $$.legendItemWidth * ($$.legendStep + 1) + : $$.currentWidth + : 0 +}; +ChartInternal.prototype.getLegendHeight = function() { + var $$ = this, + h = 0; + if ($$.config.legend_show) { + if ($$.isLegendRight) { + h = $$.currentHeight; + } else { + h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1); } - return h; -}; -ChartInternal.prototype.opacityForLegend = function (legendItem) { - return legendItem.classed(CLASS.legendItemHidden) ? null : 1; -}; -ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) { - return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3; + } + return h +}; +ChartInternal.prototype.opacityForLegend = function(legendItem) { + return legendItem.classed(CLASS.legendItemHidden) ? null : 1 +}; +ChartInternal.prototype.opacityForUnfocusedLegend = function(legendItem) { + return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3 +}; +ChartInternal.prototype.toggleFocusLegend = function(targetIds, focus) { + var $$ = this; + targetIds = $$.mapToTargetIds(targetIds); + $$.legend + .selectAll('.' + CLASS.legendItem) + .filter(function(id) { + return targetIds.indexOf(id) >= 0 + }) + .classed(CLASS.legendItemFocused, focus) + .transition() + .duration(100) + .style('opacity', function() { + var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend; + return opacity.call($$, $$.d3.select(this)) + }); }; -ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) { - var $$ = this; - targetIds = $$.mapToTargetIds(targetIds); - $$.legend.selectAll('.' + CLASS.legendItem) - .filter(function (id) { return targetIds.indexOf(id) >= 0; }) - .classed(CLASS.legendItemFocused, focus) - .transition().duration(100) - .style('opacity', function () { - var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend; - return opacity.call($$, $$.d3.select(this)); - }); +ChartInternal.prototype.revertLegend = function() { + var $$ = this, + d3 = $$.d3; + $$.legend + .selectAll('.' + CLASS.legendItem) + .classed(CLASS.legendItemFocused, false) + .transition() + .duration(100) + .style('opacity', function() { + return $$.opacityForLegend(d3.select(this)) + }); }; -ChartInternal.prototype.revertLegend = function () { - var $$ = this, d3 = $$.d3; - $$.legend.selectAll('.' + CLASS.legendItem) - .classed(CLASS.legendItemFocused, false) - .transition().duration(100) - .style('opacity', function () { return $$.opacityForLegend(d3.select(this)); }); -}; -ChartInternal.prototype.showLegend = function (targetIds) { - var $$ = this, config = $$.config; - if (!config.legend_show) { - config.legend_show = true; - $$.legend.style('visibility', 'visible'); - if (!$$.legendHasRendered) { - $$.updateLegendWithDefaults(); - } +ChartInternal.prototype.showLegend = function(targetIds) { + var $$ = this, + config = $$.config; + if (!config.legend_show) { + config.legend_show = true; + $$.legend.style('visibility', 'visible'); + if (!$$.legendHasRendered) { + $$.updateLegendWithDefaults(); } - $$.removeHiddenLegendIds(targetIds); - $$.legend.selectAll($$.selectorLegends(targetIds)) - .style('visibility', 'visible') - .transition() - .style('opacity', function () { return $$.opacityForLegend($$.d3.select(this)); }); -}; -ChartInternal.prototype.hideLegend = function (targetIds) { - var $$ = this, config = $$.config; - if (config.legend_show && isEmpty(targetIds)) { - config.legend_show = false; - $$.legend.style('visibility', 'hidden'); - } - $$.addHiddenLegendIds(targetIds); - $$.legend.selectAll($$.selectorLegends(targetIds)) - .style('opacity', 0) - .style('visibility', 'hidden'); -}; -ChartInternal.prototype.clearLegendItemTextBoxCache = function () { - this.legendItemTextBox = {}; -}; -ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) { - var $$ = this, config = $$.config; - var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile; - var paddingTop = 4, paddingRight = 10, maxWidth = 0, maxHeight = 0, posMin = 10, tileWidth = config.legend_item_tile_width + 5; - var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0; - var withTransition, withTransitionForTransform; - var texts, rects, tiles, background; - - // Skip elements when their name is set to null - targetIds = targetIds.filter(function(id) { - return !isDefined(config.data_names[id]) || config.data_names[id] !== null; + } + $$.removeHiddenLegendIds(targetIds); + $$.legend + .selectAll($$.selectorLegends(targetIds)) + .style('visibility', 'visible') + .transition() + .style('opacity', function() { + return $$.opacityForLegend($$.d3.select(this)) }); +}; +ChartInternal.prototype.hideLegend = function(targetIds) { + var $$ = this, + config = $$.config; + if (config.legend_show && isEmpty(targetIds)) { + config.legend_show = false; + $$.legend.style('visibility', 'hidden'); + } + $$.addHiddenLegendIds(targetIds); + $$.legend + .selectAll($$.selectorLegends(targetIds)) + .style('opacity', 0) + .style('visibility', 'hidden'); +}; +ChartInternal.prototype.clearLegendItemTextBoxCache = function() { + this.legendItemTextBox = {}; +}; +ChartInternal.prototype.updateLegend = function( + targetIds, + options, + transitions +) { + var $$ = this, + config = $$.config; + var xForLegend, + xForLegendText, + xForLegendRect, + yForLegend, + yForLegendText, + yForLegendRect, + x1ForLegendTile, + x2ForLegendTile, + yForLegendTile; + var paddingTop = 4, + paddingRight = 10, + maxWidth = 0, + maxHeight = 0, + posMin = 10, + tileWidth = config.legend_item_tile_width + 5; + var l, + totalLength = 0, + offsets = {}, + widths = {}, + heights = {}, + margins = [0], + steps = {}, + step = 0; + var withTransition, withTransitionForTransform; + var texts, rects, tiles, background; + + // Skip elements when their name is set to null + targetIds = targetIds.filter(function(id) { + return !isDefined(config.data_names[id]) || config.data_names[id] !== null + }); + + options = options || {}; + withTransition = getOption(options, 'withTransition', true); + withTransitionForTransform = getOption( + options, + 'withTransitionForTransform', + true + ); + + function getTextBox(textElement, id) { + if (!$$.legendItemTextBox[id]) { + $$.legendItemTextBox[id] = $$.getTextRect( + textElement.textContent, + CLASS.legendItem, + textElement + ); + } + return $$.legendItemTextBox[id] + } - options = options || {}; - withTransition = getOption(options, "withTransition", true); - withTransitionForTransform = getOption(options, "withTransitionForTransform", true); - - function getTextBox(textElement, id) { - if (!$$.legendItemTextBox[id]) { - $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement); - } - return $$.legendItemTextBox[id]; - } - - function updatePositions(textElement, id, index) { - var reset = index === 0, isLast = index === targetIds.length - 1, - box = getTextBox(textElement, id), - itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding, - itemHeight = box.height + paddingTop, - itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, - areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(), - margin, maxLength; - - // MEMO: care about condifion of step, totalLength - function updateValues(id, withoutStep) { - if (!withoutStep) { - margin = (areaLength - totalLength - itemLength) / 2; - if (margin < posMin) { - margin = (areaLength - itemLength) / 2; - totalLength = 0; - step++; - } - } - steps[id] = step; - margins[step] = $$.isLegendInset ? 10 : margin; - offsets[id] = totalLength; - totalLength += itemLength; - } - - if (reset) { - totalLength = 0; - step = 0; - maxWidth = 0; - maxHeight = 0; - } - - if (config.legend_show && !$$.isLegendToShow(id)) { - widths[id] = heights[id] = steps[id] = offsets[id] = 0; - return; - } - - widths[id] = itemWidth; - heights[id] = itemHeight; - - if (!maxWidth || itemWidth >= maxWidth) { maxWidth = itemWidth; } - if (!maxHeight || itemHeight >= maxHeight) { maxHeight = itemHeight; } - maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth; - - if (config.legend_equally) { - Object.keys(widths).forEach(function (id) { widths[id] = maxWidth; }); - Object.keys(heights).forEach(function (id) { heights[id] = maxHeight; }); - margin = (areaLength - maxLength * targetIds.length) / 2; - if (margin < posMin) { - totalLength = 0; - step = 0; - targetIds.forEach(function (id) { updateValues(id); }); - } - else { - updateValues(id, true); - } - } else { - updateValues(id); - } + function updatePositions(textElement, id, index) { + var reset = index === 0, + isLast = index === targetIds.length - 1, + box = getTextBox(textElement, id), + itemWidth = + box.width + + tileWidth + + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + + config.legend_padding, + itemHeight = box.height + paddingTop, + itemLength = + $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, + areaLength = + $$.isLegendRight || $$.isLegendInset + ? $$.getLegendHeight() + : $$.getLegendWidth(), + margin, + maxLength; + + // MEMO: care about condifion of step, totalLength + function updateValues(id, withoutStep) { + if (!withoutStep) { + margin = (areaLength - totalLength - itemLength) / 2; + if (margin < posMin) { + margin = (areaLength - itemLength) / 2; + totalLength = 0; + step++; + } + } + steps[id] = step; + margins[step] = $$.isLegendInset ? 10 : margin; + offsets[id] = totalLength; + totalLength += itemLength; + } + + if (reset) { + totalLength = 0; + step = 0; + maxWidth = 0; + maxHeight = 0; + } + + if (config.legend_show && !$$.isLegendToShow(id)) { + widths[id] = heights[id] = steps[id] = offsets[id] = 0; + return + } + + widths[id] = itemWidth; + heights[id] = itemHeight; + + if (!maxWidth || itemWidth >= maxWidth) { + maxWidth = itemWidth; + } + if (!maxHeight || itemHeight >= maxHeight) { + maxHeight = itemHeight; + } + maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth; + + if (config.legend_equally) { + Object.keys(widths).forEach(function(id) { + widths[id] = maxWidth; + }); + Object.keys(heights).forEach(function(id) { + heights[id] = maxHeight; + }); + margin = (areaLength - maxLength * targetIds.length) / 2; + if (margin < posMin) { + totalLength = 0; + step = 0; + targetIds.forEach(function(id) { + updateValues(id); + }); + } else { + updateValues(id, true); + } + } else { + updateValues(id); } + } - if ($$.isLegendInset) { - step = config.legend_inset_step ? config.legend_inset_step : targetIds.length; - $$.updateLegendStep(step); - } + if ($$.isLegendInset) { + step = config.legend_inset_step + ? config.legend_inset_step + : targetIds.length; + $$.updateLegendStep(step); + } - if ($$.isLegendRight) { - xForLegend = function (id) { return maxWidth * steps[id]; }; - yForLegend = function (id) { return margins[steps[id]] + offsets[id]; }; - } else if ($$.isLegendInset) { - xForLegend = function (id) { return maxWidth * steps[id] + 10; }; - yForLegend = function (id) { return margins[steps[id]] + offsets[id]; }; - } else { - xForLegend = function (id) { return margins[steps[id]] + offsets[id]; }; - yForLegend = function (id) { return maxHeight * steps[id]; }; - } - xForLegendText = function (id, i) { return xForLegend(id, i) + 4 + config.legend_item_tile_width; }; - yForLegendText = function (id, i) { return yForLegend(id, i) + 9; }; - xForLegendRect = function (id, i) { return xForLegend(id, i); }; - yForLegendRect = function (id, i) { return yForLegend(id, i) - 5; }; - x1ForLegendTile = function (id, i) { return xForLegend(id, i) - 2; }; - x2ForLegendTile = function (id, i) { return xForLegend(id, i) - 2 + config.legend_item_tile_width; }; - yForLegendTile = function (id, i) { return yForLegend(id, i) + 4; }; - - // Define g for legend area - l = $$.legend.selectAll('.' + CLASS.legendItem) - .data(targetIds) - .enter().append('g') - .attr('class', function (id) { return $$.generateClass(CLASS.legendItem, id); }) - .style('visibility', function (id) { return $$.isLegendToShow(id) ? 'visible' : 'hidden'; }) - .style('cursor', 'pointer') - .on('click', function (id) { + if ($$.isLegendRight) { + xForLegend = function(id) { + return maxWidth * steps[id] + }; + yForLegend = function(id) { + return margins[steps[id]] + offsets[id] + }; + } else if ($$.isLegendInset) { + xForLegend = function(id) { + return maxWidth * steps[id] + 10 + }; + yForLegend = function(id) { + return margins[steps[id]] + offsets[id] + }; + } else { + xForLegend = function(id) { + return margins[steps[id]] + offsets[id] + }; + yForLegend = function(id) { + return maxHeight * steps[id] + }; + } + xForLegendText = function(id, i) { + return xForLegend(id, i) + 4 + config.legend_item_tile_width + }; + yForLegendText = function(id, i) { + return yForLegend(id, i) + 9 + }; + xForLegendRect = function(id, i) { + return xForLegend(id, i) + }; + yForLegendRect = function(id, i) { + return yForLegend(id, i) - 5 + }; + x1ForLegendTile = function(id, i) { + return xForLegend(id, i) - 2 + }; + x2ForLegendTile = function(id, i) { + return xForLegend(id, i) - 2 + config.legend_item_tile_width + }; + yForLegendTile = function(id, i) { + return yForLegend(id, i) + 4 + }; + + // Define g for legend area + l = $$.legend + .selectAll('.' + CLASS.legendItem) + .data(targetIds) + .enter() + .append('g') + .attr('class', function(id) { + return $$.generateClass(CLASS.legendItem, id) + }) + .style('visibility', function(id) { + return $$.isLegendToShow(id) ? 'visible' : 'hidden' + }) + .style('cursor', function() { + return config.interaction_enabled ? 'pointer' : 'auto' + }) + .on('click', + config.interaction_enabled + ? function(id) { if (config.legend_item_onclick) { - config.legend_item_onclick.call($$, id); + config.legend_item_onclick.call($$, id); } else { - if ($$.d3.event.altKey) { - $$.api.hide(); - $$.api.show(id); - } else { - $$.api.toggle(id); - $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); - } + if ($$.d3.event.altKey) { + $$.api.hide(); + $$.api.show(id); + } else { + $$.api.toggle(id); + $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); + } } - }) - .on('mouseover', function (id) { + } + : null + ) + .on('mouseover', + config.interaction_enabled + ? function(id) { if (config.legend_item_onmouseover) { - config.legend_item_onmouseover.call($$, id); - } - else { - $$.d3.select(this).classed(CLASS.legendItemFocused, true); - if (!$$.transiting && $$.isTargetToShow(id)) { - $$.api.focus(id); - } + config.legend_item_onmouseover.call($$, id); + } else { + $$.d3.select(this).classed(CLASS.legendItemFocused, true); + if (!$$.transiting && $$.isTargetToShow(id)) { + $$.api.focus(id); + } } - }) - .on('mouseout', function (id) { + } + : null + ) + .on('mouseout', + config.interaction_enabled + ? function(id) { if (config.legend_item_onmouseout) { - config.legend_item_onmouseout.call($$, id); - } - else { - $$.d3.select(this).classed(CLASS.legendItemFocused, false); - $$.api.revert(); + config.legend_item_onmouseout.call($$, id); + } else { + $$.d3.select(this).classed(CLASS.legendItemFocused, false); + $$.api.revert(); } - }); - l.append('text') - .text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }) - .each(function (id, i) { updatePositions(this, id, i); }) - .style("pointer-events", "none") - .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200) - .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); - l.append('rect') - .attr("class", CLASS.legendItemEvent) - .style('fill-opacity', 0) - .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200) - .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); - l.append('line') - .attr('class', CLASS.legendItemTile) - .style('stroke', $$.color) - .style("pointer-events", "none") - .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200) - .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) - .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200) - .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) - .attr('stroke-width', config.legend_item_tile_height); - - // Set background for inset legend - background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); - if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { - background = $$.legend.insert('g', '.' + CLASS.legendItem) - .attr("class", CLASS.legendBackground) - .append('rect'); - } - - texts = $$.legend.selectAll('text') - .data(targetIds) - .text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }) // MEMO: needed for update - .each(function (id, i) { updatePositions(this, id, i); }); - (withTransition ? texts.transition() : texts) - .attr('x', xForLegendText) - .attr('y', yForLegendText); - - rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent) - .data(targetIds); - (withTransition ? rects.transition() : rects) - .attr('width', function (id) { return widths[id]; }) - .attr('height', function (id) { return heights[id]; }) - .attr('x', xForLegendRect) - .attr('y', yForLegendRect); - - tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile) - .data(targetIds); - (withTransition ? tiles.transition() : tiles) - .style('stroke', $$.levelColor ? function(id) { - return $$.levelColor($$.cache[id].values.reduce(function (total, item) { return total + item.value; }, 0)); - } : $$.color) - .attr('x1', x1ForLegendTile) - .attr('y1', yForLegendTile) - .attr('x2', x2ForLegendTile) - .attr('y2', yForLegendTile); - - if (background) { - (withTransition ? background.transition() : background) - .attr('height', $$.getLegendHeight() - 12) - .attr('width', maxWidth * (step + 1) + 10); - } - - // toggle legend state - $$.legend.selectAll('.' + CLASS.legendItem) - .classed(CLASS.legendItemHidden, function (id) { return !$$.isTargetToShow(id); }); - - // Update all to reflect change of legend - $$.updateLegendItemWidth(maxWidth); - $$.updateLegendItemHeight(maxHeight); - $$.updateLegendStep(step); - // Update size and scale - $$.updateSizes(); - $$.updateScales(); - $$.updateSvgSize(); - // Update g positions - $$.transformAll(withTransitionForTransform, transitions); - $$.legendHasRendered = true; -}; - -ChartInternal.prototype.initRegion = function () { - var $$ = this; - $$.region = $$.main.append('g') - .attr("clip-path", $$.clipPath) - .attr("class", CLASS.regions); -}; -ChartInternal.prototype.updateRegion = function (duration) { - var $$ = this, config = $$.config; - - // hide if arc type - $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); - - var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region) - .data(config.regions); - var g = mainRegion.enter().append('g'); - g.append('rect') - .attr("x", $$.regionX.bind($$)) - .attr("y", $$.regionY.bind($$)) - .attr("width", $$.regionWidth.bind($$)) - .attr("height", $$.regionHeight.bind($$)) - .style("fill-opacity", function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }); - g.append('text') - .text($$.labelRegion.bind($$)); - $$.mainRegion = g.merge(mainRegion) - .attr('class', $$.classRegion.bind($$)); - mainRegion.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); -}; -ChartInternal.prototype.redrawRegion = function (withTransition, transition) { - var $$ = this, - regions = $$.mainRegion, - regionLabels = $$.mainRegion.selectAll('text'); - return [ - (withTransition ? regions.transition(transition) : regions) - .attr("x", $$.regionX.bind($$)) - .attr("y", $$.regionY.bind($$)) - .attr("width", $$.regionWidth.bind($$)) - .attr("height", $$.regionHeight.bind($$)) - .style("fill-opacity", function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }), - (withTransition ? regionLabels.transition(transition) : regionLabels) - .attr("x", $$.labelOffsetX.bind($$)) - .attr("y", $$.labelOffsetY.bind($$)) - .attr("transform", $$.labelTransform.bind($$)) - .attr("style", 'text-anchor: left;') - ]; -}; -ChartInternal.prototype.regionX = function (d) { - var $$ = this, config = $$.config, - xPos, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0; - } else { - xPos = config.axis_rotated ? 0 : ('start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0); - } - return xPos; -}; -ChartInternal.prototype.regionY = function (d) { - var $$ = this, config = $$.config, - yPos, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - yPos = config.axis_rotated ? 0 : ('end' in d ? yScale(d.end) : 0); - } else { - yPos = config.axis_rotated ? ('start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0) : 0; - } - return yPos; -}; -ChartInternal.prototype.regionWidth = function (d) { - var $$ = this, config = $$.config, - start = $$.regionX(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - end = config.axis_rotated ? ('end' in d ? yScale(d.end) : $$.width) : $$.width; - } else { - end = config.axis_rotated ? $$.width : ('end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width); - } - return end < start ? 0 : end - start; -}; -ChartInternal.prototype.regionHeight = function (d) { - var $$ = this, config = $$.config, - start = this.regionY(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - end = config.axis_rotated ? $$.height : ('start' in d ? yScale(d.start) : $$.height); - } else { - end = config.axis_rotated ? ('end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height) : $$.height; - } - return end < start ? 0 : end - start; + } + : null + ); + + l.append('text') + .text(function(id) { + return isDefined(config.data_names[id]) ? config.data_names[id] : id + }) + .each(function(id, i) { + updatePositions(this, id, i); + }) + .style('pointer-events', 'none') + .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200) + .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); + + l.append('rect') + .attr('class', CLASS.legendItemEvent) + .style('fill-opacity', 0) + .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200) + .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); + + l.append('line') + .attr('class', CLASS.legendItemTile) + .style('stroke', $$.color) + .style('pointer-events', 'none') + .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200) + .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) + .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200) + .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) + .attr('stroke-width', config.legend_item_tile_height); + + // Set background for inset legend + background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); + if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { + background = $$.legend + .insert('g', '.' + CLASS.legendItem) + .attr('class', CLASS.legendBackground) + .append('rect'); + } + + texts = $$.legend + .selectAll('text') + .data(targetIds) + .text(function(id) { + return isDefined(config.data_names[id]) ? config.data_names[id] : id + }) // MEMO: needed for update + .each(function(id, i) { + updatePositions(this, id, i); + }) + ;(withTransition ? texts.transition() : texts) + .attr('x', xForLegendText) + .attr('y', yForLegendText); + + rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds) + ;(withTransition ? rects.transition() : rects) + .attr('width', function(id) { + return widths[id] + }) + .attr('height', function(id) { + return heights[id] + }) + .attr('x', xForLegendRect) + .attr('y', yForLegendRect); + + tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds) + ;(withTransition ? tiles.transition() : tiles) + .style( + 'stroke', + $$.levelColor + ? function(id) { + return $$.levelColor( + $$.cache[id].values.reduce(function(total, item) { + return total + item.value + }, 0) + ) + } + : $$.color + ) + .attr('x1', x1ForLegendTile) + .attr('y1', yForLegendTile) + .attr('x2', x2ForLegendTile) + .attr('y2', yForLegendTile); + + if (background) { +(withTransition ? background.transition() : background) + .attr('height', $$.getLegendHeight() - 12) + .attr('width', maxWidth * (step + 1) + 10); + } + + // toggle legend state + $$.legend + .selectAll('.' + CLASS.legendItem) + .classed(CLASS.legendItemHidden, function(id) { + return !$$.isTargetToShow(id) + }); + + // Update all to reflect change of legend + $$.updateLegendItemWidth(maxWidth); + $$.updateLegendItemHeight(maxHeight); + $$.updateLegendStep(step); + // Update size and scale + $$.updateSizes(); + $$.updateScales(); + $$.updateSvgSize(); + // Update g positions + $$.transformAll(withTransitionForTransform, transitions); + $$.legendHasRendered = true; +}; + +ChartInternal.prototype.initRegion = function() { + var $$ = this; + $$.region = $$.main + .append('g') + .attr('clip-path', $$.clipPath) + .attr('class', CLASS.regions); +}; +ChartInternal.prototype.updateRegion = function(duration) { + var $$ = this, + config = $$.config; + + // hide if arc type + $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); + + var mainRegion = $$.main + .select('.' + CLASS.regions) + .selectAll('.' + CLASS.region) + .data(config.regions); + var g = mainRegion.enter().append('g'); + g.append('rect') + .attr('x', $$.regionX.bind($$)) + .attr('y', $$.regionY.bind($$)) + .attr('width', $$.regionWidth.bind($$)) + .attr('height', $$.regionHeight.bind($$)) + .style('fill-opacity', function(d) { + return isValue(d.opacity) ? d.opacity : 0.1 + }); + g.append('text').text($$.labelRegion.bind($$)); + $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$)); + mainRegion + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); +}; +ChartInternal.prototype.redrawRegion = function(withTransition, transition) { + var $$ = this, + regions = $$.mainRegion, + regionLabels = $$.mainRegion.selectAll('text'); + return [ + (withTransition ? regions.transition(transition) : regions) + .attr('x', $$.regionX.bind($$)) + .attr('y', $$.regionY.bind($$)) + .attr('width', $$.regionWidth.bind($$)) + .attr('height', $$.regionHeight.bind($$)) + .style('fill-opacity', function(d) { + return isValue(d.opacity) ? d.opacity : 0.1 + }), + (withTransition ? regionLabels.transition(transition) : regionLabels) + .attr('x', $$.labelOffsetX.bind($$)) + .attr('y', $$.labelOffsetY.bind($$)) + .attr('transform', $$.labelTransform.bind($$)) + .attr('style', 'text-anchor: left;') + ] +}; +ChartInternal.prototype.regionX = function(d) { + var $$ = this, + config = $$.config, + xPos, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0; + } else { + xPos = config.axis_rotated + ? 0 + : 'start' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) + : 0; + } + return xPos +}; +ChartInternal.prototype.regionY = function(d) { + var $$ = this, + config = $$.config, + yPos, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0; + } else { + yPos = config.axis_rotated + ? 'start' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) + : 0 + : 0; + } + return yPos +}; +ChartInternal.prototype.regionWidth = function(d) { + var $$ = this, + config = $$.config, + start = $$.regionX(d), + end, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + end = config.axis_rotated + ? 'end' in d + ? yScale(d.end) + : $$.width + : $$.width; + } else { + end = config.axis_rotated + ? $$.width + : 'end' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) + : $$.width; + } + return end < start ? 0 : end - start +}; +ChartInternal.prototype.regionHeight = function(d) { + var $$ = this, + config = $$.config, + start = this.regionY(d), + end, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + end = config.axis_rotated + ? $$.height + : 'start' in d + ? yScale(d.start) + : $$.height; + } else { + end = config.axis_rotated + ? 'end' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) + : $$.height + : $$.height; + } + return end < start ? 0 : end - start }; -ChartInternal.prototype.isRegionOnX = function (d) { - return !d.axis || d.axis === 'x'; +ChartInternal.prototype.isRegionOnX = function(d) { + return !d.axis || d.axis === 'x' }; -ChartInternal.prototype.labelRegion = function (d) { - return 'label' in d ? d.label : ''; +ChartInternal.prototype.labelRegion = function(d) { + return 'label' in d ? d.label : '' }; -ChartInternal.prototype.labelTransform = function (d) { - return ('vertical' in d && d.vertical) ? "rotate(90)" : ""; +ChartInternal.prototype.labelTransform = function(d) { + return 'vertical' in d && d.vertical ? 'rotate(90)' : '' }; -ChartInternal.prototype.labelOffsetX = function (d) { - var paddingX = 'paddingX' in d ? d.paddingX : 3; - var paddingY = 'paddingY' in d ? d.paddingY : 3; - return ('vertical' in d && d.vertical) ? this.regionY(d) + paddingY : (this.regionX(d) + paddingX); +ChartInternal.prototype.labelOffsetX = function(d) { + var paddingX = 'paddingX' in d ? d.paddingX : 3; + var paddingY = 'paddingY' in d ? d.paddingY : 3; + return 'vertical' in d && d.vertical + ? this.regionY(d) + paddingY + : this.regionX(d) + paddingX }; -ChartInternal.prototype.labelOffsetY = function (d) { - var paddingX = 'paddingX' in d ? d.paddingX : 3; - var paddingY = 'paddingY' in d ? d.paddingY : 3; - return ('vertical' in d && d.vertical) ? -(this.regionX(d) + paddingX) : this.regionY(d) + 10 + paddingY; +ChartInternal.prototype.labelOffsetY = function(d) { + var paddingX = 'paddingX' in d ? d.paddingX : 3; + var paddingY = 'paddingY' in d ? d.paddingY : 3; + return 'vertical' in d && d.vertical + ? -(this.regionX(d) + paddingX) + : this.regionY(d) + 10 + paddingY }; function c3LogScale(d3, linearScale, logScale) { - var PROJECTION = [0.01, 10]; + var PROJECTION = [0.01, 10]; - if (!linearScale) { - linearScale = d3.scaleLinear(); - linearScale.range(PROJECTION); - } + if (!linearScale) { + linearScale = d3.scaleLinear(); + linearScale.range(PROJECTION); + } - if (!logScale) { - logScale = d3.scaleLog(); - logScale.domain(PROJECTION); - logScale.nice(); - } + if (!logScale) { + logScale = d3.scaleLog(); + logScale.domain(PROJECTION); + logScale.nice(); + } - // copied from https://github.com/compute-io/logspace - function logspace( a, b, len ) { - var arr, - end, - tmp, - d; + // copied from https://github.com/compute-io/logspace + function logspace(a, b, len) { + var arr, end, tmp, d; - if ( arguments.length < 3 ) { - len = 10; - } else { - if ( len === 0 ) { - return []; - } - } - // Calculate the increment: - end = len - 1; - d = ( b-a ) / end; - - // Build the output array... - arr = new Array( len ); - tmp = a; - arr[ 0 ] = Math.pow( 10, tmp ); - for ( var i = 1; i < end; i++ ) { - tmp += d; - arr[ i ] = Math.pow( 10, tmp ); - } - arr[ end ] = Math.pow( 10, b ); - return arr; - } + if (arguments.length < 3) { + len = 10; + } else { + if (len === 0) { + return [] + } + } + // Calculate the increment: + end = len - 1; + d = (b - a) / end; + + // Build the output array... + arr = new Array(len); + tmp = a; + arr[0] = Math.pow(10, tmp); + for (var i = 1; i < end; i++) { + tmp += d; + arr[i] = Math.pow(10, tmp); + } + arr[end] = Math.pow(10, b); + return arr + } - function scale(x) { - return logScale(linearScale(x)); - } + function scale(x) { + return logScale(linearScale(x)) + } - scale.domain = function(x) { - if (!arguments.length) { - return linearScale.domain(); - } - linearScale.domain(x); - return scale; - }; + scale.domain = function(x) { + if (!arguments.length) { + return linearScale.domain() + } + linearScale.domain(x); + return scale + }; - scale.range = function(x) { - if (!arguments.length) { - return logScale.range(); - } - logScale.range(x); - return scale; - }; + scale.range = function(x) { + if (!arguments.length) { + return logScale.range() + } + logScale.range(x); + return scale + }; - scale.ticks = function(m) { - return logspace(-2, 1, m || 10).map(function (v) { - return linearScale.invert(v); - }); - }; + scale.ticks = function(m) { + return logspace(-2, 1, m || 10).map(function(v) { + return linearScale.invert(v) + }) + }; - scale.copy = function() { - return c3LogScale(d3, linearScale.copy(), logScale.copy()); - }; + scale.copy = function() { + return c3LogScale(d3, linearScale.copy(), logScale.copy()) + }; - return scale; + return scale } - -ChartInternal.prototype.getScale = function (min, max, forTimeseries) { - return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([min, max]); -}; -ChartInternal.prototype.getX = function (min, max, domain, offset) { - var $$ = this, - scale = $$.getScale(min, max, $$.isTimeSeries()), - _scale = domain ? scale.domain(domain) : scale, key; - // Define customized scale if categorized axis - if ($$.isCategorized()) { - offset = offset || function () { return 0; }; - scale = function (d, raw) { - var v = _scale(d) + offset(d); - return raw ? v : Math.ceil(v); - }; - } else { - scale = function (d, raw) { - var v = _scale(d); - return raw ? v : Math.ceil(v); - }; - } - // define functions - for (key in _scale) { - scale[key] = _scale[key]; - } - scale.orgDomain = function () { - return _scale.domain(); +ChartInternal.prototype.getScale = function(min, max, forTimeseries) { + return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([ + min, + max + ]) +}; +ChartInternal.prototype.getX = function(min, max, domain, offset) { + var $$ = this, + scale = $$.getScale(min, max, $$.isTimeSeries()), + _scale = domain ? scale.domain(domain) : scale, + key; + // Define customized scale if categorized axis + if ($$.isCategorized()) { + offset = + offset || + function() { + return 0 + }; + scale = function(d, raw) { + var v = _scale(d) + offset(d); + return raw ? v : Math.ceil(v) }; - // define custom domain() for categorized axis - if ($$.isCategorized()) { - scale.domain = function (domain) { - if (!arguments.length) { - domain = this.orgDomain(); - return [domain[0], domain[1] + 1]; - } - _scale.domain(domain); - return scale; - }; - } - return scale; + } else { + scale = function(d, raw) { + var v = _scale(d); + return raw ? v : Math.ceil(v) + }; + } + // define functions + for (key in _scale) { + scale[key] = _scale[key]; + } + scale.orgDomain = function() { + return _scale.domain() + }; + // define custom domain() for categorized axis + if ($$.isCategorized()) { + scale.domain = function(domain) { + if (!arguments.length) { + domain = this.orgDomain(); + return [domain[0], domain[1] + 1] + } + _scale.domain(domain); + return scale + }; + } + return scale }; /** @@ -8520,270 +10961,419 @@ ChartInternal.prototype.getX = function (min, max, domain, offset) { * * @return A d3-scale instance */ -ChartInternal.prototype.getY = function (type, domain, range) { - let scale; - if (type === 'timeseries' || type === 'time') { - scale = this.d3.scaleTime(); - } else if (type === 'log') { - scale = c3LogScale(this.d3); - } else if (type === 'linear' || type === undefined) { - scale = this.d3.scaleLinear(); - } else { - throw new Error(`Invalid Y axis type: "${type}"`); - } - - if (domain) { - scale.domain(domain); - } - - if (range) { - scale.range(range); - } - - return scale; -}; -ChartInternal.prototype.getYScale = function (id) { - return this.axis.getId(id) === 'y2' ? this.y2 : this.y; -}; -ChartInternal.prototype.getSubYScale = function (id) { - return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY; -}; -ChartInternal.prototype.updateScales = function () { - var $$ = this, config = $$.config, - forInit = !$$.x; - // update edges - $$.xMin = config.axis_rotated ? 1 : 0; - $$.xMax = config.axis_rotated ? $$.height : $$.width; - $$.yMin = config.axis_rotated ? 0 : $$.height; - $$.yMax = config.axis_rotated ? $$.width : 1; - $$.subXMin = $$.xMin; - $$.subXMax = $$.xMax; - $$.subYMin = config.axis_rotated ? 0 : $$.height2; - $$.subYMax = config.axis_rotated ? $$.width2 : 1; - // update scales - $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () { return $$.xAxis.tickOffset(); }); - $$.y = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.y.domain(), [ $$.yMin, $$.yMax ]); - $$.y2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.y2.domain(), [ $$.yMin, $$.yMax ]); - $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) { return d % 1 ? 0 : $$.subXAxis.tickOffset(); }); - $$.subY = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.subY.domain(), [ $$.subYMin, $$.subYMax ]); - $$.subY2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.subY2.domain(), [ $$.subYMin, $$.subYMax ]); - // update axes - $$.xAxisTickFormat = $$.axis.getXAxisTickFormat(); - $$.xAxisTickValues = $$.axis.getXAxisTickValues(); - $$.yAxisTickValues = $$.axis.getYAxisTickValues(); - $$.y2AxisTickValues = $$.axis.getY2AxisTickValues(); - - $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer); - $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer); - $$.yAxis = $$.axis.getYAxis('y', $$.y, $$.yOrient, $$.yAxisTickValues, config.axis_y_tick_outer); - $$.y2Axis = $$.axis.getYAxis('y2', $$.y2, $$.y2Orient, $$.y2AxisTickValues, config.axis_y2_tick_outer); - - // Set initialized scales to brush and zoom - if (!forInit) { - if ($$.brush) { $$.brush.updateScale($$.subX); } - } - // update for arc - if ($$.updateArc) { $$.updateArc(); } -}; - -ChartInternal.prototype.selectPoint = function (target, d, i) { - var $$ = this, config = $$.config, - cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), - cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), - r = $$.pointSelectR.bind($$); - config.data_onselected.call($$.api, d, target.node()); - // add selected-circle on low layer g - $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i) - .data([d]) - .enter().append('circle') - .attr("class", function () { return $$.generateClass(CLASS.selectedCircle, i); }) - .attr("cx", cx) - .attr("cy", cy) - .attr("stroke", function () { return $$.color(d); }) - .attr("r", function (d) { return $$.pointSelectR(d) * 1.4; }) - .transition().duration(100) - .attr("r", r); -}; -ChartInternal.prototype.unselectPoint = function (target, d, i) { - var $$ = this; - $$.config.data_onunselected.call($$.api, d, target.node()); - // remove selected-circle from low layer g - $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i) - .transition().duration(100).attr('r', 0) - .remove(); -}; -ChartInternal.prototype.togglePoint = function (selected, target, d, i) { - selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i); -}; -ChartInternal.prototype.selectPath = function (target, d) { - var $$ = this; - $$.config.data_onselected.call($$, d, target.node()); - if ($$.config.interaction_brighten) { - target.transition().duration(100) - .style("fill", function () { return $$.d3.rgb($$.color(d)).brighter(0.75); }); +ChartInternal.prototype.getY = function(type, domain, range) { + let scale; + if (type === 'timeseries' || type === 'time') { + scale = this.d3.scaleTime(); + } else if (type === 'log') { + scale = c3LogScale(this.d3); + } else if (type === 'linear' || type === undefined) { + scale = this.d3.scaleLinear(); + } else { + throw new Error(`Invalid Y axis type: "${type}"`) + } + + if (domain) { + scale.domain(domain); + } + + if (range) { + scale.range(range); + } + + return scale +}; +ChartInternal.prototype.getYScale = function(id) { + return this.axis.getId(id) === 'y2' ? this.y2 : this.y +}; +ChartInternal.prototype.getSubYScale = function(id) { + return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY +}; +ChartInternal.prototype.updateScales = function() { + var $$ = this, + config = $$.config, + forInit = !$$.x; + // update edges + $$.xMin = config.axis_rotated ? 1 : 0; + $$.xMax = config.axis_rotated ? $$.height : $$.width; + $$.yMin = config.axis_rotated ? 0 : $$.height; + $$.yMax = config.axis_rotated ? $$.width : 1; + $$.subXMin = $$.xMin; + $$.subXMax = $$.xMax; + $$.subYMin = config.axis_rotated ? 0 : $$.height2; + $$.subYMax = config.axis_rotated ? $$.width2 : 1; + // update scales + $$.x = $$.getX( + $$.xMin, + $$.xMax, + forInit ? undefined : $$.x.orgDomain(), + function() { + return $$.xAxis.tickOffset() + } + ); + $$.y = $$.getY( + config.axis_y_type, + forInit ? config.axis_y_default : $$.y.domain(), + [$$.yMin, $$.yMax] + ); + $$.y2 = $$.getY( + config.axis_y2_type, + forInit ? config.axis_y2_default : $$.y2.domain(), + [$$.yMin, $$.yMax] + ); + $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function(d) { + return d % 1 ? 0 : $$.subXAxis.tickOffset() + }); + $$.subY = $$.getY( + config.axis_y_type, + forInit ? config.axis_y_default : $$.subY.domain(), + [$$.subYMin, $$.subYMax] + ); + $$.subY2 = $$.getY( + config.axis_y2_type, + forInit ? config.axis_y2_default : $$.subY2.domain(), + [$$.subYMin, $$.subYMax] + ); + // update axes + $$.xAxisTickFormat = $$.axis.getXAxisTickFormat(); + $$.xAxisTickValues = $$.axis.getXAxisTickValues(); + $$.yAxisTickValues = $$.axis.getYAxisTickValues(); + $$.y2AxisTickValues = $$.axis.getY2AxisTickValues(); + + $$.xAxis = $$.axis.getXAxis( + $$.x, + $$.xOrient, + $$.xAxisTickFormat, + $$.xAxisTickValues, + config.axis_x_tick_outer + ); + $$.subXAxis = $$.axis.getXAxis( + $$.subX, + $$.subXOrient, + $$.xAxisTickFormat, + $$.xAxisTickValues, + config.axis_x_tick_outer + ); + $$.yAxis = $$.axis.getYAxis( + 'y', + $$.y, + $$.yOrient, + $$.yAxisTickValues, + config.axis_y_tick_outer + ); + $$.y2Axis = $$.axis.getYAxis( + 'y2', + $$.y2, + $$.y2Orient, + $$.y2AxisTickValues, + config.axis_y2_tick_outer + ); + + // Set initialized scales to brush and zoom + if (!forInit) { + if ($$.brush) { + $$.brush.updateScale($$.subX); } + } + // update for arc + if ($$.updateArc) { + $$.updateArc(); + } }; -ChartInternal.prototype.unselectPath = function (target, d) { - var $$ = this; - $$.config.data_onunselected.call($$, d, target.node()); - if ($$.config.interaction_brighten) { - target.transition().duration(100) - .style("fill", function () { return $$.color(d); }); - } + +ChartInternal.prototype.selectPoint = function(target, d, i) { + var $$ = this, + config = $$.config, + cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), + cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), + r = $$.pointSelectR.bind($$); + config.data_onselected.call($$.api, d, target.node()); + // add selected-circle on low layer g + $$.main + .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)) + .selectAll('.' + CLASS.selectedCircle + '-' + i) + .data([d]) + .enter() + .append('circle') + .attr('class', function() { + return $$.generateClass(CLASS.selectedCircle, i) + }) + .attr('cx', cx) + .attr('cy', cy) + .attr('stroke', function() { + return $$.color(d) + }) + .attr('r', function(d) { + return $$.pointSelectR(d) * 1.4 + }) + .transition() + .duration(100) + .attr('r', r); +}; +ChartInternal.prototype.unselectPoint = function(target, d, i) { + var $$ = this; + $$.config.data_onunselected.call($$.api, d, target.node()); + // remove selected-circle from low layer g + $$.main + .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)) + .selectAll('.' + CLASS.selectedCircle + '-' + i) + .transition() + .duration(100) + .attr('r', 0) + .remove(); +}; +ChartInternal.prototype.togglePoint = function(selected, target, d, i) { + selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i); +}; +ChartInternal.prototype.selectPath = function(target, d) { + var $$ = this; + $$.config.data_onselected.call($$, d, target.node()); + if ($$.config.interaction_brighten) { + target + .transition() + .duration(100) + .style('fill', function() { + return $$.d3.rgb($$.color(d)).brighter(0.75) + }); + } +}; +ChartInternal.prototype.unselectPath = function(target, d) { + var $$ = this; + $$.config.data_onunselected.call($$, d, target.node()); + if ($$.config.interaction_brighten) { + target + .transition() + .duration(100) + .style('fill', function() { + return $$.color(d) + }); + } }; -ChartInternal.prototype.togglePath = function (selected, target, d, i) { - selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i); +ChartInternal.prototype.togglePath = function(selected, target, d, i) { + selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i); }; -ChartInternal.prototype.getToggle = function (that, d) { - var $$ = this, toggle; - if (that.nodeName === 'circle') { - if ($$.isStepType(d)) { - // circle is hidden in step chart, so treat as within the click area - toggle = function () {}; // TODO: how to select step chart? - } else { - toggle = $$.togglePoint; - } +ChartInternal.prototype.getToggle = function(that, d) { + var $$ = this, + toggle; + if (that.nodeName === 'circle') { + if ($$.isStepType(d)) { + // circle is hidden in step chart, so treat as within the click area + toggle = function() {}; // TODO: how to select step chart? + } else { + toggle = $$.togglePoint; } - else if (that.nodeName === 'path') { - toggle = $$.togglePath; + } else if (that.nodeName === 'path') { + toggle = $$.togglePath; + } + return toggle +}; +ChartInternal.prototype.toggleShape = function(that, d, i) { + var $$ = this, + d3 = $$.d3, + config = $$.config, + shape = d3.select(that), + isSelected = shape.classed(CLASS.SELECTED), + toggle = $$.getToggle(that, d).bind($$); + + if (config.data_selection_enabled && config.data_selection_isselectable(d)) { + if (!config.data_selection_multiple) { + $$.main + .selectAll( + '.' + + CLASS.shapes + + (config.data_selection_grouped + ? $$.getTargetSelectorSuffix(d.id) + : '') + ) + .selectAll('.' + CLASS.shape) + .each(function(d, i) { + var shape = d3.select(this); + if (shape.classed(CLASS.SELECTED)) { + toggle(false, shape.classed(CLASS.SELECTED, false), d, i); + } + }); } - return toggle; + shape.classed(CLASS.SELECTED, !isSelected); + toggle(!isSelected, shape, d, i); + } }; -ChartInternal.prototype.toggleShape = function (that, d, i) { - var $$ = this, d3 = $$.d3, config = $$.config, - shape = d3.select(that), isSelected = shape.classed(CLASS.SELECTED), - toggle = $$.getToggle(that, d).bind($$); - if (config.data_selection_enabled && config.data_selection_isselectable(d)) { - if (!config.data_selection_multiple) { - $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) { - var shape = d3.select(this); - if (shape.classed(CLASS.SELECTED)) { toggle(false, shape.classed(CLASS.SELECTED, false), d, i); } - }); - } - shape.classed(CLASS.SELECTED, !isSelected); - toggle(!isSelected, shape, d, i); - } -}; - -ChartInternal.prototype.initBar = function () { - var $$ = this; - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartBars); -}; -ChartInternal.prototype.updateTargetsForBar = function (targets) { - var $$ = this, config = $$.config, - mainBars, mainBarEnter, - classChartBar = $$.classChartBar.bind($$), - classBars = $$.classBars.bind($$), - classFocus = $$.classFocus.bind($$); - mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar) - .data(targets) - .attr('class', function (d) { return classChartBar(d) + classFocus(d); }); - mainBarEnter = mainBars.enter().append('g') - .attr('class', classChartBar) - .style("pointer-events", "none"); - // Bars for each data - mainBarEnter.append('g') - .attr("class", classBars) - .style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; }); - -}; -ChartInternal.prototype.updateBar = function (durationForExit) { - var $$ = this, - barData = $$.barData.bind($$), - classBar = $$.classBar.bind($$), - initialOpacity = $$.initialOpacity.bind($$), - color = function (d) { return $$.color(d.id); }; - var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar) - .data(barData); - var mainBarEnter = mainBar.enter().append('path') - .attr("class", classBar) - .style("stroke", color) - .style("fill", color); - $$.mainBar = mainBarEnter.merge(mainBar) - .style("opacity", initialOpacity); - mainBar.exit().transition().duration(durationForExit) - .style("opacity", 0); -}; -ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) { - const $$ = this; +ChartInternal.prototype.initBar = function() { + var $$ = this; + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartBars); +}; +ChartInternal.prototype.updateTargetsForBar = function(targets) { + var $$ = this, + config = $$.config, + mainBars, + mainBarEnter, + classChartBar = $$.classChartBar.bind($$), + classBars = $$.classBars.bind($$), + classFocus = $$.classFocus.bind($$); + mainBars = $$.main + .select('.' + CLASS.chartBars) + .selectAll('.' + CLASS.chartBar) + .data(targets) + .attr('class', function(d) { + return classChartBar(d) + classFocus(d) + }); + mainBarEnter = mainBars + .enter() + .append('g') + .attr('class', classChartBar) + .style('pointer-events', 'none'); + // Bars for each data + mainBarEnter + .append('g') + .attr('class', classBars) + .style('cursor', function(d) { + return config.data_selection_isselectable(d) ? 'pointer' : null + }); +}; +ChartInternal.prototype.updateBar = function(durationForExit) { + var $$ = this, + barData = $$.barData.bind($$), + classBar = $$.classBar.bind($$), + initialOpacity = $$.initialOpacity.bind($$), + color = function(d) { + return $$.color(d.id) + }; + var mainBar = $$.main + .selectAll('.' + CLASS.bars) + .selectAll('.' + CLASS.bar) + .data(barData); + var mainBarEnter = mainBar + .enter() + .append('path') + .attr('class', classBar) + .style('stroke', color) + .style('fill', color); + $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity); + mainBar + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0); +}; +ChartInternal.prototype.redrawBar = function( + drawBar, + withTransition, + transition +) { + const $$ = this; - return [ - (withTransition ? this.mainBar.transition(transition) : this.mainBar) - .attr('d', drawBar) - .style("stroke", this.color) - .style("fill", this.color) - .style("opacity", (d) => $$.isTargetToShow(d.id) ? 1 : 0) - ]; -}; -ChartInternal.prototype.getBarW = function (axis, barTargetsNum) { - var $$ = this, config = $$.config, - w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum : 0; - return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w; -}; -ChartInternal.prototype.getBars = function (i, id) { - var $$ = this; - return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')); -}; -ChartInternal.prototype.expandBars = function (i, id, reset) { - var $$ = this; - if (reset) { $$.unexpandBars(); } - $$.getBars(i, id).classed(CLASS.EXPANDED, true); -}; -ChartInternal.prototype.unexpandBars = function (i) { - var $$ = this; - $$.getBars(i).classed(CLASS.EXPANDED, false); -}; -ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) { - var $$ = this, config = $$.config, - getPoints = $$.generateGetBarPoints(barIndices, isSub); - return function (d, i) { - // 4 points that make a bar - var points = getPoints(d, i); - - // switch points if axis is rotated, not applicable for sub chart - var indexX = config.axis_rotated ? 1 : 0; - var indexY = config.axis_rotated ? 0 : 1; - - var path = 'M ' + points[0][indexX] + ',' + points[0][indexY] + ' ' + - 'L' + points[1][indexX] + ',' + points[1][indexY] + ' ' + - 'L' + points[2][indexX] + ',' + points[2][indexY] + ' ' + - 'L' + points[3][indexX] + ',' + points[3][indexY] + ' ' + - 'z'; - - return path; - }; -}; -ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) { - var $$ = this, - axis = isSub ? $$.subXAxis : $$.xAxis, - barTargetsNum = barIndices.__max__ + 1, - barW = $$.getBarW(axis, barTargetsNum), - barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), - barY = $$.getShapeY(!!isSub), - barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), - barSpaceOffset = barW * ($$.config.bar_space / 2), - yScale = isSub ? $$.getSubYScale : $$.getYScale; - return function (d, i) { - var y0 = yScale.call($$, d.id)(0), - offset = barOffset(d, i) || y0, // offset is for stacked bar chart - posX = barX(d), posY = barY(d); - // fix posY not to overflow opposite quadrant - if ($$.config.axis_rotated) { - if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; } - } + return [ + (withTransition ? this.mainBar.transition(transition) : this.mainBar) + .attr('d', drawBar) + .style('stroke', this.color) + .style('fill', this.color) + .style('opacity', d => ($$.isTargetToShow(d.id) ? 1 : 0)) + ] +}; +ChartInternal.prototype.getBarW = function(axis, barTargetsNum) { + var $$ = this, + config = $$.config, + w = + typeof config.bar_width === 'number' + ? config.bar_width + : barTargetsNum + ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum + : 0; + return config.bar_width_max && w > config.bar_width_max + ? config.bar_width_max + : w +}; +ChartInternal.prototype.getBars = function(i, id) { + var $$ = this; + return (id + ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) + : $$.main + ).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')) +}; +ChartInternal.prototype.expandBars = function(i, id, reset) { + var $$ = this; + if (reset) { + $$.unexpandBars(); + } + $$.getBars(i, id).classed(CLASS.EXPANDED, true); +}; +ChartInternal.prototype.unexpandBars = function(i) { + var $$ = this; + $$.getBars(i).classed(CLASS.EXPANDED, false); +}; +ChartInternal.prototype.generateDrawBar = function(barIndices, isSub) { + var $$ = this, + config = $$.config, + getPoints = $$.generateGetBarPoints(barIndices, isSub); + return function(d, i) { + // 4 points that make a bar + var points = getPoints(d, i); + + // switch points if axis is rotated, not applicable for sub chart + var indexX = config.axis_rotated ? 1 : 0; + var indexY = config.axis_rotated ? 0 : 1; + + var path = + 'M ' + + points[0][indexX] + + ',' + + points[0][indexY] + + ' ' + + 'L' + + points[1][indexX] + + ',' + + points[1][indexY] + + ' ' + + 'L' + + points[2][indexX] + + ',' + + points[2][indexY] + + ' ' + + 'L' + + points[3][indexX] + + ',' + + points[3][indexY] + + ' ' + + 'z'; + + return path + } +}; +ChartInternal.prototype.generateGetBarPoints = function(barIndices, isSub) { + var $$ = this, + axis = isSub ? $$.subXAxis : $$.xAxis, + barTargetsNum = barIndices.__max__ + 1, + barW = $$.getBarW(axis, barTargetsNum), + barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), + barY = $$.getShapeY(!!isSub), + barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), + barSpaceOffset = barW * ($$.config.bar_space / 2), + yScale = isSub ? $$.getSubYScale : $$.getYScale; + return function(d, i) { + var y0 = yScale.call($$, d.id)(0), + offset = barOffset(d, i) || y0, // offset is for stacked bar chart + posX = barX(d), + posY = barY(d); + // fix posY not to overflow opposite quadrant + if ($$.config.axis_rotated) { + if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { + posY = y0; + } + } - posY -= (y0 - offset); + posY -= y0 - offset; - // 4 points that make a bar - return [ - [posX + barSpaceOffset, offset], - [posX + barSpaceOffset, posY], - [posX + barW - barSpaceOffset, posY], - [posX + barW - barSpaceOffset, offset] - ]; - }; + // 4 points that make a bar + return [ + [posX + barSpaceOffset, offset], + [posX + barSpaceOffset, posY], + [posX + barW - barSpaceOffset, posY], + [posX + barW - barSpaceOffset, offset] + ] + } }; /** @@ -8793,1954 +11383,2641 @@ ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) { * @param barShape * @return {boolean} */ -ChartInternal.prototype.isWithinBar = function (mouse, barShape) { - return isWithinBox(mouse, getBBox(barShape), 2); -}; - -ChartInternal.prototype.getShapeIndices = function (typeFilter) { - var $$ = this, config = $$.config, - indices = {}, i = 0, j, k; - $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) { - for (j = 0; j < config.data_groups.length; j++) { - if (config.data_groups[j].indexOf(d.id) < 0) { continue; } - for (k = 0; k < config.data_groups[j].length; k++) { - if (config.data_groups[j][k] in indices) { - indices[d.id] = indices[config.data_groups[j][k]]; - break; - } - } - } - if (isUndefined(indices[d.id])) { indices[d.id] = i++; } - }); - indices.__max__ = i - 1; - return indices; -}; -ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) { - var $$ = this, scale = isSub ? $$.subX : $$.x; - return function (d) { - var index = d.id in indices ? indices[d.id] : 0; - return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0; - }; -}; -ChartInternal.prototype.getShapeY = function (isSub) { - const $$ = this; - - return function (d) { - const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id); - return scale($$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value); - }; -}; -ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) { - var $$ = this, - targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))), - targetIds = targets.map(function (t) { return t.id; }); - return function (d, i) { - var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), - y0 = scale(0), offset = y0; - targets.forEach(function (t) { - const rowValues = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values; - const isTargetNormalized = $$.isTargetNormalized(d.id); - const values = rowValues.map(v => (isTargetNormalized ? $$.getRatio("index", v, true) : v.value)); - - if (t.id === d.id || indices[t.id] !== indices[d.id]) { return; } - if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) { - // check if the x values line up - if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) { // "+" for timeseries - // if not, try to find the value that does line up - i = -1; - rowValues.forEach(function (v, j) { - const x1 = v.x.constructor === Date ? +v.x : v.x; - const x2 = d.x.constructor === Date ? +d.x : d.x; - - if (x1 === x2) { - i = j; - } - }); - } - if (i in rowValues && rowValues[i].value * d.value >= 0) { - offset += scale(values[i]) - y0; - } - } - }); - return offset; - }; -}; -ChartInternal.prototype.isWithinShape = function (that, d) { - var $$ = this, - shape = $$.d3.select(that), isWithin; - if (!$$.isTargetToShow(d.id)) { - isWithin = false; - } - else if (that.nodeName === 'circle') { - isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5); - } - else if (that.nodeName === 'path') { - isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar($$.d3.mouse(that), that) : true; - } - return isWithin; +ChartInternal.prototype.isWithinBar = function(mouse, barShape) { + return isWithinBox(mouse, getBBox(barShape), 2) +}; + +ChartInternal.prototype.getShapeIndices = function(typeFilter) { + var $$ = this, + config = $$.config, + indices = {}, + i = 0, + j, + k; + $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach( + function(d) { + for (j = 0; j < config.data_groups.length; j++) { + if (config.data_groups[j].indexOf(d.id) < 0) { + continue + } + for (k = 0; k < config.data_groups[j].length; k++) { + if (config.data_groups[j][k] in indices) { + indices[d.id] = indices[config.data_groups[j][k]]; + break + } + } + } + if (isUndefined(indices[d.id])) { + indices[d.id] = i++; + } + } + ); + indices.__max__ = i - 1; + return indices +}; +ChartInternal.prototype.getShapeX = function( + offset, + targetsNum, + indices, + isSub +) { + var $$ = this, + scale = isSub ? $$.subX : $$.x; + return function(d) { + var index = d.id in indices ? indices[d.id] : 0; + return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0 + } }; +ChartInternal.prototype.getShapeY = function(isSub) { + const $$ = this; - -ChartInternal.prototype.getInterpolate = function (d) { - var $$ = this, d3 = $$.d3, - types = { - 'linear': d3.curveLinear, - 'linear-closed': d3.curveLinearClosed, - 'basis': d3.curveBasis, - 'basis-open': d3.curveBasisOpen, - 'basis-closed': d3.curveBasisClosed, - 'bundle': d3.curveBundle, - 'cardinal': d3.curveCardinal, - 'cardinal-open': d3.curveCardinalOpen, - 'cardinal-closed': d3.curveCardinalClosed, - 'monotone': d3.curveMonotoneX, - 'step': d3.curveStep, - 'step-before': d3.curveStepBefore, - 'step-after': d3.curveStepAfter - }, - type; - - if ($$.isSplineType(d)) { - type = types[$$.config.spline_interpolation_type] || types.cardinal; - } - else if ($$.isStepType(d)) { - type = types[$$.config.line_step_type]; - } - else { - type = types.linear; - } - return type; -}; - -ChartInternal.prototype.initLine = function () { - var $$ = this; - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartLines); -}; -ChartInternal.prototype.updateTargetsForLine = function (targets) { - var $$ = this, config = $$.config, - mainLines, mainLineEnter, - classChartLine = $$.classChartLine.bind($$), - classLines = $$.classLines.bind($$), - classAreas = $$.classAreas.bind($$), - classCircles = $$.classCircles.bind($$), - classFocus = $$.classFocus.bind($$); - mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine) - .data(targets) - .attr('class', function (d) { return classChartLine(d) + classFocus(d); }); - mainLineEnter = mainLines.enter().append('g') - .attr('class', classChartLine) - .style('opacity', 0) - .style("pointer-events", "none"); - // Lines for each data - mainLineEnter.append('g') - .attr("class", classLines); - // Areas - mainLineEnter.append('g') - .attr('class', classAreas); - // Circles for each data point on lines - mainLineEnter.append('g') - .attr("class", function (d) { return $$.generateClass(CLASS.selectedCircles, d.id); }); - mainLineEnter.append('g') - .attr("class", classCircles) - .style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; }); - // Update date for selected circles - targets.forEach(function (t) { - $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) { - d.value = t.values[d.index].value; - }); + return function(d) { + const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id); + return scale( + $$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value + ) + } +}; +ChartInternal.prototype.getShapeOffset = function(typeFilter, indices, isSub) { + var $$ = this, + targets = $$.orderTargets( + $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)) + ), + targetIds = targets.map(function(t) { + return t.id }); - // MEMO: can not keep same color... - //mainLineUpdate.exit().remove(); -}; -ChartInternal.prototype.updateLine = function (durationForExit) { - var $$ = this; - var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line) - .data($$.lineData.bind($$)); - var mainLineEnter = mainLine.enter().append('path') - .attr('class', $$.classLine.bind($$)) - .style("stroke", $$.color); - $$.mainLine = mainLineEnter.merge(mainLine) - .style("opacity", $$.initialOpacity.bind($$)) - .style('shape-rendering', function (d) { return $$.isStepType(d) ? 'crispEdges' : ''; }) - .attr('transform', null); - mainLine.exit().transition().duration(durationForExit) - .style('opacity', 0); -}; -ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) { - return [ - (withTransition ? this.mainLine.transition(transition) : this.mainLine) - .attr("d", drawLine) - .style("stroke", this.color) - .style("opacity", 1) - ]; -}; -ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) { - var $$ = this, config = $$.config, - line = $$.d3.line(), - getPoints = $$.generateGetLinePoints(lineIndices, isSub), - yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, - xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); }, - yValue = function (d, i) { - return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value); - }; - - line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue); - if (!config.line_connectNull) { line = line.defined(function (d) { return d.value != null; }); } - return function (d) { - var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values, - x = isSub ? $$.subX : $$.x, y = yScaleGetter.call($$, d.id), x0 = 0, y0 = 0, path; - if ($$.isLineType(d)) { - if (config.data_regions[d.id]) { - path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]); - } else { - if ($$.isStepType(d)) { values = $$.convertValuesToStep(values); } - path = line.curve($$.getInterpolate(d))(values); - } - } else { - if (values[0]) { - x0 = x(values[0].x); - y0 = y(values[0].value); + return function(d, i) { + var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), + y0 = scale(0), + offset = y0; + targets.forEach(function(t) { + const rowValues = $$.isStepType(d) + ? $$.convertValuesToStep(t.values) + : t.values; + const isTargetNormalized = $$.isTargetNormalized(d.id); + const values = rowValues.map(v => + isTargetNormalized ? $$.getRatio('index', v, true) : v.value + ); + + if (t.id === d.id || indices[t.id] !== indices[d.id]) { + return + } + if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) { + // check if the x values line up + if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) { + // "+" for timeseries + // if not, try to find the value that does line up + i = -1; + rowValues.forEach(function(v, j) { + const x1 = v.x.constructor === Date ? +v.x : v.x; + const x2 = d.x.constructor === Date ? +d.x : d.x; + + if (x1 === x2) { + i = j; } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; + }); } - return path ? path : "M 0 0"; - }; -}; -ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) { // partial duplication of generateGetBarPoints - var $$ = this, config = $$.config, - lineTargetsNum = lineIndices.__max__ + 1, - x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), - y = $$.getShapeY(!!isSub), - lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), - yScale = isSub ? $$.getSubYScale : $$.getYScale; - return function (d, i) { - var y0 = yScale.call($$, d.id)(0), - offset = lineOffset(d, i) || y0, // offset is for stacked area chart - posX = x(d), posY = y(d); - // fix posY not to overflow opposite quadrant - if (config.axis_rotated) { - if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; } + if (i in rowValues && rowValues[i].value * d.value >= 0) { + offset += scale(values[i]) - y0; } - // 1 point that marks the line position - return [ - [posX, posY - (y0 - offset)], - [posX, posY - (y0 - offset)], // needed for compatibility - [posX, posY - (y0 - offset)], // needed for compatibility - [posX, posY - (y0 - offset)] // needed for compatibility - ]; - }; + } + }); + return offset + } }; +ChartInternal.prototype.isWithinShape = function(that, d) { + var $$ = this, + shape = $$.d3.select(that), + isWithin; + if (!$$.isTargetToShow(d.id)) { + isWithin = false; + } else if (that.nodeName === 'circle') { + isWithin = $$.isStepType(d) + ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) + : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5); + } else if (that.nodeName === 'path') { + isWithin = shape.classed(CLASS.bar) + ? $$.isWithinBar($$.d3.mouse(that), that) + : true; + } + return isWithin +}; + +ChartInternal.prototype.getInterpolate = function(d) { + var $$ = this, + d3 = $$.d3, + types = { + linear: d3.curveLinear, + 'linear-closed': d3.curveLinearClosed, + basis: d3.curveBasis, + 'basis-open': d3.curveBasisOpen, + 'basis-closed': d3.curveBasisClosed, + bundle: d3.curveBundle, + cardinal: d3.curveCardinal, + 'cardinal-open': d3.curveCardinalOpen, + 'cardinal-closed': d3.curveCardinalClosed, + monotone: d3.curveMonotoneX, + step: d3.curveStep, + 'step-before': d3.curveStepBefore, + 'step-after': d3.curveStepAfter + }, + type; + + if ($$.isSplineType(d)) { + type = types[$$.config.spline_interpolation_type] || types.cardinal; + } else if ($$.isStepType(d)) { + type = types[$$.config.line_step_type]; + } else { + type = types.linear; + } + return type +}; + +ChartInternal.prototype.initLine = function() { + var $$ = this; + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartLines); +}; +ChartInternal.prototype.updateTargetsForLine = function(targets) { + var $$ = this, + config = $$.config, + mainLines, + mainLineEnter, + classChartLine = $$.classChartLine.bind($$), + classLines = $$.classLines.bind($$), + classAreas = $$.classAreas.bind($$), + classCircles = $$.classCircles.bind($$), + classFocus = $$.classFocus.bind($$); + mainLines = $$.main + .select('.' + CLASS.chartLines) + .selectAll('.' + CLASS.chartLine) + .data(targets) + .attr('class', function(d) { + return classChartLine(d) + classFocus(d) + }); + mainLineEnter = mainLines + .enter() + .append('g') + .attr('class', classChartLine) + .style('opacity', 0) + .style('pointer-events', 'none'); + // Lines for each data + mainLineEnter.append('g').attr('class', classLines); + // Areas + mainLineEnter.append('g').attr('class', classAreas); + // Circles for each data point on lines + mainLineEnter.append('g').attr('class', function(d) { + return $$.generateClass(CLASS.selectedCircles, d.id) + }); + mainLineEnter + .append('g') + .attr('class', classCircles) + .style('cursor', function(d) { + return config.data_selection_isselectable(d) ? 'pointer' : null + }); + // Update date for selected circles + targets.forEach(function(t) { + $$.main + .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)) + .selectAll('.' + CLASS.selectedCircle) + .each(function(d) { + d.value = t.values[d.index].value; + }); + }); + // MEMO: can not keep same color... + //mainLineUpdate.exit().remove(); +}; +ChartInternal.prototype.updateLine = function(durationForExit) { + var $$ = this; + var mainLine = $$.main + .selectAll('.' + CLASS.lines) + .selectAll('.' + CLASS.line) + .data($$.lineData.bind($$)); + var mainLineEnter = mainLine + .enter() + .append('path') + .attr('class', $$.classLine.bind($$)) + .style('stroke', $$.color); + $$.mainLine = mainLineEnter + .merge(mainLine) + .style('opacity', $$.initialOpacity.bind($$)) + .style('shape-rendering', function(d) { + return $$.isStepType(d) ? 'crispEdges' : '' + }) + .attr('transform', null); + mainLine + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0); +}; +ChartInternal.prototype.redrawLine = function( + drawLine, + withTransition, + transition +) { + return [ + (withTransition ? this.mainLine.transition(transition) : this.mainLine) + .attr('d', drawLine) + .style('stroke', this.color) + .style('opacity', 1) + ] +}; +ChartInternal.prototype.generateDrawLine = function(lineIndices, isSub) { + var $$ = this, + config = $$.config, + line = $$.d3.line(), + getPoints = $$.generateGetLinePoints(lineIndices, isSub), + yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, + xValue = function(d) { + return (isSub ? $$.subxx : $$.xx).call($$, d) + }, + yValue = function(d, i) { + return config.data_groups.length > 0 + ? getPoints(d, i)[0][1] + : yScaleGetter.call($$, d.id)(d.value) + }; - -ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) { - var $$ = this, config = $$.config, - prev = -1, i, j, - s = "M", sWithRegion, - xp, yp, dx, dy, dd, diff, diffx2, - xOffset = $$.isCategorized() ? 0.5 : 0, - xValue, yValue, - regions = []; - - function isWithinRegions(x, regions) { - var i; - for (i = 0; i < regions.length; i++) { - if (regions[i].start < x && x <= regions[i].end) { return true; } - } - return false; - } - - // Check start/end of regions - if (isDefined(_regions)) { - for (i = 0; i < _regions.length; i++) { - regions[i] = {}; - if (isUndefined(_regions[i].start)) { - regions[i].start = d[0].x; - } else { - regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start; - } - if (isUndefined(_regions[i].end)) { - regions[i].end = d[d.length - 1].x; - } else { - regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end; - } + line = config.axis_rotated + ? line.x(yValue).y(xValue) + : line.x(xValue).y(yValue); + if (!config.line_connectNull) { + line = line.defined(function(d) { + return d.value != null + }); + } + return function(d) { + var values = config.line_connectNull + ? $$.filterRemoveNull(d.values) + : d.values, + x = isSub ? $$.subX : $$.x, + y = yScaleGetter.call($$, d.id), + x0 = 0, + y0 = 0, + path; + if ($$.isLineType(d)) { + if (config.data_regions[d.id]) { + path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]); + } else { + if ($$.isStepType(d)) { + values = $$.convertValuesToStep(values); } - } - - // Set scales - xValue = config.axis_rotated ? function (d) { return y(d.value); } : function (d) { return x(d.x); }; - yValue = config.axis_rotated ? function (d) { return x(d.x); } : function (d) { return y(d.value); }; - - // Define svg generator function for region - function generateM(points) { - return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1]; - } - if ($$.isTimeSeries()) { - sWithRegion = function (d0, d1, j, diff) { - var x0 = d0.x.getTime(), x_diff = d1.x - d0.x, - xv0 = new Date(x0 + x_diff * j), - xv1 = new Date(x0 + x_diff * (j + diff)), - points; - if (config.axis_rotated) { - points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]]; - } else { - points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]]; - } - return generateM(points); - }; + path = line.curve($$.getInterpolate(d))(values); + } } else { - sWithRegion = function (d0, d1, j, diff) { - var points; - if (config.axis_rotated) { - points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]]; - } else { - points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]]; - } - return generateM(points); - }; + if (values[0]) { + x0 = x(values[0].x); + y0 = y(values[0].value); + } + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } - - // Generate - for (i = 0; i < d.length; i++) { - - // Draw as normal - if (isUndefined(regions) || ! isWithinRegions(d[i].x, regions)) { - s += " " + xValue(d[i]) + " " + yValue(d[i]); - } - // Draw with region // TODO: Fix for horizotal charts - else { - xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries()); - yp = $$.getScale(d[i - 1].value, d[i].value); - - dx = x(d[i].x) - x(d[i - 1].x); - dy = y(d[i].value) - y(d[i - 1].value); - dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); - diff = 2 / dd; - diffx2 = diff * 2; - - for (j = diff; j <= 1; j += diffx2) { - s += sWithRegion(d[i - 1], d[i], j, diff); - } - } - prev = d[i].x; + return path ? path : 'M 0 0' + } +}; +ChartInternal.prototype.generateGetLinePoints = function(lineIndices, isSub) { + // partial duplication of generateGetBarPoints + var $$ = this, + config = $$.config, + lineTargetsNum = lineIndices.__max__ + 1, + x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), + y = $$.getShapeY(!!isSub), + lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), + yScale = isSub ? $$.getSubYScale : $$.getYScale; + return function(d, i) { + var y0 = yScale.call($$, d.id)(0), + offset = lineOffset(d, i) || y0, // offset is for stacked area chart + posX = x(d), + posY = y(d); + // fix posY not to overflow opposite quadrant + if (config.axis_rotated) { + if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { + posY = y0; + } } - - return s; + // 1 point that marks the line position + return [ + [posX, posY - (y0 - offset)], + [posX, posY - (y0 - offset)], // needed for compatibility + [posX, posY - (y0 - offset)], // needed for compatibility + [posX, posY - (y0 - offset)] // needed for compatibility + ] + } }; +ChartInternal.prototype.lineWithRegions = function(d, x, y, _regions) { + var $$ = this, + config = $$.config, + prev = -1, + i, + j, + s = 'M', + sWithRegion, + xp, + yp, + dx, + dy, + dd, + diff, + diffx2, + xOffset = $$.isCategorized() ? 0.5 : 0, + xValue, + yValue, + regions = []; + + function isWithinRegions(x, regions) { + var i; + for (i = 0; i < regions.length; i++) { + if (regions[i].start < x && x <= regions[i].end) { + return true + } + } + return false + } -ChartInternal.prototype.updateArea = function (durationForExit) { - var $$ = this, d3 = $$.d3; - var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area) - .data($$.lineData.bind($$)); - var mainAreaEnter = mainArea.enter().append('path') - .attr("class", $$.classArea.bind($$)) - .style("fill", $$.color) - .style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); - $$.mainArea = mainAreaEnter.merge(mainArea) - .style("opacity", $$.orgAreaOpacity); - mainArea.exit().transition().duration(durationForExit) - .style('opacity', 0); -}; -ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) { - return [ - (withTransition ? this.mainArea.transition(transition) : this.mainArea) - .attr("d", drawArea) - .style("fill", this.color) - .style("opacity", this.orgAreaOpacity) - ]; -}; -ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) { - var $$ = this, config = $$.config, area = $$.d3.area(), - getPoints = $$.generateGetAreaPoints(areaIndices, isSub), - yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, - xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); }, - value0 = function (d, i) { - return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id)); - }, - value1 = function (d, i) { - return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value); - }; - - area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1); - if (!config.line_connectNull) { - area = area.defined(function (d) { return d.value !== null; }); + // Check start/end of regions + if (isDefined(_regions)) { + for (i = 0; i < _regions.length; i++) { + regions[i] = {}; + if (isUndefined(_regions[i].start)) { + regions[i].start = d[0].x; + } else { + regions[i].start = $$.isTimeSeries() + ? $$.parseDate(_regions[i].start) + : _regions[i].start; + } + if (isUndefined(_regions[i].end)) { + regions[i].end = d[d.length - 1].x; + } else { + regions[i].end = $$.isTimeSeries() + ? $$.parseDate(_regions[i].end) + : _regions[i].end; + } } + } - return function (d) { - var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values, - x0 = 0, y0 = 0, path; - if ($$.isAreaType(d)) { - if ($$.isStepType(d)) { values = $$.convertValuesToStep(values); } - path = area.curve($$.getInterpolate(d))(values); - } else { - if (values[0]) { - x0 = $$.x(values[0].x); - y0 = $$.getYScale(d.id)(values[0].value); - } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; - } - return path ? path : "M 0 0"; - }; -}; -ChartInternal.prototype.getAreaBaseValue = function () { - return 0; -}; -ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) { // partial duplication of generateGetBarPoints - var $$ = this, config = $$.config, - areaTargetsNum = areaIndices.__max__ + 1, - x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), - y = $$.getShapeY(!!isSub), - areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), - yScale = isSub ? $$.getSubYScale : $$.getYScale; - return function (d, i) { - var y0 = yScale.call($$, d.id)(0), - offset = areaOffset(d, i) || y0, // offset is for stacked area chart - posX = x(d), posY = y(d); - // fix posY not to overflow opposite quadrant - if (config.axis_rotated) { - if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; } - } - // 1 point that marks the area position - return [ - [posX, offset], - [posX, posY - (y0 - offset)], - [posX, posY - (y0 - offset)], // needed for compatibility - [posX, offset] // needed for compatibility + // Set scales + xValue = config.axis_rotated + ? function(d) { + return y(d.value) + } + : function(d) { + return x(d.x) + }; + yValue = config.axis_rotated + ? function(d) { + return x(d.x) + } + : function(d) { + return y(d.value) + }; + + // Define svg generator function for region + function generateM(points) { + return ( + 'M' + + points[0][0] + + ' ' + + points[0][1] + + ' ' + + points[1][0] + + ' ' + + points[1][1] + ) + } + if ($$.isTimeSeries()) { + sWithRegion = function(d0, d1, j, diff) { + var x0 = d0.x.getTime(), + x_diff = d1.x - d0.x, + xv0 = new Date(x0 + x_diff * j), + xv1 = new Date(x0 + x_diff * (j + diff)), + points; + if (config.axis_rotated) { + points = [ + [y(yp(j)), x(xv0)], + [y(yp(j + diff)), x(xv1)] + ]; + } else { + points = [ + [x(xv0), y(yp(j))], + [x(xv1), y(yp(j + diff))] ]; + } + return generateM(points) }; -}; - - -ChartInternal.prototype.updateCircle = function (cx, cy) { - var $$ = this; - var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle) - .data($$.lineOrScatterOrStanfordData.bind($$)); + } else { + sWithRegion = function(d0, d1, j, diff) { + var points; + if (config.axis_rotated) { + points = [ + [y(yp(j), true), x(xp(j))], + [y(yp(j + diff), true), x(xp(j + diff))] + ]; + } else { + points = [ + [x(xp(j), true), y(yp(j))], + [x(xp(j + diff), true), y(yp(j + diff))] + ]; + } + return generateM(points) + }; + } - var mainCircleEnter = mainCircle.enter().append("circle") - .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '') - .attr("class", $$.classCircle.bind($$)) - .attr("cx", cx) - .attr("cy", cy) - .attr("r", $$.pointR.bind($$)) - .style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color); + // Generate + for (i = 0; i < d.length; i++) { + // Draw as normal + if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) { + s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]); + } + // Draw with region // TODO: Fix for horizotal charts + else { + xp = $$.getScale( + d[i - 1].x + xOffset, + d[i].x + xOffset, + $$.isTimeSeries() + ); + yp = $$.getScale(d[i - 1].value, d[i].value); + + dx = x(d[i].x) - x(d[i - 1].x); + dy = y(d[i].value) - y(d[i - 1].value); + dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + diff = 2 / dd; + diffx2 = diff * 2; + + for (j = diff; j <= 1; j += diffx2) { + s += sWithRegion(d[i - 1], d[i], j, diff); + } + } + prev = d[i].x; + } - $$.mainCircle = mainCircleEnter.merge(mainCircle) - .style("opacity", $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)); + return s +}; + +ChartInternal.prototype.updateArea = function(durationForExit) { + var $$ = this, + d3 = $$.d3; + var mainArea = $$.main + .selectAll('.' + CLASS.areas) + .selectAll('.' + CLASS.area) + .data($$.lineData.bind($$)); + var mainAreaEnter = mainArea + .enter() + .append('path') + .attr('class', $$.classArea.bind($$)) + .style('fill', $$.color) + .style('opacity', function() { + $$.orgAreaOpacity = +d3.select(this).style('opacity'); + return 0 + }); + $$.mainArea = mainAreaEnter + .merge(mainArea) + .style('opacity', $$.orgAreaOpacity); + mainArea + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0); +}; +ChartInternal.prototype.redrawArea = function( + drawArea, + withTransition, + transition +) { + return [ + (withTransition ? this.mainArea.transition(transition) : this.mainArea) + .attr('d', drawArea) + .style('fill', this.color) + .style('opacity', this.orgAreaOpacity) + ] +}; +ChartInternal.prototype.generateDrawArea = function(areaIndices, isSub) { + var $$ = this, + config = $$.config, + area = $$.d3.area(), + getPoints = $$.generateGetAreaPoints(areaIndices, isSub), + yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, + xValue = function(d) { + return (isSub ? $$.subxx : $$.xx).call($$, d) + }, + value0 = function(d, i) { + return config.data_groups.length > 0 + ? getPoints(d, i)[0][1] + : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id)) + }, + value1 = function(d, i) { + return config.data_groups.length > 0 + ? getPoints(d, i)[1][1] + : yScaleGetter.call($$, d.id)(d.value) + }; - mainCircle.exit() - .style("opacity", 0); -}; -ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) { - var $$ = this, - selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); - return [ - (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle) - .style('opacity', this.opacityForCircle.bind($$)) - .style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color) - .attr("cx", cx) - .attr("cy", cy), - (withTransition ? selectedCircles.transition(transition) : selectedCircles) - .attr("cx", cx) - .attr("cy", cy) - ]; -}; -ChartInternal.prototype.circleX = function (d) { - return d.x || d.x === 0 ? this.x(d.x) : null; -}; -ChartInternal.prototype.updateCircleY = function () { - var $$ = this, lineIndices, getPoints; - if ($$.config.data_groups.length > 0) { - lineIndices = $$.getShapeIndices($$.isLineType), - getPoints = $$.generateGetLinePoints(lineIndices); - $$.circleY = function (d, i) { - return getPoints(d, i)[0][1]; - }; - } else { - $$.circleY = function (d) { - return $$.getYScale(d.id)(d.value); - }; - } -}; -ChartInternal.prototype.getCircles = function (i, id) { - var $$ = this; - return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')); -}; -ChartInternal.prototype.expandCircles = function (i, id, reset) { - var $$ = this, - r = $$.pointExpandedR.bind($$); - if (reset) { $$.unexpandCircles(); } - $$.getCircles(i, id) - .classed(CLASS.EXPANDED, true) - .attr('r', r); -}; -ChartInternal.prototype.unexpandCircles = function (i) { - var $$ = this, - r = $$.pointR.bind($$); - $$.getCircles(i) - .filter(function () { return $$.d3.select(this).classed(CLASS.EXPANDED); }) - .classed(CLASS.EXPANDED, false) - .attr('r', r); -}; -ChartInternal.prototype.pointR = function (d) { - var $$ = this, config = $$.config; - return $$.isStepType(d) ? 0 : (isFunction(config.point_r) ? config.point_r(d) : config.point_r); -}; -ChartInternal.prototype.pointExpandedR = function (d) { - var $$ = this, config = $$.config; - if (config.point_focus_expand_enabled) { - return isFunction(config.point_focus_expand_r) ? config.point_focus_expand_r(d) : ((config.point_focus_expand_r) ? config.point_focus_expand_r : $$.pointR(d) * 1.75); - } else { - return $$.pointR(d); - } -}; -ChartInternal.prototype.pointSelectR = function (d) { - var $$ = this, config = $$.config; - return isFunction(config.point_select_r) ? config.point_select_r(d) : ((config.point_select_r) ? config.point_select_r : $$.pointR(d) * 4); -}; -ChartInternal.prototype.isWithinCircle = function (that, r) { - var d3 = this.d3, - mouse = d3.mouse(that), d3_this = d3.select(that), - cx = +d3_this.attr("cx"), cy = +d3_this.attr("cy"); - return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r; -}; -ChartInternal.prototype.isWithinStep = function (that, y) { - return Math.abs(y - this.d3.mouse(that)[1]) < 30; -}; + area = config.axis_rotated + ? area + .x0(value0) + .x1(value1) + .y(xValue) + : area + .x(xValue) + .y0(config.area_above ? 0 : value0) + .y1(value1); + if (!config.line_connectNull) { + area = area.defined(function(d) { + return d.value !== null + }); + } -ChartInternal.prototype.getCurrentWidth = function () { - var $$ = this, config = $$.config; - return config.size_width ? config.size_width : $$.getParentWidth(); -}; -ChartInternal.prototype.getCurrentHeight = function () { - var $$ = this, config = $$.config, - h = config.size_height ? config.size_height : $$.getParentHeight(); - return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1); -}; -ChartInternal.prototype.getCurrentPaddingTop = function () { - var $$ = this, - config = $$.config, - padding = isValue(config.padding_top) ? config.padding_top : 0; - if ($$.title && $$.title.node()) { - padding += $$.getTitlePadding(); - } - return padding; -}; -ChartInternal.prototype.getCurrentPaddingBottom = function () { - var config = this.config; - return isValue(config.padding_bottom) ? config.padding_bottom : 0; -}; -ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) { - var $$ = this, config = $$.config; - if (isValue(config.padding_left)) { - return config.padding_left; - } else if (config.axis_rotated) { - return (!config.axis_x_show || config.axis_x_inner) ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40); - } else if (!config.axis_y_show || config.axis_y_inner) { // && !config.axis_rotated - return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1; + return function(d) { + var values = config.line_connectNull + ? $$.filterRemoveNull(d.values) + : d.values, + x0 = 0, + y0 = 0, + path; + if ($$.isAreaType(d)) { + if ($$.isStepType(d)) { + values = $$.convertValuesToStep(values); + } + path = area.curve($$.getInterpolate(d))(values); } else { - return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute)); + if (values[0]) { + x0 = $$.x(values[0].x); + y0 = $$.getYScale(d.id)(values[0].value); + } + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } + return path ? path : 'M 0 0' + } }; -ChartInternal.prototype.getCurrentPaddingRight = function () { - var $$ = this, config = $$.config, padding = 0, - defaultPadding = 10, legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0; - - if (isValue(config.padding_right)) { - padding = config.padding_right + 1; // 1 is needed not to hide tick line - } else if (config.axis_rotated) { - padding = defaultPadding + legendWidthOnRight; - } else if (!config.axis_y2_show || config.axis_y2_inner) { // && !config.axis_rotated - padding = 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0); - } else { - padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight; - } - - if ($$.colorScale && $$.colorScale.node()) { - padding += $$.getColorScalePadding(); +ChartInternal.prototype.getAreaBaseValue = function() { + return 0 +}; +ChartInternal.prototype.generateGetAreaPoints = function(areaIndices, isSub) { + // partial duplication of generateGetBarPoints + var $$ = this, + config = $$.config, + areaTargetsNum = areaIndices.__max__ + 1, + x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), + y = $$.getShapeY(!!isSub), + areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), + yScale = isSub ? $$.getSubYScale : $$.getYScale; + return function(d, i) { + var y0 = yScale.call($$, d.id)(0), + offset = areaOffset(d, i) || y0, // offset is for stacked area chart + posX = x(d), + posY = y(d); + // fix posY not to overflow opposite quadrant + if (config.axis_rotated) { + if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { + posY = y0; + } } - - return padding; + // 1 point that marks the area position + return [ + [posX, offset], + [posX, posY - (y0 - offset)], + [posX, posY - (y0 - offset)], // needed for compatibility + [posX, offset] // needed for compatibility + ] + } }; -ChartInternal.prototype.getParentRectValue = function (key) { - var parent = this.selectChart.node(), v; - while (parent && parent.tagName !== 'BODY') { - try { - v = parent.getBoundingClientRect()[key]; - } catch(e) { - if (key === 'width') { - // In IE in certain cases getBoundingClientRect - // will cause an "unspecified error" - v = parent.offsetWidth; - } - } - if (v) { - break; - } - parent = parent.parentNode; - } - return v; +ChartInternal.prototype.updateCircle = function(cx, cy) { + var $$ = this; + var mainCircle = $$.main + .selectAll('.' + CLASS.circles) + .selectAll('.' + CLASS.circle) + .data($$.lineOrScatterOrStanfordData.bind($$)); + + var mainCircleEnter = mainCircle + .enter() + .append('circle') + .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '') + .attr('class', $$.classCircle.bind($$)) + .attr('cx', cx) + .attr('cy', cy) + .attr('r', $$.pointR.bind($$)) + .style( + 'color', + $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color + ); + + $$.mainCircle = mainCircleEnter + .merge(mainCircle) + .style( + 'opacity', + $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$) + ); + + mainCircle.exit().style('opacity', 0); +}; +ChartInternal.prototype.redrawCircle = function( + cx, + cy, + withTransition, + transition +) { + var $$ = this, + selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); + return [ + (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle) + .style('opacity', this.opacityForCircle.bind($$)) + .style( + 'color', + $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color + ) + .attr('cx', cx) + .attr('cy', cy), + (withTransition ? selectedCircles.transition(transition) : selectedCircles) + .attr('cx', cx) + .attr('cy', cy) + ] +}; +ChartInternal.prototype.circleX = function(d) { + return d.x || d.x === 0 ? this.x(d.x) : null +}; +ChartInternal.prototype.updateCircleY = function() { + var $$ = this, + lineIndices, + getPoints; + if ($$.config.data_groups.length > 0) { +(lineIndices = $$.getShapeIndices($$.isLineType)), + (getPoints = $$.generateGetLinePoints(lineIndices)); + $$.circleY = function(d, i) { + return getPoints(d, i)[0][1] + }; + } else { + $$.circleY = function(d) { + return $$.getYScale(d.id)(d.value) + }; + } }; -ChartInternal.prototype.getParentWidth = function () { - return this.getParentRectValue('width'); +ChartInternal.prototype.getCircles = function(i, id) { + var $$ = this; + return (id + ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) + : $$.main + ).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')) +}; +ChartInternal.prototype.expandCircles = function(i, id, reset) { + var $$ = this, + r = $$.pointExpandedR.bind($$); + if (reset) { + $$.unexpandCircles(); + } + $$.getCircles(i, id) + .classed(CLASS.EXPANDED, true) + .attr('r', r); +}; +ChartInternal.prototype.unexpandCircles = function(i) { + var $$ = this, + r = $$.pointR.bind($$); + $$.getCircles(i) + .filter(function() { + return $$.d3.select(this).classed(CLASS.EXPANDED) + }) + .classed(CLASS.EXPANDED, false) + .attr('r', r); +}; +ChartInternal.prototype.pointR = function(d) { + var $$ = this, + config = $$.config; + return $$.isStepType(d) + ? 0 + : isFunction(config.point_r) + ? config.point_r(d) + : config.point_r +}; +ChartInternal.prototype.pointExpandedR = function(d) { + var $$ = this, + config = $$.config; + if (config.point_focus_expand_enabled) { + return isFunction(config.point_focus_expand_r) + ? config.point_focus_expand_r(d) + : config.point_focus_expand_r + ? config.point_focus_expand_r + : $$.pointR(d) * 1.75 + } else { + return $$.pointR(d) + } }; -ChartInternal.prototype.getParentHeight = function () { - var h = this.selectChart.style('height'); - return h.indexOf('px') > 0 ? +h.replace('px', '') : 0; +ChartInternal.prototype.pointSelectR = function(d) { + var $$ = this, + config = $$.config; + return isFunction(config.point_select_r) + ? config.point_select_r(d) + : config.point_select_r + ? config.point_select_r + : $$.pointR(d) * 4 +}; +ChartInternal.prototype.isWithinCircle = function(that, r) { + var d3 = this.d3, + mouse = d3.mouse(that), + d3_this = d3.select(that), + cx = +d3_this.attr('cx'), + cy = +d3_this.attr('cy'); + return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r +}; +ChartInternal.prototype.isWithinStep = function(that, y) { + return Math.abs(y - this.d3.mouse(that)[1]) < 30 +}; + +ChartInternal.prototype.getCurrentWidth = function() { + var $$ = this, + config = $$.config; + return config.size_width ? config.size_width : $$.getParentWidth() +}; +ChartInternal.prototype.getCurrentHeight = function() { + var $$ = this, + config = $$.config, + h = config.size_height ? config.size_height : $$.getParentHeight(); + return h > 0 + ? h + : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1) +}; +ChartInternal.prototype.getCurrentPaddingTop = function() { + var $$ = this, + config = $$.config, + padding = isValue(config.padding_top) ? config.padding_top : 0; + if ($$.title && $$.title.node()) { + padding += $$.getTitlePadding(); + } + return padding +}; +ChartInternal.prototype.getCurrentPaddingBottom = function() { + var config = this.config; + return isValue(config.padding_bottom) ? config.padding_bottom : 0 +}; +ChartInternal.prototype.getCurrentPaddingLeft = function(withoutRecompute) { + var $$ = this, + config = $$.config; + if (isValue(config.padding_left)) { + return config.padding_left + } else if (config.axis_rotated) { + return !config.axis_x_show || config.axis_x_inner + ? 1 + : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40) + } else if (!config.axis_y_show || config.axis_y_inner) { + // && !config.axis_rotated + return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1 + } else { + return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute)) + } }; +ChartInternal.prototype.getCurrentPaddingRight = function() { + var $$ = this, + config = $$.config, + padding = 0, + defaultPadding = 10, + legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0; + + if (isValue(config.padding_right)) { + padding = config.padding_right + 1; // 1 is needed not to hide tick line + } else if (config.axis_rotated) { + padding = defaultPadding + legendWidthOnRight; + } else if (!config.axis_y2_show || config.axis_y2_inner) { + // && !config.axis_rotated + padding = + 2 + + legendWidthOnRight + + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0); + } else { + padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight; + } + if ($$.colorScale && $$.colorScale.node()) { + padding += $$.getColorScalePadding(); + } -ChartInternal.prototype.getSvgLeft = function (withoutRecompute) { - var $$ = this, config = $$.config, - hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), - leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, - leftAxis = $$.main.select('.' + leftAxisClass).node(), - svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {right: 0}, - chartRect = $$.selectChart.node().getBoundingClientRect(), - hasArc = $$.hasArcType(), - svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute)); - return svgLeft > 0 ? svgLeft : 0; + return padding }; - -ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) { - var $$ = this, position = $$.axis.getLabelPositionById(id); - return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40); -}; -ChartInternal.prototype.getHorizontalAxisHeight = function (axisId) { - var $$ = this, config = $$.config, h = 30; - if (axisId === 'x' && !config.axis_x_show) { return 8; } - if (axisId === 'x' && config.axis_x_height) { return config.axis_x_height; } - if (axisId === 'y' && !config.axis_y_show) { - return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1; +ChartInternal.prototype.getParentRectValue = function(key) { + var parent = this.selectChart.node(), + v; + while (parent && parent.tagName !== 'BODY') { + try { + v = parent.getBoundingClientRect()[key]; + } catch (e) { + if (key === 'width') { + // In IE in certain cases getBoundingClientRect + // will cause an "unspecified error" + v = parent.offsetWidth; + } } - if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; } - // Calculate x axis height when tick rotated - if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { - h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_x_tick_rotate)) / 180); - } - // Calculate y axis height when tick rotated - if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) { - h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_y_tick_rotate)) / 180); - } - return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0); -}; - -ChartInternal.prototype.initBrush = function (scale) { - var $$ = this, d3 = $$.d3; - // TODO: dynamically change brushY/brushX according to axis_rotated. - $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () { - var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { return; } - $$.redrawForBrush(); - }).on("end", function () { - var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { return; } - if ($$.brush.empty() && event && event.type !== 'end') { $$.brush.clear(); } - }); - $$.brush.updateExtent = function () { - var range = this.scale.range(), extent; - if ($$.config.axis_rotated) { - extent = [[0, range[0]], [$$.width2, range[1]]]; - } - else { - extent = [[range[0], 0], [range[1], $$.height2]]; - } - this.extent(extent); - return this; - }; - $$.brush.updateScale = function (scale) { - this.scale = scale; - return this; - }; - $$.brush.update = function (scale) { - this.updateScale(scale || $$.subX).updateExtent(); - $$.context.select('.' + CLASS.brush).call(this); - }; - $$.brush.clear = function () { - $$.context.select('.' + CLASS.brush).call($$.brush.move, null); - }; - $$.brush.selection = function () { - return d3.brushSelection($$.context.select('.' + CLASS.brush).node()); - }; - $$.brush.selectionAsValue = function (selectionAsValue, withTransition) { - var selection, brush; - if (selectionAsValue) { - if ($$.context) { - selection = [this.scale(selectionAsValue[0]), this.scale(selectionAsValue[1])]; - brush = $$.context.select('.' + CLASS.brush); - if (withTransition) { brush = brush.transition(); } - $$.brush.move(brush, selection); - } - return []; - } - selection = $$.brush.selection() || [0,0]; - return [this.scale.invert(selection[0]), this.scale.invert(selection[1])]; - }; - $$.brush.empty = function () { - var selection = $$.brush.selection(); - return !selection || selection[0] === selection[1]; - }; - return $$.brush.updateScale(scale); -}; -ChartInternal.prototype.initSubchart = function () { - var $$ = this, config = $$.config, - context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')); - - // set style - context.style('visibility', 'visible'); - - // Define g for chart area - context.append('g') - .attr("clip-path", $$.clipPathForSubchart) - .attr('class', CLASS.chart); - - // Define g for bar chart area - context.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartBars); - - // Define g for line chart area - context.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartLines); - - // Add extent rect for Brush - context.append("g") - .attr("clip-path", $$.clipPath) - .attr("class", CLASS.brush); - - // ATTENTION: This must be called AFTER chart added - // Add Axis - $$.axes.subx = context.append("g") - .attr("class", CLASS.axisX) - .attr("transform", $$.getTranslate('subx')) - .attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis); -}; -ChartInternal.prototype.initSubchartBrush = function () { - var $$ = this; - // Add extent rect for Brush - $$.initBrush($$.subX).updateExtent(); - $$.context.select('.' + CLASS.brush).call($$.brush); -}; -ChartInternal.prototype.updateTargetsForSubchart = function (targets) { - var $$ = this, context = $$.context, config = $$.config, - contextLineEnter, contextLine, contextBarEnter, contextBar, - classChartBar = $$.classChartBar.bind($$), - classBars = $$.classBars.bind($$), - classChartLine = $$.classChartLine.bind($$), - classLines = $$.classLines.bind($$), - classAreas = $$.classAreas.bind($$); - - //-- Bar --// - contextBar = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar) - .data(targets); - contextBarEnter = contextBar.enter().append('g') - .style('opacity', 0); - contextBarEnter.merge(contextBar) - .attr('class', classChartBar); - // Bars for each data - contextBarEnter.append('g') - .attr("class", classBars); - - //-- Line --// - contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine) - .data(targets); - contextLineEnter = contextLine.enter().append('g') - .style('opacity', 0); - contextLineEnter.merge(contextLine) - .attr('class', classChartLine); - // Lines for each data - contextLineEnter.append("g") - .attr("class", classLines); - // Area - contextLineEnter.append("g") - .attr("class", classAreas); - - //-- Brush --// - context.selectAll('.' + CLASS.brush + ' rect') - .attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2); -}; -ChartInternal.prototype.updateBarForSubchart = function (durationForExit) { - var $$ = this; - var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar) - .data($$.barData.bind($$)); - var contextBarEnter = contextBar.enter().append('path') - .attr("class", $$.classBar.bind($$)) - .style("stroke", 'none') - .style("fill", $$.color); - contextBar.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - $$.contextBar = contextBarEnter.merge(contextBar) - .style("opacity", $$.initialOpacity.bind($$)); -}; -ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) { - (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar) - .attr('d', drawBarOnSub) - .style('opacity', 1); -}; -ChartInternal.prototype.updateLineForSubchart = function (durationForExit) { - var $$ = this; - var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line) - .data($$.lineData.bind($$)); - var contextLineEnter = contextLine.enter().append('path') - .attr('class', $$.classLine.bind($$)) - .style('stroke', $$.color); - contextLine.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - $$.contextLine = contextLineEnter.merge(contextLine) - .style("opacity", $$.initialOpacity.bind($$)); -}; -ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) { - (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine) - .attr("d", drawLineOnSub) - .style('opacity', 1); -}; -ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) { - var $$ = this, d3 = $$.d3; - var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area) - .data($$.lineData.bind($$)); - var contextAreaEnter = contextArea.enter().append('path') - .attr("class", $$.classArea.bind($$)) - .style("fill", $$.color) - .style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); - contextArea.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - $$.contextArea = contextAreaEnter.merge(contextArea) - .style("opacity", 0); -}; -ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) { - (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea) - .attr("d", drawAreaOnSub) - .style("fill", this.color) - .style("opacity", this.orgAreaOpacity); -}; -ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) { - var $$ = this, d3 = $$.d3, - drawAreaOnSub, drawBarOnSub, drawLineOnSub; - - // reflect main chart to extent on subchart if zoomed - if (d3.event && d3.event.type === 'zoom') { - $$.brush.selectionAsValue($$.x.orgDomain()); - } - // update subchart elements if needed - if (withSubchart) { - // extent rect - if (!$$.brush.empty()) { - $$.brush.selectionAsValue($$.x.orgDomain()); - } - // setup drawer - MEMO: this must be called after axis updated - drawAreaOnSub = $$.generateDrawArea(areaIndices, true); - drawBarOnSub = $$.generateDrawBar(barIndices, true); - drawLineOnSub = $$.generateDrawLine(lineIndices, true); - - $$.updateBarForSubchart(duration); - $$.updateLineForSubchart(duration); - $$.updateAreaForSubchart(duration); - - $$.redrawBarForSubchart(drawBarOnSub, duration, duration); - $$.redrawLineForSubchart(drawLineOnSub, duration, duration); - $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration); + if (v) { + break } -}; -ChartInternal.prototype.redrawForBrush = function () { - var $$ = this, x = $$.x, d3 = $$.d3, s; - $$.redraw({ - withTransition: false, - withY: $$.config.zoom_rescale, - withSubchart: false, - withUpdateXDomain: true, - withEventRect: false, - withDimension: false + parent = parent.parentNode; + } + return v +}; +ChartInternal.prototype.getParentWidth = function() { + return this.getParentRectValue('width') +}; +ChartInternal.prototype.getParentHeight = function() { + var h = this.selectChart.style('height'); + return h.indexOf('px') > 0 ? +h.replace('px', '') : 0 +}; + +ChartInternal.prototype.getSvgLeft = function(withoutRecompute) { + var $$ = this, + config = $$.config, + hasLeftAxisRect = + config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), + leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, + leftAxis = $$.main.select('.' + leftAxisClass).node(), + svgRect = + leftAxis && hasLeftAxisRect + ? leftAxis.getBoundingClientRect() + : { right: 0 }, + chartRect = $$.selectChart.node().getBoundingClientRect(), + hasArc = $$.hasArcType(), + svgLeft = + svgRect.right - + chartRect.left - + (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute)); + return svgLeft > 0 ? svgLeft : 0 +}; + +ChartInternal.prototype.getAxisWidthByAxisId = function(id, withoutRecompute) { + var $$ = this, + position = $$.axis.getLabelPositionById(id); + return ( + $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40) + ) +}; +ChartInternal.prototype.getHorizontalAxisHeight = function(axisId) { + var $$ = this, + config = $$.config, + h = 30; + if (axisId === 'x' && !config.axis_x_show) { + return 8 + } + if (axisId === 'x' && config.axis_x_height) { + return config.axis_x_height + } + if (axisId === 'y' && !config.axis_y_show) { + return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1 + } + if (axisId === 'y2' && !config.axis_y2_show) { + return $$.rotated_padding_top + } + // Calculate x axis height when tick rotated + if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { + h = + 30 + + $$.axis.getMaxTickWidth(axisId) * + Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180); + } + // Calculate y axis height when tick rotated + if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) { + h = + 30 + + $$.axis.getMaxTickWidth(axisId) * + Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180); + } + return ( + h + + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + + (axisId === 'y2' ? -10 : 0) + ) +}; + +ChartInternal.prototype.initBrush = function(scale) { + var $$ = this, + d3 = $$.d3; + // TODO: dynamically change brushY/brushX according to axis_rotated. + $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()) + .on('brush', function() { + var event = d3.event.sourceEvent; + if (event && event.type === 'zoom') { + return + } + $$.redrawForBrush(); + }) + .on('end', function() { + var event = d3.event.sourceEvent; + if (event && event.type === 'zoom') { + return + } + if ($$.brush.empty() && event && event.type !== 'end') { + $$.brush.clear(); + } }); - // update zoom transation binded to event rect - s = d3.event.selection || $$.brush.scale.range(); - $$.main.select('.' + CLASS.eventRect).call($$.zoom.transform, d3.zoomIdentity - .scale($$.width / (s[1] - s[0])) - .translate(-s[0], 0)); - $$.config.subchart_onbrush.call($$.api, x.orgDomain()); -}; -ChartInternal.prototype.transformContext = function (withTransition, transitions) { - var $$ = this, subXAxis; - if (transitions && transitions.axisSubX) { - subXAxis = transitions.axisSubX; + $$.brush.updateExtent = function() { + var range = this.scale.range(), + extent; + if ($$.config.axis_rotated) { + extent = [ + [0, range[0]], + [$$.width2, range[1]] + ]; } else { - subXAxis = $$.context.select('.' + CLASS.axisX); - if (withTransition) { subXAxis = subXAxis.transition(); } - } - $$.context.attr("transform", $$.getTranslate('context')); - subXAxis.attr("transform", $$.getTranslate('subx')); + extent = [ + [range[0], 0], + [range[1], $$.height2] + ]; + } + this.extent(extent); + return this + }; + $$.brush.updateScale = function(scale) { + this.scale = scale; + return this + }; + $$.brush.update = function(scale) { + this.updateScale(scale || $$.subX).updateExtent(); + $$.context.select('.' + CLASS.brush).call(this); + }; + $$.brush.clear = function() { + $$.context.select('.' + CLASS.brush).call($$.brush.move, null); + }; + $$.brush.selection = function() { + return d3.brushSelection($$.context.select('.' + CLASS.brush).node()) + }; + $$.brush.selectionAsValue = function(selectionAsValue, withTransition) { + var selection, brush; + if (selectionAsValue) { + if ($$.context) { + selection = [ + this.scale(selectionAsValue[0]), + this.scale(selectionAsValue[1]) + ]; + brush = $$.context.select('.' + CLASS.brush); + if (withTransition) { + brush = brush.transition(); + } + $$.brush.move(brush, selection); + } + return [] + } + selection = $$.brush.selection() || [0, 0]; + return [this.scale.invert(selection[0]), this.scale.invert(selection[1])] + }; + $$.brush.empty = function() { + var selection = $$.brush.selection(); + return !selection || selection[0] === selection[1] + }; + return $$.brush.updateScale(scale) +}; +ChartInternal.prototype.initSubchart = function() { + var $$ = this, + config = $$.config, + context = ($$.context = $$.svg + .append('g') + .attr('transform', $$.getTranslate('context'))); + + // set style + context.style('visibility', 'visible'); + + // Define g for chart area + context + .append('g') + .attr('clip-path', $$.clipPathForSubchart) + .attr('class', CLASS.chart); + + // Define g for bar chart area + context + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartBars); + + // Define g for line chart area + context + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartLines); + + // Add extent rect for Brush + context + .append('g') + .attr('clip-path', $$.clipPath) + .attr('class', CLASS.brush); + + // ATTENTION: This must be called AFTER chart added + // Add Axis + $$.axes.subx = context + .append('g') + .attr('class', CLASS.axisX) + .attr('transform', $$.getTranslate('subx')) + .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis); +}; +ChartInternal.prototype.initSubchartBrush = function() { + var $$ = this; + // Add extent rect for Brush + $$.initBrush($$.subX).updateExtent(); + $$.context.select('.' + CLASS.brush).call($$.brush); +}; +ChartInternal.prototype.updateTargetsForSubchart = function(targets) { + var $$ = this, + context = $$.context, + config = $$.config, + contextLineEnter, + contextLine, + contextBarEnter, + contextBar, + classChartBar = $$.classChartBar.bind($$), + classBars = $$.classBars.bind($$), + classChartLine = $$.classChartLine.bind($$), + classLines = $$.classLines.bind($$), + classAreas = $$.classAreas.bind($$); + + //-- Bar --// + contextBar = context + .select('.' + CLASS.chartBars) + .selectAll('.' + CLASS.chartBar) + .data(targets); + contextBarEnter = contextBar + .enter() + .append('g') + .style('opacity', 0); + contextBarEnter.merge(contextBar).attr('class', classChartBar); + // Bars for each data + contextBarEnter.append('g').attr('class', classBars); + + //-- Line --// + contextLine = context + .select('.' + CLASS.chartLines) + .selectAll('.' + CLASS.chartLine) + .data(targets); + contextLineEnter = contextLine + .enter() + .append('g') + .style('opacity', 0); + contextLineEnter.merge(contextLine).attr('class', classChartLine); + // Lines for each data + contextLineEnter.append('g').attr('class', classLines); + // Area + contextLineEnter.append('g').attr('class', classAreas); + + //-- Brush --// + context + .selectAll('.' + CLASS.brush + ' rect') + .attr( + config.axis_rotated ? 'width' : 'height', + config.axis_rotated ? $$.width2 : $$.height2 + ); +}; +ChartInternal.prototype.updateBarForSubchart = function(durationForExit) { + var $$ = this; + var contextBar = $$.context + .selectAll('.' + CLASS.bars) + .selectAll('.' + CLASS.bar) + .data($$.barData.bind($$)); + var contextBarEnter = contextBar + .enter() + .append('path') + .attr('class', $$.classBar.bind($$)) + .style('stroke', 'none') + .style('fill', $$.color); + contextBar + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + $$.contextBar = contextBarEnter + .merge(contextBar) + .style('opacity', $$.initialOpacity.bind($$)); +}; +ChartInternal.prototype.redrawBarForSubchart = function( + drawBarOnSub, + withTransition, + duration +) { +(withTransition + ? this.contextBar.transition(Math.random().toString()).duration(duration) + : this.contextBar + ) + .attr('d', drawBarOnSub) + .style('opacity', 1); +}; +ChartInternal.prototype.updateLineForSubchart = function(durationForExit) { + var $$ = this; + var contextLine = $$.context + .selectAll('.' + CLASS.lines) + .selectAll('.' + CLASS.line) + .data($$.lineData.bind($$)); + var contextLineEnter = contextLine + .enter() + .append('path') + .attr('class', $$.classLine.bind($$)) + .style('stroke', $$.color); + contextLine + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + $$.contextLine = contextLineEnter + .merge(contextLine) + .style('opacity', $$.initialOpacity.bind($$)); +}; +ChartInternal.prototype.redrawLineForSubchart = function( + drawLineOnSub, + withTransition, + duration +) { +(withTransition + ? this.contextLine.transition(Math.random().toString()).duration(duration) + : this.contextLine + ) + .attr('d', drawLineOnSub) + .style('opacity', 1); +}; +ChartInternal.prototype.updateAreaForSubchart = function(durationForExit) { + var $$ = this, + d3 = $$.d3; + var contextArea = $$.context + .selectAll('.' + CLASS.areas) + .selectAll('.' + CLASS.area) + .data($$.lineData.bind($$)); + var contextAreaEnter = contextArea + .enter() + .append('path') + .attr('class', $$.classArea.bind($$)) + .style('fill', $$.color) + .style('opacity', function() { + $$.orgAreaOpacity = +d3.select(this).style('opacity'); + return 0 + }); + contextArea + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0); +}; +ChartInternal.prototype.redrawAreaForSubchart = function( + drawAreaOnSub, + withTransition, + duration +) { +(withTransition + ? this.contextArea.transition(Math.random().toString()).duration(duration) + : this.contextArea + ) + .attr('d', drawAreaOnSub) + .style('fill', this.color) + .style('opacity', this.orgAreaOpacity); +}; +ChartInternal.prototype.redrawSubchart = function( + withSubchart, + transitions, + duration, + durationForExit, + areaIndices, + barIndices, + lineIndices +) { + var $$ = this, + d3 = $$.d3, + drawAreaOnSub, + drawBarOnSub, + drawLineOnSub; + + // reflect main chart to extent on subchart if zoomed + if (d3.event && d3.event.type === 'zoom') { + $$.brush.selectionAsValue($$.x.orgDomain()); + } + // update subchart elements if needed + if (withSubchart) { + // extent rect + if (!$$.brush.empty()) { + $$.brush.selectionAsValue($$.x.orgDomain()); + } + // setup drawer - MEMO: this must be called after axis updated + drawAreaOnSub = $$.generateDrawArea(areaIndices, true); + drawBarOnSub = $$.generateDrawBar(barIndices, true); + drawLineOnSub = $$.generateDrawLine(lineIndices, true); + + $$.updateBarForSubchart(duration); + $$.updateLineForSubchart(duration); + $$.updateAreaForSubchart(duration); + + $$.redrawBarForSubchart(drawBarOnSub, duration, duration); + $$.redrawLineForSubchart(drawLineOnSub, duration, duration); + $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration); + } }; -ChartInternal.prototype.getDefaultSelection = function () { - var $$ = this, config = $$.config, - selection = isFunction(config.axis_x_selection) ? config.axis_x_selection($$.getXDomain($$.data.targets)) : config.axis_x_selection; - if ($$.isTimeSeries()) { - selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])]; +ChartInternal.prototype.redrawForBrush = function() { + var $$ = this, + x = $$.x, + d3 = $$.d3, + s; + $$.redraw({ + withTransition: false, + withY: $$.config.zoom_rescale, + withSubchart: false, + withUpdateXDomain: true, + withEventRect: false, + withDimension: false + }); + // update zoom transation binded to event rect + s = d3.event.selection || $$.brush.scale.range(); + $$.main + .select('.' + CLASS.eventRect) + .call( + $$.zoom.transform, + d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0) + ); + $$.config.subchart_onbrush.call($$.api, x.orgDomain()); +}; +ChartInternal.prototype.transformContext = function( + withTransition, + transitions +) { + var $$ = this, + subXAxis; + if (transitions && transitions.axisSubX) { + subXAxis = transitions.axisSubX; + } else { + subXAxis = $$.context.select('.' + CLASS.axisX); + if (withTransition) { + subXAxis = subXAxis.transition(); } - return selection; + } + $$.context.attr('transform', $$.getTranslate('context')); + subXAxis.attr('transform', $$.getTranslate('subx')); +}; +ChartInternal.prototype.getDefaultSelection = function() { + var $$ = this, + config = $$.config, + selection = isFunction(config.axis_x_selection) + ? config.axis_x_selection($$.getXDomain($$.data.targets)) + : config.axis_x_selection; + if ($$.isTimeSeries()) { + selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])]; + } + return selection }; ChartInternal.prototype.removeSubchart = function() { - const $$ = this; - - $$.brush = null; - $$.context.remove(); - $$.context = null; -}; - -ChartInternal.prototype.initText = function () { - var $$ = this; - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartTexts); - $$.mainText = $$.d3.selectAll([]); -}; -ChartInternal.prototype.updateTargetsForText = function (targets) { - var $$ = this, - classChartText = $$.classChartText.bind($$), - classTexts = $$.classTexts.bind($$), - classFocus = $$.classFocus.bind($$); - var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText) - .data(targets); - var mainTextEnter = mainText.enter().append('g') - .attr('class', classChartText) - .style('opacity', 0) - .style("pointer-events", "none"); - mainTextEnter.append('g') - .attr('class', classTexts); - mainTextEnter.merge(mainText) - .attr('class', function (d) { return classChartText(d) + classFocus(d); }); -}; -ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) { - var $$ = this, config = $$.config, - barOrLineData = $$.barOrLineData.bind($$), - classText = $$.classText.bind($$); - var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text) - .data(barOrLineData); - var mainTextEnter = mainText.enter().append('text') - .attr("class", classText) - .attr('text-anchor', function (d) { return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; }) - .style("stroke", 'none') - .attr('x', xForText) - .attr('y', yForText) - .style("fill", function (d) { return $$.color(d); }) - .style("fill-opacity", 0); - $$.mainText = mainTextEnter.merge(mainText) - .text(function (d, i, j) { return $$.dataLabelFormat(d.id)(d.value, d.id, i, j); }); - mainText.exit() - .transition().duration(durationForExit) - .style('fill-opacity', 0) - .remove(); + const $$ = this; + + $$.brush = null; + $$.context.remove(); + $$.context = null; +}; + +ChartInternal.prototype.initText = function() { + var $$ = this; + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartTexts); + $$.mainText = $$.d3.selectAll([]); +}; +ChartInternal.prototype.updateTargetsForText = function(targets) { + var $$ = this, + classChartText = $$.classChartText.bind($$), + classTexts = $$.classTexts.bind($$), + classFocus = $$.classFocus.bind($$); + var mainText = $$.main + .select('.' + CLASS.chartTexts) + .selectAll('.' + CLASS.chartText) + .data(targets); + var mainTextEnter = mainText + .enter() + .append('g') + .attr('class', classChartText) + .style('opacity', 0) + .style('pointer-events', 'none'); + mainTextEnter.append('g').attr('class', classTexts); + mainTextEnter.merge(mainText).attr('class', function(d) { + return classChartText(d) + classFocus(d) + }); +}; +ChartInternal.prototype.updateText = function( + xForText, + yForText, + durationForExit +) { + var $$ = this, + config = $$.config, + barOrLineData = $$.barOrLineData.bind($$), + classText = $$.classText.bind($$); + var mainText = $$.main + .selectAll('.' + CLASS.texts) + .selectAll('.' + CLASS.text) + .data(barOrLineData); + var mainTextEnter = mainText + .enter() + .append('text') + .attr('class', classText) + .attr('text-anchor', function(d) { + return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle' + }) + .style('stroke', 'none') + .attr('x', xForText) + .attr('y', yForText) + .style('fill', function(d) { + return $$.color(d) + }) + .style('fill-opacity', 0); + $$.mainText = mainTextEnter.merge(mainText).text(function(d, i, j) { + return $$.dataLabelFormat(d.id)(d.value, d.id, i, j) + }); + mainText + .exit() + .transition() + .duration(durationForExit) + .style('fill-opacity', 0) + .remove(); +}; +ChartInternal.prototype.redrawText = function( + xForText, + yForText, + forFlow, + withTransition, + transition +) { + return [ + (withTransition ? this.mainText.transition(transition) : this.mainText) + .attr('x', xForText) + .attr('y', yForText) + .style('fill', this.color) + .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this)) + ] +}; +ChartInternal.prototype.getTextRect = function(text, cls, element) { + var dummy = this.d3 + .select('body') + .append('div') + .classed('c3', true), + svg = dummy + .append('svg') + .style('visibility', 'hidden') + .style('position', 'fixed') + .style('top', 0) + .style('left', 0), + font = this.d3.select(element).style('font'), + rect; + svg + .selectAll('.dummy') + .data([text]) + .enter() + .append('text') + .classed(cls ? cls : '', true) + .style('font', font) + .text(text) + .each(function() { + rect = getBBox(this); + }); + dummy.remove(); + return rect +}; +ChartInternal.prototype.generateXYForText = function( + areaIndices, + barIndices, + lineIndices, + forX +) { + var $$ = this, + getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), + getBarPoints = $$.generateGetBarPoints(barIndices, false), + getLinePoints = $$.generateGetLinePoints(lineIndices, false), + getter = forX ? $$.getXForText : $$.getYForText; + return function(d, i) { + var getPoints = $$.isAreaType(d) + ? getAreaPoints + : $$.isBarType(d) + ? getBarPoints + : getLinePoints; + return getter.call($$, getPoints(d, i), d, this) + } }; -ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) { - return [ - (withTransition ? this.mainText.transition(transition) : this.mainText) - .attr('x', xForText) - .attr('y', yForText) - .style("fill", this.color) - .style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this)) - ]; -}; -ChartInternal.prototype.getTextRect = function (text, cls, element) { - var dummy = this.d3.select('body').append('div').classed('c3', true), - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), - font = this.d3.select(element).style('font'), - rect; - svg.selectAll('.dummy') - .data([text]) - .enter().append('text') - .classed(cls ? cls : "", true) - .style('font', font) - .text(text) - .each(function () { rect = getBBox(this); }); - dummy.remove(); - return rect; -}; -ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) { - var $$ = this, - getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), - getBarPoints = $$.generateGetBarPoints(barIndices, false), - getLinePoints = $$.generateGetLinePoints(lineIndices, false), - getter = forX ? $$.getXForText : $$.getYForText; - return function (d, i) { - var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints; - return getter.call($$, getPoints(d, i), d, this); - }; -}; -ChartInternal.prototype.getXForText = function (points, d, textElement) { - var $$ = this, - box = getBBox(textElement), xPos, padding; - if ($$.config.axis_rotated) { - padding = $$.isBarType(d) ? 4 : 6; - xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1); - } else { - xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0]; - } - // show labels regardless of the domain if value is null - if (d.value === null) { - if (xPos > $$.width) { - xPos = $$.width - box.width; - } else if (xPos < 0) { - xPos = 4; - } +ChartInternal.prototype.getXForText = function(points, d, textElement) { + var $$ = this, + box = getBBox(textElement), + xPos, + padding; + if ($$.config.axis_rotated) { + padding = $$.isBarType(d) ? 4 : 6; + xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1); + } else { + xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0]; + } + // show labels regardless of the domain if value is null + if (d.value === null) { + if (xPos > $$.width) { + xPos = $$.width - box.width; + } else if (xPos < 0) { + xPos = 4; } - return xPos; -}; -ChartInternal.prototype.getYForText = function (points, d, textElement) { - var $$ = this, - box = getBBox(textElement), - yPos; - if ($$.config.axis_rotated) { - yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2; + } + return xPos +}; +ChartInternal.prototype.getYForText = function(points, d, textElement) { + var $$ = this, + box = getBBox(textElement), + yPos; + if ($$.config.axis_rotated) { + yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2; + } else { + yPos = points[2][1]; + if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) { + yPos += box.height; + if ($$.isBarType(d) && $$.isSafari()) { + yPos -= 3; + } else if (!$$.isBarType(d) && $$.isChrome()) { + yPos += 3; + } } else { - yPos = points[2][1]; - if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) { - yPos += box.height; - if ($$.isBarType(d) && $$.isSafari()) { - yPos -= 3; - } - else if (!$$.isBarType(d) && $$.isChrome()) { - yPos += 3; - } - } else { - yPos += $$.isBarType(d) ? -3 : -6; - } - } - // show labels regardless of the domain if value is null - if (d.value === null && !$$.config.axis_rotated) { - if (yPos < box.height) { - yPos = box.height; - } else if (yPos > this.height) { - yPos = this.height - 4; - } + yPos += $$.isBarType(d) ? -3 : -6; } - return yPos; -}; - -ChartInternal.prototype.initTitle = function () { - var $$ = this; - $$.title = $$.svg.append("text") - .text($$.config.title_text) - .attr("class", $$.CLASS.title); -}; -ChartInternal.prototype.redrawTitle = function () { - var $$ = this; - $$.title - .attr("x", $$.xForTitle.bind($$)) - .attr("y", $$.yForTitle.bind($$)); -}; -ChartInternal.prototype.xForTitle = function () { - var $$ = this, - config = $$.config, - position = config.title_position || 'left', - x; - if (position.indexOf('right') >= 0) { - x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right; - } else if (position.indexOf('center') >= 0) { - x = Math.max(($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2, 0); - } else { // left - x = config.title_padding.left; + } + // show labels regardless of the domain if value is null + if (d.value === null && !$$.config.axis_rotated) { + if (yPos < box.height) { + yPos = box.height; + } else if (yPos > this.height) { + yPos = this.height - 4; } - return x; + } + return yPos +}; + +ChartInternal.prototype.initTitle = function() { + var $$ = this; + $$.title = $$.svg + .append('text') + .text($$.config.title_text) + .attr('class', $$.CLASS.title); +}; +ChartInternal.prototype.redrawTitle = function() { + var $$ = this; + $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$)); +}; +ChartInternal.prototype.xForTitle = function() { + var $$ = this, + config = $$.config, + position = config.title_position || 'left', + x; + if (position.indexOf('right') >= 0) { + x = + $$.currentWidth - + $$.getTextRect( + $$.title.node().textContent, + $$.CLASS.title, + $$.title.node() + ).width - + config.title_padding.right; + } else if (position.indexOf('center') >= 0) { + x = Math.max( + ($$.currentWidth - + $$.getTextRect( + $$.title.node().textContent, + $$.CLASS.title, + $$.title.node() + ).width) / + 2, + 0 + ); + } else { + // left + x = config.title_padding.left; + } + return x }; -ChartInternal.prototype.yForTitle = function () { - var $$ = this; - return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height; +ChartInternal.prototype.yForTitle = function() { + var $$ = this; + return ( + $$.config.title_padding.top + + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()) + .height + ) }; -ChartInternal.prototype.getTitlePadding = function () { - var $$ = this; - return $$.yForTitle() + $$.config.title_padding.bottom; +ChartInternal.prototype.getTitlePadding = function() { + var $$ = this; + return $$.yForTitle() + $$.config.title_padding.bottom }; function powerOfTen(d) { - return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1; + return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1 } -ChartInternal.prototype.drawColorScale = function () { - var $$ = this, - d3 = $$.d3, - config = $$.config, - target = $$.data.targets[0], - barWidth, barHeight, axis, - points, legendAxis, axisScale, inverseScale, height; - - barWidth = !isNaN(config.stanford_scaleWidth) ? config.stanford_scaleWidth : 20; - barHeight = 5; - - if(barHeight < 0 || barWidth < 0) { - throw Error("Colorscale's barheight and barwidth must be greater than 0."); - } - - height = $$.height - config.stanford_padding.bottom - config.stanford_padding.top; - - points = d3.range(config.stanford_padding.bottom, height, barHeight); - - inverseScale = d3.scaleSequential(target.colors) - .domain([points[points.length - 1], points[0]]); - - if($$.colorScale) { - $$.colorScale.remove(); - } +ChartInternal.prototype.drawColorScale = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + target = $$.data.targets[0], + barWidth, + barHeight, + axis, + points, + legendAxis, + axisScale, + inverseScale, + height; + + barWidth = !isNaN(config.stanford_scaleWidth) + ? config.stanford_scaleWidth + : 20; + barHeight = 5; + + if (barHeight < 0 || barWidth < 0) { + throw Error("Colorscale's barheight and barwidth must be greater than 0.") + } - $$.colorScale = $$.svg.append("g") - .attr('width', 50) - .attr('height', height) - .attr('class', CLASS.colorScale); + height = + $$.height - config.stanford_padding.bottom - config.stanford_padding.top; - $$.colorScale.append('g') - .attr('transform', `translate(0, ${config.stanford_padding.top})`) - .selectAll('bars') - .data(points) - .enter() - .append('rect') - .attr('y', (d, i) => i * barHeight) - .attr('x', 0) - .attr('width', barWidth) - .attr('height', barHeight) - .attr('fill', function (d) { - return inverseScale(d); - }); + points = d3.range(config.stanford_padding.bottom, height, barHeight); - // Legend Axis - axisScale = d3.scaleLog() - .domain([target.minEpochs, target.maxEpochs]) - .range([ - points[0] + config.stanford_padding.top + points[points.length - 1] + barHeight - 1, - points[0] + config.stanford_padding.top - ]); + inverseScale = d3 + .scaleSequential(target.colors) + .domain([points[points.length - 1], points[0]]); - legendAxis = d3.axisRight(axisScale); + if ($$.colorScale) { + $$.colorScale.remove(); + } - if(config.stanford_scaleFormat === 'pow10') { - legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]); - } else if(isFunction(config.stanford_scaleFormat)) { - legendAxis.tickFormat(config.stanford_scaleFormat); - } else { - legendAxis.tickFormat(d3.format("d")); - } + $$.colorScale = $$.svg + .append('g') + .attr('width', 50) + .attr('height', height) + .attr('class', CLASS.colorScale); + + $$.colorScale + .append('g') + .attr('transform', `translate(0, ${config.stanford_padding.top})`) + .selectAll('bars') + .data(points) + .enter() + .append('rect') + .attr('y', (d, i) => i * barHeight) + .attr('x', 0) + .attr('width', barWidth) + .attr('height', barHeight) + .attr('fill', function(d) { + return inverseScale(d) + }); - if(isFunction(config.stanford_scaleValues)) { - legendAxis.tickValues(config.stanford_scaleValues(target.minEpochs, target.maxEpochs)); - } + // Legend Axis + axisScale = d3 + .scaleLog() + .domain([target.minEpochs, target.maxEpochs]) + .range([ + points[0] + + config.stanford_padding.top + + points[points.length - 1] + + barHeight - + 1, + points[0] + config.stanford_padding.top + ]); + + legendAxis = d3.axisRight(axisScale); + + if (config.stanford_scaleFormat === 'pow10') { + legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]); + } else if (isFunction(config.stanford_scaleFormat)) { + legendAxis.tickFormat(config.stanford_scaleFormat); + } else { + legendAxis.tickFormat(d3.format('d')); + } - // Draw Axis - axis = $$.colorScale.append("g") - .attr("class", "legend axis") - .attr("transform", `translate(${barWidth},0)`) - .call(legendAxis); + if (isFunction(config.stanford_scaleValues)) { + legendAxis.tickValues( + config.stanford_scaleValues(target.minEpochs, target.maxEpochs) + ); + } - if(config.stanford_scaleFormat === 'pow10') { - axis.selectAll(".tick text") - .text(null) - .filter(powerOfTen) - .text(10) - .append("tspan") - .attr("dy", "-.7em") // https://bl.ocks.org/mbostock/6738229 - .text(function(d) { - return Math.round(Math.log(d) / Math.LN10); - }); - } + // Draw Axis + axis = $$.colorScale + .append('g') + .attr('class', 'legend axis') + .attr('transform', `translate(${barWidth},0)`) + .call(legendAxis); + + if (config.stanford_scaleFormat === 'pow10') { + axis + .selectAll('.tick text') + .text(null) + .filter(powerOfTen) + .text(10) + .append('tspan') + .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229 + .text(function(d) { + return Math.round(Math.log(d) / Math.LN10) + }); + } - $$.colorScale.attr('transform', `translate(${$$.currentWidth - $$.xForColorScale()}, 0)`); + $$.colorScale.attr( + 'transform', + `translate(${$$.currentWidth - $$.xForColorScale()}, 0)` + ); }; -ChartInternal.prototype.xForColorScale = function () { - var $$ = this; +ChartInternal.prototype.xForColorScale = function() { + var $$ = this; - return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width; + return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width }; -ChartInternal.prototype.getColorScalePadding = function () { - var $$ = this; - return $$.xForColorScale() + $$.config.stanford_padding.left + 20; +ChartInternal.prototype.getColorScalePadding = function() { + var $$ = this; + return $$.xForColorScale() + $$.config.stanford_padding.left + 20 }; -ChartInternal.prototype.isStanfordGraphType = function () { - var $$ = this; +ChartInternal.prototype.isStanfordGraphType = function() { + var $$ = this; - return $$.config.data_type === 'stanford'; + return $$.config.data_type === 'stanford' }; -ChartInternal.prototype.initStanfordData = function () { - var $$ = this, - d3 = $$.d3, - config = $$.config, - target = $$.data.targets[0], - epochs, - maxEpochs, - minEpochs; +ChartInternal.prototype.initStanfordData = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + target = $$.data.targets[0], + epochs, + maxEpochs, + minEpochs; - // Make larger values appear on top - target.values.sort(compareEpochs); + // Make larger values appear on top + target.values.sort(compareEpochs); - // Get array of epochs - epochs = target.values.map(a => a.epochs); + // Get array of epochs + epochs = target.values.map(a => a.epochs); - minEpochs = !isNaN(config.stanford_scaleMin) ? config.stanford_scaleMin : d3.min(epochs); - maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs); + minEpochs = !isNaN(config.stanford_scaleMin) + ? config.stanford_scaleMin + : d3.min(epochs); + maxEpochs = !isNaN(config.stanford_scaleMax) + ? config.stanford_scaleMax + : d3.max(epochs); - if (minEpochs > maxEpochs) { - throw Error("Number of minEpochs has to be smaller than maxEpochs"); - } + if (minEpochs > maxEpochs) { + throw Error('Number of minEpochs has to be smaller than maxEpochs') + } - target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)); + target.colors = isFunction(config.stanford_colors) + ? config.stanford_colors + : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)); - target.colorscale = d3.scaleSequentialLog(target.colors) - .domain([minEpochs, maxEpochs]); + target.colorscale = d3 + .scaleSequentialLog(target.colors) + .domain([minEpochs, maxEpochs]); - target.minEpochs = minEpochs; - target.maxEpochs = maxEpochs; + target.minEpochs = minEpochs; + target.maxEpochs = maxEpochs; }; -ChartInternal.prototype.getStanfordPointColor = function (d) { - var $$ = this, - target = $$.data.targets[0]; +ChartInternal.prototype.getStanfordPointColor = function(d) { + var $$ = this, + target = $$.data.targets[0]; - return target.colorscale(d.epochs); + return target.colorscale(d.epochs) }; // http://jsfiddle.net/Xotic750/KtzLq/ -ChartInternal.prototype.getCentroid = function (points) { - var area = getRegionArea(points); - - var x = 0, - y = 0, - i, - j, - f, - point1, - point2; - - for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { - point1 = points[i]; - point2 = points[j]; - f = point1.x * point2.y - point2.x * point1.y; - x += (point1.x + point2.x) * f; - y += (point1.y + point2.y) * f; - } +ChartInternal.prototype.getCentroid = function(points) { + var area = getRegionArea(points); + + var x = 0, + y = 0, + i, + j, + f, + point1, + point2; + + for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { + point1 = points[i]; + point2 = points[j]; + f = point1.x * point2.y - point2.x * point1.y; + x += (point1.x + point2.x) * f; + y += (point1.y + point2.y) * f; + } - f = area * 6; + f = area * 6; - return { - x: x / f, - y: y / f - }; + return { + x: x / f, + y: y / f + } }; -ChartInternal.prototype.getStanfordTooltipTitle = function (d) { - var $$ = this, - labelX = $$.axis.getLabelText('x'), - labelY = $$.axis.getLabelText('y'); +ChartInternal.prototype.getStanfordTooltipTitle = function(d) { + var $$ = this, + labelX = $$.axis.getLabelText('x'), + labelY = $$.axis.getLabelText('y'); - return ` - ${labelX ? sanitise(labelX) : "x"}${d.x} - ${labelY ? sanitise(labelY) : "y"}${d.value} - `; + return ` + ${labelX ? sanitise(labelX) : 'x'}${ + d.x + } + ${labelY ? sanitise(labelY) : 'y'}${ + d.value + } + ` }; -ChartInternal.prototype.countEpochsInRegion = function (region) { - var $$ = this, - target = $$.data.targets[0], - total, count; +ChartInternal.prototype.countEpochsInRegion = function(region) { + var $$ = this, + target = $$.data.targets[0], + total, + count; - total = target.values.reduce((accumulator, currentValue) => accumulator + Number(currentValue.epochs), 0); + total = target.values.reduce( + (accumulator, currentValue) => accumulator + Number(currentValue.epochs), + 0 + ); - count = target.values.reduce((accumulator, currentValue) => { - if(pointInRegion(currentValue, region)) { - return accumulator + Number(currentValue.epochs); - } + count = target.values.reduce((accumulator, currentValue) => { + if (pointInRegion(currentValue, region)) { + return accumulator + Number(currentValue.epochs) + } - return accumulator; - }, 0); + return accumulator + }, 0); - return { - value: count, - percentage: count !== 0 ? (count / total * 100).toFixed(1) : 0 - }; + return { + value: count, + percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0 + } }; -var getRegionArea = function(points) { // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript - var area = 0, - i, - j, - point1, - point2; +var getRegionArea = function(points) { + // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript + var area = 0, + i, + j, + point1, + point2; - for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { - point1 = points[i]; - point2 = points[j]; - area += point1.x * point2.y; - area -= point1.y * point2.x; - } + for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { + point1 = points[i]; + point2 = points[j]; + area += point1.x * point2.y; + area -= point1.y * point2.x; + } - area /= 2; + area /= 2; - return area; + return area }; -var pointInRegion = function(point, region) { // thanks to: http://bl.ocks.org/bycoffe/5575904 - // ray-casting algorithm based on - // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html - let xi, yi, yj, xj, intersect, - x = point.x, - y = point.value, - inside = false; - - for (let i = 0, j = region.length - 1; i < region.length; j = i++) { +var pointInRegion = function(point, region) { + // thanks to: http://bl.ocks.org/bycoffe/5575904 + // ray-casting algorithm based on + // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + let xi, + yi, + yj, + xj, + intersect, + x = point.x, + y = point.value, + inside = false; - xi = region[i].x; - yi = region[i].y; + for (let i = 0, j = region.length - 1; i < region.length; j = i++) { + xi = region[i].x; + yi = region[i].y; - xj = region[j].x; - yj = region[j].y; + xj = region[j].x; + yj = region[j].y; - intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); + intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi; - if (intersect) { - inside = !inside; - } + if (intersect) { + inside = !inside; } + } - return inside; + return inside }; var compareEpochs = function(a, b) { - if (a.epochs < b.epochs) { - return -1; - } - if (a.epochs > b.epochs) { - return 1; - } - - return 0; -}; - -ChartInternal.prototype.initStanfordElements = function () { - var $$ = this; - - // Avoid blocking eventRect - $$.stanfordElements = $$.main.select('.' + CLASS.chart) - .append('g').attr('class', CLASS.stanfordElements); - - $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines); - $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts); - $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions); -}; - -ChartInternal.prototype.updateStanfordElements = function (duration) { - var $$ = this, main = $$.main, config = $$.config, - stanfordLine, stanfordLineEnter, stanfordRegion, stanfordRegionEnter, stanfordText, stanfordTextEnter, - xvCustom = $$.xvCustom.bind($$), yvCustom = $$.yvCustom.bind($$), countPointsInRegion = $$.countEpochsInRegion.bind($$); - - // Stanford-Lines - stanfordLine = main.select('.' + CLASS.stanfordLines) - .style('shape-rendering', 'geometricprecision') - .selectAll('.' + CLASS.stanfordLine) - .data(config.stanford_lines); - - // enter - stanfordLineEnter = stanfordLine.enter().append('g') - .attr("class", function (d) { return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordLineEnter.append('line') - .attr("x1", (d) => config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')) - .attr("x2", (d) => config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')) - .attr("y1", (d) => config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')) - .attr("y2", (d) => config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')) - .style("opacity", 0); - - // update - $$.stanfordLines = stanfordLineEnter.merge(stanfordLine); - $$.stanfordLines.select('line') - .transition().duration(duration) - .attr("x1", (d) => config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')) - .attr("x2", (d) => config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')) - .attr("y1", (d) => config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')) - .attr("y2", (d) => config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')) - .style("opacity", 1); - - // exit - stanfordLine.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); - - // Stanford-Text - stanfordText = main.select('.' + CLASS.stanfordTexts).selectAll('.' + CLASS.stanfordText) - .data(config.stanford_texts); - - // enter - stanfordTextEnter = stanfordText.enter().append('g') - .attr("class", function (d) { return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordTextEnter.append('text') - .attr("x", (d) => config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')) - .attr("y", (d) => config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')) - .style("opacity", 0); - - // update - $$.stanfordTexts = stanfordTextEnter.merge(stanfordText); - $$.stanfordTexts.select('text') - .transition().duration(duration) - .attr("x", (d) => config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')) - .attr("y", (d) => config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')) - .text(function (d) { return d.content; }) - .style("opacity", 1); - - // exit - stanfordText.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); + if (a.epochs < b.epochs) { + return -1 + } + if (a.epochs > b.epochs) { + return 1 + } - // Stanford-Regions - stanfordRegion = main.select('.' + CLASS.stanfordRegions).selectAll('.' + CLASS.stanfordRegion) - .data(config.stanford_regions); - - // enter - stanfordRegionEnter = stanfordRegion.enter().append('g') - .attr("class", function (d) { return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordRegionEnter.append('polygon') - .attr("points", (d) => { - return d.points.map(value => { - return [ - config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), - config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') - ].join(","); - }).join(" "); - }) - .style("opacity", 0); - stanfordRegionEnter.append('text') - .attr("x", (d) => $$.getCentroid(d.points).x) - .attr("y", (d) => $$.getCentroid(d.points).y) - .style("opacity", 0); - - // update - $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion); - $$.stanfordRegions.select('polygon') - .transition().duration(duration) - .attr("points", (d) => { - return d.points.map(value => { - return [ - config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), - config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') - ].join(","); - }).join(" "); + return 0 +}; + +ChartInternal.prototype.initStanfordElements = function() { + var $$ = this; + + // Avoid blocking eventRect + $$.stanfordElements = $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.stanfordElements); + + $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines); + $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts); + $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions); +}; + +ChartInternal.prototype.updateStanfordElements = function(duration) { + var $$ = this, + main = $$.main, + config = $$.config, + stanfordLine, + stanfordLineEnter, + stanfordRegion, + stanfordRegionEnter, + stanfordText, + stanfordTextEnter, + xvCustom = $$.xvCustom.bind($$), + yvCustom = $$.yvCustom.bind($$), + countPointsInRegion = $$.countEpochsInRegion.bind($$); + + // Stanford-Lines + stanfordLine = main + .select('.' + CLASS.stanfordLines) + .style('shape-rendering', 'geometricprecision') + .selectAll('.' + CLASS.stanfordLine) + .data(config.stanford_lines); + + // enter + stanfordLineEnter = stanfordLine + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '') + }); + stanfordLineEnter + .append('line') + .attr('x1', d => + config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1') + ) + .attr('x2', d => + config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2') + ) + .attr('y1', d => + config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1') + ) + .attr('y2', d => + config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2') + ) + .style('opacity', 0); + + // update + $$.stanfordLines = stanfordLineEnter.merge(stanfordLine); + $$.stanfordLines + .select('line') + .transition() + .duration(duration) + .attr('x1', d => + config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1') + ) + .attr('x2', d => + config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2') + ) + .attr('y1', d => + config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1') + ) + .attr('y2', d => + config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2') + ) + .style('opacity', 1); + + // exit + stanfordLine + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); + + // Stanford-Text + stanfordText = main + .select('.' + CLASS.stanfordTexts) + .selectAll('.' + CLASS.stanfordText) + .data(config.stanford_texts); + + // enter + stanfordTextEnter = stanfordText + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '') + }); + stanfordTextEnter + .append('text') + .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'))) + .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'))) + .style('opacity', 0); + + // update + $$.stanfordTexts = stanfordTextEnter.merge(stanfordText); + $$.stanfordTexts + .select('text') + .transition() + .duration(duration) + .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'))) + .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'))) + .text(function(d) { + return d.content + }) + .style('opacity', 1); + + // exit + stanfordText + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); + + // Stanford-Regions + stanfordRegion = main + .select('.' + CLASS.stanfordRegions) + .selectAll('.' + CLASS.stanfordRegion) + .data(config.stanford_regions); + + // enter + stanfordRegionEnter = stanfordRegion + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '') + }); + stanfordRegionEnter + .append('polygon') + .attr('points', d => { + return d.points + .map(value => { + return [ + config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), + config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') + ].join(',') }) - .style("opacity", (d) => { return d.opacity ? d.opacity : 0.2; }); - $$.stanfordRegions.select('text') - .transition().duration(duration) - .attr("x", (d) => config.axis_rotated ? yvCustom($$.getCentroid(d.points), 'y') : xvCustom($$.getCentroid(d.points), 'x')) - .attr("y", (d) => config.axis_rotated ? xvCustom($$.getCentroid(d.points), 'x') : yvCustom($$.getCentroid(d.points), 'y')) - .text(function (d) { - if(d.text) { - var value, percentage, temp; - - if($$.isStanfordGraphType()) { - temp = countPointsInRegion(d.points); - value = temp.value; - percentage = temp.percentage; - } - - return d.text(value, percentage); - } - - return ""; + .join(' ') + }) + .style('opacity', 0); + stanfordRegionEnter + .append('text') + .attr('x', d => $$.getCentroid(d.points).x) + .attr('y', d => $$.getCentroid(d.points).y) + .style('opacity', 0); + + // update + $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion); + $$.stanfordRegions + .select('polygon') + .transition() + .duration(duration) + .attr('points', d => { + return d.points + .map(value => { + return [ + config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), + config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') + ].join(',') }) - .attr("text-anchor", "middle") - .attr("dominant-baseline", "middle") - .style("opacity", 1); - // exit - stanfordRegion.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); + .join(' ') + }) + .style('opacity', d => { + return d.opacity ? d.opacity : 0.2 + }); + $$.stanfordRegions + .select('text') + .transition() + .duration(duration) + .attr('x', d => + config.axis_rotated + ? yvCustom($$.getCentroid(d.points), 'y') + : xvCustom($$.getCentroid(d.points), 'x') + ) + .attr('y', d => + config.axis_rotated + ? xvCustom($$.getCentroid(d.points), 'x') + : yvCustom($$.getCentroid(d.points), 'y') + ) + .text(function(d) { + if (d.text) { + var value, percentage, temp; + + if ($$.isStanfordGraphType()) { + temp = countPointsInRegion(d.points); + value = temp.value; + percentage = temp.percentage; + } + + return d.text(value, percentage) + } + + return '' + }) + .attr('text-anchor', 'middle') + .attr('dominant-baseline', 'middle') + .style('opacity', 1); + // exit + stanfordRegion + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); +}; + +ChartInternal.prototype.initTooltip = function() { + var $$ = this, + config = $$.config, + i; + $$.tooltip = $$.selectChart + .style('position', 'relative') + .append('div') + .attr('class', CLASS.tooltipContainer) + .style('position', 'absolute') + .style('pointer-events', 'none') + .style('display', 'none'); + // Show tooltip if needed + if (config.tooltip_init_show) { + if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { + config.tooltip_init_x = $$.parseDate(config.tooltip_init_x); + for (i = 0; i < $$.data.targets[0].values.length; i++) { + if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) { + break + } + } + config.tooltip_init_x = i; + } + $$.tooltip.html( + config.tooltip_contents.call( + $$, + $$.data.targets.map(function(d) { + return $$.addName(d.values[config.tooltip_init_x]) + }), + $$.axis.getXAxisTickFormat(), + $$.getYFormat($$.hasArcType()), + $$.color + ) + ); + $$.tooltip + .style('top', config.tooltip_init_position.top) + .style('left', config.tooltip_init_position.left) + .style('display', 'block'); + } }; +ChartInternal.prototype.getTooltipSortFunction = function() { + var $$ = this, + config = $$.config; -ChartInternal.prototype.initTooltip = function () { - var $$ = this, - config = $$.config, - i; - $$.tooltip = $$.selectChart - .style("position", "relative") - .append("div") - .attr('class', CLASS.tooltipContainer) - .style("position", "absolute") - .style("pointer-events", "none") - .style("display", "none"); - // Show tooltip if needed - if (config.tooltip_init_show) { - if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { - config.tooltip_init_x = $$.parseDate(config.tooltip_init_x); - for (i = 0; i < $$.data.targets[0].values.length; i++) { - if (($$.data.targets[0].values[i].x - config.tooltip_init_x) === 0) { - break; - } - } - config.tooltip_init_x = i; - } - $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) { - return $$.addName(d.values[config.tooltip_init_x]); - }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color)); - $$.tooltip.style("top", config.tooltip_init_position.top) - .style("left", config.tooltip_init_position.left) - .style("display", "block"); - } -}; -ChartInternal.prototype.getTooltipSortFunction = function () { - var $$ = this, - config = $$.config; + if (config.data_groups.length === 0 || config.tooltip_order !== undefined) { + // if data are not grouped or if an order is specified + // for the tooltip values we sort them by their values - if (config.data_groups.length === 0 || config.tooltip_order !== undefined) { - // if data are not grouped or if an order is specified - // for the tooltip values we sort them by their values + var order = config.tooltip_order; + if (order === undefined) { + order = config.data_order; + } - var order = config.tooltip_order; - if (order === undefined) { - order = config.data_order; - } + var valueOf = function(obj) { + return obj ? obj.value : null + }; - var valueOf = function (obj) { - return obj ? obj.value : null; + // if data are not grouped, we sort them by their value + if (isString(order) && order.toLowerCase() === 'asc') { + return function(a, b) { + return valueOf(a) - valueOf(b) + } + } else if (isString(order) && order.toLowerCase() === 'desc') { + return function(a, b) { + return valueOf(b) - valueOf(a) + } + } else if (isFunction(order)) { + // if the function is from data_order we need + // to wrap the returned function in order to format + // the sorted value to the expected format + + var sortFunction = order; + + if (config.tooltip_order === undefined) { + sortFunction = function(a, b) { + return order( + a + ? { + id: a.id, + values: [a] + } + : null, + b + ? { + id: b.id, + values: [b] + } + : null + ) }; + } - // if data are not grouped, we sort them by their value - if (isString(order) && order.toLowerCase() === 'asc') { - return function (a, b) { - return valueOf(a) - valueOf(b); - }; - } else if (isString(order) && order.toLowerCase() === 'desc') { - return function (a, b) { - return valueOf(b) - valueOf(a); - }; - } else if (isFunction(order)) { - - // if the function is from data_order we need - // to wrap the returned function in order to format - // the sorted value to the expected format - - var sortFunction = order; - - if (config.tooltip_order === undefined) { - sortFunction = function (a, b) { - return order(a ? { - id: a.id, - values: [a] - } : null, b ? { - id: b.id, - values: [b] - } : null); - }; - } - - return sortFunction; - - } else if (isArray(order)) { - return function (a, b) { - return order.indexOf(a.id) - order.indexOf(b.id); - }; - } - } else { - // if data are grouped, we follow the order of grouped targets - var ids = $$.orderTargets($$.data.targets).map(function (i) { - return i.id; - }); - - // if it was either asc or desc we need to invert the order - // returned by orderTargets - if ($$.isOrderAsc() || $$.isOrderDesc()) { - ids = ids.reverse(); - } - - return function (a, b) { - return ids.indexOf(a.id) - ids.indexOf(b.id); - }; + return sortFunction + } else if (isArray(order)) { + return function(a, b) { + return order.indexOf(a.id) - order.indexOf(b.id) + } } -}; -ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) { - var $$ = this, - config = $$.config, - titleFormat = config.tooltip_format_title || defaultTitleFormat, - nameFormat = config.tooltip_format_name || function (name) { - return name; - }, - text, i, title, value, name, bgcolor; + } else { + // if data are grouped, we follow the order of grouped targets + var ids = $$.orderTargets($$.data.targets).map(function(i) { + return i.id + }); - var valueFormat = config.tooltip_format_value; - if (!valueFormat) { - valueFormat = $$.isTargetNormalized(d.id) ? ((v, ratio) => `${(ratio * 100).toFixed(2)}%`) : defaultValueFormat; + // if it was either asc or desc we need to invert the order + // returned by orderTargets + if ($$.isOrderAsc() || $$.isOrderDesc()) { + ids = ids.reverse(); } - var tooltipSortFunction = this.getTooltipSortFunction(); - if (tooltipSortFunction) { - d.sort(tooltipSortFunction); + return function(a, b) { + return ids.indexOf(a.id) - ids.indexOf(b.id) } + } +}; +ChartInternal.prototype.getTooltipContent = function( + d, + defaultTitleFormat, + defaultValueFormat, + color +) { + var $$ = this, + config = $$.config, + titleFormat = config.tooltip_format_title || defaultTitleFormat, + nameFormat = + config.tooltip_format_name || + function(name) { + return name + }, + text, + i, + title, + value, + name, + bgcolor; + + var valueFormat = config.tooltip_format_value; + if (!valueFormat) { + valueFormat = $$.isTargetNormalized(d.id) + ? (v, ratio) => `${(ratio * 100).toFixed(2)}%` + : defaultValueFormat; + } - for (i = 0; i < d.length; i++) { - if (!(d[i] && (d[i].value || d[i].value === 0))) { - continue; - } - - if($$.isStanfordGraphType()) { - // Custom tooltip for stanford plots - if (!text) { - title = $$.getStanfordTooltipTitle(d[i]); - text = "" + title; - } - - bgcolor = $$.getStanfordPointColor(d[i]); - name = sanitise(config.data_epochs); // Epochs key name - value = d[i].epochs; - } else { - // Regular tooltip - if (!text) { - title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x); - text = "
" + (title || title === 0 ? "" : ""); - } - - value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)); - if (value !== undefined) { - // Skip elements when their name is set to null - if (d[i].name === null) { - continue; - } + var tooltipSortFunction = this.getTooltipSortFunction(); + if (tooltipSortFunction) { + d.sort(tooltipSortFunction); + } - name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index)); - bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id); - } - } + for (i = 0; i < d.length; i++) { + if (!(d[i] && (d[i].value || d[i].value === 0))) { + continue + } - if(value !== undefined) { - text += ""; - text += ""; - text += ""; - text += ""; - } + if ($$.isStanfordGraphType()) { + // Custom tooltip for stanford plots + if (!text) { + title = $$.getStanfordTooltipTitle(d[i]); + text = "
" + title + "
" + name + "" + value + "
" + title; + } + + bgcolor = $$.getStanfordPointColor(d[i]); + name = sanitise(config.data_epochs); // Epochs key name + value = d[i].epochs; + } else { + // Regular tooltip + if (!text) { + title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x); + text = + "
" + + (title || title === 0 + ? "' + : ''); + } + + value = sanitise( + valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d) + ); + if (value !== undefined) { + // Skip elements when their name is set to null + if (d[i].name === null) { + continue + } + + name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index)); + bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id); + } + } + + if (value !== undefined) { + text += + ""; + text += + "'; + text += "'; + text += ''; } - return text + "
" + title + '
" + + name + + '" + value + '
"; -}; -ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) { - var $$ = this, - config = $$.config, - d3 = $$.d3; - var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight; - var forArc = $$.hasArcType(), - mouse = d3.mouse(element); - // Determin tooltip position - if (forArc) { - tooltipLeft = (($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2) + mouse[0]; - tooltipTop = ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20; + } + return text + '' +}; +ChartInternal.prototype.tooltipPosition = function( + dataToShow, + tWidth, + tHeight, + element +) { + var $$ = this, + config = $$.config, + d3 = $$.d3; + var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight; + var forArc = $$.hasArcType(), + mouse = d3.mouse(element); + // Determin tooltip position + if (forArc) { + tooltipLeft = + ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0]; + tooltipTop = + ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20; + } else { + svgLeft = $$.getSvgLeft(true); + if (config.axis_rotated) { + tooltipLeft = svgLeft + mouse[0] + 100; + tooltipRight = tooltipLeft + tWidth; + chartRight = $$.currentWidth - $$.getCurrentPaddingRight(); + tooltipTop = $$.x(dataToShow[0].x) + 20; } else { - svgLeft = $$.getSvgLeft(true); - if (config.axis_rotated) { - tooltipLeft = svgLeft + mouse[0] + 100; - tooltipRight = tooltipLeft + tWidth; - chartRight = $$.currentWidth - $$.getCurrentPaddingRight(); - tooltipTop = $$.x(dataToShow[0].x) + 20; - } else { - tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20; - tooltipRight = tooltipLeft + tWidth; - chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight(); - tooltipTop = mouse[1] + 15; - } - - if (tooltipRight > chartRight) { - // 20 is needed for Firefox to keep tooltip width - tooltipLeft -= tooltipRight - chartRight + 20; - } - if (tooltipTop + tHeight > $$.currentHeight) { - tooltipTop -= tHeight + 30; - } + tooltipLeft = + svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20; + tooltipRight = tooltipLeft + tWidth; + chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight(); + tooltipTop = mouse[1] + 15; } - if (tooltipTop < 0) { - tooltipTop = 0; + + if (tooltipRight > chartRight) { + // 20 is needed for Firefox to keep tooltip width + tooltipLeft -= tooltipRight - chartRight + 20; } - return { - top: tooltipTop, - left: tooltipLeft - }; -}; -ChartInternal.prototype.showTooltip = function (selectedData, element) { - var $$ = this, - config = $$.config; - var tWidth, tHeight, position; - var forArc = $$.hasArcType(), - dataToShow = selectedData.filter(function (d) { - return d && isValue(d.value); - }), - positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition; - if (dataToShow.length === 0 || !config.tooltip_show) { - return; + if (tooltipTop + tHeight > $$.currentHeight) { + tooltipTop -= tHeight + 30; } - $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); - - // Get tooltip dimensions - tWidth = $$.tooltip.property('offsetWidth'); - tHeight = $$.tooltip.property('offsetHeight'); - - position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); - // Set tooltip - $$.tooltip - .style("top", position.top + "px") - .style("left", position.left + 'px'); + } + if (tooltipTop < 0) { + tooltipTop = 0; + } + return { + top: tooltipTop, + left: tooltipLeft + } }; -ChartInternal.prototype.hideTooltip = function () { - this.tooltip.style("display", "none"); +ChartInternal.prototype.showTooltip = function(selectedData, element) { + var $$ = this, + config = $$.config; + var tWidth, tHeight, position; + var forArc = $$.hasArcType(), + dataToShow = selectedData.filter(function(d) { + return d && isValue(d.value) + }), + positionFunction = + config.tooltip_position || ChartInternal.prototype.tooltipPosition; + if (dataToShow.length === 0 || !config.tooltip_show) { + return + } + $$.tooltip + .html( + config.tooltip_contents.call( + $$, + selectedData, + $$.axis.getXAxisTickFormat(), + $$.getYFormat(forArc), + $$.color + ) + ) + .style('display', 'block'); + + // Get tooltip dimensions + tWidth = $$.tooltip.property('offsetWidth'); + tHeight = $$.tooltip.property('offsetHeight'); + + position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); + // Set tooltip + $$.tooltip + .style('top', position.top + 'px') + .style('left', position.left + 'px'); +}; +ChartInternal.prototype.hideTooltip = function() { + this.tooltip.style('display', 'none'); +}; + +ChartInternal.prototype.setTargetType = function(targetIds, type) { + var $$ = this, + config = $$.config; + $$.mapToTargetIds(targetIds).forEach(function(id) { + $$.withoutFadeIn[id] = type === config.data_types[id]; + config.data_types[id] = type; + }); + if (!targetIds) { + config.data_type = type; + } }; - -ChartInternal.prototype.setTargetType = function (targetIds, type) { - var $$ = this, config = $$.config; - $$.mapToTargetIds(targetIds).forEach(function (id) { - $$.withoutFadeIn[id] = (type === config.data_types[id]); - config.data_types[id] = type; +ChartInternal.prototype.hasType = function(type, targets) { + var $$ = this, + types = $$.config.data_types, + has = false; + targets = targets || $$.data.targets; + if (targets && targets.length) { + targets.forEach(function(target) { + var t = types[target.id]; + if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) { + has = true; + } }); - if (!targetIds) { - config.data_type = type; - } -}; -ChartInternal.prototype.hasType = function (type, targets) { - var $$ = this, types = $$.config.data_types, has = false; - targets = targets || $$.data.targets; - if (targets && targets.length) { - targets.forEach(function (target) { - var t = types[target.id]; - if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) { - has = true; - } - }); - } else if (Object.keys(types).length) { - Object.keys(types).forEach(function (id) { - if (types[id] === type) { has = true; } - }); - } else { - has = $$.config.data_type === type; - } - return has; -}; -ChartInternal.prototype.hasArcType = function (targets) { - return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets); -}; -ChartInternal.prototype.isLineType = function (d) { - var config = this.config, id = isString(d) ? d : d.id; - return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isStepType = function (d) { - var id = isString(d) ? d : d.id; - return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isSplineType = function (d) { - var id = isString(d) ? d : d.id; - return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isAreaType = function (d) { - var id = isString(d) ? d : d.id; - return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isBarType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'bar'; -}; -ChartInternal.prototype.isScatterType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'scatter'; -}; -ChartInternal.prototype.isStanfordType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'stanford'; -}; -ChartInternal.prototype.isPieType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'pie'; -}; -ChartInternal.prototype.isGaugeType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'gauge'; -}; -ChartInternal.prototype.isDonutType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'donut'; -}; -ChartInternal.prototype.isArcType = function (d) { - return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d); -}; -ChartInternal.prototype.lineData = function (d) { - return this.isLineType(d) ? [d] : []; -}; -ChartInternal.prototype.arcData = function (d) { - return this.isArcType(d.data) ? [d] : []; + } else if (Object.keys(types).length) { + Object.keys(types).forEach(function(id) { + if (types[id] === type) { + has = true; + } + }); + } else { + has = $$.config.data_type === type; + } + return has +}; +ChartInternal.prototype.hasArcType = function(targets) { + return ( + this.hasType('pie', targets) || + this.hasType('donut', targets) || + this.hasType('gauge', targets) + ) +}; +ChartInternal.prototype.isLineType = function(d) { + var config = this.config, + id = isString(d) ? d : d.id; + return ( + !config.data_types[id] || + ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf( + config.data_types[id] + ) >= 0 + ) +}; +ChartInternal.prototype.isStepType = function(d) { + var id = isString(d) ? d : d.id; + return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0 +}; +ChartInternal.prototype.isSplineType = function(d) { + var id = isString(d) ? d : d.id; + return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0 +}; +ChartInternal.prototype.isAreaType = function(d) { + var id = isString(d) ? d : d.id; + return ( + ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= + 0 + ) +}; +ChartInternal.prototype.isBarType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'bar' +}; +ChartInternal.prototype.isScatterType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'scatter' +}; +ChartInternal.prototype.isStanfordType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'stanford' +}; +ChartInternal.prototype.isPieType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'pie' +}; +ChartInternal.prototype.isGaugeType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'gauge' +}; +ChartInternal.prototype.isDonutType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'donut' +}; +ChartInternal.prototype.isArcType = function(d) { + return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d) +}; +ChartInternal.prototype.lineData = function(d) { + return this.isLineType(d) ? [d] : [] +}; +ChartInternal.prototype.arcData = function(d) { + return this.isArcType(d.data) ? [d] : [] }; /* not used function scatterData(d) { return isScatterType(d) ? d.values : []; } */ -ChartInternal.prototype.barData = function (d) { - return this.isBarType(d) ? d.values : []; -}; -ChartInternal.prototype.lineOrScatterOrStanfordData = function (d) { - return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d) ? d.values : []; -}; -ChartInternal.prototype.barOrLineData = function (d) { - return this.isBarType(d) || this.isLineType(d) ? d.values : []; -}; - -ChartInternal.prototype.isSafari = function () { - var ua = window.navigator.userAgent; - return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0; -}; -ChartInternal.prototype.isChrome = function () { - var ua = window.navigator.userAgent; - return ua.indexOf('Chrome') >= 0; -}; - -ChartInternal.prototype.initZoom = function () { - var $$ = this, d3 = $$.d3, config = $$.config, startEvent; - - $$.zoom = d3.zoom() - .on("start", function () { - if (config.zoom_type !== 'scroll') { - return; - } - - var e = d3.event.sourceEvent; - if (e && e.type === "brush") { return; } - startEvent = e; - config.zoom_onzoomstart.call($$.api, e); - }) - .on("zoom", function () { - if (config.zoom_type !== 'scroll') { - return; - } - - var e = d3.event.sourceEvent; - if (e && e.type === "brush") { return; } - - $$.redrawForZoom(); - - config.zoom_onzoom.call($$.api, $$.x.orgDomain()); - }) - .on('end', function () { - if (config.zoom_type !== 'scroll') { - return; - } - - var e = d3.event.sourceEvent; - if (e && e.type === "brush") { return; } - // if click, do nothing. otherwise, click interaction will be canceled. - if (e && startEvent.clientX === e.clientX && startEvent.clientY === e.clientY) { - return; - } - config.zoom_onzoomend.call($$.api, $$.x.orgDomain()); - }); - - $$.zoom.updateDomain = function () { - if (d3.event && d3.event.transform) { - $$.x.domain(d3.event.transform.rescaleX($$.subX).domain()); - } - return this; - }; - $$.zoom.updateExtent = function () { - this.scaleExtent([1, Infinity]) - .translateExtent([[0, 0], [$$.width, $$.height]]) - .extent([[0, 0], [$$.width, $$.height]]); - return this; - }; - $$.zoom.update = function () { - return this.updateExtent().updateDomain(); - }; - - return $$.zoom.updateExtent(); -}; -ChartInternal.prototype.zoomTransform = function (range) { - var $$ = this, s = [$$.x(range[0]), $$.x(range[1])]; - return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0); -}; - -ChartInternal.prototype.initDragZoom = function () { - const $$ = this; - const d3 = $$.d3; - const config = $$.config; - const context = $$.context = $$.svg; - const brushXPos = $$.margin.left + 20.5; - const brushYPos = $$.margin.top + 0.5; - - if (!(config.zoom_type === 'drag' && config.zoom_enabled)) { - return; - } - - const getZoomedDomain = selection => selection && selection.map(x => $$.x.invert(x)); - - const brush = $$.dragZoomBrush = d3.brushX() - .on("start", () => { - $$.api.unzoom(); - - $$.svg - .select("." + CLASS.dragZoom) - .classed("disabled", false); - - config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); - }) - .on("brush", () => { - config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection)); - }) - .on("end", () => { - if (d3.event.selection == null) { - return; - } - - const zoomedDomain = getZoomedDomain(d3.event.selection); - - if (!config.zoom_disableDefaultBehavior) { - $$.api.zoom(zoomedDomain); - } - - $$.svg - .select("." + CLASS.dragZoom) - .classed("disabled", true); - - config.zoom_onzoomend.call($$.api, zoomedDomain); - }); +ChartInternal.prototype.barData = function(d) { + return this.isBarType(d) ? d.values : [] +}; +ChartInternal.prototype.lineOrScatterOrStanfordData = function(d) { + return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d) + ? d.values + : [] +}; +ChartInternal.prototype.barOrLineData = function(d) { + return this.isBarType(d) || this.isLineType(d) ? d.values : [] +}; + +ChartInternal.prototype.isSafari = function() { + var ua = window.navigator.userAgent; + return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0 +}; +ChartInternal.prototype.isChrome = function() { + var ua = window.navigator.userAgent; + return ua.indexOf('Chrome') >= 0 +}; + +ChartInternal.prototype.initZoom = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + startEvent; + + $$.zoom = d3 + .zoom() + .on('start', function() { + if (config.zoom_type !== 'scroll') { + return + } + + var e = d3.event.sourceEvent; + if (e && e.type === 'brush') { + return + } + startEvent = e; + config.zoom_onzoomstart.call($$.api, e); + }) + .on('zoom', function() { + if (config.zoom_type !== 'scroll') { + return + } + + var e = d3.event.sourceEvent; + if (e && e.type === 'brush') { + return + } + + $$.redrawForZoom(); + + config.zoom_onzoom.call($$.api, $$.x.orgDomain()); + }) + .on('end', function() { + if (config.zoom_type !== 'scroll') { + return + } + + var e = d3.event.sourceEvent; + if (e && e.type === 'brush') { + return + } + // if click, do nothing. otherwise, click interaction will be canceled. + if ( + e && + startEvent.clientX === e.clientX && + startEvent.clientY === e.clientY + ) { + return + } + config.zoom_onzoomend.call($$.api, $$.x.orgDomain()); + }); - context - .append("g") - .classed(CLASS.dragZoom, true) - .attr("clip-path", $$.clipPath) - .attr("transform", "translate(" + brushXPos + "," + brushYPos + ")") - .call(brush); -}; + $$.zoom.updateDomain = function() { + if (d3.event && d3.event.transform) { + $$.x.domain(d3.event.transform.rescaleX($$.subX).domain()); + } + return this + }; + $$.zoom.updateExtent = function() { + this.scaleExtent([1, Infinity]) + .translateExtent([ + [0, 0], + [$$.width, $$.height] + ]) + .extent([ + [0, 0], + [$$.width, $$.height] + ]); + return this + }; + $$.zoom.update = function() { + return this.updateExtent().updateDomain() + }; + + return $$.zoom.updateExtent() +}; +ChartInternal.prototype.zoomTransform = function(range) { + var $$ = this, + s = [$$.x(range[0]), $$.x(range[1])]; + return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0) +}; + +ChartInternal.prototype.initDragZoom = function() { + const $$ = this; + const d3 = $$.d3; + const config = $$.config; + const context = ($$.context = $$.svg); + const brushXPos = $$.margin.left + 20.5; + const brushYPos = $$.margin.top + 0.5; + + if (!(config.zoom_type === 'drag' && config.zoom_enabled)) { + return + } -ChartInternal.prototype.getZoomDomain = function () { - var $$ = this, config = $$.config, d3 = $$.d3, - min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), - max = d3.max([$$.orgXDomain[1], config.zoom_x_max]); - return [min, max]; -}; -ChartInternal.prototype.redrawForZoom = function () { - var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x; - if (!config.zoom_enabled) { - return; - } - if ($$.filterTargetsToShow($$.data.targets).length === 0) { - return; - } + const getZoomedDomain = selection => + selection && selection.map(x => $$.x.invert(x)); + + const brush = ($$.dragZoomBrush = d3 + .brushX() + .on('start', () => { + $$.api.unzoom(); + + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false); + + config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); + }) + .on('brush', () => { + config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection)); + }) + .on('end', () => { + if (d3.event.selection == null) { + return + } + + const zoomedDomain = getZoomedDomain(d3.event.selection); + + if (!config.zoom_disableDefaultBehavior) { + $$.api.zoom(zoomedDomain); + } + + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true); + + config.zoom_onzoomend.call($$.api, zoomedDomain); + })); + + context + .append('g') + .classed(CLASS.dragZoom, true) + .attr('clip-path', $$.clipPath) + .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')') + .call(brush); +}; + +ChartInternal.prototype.getZoomDomain = function() { + var $$ = this, + config = $$.config, + d3 = $$.d3, + min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), + max = d3.max([$$.orgXDomain[1], config.zoom_x_max]); + return [min, max] +}; +ChartInternal.prototype.redrawForZoom = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + zoom = $$.zoom, + x = $$.x; + if (!config.zoom_enabled) { + return + } + if ($$.filterTargetsToShow($$.data.targets).length === 0) { + return + } - zoom.update(); + zoom.update(); - if (config.zoom_disableDefaultBehavior) { - return; - } + if (config.zoom_disableDefaultBehavior) { + return + } - if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) { - x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]); - } + if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) { + x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]); + } - $$.redraw({ - withTransition: false, - withY: config.zoom_rescale, - withSubchart: false, - withEventRect: false, - withDimension: false - }); + $$.redraw({ + withTransition: false, + withY: config.zoom_rescale, + withSubchart: false, + withEventRect: false, + withDimension: false + }); - if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') { - $$.cancelClick = true; - } + if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') { + $$.cancelClick = true; + } }; export default c3; diff --git a/c3.js b/c3.js index 5684f9d9c..d536ea849 100644 --- a/c3.js +++ b/c3.js @@ -1,4 +1,4 @@ -/* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */ +/* @license C3.js v0.7.16 | (c) C3 Team and other contributors | http://c3js.org/ */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : @@ -6,6 +6,8 @@ }(this, (function () { 'use strict'; function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; @@ -41,23 +43,36 @@ } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ChartInternal(api) { @@ -66,7 +81,7 @@ // TODO: Maybe we should check that the modification by rollup-plugin-modify // is valid during unit tests. - $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined; + $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require('d3') : undefined; $$.api = api; $$.config = $$.getDefaultConfig(); $$.data = {}; @@ -85,7 +100,8 @@ this.internal.loadConfig(config); this.internal.beforeInit(config); this.internal.init(); - this.internal.afterInit(config); // bind "this" to nested API + this.internal.afterInit(config) // bind "this" to nested API + ; (function bindThis(fn, target, argThis) { Object.keys(fn).forEach(function (key) { @@ -249,7 +265,7 @@ internal.d3 = component.d3; internal.scale = internal.d3.scaleLinear(); internal.range; - internal.orient = "bottom"; + internal.orient = 'bottom'; internal.innerTickSize = 6; internal.outerTickSize = this.params.withOuterTick ? 6 : 0; internal.tickPadding = 3; @@ -266,14 +282,14 @@ } AxisInternal.prototype.axisX = function (selection, x, tickOffset) { - selection.attr("transform", function (d) { - return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)"; + selection.attr('transform', function (d) { + return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)'; }); }; AxisInternal.prototype.axisY = function (selection, y) { - selection.attr("transform", function (d) { - return "translate(0," + Math.ceil(y(d)) + ")"; + selection.attr('transform', function (d) { + return 'translate(0,' + Math.ceil(y(d)) + ')'; }); }; @@ -389,7 +405,7 @@ textWidth, splitted = []; - if (Object.prototype.toString.call(tickText) === "[object Array]") { + if (Object.prototype.toString.call(tickText) === '[object Array]') { return tickText; } @@ -416,7 +432,7 @@ return splitted.concat(text); } - return split(splitted, tickText + ""); + return split(splitted, tickText + ''); }; AxisInternal.prototype.ellipsify = function (splitted, max) { @@ -460,13 +476,13 @@ AxisInternal.prototype.textTransform = function () { var internal = this, rotate = internal.tickTextRotate; - return rotate ? "rotate(" + rotate + ")" : ""; + return rotate ? 'rotate(' + rotate + ')' : ''; }; AxisInternal.prototype.textTextAnchor = function () { var internal = this, rotate = internal.tickTextRotate; - return rotate ? rotate > 0 ? "start" : "end" : "middle"; + return rotate ? rotate > 0 ? 'start' : 'end' : 'middle'; }; AxisInternal.prototype.tspanDx = function () { @@ -483,7 +499,7 @@ if (internal.isVertical()) { dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); } else { - dy = ".71em"; + dy = '.71em'; } } @@ -502,8 +518,8 @@ var scale0 = this.__chart__ || internal.scale, scale1 = this.__chart__ = internal.copyScale(); var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1), - ticks = g.selectAll(".tick").data(ticksValues, scale1), - tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), + ticks = g.selectAll('.tick').data(ticksValues, scale1), + tickEnter = ticks.enter().insert('g', '.domain').attr('class', 'tick').style('opacity', 1e-6), // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. tickExit = ticks.exit().remove(), tickUpdate = ticks.merge(tickEnter), @@ -522,8 +538,8 @@ internal.updateRange(); internal.updateTickLength(); internal.updateTickTextCharSize(g.select('.tick')); - var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")), - textUpdate = tickUpdate.select("text").merge(tickEnter.append("text")); + var lineUpdate = tickUpdate.select('line').merge(tickEnter.append('line')), + textUpdate = tickUpdate.select('text').merge(tickEnter.append('text')); var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) { return internal.tspanData(d, i, scale1); }), @@ -532,76 +548,76 @@ return d.splitted; }); tspans.exit().remove(); - var path = g.selectAll(".domain").data([0]), - pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); // TODO: each attr should be one function and change its behavior by internal.orient, probably + var path = g.selectAll('.domain').data([0]), + pathUpdate = path.enter().append('path').merge(path).attr('class', 'domain'); // TODO: each attr should be one function and change its behavior by internal.orient, probably switch (internal.orient) { - case "bottom": + case 'bottom': { tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) { + lineUpdate.attr('x1', tickX).attr('x2', tickX).attr('y2', function (d, i) { return internal.lineY2(d, i); }); - textUpdate.attr("x", 0).attr("y", function (d, i) { + textUpdate.attr('x', 0).attr('y', function (d, i) { return internal.textY(d, i); - }).attr("transform", function (d, i) { + }).attr('transform', function (d, i) { return internal.textTransform(d, i); - }).style("text-anchor", function (d, i) { + }).style('text-anchor', function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0).attr("dy", function (d, i) { + tspanUpdate.attr('x', 0).attr('dy', function (d, i) { return internal.tspanDy(d, i); }).attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize); + pathUpdate.attr('d', 'M' + internal.range[0] + ',' + internal.outerTickSize + 'V0H' + internal.range[1] + 'V' + internal.outerTickSize); break; } - case "top": + case 'top': { // TODO: rotated tick text tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) { + lineUpdate.attr('x1', tickX).attr('x2', tickX).attr('y2', function (d, i) { return -1 * internal.lineY2(d, i); }); - textUpdate.attr("x", 0).attr("y", function (d, i) { + textUpdate.attr('x', 0).attr('y', function (d, i) { return -1 * internal.textY(d, i) - (params.isCategory ? 2 : internal.tickLength - 2); - }).attr("transform", function (d, i) { + }).attr('transform', function (d, i) { return internal.textTransform(d, i); - }).style("text-anchor", function (d, i) { + }).style('text-anchor', function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0).attr("dy", function (d, i) { + tspanUpdate.attr('x', 0).attr('dy', function (d, i) { return internal.tspanDy(d, i); }).attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize); + pathUpdate.attr('d', 'M' + internal.range[0] + ',' + -internal.outerTickSize + 'V0H' + internal.range[1] + 'V' + -internal.outerTickSize); break; } - case "left": + case 'left': { tickTransform = internal.axisY; - lineUpdate.attr("x2", -internal.innerTickSize).attr("y1", tickY).attr("y2", tickY); - textUpdate.attr("x", -internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "end"); - tspanUpdate.attr('x', -internal.tickLength).attr("dy", function (d, i) { + lineUpdate.attr('x2', -internal.innerTickSize).attr('y1', tickY).attr('y2', tickY); + textUpdate.attr('x', -internal.tickLength).attr('y', internal.tickOffset).style('text-anchor', 'end'); + tspanUpdate.attr('x', -internal.tickLength).attr('dy', function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize); + pathUpdate.attr('d', 'M' + -internal.outerTickSize + ',' + internal.range[0] + 'H0V' + internal.range[1] + 'H' + -internal.outerTickSize); break; } - case "right": + case 'right': { tickTransform = internal.axisY; - lineUpdate.attr("x2", internal.innerTickSize).attr("y1", tickY).attr("y2", tickY); - textUpdate.attr("x", internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "start"); - tspanUpdate.attr('x', internal.tickLength).attr("dy", function (d, i) { + lineUpdate.attr('x2', internal.innerTickSize).attr('y1', tickY).attr('y2', tickY); + textUpdate.attr('x', internal.tickLength).attr('y', internal.tickOffset).style('text-anchor', 'start'); + tspanUpdate.attr('x', internal.tickLength).attr('dy', function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize); + pathUpdate.attr('d', 'M' + internal.outerTickSize + ',' + internal.range[0] + 'H0V' + internal.range[1] + 'H' + internal.outerTickSize); break; } } @@ -644,7 +660,7 @@ right: 1, bottom: 1, left: 1 - } ? x + "" : "bottom"; + } ? x + '' : 'bottom'; return axis; }; @@ -820,13 +836,13 @@ var $$ = this.owner, config = $$.config, main = $$.main; - $$.axes.x = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisX).attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis).attr("transform", $$.getTranslate('x')).style("visibility", config.axis_x_show ? 'visible' : 'hidden'); - $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this)); - $$.axes.y = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY).attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis).attr("transform", $$.getTranslate('y')).style("visibility", config.axis_y_show ? 'visible' : 'hidden'); - $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this)); - $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2) // clip-path? - .attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden'); - $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this)); + $$.axes.x = main.append('g').attr('class', CLASS.axis + ' ' + CLASS.axisX).attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis).attr('transform', $$.getTranslate('x')).style('visibility', config.axis_x_show ? 'visible' : 'hidden'); + $$.axes.x.append('text').attr('class', CLASS.axisXLabel).attr('transform', config.axis_rotated ? 'rotate(-90)' : '').style('text-anchor', this.textAnchorForXAxisLabel.bind(this)); + $$.axes.y = main.append('g').attr('class', CLASS.axis + ' ' + CLASS.axisY).attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis).attr('transform', $$.getTranslate('y')).style('visibility', config.axis_y_show ? 'visible' : 'hidden'); + $$.axes.y.append('text').attr('class', CLASS.axisYLabel).attr('transform', config.axis_rotated ? '' : 'rotate(-90)').style('text-anchor', this.textAnchorForYAxisLabel.bind(this)); + $$.axes.y2 = main.append('g').attr('class', CLASS.axis + ' ' + CLASS.axisY2) // clip-path? + .attr('transform', $$.getTranslate('y2')).style('visibility', config.axis_y2_show ? 'visible' : 'hidden'); + $$.axes.y2.append('text').attr('class', CLASS.axisY2Label).attr('transform', config.axis_rotated ? '' : 'rotate(-90)').style('text-anchor', this.textAnchorForY2AxisLabel.bind(this)); }; Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { @@ -843,7 +859,7 @@ }, axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); - if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") { + if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') { tickValues = tickValues.map(function (v) { return $$.parseDate(v); }); @@ -931,7 +947,7 @@ format = config.axis_x_tick_format; } else if ($$.isTimeSeries()) { format = function format(date) { - return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ""; + return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ''; }; } } @@ -1051,9 +1067,9 @@ Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) { if (forHorizontal) { - return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0"; + return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0'; } else { - return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0"; + return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0'; } }; @@ -1095,9 +1111,9 @@ position = this.getXAxisLabelPosition(); if (config.axis_rotated) { - return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); + return position.isInner ? '1.2em' : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); } else { - return position.isInner ? "-0.5em" : $$.getHorizontalAxisHeight('x') - 10; + return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10; } }; @@ -1106,9 +1122,9 @@ position = this.getYAxisLabelPosition(); if ($$.config.axis_rotated) { - return position.isInner ? "-0.5em" : "3em"; + return position.isInner ? '-0.5em' : '3em'; } else { - return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10); + return position.isInner ? '1.2em' : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10); } }; @@ -1117,9 +1133,9 @@ position = this.getY2AxisLabelPosition(); if ($$.config.axis_rotated) { - return position.isInner ? "1.2em" : "-2.2em"; + return position.isInner ? '1.2em' : '-2.2em'; } else { - return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15); + return position.isInner ? '-0.5em' : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15); } }; @@ -1167,7 +1183,7 @@ } dummy = $$.d3.select('body').append('div').classed('c3', true); - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () { + svg = dummy.append('svg').style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () { $$.d3.select(this).selectAll('text').each(function () { var box = getBBox(this); @@ -1188,9 +1204,9 @@ var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label); - (withTransition ? axisXLabel.transition() : axisXLabel).attr("x", this.xForXAxisLabel.bind(this)).attr("dx", this.dxForXAxisLabel.bind(this)).attr("dy", this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this)); - (withTransition ? axisYLabel.transition() : axisYLabel).attr("x", this.xForYAxisLabel.bind(this)).attr("dx", this.dxForYAxisLabel.bind(this)).attr("dy", this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this)); - (withTransition ? axisY2Label.transition() : axisY2Label).attr("x", this.xForY2AxisLabel.bind(this)).attr("dx", this.dxForY2AxisLabel.bind(this)).attr("dy", this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this)); + (withTransition ? axisXLabel.transition() : axisXLabel).attr('x', this.xForXAxisLabel.bind(this)).attr('dx', this.dxForXAxisLabel.bind(this)).attr('dy', this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this)); + (withTransition ? axisYLabel.transition() : axisYLabel).attr('x', this.xForYAxisLabel.bind(this)).attr('dx', this.dxForYAxisLabel.bind(this)).attr('dy', this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this)); + (withTransition ? axisY2Label.transition() : axisY2Label).attr('x', this.xForY2AxisLabel.bind(this)).attr('dx', this.dxForY2AxisLabel.bind(this)).attr('dy', this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this)); }; Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) { @@ -1271,14 +1287,14 @@ Axis.prototype.redraw = function redraw(duration, isHidden) { var $$ = this.owner, transition = duration ? $$.d3.transition().duration(duration) : null; - $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition); - $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition); - $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition); - $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition); + $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition); + $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition); + $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition); + $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition); }; var c3 = { - version: "0.7.15", + version: '0.7.16', chart: { fn: Chart.prototype, internal: { @@ -1325,7 +1341,7 @@ d3 = $$.d3, config = $$.config; // MEMO: clipId needs to be unique because it conflicts when multiple charts exist - $$.clipId = "c3-" + +new Date() + '-clip'; + $$.clipId = 'c3-' + new Date().valueOf() + '-clip'; $$.clipIdForXAxis = $$.clipId + '-xaxis'; $$.clipIdForYAxis = $$.clipId + '-yaxis'; $$.clipIdForGrid = $$.clipId + '-grid'; @@ -1348,44 +1364,44 @@ $$.defaultAxisTimeFormat = function (date) { if (date.getMilliseconds()) { - return d3.timeFormat(".%L")(date); + return d3.timeFormat('.%L')(date); } if (date.getSeconds()) { - return d3.timeFormat(":%S")(date); + return d3.timeFormat(':%S')(date); } if (date.getMinutes()) { - return d3.timeFormat("%I:%M")(date); + return d3.timeFormat('%I:%M')(date); } if (date.getHours()) { - return d3.timeFormat("%I %p")(date); + return d3.timeFormat('%I %p')(date); } if (date.getDay() && date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); + return d3.timeFormat('%-m/%-d')(date); } if (date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); + return d3.timeFormat('%-m/%-d')(date); } if (date.getMonth()) { - return d3.timeFormat("%-m/%-d")(date); + return d3.timeFormat('%-m/%-d')(date); } - return d3.timeFormat("%Y/%-m/%-d")(date); + return d3.timeFormat('%Y/%-m/%-d')(date); }; $$.hiddenTargetIds = []; $$.hiddenLegendIds = []; $$.focusedTargetIds = []; $$.defocusedTargetIds = []; - $$.xOrient = config.axis_rotated ? config.axis_x_inner ? "right" : "left" : config.axis_x_inner ? "top" : "bottom"; - $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left"; - $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right"; - $$.subXOrient = config.axis_rotated ? "left" : "bottom"; + $$.xOrient = config.axis_rotated ? config.axis_x_inner ? 'right' : 'left' : config.axis_x_inner ? 'top' : 'bottom'; + $$.yOrient = config.axis_rotated ? config.axis_y_inner ? 'top' : 'bottom' : config.axis_y_inner ? 'right' : 'left'; + $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? 'bottom' : 'top' : config.axis_y2_inner ? 'left' : 'right'; + $$.subXOrient = config.axis_rotated ? 'left' : 'bottom'; $$.isLegendRight = config.legend_position === 'right'; $$.isLegendInset = config.legend_position === 'inset'; $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right'; @@ -1451,7 +1467,7 @@ binding = false; } - $$.selectChart.html("").classed("c3", true); // Init data as targets + $$.selectChart.html('').classed('c3', true); // Init data as targets $$.data.xs = {}; $$.data.targets = $$.convertDataToTargets(data); @@ -1488,7 +1504,7 @@ /*-- Basic Elements --*/ // Define svgs - $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () { + $$.svg = $$.selectChart.append('svg').style('overflow', 'hidden').on('mouseenter', function () { return config.onmouseover.call($$); }).on('mouseleave', function () { return config.onmouseout.call($$); @@ -1499,7 +1515,7 @@ } // Define defs - defs = $$.svg.append("defs"); + defs = $$.svg.append('defs'); $$.clipChart = $$.appendClip(defs, $$.clipId); $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); @@ -1507,7 +1523,7 @@ $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); $$.updateSvgSize(); // Define regions - main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main')); + main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main')); if ($$.initPie) { $$.initPie(); @@ -1550,15 +1566,15 @@ // text when empty - main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers. - .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE. + main.append('text').attr('class', CLASS.text + ' ' + CLASS.empty).attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers. + .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE. // Regions $$.initRegion(); // Grids $$.initGrid(); // Define g for chart area - main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart); // Grid lines + main.append('g').attr('clip-path', $$.clipPath).attr('class', CLASS.chart); // Grid lines if (config.grid_lines_front) { $$.initGridLines(); @@ -1610,10 +1626,10 @@ y1 = g.attr('y1'), y2 = g.attr('y2'); g.attr({ - 'x1': Math.ceil(x1), - 'x2': Math.ceil(x2), - 'y1': Math.ceil(y1), - 'y2': Math.ceil(y2) + x1: Math.ceil(x1), + x2: Math.ceil(x2), + y1: Math.ceil(y1), + y2: Math.ceil(y2) }); }); } @@ -1736,7 +1752,7 @@ var $$ = this; $$.svg.selectAll('.' + CLASS.target).filter(function (d) { return $$.isTargetToShow(d.id); - }).transition().duration($$.config.transition_duration).style("opacity", 1); + }).transition().duration($$.config.transition_duration).style('opacity', 1); }; ChartInternal.prototype.redraw = function (options, transitions) { @@ -1761,19 +1777,19 @@ cx, cy; options = options || {}; - withY = getOption(options, "withY", true); - withSubchart = getOption(options, "withSubchart", true); - withTransition = getOption(options, "withTransition", true); - withTransform = getOption(options, "withTransform", false); - withUpdateXDomain = getOption(options, "withUpdateXDomain", false); - withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false); - withTrimXDomain = getOption(options, "withTrimXDomain", true); - withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain); - withLegend = getOption(options, "withLegend", false); - withEventRect = getOption(options, "withEventRect", true); - withDimension = getOption(options, "withDimension", true); - withTransitionForExit = getOption(options, "withTransitionForExit", withTransition); - withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition); + withY = getOption(options, 'withY', true); + withSubchart = getOption(options, 'withSubchart', true); + withTransition = getOption(options, 'withTransition', true); + withTransform = getOption(options, 'withTransform', false); + withUpdateXDomain = getOption(options, 'withUpdateXDomain', false); + withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false); + withTrimXDomain = getOption(options, 'withTrimXDomain', true); + withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain); + withLegend = getOption(options, 'withLegend', false); + withEventRect = getOption(options, 'withEventRect', true); + withDimension = getOption(options, 'withDimension', true); + withTransitionForExit = getOption(options, 'withTransitionForExit', withTransition); + withTransitionForAxis = getOption(options, 'withTransitionForAxis', withTransition); duration = withTransition ? config.transition_duration : 0; durationForExit = withTransitionForExit ? duration : 0; durationForAxis = withTransitionForAxis ? duration : 0; @@ -1864,7 +1880,7 @@ $$.updateXgridFocus(); // Data empty label positioning and text. - main.select("text." + CLASS.text + '.' + CLASS.empty).attr("x", $$.width / 2).attr("y", $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); // event rect + main.select('text.' + CLASS.text + '.' + CLASS.empty).attr('x', $$.width / 2).attr('y', $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); // event rect if (withEventRect) { $$.redrawEventRect(); @@ -1978,14 +1994,14 @@ transitions; options = options || {}; // same with redraw - options.withTransition = getOption(options, "withTransition", true); - options.withTransform = getOption(options, "withTransform", false); - options.withLegend = getOption(options, "withLegend", false); // NOT same with redraw + options.withTransition = getOption(options, 'withTransition', true); + options.withTransform = getOption(options, 'withTransform', false); + options.withLegend = getOption(options, 'withLegend', false); // NOT same with redraw - options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true); - options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true); + options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true); + options.withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', true); options.withTransitionForExit = false; - options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) + options.withTransitionForTransform = getOption(options, 'withTransitionForTransform', options.withTransition); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) $$.updateSizes(); // MEMO: called in updateLegend in redraw if withLegend @@ -2061,7 +2077,7 @@ y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label } - return "translate(" + x + "," + y + ")"; + return 'translate(' + x + ',' + y + ')'; }; ChartInternal.prototype.initialOpacity = function (d) { @@ -2164,12 +2180,11 @@ y2Axis = y2Axis.transition(); } } - - (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main')); - xAxis.attr("transform", $$.getTranslate('x')); - yAxis.attr("transform", $$.getTranslate('y')); - y2Axis.attr("transform", $$.getTranslate('y2')); - $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); + (withTransition ? $$.main.transition() : $$.main).attr('transform', $$.getTranslate('main')); + xAxis.attr('transform', $$.getTranslate('x')); + yAxis.attr('transform', $$.getTranslate('y')); + y2Axis.attr('transform', $$.getTranslate('y2')); + $$.main.select('.' + CLASS.chartArcs).attr('transform', $$.getTranslate('arc')); }; ChartInternal.prototype.transformAll = function (withTransition, transitions) { @@ -2194,7 +2209,7 @@ $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$)); $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() && brush.attr('height') || 0); // MEMO: parent div's height will be bigger than svg when - $$.selectChart.style('max-height', $$.currentHeight + "px"); + $$.selectChart.style('max-height', $$.currentHeight + 'px'); }; ChartInternal.prototype.updateDimension = function (withoutAxis) { @@ -2221,7 +2236,7 @@ observer; if (typeof MutationObserver === 'undefined') { - window.console.error("MutationObserver not defined."); + window.console.error('MutationObserver not defined.'); return; } @@ -2399,7 +2414,7 @@ var n = 0; transition.each(function () { ++n; - }).on("end", function () { + }).on('end', function () { if (! --n) { callback.apply(this, arguments); } @@ -2476,15 +2491,10 @@ ChartInternal.prototype.CLASS = CLASS; /* jshint ignore:start */ - // SVGPathSeg API polyfill - // https://github.com/progers/pathseg - // - // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from - // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec - // changes which were implemented in Firefox 43 and Chrome 46. + (function () { - if (!("SVGPathSeg" in window)) { + if (!('SVGPathSeg' in window)) { // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) { this.pathSegType = type; @@ -2492,7 +2502,7 @@ this._owningPathSegList = owningPathSegList; }; - window.SVGPathSeg.prototype.classname = "SVGPathSeg"; + window.SVGPathSeg.prototype.classname = 'SVGPathSeg'; window.SVGPathSeg.PATHSEG_UNKNOWN = 0; window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; @@ -2519,13 +2529,13 @@ }; window.SVGPathSegClosePath = function (owningPathSegList) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, 'z', owningPathSegList); }; window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegClosePath.prototype.toString = function () { - return "[object SVGPathSegClosePath]"; + return '[object SVGPathSegClosePath]'; }; window.SVGPathSegClosePath.prototype._asPathString = function () { @@ -2537,7 +2547,7 @@ }; window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, 'M', owningPathSegList); this._x = x; this._y = y; }; @@ -2545,18 +2555,18 @@ window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegMovetoAbs.prototype.toString = function () { - return "[object SVGPathSegMovetoAbs]"; + return '[object SVGPathSegMovetoAbs]'; }; window.SVGPathSegMovetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegMovetoAbs.prototype.clone = function () { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2567,7 +2577,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2580,7 +2590,7 @@ }); window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, 'm', owningPathSegList); this._x = x; this._y = y; }; @@ -2588,18 +2598,18 @@ window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegMovetoRel.prototype.toString = function () { - return "[object SVGPathSegMovetoRel]"; + return '[object SVGPathSegMovetoRel]'; }; window.SVGPathSegMovetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegMovetoRel.prototype.clone = function () { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2610,7 +2620,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', { get: function get() { return this._y; }, @@ -2623,7 +2633,7 @@ }); window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, 'L', owningPathSegList); this._x = x; this._y = y; }; @@ -2631,18 +2641,18 @@ window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoAbs]"; + return '[object SVGPathSegLinetoAbs]'; }; window.SVGPathSegLinetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegLinetoAbs.prototype.clone = function () { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2653,7 +2663,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2666,7 +2676,7 @@ }); window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, 'l', owningPathSegList); this._x = x; this._y = y; }; @@ -2674,18 +2684,18 @@ window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoRel.prototype.toString = function () { - return "[object SVGPathSegLinetoRel]"; + return '[object SVGPathSegLinetoRel]'; }; window.SVGPathSegLinetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegLinetoRel.prototype.clone = function () { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2696,7 +2706,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', { get: function get() { return this._y; }, @@ -2709,7 +2719,7 @@ }); window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, 'C', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2721,18 +2731,18 @@ window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicAbs]"; + return '[object SVGPathSegCurvetoCubicAbs]'; }; window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2743,7 +2753,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2754,7 +2764,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', { get: function get() { return this._x1; }, @@ -2765,7 +2775,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', { get: function get() { return this._y1; }, @@ -2776,7 +2786,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', { get: function get() { return this._x2; }, @@ -2787,7 +2797,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', { get: function get() { return this._y2; }, @@ -2800,7 +2810,7 @@ }); window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, 'c', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2812,18 +2822,18 @@ window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicRel]"; + return '[object SVGPathSegCurvetoCubicRel]'; }; window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2834,7 +2844,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', { get: function get() { return this._y; }, @@ -2845,7 +2855,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', { get: function get() { return this._x1; }, @@ -2856,7 +2866,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', { get: function get() { return this._y1; }, @@ -2867,7 +2877,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', { get: function get() { return this._x2; }, @@ -2878,7 +2888,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', { get: function get() { return this._y2; }, @@ -2891,7 +2901,7 @@ }); window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, 'Q', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2901,18 +2911,18 @@ window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticAbs]"; + return '[object SVGPathSegCurvetoQuadraticAbs]'; }; window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2923,7 +2933,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2934,7 +2944,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x1', { get: function get() { return this._x1; }, @@ -2945,7 +2955,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y1', { get: function get() { return this._y1; }, @@ -2958,7 +2968,7 @@ }); window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, 'q', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2968,18 +2978,18 @@ window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticRel]"; + return '[object SVGPathSegCurvetoQuadraticRel]'; }; window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2990,7 +3000,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3001,7 +3011,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x1', { get: function get() { return this._x1; }, @@ -3012,7 +3022,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y1', { get: function get() { return this._y1; }, @@ -3025,7 +3035,7 @@ }); window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, 'A', owningPathSegList); this._x = x; this._y = y; this._r1 = r1; @@ -3038,18 +3048,18 @@ window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegArcAbs.prototype.toString = function () { - return "[object SVGPathSegArcAbs]"; + return '[object SVGPathSegArcAbs]'; }; window.SVGPathSegArcAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegArcAbs.prototype.clone = function () { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }; - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3060,7 +3070,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3071,7 +3081,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', { get: function get() { return this._r1; }, @@ -3082,7 +3092,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', { get: function get() { return this._r2; }, @@ -3093,7 +3103,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', { get: function get() { return this._angle; }, @@ -3104,7 +3114,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', { get: function get() { return this._largeArcFlag; }, @@ -3115,7 +3125,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', { get: function get() { return this._sweepFlag; }, @@ -3128,7 +3138,7 @@ }); window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, 'a', owningPathSegList); this._x = x; this._y = y; this._r1 = r1; @@ -3141,18 +3151,18 @@ window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegArcRel.prototype.toString = function () { - return "[object SVGPathSegArcRel]"; + return '[object SVGPathSegArcRel]'; }; window.SVGPathSegArcRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegArcRel.prototype.clone = function () { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }; - Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3163,7 +3173,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3174,7 +3184,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', { get: function get() { return this._r1; }, @@ -3185,7 +3195,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', { get: function get() { return this._r2; }, @@ -3196,7 +3206,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', { get: function get() { return this._angle; }, @@ -3207,7 +3217,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', { get: function get() { return this._largeArcFlag; }, @@ -3218,7 +3228,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', { get: function get() { return this._sweepFlag; }, @@ -3231,25 +3241,25 @@ }); window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, 'H', owningPathSegList); this._x = x; }; window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalAbs]"; + return '[object SVGPathSegLinetoHorizontalAbs]'; }; window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; + return this.pathSegTypeAsLetter + ' ' + this._x; }; window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3262,25 +3272,25 @@ }); window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, 'h', owningPathSegList); this._x = x; }; window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalRel]"; + return '[object SVGPathSegLinetoHorizontalRel]'; }; window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; + return this.pathSegTypeAsLetter + ' ' + this._x; }; window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3293,25 +3303,25 @@ }); window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, 'V', owningPathSegList); this._y = y; }; window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalAbs]"; + return '[object SVGPathSegLinetoVerticalAbs]'; }; window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._y; }; window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3324,25 +3334,25 @@ }); window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, 'v', owningPathSegList); this._y = y; }; window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalRel]"; + return '[object SVGPathSegLinetoVerticalRel]'; }; window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._y; }; window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3355,7 +3365,7 @@ }); window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, 'S', owningPathSegList); this._x = x; this._y = y; this._x2 = x2; @@ -3365,18 +3375,18 @@ window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothAbs]"; + return '[object SVGPathSegCurvetoCubicSmoothAbs]'; }; window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3387,7 +3397,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3398,7 +3408,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x2', { get: function get() { return this._x2; }, @@ -3409,7 +3419,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y2', { get: function get() { return this._y2; }, @@ -3422,7 +3432,7 @@ }); window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, 's', owningPathSegList); this._x = x; this._y = y; this._x2 = x2; @@ -3432,18 +3442,18 @@ window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothRel]"; + return '[object SVGPathSegCurvetoCubicSmoothRel]'; }; window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3454,7 +3464,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3465,7 +3475,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x2', { get: function get() { return this._x2; }, @@ -3476,7 +3486,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y2', { get: function get() { return this._y2; }, @@ -3489,7 +3499,7 @@ }); window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, 'T', owningPathSegList); this._x = x; this._y = y; }; @@ -3497,18 +3507,18 @@ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; + return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'; }; window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3519,7 +3529,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3532,7 +3542,7 @@ }); window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, 't', owningPathSegList); this._x = x; this._y = y; }; @@ -3540,18 +3550,18 @@ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; + return '[object SVGPathSegCurvetoQuadraticSmoothRel]'; }; window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3562,7 +3572,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3651,14 +3661,14 @@ return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); }; - if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) { + if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) { // Add getPathSegAtLength to SVGPathElement. // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. window.SVGPathElement.prototype.getPathSegAtLength = function (distance) { - if (distance === undefined || !isFinite(distance)) throw "Invalid arguments."; - var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); - measurementElement.setAttribute("d", this.getAttribute("d")); + if (distance === undefined || !isFinite(distance)) throw 'Invalid arguments.'; + var measurementElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + measurementElement.setAttribute('d', this.getAttribute('d')); var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; // If the path is empty, return 0. if (lastPathSegment <= 0) return 0; @@ -3674,23 +3684,23 @@ } } - if (!("SVGPathSegList" in window)) { + if (!('SVGPathSegList' in window)) { // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList window.SVGPathSegList = function (pathElement) { this._pathElement = pathElement; - this._list = this._parsePath(this._pathElement.getAttribute("d")); // Use a MutationObserver to catch changes to the path's "d" attribute. + this._list = this._parsePath(this._pathElement.getAttribute('d')); // Use a MutationObserver to catch changes to the path's "d" attribute. this._mutationObserverConfig = { - "attributes": true, - "attributeFilter": ["d"] + attributes: true, + attributeFilter: ['d'] }; this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this)); this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); }; - window.SVGPathSegList.prototype.classname = "SVGPathSegList"; - Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", { + window.SVGPathSegList.prototype.classname = 'SVGPathSegList'; + Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', { get: function get() { this._checkPathSynchronizedToList(); @@ -3700,7 +3710,7 @@ }); // Add the pathSegList accessors to window.SVGPathElement. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData - Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', { get: function get() { if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this); return this._pathSegList; @@ -3708,19 +3718,19 @@ enumerable: true }); // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. - Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'normalizedPathSegList', { get: function get() { return this.pathSegList; }, enumerable: true }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'animatedPathSegList', { get: function get() { return this.pathSegList; }, enumerable: true }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'animatedNormalizedPathSegList', { get: function get() { return this.pathSegList; }, @@ -3737,16 +3747,16 @@ if (!this._pathElement) return; var hasPathMutations = false; mutationRecords.forEach(function (record) { - if (record.attributeName == "d") hasPathMutations = true; + if (record.attributeName == 'd') hasPathMutations = true; }); - if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d")); + if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute('d')); }; // Serialize the list and update the path's 'd' attribute. window.SVGPathSegList.prototype._writeListToPath = function () { this._pathElementMutationObserver.disconnect(); - this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list)); + this._pathElement.setAttribute('d', window.SVGPathSegList._pathSegArrayAsString(this._list)); this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); }; // When a path segment changes the list needs to be synchronized back to the path element. @@ -3780,7 +3790,7 @@ }; window.SVGPathSegList.prototype._checkValidIndex = function (index) { - if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR"; + if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw 'INDEX_SIZE_ERR'; }; window.SVGPathSegList.prototype.getItem = function (index) { @@ -3861,14 +3871,14 @@ }; window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) { - var string = ""; + var string = ''; var first = true; pathSegArray.forEach(function (pathSeg) { if (first) { first = false; string += pathSeg._asPathString(); } else { - string += " " + pathSeg._asPathString(); + string += ' ' + pathSeg._asPathString(); } }); return string; @@ -3898,7 +3908,7 @@ Source.prototype._isCurrentSpace = function () { var character = this._string[this._currentIndex]; - return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f"); + return character <= ' ' && (character == ' ' || character == '\n' || character == '\t' || character == '\r' || character == '\f'); }; Source.prototype._skipOptionalSpaces = function () { @@ -3910,10 +3920,10 @@ }; Source.prototype._skipOptionalSpacesOrDelimiter = function () { - if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false; + if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ',') return false; if (this._skipOptionalSpaces()) { - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") { + if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ',') { this._currentIndex++; this._skipOptionalSpaces(); @@ -3934,62 +3944,62 @@ Source.prototype._pathSegTypeFromChar = function (lookahead) { switch (lookahead) { - case "Z": - case "z": + case 'Z': + case 'z': return window.SVGPathSeg.PATHSEG_CLOSEPATH; - case "M": + case 'M': return window.SVGPathSeg.PATHSEG_MOVETO_ABS; - case "m": + case 'm': return window.SVGPathSeg.PATHSEG_MOVETO_REL; - case "L": + case 'L': return window.SVGPathSeg.PATHSEG_LINETO_ABS; - case "l": + case 'l': return window.SVGPathSeg.PATHSEG_LINETO_REL; - case "C": + case 'C': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS; - case "c": + case 'c': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL; - case "Q": + case 'Q': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS; - case "q": + case 'q': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL; - case "A": + case 'A': return window.SVGPathSeg.PATHSEG_ARC_ABS; - case "a": + case 'a': return window.SVGPathSeg.PATHSEG_ARC_REL; - case "H": + case 'H': return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS; - case "h": + case 'h': return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL; - case "V": + case 'V': return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS; - case "v": + case 'v': return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL; - case "S": + case 'S': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; - case "s": + case 's': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL; - case "T": + case 'T': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; - case "t": + case 't': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; default: @@ -3999,7 +4009,7 @@ Source.prototype._nextCommandHelper = function (lookahead, previousCommand) { // Check for remaining coordinates in the current command. - if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { + if ((lookahead == '+' || lookahead == '-' || lookahead == '.' || lookahead >= '0' && lookahead <= '9') && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS; if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL; return previousCommand; @@ -4030,16 +4040,16 @@ this._skipOptionalSpaces(); // Read the sign. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") { + if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == '+') this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == '-') { this._currentIndex++; sign = -1; } - if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") // The first character of a number must be one of [0-9+-.]. + if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') && this._string.charAt(this._currentIndex) != '.') // The first character of a number must be one of [0-9+-.]. return undefined; // Read the integer part, build right-to-left. var startIntPartIndex = this._currentIndex; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { + while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') { this._currentIndex++; } // Advance to first non-digit. @@ -4049,41 +4059,41 @@ var multiplier = 1; while (scanIntPartIndex >= startIntPartIndex) { - integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0"); + integer += multiplier * (this._string.charAt(scanIntPartIndex--) - '0'); multiplier *= 10; } } // Read the decimals. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") { + if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == '.') { this._currentIndex++; // There must be a least one digit following the . - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; + if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') return undefined; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { + while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') { frac *= 10; - decimal += (this._string.charAt(this._currentIndex) - "0") / frac; + decimal += (this._string.charAt(this._currentIndex) - '0') / frac; this._currentIndex += 1; } } // Read the exponent part. - if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m") { + if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == 'e' || this._string.charAt(this._currentIndex) == 'E') && this._string.charAt(this._currentIndex + 1) != 'x' && this._string.charAt(this._currentIndex + 1) != 'm') { this._currentIndex++; // Read the sign of the exponent. - if (this._string.charAt(this._currentIndex) == "+") { + if (this._string.charAt(this._currentIndex) == '+') { this._currentIndex++; - } else if (this._string.charAt(this._currentIndex) == "-") { + } else if (this._string.charAt(this._currentIndex) == '-') { this._currentIndex++; expsign = -1; } // There must be an exponent. - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; + if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') return undefined; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { + while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') { exponent *= 10; - exponent += this._string.charAt(this._currentIndex) - "0"; + exponent += this._string.charAt(this._currentIndex) - '0'; this._currentIndex++; } } @@ -4104,7 +4114,7 @@ var flagChar = this._string.charAt(this._currentIndex++); - if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined; + if (flagChar == '0') flag = false;else if (flagChar == '1') flag = true;else return undefined; this._skipOptionalSpacesOrDelimiter(); @@ -4246,7 +4256,7 @@ return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); default: - throw "Unknown path seg type."; + throw 'Unknown path seg type.'; } }; @@ -4293,7 +4303,7 @@ if (typeof Object.assign !== 'function') { // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { + Object.defineProperty(Object, 'assign', { value: function assign(target, varArgs) { if (target === null || target === undefined) { @@ -4510,7 +4520,7 @@ $$.resizeFunction.remove(); // Unbinds from the window focus event $$.unbindWindowFocus(); - $$.selectChart.classed('c3', false).html(""); // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. + $$.selectChart.classed('c3', false).html(''); // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. Object.keys($$).forEach(function (key) { $$[key] = null; @@ -4873,17 +4883,17 @@ } // draw again for removing flowed elements and reverting attr - xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity); + xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style('opacity', $$.xgridAttr.opacity); xgridLines.attr('transform', null); - xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv); - xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv); - mainBar.attr('transform', null).attr("d", drawBar); - mainLine.attr('transform', null).attr("d", drawLine); - mainArea.attr('transform', null).attr("d", drawArea); - mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy); + xgridLines.select('line').attr('x1', config.axis_rotated ? 0 : xv).attr('x2', config.axis_rotated ? $$.width : xv); + xgridLines.select('text').attr('x', config.axis_rotated ? $$.width : 0).attr('y', xv); + mainBar.attr('transform', null).attr('d', drawBar); + mainLine.attr('transform', null).attr('d', drawLine); + mainArea.attr('transform', null).attr('d', drawArea); + mainCircle.attr('transform', null).attr('cx', cx).attr('cy', cy); mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$)); mainRegion.attr('transform', null); - mainRegion.filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$)); // callback for end of flow + mainRegion.filter($$.isRegionOnX).attr('x', $$.regionX.bind($$)).attr('width', $$.regionWidth.bind($$)); // callback for end of flow done(); $$.flowing = false; @@ -5156,8 +5166,8 @@ classes, regions; options = options || {}; - duration = getOption(options, "duration", config.transition_duration); - classes = getOption(options, "classes", [CLASS.region]); + duration = getOption(options, 'duration', config.transition_duration); + classes = getOption(options, 'classes', [CLASS.region]); regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) { return '.' + c; })); @@ -5644,7 +5654,7 @@ updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; + return updated ? arc(updated) : 'M 0 0'; }; // TODO: extends all function @@ -5665,12 +5675,12 @@ }); return function (d) { var updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; + return updated ? arc(updated) : 'M 0 0'; }; }; ChartInternal.prototype.getArc = function (d, withoutUpdate, force) { - return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0"; + return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : 'M 0 0'; }; ChartInternal.prototype.transformForArcLabel = function (d) { @@ -5682,7 +5692,7 @@ y, h, ratio, - translate = "", + translate = '', hasGauge = $$.hasType('gauge'); if (updated && !hasGauge) { @@ -5699,12 +5709,12 @@ ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0; } - translate = "translate(" + x * ratio + ',' + y * ratio + ")"; + translate = 'translate(' + x * ratio + ',' + y * ratio + ')'; } else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) { var y1 = Math.sin(updated.endAngle - Math.PI / 2); x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; - translate = "translate(" + x + ',' + y + ")"; + translate = 'translate(' + x + ',' + y + ')'; } return translate; @@ -5736,7 +5746,7 @@ format; if (!$$.shouldShowArcLabel()) { - return ""; + return ''; } updated = $$.updateAngle(d); @@ -5745,7 +5755,7 @@ id = d.data.id; if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) { - return ""; + return ''; } format = $$.getArcLabelFormat(); @@ -5781,7 +5791,7 @@ return; } - $$.d3.select(this).selectAll('path').transition().duration($$.expandDuration(d.data.id)).attr("d", $$.svgArcExpanded).transition().duration($$.expandDuration(d.data.id) * 2).attr("d", $$.svgArcExpandedSub).each(function (d) { + $$.d3.select(this).selectAll('path').transition().duration($$.expandDuration(d.data.id)).attr('d', $$.svgArcExpanded).transition().duration($$.expandDuration(d.data.id) * 2).attr('d', $$.svgArcExpandedSub).each(function (d) { if ($$.isDonutType(d.data)) ; }); }); @@ -5797,7 +5807,7 @@ targetIds = $$.mapToTargetIds(targetIds); $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) { return $$.expandDuration(d.data.id); - }).attr("d", $$.svgArc); + }).attr('d', $$.svgArc); $$.svg.selectAll('.' + CLASS.arc); }; @@ -5866,7 +5876,7 @@ ChartInternal.prototype.getArcTitle = function () { var $$ = this; - return $$.hasType('donut') ? $$.config.donut_title : ""; + return $$.hasType('donut') ? $$.config.donut_title : ''; }; ChartInternal.prototype.updateTargetsForArc = function (targets) { @@ -5877,19 +5887,19 @@ classChartArc = $$.classChartArc.bind($$), classArcs = $$.classArcs.bind($$), classFocus = $$.classFocus.bind($$); - mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) { + mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr('class', function (d) { return classChartArc(d) + classFocus(d.data); }); - mainPieEnter = mainPies.enter().append("g").attr("class", classChartArc); + mainPieEnter = mainPies.enter().append('g').attr('class', classChartArc); mainPieEnter.append('g').attr('class', classArcs); - mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none"); // MEMO: can not keep same color..., but not bad to update color in redraw + mainPieEnter.append('text').attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em').style('opacity', 0).style('text-anchor', 'middle').style('pointer-events', 'none'); // MEMO: can not keep same color..., but not bad to update color in redraw //mainPieUpdate.exit().remove(); }; ChartInternal.prototype.initArc = function () { var $$ = this; - $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); - $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle()); + $$.arcs = $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartArcs).attr('transform', $$.getTranslate('arc')); + $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style('text-anchor', 'middle').text($$.getArcTitle()); }; ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) { @@ -5903,10 +5913,10 @@ mainArcLabelLine, hasGaugeType = $$.hasType('gauge'); arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$)); - mainArc = arcs.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) { + mainArc = arcs.enter().append('path').attr('class', $$.classArc.bind($$)).style('fill', function (d) { return $$.color(d.data); - }).style("cursor", function (d) { - return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null; + }).style('cursor', function (d) { + return config.interaction_enabled && config.data_selection_isselectable(d) ? 'pointer' : null; }).each(function (d) { if ($$.isGaugeType(d.data)) { d.startAngle = d.endAngle = config.gauge_startingAngle; @@ -5917,23 +5927,23 @@ if (hasGaugeType) { arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine).data($$.arcData.bind($$)); - mainArcLabelLine = arcLabelLines.enter().append('rect').attr("class", function (d) { + mainArcLabelLine = arcLabelLines.enter().append('rect').attr('class', function (d) { return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id; }).merge(arcLabelLines); if ($$.filterTargetsToShow($$.data.targets).length === 1) { - mainArcLabelLine.style("display", "none"); + mainArcLabelLine.style('display', 'none'); } else { - mainArcLabelLine.style("fill", function (d) { + mainArcLabelLine.style('fill', function (d) { return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data); - }).style("display", config.gauge_labelLine_show ? "" : "none").each(function (d) { + }).style('display', config.gauge_labelLine_show ? '' : 'none').each(function (d) { var lineLength = 0, lineThickness = 2, x = 0, y = 0, - transform = ""; + transform = ''; if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { var updated = $$.updateAngle(d), @@ -5944,16 +5954,16 @@ lineLength = $$.radiusExpanded - $$.radius + innerLineLength; x = Math.cos(linePositioningAngle) * arcInnerRadius; y = Math.sin(linePositioningAngle) * arcInnerRadius; - transform = "rotate(" + lineAngle * 180 / Math.PI + ", " + x + ", " + y + ")"; + transform = 'rotate(' + lineAngle * 180 / Math.PI + ', ' + x + ', ' + y + ')'; } - d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0"); + d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style('stroke-dasharray', '0, ' + (lineLength + lineThickness) + ', 0'); }); } } - mainArc.attr("transform", function (d) { - return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : ""; + mainArc.attr('transform', function (d) { + return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : ''; }).on('mouseover', config.interaction_enabled ? function (d) { var updated, arcData; @@ -6015,13 +6025,13 @@ } } : null).each(function () { $$.transiting = true; - }).transition().duration(duration).attrTween("d", function (d) { + }).transition().duration(duration).attrTween('d', function (d) { var updated = $$.updateAngle(d), interpolate; if (!updated) { return function () { - return "M 0 0"; + return 'M 0 0'; }; } // if (this._current === d) { // this._current = { @@ -6044,7 +6054,7 @@ return function (t) { // prevents crashing the charts once in transition and chart.destroy() has been called if ($$.config === null) { - return "M 0 0"; + return 'M 0 0'; } var interpolated = interpolate(t); @@ -6052,7 +6062,7 @@ return $$.getArc(interpolated, true); }; - }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) { + }).attr('transform', withTransform ? 'scale(1)' : '').style('fill', function (d) { return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data.id); @@ -6061,23 +6071,23 @@ $$.transiting = false; }); arcs.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) { + main.selectAll('.' + CLASS.chartArc).select('text').style('opacity', 0).attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; - }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) { + }).text($$.textForArcLabel.bind($$)).attr('transform', $$.transformForArcLabel.bind($$)).style('font-size', function (d) { return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : ''; - }).transition().duration(duration).style("opacity", function (d) { + }).transition().duration(duration).style('opacity', function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; }); - main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0); + main.select('.' + CLASS.chartArcsTitle).style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0); if (hasGaugeType) { var index = 0; var backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets); - backgroundArc.enter().append("path").attr("class", function (d, i) { + backgroundArc.enter().append('path').attr('class', function (d, i) { return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i; - }).merge(backgroundArc).attr("d", function (d1) { + }).merge(backgroundArc).attr('d', function (d1) { if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { - return "M 0 0"; + return 'M 0 0'; } var d = { @@ -6091,9 +6101,9 @@ return $$.getArc(d, true, true); }); backgroundArc.exit().remove(); - $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMin).attr("dx", -1 * ($$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMax).attr("dx", $$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); + $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr('dy', '.75em').text(config.gauge_label_show ? config.gauge_units : ''); + $$.arcs.select('.' + CLASS.chartArcsGaugeMin).attr('dx', -1 * ($$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + 'px').attr('dy', '1.2em').text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); + $$.arcs.select('.' + CLASS.chartArcsGaugeMax).attr('dx', $$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + 'px').attr('dy', '1.2em').text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); } }; @@ -6101,10 +6111,10 @@ var arcs = this.arcs; if (this.hasType('gauge')) { - arcs.append('g').attr("class", CLASS.chartArcsBackground); - arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none"); - arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none"); - arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none"); + arcs.append('g').attr('class', CLASS.chartArcsBackground); + arcs.append('text').attr('class', CLASS.chartArcsGaugeUnit).style('text-anchor', 'middle').style('pointer-events', 'none'); + arcs.append('text').attr('class', CLASS.chartArcsGaugeMin).style('text-anchor', 'middle').style('pointer-events', 'none'); + arcs.append('text').attr('class', CLASS.chartArcsGaugeMax).style('text-anchor', 'middle').style('pointer-events', 'none'); } }; @@ -6186,7 +6196,7 @@ }; ChartInternal.prototype.generateClass = function (prefix, targetId) { - return " " + prefix + " " + prefix + this.generateTargetClass(targetId); + return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId); }; ChartInternal.prototype.classText = function (d) { @@ -6328,11 +6338,11 @@ }; ChartInternal.prototype.getClipPath = function (id) { - return "url(" + (isIE(9) ? "" : document.URL.split('#')[0]) + "#" + id + ")"; + return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')'; }; ChartInternal.prototype.appendClip = function (parent, id) { - return parent.append("clipPath").attr("id", id).append("rect"); + return parent.append('clipPath').attr('id', id).append('rect'); }; ChartInternal.prototype.getAxisClipX = function (forHorizontal) { @@ -6529,7 +6539,7 @@ data_mimeType: undefined, data_keys: undefined, // configuration for no plot-able data supplied. - data_empty_label_text: "", + data_empty_label_text: '', // subchart subchart_show: false, subchart_size_height: 60, @@ -6667,7 +6677,7 @@ donut_label_threshold: 0.05, donut_label_ratio: undefined, donut_width: undefined, - donut_title: "", + donut_title: '', donut_expand: {}, donut_expand_duration: 50, donut_padAngle: 0, @@ -6894,7 +6904,7 @@ for (var j = 0; j < rows[i].length; j++) { if (isUndefined(rows[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); + throw new Error('Source data is missing a component at (' + i + ',' + j + ')!'); } newRow[keys[j]] = rows[i][j]; @@ -6928,7 +6938,7 @@ } if (isUndefined(columns[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); + throw new Error('Source data is missing a component at (' + i + ',' + j + ')!'); } newRows[j - 1][key] = columns[i][j]; @@ -6977,7 +6987,7 @@ ids = keys.filter($$.isNotXAndNotEpochs, $$); if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) { - throw new Error('You must define the \'x\' key name and the \'epochs\' for Stanford Diagrams'); + throw new Error("You must define the 'x' key name and the 'epochs' for Stanford Diagrams"); } } // save x for update data by load when custom x and c3.x API @@ -7812,14 +7822,14 @@ if (d && api.data.shown.call(api).length) { ratio = d.ratio || d.value; - if (type === "arc") { + if (type === 'arc') { if ($$.hasType('gauge')) { ratio = (d.endAngle - d.startAngle) / (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1)); } else { var total = $$.getTotalDataSum(); ratio = d.value / total; } - } else if (type === "index") { + } else if (type === 'index') { var _total = $$.getTotalPerIndex($$.axis.getId(d.id)); d.ratio = isNumber(d.value) && _total && _total[d.index] > 0 ? d.value / _total[d.index] : 0; @@ -8359,8 +8369,8 @@ box; if (shape.classed(CLASS.circle)) { - _x = shape.attr("cx") * 1; - _y = shape.attr("cy") * 1; + _x = shape.attr('cx') * 1; + _y = shape.attr('cy') * 1; toggle = $$.togglePoint; isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; } else if (shape.classed(CLASS.bar)) { @@ -8446,7 +8456,7 @@ }; ChartInternal.prototype.defaultValueFormat = function (v) { - return isValue(v) ? +v : ""; + return isValue(v) ? +v : ''; }; ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) { @@ -8458,7 +8468,7 @@ data_labels = $$.config.data_labels, format, defaultFormat = function defaultFormat(v) { - return isValue(v) ? +v : ""; + return isValue(v) ? +v : ''; }; // find format according to axis id @@ -8483,10 +8493,10 @@ var $$ = this, config = $$.config, d3 = $$.d3; - $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid); + $$.grid = $$.main.append('g').attr('clip-path', $$.clipPathForGrid).attr('class', CLASS.grid); if (config.grid_x_show) { - $$.grid.append("g").attr("class", CLASS.xgrids); + $$.grid.append('g').attr('class', CLASS.xgrids); } if (config.grid_y_show) { @@ -8494,7 +8504,7 @@ } if (config.grid_focus_show) { - $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus); + $$.grid.append('g').attr('class', CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus); } $$.xgrid = d3.selectAll([]); @@ -8507,8 +8517,8 @@ ChartInternal.prototype.initGridLines = function () { var $$ = this, d3 = $$.d3; - $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines); - $$.gridLines.append('g').attr("class", CLASS.xgridLines); + $$.gridLines = $$.main.append('g').attr('clip-path', $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines); + $$.gridLines.append('g').attr('class', CLASS.xgridLines); $$.gridLines.append('g').attr('class', CLASS.ygridLines); $$.xgridLines = d3.selectAll([]); }; @@ -8520,23 +8530,23 @@ xgridData = $$.generateGridData(config.grid_x_type, $$.x), tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; $$.xgridAttr = config.axis_rotated ? { - 'x1': 0, - 'x2': $$.width, - 'y1': function y1(d) { + x1: 0, + x2: $$.width, + y1: function y1(d) { return $$.x(d) - tickOffset; }, - 'y2': function y2(d) { + y2: function y2(d) { return $$.x(d) - tickOffset; } } : { - 'x1': function x1(d) { + x1: function x1(d) { return $$.x(d) + tickOffset; }, - 'x2': function x2(d) { + x2: function x2(d) { return $$.x(d) + tickOffset; }, - 'y1': 0, - 'y2': $$.height + y1: 0, + y2: $$.height }; $$.xgridAttr.opacity = function () { @@ -8545,11 +8555,11 @@ }; var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData); - var xgridEnter = xgrid.enter().append('line').attr("class", CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", 0); + var xgridEnter = xgrid.enter().append('line').attr('class', CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style('opacity', 0); $$.xgrid = xgridEnter.merge(xgrid); if (!withoutUpdate) { - $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity); + $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style('opacity', $$.xgridAttr.opacity); } xgrid.exit().remove(); @@ -8563,13 +8573,13 @@ var ygridEnter = ygrid.enter().append('line') // TODO: x1, x2, y1, y2, opacity need to be set here maybe .attr('class', CLASS.ygrid); $$.ygrid = ygridEnter.merge(ygrid); - $$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0).attr("x2", config.axis_rotated ? $$.y : $$.width).attr("y1", config.axis_rotated ? 0 : $$.y).attr("y2", config.axis_rotated ? $$.height : $$.y); + $$.ygrid.attr('x1', config.axis_rotated ? $$.y : 0).attr('x2', config.axis_rotated ? $$.y : $$.width).attr('y1', config.axis_rotated ? 0 : $$.y).attr('y2', config.axis_rotated ? $$.height : $$.y); ygrid.exit().remove(); $$.smoothLines($$.ygrid, 'grid'); }; ChartInternal.prototype.gridTextAnchor = function (d) { - return d.position ? d.position : "end"; + return d.position ? d.position : 'end'; }; ChartInternal.prototype.gridTextDx = function (d) { @@ -8598,7 +8608,7 @@ yGridTextX = $$.yGridTextX.bind($$); // hide if arc type $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); - main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); + main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); if (config.grid_x_show) { $$.updateXGrid(); @@ -8606,16 +8616,16 @@ xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines); // enter - xgridLineEnter = xgridLine.enter().append('g').attr("class", function (d) { + xgridLineEnter = xgridLine.enter().append('g').attr('class', function (d) { return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : ''); }); - xgridLineEnter.append('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 0); - xgridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "" : "rotate(-90)").attr("x", config.axis_rotated ? yGridTextX : xGridTextX).attr("y", xv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // udpate + xgridLineEnter.append('line').attr('x1', config.axis_rotated ? 0 : xv).attr('x2', config.axis_rotated ? $$.width : xv).attr('y1', config.axis_rotated ? xv : 0).attr('y2', config.axis_rotated ? xv : $$.height).style('opacity', 0); + xgridLineEnter.append('text').attr('text-anchor', $$.gridTextAnchor).attr('transform', config.axis_rotated ? '' : 'rotate(-90)').attr('x', config.axis_rotated ? yGridTextX : xGridTextX).attr('y', xv).attr('dx', $$.gridTextDx).attr('dy', -5).style('opacity', 0); // udpate $$.xgridLines = xgridLineEnter.merge(xgridLine); // done in d3.transition() of the end of this function // exit - xgridLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Y-Grid + xgridLine.exit().transition().duration(duration).style('opacity', 0).remove(); // Y-Grid if (config.grid_y_show) { $$.updateYGrid(); @@ -8623,19 +8633,19 @@ ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines); // enter - ygridLineEnter = ygridLine.enter().append('g').attr("class", function (d) { + ygridLineEnter = ygridLine.enter().append('g').attr('class', function (d) { return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : ''); }); - ygridLineEnter.append('line').attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 0); - ygridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "rotate(-90)" : "").attr("x", config.axis_rotated ? xGridTextX : yGridTextX).attr("y", yv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // update + ygridLineEnter.append('line').attr('x1', config.axis_rotated ? yv : 0).attr('x2', config.axis_rotated ? yv : $$.width).attr('y1', config.axis_rotated ? 0 : yv).attr('y2', config.axis_rotated ? $$.height : yv).style('opacity', 0); + ygridLineEnter.append('text').attr('text-anchor', $$.gridTextAnchor).attr('transform', config.axis_rotated ? 'rotate(-90)' : '').attr('x', config.axis_rotated ? xGridTextX : yGridTextX).attr('y', yv).attr('dx', $$.gridTextDx).attr('dy', -5).style('opacity', 0); // update $$.ygridLines = ygridLineEnter.merge(ygridLine); - $$.ygridLines.select('line').transition().duration(duration).attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 1); - $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) { + $$.ygridLines.select('line').transition().duration(duration).attr('x1', config.axis_rotated ? yv : 0).attr('x2', config.axis_rotated ? yv : $$.width).attr('y1', config.axis_rotated ? 0 : yv).attr('y2', config.axis_rotated ? $$.height : yv).style('opacity', 1); + $$.ygridLines.select('text').transition().duration(duration).attr('x', config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr('y', yv).text(function (d) { return d.text; - }).style("opacity", 1); // exit + }).style('opacity', 1); // exit - ygridLine.exit().transition().duration(duration).style("opacity", 0).remove(); + ygridLine.exit().transition().duration(duration).style('opacity', 0).remove(); }; ChartInternal.prototype.redrawGrid = function (withTransition, transition) { @@ -8644,9 +8654,9 @@ xv = $$.xv.bind($$), lines = $$.xgridLines.select('line'), texts = $$.xgridLines.select('text'); - return [(withTransition ? lines.transition(transition) : lines).attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 1), (withTransition ? texts.transition(transition) : texts).attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr("y", xv).text(function (d) { + return [(withTransition ? lines.transition(transition) : lines).attr('x1', config.axis_rotated ? 0 : xv).attr('x2', config.axis_rotated ? $$.width : xv).attr('y1', config.axis_rotated ? xv : 0).attr('y2', config.axis_rotated ? xv : $$.height).style('opacity', 1), (withTransition ? texts.transition(transition) : texts).attr('x', config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr('y', xv).text(function (d) { return d.text; - }).style("opacity", 1)]; + }).style('opacity', 1)]; }; ChartInternal.prototype.showXGridFocus = function (selectedData) { @@ -8667,18 +8677,18 @@ return; } - focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx); + focusEl.style('visibility', 'visible').data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx); $$.smoothLines(focusEl, 'grid'); }; ChartInternal.prototype.hideXGridFocus = function () { - this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); + this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); }; ChartInternal.prototype.updateXgridFocus = function () { var $$ = this, config = $$.config; - $$.main.select('line.' + CLASS.xgridFocus).attr("x1", config.axis_rotated ? 0 : -10).attr("x2", config.axis_rotated ? $$.width : -10).attr("y1", config.axis_rotated ? -10 : 0).attr("y2", config.axis_rotated ? -10 : $$.height); + $$.main.select('line.' + CLASS.xgridFocus).attr('x1', config.axis_rotated ? 0 : -10).attr('x2', config.axis_rotated ? $$.width : -10).attr('y1', config.axis_rotated ? -10 : 0).attr('y2', config.axis_rotated ? -10 : $$.height); }; ChartInternal.prototype.generateGridData = function (type, scale) { @@ -8688,7 +8698,7 @@ firstYear, lastYear, i, - tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size(); + tickNum = $$.main.select('.' + CLASS.axisX).selectAll('.tick').size(); if (type === 'year') { xDomain = $$.getXDomain(); @@ -8704,7 +8714,7 @@ if (gridData.length > tickNum) { // use only int gridData = gridData.filter(function (d) { - return ("" + d).indexOf('.') < 0; + return ('' + d).indexOf('.') < 0; }); } } @@ -8748,11 +8758,11 @@ ChartInternal.prototype.initEventRect = function () { var $$ = this, config = $$.config; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.eventRects).style('fill-opacity', 0); $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect').attr('class', CLASS.eventRect); // event rect handle zoom event as well if (config.zoom_enabled && $$.zoom) { - $$.eventRect.call($$.zoom).on("dblclick.zoom", null); + $$.eventRect.call($$.zoom).on('dblclick.zoom', null); if (config.zoom_initialRange) { // WORKAROUND: Add transition to apply transform immediately when no subchart @@ -8936,7 +8946,7 @@ box = eventRect.getBoundingClientRect(), x = box.left + (mouse ? mouse[0] : 0), y = box.top + (mouse ? mouse[1] : 0), - event = document.createEvent("MouseEvents"); + event = document.createEvent('MouseEvents'); event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null); eventRect.dispatchEvent(event); }; @@ -8945,7 +8955,7 @@ var $$ = this; $$.legendItemTextBox = {}; $$.legendHasRendered = false; - $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend')); + $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend')); if (!$$.config.legend_show) { $$.legend.style('visibility', 'hidden'); @@ -8984,7 +8994,7 @@ ChartInternal.prototype.transformLegend = function (withTransition) { var $$ = this; - (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend')); + (withTransition ? $$.legend.transition() : $$.legend).attr('transform', $$.getTranslate('legend')); }; ChartInternal.prototype.updateLegendStep = function (step) { @@ -9107,8 +9117,8 @@ return !isDefined(config.data_names[id]) || config.data_names[id] !== null; }); options = options || {}; - withTransition = getOption(options, "withTransition", true); - withTransitionForTransform = getOption(options, "withTransitionForTransform", true); + withTransition = getOption(options, 'withTransition', true); + withTransitionForTransform = getOption(options, 'withTransitionForTransform', true); function getTextBox(textElement, id) { if (!$$.legendItemTextBox[id]) { @@ -9258,7 +9268,9 @@ return $$.generateClass(CLASS.legendItem, id); }).style('visibility', function (id) { return $$.isLegendToShow(id) ? 'visible' : 'hidden'; - }).style('cursor', 'pointer').on('click', function (id) { + }).style('cursor', function () { + return config.interaction_enabled ? 'pointer' : 'auto'; + }).on('click', config.interaction_enabled ? function (id) { if (config.legend_item_onclick) { config.legend_item_onclick.call($$, id); } else { @@ -9270,7 +9282,7 @@ $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); } } - }).on('mouseover', function (id) { + } : null).on('mouseover', config.interaction_enabled ? function (id) { if (config.legend_item_onmouseover) { config.legend_item_onmouseover.call($$, id); } else { @@ -9280,26 +9292,26 @@ $$.api.focus(id); } } - }).on('mouseout', function (id) { + } : null).on('mouseout', config.interaction_enabled ? function (id) { if (config.legend_item_onmouseout) { config.legend_item_onmouseout.call($$, id); } else { $$.d3.select(this).classed(CLASS.legendItemFocused, false); $$.api.revert(); } - }); + } : null); l.append('text').text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }).each(function (id, i) { updatePositions(this, id, i); - }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); - l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); - l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style("pointer-events", "none").attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); // Set background for inset legend + }).style('pointer-events', 'none').attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); + l.append('rect').attr('class', CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); + l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style('pointer-events', 'none').attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); // Set background for inset legend background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { - background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect'); + background = $$.legend.insert('g', '.' + CLASS.legendItem).attr('class', CLASS.legendBackground).append('rect'); } texts = $$.legend.selectAll('text').data(targetIds).text(function (id) { @@ -9345,7 +9357,7 @@ ChartInternal.prototype.initRegion = function () { var $$ = this; - $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions); + $$.region = $$.main.append('g').attr('clip-path', $$.clipPath).attr('class', CLASS.regions); }; ChartInternal.prototype.updateRegion = function (duration) { @@ -9355,21 +9367,21 @@ $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions); var g = mainRegion.enter().append('g'); - g.append('rect').attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) { + g.append('rect').attr('x', $$.regionX.bind($$)).attr('y', $$.regionY.bind($$)).attr('width', $$.regionWidth.bind($$)).attr('height', $$.regionHeight.bind($$)).style('fill-opacity', function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }); g.append('text').text($$.labelRegion.bind($$)); $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$)); - mainRegion.exit().transition().duration(duration).style("opacity", 0).remove(); + mainRegion.exit().transition().duration(duration).style('opacity', 0).remove(); }; ChartInternal.prototype.redrawRegion = function (withTransition, transition) { var $$ = this, regions = $$.mainRegion, regionLabels = $$.mainRegion.selectAll('text'); - return [(withTransition ? regions.transition(transition) : regions).attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) { + return [(withTransition ? regions.transition(transition) : regions).attr('x', $$.regionX.bind($$)).attr('y', $$.regionY.bind($$)).attr('width', $$.regionWidth.bind($$)).attr('height', $$.regionHeight.bind($$)).style('fill-opacity', function (d) { return isValue(d.opacity) ? d.opacity : 0.1; - }), (withTransition ? regionLabels.transition(transition) : regionLabels).attr("x", $$.labelOffsetX.bind($$)).attr("y", $$.labelOffsetY.bind($$)).attr("transform", $$.labelTransform.bind($$)).attr("style", 'text-anchor: left;')]; + }), (withTransition ? regionLabels.transition(transition) : regionLabels).attr('x', $$.labelOffsetX.bind($$)).attr('y', $$.labelOffsetY.bind($$)).attr('transform', $$.labelTransform.bind($$)).attr('style', 'text-anchor: left;')]; }; ChartInternal.prototype.regionX = function (d) { @@ -9443,7 +9455,7 @@ }; ChartInternal.prototype.labelTransform = function (d) { - return 'vertical' in d && d.vertical ? "rotate(90)" : ""; + return 'vertical' in d && d.vertical ? 'rotate(90)' : ''; }; ChartInternal.prototype.labelOffsetX = function (d) { @@ -9688,13 +9700,13 @@ r = $$.pointSelectR.bind($$); config.data_onselected.call($$.api, d, target.node()); // add selected-circle on low layer g - $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () { + $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr('class', function () { return $$.generateClass(CLASS.selectedCircle, i); - }).attr("cx", cx).attr("cy", cy).attr("stroke", function () { + }).attr('cx', cx).attr('cy', cy).attr('stroke', function () { return $$.color(d); - }).attr("r", function (d) { + }).attr('r', function (d) { return $$.pointSelectR(d) * 1.4; - }).transition().duration(100).attr("r", r); + }).transition().duration(100).attr('r', r); }; ChartInternal.prototype.unselectPoint = function (target, d, i) { @@ -9713,7 +9725,7 @@ $$.config.data_onselected.call($$, d, target.node()); if ($$.config.interaction_brighten) { - target.transition().duration(100).style("fill", function () { + target.transition().duration(100).style('fill', function () { return $$.d3.rgb($$.color(d)).brighter(0.75); }); } @@ -9724,7 +9736,7 @@ $$.config.data_onunselected.call($$, d, target.node()); if ($$.config.interaction_brighten) { - target.transition().duration(100).style("fill", function () { + target.transition().duration(100).style('fill', function () { return $$.color(d); }); } @@ -9763,7 +9775,7 @@ if (config.data_selection_enabled && config.data_selection_isselectable(d)) { if (!config.data_selection_multiple) { - $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) { + $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : '')).selectAll('.' + CLASS.shape).each(function (d, i) { var shape = d3.select(this); if (shape.classed(CLASS.SELECTED)) { @@ -9779,7 +9791,7 @@ ChartInternal.prototype.initBar = function () { var $$ = this; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartBars); }; ChartInternal.prototype.updateTargetsForBar = function (targets) { @@ -9793,10 +9805,10 @@ mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) { return classChartBar(d) + classFocus(d); }); - mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style("pointer-events", "none"); // Bars for each data + mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style('pointer-events', 'none'); // Bars for each data - mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) { - return config.data_selection_isselectable(d) ? "pointer" : null; + mainBarEnter.append('g').attr('class', classBars).style('cursor', function (d) { + return config.data_selection_isselectable(d) ? 'pointer' : null; }); }; @@ -9810,14 +9822,14 @@ }; var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData); - var mainBarEnter = mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color); - $$.mainBar = mainBarEnter.merge(mainBar).style("opacity", initialOpacity); - mainBar.exit().transition().duration(durationForExit).style("opacity", 0); + var mainBarEnter = mainBar.enter().append('path').attr('class', classBar).style('stroke', color).style('fill', color); + $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity); + mainBar.exit().transition().duration(durationForExit).style('opacity', 0); }; ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) { var $$ = this; - return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style("stroke", this.color).style("fill", this.color).style("opacity", function (d) { + return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style('stroke', this.color).style('fill', this.color).style('opacity', function (d) { return $$.isTargetToShow(d.id) ? 1 : 0; })]; }; @@ -9965,7 +9977,7 @@ var rowValues = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values; var isTargetNormalized = $$.isTargetNormalized(d.id); var values = rowValues.map(function (v) { - return isTargetNormalized ? $$.getRatio("index", v, true) : v.value; + return isTargetNormalized ? $$.getRatio('index', v, true) : v.value; }); if (t.id === d.id || indices[t.id] !== indices[d.id]) { @@ -10017,17 +10029,17 @@ var $$ = this, d3 = $$.d3, types = { - 'linear': d3.curveLinear, + linear: d3.curveLinear, 'linear-closed': d3.curveLinearClosed, - 'basis': d3.curveBasis, + basis: d3.curveBasis, 'basis-open': d3.curveBasisOpen, 'basis-closed': d3.curveBasisClosed, - 'bundle': d3.curveBundle, - 'cardinal': d3.curveCardinal, + bundle: d3.curveBundle, + cardinal: d3.curveCardinal, 'cardinal-open': d3.curveCardinalOpen, 'cardinal-closed': d3.curveCardinalClosed, - 'monotone': d3.curveMonotoneX, - 'step': d3.curveStep, + monotone: d3.curveMonotoneX, + step: d3.curveStep, 'step-before': d3.curveStepBefore, 'step-after': d3.curveStepAfter }, @@ -10046,7 +10058,7 @@ ChartInternal.prototype.initLine = function () { var $$ = this; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartLines); }; ChartInternal.prototype.updateTargetsForLine = function (targets) { @@ -10062,17 +10074,17 @@ mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) { return classChartLine(d) + classFocus(d); }); - mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none"); // Lines for each data + mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style('pointer-events', 'none'); // Lines for each data - mainLineEnter.append('g').attr("class", classLines); // Areas + mainLineEnter.append('g').attr('class', classLines); // Areas mainLineEnter.append('g').attr('class', classAreas); // Circles for each data point on lines - mainLineEnter.append('g').attr("class", function (d) { + mainLineEnter.append('g').attr('class', function (d) { return $$.generateClass(CLASS.selectedCircles, d.id); }); - mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) { - return config.data_selection_isselectable(d) ? "pointer" : null; + mainLineEnter.append('g').attr('class', classCircles).style('cursor', function (d) { + return config.data_selection_isselectable(d) ? 'pointer' : null; }); // Update date for selected circles targets.forEach(function (t) { @@ -10086,15 +10098,15 @@ ChartInternal.prototype.updateLine = function (durationForExit) { var $$ = this; var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$)); - var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color); - $$.mainLine = mainLineEnter.merge(mainLine).style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) { + var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color); + $$.mainLine = mainLineEnter.merge(mainLine).style('opacity', $$.initialOpacity.bind($$)).style('shape-rendering', function (d) { return $$.isStepType(d) ? 'crispEdges' : ''; }).attr('transform', null); mainLine.exit().transition().duration(durationForExit).style('opacity', 0); }; ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) { - return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)]; + return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr('d', drawLine).style('stroke', this.color).style('opacity', 1)]; }; ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) { @@ -10142,10 +10154,10 @@ y0 = y(values[0].value); } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } - return path ? path : "M 0 0"; + return path ? path : 'M 0 0'; }; }; @@ -10185,7 +10197,7 @@ prev = -1, i, j, - s = "M", + s = 'M', sWithRegion, xp, yp, @@ -10280,7 +10292,7 @@ for (i = 0; i < d.length; i++) { // Draw as normal if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) { - s += " " + xValue(d[i]) + " " + yValue(d[i]); + s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]); } // Draw with region // TODO: Fix for horizotal charts else { xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries()); @@ -10306,16 +10318,16 @@ var $$ = this, d3 = $$.d3; var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$)); - var mainAreaEnter = mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () { + var mainAreaEnter = mainArea.enter().append('path').attr('class', $$.classArea.bind($$)).style('fill', $$.color).style('opacity', function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); - $$.mainArea = mainAreaEnter.merge(mainArea).style("opacity", $$.orgAreaOpacity); + $$.mainArea = mainAreaEnter.merge(mainArea).style('opacity', $$.orgAreaOpacity); mainArea.exit().transition().duration(durationForExit).style('opacity', 0); }; ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) { - return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)]; + return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr('d', drawArea).style('fill', this.color).style('opacity', this.orgAreaOpacity)]; }; ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) { @@ -10360,10 +10372,10 @@ y0 = $$.getYScale(d.id)(values[0].value); } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } - return path ? path : "M 0 0"; + return path ? path : 'M 0 0'; }; }; @@ -10403,15 +10415,15 @@ ChartInternal.prototype.updateCircle = function (cx, cy) { var $$ = this; var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterOrStanfordData.bind($$)); - var mainCircleEnter = mainCircle.enter().append("circle").attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '').attr("class", $$.classCircle.bind($$)).attr("cx", cx).attr("cy", cy).attr("r", $$.pointR.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color); - $$.mainCircle = mainCircleEnter.merge(mainCircle).style("opacity", $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)); - mainCircle.exit().style("opacity", 0); + var mainCircleEnter = mainCircle.enter().append('circle').attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '').attr('class', $$.classCircle.bind($$)).attr('cx', cx).attr('cy', cy).attr('r', $$.pointR.bind($$)).style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color); + $$.mainCircle = mainCircleEnter.merge(mainCircle).style('opacity', $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)); + mainCircle.exit().style('opacity', 0); }; ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) { var $$ = this, selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); - return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr("cx", cx).attr("cy", cy)]; + return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color).attr('cx', cx).attr('cy', cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr('cx', cx).attr('cy', cy)]; }; ChartInternal.prototype.circleX = function (d) { @@ -10487,8 +10499,8 @@ var d3 = this.d3, mouse = d3.mouse(that), d3_this = d3.select(that), - cx = +d3_this.attr("cx"), - cy = +d3_this.attr("cy"); + cx = +d3_this.attr('cx'), + cy = +d3_this.attr('cy'); return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r; }; @@ -10660,18 +10672,18 @@ var $$ = this, d3 = $$.d3; // TODO: dynamically change brushY/brushX according to axis_rotated. - $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () { + $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on('brush', function () { var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { + if (event && event.type === 'zoom') { return; } $$.redrawForBrush(); - }).on("end", function () { + }).on('end', function () { var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { + if (event && event.type === 'zoom') { return; } @@ -10745,20 +10757,20 @@ ChartInternal.prototype.initSubchart = function () { var $$ = this, config = $$.config, - context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')); // set style + context = $$.context = $$.svg.append('g').attr('transform', $$.getTranslate('context')); // set style context.style('visibility', 'visible'); // Define g for chart area - context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart); // Define g for bar chart area + context.append('g').attr('clip-path', $$.clipPathForSubchart).attr('class', CLASS.chart); // Define g for bar chart area - context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); // Define g for line chart area + context.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartBars); // Define g for line chart area - context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); // Add extent rect for Brush + context.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartLines); // Add extent rect for Brush - context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush); // ATTENTION: This must be called AFTER chart added + context.append('g').attr('clip-path', $$.clipPath).attr('class', CLASS.brush); // ATTENTION: This must be called AFTER chart added // Add Axis - $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis); + $$.axes.subx = context.append('g').attr('class', CLASS.axisX).attr('transform', $$.getTranslate('subx')).attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis); }; ChartInternal.prototype.initSubchartBrush = function () { @@ -10786,25 +10798,25 @@ contextBarEnter = contextBar.enter().append('g').style('opacity', 0); contextBarEnter.merge(contextBar).attr('class', classChartBar); // Bars for each data - contextBarEnter.append('g').attr("class", classBars); //-- Line --// + contextBarEnter.append('g').attr('class', classBars); //-- Line --// contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets); contextLineEnter = contextLine.enter().append('g').style('opacity', 0); contextLineEnter.merge(contextLine).attr('class', classChartLine); // Lines for each data - contextLineEnter.append("g").attr("class", classLines); // Area + contextLineEnter.append('g').attr('class', classLines); // Area - contextLineEnter.append("g").attr("class", classAreas); //-- Brush --// + contextLineEnter.append('g').attr('class', classAreas); //-- Brush --// - context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2); + context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? 'width' : 'height', config.axis_rotated ? $$.width2 : $$.height2); }; ChartInternal.prototype.updateBarForSubchart = function (durationForExit) { var $$ = this; var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$)); - var contextBarEnter = contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color); + var contextBarEnter = contextBar.enter().append('path').attr('class', $$.classBar.bind($$)).style('stroke', 'none').style('fill', $$.color); contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - $$.contextBar = contextBarEnter.merge(contextBar).style("opacity", $$.initialOpacity.bind($$)); + $$.contextBar = contextBarEnter.merge(contextBar).style('opacity', $$.initialOpacity.bind($$)); }; ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) { @@ -10816,27 +10828,27 @@ var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$)); var contextLineEnter = contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color); contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - $$.contextLine = contextLineEnter.merge(contextLine).style("opacity", $$.initialOpacity.bind($$)); + $$.contextLine = contextLineEnter.merge(contextLine).style('opacity', $$.initialOpacity.bind($$)); }; ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) { - (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1); + (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr('d', drawLineOnSub).style('opacity', 1); }; ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) { var $$ = this, d3 = $$.d3; var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$)); - var contextAreaEnter = contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () { + var contextAreaEnter = contextArea.enter().append('path').attr('class', $$.classArea.bind($$)).style('fill', $$.color).style('opacity', function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - $$.contextArea = contextAreaEnter.merge(contextArea).style("opacity", 0); + $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0); }; ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) { - (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity); + (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr('d', drawAreaOnSub).style('fill', this.color).style('opacity', this.orgAreaOpacity); }; ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) { @@ -10903,8 +10915,8 @@ } } - $$.context.attr("transform", $$.getTranslate('context')); - subXAxis.attr("transform", $$.getTranslate('subx')); + $$.context.attr('transform', $$.getTranslate('context')); + subXAxis.attr('transform', $$.getTranslate('subx')); }; ChartInternal.prototype.getDefaultSelection = function () { @@ -10928,7 +10940,7 @@ ChartInternal.prototype.initText = function () { var $$ = this; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartTexts); $$.mainText = $$.d3.selectAll([]); }; @@ -10938,7 +10950,7 @@ classTexts = $$.classTexts.bind($$), classFocus = $$.classFocus.bind($$); var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets); - var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none"); + var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style('pointer-events', 'none'); mainTextEnter.append('g').attr('class', classTexts); mainTextEnter.merge(mainText).attr('class', function (d) { return classChartText(d) + classFocus(d); @@ -10951,11 +10963,11 @@ barOrLineData = $$.barOrLineData.bind($$), classText = $$.classText.bind($$); var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData); - var mainTextEnter = mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) { + var mainTextEnter = mainText.enter().append('text').attr('class', classText).attr('text-anchor', function (d) { return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle'; - }).style("stroke", 'none').attr('x', xForText).attr('y', yForText).style("fill", function (d) { + }).style('stroke', 'none').attr('x', xForText).attr('y', yForText).style('fill', function (d) { return $$.color(d); - }).style("fill-opacity", 0); + }).style('fill-opacity', 0); $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) { return $$.dataLabelFormat(d.id)(d.value, d.id, i, j); }); @@ -10963,15 +10975,15 @@ }; ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) { - return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style("fill", this.color).style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))]; + return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style('fill', this.color).style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))]; }; ChartInternal.prototype.getTextRect = function (text, cls, element) { var dummy = this.d3.select('body').append('div').classed('c3', true), - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), + svg = dummy.append('svg').style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), font = this.d3.select(element).style('font'), rect; - svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () { + svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : '', true).style('font', font).text(text).each(function () { rect = getBBox(this); }); dummy.remove(); @@ -11052,12 +11064,12 @@ ChartInternal.prototype.initTitle = function () { var $$ = this; - $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title); + $$.title = $$.svg.append('text').text($$.config.title_text).attr('class', $$.CLASS.title); }; ChartInternal.prototype.redrawTitle = function () { var $$ = this; - $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$)); + $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$)); }; ChartInternal.prototype.xForTitle = function () { @@ -11120,7 +11132,7 @@ $$.colorScale.remove(); } - $$.colorScale = $$.svg.append("g").attr('width', 50).attr('height', height).attr('class', CLASS.colorScale); + $$.colorScale = $$.svg.append('g').attr('width', 50).attr('height', height).attr('class', CLASS.colorScale); $$.colorScale.append('g').attr('transform', "translate(0, ".concat(config.stanford_padding.top, ")")).selectAll('bars').data(points).enter().append('rect').attr('y', function (d, i) { return i * barHeight; }).attr('x', 0).attr('width', barWidth).attr('height', barHeight).attr('fill', function (d) { @@ -11135,7 +11147,7 @@ } else if (isFunction(config.stanford_scaleFormat)) { legendAxis.tickFormat(config.stanford_scaleFormat); } else { - legendAxis.tickFormat(d3.format("d")); + legendAxis.tickFormat(d3.format('d')); } if (isFunction(config.stanford_scaleValues)) { @@ -11143,10 +11155,10 @@ } // Draw Axis - axis = $$.colorScale.append("g").attr("class", "legend axis").attr("transform", "translate(".concat(barWidth, ",0)")).call(legendAxis); + axis = $$.colorScale.append('g').attr('class', 'legend axis').attr('transform', "translate(".concat(barWidth, ",0)")).call(legendAxis); if (config.stanford_scaleFormat === 'pow10') { - axis.selectAll(".tick text").text(null).filter(powerOfTen).text(10).append("tspan").attr("dy", "-.7em") // https://bl.ocks.org/mbostock/6738229 + axis.selectAll('.tick text').text(null).filter(powerOfTen).text(10).append('tspan').attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229 .text(function (d) { return Math.round(Math.log(d) / Math.LN10); }); @@ -11188,7 +11200,7 @@ maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs); if (minEpochs > maxEpochs) { - throw Error("Number of minEpochs has to be smaller than maxEpochs"); + throw Error('Number of minEpochs has to be smaller than maxEpochs'); } target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)); @@ -11233,7 +11245,7 @@ var $$ = this, labelX = $$.axis.getLabelText('x'), labelY = $$.axis.getLabelText('y'); - return "\n ".concat(labelX ? sanitise(labelX) : "x", "").concat(d.x, "\n ").concat(labelY ? sanitise(labelY) : "y", "").concat(d.value, "\n "); + return "\n ".concat(labelX ? sanitise(labelX) : 'x', "").concat(d.x, "\n ").concat(labelY ? sanitise(labelY) : 'y', "").concat(d.value, "\n "); }; ChartInternal.prototype.countEpochsInRegion = function (region) { @@ -11339,81 +11351,81 @@ stanfordLine = main.select('.' + CLASS.stanfordLines).style('shape-rendering', 'geometricprecision').selectAll('.' + CLASS.stanfordLine).data(config.stanford_lines); // enter - stanfordLineEnter = stanfordLine.enter().append('g').attr("class", function (d) { + stanfordLineEnter = stanfordLine.enter().append('g').attr('class', function (d) { return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordLineEnter.append('line').attr("x1", function (d) { + stanfordLineEnter.append('line').attr('x1', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1'); - }).attr("x2", function (d) { + }).attr('x2', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2'); - }).attr("y1", function (d) { + }).attr('y1', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1'); - }).attr("y2", function (d) { + }).attr('y2', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2'); - }).style("opacity", 0); // update + }).style('opacity', 0); // update $$.stanfordLines = stanfordLineEnter.merge(stanfordLine); - $$.stanfordLines.select('line').transition().duration(duration).attr("x1", function (d) { + $$.stanfordLines.select('line').transition().duration(duration).attr('x1', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1'); - }).attr("x2", function (d) { + }).attr('x2', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2'); - }).attr("y1", function (d) { + }).attr('y1', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1'); - }).attr("y2", function (d) { + }).attr('y2', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2'); - }).style("opacity", 1); // exit + }).style('opacity', 1); // exit - stanfordLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Text + stanfordLine.exit().transition().duration(duration).style('opacity', 0).remove(); // Stanford-Text stanfordText = main.select('.' + CLASS.stanfordTexts).selectAll('.' + CLASS.stanfordText).data(config.stanford_texts); // enter - stanfordTextEnter = stanfordText.enter().append('g').attr("class", function (d) { + stanfordTextEnter = stanfordText.enter().append('g').attr('class', function (d) { return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordTextEnter.append('text').attr("x", function (d) { + stanfordTextEnter.append('text').attr('x', function (d) { return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'); - }).attr("y", function (d) { + }).attr('y', function (d) { return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'); - }).style("opacity", 0); // update + }).style('opacity', 0); // update $$.stanfordTexts = stanfordTextEnter.merge(stanfordText); - $$.stanfordTexts.select('text').transition().duration(duration).attr("x", function (d) { + $$.stanfordTexts.select('text').transition().duration(duration).attr('x', function (d) { return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'); - }).attr("y", function (d) { + }).attr('y', function (d) { return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'); }).text(function (d) { return d.content; - }).style("opacity", 1); // exit + }).style('opacity', 1); // exit - stanfordText.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Regions + stanfordText.exit().transition().duration(duration).style('opacity', 0).remove(); // Stanford-Regions stanfordRegion = main.select('.' + CLASS.stanfordRegions).selectAll('.' + CLASS.stanfordRegion).data(config.stanford_regions); // enter - stanfordRegionEnter = stanfordRegion.enter().append('g').attr("class", function (d) { + stanfordRegionEnter = stanfordRegion.enter().append('g').attr('class', function (d) { return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordRegionEnter.append('polygon').attr("points", function (d) { + stanfordRegionEnter.append('polygon').attr('points', function (d) { return d.points.map(function (value) { - return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(","); - }).join(" "); - }).style("opacity", 0); - stanfordRegionEnter.append('text').attr("x", function (d) { + return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(','); + }).join(' '); + }).style('opacity', 0); + stanfordRegionEnter.append('text').attr('x', function (d) { return $$.getCentroid(d.points).x; - }).attr("y", function (d) { + }).attr('y', function (d) { return $$.getCentroid(d.points).y; - }).style("opacity", 0); // update + }).style('opacity', 0); // update $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion); - $$.stanfordRegions.select('polygon').transition().duration(duration).attr("points", function (d) { + $$.stanfordRegions.select('polygon').transition().duration(duration).attr('points', function (d) { return d.points.map(function (value) { - return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(","); - }).join(" "); - }).style("opacity", function (d) { + return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(','); + }).join(' '); + }).style('opacity', function (d) { return d.opacity ? d.opacity : 0.2; }); - $$.stanfordRegions.select('text').transition().duration(duration).attr("x", function (d) { + $$.stanfordRegions.select('text').transition().duration(duration).attr('x', function (d) { return config.axis_rotated ? yvCustom($$.getCentroid(d.points), 'y') : xvCustom($$.getCentroid(d.points), 'x'); - }).attr("y", function (d) { + }).attr('y', function (d) { return config.axis_rotated ? xvCustom($$.getCentroid(d.points), 'x') : yvCustom($$.getCentroid(d.points), 'y'); }).text(function (d) { if (d.text) { @@ -11428,17 +11440,17 @@ return d.text(value, percentage); } - return ""; - }).attr("text-anchor", "middle").attr("dominant-baseline", "middle").style("opacity", 1); // exit + return ''; + }).attr('text-anchor', 'middle').attr('dominant-baseline', 'middle').style('opacity', 1); // exit - stanfordRegion.exit().transition().duration(duration).style("opacity", 0).remove(); + stanfordRegion.exit().transition().duration(duration).style('opacity', 0).remove(); }; ChartInternal.prototype.initTooltip = function () { var $$ = this, config = $$.config, i; - $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none"); // Show tooltip if needed + $$.tooltip = $$.selectChart.style('position', 'relative').append('div').attr('class', CLASS.tooltipContainer).style('position', 'absolute').style('pointer-events', 'none').style('display', 'none'); // Show tooltip if needed if (config.tooltip_init_show) { if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { @@ -11456,7 +11468,7 @@ $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) { return $$.addName(d.values[config.tooltip_init_x]); }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color)); - $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block"); + $$.tooltip.style('top', config.tooltip_init_position.top).style('left', config.tooltip_init_position.left).style('display', 'block'); } }; @@ -11575,7 +11587,7 @@ // Regular tooltip if (!text) { title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x); - text = "" + (title || title === 0 ? "" : ""); + text = "
" + title + "
" + (title || title === 0 ? "' : ''); } value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)); @@ -11592,14 +11604,14 @@ } if (value !== undefined) { - text += ""; - text += ""; - text += ""; - text += ""; + text += ""; + text += "'; + text += "'; + text += ''; } } - return text + "
" + title + '
" + name + "" + value + "
" + name + '" + value + '
"; + return text + ''; }; ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) { @@ -11662,17 +11674,17 @@ return; } - $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); // Get tooltip dimensions + $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style('display', 'block'); // Get tooltip dimensions tWidth = $$.tooltip.property('offsetWidth'); tHeight = $$.tooltip.property('offsetHeight'); position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); // Set tooltip - $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px'); + $$.tooltip.style('top', position.top + 'px').style('left', position.left + 'px'); }; ChartInternal.prototype.hideTooltip = function () { - this.tooltip.style("display", "none"); + this.tooltip.style('display', 'none'); }; ChartInternal.prototype.setTargetType = function (targetIds, type) { @@ -11815,27 +11827,27 @@ d3 = $$.d3, config = $$.config, startEvent; - $$.zoom = d3.zoom().on("start", function () { + $$.zoom = d3.zoom().on('start', function () { if (config.zoom_type !== 'scroll') { return; } var e = d3.event.sourceEvent; - if (e && e.type === "brush") { + if (e && e.type === 'brush') { return; } startEvent = e; config.zoom_onzoomstart.call($$.api, e); - }).on("zoom", function () { + }).on('zoom', function () { if (config.zoom_type !== 'scroll') { return; } var e = d3.event.sourceEvent; - if (e && e.type === "brush") { + if (e && e.type === 'brush') { return; } @@ -11848,7 +11860,7 @@ var e = d3.event.sourceEvent; - if (e && e.type === "brush") { + if (e && e.type === 'brush') { return; } // if click, do nothing. otherwise, click interaction will be canceled. @@ -11904,13 +11916,13 @@ }); }; - var brush = $$.dragZoomBrush = d3.brushX().on("start", function () { + var brush = $$.dragZoomBrush = d3.brushX().on('start', function () { $$.api.unzoom(); - $$.svg.select("." + CLASS.dragZoom).classed("disabled", false); + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false); config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); - }).on("brush", function () { + }).on('brush', function () { config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection)); - }).on("end", function () { + }).on('end', function () { if (d3.event.selection == null) { return; } @@ -11921,10 +11933,10 @@ $$.api.zoom(zoomedDomain); } - $$.svg.select("." + CLASS.dragZoom).classed("disabled", true); + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true); config.zoom_onzoomend.call($$.api, zoomedDomain); }); - context.append("g").classed(CLASS.dragZoom, true).attr("clip-path", $$.clipPath).attr("transform", "translate(" + brushXPos + "," + brushYPos + ")").call(brush); + context.append('g').classed(CLASS.dragZoom, true).attr('clip-path', $$.clipPath).attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')').call(brush); }; ChartInternal.prototype.getZoomDomain = function () { diff --git a/c3.min.js b/c3.min.js index ed9aca193..a971317ac 100644 --- a/c3.min.js +++ b/c3.min.js @@ -1,2 +1,2 @@ -/* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).c3=e()}(this,function(){"use strict";function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t){return function(t){if(Array.isArray(t)){for(var e=0,i=new Array(t.length);e/g,">"):t}function g(t){var e=function(t){void 0===t&&(t=window.navigator.userAgent);var e=t.indexOf("MSIE ");return 0e.getTotalLength())break;i--}while(0=this.numberOfItems)throw"INDEX_SIZE_ERR"},window.SVGPathSegList.prototype.getItem=function(t){return this._checkPathSynchronizedToList(),this._checkValidIndex(t),this._list[t]},window.SVGPathSegList.prototype.insertItemBefore=function(t,e){return this._checkPathSynchronizedToList(),e>this.numberOfItems&&(e=this.numberOfItems),t._owningPathSegList&&(t=t.clone()),this._list.splice(e,0,t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.replaceItem=function(t,e){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._checkValidIndex(e),((this._list[e]=t)._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.removeItem=function(t){this._checkPathSynchronizedToList(),this._checkValidIndex(t);var e=this._list[t];return this._list.splice(t,1),this._writeListToPath(),e},window.SVGPathSegList.prototype.appendItem=function(t){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._list.push(t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList._pathSegArrayAsString=function(t){var e="",i=!0;return t.forEach(function(t){i?(i=!1,e+=t._asPathString()):e+=" "+t._asPathString()}),e},window.SVGPathSegList.prototype._parsePath=function(t){if(!t||0==t.length)return[];function e(){this.pathSegList=[]}var n=this;e.prototype.appendSegment=function(t){this.pathSegList.push(t)};function i(t){this._string=t,this._currentIndex=0,this._endIndex=this._string.length,this._previousCommand=window.SVGPathSeg.PATHSEG_UNKNOWN,this._skipOptionalSpaces()}i.prototype._isCurrentSpace=function(){var t=this._string[this._currentIndex];return t<=" "&&(" "==t||"\n"==t||"\t"==t||"\r"==t||"\f"==t)},i.prototype._skipOptionalSpaces=function(){for(;this._currentIndex=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex)){var t=!1,e=this._string.charAt(this._currentIndex++);if("0"==e)t=!1;else{if("1"!=e)return;t=!0}return this._skipOptionalSpacesOrDelimiter(),t}},i.prototype.parseSegment=function(){var t=this._string[this._currentIndex],e=this._pathSegTypeFromChar(t);if(e==window.SVGPathSeg.PATHSEG_UNKNOWN){if(this._previousCommand==window.SVGPathSeg.PATHSEG_UNKNOWN)return null;if((e=this._nextCommandHelper(t,this._previousCommand))==window.SVGPathSeg.PATHSEG_UNKNOWN)return null}else this._currentIndex++;switch(this._previousCommand=e){case window.SVGPathSeg.PATHSEG_MOVETO_REL:return new window.SVGPathSegMovetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_MOVETO_ABS:return new window.SVGPathSegMovetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_REL:return new window.SVGPathSegLinetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_ABS:return new window.SVGPathSegLinetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:return new window.SVGPathSegLinetoHorizontalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:return new window.SVGPathSegLinetoHorizontalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:return new window.SVGPathSegLinetoVerticalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:return new window.SVGPathSegLinetoVerticalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_CLOSEPATH:return this._skipOptionalSpaces(),new window.SVGPathSegClosePath(n);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:var i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicRel(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicAbs(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothRel(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothAbs(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticRel(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticAbs(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:return new window.SVGPathSegCurvetoQuadraticSmoothRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:return new window.SVGPathSegCurvetoQuadraticSmoothAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_ARC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcRel(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);case window.SVGPathSeg.PATHSEG_ARC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcAbs(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);default:throw"Unknown path seg type."}};var r=new e,a=new i(t);if(!a.initialCommandIsMoveTo())return[];for(;a.hasMoreData();){var o=a.parseSegment();if(!o)return[];r.appendSegment(o)}return r.pathSegList}),String.prototype.padEnd||(String.prototype.padEnd=function(t,e){return t>>=0,e=String(void 0!==e?e:" "),this.length>t?String(this):((t-=this.length)>e.length&&(e+=e.repeat(t/e.length)),String(this)+e.slice(0,t))}),"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(t,e){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),n=1;n'":;\[\]\/|~`{}\\])/g,"\\$1")},l.prototype.selectorTarget=function(t,e){return(e||"")+"."+Y.target+this.getTargetSelectorSuffix(t)},l.prototype.selectorTargets=function(t,e){var i=this;return(t=t||[]).length?t.map(function(t){return i.selectorTarget(t,e)}):null},l.prototype.selectorLegend=function(t){return"."+Y.legendItem+this.getTargetSelectorSuffix(t)},l.prototype.selectorLegends=function(t){var e=this;return t&&t.length?t.map(function(t){return e.selectorLegend(t)}):null},l.prototype.getClipPath=function(t){return"url("+(g(9)?"":document.URL.split("#")[0])+"#"+t+")"},l.prototype.appendClip=function(t,e){return t.append("clipPath").attr("id",e).append("rect")},l.prototype.getAxisClipX=function(t){var e=Math.max(30,this.margin.left);return t?-(1+e):-(e-1)},l.prototype.getAxisClipY=function(t){return t?-20:-this.margin.top},l.prototype.getXAxisClipX=function(){return this.getAxisClipX(!this.config.axis_rotated)},l.prototype.getXAxisClipY=function(){return this.getAxisClipY(!this.config.axis_rotated)},l.prototype.getYAxisClipX=function(){return this.config.axis_y_inner?-1:this.getAxisClipX(this.config.axis_rotated)},l.prototype.getYAxisClipY=function(){return this.getAxisClipY(this.config.axis_rotated)},l.prototype.getAxisClipWidth=function(t){var e=Math.max(30,this.margin.left),i=Math.max(30,this.margin.right);return t?this.width+2+e+i:this.margin.left+20},l.prototype.getAxisClipHeight=function(t){return(t?this.margin.bottom:this.margin.top+this.height)+20},l.prototype.getXAxisClipWidth=function(){return this.getAxisClipWidth(!this.config.axis_rotated)},l.prototype.getXAxisClipHeight=function(){return this.getAxisClipHeight(!this.config.axis_rotated)},l.prototype.getYAxisClipWidth=function(){return this.getAxisClipWidth(this.config.axis_rotated)+(this.config.axis_y_inner?20:0)},l.prototype.getYAxisClipHeight=function(){return this.getAxisClipHeight(this.config.axis_rotated)},l.prototype.generateColor=function(){var t=this.config,e=this.d3,n=t.data_colors,r=L(t.color_pattern)?t.color_pattern:e.schemeCategory10,a=t.data_color,o=[];return function(t){var e,i=t.id||t.data&&t.data.id||t;return n[i]instanceof Function?e=n[i](t):n[i]?e=n[i]:(o.indexOf(i)<0&&o.push(i),e=r[o.indexOf(i)%r.length],n[i]=e),a instanceof Function?a(e,t):e}},l.prototype.generateLevelColor=function(){var t=this.config,n=t.color_pattern,e=t.color_threshold,r="value"===e.unit,a=e.values&&e.values.length?e.values:[],o=e.max||100;return L(e)&&L(n)?function(t){var e,i=n[n.length-1];for(e=0;es&&(o=o.filter(function(t){return(""+t).indexOf(".")<0}));return o},l.prototype.getGridFilterToRemove=function(t){return t?function(e){var i=!1;return[].concat(t).forEach(function(t){("value"in t&&e.value===t.value||"class"in t&&e.class===t.class)&&(i=!0)}),i}:function(){return!0}},l.prototype.removeGridLines=function(t,e){function i(t){return!r(t)}var n=this.config,r=this.getGridFilterToRemove(t),a=e?Y.xgridLines:Y.ygridLines,o=e?Y.xgridLine:Y.ygridLine;this.main.select("."+a).selectAll("."+o).filter(r).transition().duration(n.transition_duration).style("opacity",0).remove(),e?n.grid_x_lines=n.grid_x_lines.filter(i):n.grid_y_lines=n.grid_y_lines.filter(i)},l.prototype.initEventRect=function(){var t=this,e=t.config;t.main.select("."+Y.chart).append("g").attr("class",Y.eventRects).style("fill-opacity",0),t.eventRect=t.main.select("."+Y.eventRects).append("rect").attr("class",Y.eventRect),e.zoom_enabled&&t.zoom&&(t.eventRect.call(t.zoom).on("dblclick.zoom",null),e.zoom_initialRange&&t.eventRect.transition().duration(0).call(t.zoom.transform,t.zoomTransform(e.zoom_initialRange)))},l.prototype.redrawEventRect=function(){var s=this,c=s.d3,d=s.config;function l(){s.svg.select("."+Y.eventRect).style("cursor",null),s.hideXGridFocus(),s.hideTooltip(),s.unexpandCircles(),s.unexpandBars()}function u(t,e){return e&&(s.isBarType(e.id)||s.dist(e,t)i.bar_width_max?i.bar_width_max:n},l.prototype.getBars=function(t,e){return(e?this.main.selectAll("."+Y.bars+this.getTargetSelectorSuffix(e)):this.main).selectAll("."+Y.bar+(C(t)?"-"+t:""))},l.prototype.expandBars=function(t,e,i){i&&this.unexpandBars(),this.getBars(t,e).classed(Y.EXPANDED,!0)},l.prototype.unexpandBars=function(t){this.getBars(t).classed(Y.EXPANDED,!1)},l.prototype.generateDrawBar=function(t,e){var a=this.config,o=this.generateGetBarPoints(t,e);return function(t,e){var i=o(t,e),n=a.axis_rotated?1:0,r=a.axis_rotated?0:1;return"M "+i[0][n]+","+i[0][r]+" L"+i[1][n]+","+i[1][r]+" L"+i[2][n]+","+i[2][r]+" L"+i[3][n]+","+i[3][r]+" z"}},l.prototype.generateGetBarPoints=function(t,e){var o=this,i=e?o.subXAxis:o.xAxis,n=t.__max__+1,s=o.getBarW(i,n),c=o.getShapeX(s,n,t,!!e),d=o.getShapeY(!!e),l=o.getShapeOffset(o.isBarType,t,!!e),u=s*(o.config.bar_space/2),h=e?o.getSubYScale:o.getYScale;return function(t,e){var i=h.call(o,t.id)(0),n=l(t,e)||i,r=c(t),a=d(t);return o.config.axis_rotated&&(0a.width?n=a.width-o.width:n<0&&(n=4)),n},l.prototype.getYForText=function(t,e,i){var n,r=this,a=p(i);return r.config.axis_rotated?n=(t[0][0]+t[2][0]+.6*a.height)/2:(n=t[2][1],e.value<0||0===e.value&&!r.hasPositiveValue?(n+=a.height,r.isBarType(e)&&r.isSafari()?n-=3:!r.isBarType(e)&&r.isChrome()&&(n+=3)):n+=r.isBarType(e)?-3:-6),null!==e.value||r.config.axis_rotated||(nthis.height&&(n=this.height-4)),n},l.prototype.initTitle=function(){this.title=this.svg.append("text").text(this.config.title_text).attr("class",this.CLASS.title)},l.prototype.redrawTitle=function(){var t=this;t.title.attr("x",t.xForTitle.bind(t)).attr("y",t.yForTitle.bind(t))},l.prototype.xForTitle=function(){var t=this,e=t.config,i=e.title_position||"left";return 0<=i.indexOf("right")?t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width-e.title_padding.right:0<=i.indexOf("center")?Math.max((t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width)/2,0):e.title_padding.left},l.prototype.yForTitle=function(){var t=this;return t.config.title_padding.top+t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).height},l.prototype.getTitlePadding=function(){return this.yForTitle()+this.config.title_padding.bottom},l.prototype.drawColorScale=function(){var t,e,i,n,r,a,o,s=this,c=s.d3,d=s.config,l=s.data.targets[0];if(t=isNaN(d.stanford_scaleWidth)?20:d.stanford_scaleWidth,t<0)throw Error("Colorscale's barheight and barwidth must be greater than 0.");o=s.height-d.stanford_padding.bottom-d.stanford_padding.top,i=c.range(d.stanford_padding.bottom,o,5),a=c.scaleSequential(l.colors).domain([i[i.length-1],i[0]]),s.colorScale&&s.colorScale.remove(),s.colorScale=s.svg.append("g").attr("width",50).attr("height",o).attr("class",Y.colorScale),s.colorScale.append("g").attr("transform","translate(0, ".concat(d.stanford_padding.top,")")).selectAll("bars").data(i).enter().append("rect").attr("y",function(t,e){return 5*e}).attr("x",0).attr("width",t).attr("height",5).attr("fill",function(t){return a(t)}),r=c.scaleLog().domain([l.minEpochs,l.maxEpochs]).range([i[0]+d.stanford_padding.top+i[i.length-1]+5-1,i[0]+d.stanford_padding.top]),n=c.axisRight(r),"pow10"===d.stanford_scaleFormat?n.tickValues([1,10,100,1e3,1e4,1e5,1e6,1e7]):h(d.stanford_scaleFormat)?n.tickFormat(d.stanford_scaleFormat):n.tickFormat(c.format("d")),h(d.stanford_scaleValues)&&n.tickValues(d.stanford_scaleValues(l.minEpochs,l.maxEpochs)),e=s.colorScale.append("g").attr("class","legend axis").attr("transform","translate(".concat(t,",0)")).call(n),"pow10"===d.stanford_scaleFormat&&e.selectAll(".tick text").text(null).filter(S).text(10).append("tspan").attr("dy","-.7em").text(function(t){return Math.round(Math.log(t)/Math.LN10)}),s.colorScale.attr("transform","translate(".concat(s.currentWidth-s.xForColorScale(),", 0)"))},l.prototype.xForColorScale=function(){return this.config.stanford_padding.right+p(this.colorScale.node()).width},l.prototype.getColorScalePadding=function(){return this.xForColorScale()+this.config.stanford_padding.left+20},l.prototype.isStanfordGraphType=function(){return"stanford"===this.config.data_type},l.prototype.initStanfordData=function(){var t,e,i,n=this.d3,r=this.config,a=this.data.targets[0];if(a.values.sort(T),t=a.values.map(function(t){return t.epochs}),i=isNaN(r.stanford_scaleMin)?n.min(t):r.stanford_scaleMin,(e=isNaN(r.stanford_scaleMax)?n.max(t):r.stanford_scaleMax)".concat(e?_(e):"x","").concat(t.x,"\n ").concat(i?_(i):"y","").concat(t.value,"\n ")},l.prototype.countEpochsInRegion=function(i){var t,e,n=this.data.targets[0];return t=n.values.reduce(function(t,e){return t+Number(e.epochs)},0),{value:e=n.values.reduce(function(t,e){return b(e,i)?t+Number(e.epochs):t},0),percentage:0!==e?(e/t*100).toFixed(1):0}};var w=function(t){var e,i,n,r,a=0;for(e=0,i=t.length-1;ee.epochs?1:0};return l.prototype.initStanfordElements=function(){var t=this;t.stanfordElements=t.main.select("."+Y.chart).append("g").attr("class",Y.stanfordElements),t.stanfordElements.append("g").attr("class",Y.stanfordLines),t.stanfordElements.append("g").attr("class",Y.stanfordTexts),t.stanfordElements.append("g").attr("class",Y.stanfordRegions)},l.prototype.updateStanfordElements=function(t){var e,i,n,r,a,o,s=this,c=s.main,d=s.config,l=s.xvCustom.bind(s),u=s.yvCustom.bind(s),h=s.countEpochsInRegion.bind(s);(i=(e=c.select("."+Y.stanfordLines).style("shape-rendering","geometricprecision").selectAll("."+Y.stanfordLine).data(d.stanford_lines)).enter().append("g").attr("class",function(t){return Y.stanfordLine+(t.class?" "+t.class:"")})).append("line").attr("x1",function(t){return d.axis_rotated?u(t,"value_y1"):l(t,"value_x1")}).attr("x2",function(t){return d.axis_rotated?u(t,"value_y2"):l(t,"value_x2")}).attr("y1",function(t){return d.axis_rotated?l(t,"value_x1"):u(t,"value_y1")}).attr("y2",function(t){return d.axis_rotated?l(t,"value_x2"):u(t,"value_y2")}).style("opacity",0),s.stanfordLines=i.merge(e),s.stanfordLines.select("line").transition().duration(t).attr("x1",function(t){return d.axis_rotated?u(t,"value_y1"):l(t,"value_x1")}).attr("x2",function(t){return d.axis_rotated?u(t,"value_y2"):l(t,"value_x2")}).attr("y1",function(t){return d.axis_rotated?l(t,"value_x1"):u(t,"value_y1")}).attr("y2",function(t){return d.axis_rotated?l(t,"value_x2"):u(t,"value_y2")}).style("opacity",1),e.exit().transition().duration(t).style("opacity",0).remove(),(o=(a=c.select("."+Y.stanfordTexts).selectAll("."+Y.stanfordText).data(d.stanford_texts)).enter().append("g").attr("class",function(t){return Y.stanfordText+(t.class?" "+t.class:"")})).append("text").attr("x",function(t){return d.axis_rotated?u(t,"y"):l(t,"x")}).attr("y",function(t){return d.axis_rotated?l(t,"x"):u(t,"y")}).style("opacity",0),s.stanfordTexts=o.merge(a),s.stanfordTexts.select("text").transition().duration(t).attr("x",function(t){return d.axis_rotated?u(t,"y"):l(t,"x")}).attr("y",function(t){return d.axis_rotated?l(t,"x"):u(t,"y")}).text(function(t){return t.content}).style("opacity",1),a.exit().transition().duration(t).style("opacity",0).remove(),(r=(n=c.select("."+Y.stanfordRegions).selectAll("."+Y.stanfordRegion).data(d.stanford_regions)).enter().append("g").attr("class",function(t){return Y.stanfordRegion+(t.class?" "+t.class:"")})).append("polygon").attr("points",function(t){return t.points.map(function(t){return[d.axis_rotated?u(t,"y"):l(t,"x"),d.axis_rotated?l(t,"x"):u(t,"y")].join(",")}).join(" ")}).style("opacity",0),r.append("text").attr("x",function(t){return s.getCentroid(t.points).x}).attr("y",function(t){return s.getCentroid(t.points).y}).style("opacity",0),s.stanfordRegions=r.merge(n),s.stanfordRegions.select("polygon").transition().duration(t).attr("points",function(t){return t.points.map(function(t){return[d.axis_rotated?u(t,"y"):l(t,"x"),d.axis_rotated?l(t,"x"):u(t,"y")].join(",")}).join(" ")}).style("opacity",function(t){return t.opacity?t.opacity:.2}),s.stanfordRegions.select("text").transition().duration(t).attr("x",function(t){return d.axis_rotated?u(s.getCentroid(t.points),"y"):l(s.getCentroid(t.points),"x")}).attr("y",function(t){return d.axis_rotated?l(s.getCentroid(t.points),"x"):u(s.getCentroid(t.points),"y")}).text(function(t){var e,i,n;return t.text?(s.isStanfordGraphType()&&(e=(n=h(t.points)).value,i=n.percentage),t.text(e,i)):""}).attr("text-anchor","middle").attr("dominant-baseline","middle").style("opacity",1),n.exit().transition().duration(t).style("opacity",0).remove()},l.prototype.initTooltip=function(){var t,e=this,i=e.config;if(e.tooltip=e.selectChart.style("position","relative").append("div").attr("class",Y.tooltipContainer).style("position","absolute").style("pointer-events","none").style("display","none"),i.tooltip_init_show){if(e.isTimeSeries()&&f(i.tooltip_init_x)){for(i.tooltip_init_x=e.parseDate(i.tooltip_init_x),t=0;t"+o),d=l.getStanfordPointColor(t[a]),c=_(u.data_epochs),s=t[a].epochs;else if(r||(o=_(h?h(t[a].x,t[a].index):t[a].x),r=""+(o||0===o?"":"")),void 0!==(s=_(p(t[a].value,t[a].ratio,t[a].id,t[a].index,t)))){if(null===t[a].name)continue;c=_(g(t[a].name,t[a].ratio,t[a].id,t[a].index)),d=l.levelColor?l.levelColor(t[a].value):n(t[a].id)}void 0!==s&&(r+="",r+="",r+="",r+="")}return r+"
"+o+"
"+c+""+s+"
"},l.prototype.tooltipPosition=function(t,e,i,n){var r,a,o,s,c,d=this,l=d.config,u=d.d3,h=d.hasArcType(),g=u.mouse(n);return h?(a=(d.width-(d.isLegendRight?d.getLegendWidth():0))/2+g[0],s=(d.hasType("gauge")?d.height:d.height/2)+g[1]+20):(r=d.getSvgLeft(!0),s=l.axis_rotated?(o=(a=r+g[0]+100)+e,c=d.currentWidth-d.getCurrentPaddingRight(),d.x(t[0].x)+20):(o=(a=r+d.getCurrentPaddingLeft(!0)+d.x(t[0].x)+20)+e,c=r+d.currentWidth-d.getCurrentPaddingRight(),g[1]+15),cd.currentHeight&&(s-=i+30)),s<0&&(s=0),{top:s,left:a}},l.prototype.showTooltip=function(t,e){var i,n,r,a=this,o=a.config,s=a.hasArcType(),c=t.filter(function(t){return t&&C(t.value)}),d=o.tooltip_position||l.prototype.tooltipPosition;0!==c.length&&o.tooltip_show&&(a.tooltip.html(o.tooltip_contents.call(a,t,a.axis.getXAxisTickFormat(),a.getYFormat(s),a.color)).style("display","block"),i=a.tooltip.property("offsetWidth"),n=a.tooltip.property("offsetHeight"),r=d.call(this,c,i,n,e),a.tooltip.style("top",r.top+"px").style("left",r.left+"px"))},l.prototype.hideTooltip=function(){this.tooltip.style("display","none")},l.prototype.setTargetType=function(t,e){var i=this,n=i.config;i.mapToTargetIds(t).forEach(function(t){i.withoutFadeIn[t]=e===n.data_types[t],n.data_types[t]=e}),t||(n.data_type=e)},l.prototype.hasType=function(i,t){var n=this.config.data_types,r=!1;return(t=t||this.data.targets)&&t.length?t.forEach(function(t){var e=n[t.id];(e&&0<=e.indexOf(i)||!e&&"line"===i)&&(r=!0)}):Object.keys(n).length?Object.keys(n).forEach(function(t){n[t]===i&&(r=!0)}):r=this.config.data_type===i,r},l.prototype.hasArcType=function(t){return this.hasType("pie",t)||this.hasType("donut",t)||this.hasType("gauge",t)},l.prototype.isLineType=function(t){var e=this.config,i=f(t)?t:t.id;return!e.data_types[i]||0<=["line","spline","area","area-spline","step","area-step"].indexOf(e.data_types[i])},l.prototype.isStepType=function(t){var e=f(t)?t:t.id;return 0<=["step","area-step"].indexOf(this.config.data_types[e])},l.prototype.isSplineType=function(t){var e=f(t)?t:t.id;return 0<=["spline","area-spline"].indexOf(this.config.data_types[e])},l.prototype.isAreaType=function(t){var e=f(t)?t:t.id;return 0<=["area","area-spline","area-step"].indexOf(this.config.data_types[e])},l.prototype.isBarType=function(t){var e=f(t)?t:t.id;return"bar"===this.config.data_types[e]},l.prototype.isScatterType=function(t){var e=f(t)?t:t.id;return"scatter"===this.config.data_types[e]},l.prototype.isStanfordType=function(t){var e=f(t)?t:t.id;return"stanford"===this.config.data_types[e]},l.prototype.isPieType=function(t){var e=f(t)?t:t.id;return"pie"===this.config.data_types[e]},l.prototype.isGaugeType=function(t){var e=f(t)?t:t.id;return"gauge"===this.config.data_types[e]},l.prototype.isDonutType=function(t){var e=f(t)?t:t.id;return"donut"===this.config.data_types[e]},l.prototype.isArcType=function(t){return this.isPieType(t)||this.isDonutType(t)||this.isGaugeType(t)},l.prototype.lineData=function(t){return this.isLineType(t)?[t]:[]},l.prototype.arcData=function(t){return this.isArcType(t.data)?[t]:[]},l.prototype.barData=function(t){return this.isBarType(t)?t.values:[]},l.prototype.lineOrScatterOrStanfordData=function(t){return this.isLineType(t)||this.isScatterType(t)||this.isStanfordType(t)?t.values:[]},l.prototype.barOrLineData=function(t){return this.isBarType(t)||this.isLineType(t)?t.values:[]},l.prototype.isSafari=function(){var t=window.navigator.userAgent;return 0<=t.indexOf("Safari")&&t.indexOf("Chrome")<0},l.prototype.isChrome=function(){return 0<=window.navigator.userAgent.indexOf("Chrome")},l.prototype.initZoom=function(){var e,i=this,n=i.d3,r=i.config;return i.zoom=n.zoom().on("start",function(){if("scroll"===r.zoom_type){var t=n.event.sourceEvent;t&&"brush"===t.type||(e=t,r.zoom_onzoomstart.call(i.api,t))}}).on("zoom",function(){if("scroll"===r.zoom_type){var t=n.event.sourceEvent;t&&"brush"===t.type||(i.redrawForZoom(),r.zoom_onzoom.call(i.api,i.x.orgDomain()))}}).on("end",function(){if("scroll"===r.zoom_type){var t=n.event.sourceEvent;t&&"brush"===t.type||t&&e.clientX===t.clientX&&e.clientY===t.clientY||r.zoom_onzoomend.call(i.api,i.x.orgDomain())}}),i.zoom.updateDomain=function(){return n.event&&n.event.transform&&i.x.domain(n.event.transform.rescaleX(i.subX).domain()),this},i.zoom.updateExtent=function(){return this.scaleExtent([1,1/0]).translateExtent([[0,0],[i.width,i.height]]).extent([[0,0],[i.width,i.height]]),this},i.zoom.update=function(){return this.updateExtent().updateDomain()},i.zoom.updateExtent()},l.prototype.zoomTransform=function(t){var e=[this.x(t[0]),this.x(t[1])];return this.d3.zoomIdentity.scale(this.width/(e[1]-e[0])).translate(-e[0],0)},l.prototype.initDragZoom=function(){var e=this,i=e.d3,n=e.config,t=e.context=e.svg,r=e.margin.left+20.5,a=e.margin.top+.5;if("drag"===n.zoom_type&&n.zoom_enabled){var o=function(t){return t&&t.map(function(t){return e.x.invert(t)})},s=e.dragZoomBrush=i.brushX().on("start",function(){e.api.unzoom(),e.svg.select("."+Y.dragZoom).classed("disabled",!1),n.zoom_onzoomstart.call(e.api,i.event.sourceEvent)}).on("brush",function(){n.zoom_onzoom.call(e.api,o(i.event.selection))}).on("end",function(){if(null!=i.event.selection){var t=o(i.event.selection);n.zoom_disableDefaultBehavior||e.api.zoom(t),e.svg.select("."+Y.dragZoom).classed("disabled",!0),n.zoom_onzoomend.call(e.api,t)}});t.append("g").classed(Y.dragZoom,!0).attr("clip-path",e.clipPath).attr("transform","translate("+r+","+a+")").call(s)}},l.prototype.getZoomDomain=function(){var t=this.config,e=this.d3;return[e.min([this.orgXDomain[0],t.zoom_x_min]),e.max([this.orgXDomain[1],t.zoom_x_max])]},l.prototype.redrawForZoom=function(){var t=this,e=t.d3,i=t.config,n=t.zoom,r=t.x;i.zoom_enabled&&0!==t.filterTargetsToShow(t.data.targets).length&&(n.update(),i.zoom_disableDefaultBehavior||(t.isCategorized()&&r.orgDomain()[0]===t.orgXDomain[0]&&r.domain([t.orgXDomain[0]-1e-10,r.orgDomain()[1]]),t.redraw({withTransition:!1,withY:i.zoom_rescale,withSubchart:!1,withEventRect:!1,withDimension:!1}),e.event.sourceEvent&&"mousemove"===e.event.sourceEvent.type&&(t.cancelClick=!0)))},t}); \ No newline at end of file +/* @license C3.js v0.7.16 | (c) C3 Team and other contributors | http://c3js.org/ */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).c3=e()}(this,function(){"use strict";function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t){return function(t){if(Array.isArray(t))return n(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return n(t,e);var i=Object.prototype.toString.call(t).slice(8,-1);"Object"===i&&t.constructor&&(i=t.constructor.name);if("Map"===i||"Set"===i)return Array.from(t);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return n(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(t,e){(null==e||e>t.length)&&(e=t.length);for(var i=0,n=new Array(e);i/g,">"):t}function p(t){var e=function(t){void 0===t&&(t=window.navigator.userAgent);var e=t.indexOf("MSIE ");return 0e.getTotalLength())break;i--}while(0=this.numberOfItems)throw"INDEX_SIZE_ERR"},window.SVGPathSegList.prototype.getItem=function(t){return this._checkPathSynchronizedToList(),this._checkValidIndex(t),this._list[t]},window.SVGPathSegList.prototype.insertItemBefore=function(t,e){return this._checkPathSynchronizedToList(),e>this.numberOfItems&&(e=this.numberOfItems),t._owningPathSegList&&(t=t.clone()),this._list.splice(e,0,t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.replaceItem=function(t,e){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._checkValidIndex(e),((this._list[e]=t)._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.removeItem=function(t){this._checkPathSynchronizedToList(),this._checkValidIndex(t);var e=this._list[t];return this._list.splice(t,1),this._writeListToPath(),e},window.SVGPathSegList.prototype.appendItem=function(t){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._list.push(t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList._pathSegArrayAsString=function(t){var e="",i=!0;return t.forEach(function(t){i?(i=!1,e+=t._asPathString()):e+=" "+t._asPathString()}),e},window.SVGPathSegList.prototype._parsePath=function(t){if(!t||0==t.length)return[];function e(){this.pathSegList=[]}var n=this;e.prototype.appendSegment=function(t){this.pathSegList.push(t)};function i(t){this._string=t,this._currentIndex=0,this._endIndex=this._string.length,this._previousCommand=window.SVGPathSeg.PATHSEG_UNKNOWN,this._skipOptionalSpaces()}i.prototype._isCurrentSpace=function(){var t=this._string[this._currentIndex];return t<=" "&&(" "==t||"\n"==t||"\t"==t||"\r"==t||"\f"==t)},i.prototype._skipOptionalSpaces=function(){for(;this._currentIndex=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex)){var t=!1,e=this._string.charAt(this._currentIndex++);if("0"==e)t=!1;else{if("1"!=e)return;t=!0}return this._skipOptionalSpacesOrDelimiter(),t}},i.prototype.parseSegment=function(){var t=this._string[this._currentIndex],e=this._pathSegTypeFromChar(t);if(e==window.SVGPathSeg.PATHSEG_UNKNOWN){if(this._previousCommand==window.SVGPathSeg.PATHSEG_UNKNOWN)return null;if((e=this._nextCommandHelper(t,this._previousCommand))==window.SVGPathSeg.PATHSEG_UNKNOWN)return null}else this._currentIndex++;switch(this._previousCommand=e){case window.SVGPathSeg.PATHSEG_MOVETO_REL:return new window.SVGPathSegMovetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_MOVETO_ABS:return new window.SVGPathSegMovetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_REL:return new window.SVGPathSegLinetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_ABS:return new window.SVGPathSegLinetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:return new window.SVGPathSegLinetoHorizontalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:return new window.SVGPathSegLinetoHorizontalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:return new window.SVGPathSegLinetoVerticalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:return new window.SVGPathSegLinetoVerticalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_CLOSEPATH:return this._skipOptionalSpaces(),new window.SVGPathSegClosePath(n);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:var i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicRel(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicAbs(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothRel(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothAbs(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticRel(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticAbs(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:return new window.SVGPathSegCurvetoQuadraticSmoothRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:return new window.SVGPathSegCurvetoQuadraticSmoothAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_ARC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcRel(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);case window.SVGPathSeg.PATHSEG_ARC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcAbs(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);default:throw"Unknown path seg type."}};var r=new e,a=new i(t);if(!a.initialCommandIsMoveTo())return[];for(;a.hasMoreData();){var o=a.parseSegment();if(!o)return[];r.appendSegment(o)}return r.pathSegList}),String.prototype.padEnd||(String.prototype.padEnd=function(t,e){return t>>=0,e=String(void 0!==e?e:" "),this.length>t?String(this):((t-=this.length)>e.length&&(e+=e.repeat(t/e.length)),String(this)+e.slice(0,t))}),"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(t,e){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),n=1;n'":;\[\]\/|~`{}\\])/g,"\\$1")},l.prototype.selectorTarget=function(t,e){return(e||"")+"."+Y.target+this.getTargetSelectorSuffix(t)},l.prototype.selectorTargets=function(t,e){var i=this;return(t=t||[]).length?t.map(function(t){return i.selectorTarget(t,e)}):null},l.prototype.selectorLegend=function(t){return"."+Y.legendItem+this.getTargetSelectorSuffix(t)},l.prototype.selectorLegends=function(t){var e=this;return t&&t.length?t.map(function(t){return e.selectorLegend(t)}):null},l.prototype.getClipPath=function(t){return"url("+(p(9)?"":document.URL.split("#")[0])+"#"+t+")"},l.prototype.appendClip=function(t,e){return t.append("clipPath").attr("id",e).append("rect")},l.prototype.getAxisClipX=function(t){var e=Math.max(30,this.margin.left);return t?-(1+e):-(e-1)},l.prototype.getAxisClipY=function(t){return t?-20:-this.margin.top},l.prototype.getXAxisClipX=function(){return this.getAxisClipX(!this.config.axis_rotated)},l.prototype.getXAxisClipY=function(){return this.getAxisClipY(!this.config.axis_rotated)},l.prototype.getYAxisClipX=function(){return this.config.axis_y_inner?-1:this.getAxisClipX(this.config.axis_rotated)},l.prototype.getYAxisClipY=function(){return this.getAxisClipY(this.config.axis_rotated)},l.prototype.getAxisClipWidth=function(t){var e=Math.max(30,this.margin.left),i=Math.max(30,this.margin.right);return t?this.width+2+e+i:this.margin.left+20},l.prototype.getAxisClipHeight=function(t){return(t?this.margin.bottom:this.margin.top+this.height)+20},l.prototype.getXAxisClipWidth=function(){return this.getAxisClipWidth(!this.config.axis_rotated)},l.prototype.getXAxisClipHeight=function(){return this.getAxisClipHeight(!this.config.axis_rotated)},l.prototype.getYAxisClipWidth=function(){return this.getAxisClipWidth(this.config.axis_rotated)+(this.config.axis_y_inner?20:0)},l.prototype.getYAxisClipHeight=function(){return this.getAxisClipHeight(this.config.axis_rotated)},l.prototype.generateColor=function(){var t=this.config,e=this.d3,n=t.data_colors,r=L(t.color_pattern)?t.color_pattern:e.schemeCategory10,a=t.data_color,o=[];return function(t){var e,i=t.id||t.data&&t.data.id||t;return n[i]instanceof Function?e=n[i](t):n[i]?e=n[i]:(o.indexOf(i)<0&&o.push(i),e=r[o.indexOf(i)%r.length],n[i]=e),a instanceof Function?a(e,t):e}},l.prototype.generateLevelColor=function(){var t=this.config,n=t.color_pattern,e=t.color_threshold,r="value"===e.unit,a=e.values&&e.values.length?e.values:[],o=e.max||100;return L(e)&&L(n)?function(t){for(var e=n[n.length-1],i=0;is&&(o=o.filter(function(t){return(""+t).indexOf(".")<0}));return o},l.prototype.getGridFilterToRemove=function(t){return t?function(e){var i=!1;return[].concat(t).forEach(function(t){("value"in t&&e.value===t.value||"class"in t&&e.class===t.class)&&(i=!0)}),i}:function(){return!0}},l.prototype.removeGridLines=function(t,e){function i(t){return!r(t)}var n=this.config,r=this.getGridFilterToRemove(t),a=e?Y.xgridLines:Y.ygridLines,o=e?Y.xgridLine:Y.ygridLine;this.main.select("."+a).selectAll("."+o).filter(r).transition().duration(n.transition_duration).style("opacity",0).remove(),e?n.grid_x_lines=n.grid_x_lines.filter(i):n.grid_y_lines=n.grid_y_lines.filter(i)},l.prototype.initEventRect=function(){var t=this,e=t.config;t.main.select("."+Y.chart).append("g").attr("class",Y.eventRects).style("fill-opacity",0),t.eventRect=t.main.select("."+Y.eventRects).append("rect").attr("class",Y.eventRect),e.zoom_enabled&&t.zoom&&(t.eventRect.call(t.zoom).on("dblclick.zoom",null),e.zoom_initialRange&&t.eventRect.transition().duration(0).call(t.zoom.transform,t.zoomTransform(e.zoom_initialRange)))},l.prototype.redrawEventRect=function(){var s=this,c=s.d3,d=s.config;function l(){s.svg.select("."+Y.eventRect).style("cursor",null),s.hideXGridFocus(),s.hideTooltip(),s.unexpandCircles(),s.unexpandBars()}function u(t,e){return e&&(s.isBarType(e.id)||s.dist(e,t)i.bar_width_max?i.bar_width_max:n},l.prototype.getBars=function(t,e){return(e?this.main.selectAll("."+Y.bars+this.getTargetSelectorSuffix(e)):this.main).selectAll("."+Y.bar+(C(t)?"-"+t:""))},l.prototype.expandBars=function(t,e,i){i&&this.unexpandBars(),this.getBars(t,e).classed(Y.EXPANDED,!0)},l.prototype.unexpandBars=function(t){this.getBars(t).classed(Y.EXPANDED,!1)},l.prototype.generateDrawBar=function(t,e){var a=this.config,o=this.generateGetBarPoints(t,e);return function(t,e){var i=o(t,e),n=a.axis_rotated?1:0,r=a.axis_rotated?0:1;return"M "+i[0][n]+","+i[0][r]+" L"+i[1][n]+","+i[1][r]+" L"+i[2][n]+","+i[2][r]+" L"+i[3][n]+","+i[3][r]+" z"}},l.prototype.generateGetBarPoints=function(t,e){var o=this,i=e?o.subXAxis:o.xAxis,n=t.__max__+1,s=o.getBarW(i,n),c=o.getShapeX(s,n,t,!!e),d=o.getShapeY(!!e),l=o.getShapeOffset(o.isBarType,t,!!e),u=s*(o.config.bar_space/2),h=e?o.getSubYScale:o.getYScale;return function(t,e){var i=h.call(o,t.id)(0),n=l(t,e)||i,r=c(t),a=d(t);return o.config.axis_rotated&&(0r.width?o=r.width-a.width:o<0&&(o=4)),o},l.prototype.getYForText=function(t,e,i){var n,r=this,a=f(i);return r.config.axis_rotated?n=(t[0][0]+t[2][0]+.6*a.height)/2:(n=t[2][1],e.value<0||0===e.value&&!r.hasPositiveValue?(n+=a.height,r.isBarType(e)&&r.isSafari()?n-=3:!r.isBarType(e)&&r.isChrome()&&(n+=3)):n+=r.isBarType(e)?-3:-6),null!==e.value||r.config.axis_rotated||(nthis.height&&(n=this.height-4)),n},l.prototype.initTitle=function(){this.title=this.svg.append("text").text(this.config.title_text).attr("class",this.CLASS.title)},l.prototype.redrawTitle=function(){var t=this;t.title.attr("x",t.xForTitle.bind(t)).attr("y",t.yForTitle.bind(t))},l.prototype.xForTitle=function(){var t=this,e=t.config,i=e.title_position||"left",n=0<=i.indexOf("right")?t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width-e.title_padding.right:0<=i.indexOf("center")?Math.max((t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width)/2,0):e.title_padding.left;return n},l.prototype.yForTitle=function(){var t=this;return t.config.title_padding.top+t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).height},l.prototype.getTitlePadding=function(){return this.yForTitle()+this.config.title_padding.bottom},l.prototype.drawColorScale=function(){var t,e,i,n,r,a,o=this,s=o.d3,c=o.config,d=o.data.targets[0],l=isNaN(c.stanford_scaleWidth)?20:c.stanford_scaleWidth;if(l<0)throw Error("Colorscale's barheight and barwidth must be greater than 0.");a=o.height-c.stanford_padding.bottom-c.stanford_padding.top,e=s.range(c.stanford_padding.bottom,a,5),r=s.scaleSequential(d.colors).domain([e[e.length-1],e[0]]),o.colorScale&&o.colorScale.remove(),o.colorScale=o.svg.append("g").attr("width",50).attr("height",a).attr("class",Y.colorScale),o.colorScale.append("g").attr("transform","translate(0, ".concat(c.stanford_padding.top,")")).selectAll("bars").data(e).enter().append("rect").attr("y",function(t,e){return 5*e}).attr("x",0).attr("width",l).attr("height",5).attr("fill",function(t){return r(t)}),n=s.scaleLog().domain([d.minEpochs,d.maxEpochs]).range([e[0]+c.stanford_padding.top+e[e.length-1]+5-1,e[0]+c.stanford_padding.top]),i=s.axisRight(n),"pow10"===c.stanford_scaleFormat?i.tickValues([1,10,100,1e3,1e4,1e5,1e6,1e7]):g(c.stanford_scaleFormat)?i.tickFormat(c.stanford_scaleFormat):i.tickFormat(s.format("d")),g(c.stanford_scaleValues)&&i.tickValues(c.stanford_scaleValues(d.minEpochs,d.maxEpochs)),t=o.colorScale.append("g").attr("class","legend axis").attr("transform","translate(".concat(l,",0)")).call(i),"pow10"===c.stanford_scaleFormat&&t.selectAll(".tick text").text(null).filter(v).text(10).append("tspan").attr("dy","-.7em").text(function(t){return Math.round(Math.log(t)/Math.LN10)}),o.colorScale.attr("transform","translate(".concat(o.currentWidth-o.xForColorScale(),", 0)"))},l.prototype.xForColorScale=function(){return this.config.stanford_padding.right+f(this.colorScale.node()).width},l.prototype.getColorScalePadding=function(){return this.xForColorScale()+this.config.stanford_padding.left+20},l.prototype.isStanfordGraphType=function(){return"stanford"===this.config.data_type},l.prototype.initStanfordData=function(){var t,e,i,n=this.d3,r=this.config,a=this.data.targets[0];if(a.values.sort(A),t=a.values.map(function(t){return t.epochs}),i=isNaN(r.stanford_scaleMin)?n.min(t):r.stanford_scaleMin,(e=isNaN(r.stanford_scaleMax)?n.max(t):r.stanford_scaleMax)".concat(e?_(e):"x","").concat(t.x,"\n ").concat(i?_(i):"y","").concat(t.value,"\n ")},l.prototype.countEpochsInRegion=function(i){var t=this.data.targets[0],e=t.values.reduce(function(t,e){return t+Number(e.epochs)},0),n=t.values.reduce(function(t,e){return T(e,i)?t+Number(e.epochs):t},0);return{value:n,percentage:0!==n?(n/e*100).toFixed(1):0}};var b=function(t){for(var e,i,n=0,r=0,a=t.length-1;re.epochs?1:0};return l.prototype.initStanfordElements=function(){var t=this;t.stanfordElements=t.main.select("."+Y.chart).append("g").attr("class",Y.stanfordElements),t.stanfordElements.append("g").attr("class",Y.stanfordLines),t.stanfordElements.append("g").attr("class",Y.stanfordTexts),t.stanfordElements.append("g").attr("class",Y.stanfordRegions)},l.prototype.updateStanfordElements=function(t){var e,i,n,r,a=this,o=a.main,s=a.config,c=a.xvCustom.bind(a),d=a.yvCustom.bind(a),l=a.countEpochsInRegion.bind(a),u=o.select("."+Y.stanfordLines).style("shape-rendering","geometricprecision").selectAll("."+Y.stanfordLine).data(s.stanford_lines),h=u.enter().append("g").attr("class",function(t){return Y.stanfordLine+(t.class?" "+t.class:"")});h.append("line").attr("x1",function(t){return s.axis_rotated?d(t,"value_y1"):c(t,"value_x1")}).attr("x2",function(t){return s.axis_rotated?d(t,"value_y2"):c(t,"value_x2")}).attr("y1",function(t){return s.axis_rotated?c(t,"value_x1"):d(t,"value_y1")}).attr("y2",function(t){return s.axis_rotated?c(t,"value_x2"):d(t,"value_y2")}).style("opacity",0),a.stanfordLines=h.merge(u),a.stanfordLines.select("line").transition().duration(t).attr("x1",function(t){return s.axis_rotated?d(t,"value_y1"):c(t,"value_x1")}).attr("x2",function(t){return s.axis_rotated?d(t,"value_y2"):c(t,"value_x2")}).attr("y1",function(t){return s.axis_rotated?c(t,"value_x1"):d(t,"value_y1")}).attr("y2",function(t){return s.axis_rotated?c(t,"value_x2"):d(t,"value_y2")}).style("opacity",1),u.exit().transition().duration(t).style("opacity",0).remove(),(r=(n=o.select("."+Y.stanfordTexts).selectAll("."+Y.stanfordText).data(s.stanford_texts)).enter().append("g").attr("class",function(t){return Y.stanfordText+(t.class?" "+t.class:"")})).append("text").attr("x",function(t){return s.axis_rotated?d(t,"y"):c(t,"x")}).attr("y",function(t){return s.axis_rotated?c(t,"x"):d(t,"y")}).style("opacity",0),a.stanfordTexts=r.merge(n),a.stanfordTexts.select("text").transition().duration(t).attr("x",function(t){return s.axis_rotated?d(t,"y"):c(t,"x")}).attr("y",function(t){return s.axis_rotated?c(t,"x"):d(t,"y")}).text(function(t){return t.content}).style("opacity",1),n.exit().transition().duration(t).style("opacity",0).remove(),(i=(e=o.select("."+Y.stanfordRegions).selectAll("."+Y.stanfordRegion).data(s.stanford_regions)).enter().append("g").attr("class",function(t){return Y.stanfordRegion+(t.class?" "+t.class:"")})).append("polygon").attr("points",function(t){return t.points.map(function(t){return[s.axis_rotated?d(t,"y"):c(t,"x"),s.axis_rotated?c(t,"x"):d(t,"y")].join(",")}).join(" ")}).style("opacity",0),i.append("text").attr("x",function(t){return a.getCentroid(t.points).x}).attr("y",function(t){return a.getCentroid(t.points).y}).style("opacity",0),a.stanfordRegions=i.merge(e),a.stanfordRegions.select("polygon").transition().duration(t).attr("points",function(t){return t.points.map(function(t){return[s.axis_rotated?d(t,"y"):c(t,"x"),s.axis_rotated?c(t,"x"):d(t,"y")].join(",")}).join(" ")}).style("opacity",function(t){return t.opacity?t.opacity:.2}),a.stanfordRegions.select("text").transition().duration(t).attr("x",function(t){return s.axis_rotated?d(a.getCentroid(t.points),"y"):c(a.getCentroid(t.points),"x")}).attr("y",function(t){return s.axis_rotated?c(a.getCentroid(t.points),"x"):d(a.getCentroid(t.points),"y")}).text(function(t){var e,i,n;return t.text?(a.isStanfordGraphType()&&(e=(n=l(t.points)).value,i=n.percentage),t.text(e,i)):""}).attr("text-anchor","middle").attr("dominant-baseline","middle").style("opacity",1),e.exit().transition().duration(t).style("opacity",0).remove()},l.prototype.initTooltip=function(){var t,e=this,i=e.config;if(e.tooltip=e.selectChart.style("position","relative").append("div").attr("class",Y.tooltipContainer).style("position","absolute").style("pointer-events","none").style("display","none"),i.tooltip_init_show){if(e.isTimeSeries()&&x(i.tooltip_init_x)){for(i.tooltip_init_x=e.parseDate(i.tooltip_init_x),t=0;t"+o),d=l.getStanfordPointColor(t[a]),c=_(u.data_epochs),s=t[a].epochs;else if(r||(o=_(h?h(t[a].x,t[a].index):t[a].x),r=""+(o||0===o?"":"")),void 0!==(s=_(p(t[a].value,t[a].ratio,t[a].id,t[a].index,t)))){if(null===t[a].name)continue;c=_(g(t[a].name,t[a].ratio,t[a].id,t[a].index)),d=l.levelColor?l.levelColor(t[a].value):n(t[a].id)}void 0!==s&&(r+="",r+="",r+="",r+="")}return r+"
"+o+"
"+c+""+s+"
"},l.prototype.tooltipPosition=function(t,e,i,n){var r,a,o,s,c,d=this,l=d.config,u=d.d3,h=d.hasArcType(),g=u.mouse(n);return h?(a=(d.width-(d.isLegendRight?d.getLegendWidth():0))/2+g[0],s=(d.hasType("gauge")?d.height:d.height/2)+g[1]+20):(r=d.getSvgLeft(!0),s=l.axis_rotated?(o=(a=r+g[0]+100)+e,c=d.currentWidth-d.getCurrentPaddingRight(),d.x(t[0].x)+20):(o=(a=r+d.getCurrentPaddingLeft(!0)+d.x(t[0].x)+20)+e,c=r+d.currentWidth-d.getCurrentPaddingRight(),g[1]+15),cd.currentHeight&&(s-=i+30)),s<0&&(s=0),{top:s,left:a}},l.prototype.showTooltip=function(t,e){var i,n,r,a=this,o=a.config,s=a.hasArcType(),c=t.filter(function(t){return t&&C(t.value)}),d=o.tooltip_position||l.prototype.tooltipPosition;0!==c.length&&o.tooltip_show&&(a.tooltip.html(o.tooltip_contents.call(a,t,a.axis.getXAxisTickFormat(),a.getYFormat(s),a.color)).style("display","block"),i=a.tooltip.property("offsetWidth"),n=a.tooltip.property("offsetHeight"),r=d.call(this,c,i,n,e),a.tooltip.style("top",r.top+"px").style("left",r.left+"px"))},l.prototype.hideTooltip=function(){this.tooltip.style("display","none")},l.prototype.setTargetType=function(t,e){var i=this,n=i.config;i.mapToTargetIds(t).forEach(function(t){i.withoutFadeIn[t]=e===n.data_types[t],n.data_types[t]=e}),t||(n.data_type=e)},l.prototype.hasType=function(i,t){var n=this.config.data_types,r=!1;return(t=t||this.data.targets)&&t.length?t.forEach(function(t){var e=n[t.id];(e&&0<=e.indexOf(i)||!e&&"line"===i)&&(r=!0)}):Object.keys(n).length?Object.keys(n).forEach(function(t){n[t]===i&&(r=!0)}):r=this.config.data_type===i,r},l.prototype.hasArcType=function(t){return this.hasType("pie",t)||this.hasType("donut",t)||this.hasType("gauge",t)},l.prototype.isLineType=function(t){var e=this.config,i=x(t)?t:t.id;return!e.data_types[i]||0<=["line","spline","area","area-spline","step","area-step"].indexOf(e.data_types[i])},l.prototype.isStepType=function(t){var e=x(t)?t:t.id;return 0<=["step","area-step"].indexOf(this.config.data_types[e])},l.prototype.isSplineType=function(t){var e=x(t)?t:t.id;return 0<=["spline","area-spline"].indexOf(this.config.data_types[e])},l.prototype.isAreaType=function(t){var e=x(t)?t:t.id;return 0<=["area","area-spline","area-step"].indexOf(this.config.data_types[e])},l.prototype.isBarType=function(t){var e=x(t)?t:t.id;return"bar"===this.config.data_types[e]},l.prototype.isScatterType=function(t){var e=x(t)?t:t.id;return"scatter"===this.config.data_types[e]},l.prototype.isStanfordType=function(t){var e=x(t)?t:t.id;return"stanford"===this.config.data_types[e]},l.prototype.isPieType=function(t){var e=x(t)?t:t.id;return"pie"===this.config.data_types[e]},l.prototype.isGaugeType=function(t){var e=x(t)?t:t.id;return"gauge"===this.config.data_types[e]},l.prototype.isDonutType=function(t){var e=x(t)?t:t.id;return"donut"===this.config.data_types[e]},l.prototype.isArcType=function(t){return this.isPieType(t)||this.isDonutType(t)||this.isGaugeType(t)},l.prototype.lineData=function(t){return this.isLineType(t)?[t]:[]},l.prototype.arcData=function(t){return this.isArcType(t.data)?[t]:[]},l.prototype.barData=function(t){return this.isBarType(t)?t.values:[]},l.prototype.lineOrScatterOrStanfordData=function(t){return this.isLineType(t)||this.isScatterType(t)||this.isStanfordType(t)?t.values:[]},l.prototype.barOrLineData=function(t){return this.isBarType(t)||this.isLineType(t)?t.values:[]},l.prototype.isSafari=function(){var t=window.navigator.userAgent;return 0<=t.indexOf("Safari")&&t.indexOf("Chrome")<0},l.prototype.isChrome=function(){return 0<=window.navigator.userAgent.indexOf("Chrome")},l.prototype.initZoom=function(){var e,i=this,n=i.d3,r=i.config;return i.zoom=n.zoom().on("start",function(){var t;"scroll"===r.zoom_type&&((t=n.event.sourceEvent)&&"brush"===t.type||(e=t,r.zoom_onzoomstart.call(i.api,t)))}).on("zoom",function(){var t;"scroll"===r.zoom_type&&((t=n.event.sourceEvent)&&"brush"===t.type||(i.redrawForZoom(),r.zoom_onzoom.call(i.api,i.x.orgDomain())))}).on("end",function(){var t;"scroll"===r.zoom_type&&((t=n.event.sourceEvent)&&"brush"===t.type||t&&e.clientX===t.clientX&&e.clientY===t.clientY||r.zoom_onzoomend.call(i.api,i.x.orgDomain()))}),i.zoom.updateDomain=function(){return n.event&&n.event.transform&&i.x.domain(n.event.transform.rescaleX(i.subX).domain()),this},i.zoom.updateExtent=function(){return this.scaleExtent([1,1/0]).translateExtent([[0,0],[i.width,i.height]]).extent([[0,0],[i.width,i.height]]),this},i.zoom.update=function(){return this.updateExtent().updateDomain()},i.zoom.updateExtent()},l.prototype.zoomTransform=function(t){var e=[this.x(t[0]),this.x(t[1])];return this.d3.zoomIdentity.scale(this.width/(e[1]-e[0])).translate(-e[0],0)},l.prototype.initDragZoom=function(){var e,t,i=this,n=i.d3,r=i.config,a=i.context=i.svg,o=i.margin.left+20.5,s=i.margin.top+.5;"drag"===r.zoom_type&&r.zoom_enabled&&(e=function(t){return t&&t.map(function(t){return i.x.invert(t)})},t=i.dragZoomBrush=n.brushX().on("start",function(){i.api.unzoom(),i.svg.select("."+Y.dragZoom).classed("disabled",!1),r.zoom_onzoomstart.call(i.api,n.event.sourceEvent)}).on("brush",function(){r.zoom_onzoom.call(i.api,e(n.event.selection))}).on("end",function(){var t;null!=n.event.selection&&(t=e(n.event.selection),r.zoom_disableDefaultBehavior||i.api.zoom(t),i.svg.select("."+Y.dragZoom).classed("disabled",!0),r.zoom_onzoomend.call(i.api,t))}),a.append("g").classed(Y.dragZoom,!0).attr("clip-path",i.clipPath).attr("transform","translate("+o+","+s+")").call(t))},l.prototype.getZoomDomain=function(){var t=this.config,e=this.d3;return[e.min([this.orgXDomain[0],t.zoom_x_min]),e.max([this.orgXDomain[1],t.zoom_x_max])]},l.prototype.redrawForZoom=function(){var t=this,e=t.d3,i=t.config,n=t.zoom,r=t.x;i.zoom_enabled&&0!==t.filterTargetsToShow(t.data.targets).length&&(n.update(),i.zoom_disableDefaultBehavior||(t.isCategorized()&&r.orgDomain()[0]===t.orgXDomain[0]&&r.domain([t.orgXDomain[0]-1e-10,r.orgDomain()[1]]),t.redraw({withTransition:!1,withY:i.zoom_rescale,withSubchart:!1,withEventRect:!1,withDimension:!1}),e.event.sourceEvent&&"mousemove"===e.event.sourceEvent.type&&(t.cancelClick=!0)))},t}); \ No newline at end of file diff --git a/component.json b/component.json index 890d97f42..dadf0feff 100644 --- a/component.json +++ b/component.json @@ -2,7 +2,7 @@ "name": "c3", "repo": "masayuki0812/c3", "description": "A D3-based reusable chart library", - "version": "0.7.15", + "version": "0.7.16", "keywords": [], "dependencies": { "mbostock/d3": "v5.0.0" diff --git a/docs/index.html.haml b/docs/index.html.haml index 673dd018e..41adf9f51 100644 --- a/docs/index.html.haml +++ b/docs/index.html.haml @@ -38,6 +38,10 @@ %h3 Change Log %ul + %li + v0.7.16 - 2020-06-15 + %ul + %li Bug fixes. %li v0.7.15 - 2020-02-28 %ul diff --git a/docs/js/c3.esm.js b/docs/js/c3.esm.js index b9145bcda..15a8edd9f 100644 --- a/docs/js/c3.esm.js +++ b/docs/js/c3.esm.js @@ -1,18 +1,22 @@ -/* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */ +/* @license C3.js v0.7.16 | (c) C3 Team and other contributors | http://c3js.org/ */ import * as d3 from 'd3'; function ChartInternal(api) { - var $$ = this; - // Note: This part will be replaced by rollup-plugin-modify - // When bundling esm output. Beware of changing this line. - // TODO: Maybe we should check that the modification by rollup-plugin-modify - // is valid during unit tests. - $$.d3 = d3; - $$.api = api; - $$.config = $$.getDefaultConfig(); - $$.data = {}; - $$.cache = {}; - $$.axes = {}; + var $$ = this; + // Note: This part will be replaced by rollup-plugin-modify + // When bundling esm output. Beware of changing this line. + // TODO: Maybe we should check that the modification by rollup-plugin-modify + // is valid during unit tests. + $$.d3 = window.d3 + ? window.d3 + : typeof require !== 'undefined' + ? require('d3') + : undefined; + $$.api = api; + $$.config = $$.getDefaultConfig(); + $$.data = {}; + $$.cache = {}; + $$.axes = {}; } /** @@ -21,96 +25,105 @@ function ChartInternal(api) { * The methods of this class is the public APIs of the chart object. */ function Chart(config) { - this.internal = new ChartInternal(this); - this.internal.loadConfig(config); - - this.internal.beforeInit(config); - this.internal.init(); - this.internal.afterInit(config); - - // bind "this" to nested API - (function bindThis(fn, target, argThis) { - Object.keys(fn).forEach(function (key) { - target[key] = fn[key].bind(argThis); - if (Object.keys(fn[key]).length > 0) { - bindThis(fn[key], target[key], argThis); - } - }); - })(Chart.prototype, this, this); + this.internal = new ChartInternal(this); + this.internal.loadConfig(config); + + this.internal.beforeInit(config); + this.internal.init(); + this.internal.afterInit(config) + + // bind "this" to nested API + ;(function bindThis(fn, target, argThis) { + Object.keys(fn).forEach(function(key) { + target[key] = fn[key].bind(argThis); + if (Object.keys(fn[key]).length > 0) { + bindThis(fn[key], target[key], argThis); + } + }); + })(Chart.prototype, this, this); } var asHalfPixel = function(n) { - return Math.ceil(n) + 0.5; + return Math.ceil(n) + 0.5 }; var ceil10 = function(v) { - return Math.ceil(v / 10) * 10; + return Math.ceil(v / 10) * 10 }; var diffDomain = function(d) { - return d[1] - d[0]; + return d[1] - d[0] }; var getOption = function(options, key, defaultValue) { - return isDefined(options[key]) ? options[key] : defaultValue; + return isDefined(options[key]) ? options[key] : defaultValue }; var getPathBox = function(path) { - var box = getBBox(path), - items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], - minX = items[0].x, - minY = Math.min(items[0].y, items[1].y); - return { x: minX, y: minY, width: box.width, height: box.height }; + var box = getBBox(path), + items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], + minX = items[0].x, + minY = Math.min(items[0].y, items[1].y); + return { x: minX, y: minY, width: box.width, height: box.height } }; var getBBox = function(element) { try { - return element.getBBox(); + return element.getBBox() } catch (ignore) { - // Firefox will throw an exception if getBBox() is called whereas the - // element is rendered with display:none - // See https://github.com/c3js/c3/issues/2692 + // Firefox will throw an exception if getBBox() is called whereas the + // element is rendered with display:none + // See https://github.com/c3js/c3/issues/2692 - // The previous code was using `getBoundingClientRect` which was returning - // everything at 0 in this case so let's reproduce this behavior here. + // The previous code was using `getBoundingClientRect` which was returning + // everything at 0 in this case so let's reproduce this behavior here. - return { x: 0, y: 0, width: 0, height: 0 }; + return { x: 0, y: 0, width: 0, height: 0 } } }; var hasValue = function(dict, value) { - var found = false; - Object.keys(dict).forEach(function(key) { - if (dict[key] === value) { found = true; } - }); - return found; + var found = false; + Object.keys(dict).forEach(function(key) { + if (dict[key] === value) { + found = true; + } + }); + return found }; var isArray = function(o) { - return Array.isArray(o); + return Array.isArray(o) }; var isDefined = function(v) { - return typeof v !== 'undefined'; + return typeof v !== 'undefined' }; var isEmpty = function(o) { - return typeof o === 'undefined' || o === null || (isString(o) && o.length === 0) || (typeof o === 'object' && Object.keys(o).length === 0); + return ( + typeof o === 'undefined' || + o === null || + (isString(o) && o.length === 0) || + (typeof o === 'object' && Object.keys(o).length === 0) + ) }; var isFunction = function(o) { - return typeof o === 'function'; + return typeof o === 'function' }; var isNumber = function(o) { - return typeof o === 'number'; + return typeof o === 'number' }; var isString = function(o) { - return typeof o === 'string'; + return typeof o === 'string' }; var isUndefined = function(v) { - return typeof v === 'undefined'; + return typeof v === 'undefined' }; var isValue = function(v) { - return v || v === 0; + return v || v === 0 }; var notEmpty = function(o) { - return !isEmpty(o); + return !isEmpty(o) }; var sanitise = function(str) { - return typeof str === 'string' ? str.replace(//g, '>') : str; + return typeof str === 'string' + ? str.replace(//g, '>') + : str }; var flattenArray = function(arr) { - return Array.isArray(arr) ? [].concat(...arr) : []; + return Array.isArray(arr) ? [].concat(...arr) : [] }; /** * Returns whether the point is within the given box. @@ -120,12 +133,14 @@ var flattenArray = function(arr) { * @param {Number} sensitivity An offset to ease check on very small boxes */ var isWithinBox = function(point, box, sensitivity = 0) { - const xStart = box.x - sensitivity; - const xEnd = box.x + box.width + sensitivity; - const yStart = box.y + box.height + sensitivity; - const yEnd = box.y - sensitivity; + const xStart = box.x - sensitivity; + const xEnd = box.x + box.width + sensitivity; + const yStart = box.y + box.height + sensitivity; + const yEnd = box.y - sensitivity; - return xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart; + return ( + xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart + ) }; /** @@ -134,23 +149,23 @@ var isWithinBox = function(point, box, sensitivity = 0) { * @param string agent Optional parameter to specify user agent */ var getIEVersion = function(agent) { - // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie - if (typeof agent === 'undefined') { - agent = window.navigator.userAgent; - } + // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie + if (typeof agent === 'undefined') { + agent = window.navigator.userAgent; + } - let pos = agent.indexOf('MSIE '); // up to IE10 - if (pos > 0) { - return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10); - } + let pos = agent.indexOf('MSIE '); // up to IE10 + if (pos > 0) { + return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10) + } - pos = agent.indexOf('Trident/'); // IE11 - if (pos > 0) { - pos = agent.indexOf('rv:'); - return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10); - } + pos = agent.indexOf('Trident/'); // IE11 + if (pos > 0) { + pos = agent.indexOf('rv:'); + return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10) + } - return false; + return false }; /** @@ -159,3899 +174,5096 @@ var getIEVersion = function(agent) { * @param {Number} version Optional parameter to specify IE version */ var isIE = function(version) { - const ver = getIEVersion(); + const ver = getIEVersion(); - if (typeof version === 'undefined') { - return !!ver; - } + if (typeof version === 'undefined') { + return !!ver + } - return version === ver; + return version === ver }; function AxisInternal(component, params) { - var internal = this; - internal.component = component; - internal.params = params || {}; - - internal.d3 = component.d3; - internal.scale = internal.d3.scaleLinear(); - internal.range; - internal.orient = "bottom"; - internal.innerTickSize = 6; - internal.outerTickSize = this.params.withOuterTick ? 6 : 0; - internal.tickPadding = 3; - internal.tickValues = null; - internal.tickFormat; - internal.tickArguments; - - internal.tickOffset = 0; - internal.tickCulling = true; - internal.tickCentered; - internal.tickTextCharSize; - internal.tickTextRotate = internal.params.tickTextRotate; - internal.tickLength; - - internal.axis = internal.generateAxis(); + var internal = this; + internal.component = component; + internal.params = params || {}; + + internal.d3 = component.d3; + internal.scale = internal.d3.scaleLinear(); + internal.range; + internal.orient = 'bottom'; + internal.innerTickSize = 6; + internal.outerTickSize = this.params.withOuterTick ? 6 : 0; + internal.tickPadding = 3; + internal.tickValues = null; + internal.tickFormat; + internal.tickArguments; + + internal.tickOffset = 0; + internal.tickCulling = true; + internal.tickCentered; + internal.tickTextCharSize; + internal.tickTextRotate = internal.params.tickTextRotate; + internal.tickLength; + + internal.axis = internal.generateAxis(); } -AxisInternal.prototype.axisX = function (selection, x, tickOffset) { - selection.attr("transform", function (d) { - return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)"; - }); -}; -AxisInternal.prototype.axisY = function (selection, y) { - selection.attr("transform", function (d) { - return "translate(0," + Math.ceil(y(d)) + ")"; - }); -}; -AxisInternal.prototype.scaleExtent = function (domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; -}; -AxisInternal.prototype.generateTicks = function (scale) { - var internal = this; - var i, domain, ticks = []; - if (scale.ticks) { - return scale.ticks.apply(scale, internal.tickArguments); - } - domain = scale.domain(); - for (i = Math.ceil(domain[0]); i < domain[1]; i++) { - ticks.push(i); - } - if (ticks.length > 0 && ticks[0] > 0) { - ticks.unshift(ticks[0] - (ticks[1] - ticks[0])); - } - return ticks; -}; -AxisInternal.prototype.copyScale = function () { - var internal = this; - var newScale = internal.scale.copy(), domain; - if (internal.params.isCategory) { - domain = internal.scale.domain(); - newScale.domain([domain[0], domain[1] - 1]); - } - return newScale; -}; -AxisInternal.prototype.textFormatted = function (v) { - var internal = this, - formatted = internal.tickFormat ? internal.tickFormat(v) : v; - return typeof formatted !== 'undefined' ? formatted : ''; -}; -AxisInternal.prototype.updateRange = function () { - var internal = this; - internal.range = internal.scale.rangeExtent ? internal.scale.rangeExtent() : internal.scaleExtent(internal.scale.range()); - return internal.range; -}; -AxisInternal.prototype.updateTickTextCharSize = function (tick) { - var internal = this; - if (internal.tickTextCharSize) { - return internal.tickTextCharSize; - } - var size = { - h: 11.5, - w: 5.5 - }; - tick.select('text').text(function(d) { return internal.textFormatted(d); }).each(function (d) { - var box = getBBox(this), - text = internal.textFormatted(d), - h = box.height, - w = text ? (box.width / text.length) : undefined; - if (h && w) { - size.h = h; - size.w = w; - } - }).text(''); - internal.tickTextCharSize = size; - return size; -}; -AxisInternal.prototype.isVertical = function () { - return this.orient === 'left' || this.orient === 'right'; -}; -AxisInternal.prototype.tspanData = function (d, i, scale) { - var internal = this; - var splitted = internal.params.tickMultiline ? internal.splitTickText(d, scale) : [].concat(internal.textFormatted(d)); - - if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) { - splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax); - } - - return splitted.map(function (s) { - return { index: i, splitted: s, length: splitted.length }; - }); -}; -AxisInternal.prototype.splitTickText = function (d, scale) { - var internal = this, - tickText = internal.textFormatted(d), - maxWidth = internal.params.tickWidth, - subtext, spaceIndex, textWidth, splitted = []; +AxisInternal.prototype.axisX = function(selection, x, tickOffset) { + selection.attr('transform', function(d) { + return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)' + }); +}; +AxisInternal.prototype.axisY = function(selection, y) { + selection.attr('transform', function(d) { + return 'translate(0,' + Math.ceil(y(d)) + ')' + }); +}; +AxisInternal.prototype.scaleExtent = function(domain) { + var start = domain[0], + stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start] +}; +AxisInternal.prototype.generateTicks = function(scale) { + var internal = this; + var i, + domain, + ticks = []; + if (scale.ticks) { + return scale.ticks.apply(scale, internal.tickArguments) + } + domain = scale.domain(); + for (i = Math.ceil(domain[0]); i < domain[1]; i++) { + ticks.push(i); + } + if (ticks.length > 0 && ticks[0] > 0) { + ticks.unshift(ticks[0] - (ticks[1] - ticks[0])); + } + return ticks +}; +AxisInternal.prototype.copyScale = function() { + var internal = this; + var newScale = internal.scale.copy(), + domain; + if (internal.params.isCategory) { + domain = internal.scale.domain(); + newScale.domain([domain[0], domain[1] - 1]); + } + return newScale +}; +AxisInternal.prototype.textFormatted = function(v) { + var internal = this, + formatted = internal.tickFormat ? internal.tickFormat(v) : v; + return typeof formatted !== 'undefined' ? formatted : '' +}; +AxisInternal.prototype.updateRange = function() { + var internal = this; + internal.range = internal.scale.rangeExtent + ? internal.scale.rangeExtent() + : internal.scaleExtent(internal.scale.range()); + return internal.range +}; +AxisInternal.prototype.updateTickTextCharSize = function(tick) { + var internal = this; + if (internal.tickTextCharSize) { + return internal.tickTextCharSize + } + var size = { + h: 11.5, + w: 5.5 + }; + tick + .select('text') + .text(function(d) { + return internal.textFormatted(d) + }) + .each(function(d) { + var box = getBBox(this), + text = internal.textFormatted(d), + h = box.height, + w = text ? box.width / text.length : undefined; + if (h && w) { + size.h = h; + size.w = w; + } + }) + .text(''); + internal.tickTextCharSize = size; + return size +}; +AxisInternal.prototype.isVertical = function() { + return this.orient === 'left' || this.orient === 'right' +}; +AxisInternal.prototype.tspanData = function(d, i, scale) { + var internal = this; + var splitted = internal.params.tickMultiline + ? internal.splitTickText(d, scale) + : [].concat(internal.textFormatted(d)); + + if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) { + splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax); + } - if (Object.prototype.toString.call(tickText) === "[object Array]") { - return tickText; - } + return splitted.map(function(s) { + return { index: i, splitted: s, length: splitted.length } + }) +}; +AxisInternal.prototype.splitTickText = function(d, scale) { + var internal = this, + tickText = internal.textFormatted(d), + maxWidth = internal.params.tickWidth, + subtext, + spaceIndex, + textWidth, + splitted = []; + + if (Object.prototype.toString.call(tickText) === '[object Array]') { + return tickText + } - if (!maxWidth || maxWidth <= 0) { - maxWidth = internal.isVertical() ? 95 : internal.params.isCategory ? (Math.ceil(scale(1) - scale(0)) - 12) : 110; - } + if (!maxWidth || maxWidth <= 0) { + maxWidth = internal.isVertical() + ? 95 + : internal.params.isCategory + ? Math.ceil(scale(1) - scale(0)) - 12 + : 110; + } - function split(splitted, text) { - spaceIndex = undefined; - for (var i = 1; i < text.length; i++) { - if (text.charAt(i) === ' ') { - spaceIndex = i; - } - subtext = text.substr(0, i + 1); - textWidth = internal.tickTextCharSize.w * subtext.length; - // if text width gets over tick width, split by space index or crrent index - if (maxWidth < textWidth) { - return split( - splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), - text.slice(spaceIndex ? spaceIndex + 1 : i) - ); - } - } - return splitted.concat(text); - } + function split(splitted, text) { + spaceIndex = undefined; + for (var i = 1; i < text.length; i++) { + if (text.charAt(i) === ' ') { + spaceIndex = i; + } + subtext = text.substr(0, i + 1); + textWidth = internal.tickTextCharSize.w * subtext.length; + // if text width gets over tick width, split by space index or crrent index + if (maxWidth < textWidth) { + return split( + splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), + text.slice(spaceIndex ? spaceIndex + 1 : i) + ) + } + } + return splitted.concat(text) + } - return split(splitted, tickText + ""); + return split(splitted, tickText + '') }; AxisInternal.prototype.ellipsify = function(splitted, max) { - if (splitted.length <= max) { - return splitted; - } + if (splitted.length <= max) { + return splitted + } - var ellipsified = splitted.slice(0, max); - var remaining = 3; - for (var i = max-1 ; i >= 0 ; i--) { - var available = ellipsified[i].length; + var ellipsified = splitted.slice(0, max); + var remaining = 3; + for (var i = max - 1; i >= 0; i--) { + var available = ellipsified[i].length; - ellipsified[i] = ellipsified[i].substr(0, available-remaining).padEnd(available, '.'); + ellipsified[i] = ellipsified[i] + .substr(0, available - remaining) + .padEnd(available, '.'); - remaining -= available; + remaining -= available; - if (remaining <= 0) { - break; - } + if (remaining <= 0) { + break } + } - return ellipsified; -}; -AxisInternal.prototype.updateTickLength = function () { - var internal = this; - internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding; -}; -AxisInternal.prototype.lineY2 = function (d) { - var internal = this, - tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset); - return internal.range[0] < tickPosition && tickPosition < internal.range[1] ? internal.innerTickSize : 0; -}; -AxisInternal.prototype.textY = function (){ - var internal = this, rotate = internal.tickTextRotate; - return rotate ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) : internal.tickLength; -}; -AxisInternal.prototype.textTransform = function () { - var internal = this, rotate = internal.tickTextRotate; - return rotate ? "rotate(" + rotate + ")" : ""; -}; -AxisInternal.prototype.textTextAnchor = function () { - var internal = this, rotate = internal.tickTextRotate; - return rotate ? (rotate > 0 ? "start" : "end") : "middle"; -}; -AxisInternal.prototype.tspanDx = function () { - var internal = this, rotate = internal.tickTextRotate; - return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0; -}; -AxisInternal.prototype.tspanDy = function (d, i) { - var internal = this, - dy = internal.tickTextCharSize.h; - if (i === 0) { - if (internal.isVertical()) { - dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); - } else { - dy = ".71em"; - } + return ellipsified +}; +AxisInternal.prototype.updateTickLength = function() { + var internal = this; + internal.tickLength = + Math.max(internal.innerTickSize, 0) + internal.tickPadding; +}; +AxisInternal.prototype.lineY2 = function(d) { + var internal = this, + tickPosition = + internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset); + return internal.range[0] < tickPosition && tickPosition < internal.range[1] + ? internal.innerTickSize + : 0 +}; +AxisInternal.prototype.textY = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate + ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) + : internal.tickLength +}; +AxisInternal.prototype.textTransform = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate ? 'rotate(' + rotate + ')' : '' +}; +AxisInternal.prototype.textTextAnchor = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle' +}; +AxisInternal.prototype.tspanDx = function() { + var internal = this, + rotate = internal.tickTextRotate; + return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0 +}; +AxisInternal.prototype.tspanDy = function(d, i) { + var internal = this, + dy = internal.tickTextCharSize.h; + if (i === 0) { + if (internal.isVertical()) { + dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); + } else { + dy = '.71em'; } - return dy; -}; - - -AxisInternal.prototype.generateAxis = function () { - var internal = this, d3 = internal.d3, params = internal.params; - function axis(g, transition) { - var self; - g.each(function () { - var g = axis.g = d3.select(this); - - var scale0 = this.__chart__ || internal.scale, - scale1 = this.__chart__ = internal.copyScale(); - - var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1), - ticks = g.selectAll(".tick").data(ticksValues, scale1), - tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), - // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. - tickExit = ticks.exit().remove(), - tickUpdate = ticks.merge(tickEnter), - tickTransform, tickX, tickY; - - if (params.isCategory) { - internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2); - tickX = internal.tickCentered ? 0 : internal.tickOffset; - tickY = internal.tickCentered ? internal.tickOffset : 0; - } else { - internal.tickOffset = tickX = 0; - } - - internal.updateRange(); - internal.updateTickLength(); - internal.updateTickTextCharSize(g.select('.tick')); - - var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")), - textUpdate = tickUpdate.select("text").merge(tickEnter.append("text")); - - var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) { - return internal.tspanData(d, i, scale1); - }), - tspanEnter = tspans.enter().append('tspan'), - tspanUpdate = tspanEnter.merge(tspans).text(function (d) { return d.splitted; }); - tspans.exit().remove(); - - var path = g.selectAll(".domain").data([ 0 ]), - pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); - - // TODO: each attr should be one function and change its behavior by internal.orient, probably - switch (internal.orient) { - case "bottom": - { - tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX) - .attr("x2", tickX) - .attr("y2", function (d, i) { return internal.lineY2(d, i); }); - textUpdate.attr("x", 0) - .attr("y", function (d, i) { return internal.textY(d, i); }) - .attr("transform", function (d, i) { return internal.textTransform(d, i); }) - .style("text-anchor", function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }) - .attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize); - break; - } - case "top": - { - // TODO: rotated tick text - tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX) - .attr("x2", tickX) - .attr("y2", function (d, i) { return -1 * internal.lineY2(d, i); }); - textUpdate.attr("x", 0) - .attr("y", function (d, i) { return -1 * internal.textY(d, i) - (params.isCategory ? 2 : (internal.tickLength - 2)); }) - .attr("transform", function (d, i) { return internal.textTransform(d, i); }) - .style("text-anchor", function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }) - .attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize); - break; - } - case "left": - { - tickTransform = internal.axisY; - lineUpdate.attr("x2", -internal.innerTickSize) - .attr("y1", tickY) - .attr("y2", tickY); - textUpdate.attr("x", -internal.tickLength) - .attr("y", internal.tickOffset) - .style("text-anchor", "end"); - tspanUpdate.attr('x', -internal.tickLength) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize); - break; - } - case "right": - { - tickTransform = internal.axisY; - lineUpdate.attr("x2", internal.innerTickSize) - .attr("y1", tickY) - .attr("y2", tickY); - textUpdate.attr("x", internal.tickLength) - .attr("y", internal.tickOffset) - .style("text-anchor", "start"); - tspanUpdate.attr('x', internal.tickLength) - .attr("dy", function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize); - break; - } - } - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function (d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; - } else { - tickExit.call(tickTransform, scale1, internal.tickOffset); - } - tickEnter.call(tickTransform, scale0, internal.tickOffset); - self = (transition ? tickUpdate.transition(transition) : tickUpdate) - .style('opacity', 1) - .call(tickTransform, scale1, internal.tickOffset); + } + return dy +}; + +AxisInternal.prototype.generateAxis = function() { + var internal = this, + d3 = internal.d3, + params = internal.params; + function axis(g, transition) { + var self; + g.each(function() { + var g = (axis.g = d3.select(this)); + + var scale0 = this.__chart__ || internal.scale, + scale1 = (this.__chart__ = internal.copyScale()); + + var ticksValues = internal.tickValues + ? internal.tickValues + : internal.generateTicks(scale1), + ticks = g.selectAll('.tick').data(ticksValues, scale1), + tickEnter = ticks + .enter() + .insert('g', '.domain') + .attr('class', 'tick') + .style('opacity', 1e-6), + // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. + tickExit = ticks.exit().remove(), + tickUpdate = ticks.merge(tickEnter), + tickTransform, + tickX, + tickY; + + if (params.isCategory) { + internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2); + tickX = internal.tickCentered ? 0 : internal.tickOffset; + tickY = internal.tickCentered ? internal.tickOffset : 0; + } else { + internal.tickOffset = tickX = 0; + } + + internal.updateRange(); + internal.updateTickLength(); + internal.updateTickTextCharSize(g.select('.tick')); + + var lineUpdate = tickUpdate + .select('line') + .merge(tickEnter.append('line')), + textUpdate = tickUpdate.select('text').merge(tickEnter.append('text')); + + var tspans = tickUpdate + .selectAll('text') + .selectAll('tspan') + .data(function(d, i) { + return internal.tspanData(d, i, scale1) + }), + tspanEnter = tspans.enter().append('tspan'), + tspanUpdate = tspanEnter.merge(tspans).text(function(d) { + return d.splitted }); - return self; - } - axis.scale = function (x) { - if (!arguments.length) { return internal.scale; } - internal.scale = x; - return axis; - }; - axis.orient = function (x) { - if (!arguments.length) { return internal.orient; } - internal.orient = x in {top: 1, right: 1, bottom: 1, left: 1} ? x + "" : "bottom"; - return axis; - }; - axis.tickFormat = function (format) { - if (!arguments.length) { return internal.tickFormat; } - internal.tickFormat = format; - return axis; - }; - axis.tickCentered = function (isCentered) { - if (!arguments.length) { return internal.tickCentered; } - internal.tickCentered = isCentered; - return axis; - }; - axis.tickOffset = function () { - return internal.tickOffset; - }; - axis.tickInterval = function () { - var interval, length; - if (params.isCategory) { - interval = internal.tickOffset * 2; - } - else { - length = axis.g.select('path.domain').node().getTotalLength() - internal.outerTickSize * 2; - interval = length / axis.g.selectAll('line').size(); - } - return interval === Infinity ? 0 : interval; - }; - axis.ticks = function () { - if (!arguments.length) { return internal.tickArguments; } - internal.tickArguments = arguments; - return axis; - }; - axis.tickCulling = function (culling) { - if (!arguments.length) { return internal.tickCulling; } - internal.tickCulling = culling; - return axis; - }; - axis.tickValues = function (x) { - if (typeof x === 'function') { - internal.tickValues = function () { - return x(internal.scale.domain()); - }; - } - else { - if (!arguments.length) { return internal.tickValues; } - internal.tickValues = x; - } - return axis; - }; - return axis; + tspans.exit().remove(); + + var path = g.selectAll('.domain').data([0]), + pathUpdate = path + .enter() + .append('path') + .merge(path) + .attr('class', 'domain'); + + // TODO: each attr should be one function and change its behavior by internal.orient, probably + switch (internal.orient) { + case 'bottom': { + tickTransform = internal.axisX; + lineUpdate + .attr('x1', tickX) + .attr('x2', tickX) + .attr('y2', function(d, i) { + return internal.lineY2(d, i) + }); + textUpdate + .attr('x', 0) + .attr('y', function(d, i) { + return internal.textY(d, i) + }) + .attr('transform', function(d, i) { + return internal.textTransform(d, i) + }) + .style('text-anchor', function(d, i) { + return internal.textTextAnchor(d, i) + }); + tspanUpdate + .attr('x', 0) + .attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }) + .attr('dx', function(d, i) { + return internal.tspanDx(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + internal.range[0] + + ',' + + internal.outerTickSize + + 'V0H' + + internal.range[1] + + 'V' + + internal.outerTickSize + ); + break + } + case 'top': { + // TODO: rotated tick text + tickTransform = internal.axisX; + lineUpdate + .attr('x1', tickX) + .attr('x2', tickX) + .attr('y2', function(d, i) { + return -1 * internal.lineY2(d, i) + }); + textUpdate + .attr('x', 0) + .attr('y', function(d, i) { + return ( + -1 * internal.textY(d, i) - + (params.isCategory ? 2 : internal.tickLength - 2) + ) + }) + .attr('transform', function(d, i) { + return internal.textTransform(d, i) + }) + .style('text-anchor', function(d, i) { + return internal.textTextAnchor(d, i) + }); + tspanUpdate + .attr('x', 0) + .attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }) + .attr('dx', function(d, i) { + return internal.tspanDx(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + internal.range[0] + + ',' + + -internal.outerTickSize + + 'V0H' + + internal.range[1] + + 'V' + + -internal.outerTickSize + ); + break + } + case 'left': { + tickTransform = internal.axisY; + lineUpdate + .attr('x2', -internal.innerTickSize) + .attr('y1', tickY) + .attr('y2', tickY); + textUpdate + .attr('x', -internal.tickLength) + .attr('y', internal.tickOffset) + .style('text-anchor', 'end'); + tspanUpdate + .attr('x', -internal.tickLength) + .attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + -internal.outerTickSize + + ',' + + internal.range[0] + + 'H0V' + + internal.range[1] + + 'H' + + -internal.outerTickSize + ); + break + } + case 'right': { + tickTransform = internal.axisY; + lineUpdate + .attr('x2', internal.innerTickSize) + .attr('y1', tickY) + .attr('y2', tickY); + textUpdate + .attr('x', internal.tickLength) + .attr('y', internal.tickOffset) + .style('text-anchor', 'start'); + tspanUpdate.attr('x', internal.tickLength).attr('dy', function(d, i) { + return internal.tspanDy(d, i) + }); + pathUpdate.attr( + 'd', + 'M' + + internal.outerTickSize + + ',' + + internal.range[0] + + 'H0V' + + internal.range[1] + + 'H' + + internal.outerTickSize + ); + break + } + } + if (scale1.rangeBand) { + var x = scale1, + dx = x.rangeBand() / 2; + scale0 = scale1 = function(d) { + return x(d) + dx + }; + } else if (scale0.rangeBand) { + scale0 = scale1; + } else { + tickExit.call(tickTransform, scale1, internal.tickOffset); + } + tickEnter.call(tickTransform, scale0, internal.tickOffset); + self = (transition ? tickUpdate.transition(transition) : tickUpdate) + .style('opacity', 1) + .call(tickTransform, scale1, internal.tickOffset); + }); + return self + } + axis.scale = function(x) { + if (!arguments.length) { + return internal.scale + } + internal.scale = x; + return axis + }; + axis.orient = function(x) { + if (!arguments.length) { + return internal.orient + } + internal.orient = + x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom'; + return axis + }; + axis.tickFormat = function(format) { + if (!arguments.length) { + return internal.tickFormat + } + internal.tickFormat = format; + return axis + }; + axis.tickCentered = function(isCentered) { + if (!arguments.length) { + return internal.tickCentered + } + internal.tickCentered = isCentered; + return axis + }; + axis.tickOffset = function() { + return internal.tickOffset + }; + axis.tickInterval = function() { + var interval, length; + if (params.isCategory) { + interval = internal.tickOffset * 2; + } else { + length = + axis.g + .select('path.domain') + .node() + .getTotalLength() - + internal.outerTickSize * 2; + interval = length / axis.g.selectAll('line').size(); + } + return interval === Infinity ? 0 : interval + }; + axis.ticks = function() { + if (!arguments.length) { + return internal.tickArguments + } + internal.tickArguments = arguments; + return axis + }; + axis.tickCulling = function(culling) { + if (!arguments.length) { + return internal.tickCulling + } + internal.tickCulling = culling; + return axis + }; + axis.tickValues = function(x) { + if (typeof x === 'function') { + internal.tickValues = function() { + return x(internal.scale.domain()) + }; + } else { + if (!arguments.length) { + return internal.tickValues + } + internal.tickValues = x; + } + return axis + }; + return axis }; var CLASS = { - target: 'c3-target', - chart: 'c3-chart', - chartLine: 'c3-chart-line', - chartLines: 'c3-chart-lines', - chartBar: 'c3-chart-bar', - chartBars: 'c3-chart-bars', - chartText: 'c3-chart-text', - chartTexts: 'c3-chart-texts', - chartArc: 'c3-chart-arc', - chartArcs: 'c3-chart-arcs', - chartArcsTitle: 'c3-chart-arcs-title', - chartArcsBackground: 'c3-chart-arcs-background', - chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit', - chartArcsGaugeMax: 'c3-chart-arcs-gauge-max', - chartArcsGaugeMin: 'c3-chart-arcs-gauge-min', - selectedCircle: 'c3-selected-circle', - selectedCircles: 'c3-selected-circles', - eventRect: 'c3-event-rect', - eventRects: 'c3-event-rects', - eventRectsSingle: 'c3-event-rects-single', - eventRectsMultiple: 'c3-event-rects-multiple', - zoomRect: 'c3-zoom-rect', - brush: 'c3-brush', - dragZoom: 'c3-drag-zoom', - focused: 'c3-focused', - defocused: 'c3-defocused', - region: 'c3-region', - regions: 'c3-regions', - title: 'c3-title', - tooltipContainer: 'c3-tooltip-container', - tooltip: 'c3-tooltip', - tooltipName: 'c3-tooltip-name', - shape: 'c3-shape', - shapes: 'c3-shapes', - line: 'c3-line', - lines: 'c3-lines', - bar: 'c3-bar', - bars: 'c3-bars', - circle: 'c3-circle', - circles: 'c3-circles', - arc: 'c3-arc', - arcLabelLine: 'c3-arc-label-line', - arcs: 'c3-arcs', - area: 'c3-area', - areas: 'c3-areas', - empty: 'c3-empty', - text: 'c3-text', - texts: 'c3-texts', - gaugeValue: 'c3-gauge-value', - grid: 'c3-grid', - gridLines: 'c3-grid-lines', - xgrid: 'c3-xgrid', - xgrids: 'c3-xgrids', - xgridLine: 'c3-xgrid-line', - xgridLines: 'c3-xgrid-lines', - xgridFocus: 'c3-xgrid-focus', - ygrid: 'c3-ygrid', - ygrids: 'c3-ygrids', - ygridLine: 'c3-ygrid-line', - ygridLines: 'c3-ygrid-lines', - colorScale: 'c3-colorscale', - stanfordElements: 'c3-stanford-elements', - stanfordLine: 'c3-stanford-line', - stanfordLines: 'c3-stanford-lines', - stanfordRegion: 'c3-stanford-region', - stanfordRegions: 'c3-stanford-regions', - stanfordText: 'c3-stanford-text', - stanfordTexts: 'c3-stanford-texts', - axis: 'c3-axis', - axisX: 'c3-axis-x', - axisXLabel: 'c3-axis-x-label', - axisY: 'c3-axis-y', - axisYLabel: 'c3-axis-y-label', - axisY2: 'c3-axis-y2', - axisY2Label: 'c3-axis-y2-label', - legendBackground: 'c3-legend-background', - legendItem: 'c3-legend-item', - legendItemEvent: 'c3-legend-item-event', - legendItemTile: 'c3-legend-item-tile', - legendItemHidden: 'c3-legend-item-hidden', - legendItemFocused: 'c3-legend-item-focused', - dragarea: 'c3-dragarea', - EXPANDED: '_expanded_', - SELECTED: '_selected_', - INCLUDED: '_included_' + target: 'c3-target', + chart: 'c3-chart', + chartLine: 'c3-chart-line', + chartLines: 'c3-chart-lines', + chartBar: 'c3-chart-bar', + chartBars: 'c3-chart-bars', + chartText: 'c3-chart-text', + chartTexts: 'c3-chart-texts', + chartArc: 'c3-chart-arc', + chartArcs: 'c3-chart-arcs', + chartArcsTitle: 'c3-chart-arcs-title', + chartArcsBackground: 'c3-chart-arcs-background', + chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit', + chartArcsGaugeMax: 'c3-chart-arcs-gauge-max', + chartArcsGaugeMin: 'c3-chart-arcs-gauge-min', + selectedCircle: 'c3-selected-circle', + selectedCircles: 'c3-selected-circles', + eventRect: 'c3-event-rect', + eventRects: 'c3-event-rects', + eventRectsSingle: 'c3-event-rects-single', + eventRectsMultiple: 'c3-event-rects-multiple', + zoomRect: 'c3-zoom-rect', + brush: 'c3-brush', + dragZoom: 'c3-drag-zoom', + focused: 'c3-focused', + defocused: 'c3-defocused', + region: 'c3-region', + regions: 'c3-regions', + title: 'c3-title', + tooltipContainer: 'c3-tooltip-container', + tooltip: 'c3-tooltip', + tooltipName: 'c3-tooltip-name', + shape: 'c3-shape', + shapes: 'c3-shapes', + line: 'c3-line', + lines: 'c3-lines', + bar: 'c3-bar', + bars: 'c3-bars', + circle: 'c3-circle', + circles: 'c3-circles', + arc: 'c3-arc', + arcLabelLine: 'c3-arc-label-line', + arcs: 'c3-arcs', + area: 'c3-area', + areas: 'c3-areas', + empty: 'c3-empty', + text: 'c3-text', + texts: 'c3-texts', + gaugeValue: 'c3-gauge-value', + grid: 'c3-grid', + gridLines: 'c3-grid-lines', + xgrid: 'c3-xgrid', + xgrids: 'c3-xgrids', + xgridLine: 'c3-xgrid-line', + xgridLines: 'c3-xgrid-lines', + xgridFocus: 'c3-xgrid-focus', + ygrid: 'c3-ygrid', + ygrids: 'c3-ygrids', + ygridLine: 'c3-ygrid-line', + ygridLines: 'c3-ygrid-lines', + colorScale: 'c3-colorscale', + stanfordElements: 'c3-stanford-elements', + stanfordLine: 'c3-stanford-line', + stanfordLines: 'c3-stanford-lines', + stanfordRegion: 'c3-stanford-region', + stanfordRegions: 'c3-stanford-regions', + stanfordText: 'c3-stanford-text', + stanfordTexts: 'c3-stanford-texts', + axis: 'c3-axis', + axisX: 'c3-axis-x', + axisXLabel: 'c3-axis-x-label', + axisY: 'c3-axis-y', + axisYLabel: 'c3-axis-y-label', + axisY2: 'c3-axis-y2', + axisY2Label: 'c3-axis-y2-label', + legendBackground: 'c3-legend-background', + legendItem: 'c3-legend-item', + legendItemEvent: 'c3-legend-item-event', + legendItemTile: 'c3-legend-item-tile', + legendItemHidden: 'c3-legend-item-hidden', + legendItemFocused: 'c3-legend-item-focused', + dragarea: 'c3-dragarea', + EXPANDED: '_expanded_', + SELECTED: '_selected_', + INCLUDED: '_included_' }; class Axis { - constructor(owner) { - this.owner = owner; - this.d3 = owner.d3; - this.internal = AxisInternal; - } + constructor(owner) { + this.owner = owner; + this.d3 = owner.d3; + this.internal = AxisInternal; + } } Axis.prototype.init = function init() { - var $$ = this.owner, - config = $$.config, - main = $$.main; - $$.axes.x = main.append("g") - .attr("class", CLASS.axis + ' ' + CLASS.axisX) - .attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis) - .attr("transform", $$.getTranslate('x')) - .style("visibility", config.axis_x_show ? 'visible' : 'hidden'); - $$.axes.x.append("text") - .attr("class", CLASS.axisXLabel) - .attr("transform", config.axis_rotated ? "rotate(-90)" : "") - .style("text-anchor", this.textAnchorForXAxisLabel.bind(this)); - $$.axes.y = main.append("g") - .attr("class", CLASS.axis + ' ' + CLASS.axisY) - .attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis) - .attr("transform", $$.getTranslate('y')) - .style("visibility", config.axis_y_show ? 'visible' : 'hidden'); - $$.axes.y.append("text") - .attr("class", CLASS.axisYLabel) - .attr("transform", config.axis_rotated ? "" : "rotate(-90)") - .style("text-anchor", this.textAnchorForYAxisLabel.bind(this)); - - $$.axes.y2 = main.append("g") - .attr("class", CLASS.axis + ' ' + CLASS.axisY2) - // clip-path? - .attr("transform", $$.getTranslate('y2')) - .style("visibility", config.axis_y2_show ? 'visible' : 'hidden'); - $$.axes.y2.append("text") - .attr("class", CLASS.axisY2Label) - .attr("transform", config.axis_rotated ? "" : "rotate(-90)") - .style("text-anchor", this.textAnchorForY2AxisLabel.bind(this)); -}; -Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { - var $$ = this.owner, - config = $$.config, - axisParams = { - isCategory: $$.isCategorized(), - withOuterTick: withOuterTick, - tickMultiline: config.axis_x_tick_multiline, - tickMultilineMax: config.axis_x_tick_multiline ? Number(config.axis_x_tick_multilineMax) : 0, - tickWidth: config.axis_x_tick_width, - tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate, - withoutTransition: withoutTransition, - }, - axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); - - if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") { - tickValues = tickValues.map(function (v) { - return $$.parseDate(v); - }); - } + var $$ = this.owner, + config = $$.config, + main = $$.main; + $$.axes.x = main + .append('g') + .attr('class', CLASS.axis + ' ' + CLASS.axisX) + .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis) + .attr('transform', $$.getTranslate('x')) + .style('visibility', config.axis_x_show ? 'visible' : 'hidden'); + $$.axes.x + .append('text') + .attr('class', CLASS.axisXLabel) + .attr('transform', config.axis_rotated ? 'rotate(-90)' : '') + .style('text-anchor', this.textAnchorForXAxisLabel.bind(this)); + $$.axes.y = main + .append('g') + .attr('class', CLASS.axis + ' ' + CLASS.axisY) + .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis) + .attr('transform', $$.getTranslate('y')) + .style('visibility', config.axis_y_show ? 'visible' : 'hidden'); + $$.axes.y + .append('text') + .attr('class', CLASS.axisYLabel) + .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') + .style('text-anchor', this.textAnchorForYAxisLabel.bind(this)); + + $$.axes.y2 = main + .append('g') + .attr('class', CLASS.axis + ' ' + CLASS.axisY2) + // clip-path? + .attr('transform', $$.getTranslate('y2')) + .style('visibility', config.axis_y2_show ? 'visible' : 'hidden'); + $$.axes.y2 + .append('text') + .attr('class', CLASS.axisY2Label) + .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') + .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this)); +}; +Axis.prototype.getXAxis = function getXAxis( + scale, + orient, + tickFormat, + tickValues, + withOuterTick, + withoutTransition, + withoutRotateTickText +) { + var $$ = this.owner, + config = $$.config, + axisParams = { + isCategory: $$.isCategorized(), + withOuterTick: withOuterTick, + tickMultiline: config.axis_x_tick_multiline, + tickMultilineMax: config.axis_x_tick_multiline + ? Number(config.axis_x_tick_multilineMax) + : 0, + tickWidth: config.axis_x_tick_width, + tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate, + withoutTransition: withoutTransition + }, + axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); - // Set tick - axis.tickFormat(tickFormat).tickValues(tickValues); - if ($$.isCategorized()) { - axis.tickCentered(config.axis_x_tick_centered); - if (isEmpty(config.axis_x_tick_culling)) { - config.axis_x_tick_culling = false; - } - } + if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') { + tickValues = tickValues.map(function(v) { + return $$.parseDate(v) + }); + } - return axis; -}; -Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) { - var $$ = this.owner, - config = $$.config, - tickValues; - if (config.axis_x_tick_fit || config.axis_x_tick_count) { - tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries()); - } - if (axis) { - axis.tickValues(tickValues); - } else { - $$.xAxis.tickValues(tickValues); - $$.subXAxis.tickValues(tickValues); + // Set tick + axis.tickFormat(tickFormat).tickValues(tickValues); + if ($$.isCategorized()) { + axis.tickCentered(config.axis_x_tick_centered); + if (isEmpty(config.axis_x_tick_culling)) { + config.axis_x_tick_culling = false; } - return tickValues; -}; -Axis.prototype.getYAxis = function getYAxis(axisId, scale, orient, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { - const $$ = this.owner; - const config = $$.config; + } - let tickFormat = config[`axis_${axisId}_tick_format`]; - if (!tickFormat && $$.isAxisNormalized(axisId)) { - tickFormat = (x) => `${x}%`; - } + return axis +}; +Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues( + targets, + axis +) { + var $$ = this.owner, + config = $$.config, + tickValues; + if (config.axis_x_tick_fit || config.axis_x_tick_count) { + tickValues = this.generateTickValues( + $$.mapTargetsToUniqueXs(targets), + config.axis_x_tick_count, + $$.isTimeSeries() + ); + } + if (axis) { + axis.tickValues(tickValues); + } else { + $$.xAxis.tickValues(tickValues); + $$.subXAxis.tickValues(tickValues); + } + return tickValues +}; +Axis.prototype.getYAxis = function getYAxis( + axisId, + scale, + orient, + tickValues, + withOuterTick, + withoutTransition, + withoutRotateTickText +) { + const $$ = this.owner; + const config = $$.config; + + let tickFormat = config[`axis_${axisId}_tick_format`]; + if (!tickFormat && $$.isAxisNormalized(axisId)) { + tickFormat = x => `${x}%`; + } - const axis = new this.internal(this, { - withOuterTick: withOuterTick, - withoutTransition: withoutTransition, - tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate - }).axis - .scale(scale) - .orient(orient); + const axis = new this.internal(this, { + withOuterTick: withOuterTick, + withoutTransition: withoutTransition, + tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate + }).axis + .scale(scale) + .orient(orient); - if (tickFormat) { - axis.tickFormat(tickFormat); - } + if (tickFormat) { + axis.tickFormat(tickFormat); + } - if ($$.isTimeSeriesY()) { - axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval); - } else { - axis.tickValues(tickValues); - } - return axis; + if ($$.isTimeSeriesY()) { + axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval); + } else { + axis.tickValues(tickValues); + } + return axis }; Axis.prototype.getId = function getId(id) { - var config = this.owner.config; - return id in config.data_axes ? config.data_axes[id] : 'y'; + var config = this.owner.config; + return id in config.data_axes ? config.data_axes[id] : 'y' }; Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() { - // #2251 previously set any negative values to a whole number, - // however both should be truncated according to the users format specification - var $$ = this.owner, - config = $$.config; - let format = ($$.isTimeSeries()) ? $$.defaultAxisTimeFormat : ($$.isCategorized()) ? $$.categoryName : function (v) { - return v; - }; - - if (config.axis_x_tick_format) { - if (isFunction(config.axis_x_tick_format)) { - format = config.axis_x_tick_format; - } else if ($$.isTimeSeries()) { - format = function (date) { - return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ""; - }; - } + // #2251 previously set any negative values to a whole number, + // however both should be truncated according to the users format specification + var $$ = this.owner, + config = $$.config; + let format = $$.isTimeSeries() + ? $$.defaultAxisTimeFormat + : $$.isCategorized() + ? $$.categoryName + : function(v) { + return v + }; + + if (config.axis_x_tick_format) { + if (isFunction(config.axis_x_tick_format)) { + format = config.axis_x_tick_format; + } else if ($$.isTimeSeries()) { + format = function(date) { + return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : '' + }; } - return isFunction(format) ? function (v) { - return format.call($$, v); - } : format; + } + return isFunction(format) + ? function(v) { + return format.call($$, v) + } + : format }; Axis.prototype.getTickValues = function getTickValues(tickValues, axis) { - return tickValues ? tickValues : axis ? axis.tickValues() : undefined; + return tickValues ? tickValues : axis ? axis.tickValues() : undefined }; Axis.prototype.getXAxisTickValues = function getXAxisTickValues() { - return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis); + return this.getTickValues( + this.owner.config.axis_x_tick_values, + this.owner.xAxis + ) }; Axis.prototype.getYAxisTickValues = function getYAxisTickValues() { - return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis); + return this.getTickValues( + this.owner.config.axis_y_tick_values, + this.owner.yAxis + ) }; Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() { - return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis); -}; -Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) { - var $$ = this.owner, - config = $$.config, - option; - if (axisId === 'y') { - option = config.axis_y_label; - } else if (axisId === 'y2') { - option = config.axis_y2_label; - } else if (axisId === 'x') { - option = config.axis_x_label; - } - return option; + return this.getTickValues( + this.owner.config.axis_y2_tick_values, + this.owner.y2Axis + ) +}; +Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId( + axisId +) { + var $$ = this.owner, + config = $$.config, + option; + if (axisId === 'y') { + option = config.axis_y_label; + } else if (axisId === 'y2') { + option = config.axis_y2_label; + } else if (axisId === 'x') { + option = config.axis_x_label; + } + return option }; Axis.prototype.getLabelText = function getLabelText(axisId) { - var option = this.getLabelOptionByAxisId(axisId); - return isString(option) ? option : option ? option.text : null; + var option = this.getLabelOptionByAxisId(axisId); + return isString(option) ? option : option ? option.text : null }; Axis.prototype.setLabelText = function setLabelText(axisId, text) { - var $$ = this.owner, - config = $$.config, - option = this.getLabelOptionByAxisId(axisId); - if (isString(option)) { - if (axisId === 'y') { - config.axis_y_label = text; - } else if (axisId === 'y2') { - config.axis_y2_label = text; - } else if (axisId === 'x') { - config.axis_x_label = text; - } - } else if (option) { - option.text = text; + var $$ = this.owner, + config = $$.config, + option = this.getLabelOptionByAxisId(axisId); + if (isString(option)) { + if (axisId === 'y') { + config.axis_y_label = text; + } else if (axisId === 'y2') { + config.axis_y2_label = text; + } else if (axisId === 'x') { + config.axis_x_label = text; } + } else if (option) { + option.text = text; + } }; -Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) { - var option = this.getLabelOptionByAxisId(axisId), - position = (option && typeof option === 'object' && option.position) ? option.position : defaultPosition; - return { - isInner: position.indexOf('inner') >= 0, - isOuter: position.indexOf('outer') >= 0, - isLeft: position.indexOf('left') >= 0, - isCenter: position.indexOf('center') >= 0, - isRight: position.indexOf('right') >= 0, - isTop: position.indexOf('top') >= 0, - isMiddle: position.indexOf('middle') >= 0, - isBottom: position.indexOf('bottom') >= 0 - }; +Axis.prototype.getLabelPosition = function getLabelPosition( + axisId, + defaultPosition +) { + var option = this.getLabelOptionByAxisId(axisId), + position = + option && typeof option === 'object' && option.position + ? option.position + : defaultPosition; + return { + isInner: position.indexOf('inner') >= 0, + isOuter: position.indexOf('outer') >= 0, + isLeft: position.indexOf('left') >= 0, + isCenter: position.indexOf('center') >= 0, + isRight: position.indexOf('right') >= 0, + isTop: position.indexOf('top') >= 0, + isMiddle: position.indexOf('middle') >= 0, + isBottom: position.indexOf('bottom') >= 0 + } }; Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() { - return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'); + return this.getLabelPosition( + 'x', + this.owner.config.axis_rotated ? 'inner-top' : 'inner-right' + ) }; Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() { - return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'); + return this.getLabelPosition( + 'y', + this.owner.config.axis_rotated ? 'inner-right' : 'inner-top' + ) }; Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() { - return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'); + return this.getLabelPosition( + 'y2', + this.owner.config.axis_rotated ? 'inner-right' : 'inner-top' + ) }; Axis.prototype.getLabelPositionById = function getLabelPositionById(id) { - return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition(); + return id === 'y2' + ? this.getY2AxisLabelPosition() + : id === 'y' + ? this.getYAxisLabelPosition() + : this.getXAxisLabelPosition() }; Axis.prototype.textForXAxisLabel = function textForXAxisLabel() { - return this.getLabelText('x'); + return this.getLabelText('x') }; Axis.prototype.textForYAxisLabel = function textForYAxisLabel() { - return this.getLabelText('y'); + return this.getLabelText('y') }; Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() { - return this.getLabelText('y2'); + return this.getLabelText('y2') }; Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) { - var $$ = this.owner; - if (forHorizontal) { - return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width; - } else { - return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0; - } + var $$ = this.owner; + if (forHorizontal) { + return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width + } else { + return position.isBottom + ? -$$.height + : position.isMiddle + ? -$$.height / 2 + : 0 + } }; -Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) { - if (forHorizontal) { - return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0"; - } else { - return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0"; - } +Axis.prototype.dxForAxisLabel = function dxForAxisLabel( + forHorizontal, + position +) { + if (forHorizontal) { + return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0' + } else { + return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0' + } }; -Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) { - if (forHorizontal) { - return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'; - } else { - return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'; - } +Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel( + forHorizontal, + position +) { + if (forHorizontal) { + return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end' + } else { + return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end' + } }; Axis.prototype.xForXAxisLabel = function xForXAxisLabel() { - return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition()); + return this.xForAxisLabel( + !this.owner.config.axis_rotated, + this.getXAxisLabelPosition() + ) }; Axis.prototype.xForYAxisLabel = function xForYAxisLabel() { - return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition()); + return this.xForAxisLabel( + this.owner.config.axis_rotated, + this.getYAxisLabelPosition() + ) }; Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() { - return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition()); + return this.xForAxisLabel( + this.owner.config.axis_rotated, + this.getY2AxisLabelPosition() + ) }; Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() { - return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition()); + return this.dxForAxisLabel( + !this.owner.config.axis_rotated, + this.getXAxisLabelPosition() + ) }; Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() { - return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition()); + return this.dxForAxisLabel( + this.owner.config.axis_rotated, + this.getYAxisLabelPosition() + ) }; Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() { - return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition()); + return this.dxForAxisLabel( + this.owner.config.axis_rotated, + this.getY2AxisLabelPosition() + ) }; Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() { - var $$ = this.owner, - config = $$.config, - position = this.getXAxisLabelPosition(); - if (config.axis_rotated) { - return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); - } else { - return position.isInner ? "-0.5em" : $$.getHorizontalAxisHeight('x') - 10; - } + var $$ = this.owner, + config = $$.config, + position = this.getXAxisLabelPosition(); + if (config.axis_rotated) { + return position.isInner + ? '1.2em' + : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')) + } else { + return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10 + } }; Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() { - var $$ = this.owner, - position = this.getYAxisLabelPosition(); - if ($$.config.axis_rotated) { - return position.isInner ? "-0.5em" : "3em"; - } else { - return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : (this.getMaxTickWidth('y') + 10)); - } + var $$ = this.owner, + position = this.getYAxisLabelPosition(); + if ($$.config.axis_rotated) { + return position.isInner ? '-0.5em' : '3em' + } else { + return position.isInner + ? '1.2em' + : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10) + } }; Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() { - var $$ = this.owner, - position = this.getY2AxisLabelPosition(); - if ($$.config.axis_rotated) { - return position.isInner ? "1.2em" : "-2.2em"; - } else { - return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : (this.getMaxTickWidth('y2') + 15)); - } + var $$ = this.owner, + position = this.getY2AxisLabelPosition(); + if ($$.config.axis_rotated) { + return position.isInner ? '1.2em' : '-2.2em' + } else { + return position.isInner + ? '-0.5em' + : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15) + } }; Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() { - var $$ = this.owner; - return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition()); + var $$ = this.owner; + return this.textAnchorForAxisLabel( + !$$.config.axis_rotated, + this.getXAxisLabelPosition() + ) }; Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() { - var $$ = this.owner; - return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition()); + var $$ = this.owner; + return this.textAnchorForAxisLabel( + $$.config.axis_rotated, + this.getYAxisLabelPosition() + ) }; Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() { - var $$ = this.owner; - return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition()); -}; -Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) { - var $$ = this.owner, - maxWidth = 0, - targetsToShow, scale, axis, dummy, svg; - if (withoutRecompute && $$.currentMaxTickWidths[id]) { - return $$.currentMaxTickWidths[id]; - } - if ($$.svg) { - targetsToShow = $$.filterTargetsToShow($$.data.targets); - if (id === 'y') { - scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); - axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true); - } else if (id === 'y2') { - scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); - axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true); - } else { - scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); - axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true); - this.updateXAxisTickValues(targetsToShow, axis); - } - dummy = $$.d3.select('body').append('div').classed('c3', true); - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), - svg.append('g').call(axis).each(function () { - $$.d3.select(this).selectAll('text').each(function () { - var box = getBBox(this); - if (maxWidth < box.width) { - maxWidth = box.width; - } - }); - dummy.remove(); + var $$ = this.owner; + return this.textAnchorForAxisLabel( + $$.config.axis_rotated, + this.getY2AxisLabelPosition() + ) +}; +Axis.prototype.getMaxTickWidth = function getMaxTickWidth( + id, + withoutRecompute +) { + var $$ = this.owner, + maxWidth = 0, + targetsToShow, + scale, + axis, + dummy, + svg; + if (withoutRecompute && $$.currentMaxTickWidths[id]) { + return $$.currentMaxTickWidths[id] + } + if ($$.svg) { + targetsToShow = $$.filterTargetsToShow($$.data.targets); + if (id === 'y') { + scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); + axis = this.getYAxis( + id, + scale, + $$.yOrient, + $$.yAxisTickValues, + false, + true, + true + ); + } else if (id === 'y2') { + scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); + axis = this.getYAxis( + id, + scale, + $$.y2Orient, + $$.y2AxisTickValues, + false, + true, + true + ); + } else { + scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); + axis = this.getXAxis( + scale, + $$.xOrient, + $$.xAxisTickFormat, + $$.xAxisTickValues, + false, + true, + true + ); + this.updateXAxisTickValues(targetsToShow, axis); + } + dummy = $$.d3 + .select('body') + .append('div') + .classed('c3', true) + ;(svg = dummy + .append('svg') + .style('visibility', 'hidden') + .style('position', 'fixed') + .style('top', 0) + .style('left', 0)), + svg + .append('g') + .call(axis) + .each(function() { + $$.d3 + .select(this) + .selectAll('text') + .each(function() { + var box = getBBox(this); + if (maxWidth < box.width) { + maxWidth = box.width; + } }); - } - $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth; - return $$.currentMaxTickWidths[id]; + dummy.remove(); + }); + } + $$.currentMaxTickWidths[id] = + maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth; + return $$.currentMaxTickWidths[id] }; Axis.prototype.updateLabels = function updateLabels(withTransition) { - var $$ = this.owner; - var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), - axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), - axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label); - (withTransition ? axisXLabel.transition() : axisXLabel) - .attr("x", this.xForXAxisLabel.bind(this)) - .attr("dx", this.dxForXAxisLabel.bind(this)) - .attr("dy", this.dyForXAxisLabel.bind(this)) - .text(this.textForXAxisLabel.bind(this)); - (withTransition ? axisYLabel.transition() : axisYLabel) - .attr("x", this.xForYAxisLabel.bind(this)) - .attr("dx", this.dxForYAxisLabel.bind(this)) - .attr("dy", this.dyForYAxisLabel.bind(this)) - .text(this.textForYAxisLabel.bind(this)); - (withTransition ? axisY2Label.transition() : axisY2Label) - .attr("x", this.xForY2AxisLabel.bind(this)) - .attr("dx", this.dxForY2AxisLabel.bind(this)) - .attr("dy", this.dyForY2AxisLabel.bind(this)) - .text(this.textForY2AxisLabel.bind(this)); -}; -Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) { - var p = typeof padding === 'number' ? padding : padding[key]; - if (!isValue(p)) { - return defaultValue; - } - if (padding.unit === 'ratio') { - return padding[key] * domainLength; - } - // assume padding is pixels if unit is not specified - return this.convertPixelsToAxisPadding(p, domainLength); -}; -Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) { - var $$ = this.owner, - length = $$.config.axis_rotated ? $$.width : $$.height; - return domainLength * (pixels / length); -}; -Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) { - var tickValues = values, - targetCount, start, end, count, interval, i, tickValue; - if (tickCount) { - targetCount = isFunction(tickCount) ? tickCount() : tickCount; - // compute ticks according to tickCount - if (targetCount === 1) { - tickValues = [values[0]]; - } else if (targetCount === 2) { - tickValues = [values[0], values[values.length - 1]]; - } else if (targetCount > 2) { - count = targetCount - 2; - start = values[0]; - end = values[values.length - 1]; - interval = (end - start) / (count + 1); - // re-construct unique values - tickValues = [start]; - for (i = 0; i < count; i++) { - tickValue = +start + interval * (i + 1); - tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue); - } - tickValues.push(end); - } - } - if (!forTimeSeries) { - tickValues = tickValues.sort(function (a, b) { - return a - b; - }); + var $$ = this.owner; + var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), + axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), + axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label) + ;(withTransition ? axisXLabel.transition() : axisXLabel) + .attr('x', this.xForXAxisLabel.bind(this)) + .attr('dx', this.dxForXAxisLabel.bind(this)) + .attr('dy', this.dyForXAxisLabel.bind(this)) + .text(this.textForXAxisLabel.bind(this)) + ;(withTransition ? axisYLabel.transition() : axisYLabel) + .attr('x', this.xForYAxisLabel.bind(this)) + .attr('dx', this.dxForYAxisLabel.bind(this)) + .attr('dy', this.dyForYAxisLabel.bind(this)) + .text(this.textForYAxisLabel.bind(this)) + ;(withTransition ? axisY2Label.transition() : axisY2Label) + .attr('x', this.xForY2AxisLabel.bind(this)) + .attr('dx', this.dxForY2AxisLabel.bind(this)) + .attr('dy', this.dyForY2AxisLabel.bind(this)) + .text(this.textForY2AxisLabel.bind(this)); +}; +Axis.prototype.getPadding = function getPadding( + padding, + key, + defaultValue, + domainLength +) { + var p = typeof padding === 'number' ? padding : padding[key]; + if (!isValue(p)) { + return defaultValue + } + if (padding.unit === 'ratio') { + return padding[key] * domainLength + } + // assume padding is pixels if unit is not specified + return this.convertPixelsToAxisPadding(p, domainLength) +}; +Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding( + pixels, + domainLength +) { + var $$ = this.owner, + length = $$.config.axis_rotated ? $$.width : $$.height; + return domainLength * (pixels / length) +}; +Axis.prototype.generateTickValues = function generateTickValues( + values, + tickCount, + forTimeSeries +) { + var tickValues = values, + targetCount, + start, + end, + count, + interval, + i, + tickValue; + if (tickCount) { + targetCount = isFunction(tickCount) ? tickCount() : tickCount; + // compute ticks according to tickCount + if (targetCount === 1) { + tickValues = [values[0]]; + } else if (targetCount === 2) { + tickValues = [values[0], values[values.length - 1]]; + } else if (targetCount > 2) { + count = targetCount - 2; + start = values[0]; + end = values[values.length - 1]; + interval = (end - start) / (count + 1); + // re-construct unique values + tickValues = [start]; + for (i = 0; i < count; i++) { + tickValue = +start + interval * (i + 1); + tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue); + } + tickValues.push(end); } - return tickValues; + } + if (!forTimeSeries) { + tickValues = tickValues.sort(function(a, b) { + return a - b + }); + } + return tickValues }; Axis.prototype.generateTransitions = function generateTransitions(duration) { - var $$ = this.owner, - axes = $$.axes; - return { - axisX: duration ? axes.x.transition().duration(duration) : axes.x, - axisY: duration ? axes.y.transition().duration(duration) : axes.y, - axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2, - axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx - }; + var $$ = this.owner, + axes = $$.axes; + return { + axisX: duration ? axes.x.transition().duration(duration) : axes.x, + axisY: duration ? axes.y.transition().duration(duration) : axes.y, + axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2, + axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx + } }; Axis.prototype.redraw = function redraw(duration, isHidden) { - var $$ = this.owner, - transition = duration ? $$.d3.transition().duration(duration) : null; - $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition); - $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition); - $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition); - $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition); + var $$ = this.owner, + transition = duration ? $$.d3.transition().duration(duration) : null; + $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition); + $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition); + $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition); + $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition); }; var c3 = { - version: "0.7.15", - chart: { - fn: Chart.prototype, + version: '0.7.16', + chart: { + fn: Chart.prototype, + internal: { + fn: ChartInternal.prototype, + axis: { + fn: Axis.prototype, internal: { - fn: ChartInternal.prototype, - axis: { - fn: Axis.prototype, - internal: { - fn: AxisInternal.prototype - } - } + fn: AxisInternal.prototype } - }, - generate: function(config) { - return new Chart(config); + } } + }, + generate: function(config) { + return new Chart(config) + } }; ChartInternal.prototype.beforeInit = function() { - // can do something + // can do something }; ChartInternal.prototype.afterInit = function() { - // can do something + // can do something }; ChartInternal.prototype.init = function() { - var $$ = this, - config = $$.config; - - $$.initParams(); - - if (config.data_url) { - $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData); - } else if (config.data_json) { - $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys)); - } else if (config.data_rows) { - $$.initWithData($$.convertRowsToData(config.data_rows)); - } else if (config.data_columns) { - $$.initWithData($$.convertColumnsToData(config.data_columns)); - } else { - throw Error('url or json or rows or columns is required.'); - } + var $$ = this, + config = $$.config; + + $$.initParams(); + + if (config.data_url) { + $$.convertUrlToData( + config.data_url, + config.data_mimeType, + config.data_headers, + config.data_keys, + $$.initWithData + ); + } else if (config.data_json) { + $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys)); + } else if (config.data_rows) { + $$.initWithData($$.convertRowsToData(config.data_rows)); + } else if (config.data_columns) { + $$.initWithData($$.convertColumnsToData(config.data_columns)); + } else { + throw Error('url or json or rows or columns is required.') + } }; ChartInternal.prototype.initParams = function() { - var $$ = this, - d3 = $$.d3, - config = $$.config; - - // MEMO: clipId needs to be unique because it conflicts when multiple charts exist - $$.clipId = "c3-" + (+new Date()) + '-clip'; - $$.clipIdForXAxis = $$.clipId + '-xaxis'; - $$.clipIdForYAxis = $$.clipId + '-yaxis'; - $$.clipIdForGrid = $$.clipId + '-grid'; - $$.clipIdForSubchart = $$.clipId + '-subchart'; - $$.clipPath = $$.getClipPath($$.clipId); - $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis); - $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis); - $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid); - $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart); - - $$.dragStart = null; - $$.dragging = false; - $$.flowing = false; - $$.cancelClick = false; - $$.mouseover = undefined; - $$.transiting = false; - - $$.color = $$.generateColor(); - $$.levelColor = $$.generateLevelColor(); - - $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat); - $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat; - $$.defaultAxisTimeFormat = function(date) { - if (date.getMilliseconds()) { - return d3.timeFormat(".%L")(date); - } - if (date.getSeconds()) { - return d3.timeFormat(":%S")(date); - } - if (date.getMinutes()) { - return d3.timeFormat("%I:%M")(date); - } - if (date.getHours()) { - return d3.timeFormat("%I %p")(date); - } - if (date.getDay() && date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); - } - if (date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); - } - if (date.getMonth()) { - return d3.timeFormat("%-m/%-d")(date); - } - return d3.timeFormat("%Y/%-m/%-d")(date); - }; - $$.hiddenTargetIds = []; - $$.hiddenLegendIds = []; - $$.focusedTargetIds = []; - $$.defocusedTargetIds = []; + var $$ = this, + d3 = $$.d3, + config = $$.config; + + // MEMO: clipId needs to be unique because it conflicts when multiple charts exist + $$.clipId = 'c3-' + new Date().valueOf() + '-clip'; + $$.clipIdForXAxis = $$.clipId + '-xaxis'; + $$.clipIdForYAxis = $$.clipId + '-yaxis'; + $$.clipIdForGrid = $$.clipId + '-grid'; + $$.clipIdForSubchart = $$.clipId + '-subchart'; + $$.clipPath = $$.getClipPath($$.clipId); + $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis); + $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis); + $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid); + $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart); + + $$.dragStart = null; + $$.dragging = false; + $$.flowing = false; + $$.cancelClick = false; + $$.mouseover = undefined; + $$.transiting = false; + + $$.color = $$.generateColor(); + $$.levelColor = $$.generateLevelColor(); + + $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)( + $$.config.data_xFormat + ); + $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat; + $$.defaultAxisTimeFormat = function(date) { + if (date.getMilliseconds()) { + return d3.timeFormat('.%L')(date) + } + if (date.getSeconds()) { + return d3.timeFormat(':%S')(date) + } + if (date.getMinutes()) { + return d3.timeFormat('%I:%M')(date) + } + if (date.getHours()) { + return d3.timeFormat('%I %p')(date) + } + if (date.getDay() && date.getDate() !== 1) { + return d3.timeFormat('%-m/%-d')(date) + } + if (date.getDate() !== 1) { + return d3.timeFormat('%-m/%-d')(date) + } + if (date.getMonth()) { + return d3.timeFormat('%-m/%-d')(date) + } + return d3.timeFormat('%Y/%-m/%-d')(date) + }; + $$.hiddenTargetIds = []; + $$.hiddenLegendIds = []; + $$.focusedTargetIds = []; + $$.defocusedTargetIds = []; + + $$.xOrient = config.axis_rotated + ? config.axis_x_inner + ? 'right' + : 'left' + : config.axis_x_inner + ? 'top' + : 'bottom'; + $$.yOrient = config.axis_rotated + ? config.axis_y_inner + ? 'top' + : 'bottom' + : config.axis_y_inner + ? 'right' + : 'left'; + $$.y2Orient = config.axis_rotated + ? config.axis_y2_inner + ? 'bottom' + : 'top' + : config.axis_y2_inner + ? 'left' + : 'right'; + $$.subXOrient = config.axis_rotated ? 'left' : 'bottom'; + + $$.isLegendRight = config.legend_position === 'right'; + $$.isLegendInset = config.legend_position === 'inset'; + $$.isLegendTop = + config.legend_inset_anchor === 'top-left' || + config.legend_inset_anchor === 'top-right'; + $$.isLegendLeft = + config.legend_inset_anchor === 'top-left' || + config.legend_inset_anchor === 'bottom-left'; + $$.legendStep = 0; + $$.legendItemWidth = 0; + $$.legendItemHeight = 0; + + $$.currentMaxTickWidths = { + x: 0, + y: 0, + y2: 0 + }; + + $$.rotated_padding_left = 30; + $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30; + $$.rotated_padding_top = 5; + + $$.withoutFadeIn = {}; + + $$.intervalForObserveInserted = undefined; + + $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js +}; - $$.xOrient = config.axis_rotated ? (config.axis_x_inner ? "right" : "left") : (config.axis_x_inner ? "top" : "bottom"); - $$.yOrient = config.axis_rotated ? (config.axis_y_inner ? "top" : "bottom") : (config.axis_y_inner ? "right" : "left"); - $$.y2Orient = config.axis_rotated ? (config.axis_y2_inner ? "bottom" : "top") : (config.axis_y2_inner ? "left" : "right"); - $$.subXOrient = config.axis_rotated ? "left" : "bottom"; +ChartInternal.prototype.initChartElements = function() { + if (this.initBar) { + this.initBar(); + } + if (this.initLine) { + this.initLine(); + } + if (this.initArc) { + this.initArc(); + } + if (this.initGauge) { + this.initGauge(); + } + if (this.initText) { + this.initText(); + } +}; - $$.isLegendRight = config.legend_position === 'right'; - $$.isLegendInset = config.legend_position === 'inset'; - $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right'; - $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left'; - $$.legendStep = 0; - $$.legendItemWidth = 0; - $$.legendItemHeight = 0; +ChartInternal.prototype.initWithData = function(data) { + var $$ = this, + d3 = $$.d3, + config = $$.config; + var defs, + main, + binding = true; + + $$.axis = new Axis($$); + + if (!config.bindto) { + $$.selectChart = d3.selectAll([]); + } else if (typeof config.bindto.node === 'function') { + $$.selectChart = config.bindto; + } else { + $$.selectChart = d3.select(config.bindto); + } + if ($$.selectChart.empty()) { + $$.selectChart = d3 + .select(document.createElement('div')) + .style('opacity', 0); + $$.observeInserted($$.selectChart); + binding = false; + } + $$.selectChart.html('').classed('c3', true); - $$.currentMaxTickWidths = { - x: 0, - y: 0, - y2: 0 - }; + // Init data as targets + $$.data.xs = {}; + $$.data.targets = $$.convertDataToTargets(data); - $$.rotated_padding_left = 30; - $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30; - $$.rotated_padding_top = 5; + if (config.data_filter) { + $$.data.targets = $$.data.targets.filter(config.data_filter); + } - $$.withoutFadeIn = {}; + // Set targets to hide if needed + if (config.data_hide) { + $$.addHiddenTargetIds( + config.data_hide === true + ? $$.mapToIds($$.data.targets) + : config.data_hide + ); + } + if (config.legend_hide) { + $$.addHiddenLegendIds( + config.legend_hide === true + ? $$.mapToIds($$.data.targets) + : config.legend_hide + ); + } - $$.intervalForObserveInserted = undefined; + if ($$.isStanfordGraphType()) { + $$.initStanfordData(); + } - $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js -}; + // Init sizes and scales + $$.updateSizes(); + $$.updateScales(); + + // Set domains for each scale + $$.x.domain(d3.extent($$.getXDomain($$.data.targets))); + $$.y.domain($$.getYDomain($$.data.targets, 'y')); + $$.y2.domain($$.getYDomain($$.data.targets, 'y2')); + $$.subX.domain($$.x.domain()); + $$.subY.domain($$.y.domain()); + $$.subY2.domain($$.y2.domain()); + + // Save original x domain for zoom update + $$.orgXDomain = $$.x.domain(); + + /*-- Basic Elements --*/ + + // Define svgs + $$.svg = $$.selectChart + .append('svg') + .style('overflow', 'hidden') + .on('mouseenter', function() { + return config.onmouseover.call($$) + }) + .on('mouseleave', function() { + return config.onmouseout.call($$) + }); -ChartInternal.prototype.initChartElements = function() { - if (this.initBar) { - this.initBar(); - } - if (this.initLine) { - this.initLine(); - } - if (this.initArc) { - this.initArc(); - } - if (this.initGauge) { - this.initGauge(); - } - if (this.initText) { - this.initText(); - } -}; + if ($$.config.svg_classname) { + $$.svg.attr('class', $$.config.svg_classname); + } -ChartInternal.prototype.initWithData = function(data) { - var $$ = this, - d3 = $$.d3, - config = $$.config; - var defs, main, binding = true; + // Define defs + defs = $$.svg.append('defs'); + $$.clipChart = $$.appendClip(defs, $$.clipId); + $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); + $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); + $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid); + $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); + $$.updateSvgSize(); - $$.axis = new Axis($$); + // Define regions + main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main')); - if (!config.bindto) { - $$.selectChart = d3.selectAll([]); - } else if (typeof config.bindto.node === 'function') { - $$.selectChart = config.bindto; - } else { - $$.selectChart = d3.select(config.bindto); - } - if ($$.selectChart.empty()) { - $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0); - $$.observeInserted($$.selectChart); - binding = false; - } - $$.selectChart.html("").classed("c3", true); + if ($$.initPie) { + $$.initPie(); + } + if ($$.initDragZoom) { + $$.initDragZoom(); + } + if (config.subchart_show && $$.initSubchart) { + $$.initSubchart(); + } + if ($$.initTooltip) { + $$.initTooltip(); + } + if ($$.initLegend) { + $$.initLegend(); + } + if ($$.initTitle) { + $$.initTitle(); + } + if ($$.initZoom) { + $$.initZoom(); + } + if ($$.isStanfordGraphType()) { + $$.drawColorScale(); + } - // Init data as targets - $$.data.xs = {}; - $$.data.targets = $$.convertDataToTargets(data); + // Update selection based on size and scale + // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart. + if (config.subchart_show && $$.initSubchartBrush) { + $$.initSubchartBrush(); + } - if (config.data_filter) { - $$.data.targets = $$.data.targets.filter(config.data_filter); - } + /*-- Main Region --*/ - // Set targets to hide if needed - if (config.data_hide) { - $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide); - } - if (config.legend_hide) { - $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide); - } + // text when empty + main + .append('text') + .attr('class', CLASS.text + ' ' + CLASS.empty) + .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers. + .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE. - if($$.isStanfordGraphType()) { - $$.initStanfordData(); - } + // Regions + $$.initRegion(); - // Init sizes and scales - $$.updateSizes(); - $$.updateScales(); + // Grids + $$.initGrid(); - // Set domains for each scale - $$.x.domain(d3.extent($$.getXDomain($$.data.targets))); - $$.y.domain($$.getYDomain($$.data.targets, 'y')); - $$.y2.domain($$.getYDomain($$.data.targets, 'y2')); - $$.subX.domain($$.x.domain()); - $$.subY.domain($$.y.domain()); - $$.subY2.domain($$.y2.domain()); + // Define g for chart area + main + .append('g') + .attr('clip-path', $$.clipPath) + .attr('class', CLASS.chart); - // Save original x domain for zoom update - $$.orgXDomain = $$.x.domain(); + // Grid lines + if (config.grid_lines_front) { + $$.initGridLines(); + } - /*-- Basic Elements --*/ + $$.initStanfordElements(); - // Define svgs - $$.svg = $$.selectChart.append("svg") - .style("overflow", "hidden") - .on('mouseenter', function() { - return config.onmouseover.call($$); - }) - .on('mouseleave', function() { - return config.onmouseout.call($$); - }); + // Cover whole with rects for events + $$.initEventRect(); - if ($$.config.svg_classname) { - $$.svg.attr('class', $$.config.svg_classname); - } + // Define g for chart + $$.initChartElements(); - // Define defs - defs = $$.svg.append("defs"); - $$.clipChart = $$.appendClip(defs, $$.clipId); - $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); - $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); - $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid); - $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); - $$.updateSvgSize(); + // Add Axis + $$.axis.init(); - // Define regions - main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main')); + // Set targets + $$.updateTargets($$.data.targets); - if ($$.initPie) { - $$.initPie(); - } - if ($$.initDragZoom) { - $$.initDragZoom(); - } - if (config.subchart_show && $$.initSubchart) { - $$.initSubchart(); - } - if ($$.initTooltip) { - $$.initTooltip(); - } - if ($$.initLegend) { - $$.initLegend(); - } - if ($$.initTitle) { - $$.initTitle(); - } - if ($$.initZoom) { - $$.initZoom(); - } - if($$.isStanfordGraphType()) { - $$.drawColorScale(); - } - - // Update selection based on size and scale - // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart. - if (config.subchart_show && $$.initSubchartBrush) { - $$.initSubchartBrush(); - } - - /*-- Main Region --*/ - - // text when empty - main.append("text") - .attr("class", CLASS.text + ' ' + CLASS.empty) - .attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers. - .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE. - - // Regions - $$.initRegion(); - - // Grids - $$.initGrid(); - - // Define g for chart area - main.append('g') - .attr("clip-path", $$.clipPath) - .attr('class', CLASS.chart); - - // Grid lines - if (config.grid_lines_front) { - $$.initGridLines(); - } - - $$.initStanfordElements(); - - // Cover whole with rects for events - $$.initEventRect(); - - // Define g for chart - $$.initChartElements(); - - // Add Axis - $$.axis.init(); - - // Set targets - $$.updateTargets($$.data.targets); - - // Set default extent if defined - if (config.axis_x_selection) { - $$.brush.selectionAsValue($$.getDefaultSelection()); - } + // Set default extent if defined + if (config.axis_x_selection) { + $$.brush.selectionAsValue($$.getDefaultSelection()); + } - // Draw with targets - if (binding) { - $$.updateDimension(); - $$.config.oninit.call($$); - $$.redraw({ - withTransition: false, - withTransform: true, - withUpdateXDomain: true, - withUpdateOrgXDomain: true, - withTransitionForAxis: false - }); - } + // Draw with targets + if (binding) { + $$.updateDimension(); + $$.config.oninit.call($$); + $$.redraw({ + withTransition: false, + withTransform: true, + withUpdateXDomain: true, + withUpdateOrgXDomain: true, + withTransitionForAxis: false + }); + } - // Bind to resize event - $$.bindResize(); + // Bind to resize event + $$.bindResize(); - // Bind to window focus event - $$.bindWindowFocus(); + // Bind to window focus event + $$.bindWindowFocus(); - // export element of the chart - $$.api.element = $$.selectChart.node(); + // export element of the chart + $$.api.element = $$.selectChart.node(); }; ChartInternal.prototype.smoothLines = function(el, type) { - var $$ = this; - if (type === 'grid') { - el.each(function() { - var g = $$.d3.select(this), - x1 = g.attr('x1'), - x2 = g.attr('x2'), - y1 = g.attr('y1'), - y2 = g.attr('y2'); - g.attr({ - 'x1': Math.ceil(x1), - 'x2': Math.ceil(x2), - 'y1': Math.ceil(y1), - 'y2': Math.ceil(y2) - }); - }); - } + var $$ = this; + if (type === 'grid') { + el.each(function() { + var g = $$.d3.select(this), + x1 = g.attr('x1'), + x2 = g.attr('x2'), + y1 = g.attr('y1'), + y2 = g.attr('y2'); + g.attr({ + x1: Math.ceil(x1), + x2: Math.ceil(x2), + y1: Math.ceil(y1), + y2: Math.ceil(y2) + }); + }); + } }; ChartInternal.prototype.updateSizes = function() { - var $$ = this, - config = $$.config; - var legendHeight = $$.legend ? $$.getLegendHeight() : 0, - legendWidth = $$.legend ? $$.getLegendWidth() : 0, - legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, - hasArc = $$.hasArcType(), - xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), - subchartHeight = config.subchart_show && !hasArc ? (config.subchart_size_height + xAxisHeight) : 0; - - $$.currentWidth = $$.getCurrentWidth(); - $$.currentHeight = $$.getCurrentHeight(); - - // for main - $$.margin = config.axis_rotated ? { + var $$ = this, + config = $$.config; + var legendHeight = $$.legend ? $$.getLegendHeight() : 0, + legendWidth = $$.legend ? $$.getLegendWidth() : 0, + legendHeightForBottom = + $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, + hasArc = $$.hasArcType(), + xAxisHeight = + config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), + subchartHeight = + config.subchart_show && !hasArc + ? config.subchart_size_height + xAxisHeight + : 0; + + $$.currentWidth = $$.getCurrentWidth(); + $$.currentHeight = $$.getCurrentHeight(); + + // for main + $$.margin = config.axis_rotated + ? { top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(), right: hasArc ? 0 : $$.getCurrentPaddingRight(), - bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(), + bottom: + $$.getHorizontalAxisHeight('y') + + legendHeightForBottom + + $$.getCurrentPaddingBottom(), left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft()) - } : { + } + : { top: 4 + $$.getCurrentPaddingTop(), // for top tick text right: hasArc ? 0 : $$.getCurrentPaddingRight(), - bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(), + bottom: + xAxisHeight + + subchartHeight + + legendHeightForBottom + + $$.getCurrentPaddingBottom(), left: hasArc ? 0 : $$.getCurrentPaddingLeft() - }; + }; - // for subchart - $$.margin2 = config.axis_rotated ? { + // for subchart + $$.margin2 = config.axis_rotated + ? { top: $$.margin.top, right: NaN, bottom: 20 + legendHeightForBottom, left: $$.rotated_padding_left - } : { + } + : { top: $$.currentHeight - subchartHeight - legendHeightForBottom, right: NaN, bottom: xAxisHeight + legendHeightForBottom, left: $$.margin.left - }; - - // for legend - $$.margin3 = { - top: 0, - right: NaN, - bottom: 0, - left: 0 - }; - if ($$.updateSizeForLegend) { - $$.updateSizeForLegend(legendHeight, legendWidth); - } + }; + + // for legend + $$.margin3 = { + top: 0, + right: NaN, + bottom: 0, + left: 0 + }; + if ($$.updateSizeForLegend) { + $$.updateSizeForLegend(legendHeight, legendWidth); + } - $$.width = $$.currentWidth - $$.margin.left - $$.margin.right; - $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom; - if ($$.width < 0) { - $$.width = 0; - } - if ($$.height < 0) { - $$.height = 0; - } + $$.width = $$.currentWidth - $$.margin.left - $$.margin.right; + $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom; + if ($$.width < 0) { + $$.width = 0; + } + if ($$.height < 0) { + $$.height = 0; + } - $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width; - $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom; - if ($$.width2 < 0) { - $$.width2 = 0; - } - if ($$.height2 < 0) { - $$.height2 = 0; - } + $$.width2 = config.axis_rotated + ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right + : $$.width; + $$.height2 = config.axis_rotated + ? $$.height + : $$.currentHeight - $$.margin2.top - $$.margin2.bottom; + if ($$.width2 < 0) { + $$.width2 = 0; + } + if ($$.height2 < 0) { + $$.height2 = 0; + } - // for arc - $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0); - $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10); - if ($$.hasType('gauge') && !config.gauge_fullCircle) { - $$.arcHeight += $$.height - $$.getGaugeLabelHeight(); - } - if ($$.updateRadius) { - $$.updateRadius(); - } + // for arc + $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0); + $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10); + if ($$.hasType('gauge') && !config.gauge_fullCircle) { + $$.arcHeight += $$.height - $$.getGaugeLabelHeight(); + } + if ($$.updateRadius) { + $$.updateRadius(); + } - if ($$.isLegendRight && hasArc) { - $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1; - } + if ($$.isLegendRight && hasArc) { + $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1; + } }; ChartInternal.prototype.updateTargets = function(targets) { - var $$ = this, config = $$.config; + var $$ = this, + config = $$.config; - /*-- Main --*/ + /*-- Main --*/ - //-- Text --// - $$.updateTargetsForText(targets); + //-- Text --// + $$.updateTargetsForText(targets); - //-- Bar --// - $$.updateTargetsForBar(targets); + //-- Bar --// + $$.updateTargetsForBar(targets); - //-- Line --// - $$.updateTargetsForLine(targets); + //-- Line --// + $$.updateTargetsForLine(targets); - //-- Arc --// - if ($$.hasArcType() && $$.updateTargetsForArc) { - $$.updateTargetsForArc(targets); - } + //-- Arc --// + if ($$.hasArcType() && $$.updateTargetsForArc) { + $$.updateTargetsForArc(targets); + } - /*-- Sub --*/ + /*-- Sub --*/ - if (config.subchart_show && $$.updateTargetsForSubchart) { - $$.updateTargetsForSubchart(targets); - } + if (config.subchart_show && $$.updateTargetsForSubchart) { + $$.updateTargetsForSubchart(targets); + } - // Fade-in each chart - $$.showTargets(); + // Fade-in each chart + $$.showTargets(); }; ChartInternal.prototype.showTargets = function() { - var $$ = this; - $$.svg.selectAll('.' + CLASS.target).filter(function(d) { - return $$.isTargetToShow(d.id); - }) - .transition().duration($$.config.transition_duration) - .style("opacity", 1); + var $$ = this; + $$.svg + .selectAll('.' + CLASS.target) + .filter(function(d) { + return $$.isTargetToShow(d.id) + }) + .transition() + .duration($$.config.transition_duration) + .style('opacity', 1); }; ChartInternal.prototype.redraw = function(options, transitions) { - var $$ = this, - main = $$.main, - d3 = $$.d3, - config = $$.config; - var areaIndices = $$.getShapeIndices($$.isAreaType), - barIndices = $$.getShapeIndices($$.isBarType), - lineIndices = $$.getShapeIndices($$.isLineType); - var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, - withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, - withEventRect, withDimension, withUpdateXAxis; - var hideAxis = $$.hasArcType(); - var drawArea, drawBar, drawLine, xForText, yForText; - var duration, durationForExit, durationForAxis; - var transitionsToWait, waitForDraw, flow, transition; - var targetsToShow = $$.filterTargetsToShow($$.data.targets), - tickValues, i, intervalForCulling, xDomainForZoom; - var xv = $$.xv.bind($$), - cx, cy; - - options = options || {}; - withY = getOption(options, "withY", true); - withSubchart = getOption(options, "withSubchart", true); - withTransition = getOption(options, "withTransition", true); - withTransform = getOption(options, "withTransform", false); - withUpdateXDomain = getOption(options, "withUpdateXDomain", false); - withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false); - withTrimXDomain = getOption(options, "withTrimXDomain", true); - withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain); - withLegend = getOption(options, "withLegend", false); - withEventRect = getOption(options, "withEventRect", true); - withDimension = getOption(options, "withDimension", true); - withTransitionForExit = getOption(options, "withTransitionForExit", withTransition); - withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition); - - duration = withTransition ? config.transition_duration : 0; - durationForExit = withTransitionForExit ? duration : 0; - durationForAxis = withTransitionForAxis ? duration : 0; - - transitions = transitions || $$.axis.generateTransitions(durationForAxis); - - // update legend and transform each g - if (withLegend && config.legend_show) { - $$.updateLegend($$.mapToIds($$.data.targets), options, transitions); - } else if (withDimension) { - // need to update dimension (e.g. axis.y.tick.values) because y tick values should change - // no need to update axis in it because they will be updated in redraw() - $$.updateDimension(true); - } - - // MEMO: needed for grids calculation - if ($$.isCategorized() && targetsToShow.length === 0) { - $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]); - } - - if (targetsToShow.length) { - $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain); - if (!config.axis_x_tick_values) { - tickValues = $$.axis.updateXAxisTickValues(targetsToShow); - } - } else { - $$.xAxis.tickValues([]); - $$.subXAxis.tickValues([]); - } - - if (config.zoom_rescale && !options.flow) { - xDomainForZoom = $$.x.orgDomain(); - } - - $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom)); - $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom)); - - if (!config.axis_y_tick_values && config.axis_y_tick_count) { - $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)); - } - if (!config.axis_y2_tick_values && config.axis_y2_tick_count) { - $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)); - } + var $$ = this, + main = $$.main, + d3 = $$.d3, + config = $$.config; + var areaIndices = $$.getShapeIndices($$.isAreaType), + barIndices = $$.getShapeIndices($$.isBarType), + lineIndices = $$.getShapeIndices($$.isLineType); + var withY, + withSubchart, + withTransition, + withTransitionForExit, + withTransitionForAxis, + withTransform, + withUpdateXDomain, + withUpdateOrgXDomain, + withTrimXDomain, + withLegend, + withEventRect, + withDimension, + withUpdateXAxis; + var hideAxis = $$.hasArcType(); + var drawArea, drawBar, drawLine, xForText, yForText; + var duration, durationForExit, durationForAxis; + var transitionsToWait, waitForDraw, flow, transition; + var targetsToShow = $$.filterTargetsToShow($$.data.targets), + tickValues, + i, + intervalForCulling, + xDomainForZoom; + var xv = $$.xv.bind($$), + cx, + cy; + + options = options || {}; + withY = getOption(options, 'withY', true); + withSubchart = getOption(options, 'withSubchart', true); + withTransition = getOption(options, 'withTransition', true); + withTransform = getOption(options, 'withTransform', false); + withUpdateXDomain = getOption(options, 'withUpdateXDomain', false); + withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false); + withTrimXDomain = getOption(options, 'withTrimXDomain', true); + withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain); + withLegend = getOption(options, 'withLegend', false); + withEventRect = getOption(options, 'withEventRect', true); + withDimension = getOption(options, 'withDimension', true); + withTransitionForExit = getOption( + options, + 'withTransitionForExit', + withTransition + ); + withTransitionForAxis = getOption( + options, + 'withTransitionForAxis', + withTransition + ); + + duration = withTransition ? config.transition_duration : 0; + durationForExit = withTransitionForExit ? duration : 0; + durationForAxis = withTransitionForAxis ? duration : 0; + + transitions = transitions || $$.axis.generateTransitions(durationForAxis); + + // update legend and transform each g + if (withLegend && config.legend_show) { + $$.updateLegend($$.mapToIds($$.data.targets), options, transitions); + } else if (withDimension) { + // need to update dimension (e.g. axis.y.tick.values) because y tick values should change + // no need to update axis in it because they will be updated in redraw() + $$.updateDimension(true); + } - // axes - $$.axis.redraw(durationForAxis, hideAxis); + // MEMO: needed for grids calculation + if ($$.isCategorized() && targetsToShow.length === 0) { + $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]); + } - // Update axis label - $$.axis.updateLabels(withTransition); + if (targetsToShow.length) { + $$.updateXDomain( + targetsToShow, + withUpdateXDomain, + withUpdateOrgXDomain, + withTrimXDomain + ); + if (!config.axis_x_tick_values) { + tickValues = $$.axis.updateXAxisTickValues(targetsToShow); + } + } else { + $$.xAxis.tickValues([]); + $$.subXAxis.tickValues([]); + } - // show/hide if manual culling needed - if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) { - if (config.axis_x_tick_culling && tickValues) { - for (i = 1; i < tickValues.length; i++) { - if (tickValues.length / i < config.axis_x_tick_culling_max) { - intervalForCulling = i; - break; - } - } - $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) { - var index = tickValues.indexOf(e); - if (index >= 0) { - d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block'); - } - }); - } else { - $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block'); - } - } + if (config.zoom_rescale && !options.flow) { + xDomainForZoom = $$.x.orgDomain(); + } - // setup drawer - MEMO: these must be called after axis updated - drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined; - drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined; - drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined; - xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true); - yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); + $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom)); + $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom)); - // update circleY based on updated parameters - $$.updateCircleY(); - // generate circle x/y functions depending on updated params - cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$); - cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); + if (!config.axis_y_tick_values && config.axis_y_tick_count) { + $$.yAxis.tickValues( + $$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count) + ); + } + if (!config.axis_y2_tick_values && config.axis_y2_tick_count) { + $$.y2Axis.tickValues( + $$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count) + ); + } - // Update sub domain - if (withY) { - $$.subY.domain($$.getYDomain(targetsToShow, 'y')); - $$.subY2.domain($$.getYDomain(targetsToShow, 'y2')); + // axes + $$.axis.redraw(durationForAxis, hideAxis); + + // Update axis label + $$.axis.updateLabels(withTransition); + + // show/hide if manual culling needed + if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) { + if (config.axis_x_tick_culling && tickValues) { + for (i = 1; i < tickValues.length; i++) { + if (tickValues.length / i < config.axis_x_tick_culling_max) { + intervalForCulling = i; + break + } + } + $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) { + var index = tickValues.indexOf(e); + if (index >= 0) { + d3.select(this).style( + 'display', + index % intervalForCulling ? 'none' : 'block' + ); + } + }); + } else { + $$.svg + .selectAll('.' + CLASS.axisX + ' .tick text') + .style('display', 'block'); } + } - // xgrid focus - $$.updateXgridFocus(); - - // Data empty label positioning and text. - main.select("text." + CLASS.text + '.' + CLASS.empty) - .attr("x", $$.width / 2) - .attr("y", $$.height / 2) - .text(config.data_empty_label_text) - .transition() - .style('opacity', targetsToShow.length ? 0 : 1); - - // event rect - if (withEventRect) { - $$.redrawEventRect(); - } + // setup drawer - MEMO: these must be called after axis updated + drawArea = $$.generateDrawArea + ? $$.generateDrawArea(areaIndices, false) + : undefined; + drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined; + drawLine = $$.generateDrawLine + ? $$.generateDrawLine(lineIndices, false) + : undefined; + xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true); + yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); + + // update circleY based on updated parameters + $$.updateCircleY(); + // generate circle x/y functions depending on updated params + cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$); + cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); + + // Update sub domain + if (withY) { + $$.subY.domain($$.getYDomain(targetsToShow, 'y')); + $$.subY2.domain($$.getYDomain(targetsToShow, 'y2')); + } - // grid - $$.updateGrid(duration); + // xgrid focus + $$.updateXgridFocus(); + + // Data empty label positioning and text. + main + .select('text.' + CLASS.text + '.' + CLASS.empty) + .attr('x', $$.width / 2) + .attr('y', $$.height / 2) + .text(config.data_empty_label_text) + .transition() + .style('opacity', targetsToShow.length ? 0 : 1); + + // event rect + if (withEventRect) { + $$.redrawEventRect(); + } - $$.updateStanfordElements(duration); + // grid + $$.updateGrid(duration); - // rect for regions - $$.updateRegion(duration); + $$.updateStanfordElements(duration); - // bars - $$.updateBar(durationForExit); + // rect for regions + $$.updateRegion(duration); - // lines, areas and circles - $$.updateLine(durationForExit); - $$.updateArea(durationForExit); - $$.updateCircle(cx, cy); + // bars + $$.updateBar(durationForExit); - // text - if ($$.hasDataLabel()) { - $$.updateText(xForText, yForText, durationForExit); - } + // lines, areas and circles + $$.updateLine(durationForExit); + $$.updateArea(durationForExit); + $$.updateCircle(cx, cy); - // title - if ($$.redrawTitle) { - $$.redrawTitle(); - } + // text + if ($$.hasDataLabel()) { + $$.updateText(xForText, yForText, durationForExit); + } - // arc - if ($$.redrawArc) { - $$.redrawArc(duration, durationForExit, withTransform); - } + // title + if ($$.redrawTitle) { + $$.redrawTitle(); + } - // subchart - if (config.subchart_show && $$.redrawSubchart) { - $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices); - } + // arc + if ($$.redrawArc) { + $$.redrawArc(duration, durationForExit, withTransform); + } - if ($$.isStanfordGraphType()) { - $$.drawColorScale(); - } + // subchart + if (config.subchart_show && $$.redrawSubchart) { + $$.redrawSubchart( + withSubchart, + transitions, + duration, + durationForExit, + areaIndices, + barIndices, + lineIndices + ); + } - // circles for select - main.selectAll('.' + CLASS.selectedCircles) - .filter($$.isBarType.bind($$)) - .selectAll('circle') - .remove(); + if ($$.isStanfordGraphType()) { + $$.drawColorScale(); + } - if (options.flow) { - flow = $$.generateFlow({ - targets: targetsToShow, - flow: options.flow, - duration: options.flow.duration, - drawBar: drawBar, - drawLine: drawLine, - drawArea: drawArea, - cx: cx, - cy: cy, - xv: xv, - xForText: xForText, - yForText: yForText - }); - } + // circles for select + main + .selectAll('.' + CLASS.selectedCircles) + .filter($$.isBarType.bind($$)) + .selectAll('circle') + .remove(); + + if (options.flow) { + flow = $$.generateFlow({ + targets: targetsToShow, + flow: options.flow, + duration: options.flow.duration, + drawBar: drawBar, + drawLine: drawLine, + drawArea: drawArea, + cx: cx, + cy: cy, + xv: xv, + xForText: xForText, + yForText: yForText + }); + } - if (duration && $$.isTabVisible()) { // Only use transition if tab visible. See #938. - // transition should be derived from one transition - transition = d3.transition().duration(duration); - transitionsToWait = []; - [ - $$.redrawBar(drawBar, true, transition), - $$.redrawLine(drawLine, true, transition), - $$.redrawArea(drawArea, true, transition), - $$.redrawCircle(cx, cy, true, transition), - $$.redrawText(xForText, yForText, options.flow, true, transition), - $$.redrawRegion(true, transition), - $$.redrawGrid(true, transition), - ].forEach(function(transitions) { - transitions.forEach(function(transition) { - transitionsToWait.push(transition); - }); - }); - // Wait for end of transitions to call flow and onrendered callback - waitForDraw = $$.generateWait(); - transitionsToWait.forEach(function(t) { - waitForDraw.add(t); - }); - waitForDraw(function() { - if (flow) { - flow(); - } - if (config.onrendered) { - config.onrendered.call($$); - } - }); - } else { - $$.redrawBar(drawBar); - $$.redrawLine(drawLine); - $$.redrawArea(drawArea); - $$.redrawCircle(cx, cy); - $$.redrawText(xForText, yForText, options.flow); - $$.redrawRegion(); - $$.redrawGrid(); - if (flow) { - flow(); - } - if (config.onrendered) { - config.onrendered.call($$); - } + if (duration && $$.isTabVisible()) { + // Only use transition if tab visible. See #938. + // transition should be derived from one transition + transition = d3.transition().duration(duration); + transitionsToWait = [] + ;[ + $$.redrawBar(drawBar, true, transition), + $$.redrawLine(drawLine, true, transition), + $$.redrawArea(drawArea, true, transition), + $$.redrawCircle(cx, cy, true, transition), + $$.redrawText(xForText, yForText, options.flow, true, transition), + $$.redrawRegion(true, transition), + $$.redrawGrid(true, transition) + ].forEach(function(transitions) { + transitions.forEach(function(transition) { + transitionsToWait.push(transition); + }); + }); + // Wait for end of transitions to call flow and onrendered callback + waitForDraw = $$.generateWait(); + transitionsToWait.forEach(function(t) { + waitForDraw.add(t); + }); + waitForDraw(function() { + if (flow) { + flow(); + } + if (config.onrendered) { + config.onrendered.call($$); + } + }); + } else { + $$.redrawBar(drawBar); + $$.redrawLine(drawLine); + $$.redrawArea(drawArea); + $$.redrawCircle(cx, cy); + $$.redrawText(xForText, yForText, options.flow); + $$.redrawRegion(); + $$.redrawGrid(); + if (flow) { + flow(); + } + if (config.onrendered) { + config.onrendered.call($$); } + } - // update fadein condition - $$.mapToIds($$.data.targets).forEach(function(id) { - $$.withoutFadeIn[id] = true; - }); + // update fadein condition + $$.mapToIds($$.data.targets).forEach(function(id) { + $$.withoutFadeIn[id] = true; + }); }; ChartInternal.prototype.updateAndRedraw = function(options) { - var $$ = this, - config = $$.config, - transitions; - options = options || {}; - // same with redraw - options.withTransition = getOption(options, "withTransition", true); - options.withTransform = getOption(options, "withTransform", false); - options.withLegend = getOption(options, "withLegend", false); - // NOT same with redraw - options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true); - options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true); - options.withTransitionForExit = false; - options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); - // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) - $$.updateSizes(); - // MEMO: called in updateLegend in redraw if withLegend - if (!(options.withLegend && config.legend_show)) { - transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0); - // Update scales - $$.updateScales(); - $$.updateSvgSize(); - // Update g positions - $$.transformAll(options.withTransitionForTransform, transitions); - } - // Draw with new sizes & scales - $$.redraw(options, transitions); + var $$ = this, + config = $$.config, + transitions; + options = options || {}; + // same with redraw + options.withTransition = getOption(options, 'withTransition', true); + options.withTransform = getOption(options, 'withTransform', false); + options.withLegend = getOption(options, 'withLegend', false); + // NOT same with redraw + options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true); + options.withUpdateOrgXDomain = getOption( + options, + 'withUpdateOrgXDomain', + true + ); + options.withTransitionForExit = false; + options.withTransitionForTransform = getOption( + options, + 'withTransitionForTransform', + options.withTransition + ); + // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) + $$.updateSizes(); + // MEMO: called in updateLegend in redraw if withLegend + if (!(options.withLegend && config.legend_show)) { + transitions = $$.axis.generateTransitions( + options.withTransitionForAxis ? config.transition_duration : 0 + ); + // Update scales + $$.updateScales(); + $$.updateSvgSize(); + // Update g positions + $$.transformAll(options.withTransitionForTransform, transitions); + } + // Draw with new sizes & scales + $$.redraw(options, transitions); }; ChartInternal.prototype.redrawWithoutRescale = function() { - this.redraw({ - withY: false, - withSubchart: false, - withEventRect: false, - withTransitionForAxis: false - }); + this.redraw({ + withY: false, + withSubchart: false, + withEventRect: false, + withTransitionForAxis: false + }); }; ChartInternal.prototype.isTimeSeries = function() { - return this.config.axis_x_type === 'timeseries'; + return this.config.axis_x_type === 'timeseries' }; ChartInternal.prototype.isCategorized = function() { - return this.config.axis_x_type.indexOf('categor') >= 0; + return this.config.axis_x_type.indexOf('categor') >= 0 }; ChartInternal.prototype.isCustomX = function() { - var $$ = this, - config = $$.config; - return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs)); + var $$ = this, + config = $$.config; + return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs)) }; ChartInternal.prototype.isTimeSeriesY = function() { - return this.config.axis_y_type === 'timeseries'; + return this.config.axis_y_type === 'timeseries' }; ChartInternal.prototype.getTranslate = function(target) { - var $$ = this, - config = $$.config, - x, y; - if (target === 'main') { - x = asHalfPixel($$.margin.left); - y = asHalfPixel($$.margin.top); - } else if (target === 'context') { - x = asHalfPixel($$.margin2.left); - y = asHalfPixel($$.margin2.top); - } else if (target === 'legend') { - x = $$.margin3.left; - y = $$.margin3.top; - } else if (target === 'x') { - x = 0; - y = config.axis_rotated ? 0 : $$.height; - } else if (target === 'y') { - x = 0; - y = config.axis_rotated ? $$.height : 0; - } else if (target === 'y2') { - x = config.axis_rotated ? 0 : $$.width; - y = config.axis_rotated ? 1 : 0; - } else if (target === 'subx') { - x = 0; - y = config.axis_rotated ? 0 : $$.height2; - } else if (target === 'arc') { - x = $$.arcWidth / 2; - y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label - } - return "translate(" + x + "," + y + ")"; + var $$ = this, + config = $$.config, + x, + y; + if (target === 'main') { + x = asHalfPixel($$.margin.left); + y = asHalfPixel($$.margin.top); + } else if (target === 'context') { + x = asHalfPixel($$.margin2.left); + y = asHalfPixel($$.margin2.top); + } else if (target === 'legend') { + x = $$.margin3.left; + y = $$.margin3.top; + } else if (target === 'x') { + x = 0; + y = config.axis_rotated ? 0 : $$.height; + } else if (target === 'y') { + x = 0; + y = config.axis_rotated ? $$.height : 0; + } else if (target === 'y2') { + x = config.axis_rotated ? 0 : $$.width; + y = config.axis_rotated ? 1 : 0; + } else if (target === 'subx') { + x = 0; + y = config.axis_rotated ? 0 : $$.height2; + } else if (target === 'arc') { + x = $$.arcWidth / 2; + y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label + } + return 'translate(' + x + ',' + y + ')' }; ChartInternal.prototype.initialOpacity = function(d) { - return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0; + return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0 }; ChartInternal.prototype.initialOpacityForCircle = function(d) { - return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0; + return d.value !== null && this.withoutFadeIn[d.id] + ? this.opacityForCircle(d) + : 0 }; ChartInternal.prototype.opacityForCircle = function(d) { - var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show; - var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0; - return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0; + var isPointShouldBeShown = isFunction(this.config.point_show) + ? this.config.point_show(d) + : this.config.point_show; + var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0; + return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0 }; ChartInternal.prototype.opacityForText = function() { - return this.hasDataLabel() ? 1 : 0; + return this.hasDataLabel() ? 1 : 0 }; ChartInternal.prototype.xx = function(d) { - return d ? this.x(d.x) : null; + return d ? this.x(d.x) : null }; ChartInternal.prototype.xvCustom = function(d, xyValue) { - var $$ = this, - value = xyValue ? d[xyValue] : d.value; - if ($$.isTimeSeries()) { - value = $$.parseDate(d.value); - } else if ($$.isCategorized() && typeof d.value === 'string') { - value = $$.config.axis_x_categories.indexOf(d.value); - } - return Math.ceil($$.x(value)); + var $$ = this, + value = xyValue ? d[xyValue] : d.value; + if ($$.isTimeSeries()) { + value = $$.parseDate(d.value); + } else if ($$.isCategorized() && typeof d.value === 'string') { + value = $$.config.axis_x_categories.indexOf(d.value); + } + return Math.ceil($$.x(value)) }; ChartInternal.prototype.yvCustom = function(d, xyValue) { - var $$ = this, - yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y, - value = xyValue ? d[xyValue] : d.value; - return Math.ceil(yScale(value)); + var $$ = this, + yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y, + value = xyValue ? d[xyValue] : d.value; + return Math.ceil(yScale(value)) }; ChartInternal.prototype.xv = function(d) { - var $$ = this, - value = d.value; - if ($$.isTimeSeries()) { - value = $$.parseDate(d.value); - } else if ($$.isCategorized() && typeof d.value === 'string') { - value = $$.config.axis_x_categories.indexOf(d.value); - } - return Math.ceil($$.x(value)); + var $$ = this, + value = d.value; + if ($$.isTimeSeries()) { + value = $$.parseDate(d.value); + } else if ($$.isCategorized() && typeof d.value === 'string') { + value = $$.config.axis_x_categories.indexOf(d.value); + } + return Math.ceil($$.x(value)) }; ChartInternal.prototype.yv = function(d) { - var $$ = this, - yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y; - return Math.ceil(yScale(d.value)); + var $$ = this, + yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y; + return Math.ceil(yScale(d.value)) }; ChartInternal.prototype.subxx = function(d) { - return d ? this.subX(d.x) : null; + return d ? this.subX(d.x) : null }; ChartInternal.prototype.transformMain = function(withTransition, transitions) { - var $$ = this, - xAxis, yAxis, y2Axis; - if (transitions && transitions.axisX) { - xAxis = transitions.axisX; - } else { - xAxis = $$.main.select('.' + CLASS.axisX); - if (withTransition) { - xAxis = xAxis.transition(); - } + var $$ = this, + xAxis, + yAxis, + y2Axis; + if (transitions && transitions.axisX) { + xAxis = transitions.axisX; + } else { + xAxis = $$.main.select('.' + CLASS.axisX); + if (withTransition) { + xAxis = xAxis.transition(); } - if (transitions && transitions.axisY) { - yAxis = transitions.axisY; - } else { - yAxis = $$.main.select('.' + CLASS.axisY); - if (withTransition) { - yAxis = yAxis.transition(); - } + } + if (transitions && transitions.axisY) { + yAxis = transitions.axisY; + } else { + yAxis = $$.main.select('.' + CLASS.axisY); + if (withTransition) { + yAxis = yAxis.transition(); } - if (transitions && transitions.axisY2) { - y2Axis = transitions.axisY2; - } else { - y2Axis = $$.main.select('.' + CLASS.axisY2); - if (withTransition) { - y2Axis = y2Axis.transition(); - } + } + if (transitions && transitions.axisY2) { + y2Axis = transitions.axisY2; + } else { + y2Axis = $$.main.select('.' + CLASS.axisY2); + if (withTransition) { + y2Axis = y2Axis.transition(); } - (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main')); - xAxis.attr("transform", $$.getTranslate('x')); - yAxis.attr("transform", $$.getTranslate('y')); - y2Axis.attr("transform", $$.getTranslate('y2')); - $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); + } +(withTransition ? $$.main.transition() : $$.main).attr( + 'transform', + $$.getTranslate('main') + ); + xAxis.attr('transform', $$.getTranslate('x')); + yAxis.attr('transform', $$.getTranslate('y')); + y2Axis.attr('transform', $$.getTranslate('y2')); + $$.main + .select('.' + CLASS.chartArcs) + .attr('transform', $$.getTranslate('arc')); }; ChartInternal.prototype.transformAll = function(withTransition, transitions) { - var $$ = this; - $$.transformMain(withTransition, transitions); - if ($$.config.subchart_show) { - $$.transformContext(withTransition, transitions); - } - if ($$.legend) { - $$.transformLegend(withTransition); - } + var $$ = this; + $$.transformMain(withTransition, transitions); + if ($$.config.subchart_show) { + $$.transformContext(withTransition, transitions); + } + if ($$.legend) { + $$.transformLegend(withTransition); + } }; ChartInternal.prototype.updateSvgSize = function() { - var $$ = this, - brush = $$.svg.select(`.${CLASS.brush} .overlay`); - $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight); - $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect') - .attr('width', $$.width) - .attr('height', $$.height); - $$.svg.select('#' + $$.clipIdForXAxis).select('rect') - .attr('x', $$.getXAxisClipX.bind($$)) - .attr('y', $$.getXAxisClipY.bind($$)) - .attr('width', $$.getXAxisClipWidth.bind($$)) - .attr('height', $$.getXAxisClipHeight.bind($$)); - $$.svg.select('#' + $$.clipIdForYAxis).select('rect') - .attr('x', $$.getYAxisClipX.bind($$)) - .attr('y', $$.getYAxisClipY.bind($$)) - .attr('width', $$.getYAxisClipWidth.bind($$)) - .attr('height', $$.getYAxisClipHeight.bind($$)); - $$.svg.select('#' + $$.clipIdForSubchart).select('rect') - .attr('width', $$.width) - .attr('height', brush.size() && brush.attr('height') || 0); - // MEMO: parent div's height will be bigger than svg when - $$.selectChart.style('max-height', $$.currentHeight + "px"); + var $$ = this, + brush = $$.svg.select(`.${CLASS.brush} .overlay`); + $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight); + $$.svg + .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]) + .select('rect') + .attr('width', $$.width) + .attr('height', $$.height); + $$.svg + .select('#' + $$.clipIdForXAxis) + .select('rect') + .attr('x', $$.getXAxisClipX.bind($$)) + .attr('y', $$.getXAxisClipY.bind($$)) + .attr('width', $$.getXAxisClipWidth.bind($$)) + .attr('height', $$.getXAxisClipHeight.bind($$)); + $$.svg + .select('#' + $$.clipIdForYAxis) + .select('rect') + .attr('x', $$.getYAxisClipX.bind($$)) + .attr('y', $$.getYAxisClipY.bind($$)) + .attr('width', $$.getYAxisClipWidth.bind($$)) + .attr('height', $$.getYAxisClipHeight.bind($$)); + $$.svg + .select('#' + $$.clipIdForSubchart) + .select('rect') + .attr('width', $$.width) + .attr('height', (brush.size() && brush.attr('height')) || 0); + // MEMO: parent div's height will be bigger than svg when + $$.selectChart.style('max-height', $$.currentHeight + 'px'); }; ChartInternal.prototype.updateDimension = function(withoutAxis) { - var $$ = this; - if (!withoutAxis) { - if ($$.config.axis_rotated) { - $$.axes.x.call($$.xAxis); - $$.axes.subx.call($$.subXAxis); - } else { - $$.axes.y.call($$.yAxis); - $$.axes.y2.call($$.y2Axis); - } + var $$ = this; + if (!withoutAxis) { + if ($$.config.axis_rotated) { + $$.axes.x.call($$.xAxis); + $$.axes.subx.call($$.subXAxis); + } else { + $$.axes.y.call($$.yAxis); + $$.axes.y2.call($$.y2Axis); } - $$.updateSizes(); - $$.updateScales(); - $$.updateSvgSize(); - $$.transformAll(false); + } + $$.updateSizes(); + $$.updateScales(); + $$.updateSvgSize(); + $$.transformAll(false); }; ChartInternal.prototype.observeInserted = function(selection) { - var $$ = this, - observer; - if (typeof MutationObserver === 'undefined') { - window.console.error("MutationObserver not defined."); - return; - } - observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - if (mutation.type === 'childList' && mutation.previousSibling) { - observer.disconnect(); - // need to wait for completion of load because size calculation requires the actual sizes determined after that completion - $$.intervalForObserveInserted = window.setInterval(function() { - // parentNode will NOT be null when completed - if (selection.node().parentNode) { - window.clearInterval($$.intervalForObserveInserted); - $$.updateDimension(); - if ($$.brush) { - $$.brush.update(); - } - $$.config.oninit.call($$); - $$.redraw({ - withTransform: true, - withUpdateXDomain: true, - withUpdateOrgXDomain: true, - withTransition: false, - withTransitionForTransform: false, - withLegend: true - }); - selection.transition().style('opacity', 1); - } - }, 10); + var $$ = this, + observer; + if (typeof MutationObserver === 'undefined') { + window.console.error('MutationObserver not defined.'); + return + } + observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'childList' && mutation.previousSibling) { + observer.disconnect(); + // need to wait for completion of load because size calculation requires the actual sizes determined after that completion + $$.intervalForObserveInserted = window.setInterval(function() { + // parentNode will NOT be null when completed + if (selection.node().parentNode) { + window.clearInterval($$.intervalForObserveInserted); + $$.updateDimension(); + if ($$.brush) { + $$.brush.update(); } - }); - }); - observer.observe(selection.node(), { - attributes: true, - childList: true, - characterData: true + $$.config.oninit.call($$); + $$.redraw({ + withTransform: true, + withUpdateXDomain: true, + withUpdateOrgXDomain: true, + withTransition: false, + withTransitionForTransform: false, + withLegend: true + }); + selection.transition().style('opacity', 1); + } + }, 10); + } }); + }); + observer.observe(selection.node(), { + attributes: true, + childList: true, + characterData: true + }); }; /** * Binds handlers to the window resize event. */ ChartInternal.prototype.bindResize = function() { - var $$ = this, - config = $$.config; + var $$ = this, + config = $$.config; - $$.resizeFunction = $$.generateResize(); // need to call .remove + $$.resizeFunction = $$.generateResize(); // need to call .remove + $$.resizeFunction.add(function() { + config.onresize.call($$); + }); + if (config.resize_auto) { $$.resizeFunction.add(function() { - config.onresize.call($$); - }); - if (config.resize_auto) { - $$.resizeFunction.add(function() { - if ($$.resizeTimeout !== undefined) { - window.clearTimeout($$.resizeTimeout); - } - $$.resizeTimeout = window.setTimeout(function() { - delete $$.resizeTimeout; - $$.updateAndRedraw({ - withUpdateXDomain: false, - withUpdateOrgXDomain: false, - withTransition: false, - withTransitionForTransform: false, - withLegend: true, - }); - if ($$.brush) { - $$.brush.update(); - } - }, 100); + if ($$.resizeTimeout !== undefined) { + window.clearTimeout($$.resizeTimeout); + } + $$.resizeTimeout = window.setTimeout(function() { + delete $$.resizeTimeout; + $$.updateAndRedraw({ + withUpdateXDomain: false, + withUpdateOrgXDomain: false, + withTransition: false, + withTransitionForTransform: false, + withLegend: true }); - } - $$.resizeFunction.add(function() { - config.onresized.call($$); - }); - - $$.resizeIfElementDisplayed = function() { - // if element not displayed skip it - if ($$.api == null || !$$.api.element.offsetParent) { - return; + if ($$.brush) { + $$.brush.update(); } - - $$.resizeFunction(); + }, 100); + }); + } + $$.resizeFunction.add(function() { + config.onresized.call($$); + }); + + $$.resizeIfElementDisplayed = function() { + // if element not displayed skip it + if ($$.api == null || !$$.api.element.offsetParent) { + return + } + + $$.resizeFunction(); + }; + + if (window.attachEvent) { + window.attachEvent('onresize', $$.resizeIfElementDisplayed); + } else if (window.addEventListener) { + window.addEventListener('resize', $$.resizeIfElementDisplayed, false); + } else { + // fallback to this, if this is a very old browser + var wrapper = window.onresize; + if (!wrapper) { + // create a wrapper that will call all charts + wrapper = $$.generateResize(); + } else if (!wrapper.add || !wrapper.remove) { + // there is already a handler registered, make sure we call it too + wrapper = $$.generateResize(); + wrapper.add(window.onresize); + } + // add this graph to the wrapper, we will be removed if the user calls destroy + wrapper.add($$.resizeFunction); + window.onresize = function() { + // if element not displayed skip it + if (!$$.api.element.offsetParent) { + return + } + + wrapper(); }; - - if (window.attachEvent) { - window.attachEvent('onresize', $$.resizeIfElementDisplayed); - } else if (window.addEventListener) { - window.addEventListener('resize', $$.resizeIfElementDisplayed, false); - } else { - // fallback to this, if this is a very old browser - var wrapper = window.onresize; - if (!wrapper) { - // create a wrapper that will call all charts - wrapper = $$.generateResize(); - } else if (!wrapper.add || !wrapper.remove) { - // there is already a handler registered, make sure we call it too - wrapper = $$.generateResize(); - wrapper.add(window.onresize); - } - // add this graph to the wrapper, we will be removed if the user calls destroy - wrapper.add($$.resizeFunction); - window.onresize = function() { - // if element not displayed skip it - if (!$$.api.element.offsetParent) { - return; - } - - wrapper(); - }; - } + } }; /** * Binds handlers to the window focus event. */ ChartInternal.prototype.bindWindowFocus = function() { - if (this.windowFocusHandler) { - // The handler is already set - return; - } + if (this.windowFocusHandler) { + // The handler is already set + return + } - this.windowFocusHandler = () => { this.redraw(); }; + this.windowFocusHandler = () => { + this.redraw(); + }; - window.addEventListener('focus', this.windowFocusHandler); + window.addEventListener('focus', this.windowFocusHandler); }; /** * Unbinds from the window focus event. */ -ChartInternal.prototype.unbindWindowFocus = function () { - window.removeEventListener('focus', this.windowFocusHandler); - delete this.windowFocusHandler; +ChartInternal.prototype.unbindWindowFocus = function() { + window.removeEventListener('focus', this.windowFocusHandler); + delete this.windowFocusHandler; }; ChartInternal.prototype.generateResize = function() { - var resizeFunctions = []; + var resizeFunctions = []; - function callResizeFunctions() { - resizeFunctions.forEach(function(f) { - f(); - }); + function callResizeFunctions() { + resizeFunctions.forEach(function(f) { + f(); + }); + } + callResizeFunctions.add = function(f) { + resizeFunctions.push(f); + }; + callResizeFunctions.remove = function(f) { + for (var i = 0; i < resizeFunctions.length; i++) { + if (resizeFunctions[i] === f) { + resizeFunctions.splice(i, 1); + break + } } - callResizeFunctions.add = function(f) { - resizeFunctions.push(f); - }; - callResizeFunctions.remove = function(f) { - for (var i = 0; i < resizeFunctions.length; i++) { - if (resizeFunctions[i] === f) { - resizeFunctions.splice(i, 1); - break; - } - } - }; - return callResizeFunctions; + }; + return callResizeFunctions }; ChartInternal.prototype.endall = function(transition, callback) { - var n = 0; - transition - .each(function() { - ++n; - }) - .on("end", function() { - if (!--n) { - callback.apply(this, arguments); - } - }); + var n = 0; + transition + .each(function() { + ++n; + }) + .on('end', function() { + if (!--n) { + callback.apply(this, arguments); + } + }); }; ChartInternal.prototype.generateWait = function() { - var $$ = this; - var transitionsToWait = [], - f = function(callback) { - var timer = setInterval(function() { - if (!$$.isTabVisible()) { - return; - } + var $$ = this; + var transitionsToWait = [], + f = function(callback) { + var timer = setInterval(function() { + if (!$$.isTabVisible()) { + return + } - var done = 0; - transitionsToWait.forEach(function(t) { - if (t.empty()) { - done += 1; - return; - } - try { - t.transition(); - } catch (e) { - done += 1; - } - }); - if (done === transitionsToWait.length) { - clearInterval(timer); - if (callback) { - callback(); - } - } - }, 50); - }; - f.add = function(transition) { - transitionsToWait.push(transition); + var done = 0; + transitionsToWait.forEach(function(t) { + if (t.empty()) { + done += 1; + return + } + try { + t.transition(); + } catch (e) { + done += 1; + } + }); + if (done === transitionsToWait.length) { + clearInterval(timer); + if (callback) { + callback(); + } + } + }, 50); }; - return f; + f.add = function(transition) { + transitionsToWait.push(transition); + }; + return f }; ChartInternal.prototype.parseDate = function(date) { - var $$ = this, - parsedDate; - if (date instanceof Date) { - parsedDate = date; - } else if (typeof date === 'string') { - parsedDate = $$.dataTimeParse(date); - } else if (typeof date === 'object') { - parsedDate = new Date(+date); - } else if (typeof date === 'number' && !isNaN(date)) { - parsedDate = new Date(+date); - } - if (!parsedDate || isNaN(+parsedDate)) { - window.console.error("Failed to parse x '" + date + "' to Date object"); - } - return parsedDate; + var $$ = this, + parsedDate; + if (date instanceof Date) { + parsedDate = date; + } else if (typeof date === 'string') { + parsedDate = $$.dataTimeParse(date); + } else if (typeof date === 'object') { + parsedDate = new Date(+date); + } else if (typeof date === 'number' && !isNaN(date)) { + parsedDate = new Date(+date); + } + if (!parsedDate || isNaN(+parsedDate)) { + window.console.error("Failed to parse x '" + date + "' to Date object"); + } + return parsedDate }; ChartInternal.prototype.isTabVisible = function() { - return !document.hidden; + return !document.hidden }; ChartInternal.prototype.getPathBox = getPathBox; ChartInternal.prototype.CLASS = CLASS; /* jshint ignore:start */ +(function() { + if (!('SVGPathSeg' in window)) { + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg + window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) { + this.pathSegType = type; + this.pathSegTypeAsLetter = typeAsLetter; + this._owningPathSegList = owningPathSegList; + }; -// SVGPathSeg API polyfill -// https://github.com/progers/pathseg -// -// This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from -// SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec -// changes which were implemented in Firefox 43 and Chrome 46. - -(function () { - if (!("SVGPathSeg" in window)) { - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg - window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) { - this.pathSegType = type; - this.pathSegTypeAsLetter = typeAsLetter; - this._owningPathSegList = owningPathSegList; - }; + window.SVGPathSeg.prototype.classname = 'SVGPathSeg'; + + window.SVGPathSeg.PATHSEG_UNKNOWN = 0; + window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; + window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; + window.SVGPathSeg.PATHSEG_MOVETO_REL = 3; + window.SVGPathSeg.PATHSEG_LINETO_ABS = 4; + window.SVGPathSeg.PATHSEG_LINETO_REL = 5; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9; + window.SVGPathSeg.PATHSEG_ARC_ABS = 10; + window.SVGPathSeg.PATHSEG_ARC_REL = 11; + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12; + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13; + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14; + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16; + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18; + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; + + // Notify owning PathSegList on any changes so they can be synchronized back to the path element. + window.SVGPathSeg.prototype._segmentChanged = function() { + if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this); + }; - window.SVGPathSeg.prototype.classname = "SVGPathSeg"; - - window.SVGPathSeg.PATHSEG_UNKNOWN = 0; - window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; - window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; - window.SVGPathSeg.PATHSEG_MOVETO_REL = 3; - window.SVGPathSeg.PATHSEG_LINETO_ABS = 4; - window.SVGPathSeg.PATHSEG_LINETO_REL = 5; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9; - window.SVGPathSeg.PATHSEG_ARC_ABS = 10; - window.SVGPathSeg.PATHSEG_ARC_REL = 11; - window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12; - window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13; - window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14; - window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; - - // Notify owning PathSegList on any changes so they can be synchronized back to the path element. - window.SVGPathSeg.prototype._segmentChanged = function () { - if (this._owningPathSegList) - this._owningPathSegList.segmentChanged(this); - }; + window.SVGPathSegClosePath = function(owningPathSegList) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CLOSEPATH, + 'z', + owningPathSegList + ); + }; + window.SVGPathSegClosePath.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegClosePath.prototype.toString = function() { + return '[object SVGPathSegClosePath]' + }; + window.SVGPathSegClosePath.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + }; + window.SVGPathSegClosePath.prototype.clone = function() { + return new window.SVGPathSegClosePath(undefined) + }; - window.SVGPathSegClosePath = function (owningPathSegList) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList); - }; - window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegClosePath.prototype.toString = function () { - return "[object SVGPathSegClosePath]"; - }; - window.SVGPathSegClosePath.prototype._asPathString = function () { - return this.pathSegTypeAsLetter; - }; - window.SVGPathSegClosePath.prototype.clone = function () { - return new window.SVGPathSegClosePath(undefined); - }; + window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_MOVETO_ABS, + 'M', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegMovetoAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegMovetoAbs.prototype.toString = function() { + return '[object SVGPathSegMovetoAbs]' + }; + window.SVGPathSegMovetoAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegMovetoAbs.prototype.clone = function() { + return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegMovetoAbs.prototype.toString = function () { - return "[object SVGPathSegMovetoAbs]"; - }; - window.SVGPathSegMovetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegMovetoAbs.prototype.clone = function () { - return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_MOVETO_REL, + 'm', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegMovetoRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegMovetoRel.prototype.toString = function() { + return '[object SVGPathSegMovetoRel]' + }; + window.SVGPathSegMovetoRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegMovetoRel.prototype.clone = function() { + return new window.SVGPathSegMovetoRel(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegMovetoRel.prototype.toString = function () { - return "[object SVGPathSegMovetoRel]"; - }; - window.SVGPathSegMovetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegMovetoRel.prototype.clone = function () { - return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_ABS, + 'L', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegLinetoAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoAbs.prototype.toString = function() { + return '[object SVGPathSegLinetoAbs]' + }; + window.SVGPathSegLinetoAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegLinetoAbs.prototype.clone = function() { + return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoAbs]"; - }; - window.SVGPathSegLinetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegLinetoAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoRel.prototype.toString = function () { - return "[object SVGPathSegLinetoRel]"; - }; - window.SVGPathSegLinetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegLinetoRel.prototype.clone = function () { - return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicAbs]"; - }; - window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicRel]"; - }; - window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - }; - window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticAbs]"; - }; - window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - }; - window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticRel]"; - }; - window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_REL, + 'l', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegLinetoRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoRel.prototype.toString = function() { + return '[object SVGPathSegLinetoRel]' + }; + window.SVGPathSegLinetoRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegLinetoRel.prototype.clone = function() { + return new window.SVGPathSegLinetoRel(undefined, this._x, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList); - this._x = x; - this._y = y; - this._r1 = r1; - this._r2 = r2; - this._angle = angle; - this._largeArcFlag = largeArcFlag; - this._sweepFlag = sweepFlag; - }; - window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegArcAbs.prototype.toString = function () { - return "[object SVGPathSegArcAbs]"; - }; - window.SVGPathSegArcAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + - this._x + " " + this._y; - }; - window.SVGPathSegArcAbs.prototype.clone = function () { - return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); - }; - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { - get: function () { - return this._r1; - }, - set: function (r1) { - this._r1 = r1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { - get: function () { - return this._r2; - }, - set: function (r2) { - this._r2 = r2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { - get: function () { - return this._angle; - }, - set: function (angle) { - this._angle = angle; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { - get: function () { - return this._largeArcFlag; - }, - set: function (largeArcFlag) { - this._largeArcFlag = largeArcFlag; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { - get: function () { - return this._sweepFlag; - }, - set: function (sweepFlag) { - this._sweepFlag = sweepFlag; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoCubicAbs = function( + owningPathSegList, + x, + y, + x1, + y1, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, + 'C', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicAbs]' + }; + window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicAbs( + undefined, + this._x, + this._y, + this._x1, + this._y1, + this._x2, + this._y2 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList); - this._x = x; - this._y = y; - this._r1 = r1; - this._r2 = r2; - this._angle = angle; - this._largeArcFlag = largeArcFlag; - this._sweepFlag = sweepFlag; - }; - window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegArcRel.prototype.toString = function () { - return "[object SVGPathSegArcRel]"; - }; - window.SVGPathSegArcRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + - this._x + " " + this._y; - }; - window.SVGPathSegArcRel.prototype.clone = function () { - return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); - }; - Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { - get: function () { - return this._r1; - }, - set: function (r1) { - this._r1 = r1; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { - get: function () { - return this._r2; - }, - set: function (r2) { - this._r2 = r2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { - get: function () { - return this._angle; - }, - set: function (angle) { - this._angle = angle; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { - get: function () { - return this._largeArcFlag; - }, - set: function (largeArcFlag) { - this._largeArcFlag = largeArcFlag; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { - get: function () { - return this._sweepFlag; - }, - set: function (sweepFlag) { - this._sweepFlag = sweepFlag; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoCubicRel = function( + owningPathSegList, + x, + y, + x1, + y1, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, + 'c', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicRel]' + }; + window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicRel( + undefined, + this._x, + this._y, + this._x1, + this._y1, + this._x2, + this._y2 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList); - this._x = x; - }; - window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalAbs]"; - }; - window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; - }; - window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); - }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoQuadraticAbs = function( + owningPathSegList, + x, + y, + x1, + y1 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, + 'Q', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + }; + window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticAbs]' + }; + window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticAbs( + undefined, + this._x, + this._y, + this._x1, + this._y1 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticAbs.prototype, + 'x1', + { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticAbs.prototype, + 'y1', + { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoQuadraticRel = function( + owningPathSegList, + x, + y, + x1, + y1 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, + 'q', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x1 = x1; + this._y1 = y1; + }; + window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticRel]' + }; + window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x1 + + ' ' + + this._y1 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticRel( + undefined, + this._x, + this._y, + this._x1, + this._y1 + ) + }; + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticRel.prototype, + 'x1', + { + get: function() { + return this._x1 + }, + set: function(x1) { + this._x1 = x1; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticRel.prototype, + 'y1', + { + get: function() { + return this._y1 + }, + set: function(y1) { + this._y1 = y1; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegArcAbs = function( + owningPathSegList, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_ARC_ABS, + 'A', + owningPathSegList + ); + this._x = x; + this._y = y; + this._r1 = r1; + this._r2 = r2; + this._angle = angle; + this._largeArcFlag = largeArcFlag; + this._sweepFlag = sweepFlag; + }; + window.SVGPathSegArcAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegArcAbs.prototype.toString = function() { + return '[object SVGPathSegArcAbs]' + }; + window.SVGPathSegArcAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._r1 + + ' ' + + this._r2 + + ' ' + + this._angle + + ' ' + + (this._largeArcFlag ? '1' : '0') + + ' ' + + (this._sweepFlag ? '1' : '0') + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegArcAbs.prototype.clone = function() { + return new window.SVGPathSegArcAbs( + undefined, + this._x, + this._y, + this._r1, + this._r2, + this._angle, + this._largeArcFlag, + this._sweepFlag + ) + }; + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', { + get: function() { + return this._r1 + }, + set: function(r1) { + this._r1 = r1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', { + get: function() { + return this._r2 + }, + set: function(r2) { + this._r2 = r2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', { + get: function() { + return this._angle + }, + set: function(angle) { + this._angle = angle; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', { + get: function() { + return this._largeArcFlag + }, + set: function(largeArcFlag) { + this._largeArcFlag = largeArcFlag; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', { + get: function() { + return this._sweepFlag + }, + set: function(sweepFlag) { + this._sweepFlag = sweepFlag; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList); - this._x = x; - }; - window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalRel]"; - }; - window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; - }; - window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { - return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); - }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegArcRel = function( + owningPathSegList, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_ARC_REL, + 'a', + owningPathSegList + ); + this._x = x; + this._y = y; + this._r1 = r1; + this._r2 = r2; + this._angle = angle; + this._largeArcFlag = largeArcFlag; + this._sweepFlag = sweepFlag; + }; + window.SVGPathSegArcRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegArcRel.prototype.toString = function() { + return '[object SVGPathSegArcRel]' + }; + window.SVGPathSegArcRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._r1 + + ' ' + + this._r2 + + ' ' + + this._angle + + ' ' + + (this._largeArcFlag ? '1' : '0') + + ' ' + + (this._sweepFlag ? '1' : '0') + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegArcRel.prototype.clone = function() { + return new window.SVGPathSegArcRel( + undefined, + this._x, + this._y, + this._r1, + this._r2, + this._angle, + this._largeArcFlag, + this._sweepFlag + ) + }; + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', { + get: function() { + return this._r1 + }, + set: function(r1) { + this._r1 = r1; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', { + get: function() { + return this._r2 + }, + set: function(r2) { + this._r2 = r2; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', { + get: function() { + return this._angle + }, + set: function(angle) { + this._angle = angle; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', { + get: function() { + return this._largeArcFlag + }, + set: function(largeArcFlag) { + this._largeArcFlag = largeArcFlag; + this._segmentChanged(); + }, + enumerable: true + }); + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', { + get: function() { + return this._sweepFlag + }, + set: function(sweepFlag) { + this._sweepFlag = sweepFlag; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList); - this._y = y; - }; - window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalAbs]"; - }; - window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; - }; - window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, + 'H', + owningPathSegList + ); + this._x = x; + }; + window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() { + return '[object SVGPathSegLinetoHorizontalAbs]' + }; + window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + }; + window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() { + return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x) + }; + Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList); - this._y = y; - }; - window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalRel]"; - }; - window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; - }; - window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { - return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); - }; - Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, + 'h', + owningPathSegList + ); + this._x = x; + }; + window.SVGPathSegLinetoHorizontalRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() { + return '[object SVGPathSegLinetoHorizontalRel]' + }; + window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + }; + window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() { + return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x) + }; + Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList); - this._x = x; - this._y = y; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothAbs]"; - }; - window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, + 'V', + owningPathSegList + ); + this._y = y; + }; + window.SVGPathSegLinetoVerticalAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() { + return '[object SVGPathSegLinetoVerticalAbs]' + }; + window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._y + }; + window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() { + return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList); - this._x = x; - this._y = y; - this._x2 = x2; - this._y2 = y2; - }; - window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothRel]"; - }; - window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); - }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, + 'v', + owningPathSegList + ); + this._y = y; + }; + window.SVGPathSegLinetoVerticalRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegLinetoVerticalRel.prototype.toString = function() { + return '[object SVGPathSegLinetoVerticalRel]' + }; + window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._y + }; + window.SVGPathSegLinetoVerticalRel.prototype.clone = function() { + return new window.SVGPathSegLinetoVerticalRel(undefined, this._y) + }; + Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + }); - window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; - }; - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + window.SVGPathSegCurvetoCubicSmoothAbs = function( + owningPathSegList, + x, + y, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, + 'S', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicSmoothAbs]' + }; + window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicSmoothAbs( + undefined, + this._x, + this._y, + this._x2, + this._y2 + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'x2', + { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothAbs.prototype, + 'y2', + { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoCubicSmoothRel = function( + owningPathSegList, + x, + y, + x2, + y2 + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, + 's', + owningPathSegList + ); + this._x = x; + this._y = y; + this._x2 = x2; + this._y2 = y2; + }; + window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoCubicSmoothRel]' + }; + window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() { + return ( + this.pathSegTypeAsLetter + + ' ' + + this._x2 + + ' ' + + this._y2 + + ' ' + + this._x + + ' ' + + this._y + ) + }; + window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoCubicSmoothRel( + undefined, + this._x, + this._y, + this._x2, + this._y2 + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'x2', + { + get: function() { + return this._x2 + }, + set: function(x2) { + this._x2 = x2; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoCubicSmoothRel.prototype, + 'y2', + { + get: function() { + return this._y2 + }, + set: function(y2) { + this._y2 = y2; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoQuadraticSmoothAbs = function( + owningPathSegList, + x, + y + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, + 'T', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticSmoothAbs]' + }; + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticSmoothAbs( + undefined, + this._x, + this._y + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + + window.SVGPathSegCurvetoQuadraticSmoothRel = function( + owningPathSegList, + x, + y + ) { + window.SVGPathSeg.call( + this, + window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, + 't', + owningPathSegList + ); + this._x = x; + this._y = y; + }; + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create( + window.SVGPathSeg.prototype + ); + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() { + return '[object SVGPathSegCurvetoQuadraticSmoothRel]' + }; + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() { + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y + }; + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() { + return new window.SVGPathSegCurvetoQuadraticSmoothRel( + undefined, + this._x, + this._y + ) + }; + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, + 'x', + { + get: function() { + return this._x + }, + set: function(x) { + this._x = x; + this._segmentChanged(); + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, + 'y', + { + get: function() { + return this._y + }, + set: function(y) { + this._y = y; + this._segmentChanged(); + }, + enumerable: true + } + ); + + // Add createSVGPathSeg* functions to window.SVGPathElement. + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement. + window.SVGPathElement.prototype.createSVGPathSegClosePath = function() { + return new window.SVGPathSegClosePath(undefined) + }; + window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) { + return new window.SVGPathSegMovetoAbs(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) { + return new window.SVGPathSegMovetoRel(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) { + return new window.SVGPathSegLinetoAbs(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) { + return new window.SVGPathSegLinetoRel(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function( + x, + y, + x1, + y1, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicAbs( + undefined, + x, + y, + x1, + y1, + x2, + y2 + ) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function( + x, + y, + x1, + y1, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicRel( + undefined, + x, + y, + x1, + y1, + x2, + y2 + ) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function( + x, + y, + x1, + y1 + ) { + return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function( + x, + y, + x1, + y1 + ) { + return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1) + }; + window.SVGPathElement.prototype.createSVGPathSegArcAbs = function( + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + return new window.SVGPathSegArcAbs( + undefined, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) + }; + window.SVGPathElement.prototype.createSVGPathSegArcRel = function( + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) { + return new window.SVGPathSegArcRel( + undefined, + x, + y, + r1, + r2, + angle, + largeArcFlag, + sweepFlag + ) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function( + x + ) { + return new window.SVGPathSegLinetoHorizontalAbs(undefined, x) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function( + x + ) { + return new window.SVGPathSegLinetoHorizontalRel(undefined, x) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function( + y + ) { + return new window.SVGPathSegLinetoVerticalAbs(undefined, y) + }; + window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function( + y + ) { + return new window.SVGPathSegLinetoVerticalRel(undefined, y) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function( + x, + y, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function( + x, + y, + x2, + y2 + ) { + return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function( + x, + y + ) { + return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y) + }; + window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function( + x, + y + ) { + return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y) + }; - window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList); - this._x = x; - this._y = y; - }; - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; - }; - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); - }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - this._segmentChanged(); - }, - enumerable: true - }); + if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) { + // Add getPathSegAtLength to SVGPathElement. + // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength + // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. + window.SVGPathElement.prototype.getPathSegAtLength = function(distance) { + if (distance === undefined || !isFinite(distance)) + throw 'Invalid arguments.' + + var measurementElement = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'path' + ); + measurementElement.setAttribute('d', this.getAttribute('d')); + var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; - // Add createSVGPathSeg* functions to window.SVGPathElement. - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement. - window.SVGPathElement.prototype.createSVGPathSegClosePath = function () { - return new window.SVGPathSegClosePath(undefined); - }; - window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) { - return new window.SVGPathSegMovetoAbs(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) { - return new window.SVGPathSegMovetoRel(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) { - return new window.SVGPathSegLinetoAbs(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) { - return new window.SVGPathSegLinetoRel(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) { - return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) { - return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) { - return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) { - return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); - }; - window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); - }; - window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) { - return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) { - return new window.SVGPathSegLinetoHorizontalRel(undefined, x); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) { - return new window.SVGPathSegLinetoVerticalAbs(undefined, y); - }; - window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) { - return new window.SVGPathSegLinetoVerticalRel(undefined, y); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) { - return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) { - return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) { - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); - }; - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) { - return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); - }; + // If the path is empty, return 0. + if (lastPathSegment <= 0) return 0 - if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) { - // Add getPathSegAtLength to SVGPathElement. - // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength - // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. - window.SVGPathElement.prototype.getPathSegAtLength = function (distance) { - if (distance === undefined || !isFinite(distance)) - throw "Invalid arguments."; - - var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); - measurementElement.setAttribute("d", this.getAttribute("d")); - var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; - - // If the path is empty, return 0. - if (lastPathSegment <= 0) - return 0; - - do { - measurementElement.pathSegList.removeItem(lastPathSegment); - if (distance > measurementElement.getTotalLength()) - break; - lastPathSegment--; - } while (lastPathSegment > 0); - return lastPathSegment; - }; - } + do { + measurementElement.pathSegList.removeItem(lastPathSegment); + if (distance > measurementElement.getTotalLength()) break + lastPathSegment--; + } while (lastPathSegment > 0) + return lastPathSegment + }; } + } - if (!("SVGPathSegList" in window)) { - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList - window.SVGPathSegList = function (pathElement) { - this._pathElement = pathElement; - this._list = this._parsePath(this._pathElement.getAttribute("d")); - - // Use a MutationObserver to catch changes to the path's "d" attribute. - this._mutationObserverConfig = { - "attributes": true, - "attributeFilter": ["d"] - }; - this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this)); - this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); - }; - - window.SVGPathSegList.prototype.classname = "SVGPathSegList"; - - Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", { - get: function () { - this._checkPathSynchronizedToList(); - return this._list.length; - }, - enumerable: true - }); - - // Add the pathSegList accessors to window.SVGPathElement. - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData - Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", { - get: function () { - if (!this._pathSegList) - this._pathSegList = new window.SVGPathSegList(this); - return this._pathSegList; - }, - enumerable: true - }); - // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. - Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - - // Process any pending mutations to the path element and update the list as needed. - // This should be the first call of all public functions and is needed because - // MutationObservers are not synchronous so we can have pending asynchronous mutations. - window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () { - this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords()); - }; - - window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) { - if (!this._pathElement) - return; - var hasPathMutations = false; - mutationRecords.forEach(function (record) { - if (record.attributeName == "d") - hasPathMutations = true; - }); - if (hasPathMutations) - this._list = this._parsePath(this._pathElement.getAttribute("d")); - }; - - // Serialize the list and update the path's 'd' attribute. - window.SVGPathSegList.prototype._writeListToPath = function () { - this._pathElementMutationObserver.disconnect(); - this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list)); - this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); - }; - - // When a path segment changes the list needs to be synchronized back to the path element. - window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) { - this._writeListToPath(); - }; - - window.SVGPathSegList.prototype.clear = function () { - this._checkPathSynchronizedToList(); - - this._list.forEach(function (pathSeg) { - pathSeg._owningPathSegList = null; - }); - this._list = []; - this._writeListToPath(); - }; - - window.SVGPathSegList.prototype.initialize = function (newItem) { - this._checkPathSynchronizedToList(); - - this._list = [newItem]; - newItem._owningPathSegList = this; - this._writeListToPath(); - return newItem; - }; - - window.SVGPathSegList.prototype._checkValidIndex = function (index) { - if (isNaN(index) || index < 0 || index >= this.numberOfItems) - throw "INDEX_SIZE_ERR"; - }; + if (!('SVGPathSegList' in window)) { + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList + window.SVGPathSegList = function(pathElement) { + this._pathElement = pathElement; + this._list = this._parsePath(this._pathElement.getAttribute('d')); - window.SVGPathSegList.prototype.getItem = function (index) { - this._checkPathSynchronizedToList(); + // Use a MutationObserver to catch changes to the path's "d" attribute. + this._mutationObserverConfig = { + attributes: true, + attributeFilter: ['d'] + }; + this._pathElementMutationObserver = new MutationObserver( + this._updateListFromPathMutations.bind(this) + ); + this._pathElementMutationObserver.observe( + this._pathElement, + this._mutationObserverConfig + ); + }; - this._checkValidIndex(index); - return this._list[index]; - }; + window.SVGPathSegList.prototype.classname = 'SVGPathSegList'; - window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) { - this._checkPathSynchronizedToList(); + Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', { + get: function() { + this._checkPathSynchronizedToList(); + return this._list.length + }, + enumerable: true + }); - // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. - if (index > this.numberOfItems) - index = this.numberOfItems; - if (newItem._owningPathSegList) { - // SVG2 spec says to make a copy. - newItem = newItem.clone(); - } - this._list.splice(index, 0, newItem); - newItem._owningPathSegList = this; - this._writeListToPath(); - return newItem; - }; + // Add the pathSegList accessors to window.SVGPathElement. + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData + Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', { + get: function() { + if (!this._pathSegList) + this._pathSegList = new window.SVGPathSegList(this); + return this._pathSegList + }, + enumerable: true + }); + // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. + Object.defineProperty( + window.SVGPathElement.prototype, + 'normalizedPathSegList', + { + get: function() { + return this.pathSegList + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathElement.prototype, + 'animatedPathSegList', + { + get: function() { + return this.pathSegList + }, + enumerable: true + } + ); + Object.defineProperty( + window.SVGPathElement.prototype, + 'animatedNormalizedPathSegList', + { + get: function() { + return this.pathSegList + }, + enumerable: true + } + ); + + // Process any pending mutations to the path element and update the list as needed. + // This should be the first call of all public functions and is needed because + // MutationObservers are not synchronous so we can have pending asynchronous mutations. + window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() { + this._updateListFromPathMutations( + this._pathElementMutationObserver.takeRecords() + ); + }; - window.SVGPathSegList.prototype.replaceItem = function (newItem, index) { - this._checkPathSynchronizedToList(); + window.SVGPathSegList.prototype._updateListFromPathMutations = function( + mutationRecords + ) { + if (!this._pathElement) return + var hasPathMutations = false; + mutationRecords.forEach(function(record) { + if (record.attributeName == 'd') hasPathMutations = true; + }); + if (hasPathMutations) + this._list = this._parsePath(this._pathElement.getAttribute('d')); + }; - if (newItem._owningPathSegList) { - // SVG2 spec says to make a copy. - newItem = newItem.clone(); - } - this._checkValidIndex(index); - this._list[index] = newItem; - newItem._owningPathSegList = this; - this._writeListToPath(); - return newItem; - }; + // Serialize the list and update the path's 'd' attribute. + window.SVGPathSegList.prototype._writeListToPath = function() { + this._pathElementMutationObserver.disconnect(); + this._pathElement.setAttribute( + 'd', + window.SVGPathSegList._pathSegArrayAsString(this._list) + ); + this._pathElementMutationObserver.observe( + this._pathElement, + this._mutationObserverConfig + ); + }; - window.SVGPathSegList.prototype.removeItem = function (index) { - this._checkPathSynchronizedToList(); + // When a path segment changes the list needs to be synchronized back to the path element. + window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) { + this._writeListToPath(); + }; - this._checkValidIndex(index); - var item = this._list[index]; - this._list.splice(index, 1); - this._writeListToPath(); - return item; - }; + window.SVGPathSegList.prototype.clear = function() { + this._checkPathSynchronizedToList(); - window.SVGPathSegList.prototype.appendItem = function (newItem) { - this._checkPathSynchronizedToList(); + this._list.forEach(function(pathSeg) { + pathSeg._owningPathSegList = null; + }); + this._list = []; + this._writeListToPath(); + }; - if (newItem._owningPathSegList) { - // SVG2 spec says to make a copy. - newItem = newItem.clone(); - } - this._list.push(newItem); - newItem._owningPathSegList = this; - // TODO: Optimize this to just append to the existing attribute. - this._writeListToPath(); - return newItem; - }; + window.SVGPathSegList.prototype.initialize = function(newItem) { + this._checkPathSynchronizedToList(); - window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) { - var string = ""; - var first = true; - pathSegArray.forEach(function (pathSeg) { - if (first) { - first = false; - string += pathSeg._asPathString(); - } else { - string += " " + pathSeg._asPathString(); - } - }); - return string; - }; + this._list = [newItem]; + newItem._owningPathSegList = this; + this._writeListToPath(); + return newItem + }; - // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp. - window.SVGPathSegList.prototype._parsePath = function (string) { - if (!string || string.length == 0) - return []; + window.SVGPathSegList.prototype._checkValidIndex = function(index) { + if (isNaN(index) || index < 0 || index >= this.numberOfItems) + throw 'INDEX_SIZE_ERR' + }; - var owningPathSegList = this; + window.SVGPathSegList.prototype.getItem = function(index) { + this._checkPathSynchronizedToList(); - var Builder = function () { - this.pathSegList = []; - }; + this._checkValidIndex(index); + return this._list[index] + }; - Builder.prototype.appendSegment = function (pathSeg) { - this.pathSegList.push(pathSeg); - }; + window.SVGPathSegList.prototype.insertItemBefore = function( + newItem, + index + ) { + this._checkPathSynchronizedToList(); + + // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. + if (index > this.numberOfItems) index = this.numberOfItems; + if (newItem._owningPathSegList) { + // SVG2 spec says to make a copy. + newItem = newItem.clone(); + } + this._list.splice(index, 0, newItem); + newItem._owningPathSegList = this; + this._writeListToPath(); + return newItem + }; - var Source = function (string) { - this._string = string; - this._currentIndex = 0; - this._endIndex = this._string.length; - this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN; + window.SVGPathSegList.prototype.replaceItem = function(newItem, index) { + this._checkPathSynchronizedToList(); + + if (newItem._owningPathSegList) { + // SVG2 spec says to make a copy. + newItem = newItem.clone(); + } + this._checkValidIndex(index); + this._list[index] = newItem; + newItem._owningPathSegList = this; + this._writeListToPath(); + return newItem + }; - this._skipOptionalSpaces(); - }; + window.SVGPathSegList.prototype.removeItem = function(index) { + this._checkPathSynchronizedToList(); - Source.prototype._isCurrentSpace = function () { - var character = this._string[this._currentIndex]; - return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f"); - }; + this._checkValidIndex(index); + var item = this._list[index]; + this._list.splice(index, 1); + this._writeListToPath(); + return item + }; - Source.prototype._skipOptionalSpaces = function () { - while (this._currentIndex < this._endIndex && this._isCurrentSpace()) - this._currentIndex++; - return this._currentIndex < this._endIndex; - }; + window.SVGPathSegList.prototype.appendItem = function(newItem) { + this._checkPathSynchronizedToList(); + + if (newItem._owningPathSegList) { + // SVG2 spec says to make a copy. + newItem = newItem.clone(); + } + this._list.push(newItem); + newItem._owningPathSegList = this; + // TODO: Optimize this to just append to the existing attribute. + this._writeListToPath(); + return newItem + }; - Source.prototype._skipOptionalSpacesOrDelimiter = function () { - if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") - return false; - if (this._skipOptionalSpaces()) { - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") { - this._currentIndex++; - this._skipOptionalSpaces(); - } - } - return this._currentIndex < this._endIndex; - }; + window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) { + var string = ''; + var first = true; + pathSegArray.forEach(function(pathSeg) { + if (first) { + first = false; + string += pathSeg._asPathString(); + } else { + string += ' ' + pathSeg._asPathString(); + } + }); + return string + }; - Source.prototype.hasMoreData = function () { - return this._currentIndex < this._endIndex; + // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp. + window.SVGPathSegList.prototype._parsePath = function(string) { + if (!string || string.length == 0) return [] + + var owningPathSegList = this; + + var Builder = function() { + this.pathSegList = []; + }; + + Builder.prototype.appendSegment = function(pathSeg) { + this.pathSegList.push(pathSeg); + }; + + var Source = function(string) { + this._string = string; + this._currentIndex = 0; + this._endIndex = this._string.length; + this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN; + + this._skipOptionalSpaces(); + }; + + Source.prototype._isCurrentSpace = function() { + var character = this._string[this._currentIndex]; + return ( + character <= ' ' && + (character == ' ' || + character == '\n' || + character == '\t' || + character == '\r' || + character == '\f') + ) + }; + + Source.prototype._skipOptionalSpaces = function() { + while (this._currentIndex < this._endIndex && this._isCurrentSpace()) + this._currentIndex++; + return this._currentIndex < this._endIndex + }; + + Source.prototype._skipOptionalSpacesOrDelimiter = function() { + if ( + this._currentIndex < this._endIndex && + !this._isCurrentSpace() && + this._string.charAt(this._currentIndex) != ',' + ) + return false + if (this._skipOptionalSpaces()) { + if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == ',' + ) { + this._currentIndex++; + this._skipOptionalSpaces(); + } + } + return this._currentIndex < this._endIndex + }; + + Source.prototype.hasMoreData = function() { + return this._currentIndex < this._endIndex + }; + + Source.prototype.peekSegmentType = function() { + var lookahead = this._string[this._currentIndex]; + return this._pathSegTypeFromChar(lookahead) + }; + + Source.prototype._pathSegTypeFromChar = function(lookahead) { + switch (lookahead) { + case 'Z': + case 'z': + return window.SVGPathSeg.PATHSEG_CLOSEPATH + case 'M': + return window.SVGPathSeg.PATHSEG_MOVETO_ABS + case 'm': + return window.SVGPathSeg.PATHSEG_MOVETO_REL + case 'L': + return window.SVGPathSeg.PATHSEG_LINETO_ABS + case 'l': + return window.SVGPathSeg.PATHSEG_LINETO_REL + case 'C': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS + case 'c': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL + case 'Q': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS + case 'q': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL + case 'A': + return window.SVGPathSeg.PATHSEG_ARC_ABS + case 'a': + return window.SVGPathSeg.PATHSEG_ARC_REL + case 'H': + return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS + case 'h': + return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL + case 'V': + return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS + case 'v': + return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL + case 'S': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS + case 's': + return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL + case 'T': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS + case 't': + return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL + default: + return window.SVGPathSeg.PATHSEG_UNKNOWN + } + }; + + Source.prototype._nextCommandHelper = function( + lookahead, + previousCommand + ) { + // Check for remaining coordinates in the current command. + if ( + (lookahead == '+' || + lookahead == '-' || + lookahead == '.' || + (lookahead >= '0' && lookahead <= '9')) && + previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH + ) { + if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) + return window.SVGPathSeg.PATHSEG_LINETO_ABS + if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) + return window.SVGPathSeg.PATHSEG_LINETO_REL + return previousCommand + } + return window.SVGPathSeg.PATHSEG_UNKNOWN + }; + + Source.prototype.initialCommandIsMoveTo = function() { + // If the path is empty it is still valid, so return true. + if (!this.hasMoreData()) return true + var command = this.peekSegmentType(); + // Path must start with moveTo. + return ( + command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || + command == window.SVGPathSeg.PATHSEG_MOVETO_REL + ) + }; + + // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp. + // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF + Source.prototype._parseNumber = function() { + var exponent = 0; + var integer = 0; + var frac = 1; + var decimal = 0; + var sign = 1; + var expsign = 1; + + var startIndex = this._currentIndex; + + this._skipOptionalSpaces(); + + // Read the sign. + if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == '+' + ) + this._currentIndex++; + else if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == '-' + ) { + this._currentIndex++; + sign = -1; + } + + if ( + this._currentIndex == this._endIndex || + ((this._string.charAt(this._currentIndex) < '0' || + this._string.charAt(this._currentIndex) > '9') && + this._string.charAt(this._currentIndex) != '.') + ) + // The first character of a number must be one of [0-9+-.]. + return undefined + + // Read the integer part, build right-to-left. + var startIntPartIndex = this._currentIndex; + while ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) >= '0' && + this._string.charAt(this._currentIndex) <= '9' + ) + this._currentIndex++; // Advance to first non-digit. + + if (this._currentIndex != startIntPartIndex) { + var scanIntPartIndex = this._currentIndex - 1; + var multiplier = 1; + while (scanIntPartIndex >= startIntPartIndex) { + integer += + multiplier * (this._string.charAt(scanIntPartIndex--) - '0'); + multiplier *= 10; + } + } + + // Read the decimals. + if ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) == '.' + ) { + this._currentIndex++; + + // There must be a least one digit following the . + if ( + this._currentIndex >= this._endIndex || + this._string.charAt(this._currentIndex) < '0' || + this._string.charAt(this._currentIndex) > '9' + ) + return undefined + while ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) >= '0' && + this._string.charAt(this._currentIndex) <= '9' + ) { + frac *= 10; + decimal += (this._string.charAt(this._currentIndex) - '0') / frac; + this._currentIndex += 1; + } + } + + // Read the exponent part. + if ( + this._currentIndex != startIndex && + this._currentIndex + 1 < this._endIndex && + (this._string.charAt(this._currentIndex) == 'e' || + this._string.charAt(this._currentIndex) == 'E') && + this._string.charAt(this._currentIndex + 1) != 'x' && + this._string.charAt(this._currentIndex + 1) != 'm' + ) { + this._currentIndex++; + + // Read the sign of the exponent. + if (this._string.charAt(this._currentIndex) == '+') { + this._currentIndex++; + } else if (this._string.charAt(this._currentIndex) == '-') { + this._currentIndex++; + expsign = -1; + } + + // There must be an exponent. + if ( + this._currentIndex >= this._endIndex || + this._string.charAt(this._currentIndex) < '0' || + this._string.charAt(this._currentIndex) > '9' + ) + return undefined + + while ( + this._currentIndex < this._endIndex && + this._string.charAt(this._currentIndex) >= '0' && + this._string.charAt(this._currentIndex) <= '9' + ) { + exponent *= 10; + exponent += this._string.charAt(this._currentIndex) - '0'; + this._currentIndex++; + } + } + + var number = integer + decimal; + number *= sign; + + if (exponent) number *= Math.pow(10, expsign * exponent); + + if (startIndex == this._currentIndex) return undefined + + this._skipOptionalSpacesOrDelimiter(); + + return number + }; + + Source.prototype._parseArcFlag = function() { + if (this._currentIndex >= this._endIndex) return undefined + var flag = false; + var flagChar = this._string.charAt(this._currentIndex++); + if (flagChar == '0') flag = false; + else if (flagChar == '1') flag = true; + else return undefined + + this._skipOptionalSpacesOrDelimiter(); + return flag + }; + + Source.prototype.parseSegment = function() { + var lookahead = this._string[this._currentIndex]; + var command = this._pathSegTypeFromChar(lookahead); + if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) { + // Possibly an implicit command. Not allowed if this is the first command. + if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) + return null + command = this._nextCommandHelper(lookahead, this._previousCommand); + if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null + } else { + this._currentIndex++; + } + + this._previousCommand = command; + + switch (command) { + case window.SVGPathSeg.PATHSEG_MOVETO_REL: + return new window.SVGPathSegMovetoRel( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_MOVETO_ABS: + return new window.SVGPathSegMovetoAbs( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_REL: + return new window.SVGPathSegLinetoRel( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_ABS: + return new window.SVGPathSegLinetoAbs( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: + return new window.SVGPathSegLinetoHorizontalRel( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: + return new window.SVGPathSegLinetoHorizontalAbs( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: + return new window.SVGPathSegLinetoVerticalRel( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: + return new window.SVGPathSegLinetoVerticalAbs( + owningPathSegList, + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_CLOSEPATH: + this._skipOptionalSpaces(); + return new window.SVGPathSegClosePath(owningPathSegList) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype.peekSegmentType = function () { - var lookahead = this._string[this._currentIndex]; - return this._pathSegTypeFromChar(lookahead); + return new window.SVGPathSegCurvetoCubicRel( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype._pathSegTypeFromChar = function (lookahead) { - switch (lookahead) { - case "Z": - case "z": - return window.SVGPathSeg.PATHSEG_CLOSEPATH; - case "M": - return window.SVGPathSeg.PATHSEG_MOVETO_ABS; - case "m": - return window.SVGPathSeg.PATHSEG_MOVETO_REL; - case "L": - return window.SVGPathSeg.PATHSEG_LINETO_ABS; - case "l": - return window.SVGPathSeg.PATHSEG_LINETO_REL; - case "C": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS; - case "c": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL; - case "Q": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS; - case "q": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL; - case "A": - return window.SVGPathSeg.PATHSEG_ARC_ABS; - case "a": - return window.SVGPathSeg.PATHSEG_ARC_REL; - case "H": - return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS; - case "h": - return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL; - case "V": - return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS; - case "v": - return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL; - case "S": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; - case "s": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL; - case "T": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; - case "t": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; - default: - return window.SVGPathSeg.PATHSEG_UNKNOWN; - } + return new window.SVGPathSegCurvetoCubicAbs( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: + var points = { + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype._nextCommandHelper = function (lookahead, previousCommand) { - // Check for remaining coordinates in the current command. - if ((lookahead == "+" || lookahead == "-" || lookahead == "." || (lookahead >= "0" && lookahead <= "9")) && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { - if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) - return window.SVGPathSeg.PATHSEG_LINETO_ABS; - if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) - return window.SVGPathSeg.PATHSEG_LINETO_REL; - return previousCommand; - } - return window.SVGPathSeg.PATHSEG_UNKNOWN; + return new window.SVGPathSegCurvetoCubicSmoothRel( + owningPathSegList, + points.x, + points.y, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + var points = { + x2: this._parseNumber(), + y2: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype.initialCommandIsMoveTo = function () { - // If the path is empty it is still valid, so return true. - if (!this.hasMoreData()) - return true; - var command = this.peekSegmentType(); - // Path must start with moveTo. - return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL; + return new window.SVGPathSegCurvetoCubicSmoothAbs( + owningPathSegList, + points.x, + points.y, + points.x2, + points.y2 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp. - // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF - Source.prototype._parseNumber = function () { - var exponent = 0; - var integer = 0; - var frac = 1; - var decimal = 0; - var sign = 1; - var expsign = 1; - - var startIndex = this._currentIndex; - - this._skipOptionalSpaces(); - - // Read the sign. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") - this._currentIndex++; - else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") { - this._currentIndex++; - sign = -1; - } - - if (this._currentIndex == this._endIndex || ((this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != - ".")) - // The first character of a number must be one of [0-9+-.]. - return undefined; - - // Read the integer part, build right-to-left. - var startIntPartIndex = this._currentIndex; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") - this._currentIndex++; // Advance to first non-digit. - - if (this._currentIndex != startIntPartIndex) { - var scanIntPartIndex = this._currentIndex - 1; - var multiplier = 1; - while (scanIntPartIndex >= startIntPartIndex) { - integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0"); - multiplier *= 10; - } - } - - // Read the decimals. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") { - this._currentIndex++; - - // There must be a least one digit following the . - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") - return undefined; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { - frac *= 10; - decimal += (this._string.charAt(this._currentIndex) - "0") / frac; - this._currentIndex += 1; - } - } - - // Read the exponent part. - if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == - "E") && (this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m")) { - this._currentIndex++; - - // Read the sign of the exponent. - if (this._string.charAt(this._currentIndex) == "+") { - this._currentIndex++; - } else if (this._string.charAt(this._currentIndex) == "-") { - this._currentIndex++; - expsign = -1; - } - - // There must be an exponent. - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") - return undefined; - - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { - exponent *= 10; - exponent += (this._string.charAt(this._currentIndex) - "0"); - this._currentIndex++; - } - } - - var number = integer + decimal; - number *= sign; - - if (exponent) - number *= Math.pow(10, expsign * exponent); - - if (startIndex == this._currentIndex) - return undefined; - - this._skipOptionalSpacesOrDelimiter(); - - return number; + return new window.SVGPathSegCurvetoQuadraticRel( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype._parseArcFlag = function () { - if (this._currentIndex >= this._endIndex) - return undefined; - var flag = false; - var flagChar = this._string.charAt(this._currentIndex++); - if (flagChar == "0") - flag = false; - else if (flagChar == "1") - flag = true; - else - return undefined; - - this._skipOptionalSpacesOrDelimiter(); - return flag; + return new window.SVGPathSegCurvetoQuadraticAbs( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1 + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: + return new window.SVGPathSegCurvetoQuadraticSmoothRel( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + return new window.SVGPathSegCurvetoQuadraticSmoothAbs( + owningPathSegList, + this._parseNumber(), + this._parseNumber() + ) + case window.SVGPathSeg.PATHSEG_ARC_REL: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + arcAngle: this._parseNumber(), + arcLarge: this._parseArcFlag(), + arcSweep: this._parseArcFlag(), + x: this._parseNumber(), + y: this._parseNumber() }; - - Source.prototype.parseSegment = function () { - var lookahead = this._string[this._currentIndex]; - var command = this._pathSegTypeFromChar(lookahead); - if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) { - // Possibly an implicit command. Not allowed if this is the first command. - if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) - return null; - command = this._nextCommandHelper(lookahead, this._previousCommand); - if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) - return null; - } else { - this._currentIndex++; - } - - this._previousCommand = command; - - switch (command) { - case window.SVGPathSeg.PATHSEG_MOVETO_REL: - return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_MOVETO_ABS: - return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_REL: - return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_ABS: - return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: - return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: - return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: - return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: - return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber()); - case window.SVGPathSeg.PATHSEG_CLOSEPATH: - this._skipOptionalSpaces(); - return new window.SVGPathSegClosePath(owningPathSegList); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: - var points = { - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: - var points = { - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: - return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - case window.SVGPathSeg.PATHSEG_ARC_REL: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - arcAngle: this._parseNumber(), - arcLarge: this._parseArcFlag(), - arcSweep: this._parseArcFlag(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); - case window.SVGPathSeg.PATHSEG_ARC_ABS: - var points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - arcAngle: this._parseNumber(), - arcLarge: this._parseArcFlag(), - arcSweep: this._parseArcFlag(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); - default: - throw "Unknown path seg type." - } + return new window.SVGPathSegArcRel( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.arcAngle, + points.arcLarge, + points.arcSweep + ) + case window.SVGPathSeg.PATHSEG_ARC_ABS: + var points = { + x1: this._parseNumber(), + y1: this._parseNumber(), + arcAngle: this._parseNumber(), + arcLarge: this._parseArcFlag(), + arcSweep: this._parseArcFlag(), + x: this._parseNumber(), + y: this._parseNumber() }; - - var builder = new Builder(); - var source = new Source(string); - - if (!source.initialCommandIsMoveTo()) - return []; - while (source.hasMoreData()) { - var pathSeg = source.parseSegment(); - if (!pathSeg) - return []; - builder.appendSegment(pathSeg); - } - - return builder.pathSegList; - }; - } -}()); + return new window.SVGPathSegArcAbs( + owningPathSegList, + points.x, + points.y, + points.x1, + points.y1, + points.arcAngle, + points.arcLarge, + points.arcSweep + ) + default: + throw 'Unknown path seg type.' + } + }; + + var builder = new Builder(); + var source = new Source(string); + + if (!source.initialCommandIsMoveTo()) return [] + while (source.hasMoreData()) { + var pathSeg = source.parseSegment(); + if (!pathSeg) return [] + builder.appendSegment(pathSeg); + } + + return builder.pathSegList + }; + } +})(); // String.padEnd polyfill for IE11 // // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd if (!String.prototype.padEnd) { - String.prototype.padEnd = function padEnd(targetLength, padString) { - targetLength = targetLength >> 0; //floor if number or convert non-number to 0; - padString = String((typeof padString !== 'undefined' ? padString : ' ')); - if (this.length > targetLength) { - return String(this); - } else { - targetLength = targetLength - this.length; - if (targetLength > padString.length) { - padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed - } - return String(this) + padString.slice(0, targetLength); - } - }; + String.prototype.padEnd = function padEnd(targetLength, padString) { + targetLength = targetLength >> 0; //floor if number or convert non-number to 0; + padString = String(typeof padString !== 'undefined' ? padString : ' '); + if (this.length > targetLength) { + return String(this) + } else { + targetLength = targetLength - this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed + } + return String(this) + padString.slice(0, targetLength) + } + }; } // Object.assign polyfill for IE11 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill if (typeof Object.assign !== 'function') { - // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { - value: function assign(target, varArgs) { // .length of function is 2 - if (target === null || target === undefined) { - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - - if (nextSource !== null && nextSource !== undefined) { - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } + // Must be writable: true, enumerable: false, configurable: true + Object.defineProperty(Object, 'assign', { + value: function assign(target, varArgs) { + if (target === null || target === undefined) { + throw new TypeError('Cannot convert undefined or null to object') + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource !== null && nextSource !== undefined) { + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; } - return to; - }, - writable: true, - configurable: true - }); + } + } + } + return to + }, + writable: true, + configurable: true + }); } /* jshint ignore:end */ -Chart.prototype.axis = function () {}; -Chart.prototype.axis.labels = function (labels) { - var $$ = this.internal; - if (arguments.length) { - Object.keys(labels).forEach(function (axisId) { - $$.axis.setLabelText(axisId, labels[axisId]); - }); - $$.axis.updateLabels(); - } - // TODO: return some values? -}; -Chart.prototype.axis.max = function (max) { - var $$ = this.internal, config = $$.config; - if (arguments.length) { - if (typeof max === 'object') { - if (isValue(max.x)) { config.axis_x_max = max.x; } - if (isValue(max.y)) { config.axis_y_max = max.y; } - if (isValue(max.y2)) { config.axis_y2_max = max.y2; } - } else { - config.axis_y_max = config.axis_y2_max = max; - } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); +Chart.prototype.axis = function() {}; +Chart.prototype.axis.labels = function(labels) { + var $$ = this.internal; + if (arguments.length) { + Object.keys(labels).forEach(function(axisId) { + $$.axis.setLabelText(axisId, labels[axisId]); + }); + $$.axis.updateLabels(); + } + // TODO: return some values? +}; +Chart.prototype.axis.max = function(max) { + var $$ = this.internal, + config = $$.config; + if (arguments.length) { + if (typeof max === 'object') { + if (isValue(max.x)) { + config.axis_x_max = max.x; + } + if (isValue(max.y)) { + config.axis_y_max = max.y; + } + if (isValue(max.y2)) { + config.axis_y2_max = max.y2; + } } else { - return { - x: config.axis_x_max, - y: config.axis_y_max, - y2: config.axis_y2_max - }; + config.axis_y_max = config.axis_y2_max = max; } + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } else { + return { + x: config.axis_x_max, + y: config.axis_y_max, + y2: config.axis_y2_max + } + } }; -Chart.prototype.axis.min = function (min) { - var $$ = this.internal, config = $$.config; - if (arguments.length) { - if (typeof min === 'object') { - if (isValue(min.x)) { config.axis_x_min = min.x; } - if (isValue(min.y)) { config.axis_y_min = min.y; } - if (isValue(min.y2)) { config.axis_y2_min = min.y2; } - } else { - config.axis_y_min = config.axis_y2_min = min; - } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); +Chart.prototype.axis.min = function(min) { + var $$ = this.internal, + config = $$.config; + if (arguments.length) { + if (typeof min === 'object') { + if (isValue(min.x)) { + config.axis_x_min = min.x; + } + if (isValue(min.y)) { + config.axis_y_min = min.y; + } + if (isValue(min.y2)) { + config.axis_y2_min = min.y2; + } } else { - return { - x: config.axis_x_min, - y: config.axis_y_min, - y2: config.axis_y2_min - }; + config.axis_y_min = config.axis_y2_min = min; + } + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } else { + return { + x: config.axis_x_min, + y: config.axis_y_min, + y2: config.axis_y2_min } + } }; -Chart.prototype.axis.range = function (range) { - if (arguments.length) { - if (isDefined(range.max)) { this.axis.max(range.max); } - if (isDefined(range.min)) { this.axis.min(range.min); } - } else { - return { - max: this.axis.max(), - min: this.axis.min() - }; +Chart.prototype.axis.range = function(range) { + if (arguments.length) { + if (isDefined(range.max)) { + this.axis.max(range.max); + } + if (isDefined(range.min)) { + this.axis.min(range.min); } + } else { + return { + max: this.axis.max(), + min: this.axis.min() + } + } }; -Chart.prototype.axis.types = function (types) { - const $$ = this.internal; - if (types === undefined) { - return { - y: $$.config.axis_y_type, - y2: $$.config.axis_y2_type - }; - } else { - if (isDefined(types.y)) { - $$.config.axis_y_type = types.y; - } - - if (isDefined(types.y2)) { - $$.config.axis_y2_type = types.y2; - } - - $$.updateScales(); - $$.redraw(); +Chart.prototype.axis.types = function(types) { + const $$ = this.internal; + if (types === undefined) { + return { + y: $$.config.axis_y_type, + y2: $$.config.axis_y2_type + } + } else { + if (isDefined(types.y)) { + $$.config.axis_y_type = types.y; } -}; -Chart.prototype.category = function (i, category) { - var $$ = this.internal, config = $$.config; - if (arguments.length > 1) { - config.axis_x_categories[i] = category; - $$.redraw(); + if (isDefined(types.y2)) { + $$.config.axis_y2_type = types.y2; } - return config.axis_x_categories[i]; + + $$.updateScales(); + $$.redraw(); + } }; -Chart.prototype.categories = function (categories) { - var $$ = this.internal, config = $$.config; - if (!arguments.length) { return config.axis_x_categories; } - config.axis_x_categories = categories; + +Chart.prototype.category = function(i, category) { + var $$ = this.internal, + config = $$.config; + if (arguments.length > 1) { + config.axis_x_categories[i] = category; $$.redraw(); - return config.axis_x_categories; + } + return config.axis_x_categories[i] +}; +Chart.prototype.categories = function(categories) { + var $$ = this.internal, + config = $$.config; + if (!arguments.length) { + return config.axis_x_categories + } + config.axis_x_categories = categories; + $$.redraw(); + return config.axis_x_categories }; -Chart.prototype.resize = function (size) { - var $$ = this.internal, config = $$.config; - config.size_width = size ? size.width : null; - config.size_height = size ? size.height : null; - this.flush(); +Chart.prototype.resize = function(size) { + var $$ = this.internal, + config = $$.config; + config.size_width = size ? size.width : null; + config.size_height = size ? size.height : null; + this.flush(); }; -Chart.prototype.flush = function () { - var $$ = this.internal; - $$.updateAndRedraw({withLegend: true, withTransition: false, withTransitionForTransform: false}); +Chart.prototype.flush = function() { + var $$ = this.internal; + $$.updateAndRedraw({ + withLegend: true, + withTransition: false, + withTransitionForTransform: false + }); }; -Chart.prototype.destroy = function () { - var $$ = this.internal; +Chart.prototype.destroy = function() { + var $$ = this.internal; - window.clearInterval($$.intervalForObserveInserted); + window.clearInterval($$.intervalForObserveInserted); - if ($$.resizeTimeout !== undefined) { - window.clearTimeout($$.resizeTimeout); - } + if ($$.resizeTimeout !== undefined) { + window.clearTimeout($$.resizeTimeout); + } - if (window.detachEvent) { - window.detachEvent('onresize', $$.resizeIfElementDisplayed); - } else if (window.removeEventListener) { - window.removeEventListener('resize', $$.resizeIfElementDisplayed); - } else { - var wrapper = window.onresize; - // check if no one else removed our wrapper and remove our resizeFunction from it - if (wrapper && wrapper.add && wrapper.remove) { - wrapper.remove($$.resizeFunction); - } + if (window.detachEvent) { + window.detachEvent('onresize', $$.resizeIfElementDisplayed); + } else if (window.removeEventListener) { + window.removeEventListener('resize', $$.resizeIfElementDisplayed); + } else { + var wrapper = window.onresize; + // check if no one else removed our wrapper and remove our resizeFunction from it + if (wrapper && wrapper.add && wrapper.remove) { + wrapper.remove($$.resizeFunction); } + } - // Removes the inner resize functions - $$.resizeFunction.remove(); + // Removes the inner resize functions + $$.resizeFunction.remove(); - // Unbinds from the window focus event - $$.unbindWindowFocus(); + // Unbinds from the window focus event + $$.unbindWindowFocus(); - $$.selectChart.classed('c3', false).html(""); + $$.selectChart.classed('c3', false).html(''); - // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. - Object.keys($$).forEach(function (key) { - $$[key] = null; - }); + // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. + Object.keys($$).forEach(function(key) { + $$[key] = null; + }); - return null; + return null }; // TODO: fix -Chart.prototype.color = function (id) { - var $$ = this.internal; - return $$.color(id); // more patterns +Chart.prototype.color = function(id) { + var $$ = this.internal; + return $$.color(id) // more patterns }; -Chart.prototype.data = function (targetIds) { - var targets = this.internal.data.targets; - return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) { - return [].concat(targetIds).indexOf(t.id) >= 0; - }); +Chart.prototype.data = function(targetIds) { + var targets = this.internal.data.targets; + return typeof targetIds === 'undefined' + ? targets + : targets.filter(function(t) { + return [].concat(targetIds).indexOf(t.id) >= 0 + }) }; -Chart.prototype.data.shown = function (targetIds) { - return this.internal.filterTargetsToShow(this.data(targetIds)); +Chart.prototype.data.shown = function(targetIds) { + return this.internal.filterTargetsToShow(this.data(targetIds)) }; /** @@ -4061,1421 +5273,1821 @@ Chart.prototype.data.shown = function (targetIds) { * @param flat * @return {Array} Data values */ -Chart.prototype.data.values = function (targetId, flat = true) { - let values = null; - - if (targetId) { - const targets = this.data(targetId); - if (targets && isArray(targets)) { - values = targets.reduce((ret, v) => { - const dataValue = v.values.map(d => d.value); - if (flat) { - ret = ret.concat(dataValue); - } else { - ret.push(dataValue); - } - return ret; - }, []); +Chart.prototype.data.values = function(targetId, flat = true) { + let values = null; + + if (targetId) { + const targets = this.data(targetId); + if (targets && isArray(targets)) { + values = targets.reduce((ret, v) => { + const dataValue = v.values.map(d => d.value); + if (flat) { + ret = ret.concat(dataValue); + } else { + ret.push(dataValue); } + return ret + }, []); } + } - return values; + return values }; -Chart.prototype.data.names = function (names) { - this.internal.clearLegendItemTextBoxCache(); - return this.internal.updateDataAttributes('names', names); +Chart.prototype.data.names = function(names) { + this.internal.clearLegendItemTextBoxCache(); + return this.internal.updateDataAttributes('names', names) }; -Chart.prototype.data.colors = function (colors) { - return this.internal.updateDataAttributes('colors', colors); +Chart.prototype.data.colors = function(colors) { + return this.internal.updateDataAttributes('colors', colors) }; -Chart.prototype.data.axes = function (axes) { - return this.internal.updateDataAttributes('axes', axes); +Chart.prototype.data.axes = function(axes) { + return this.internal.updateDataAttributes('axes', axes) }; -Chart.prototype.data.stackNormalized = function (normalized) { - if (normalized === undefined) { - return this.internal.isStackNormalized(); - } +Chart.prototype.data.stackNormalized = function(normalized) { + if (normalized === undefined) { + return this.internal.isStackNormalized() + } - this.internal.config.data_stack_normalize = !!normalized; - this.internal.redraw(); + this.internal.config.data_stack_normalize = !!normalized; + this.internal.redraw(); }; Chart.prototype.donut = function() {}; -Chart.prototype.donut.padAngle = function (padAngle) { - if (padAngle === undefined) { - return this.internal.config.donut_padAngle; - } - this.internal.config.donut_padAngle = padAngle; - this.flush(); -}; - -Chart.prototype.flow = function (args) { - var $$ = this.internal, - targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(), - dataCount, domain, baseTarget, baseValue, length = 0, tail = 0, diff, to; - - if (args.json) { - data = $$.convertJsonToData(args.json, args.keys); - } - else if (args.rows) { - data = $$.convertRowsToData(args.rows); - } - else if (args.columns) { - data = $$.convertColumnsToData(args.columns); - } - else { - return; - } - targets = $$.convertDataToTargets(data, true); - - // Update/Add data - $$.data.targets.forEach(function (t) { - var found = false, i, j; - for (i = 0; i < targets.length; i++) { - if (t.id === targets[i].id) { - found = true; - - if (t.values[t.values.length - 1]) { - tail = t.values[t.values.length - 1].index + 1; - } - length = targets[i].values.length; - - for (j = 0; j < length; j++) { - targets[i].values[j].index = tail + j; - if (!$$.isTimeSeries()) { - targets[i].values[j].x = tail + j; - } - } - t.values = t.values.concat(targets[i].values); - - targets.splice(i, 1); - break; - } - } - if (!found) { notfoundIds.push(t.id); } +Chart.prototype.donut.padAngle = function(padAngle) { + if (padAngle === undefined) { + return this.internal.config.donut_padAngle + } + this.internal.config.donut_padAngle = padAngle; + this.flush(); +}; + +Chart.prototype.flow = function(args) { + var $$ = this.internal, + targets, + data, + notfoundIds = [], + orgDataCount = $$.getMaxDataCount(), + dataCount, + domain, + baseTarget, + baseValue, + length = 0, + tail = 0, + diff, + to; + + if (args.json) { + data = $$.convertJsonToData(args.json, args.keys); + } else if (args.rows) { + data = $$.convertRowsToData(args.rows); + } else if (args.columns) { + data = $$.convertColumnsToData(args.columns); + } else { + return + } + targets = $$.convertDataToTargets(data, true); + + // Update/Add data + $$.data.targets.forEach(function(t) { + var found = false, + i, + j; + for (i = 0; i < targets.length; i++) { + if (t.id === targets[i].id) { + found = true; + + if (t.values[t.values.length - 1]) { + tail = t.values[t.values.length - 1].index + 1; + } + length = targets[i].values.length; + + for (j = 0; j < length; j++) { + targets[i].values[j].index = tail + j; + if (!$$.isTimeSeries()) { + targets[i].values[j].x = tail + j; + } + } + t.values = t.values.concat(targets[i].values); + + targets.splice(i, 1); + break + } + } + if (!found) { + notfoundIds.push(t.id); + } + }); + + // Append null for not found targets + $$.data.targets.forEach(function(t) { + var i, j; + for (i = 0; i < notfoundIds.length; i++) { + if (t.id === notfoundIds[i]) { + tail = t.values[t.values.length - 1].index + 1; + for (j = 0; j < length; j++) { + t.values.push({ + id: t.id, + index: tail + j, + x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j, + value: null + }); + } + } + } + }); + + // Generate null values for new target + if ($$.data.targets.length) { + targets.forEach(function(t) { + var i, + missing = []; + for (i = $$.data.targets[0].values[0].index; i < tail; i++) { + missing.push({ + id: t.id, + index: i, + x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i, + value: null + }); + } + t.values.forEach(function(v) { + v.index += tail; + if (!$$.isTimeSeries()) { + v.x += tail; + } + }); + t.values = missing.concat(t.values); }); - - // Append null for not found targets - $$.data.targets.forEach(function (t) { - var i, j; - for (i = 0; i < notfoundIds.length; i++) { - if (t.id === notfoundIds[i]) { - tail = t.values[t.values.length - 1].index + 1; - for (j = 0; j < length; j++) { - t.values.push({ - id: t.id, - index: tail + j, - x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j, - value: null - }); - } - } - } + } + $$.data.targets = $$.data.targets.concat(targets); // add remained + + // check data count because behavior needs to change when it's only one + dataCount = $$.getMaxDataCount(); + baseTarget = $$.data.targets[0]; + baseValue = baseTarget.values[0]; + + // Update length to flow if needed + if (isDefined(args.to)) { + length = 0; + to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to; + baseTarget.values.forEach(function(v) { + if (v.x < to) { + length++; + } }); + } else if (isDefined(args.length)) { + length = args.length; + } - // Generate null values for new target - if ($$.data.targets.length) { - targets.forEach(function (t) { - var i, missing = []; - for (i = $$.data.targets[0].values[0].index; i < tail; i++) { - missing.push({ - id: t.id, - index: i, - x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i, - value: null - }); - } - t.values.forEach(function (v) { - v.index += tail; - if (!$$.isTimeSeries()) { - v.x += tail; - } - }); - t.values = missing.concat(t.values); - }); + // If only one data, update the domain to flow from left edge of the chart + if (!orgDataCount) { + if ($$.isTimeSeries()) { + if (baseTarget.values.length > 1) { + diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x; + } else { + diff = baseValue.x - $$.getXDomain($$.data.targets)[0]; + } + } else { + diff = 1; } - $$.data.targets = $$.data.targets.concat(targets); // add remained - - // check data count because behavior needs to change when it's only one - dataCount = $$.getMaxDataCount(); - baseTarget = $$.data.targets[0]; - baseValue = baseTarget.values[0]; - - // Update length to flow if needed - if (isDefined(args.to)) { - length = 0; - to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to; - baseTarget.values.forEach(function (v) { - if (v.x < to) { length++; } - }); - } else if (isDefined(args.length)) { - length = args.length; + domain = [baseValue.x - diff, baseValue.x]; + $$.updateXDomain(null, true, true, false, domain); + } else if (orgDataCount === 1) { + if ($$.isTimeSeries()) { + diff = + (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2; + domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)]; + $$.updateXDomain(null, true, true, false, domain); } + } - // If only one data, update the domain to flow from left edge of the chart - if (!orgDataCount) { + // Set targets + $$.updateTargets($$.data.targets); + + // Redraw with new targets + $$.redraw({ + flow: { + index: baseValue.index, + length: length, + duration: isValue(args.duration) + ? args.duration + : $$.config.transition_duration, + done: args.done, + orgDataCount: orgDataCount + }, + withLegend: true, + withTransition: orgDataCount > 1, + withTrimXDomain: false, + withUpdateXAxis: true + }); +}; + +ChartInternal.prototype.generateFlow = function(args) { + var $$ = this, + config = $$.config, + d3 = $$.d3; + + return function() { + var targets = args.targets, + flow = args.flow, + drawBar = args.drawBar, + drawLine = args.drawLine, + drawArea = args.drawArea, + cx = args.cx, + cy = args.cy, + xv = args.xv, + xForText = args.xForText, + yForText = args.yForText, + duration = args.duration; + + var translateX, + scaleX = 1, + transform, + flowIndex = flow.index, + flowLength = flow.length, + flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), + flowEnd = $$.getValueOnIndex( + $$.data.targets[0].values, + flowIndex + flowLength + ), + orgDomain = $$.x.domain(), + domain, + durationForFlow = flow.duration || duration, + done = flow.done || function() {}, + wait = $$.generateWait(); + + var xgrid, + xgridLines, + mainRegion, + mainText, + mainBar, + mainLine, + mainArea, + mainCircle; + + // set flag + $$.flowing = true; + + // remove head data after rendered + $$.data.targets.forEach(function(d) { + d.values.splice(0, flowLength); + }); + + // update x domain to generate axis elements for flow + domain = $$.updateXDomain(targets, true, true); + // update elements related to x scale + if ($$.updateXGrid) { + $$.updateXGrid(true); + } + + xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid + xgridLines = $$.xgridLines || d3.selectAll([]); + mainRegion = $$.mainRegion || d3.selectAll([]); + mainText = $$.mainText || d3.selectAll([]); + mainBar = $$.mainBar || d3.selectAll([]); + mainLine = $$.mainLine || d3.selectAll([]); + mainArea = $$.mainArea || d3.selectAll([]); + mainCircle = $$.mainCircle || d3.selectAll([]); + + // generate transform to flow + if (!flow.orgDataCount) { + // if empty + if ($$.data.targets[0].values.length !== 1) { + translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); + } else { if ($$.isTimeSeries()) { - if (baseTarget.values.length > 1) { - diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x; - } else { - diff = baseValue.x - $$.getXDomain($$.data.targets)[0]; - } + flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0); + flowEnd = $$.getValueOnIndex( + $$.data.targets[0].values, + $$.data.targets[0].values.length - 1 + ); + translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); } else { - diff = 1; - } - domain = [baseValue.x - diff, baseValue.x]; - $$.updateXDomain(null, true, true, false, domain); - } else if (orgDataCount === 1) { - if ($$.isTimeSeries()) { - diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2; - domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)]; - $$.updateXDomain(null, true, true, false, domain); - } - } + translateX = diffDomain(domain) / 2; + } + } + } else if ( + flow.orgDataCount === 1 || + (flowStart && flowStart.x) === (flowEnd && flowEnd.x) + ) { + translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); + } else { + if ($$.isTimeSeries()) { + translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); + } else { + translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); + } + } + scaleX = diffDomain(orgDomain) / diffDomain(domain); + transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)'; + + $$.hideXGridFocus(); + + var flowTransition = d3 + .transition() + .ease(d3.easeLinear) + .duration(durationForFlow); + wait.add($$.xAxis($$.axes.x, flowTransition)); + wait.add(mainBar.transition(flowTransition).attr('transform', transform)); + wait.add(mainLine.transition(flowTransition).attr('transform', transform)); + wait.add(mainArea.transition(flowTransition).attr('transform', transform)); + wait.add(mainCircle.transition(flowTransition).attr('transform', transform)); + wait.add(mainText.transition(flowTransition).attr('transform', transform)); + wait.add( + mainRegion + .filter($$.isRegionOnX) + .transition(flowTransition) + .attr('transform', transform) + ); + wait.add(xgrid.transition(flowTransition).attr('transform', transform)); + wait.add(xgridLines.transition(flowTransition).attr('transform', transform)); + wait(function() { + var i, + shapes = [], + texts = []; + + // remove flowed elements + if (flowLength) { + for (i = 0; i < flowLength; i++) { + shapes.push('.' + CLASS.shape + '-' + (flowIndex + i)); + texts.push('.' + CLASS.text + '-' + (flowIndex + i)); + } + $$.svg + .selectAll('.' + CLASS.shapes) + .selectAll(shapes) + .remove(); + $$.svg + .selectAll('.' + CLASS.texts) + .selectAll(texts) + .remove(); + $$.svg.select('.' + CLASS.xgrid).remove(); + } + + // draw again for removing flowed elements and reverting attr + xgrid + .attr('transform', null) + .attr('x1', $$.xgridAttr.x1) + .attr('x2', $$.xgridAttr.x2) + .attr('y1', $$.xgridAttr.y1) + .attr('y2', $$.xgridAttr.y2) + .style('opacity', $$.xgridAttr.opacity); + xgridLines.attr('transform', null); + xgridLines + .select('line') + .attr('x1', config.axis_rotated ? 0 : xv) + .attr('x2', config.axis_rotated ? $$.width : xv); + xgridLines + .select('text') + .attr('x', config.axis_rotated ? $$.width : 0) + .attr('y', xv); + mainBar.attr('transform', null).attr('d', drawBar); + mainLine.attr('transform', null).attr('d', drawLine); + mainArea.attr('transform', null).attr('d', drawArea); + mainCircle + .attr('transform', null) + .attr('cx', cx) + .attr('cy', cy); + mainText + .attr('transform', null) + .attr('x', xForText) + .attr('y', yForText) + .style('fill-opacity', $$.opacityForText.bind($$)); + mainRegion.attr('transform', null); + mainRegion + .filter($$.isRegionOnX) + .attr('x', $$.regionX.bind($$)) + .attr('width', $$.regionWidth.bind($$)); - // Set targets - $$.updateTargets($$.data.targets); + // callback for end of flow + done(); - // Redraw with new targets - $$.redraw({ - flow: { - index: baseValue.index, - length: length, - duration: isValue(args.duration) ? args.duration : $$.config.transition_duration, - done: args.done, - orgDataCount: orgDataCount, - }, - withLegend: true, - withTransition: orgDataCount > 1, - withTrimXDomain: false, - withUpdateXAxis: true, + $$.flowing = false; }); + } }; -ChartInternal.prototype.generateFlow = function (args) { - var $$ = this, config = $$.config, d3 = $$.d3; - - return function () { - var targets = args.targets, - flow = args.flow, - drawBar = args.drawBar, - drawLine = args.drawLine, - drawArea = args.drawArea, - cx = args.cx, - cy = args.cy, - xv = args.xv, - xForText = args.xForText, - yForText = args.yForText, - duration = args.duration; - - var translateX, scaleX = 1, transform, - flowIndex = flow.index, - flowLength = flow.length, - flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), - flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength), - orgDomain = $$.x.domain(), domain, - durationForFlow = flow.duration || duration, - done = flow.done || function () {}, - wait = $$.generateWait(); - - var xgrid, - xgridLines, - mainRegion, - mainText, - mainBar, - mainLine, - mainArea, - mainCircle; - - // set flag - $$.flowing = true; - - // remove head data after rendered - $$.data.targets.forEach(function (d) { - d.values.splice(0, flowLength); - }); - - // update x domain to generate axis elements for flow - domain = $$.updateXDomain(targets, true, true); - // update elements related to x scale - if ($$.updateXGrid) { $$.updateXGrid(true); } - - xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid - xgridLines = $$.xgridLines || d3.selectAll([]); - mainRegion = $$.mainRegion || d3.selectAll([]); - mainText = $$.mainText || d3.selectAll([]); - mainBar = $$.mainBar || d3.selectAll([]); - mainLine = $$.mainLine || d3.selectAll([]); - mainArea = $$.mainArea || d3.selectAll([]); - mainCircle = $$.mainCircle || d3.selectAll([]); - - // generate transform to flow - if (!flow.orgDataCount) { // if empty - if ($$.data.targets[0].values.length !== 1) { - translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); - } else { - if ($$.isTimeSeries()) { - flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0); - flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1); - translateX = $$.x(flowStart.x) - $$.x(flowEnd.x); - } else { - translateX = diffDomain(domain) / 2; - } - } - } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) { - translateX = $$.x(orgDomain[0]) - $$.x(domain[0]); - } else { - if ($$.isTimeSeries()) { - translateX = ($$.x(orgDomain[0]) - $$.x(domain[0])); - } else { - translateX = ($$.x(flowStart.x) - $$.x(flowEnd.x)); - } - } - scaleX = (diffDomain(orgDomain) / diffDomain(domain)); - transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)'; - - $$.hideXGridFocus(); - - var flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow); - wait.add($$.xAxis($$.axes.x, flowTransition)); - wait.add(mainBar.transition(flowTransition).attr('transform', transform)); - wait.add(mainLine.transition(flowTransition).attr('transform', transform)); - wait.add(mainArea.transition(flowTransition).attr('transform', transform)); - wait.add(mainCircle.transition(flowTransition).attr('transform', transform)); - wait.add(mainText.transition(flowTransition).attr('transform', transform)); - wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform)); - wait.add(xgrid.transition(flowTransition).attr('transform', transform)); - wait.add(xgridLines.transition(flowTransition).attr('transform', transform)); - wait(function () { - var i, shapes = [], texts = []; - - // remove flowed elements - if (flowLength) { - for (i = 0; i < flowLength; i++) { - shapes.push('.' + CLASS.shape + '-' + (flowIndex + i)); - texts.push('.' + CLASS.text + '-' + (flowIndex + i)); - } - $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove(); - $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove(); - $$.svg.select('.' + CLASS.xgrid).remove(); - } - - // draw again for removing flowed elements and reverting attr - xgrid - .attr('transform', null) - .attr('x1', $$.xgridAttr.x1) - .attr('x2', $$.xgridAttr.x2) - .attr('y1', $$.xgridAttr.y1) - .attr('y2', $$.xgridAttr.y2) - .style("opacity", $$.xgridAttr.opacity); - xgridLines - .attr('transform', null); - xgridLines.select('line') - .attr("x1", config.axis_rotated ? 0 : xv) - .attr("x2", config.axis_rotated ? $$.width : xv); - xgridLines.select('text') - .attr("x", config.axis_rotated ? $$.width : 0) - .attr("y", xv); - mainBar - .attr('transform', null) - .attr("d", drawBar); - mainLine - .attr('transform', null) - .attr("d", drawLine); - mainArea - .attr('transform', null) - .attr("d", drawArea); - mainCircle - .attr('transform', null) - .attr("cx", cx) - .attr("cy", cy); - mainText - .attr('transform', null) - .attr('x', xForText) - .attr('y', yForText) - .style('fill-opacity', $$.opacityForText.bind($$)); - mainRegion - .attr('transform', null); - mainRegion.filter($$.isRegionOnX) - .attr("x", $$.regionX.bind($$)) - .attr("width", $$.regionWidth.bind($$)); - - // callback for end of flow - done(); - - $$.flowing = false; - }); - }; -}; - -Chart.prototype.focus = function (targetIds) { - var $$ = this.internal, candidates; - - targetIds = $$.mapToTargetIds(targetIds); - candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), +Chart.prototype.focus = function(targetIds) { + var $$ = this.internal, + candidates; + targetIds = $$.mapToTargetIds(targetIds) + ;(candidates = $$.svg.selectAll( + $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)) + )), this.revert(); - this.defocus(); - candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false); - if ($$.hasArcType()) { - $$.expandArc(targetIds); - } - $$.toggleFocusLegend(targetIds, true); + this.defocus(); + candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false); + if ($$.hasArcType()) { + $$.expandArc(targetIds); + } + $$.toggleFocusLegend(targetIds, true); - $$.focusedTargetIds = targetIds; - $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); + $$.focusedTargetIds = targetIds; + $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); }; -Chart.prototype.defocus = function (targetIds) { - var $$ = this.internal, candidates; - - targetIds = $$.mapToTargetIds(targetIds); - candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), +Chart.prototype.defocus = function(targetIds) { + var $$ = this.internal, + candidates; + targetIds = $$.mapToTargetIds(targetIds) + ;(candidates = $$.svg.selectAll( + $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)) + )), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true); - if ($$.hasArcType()) { - $$.unexpandArc(targetIds); - } - $$.toggleFocusLegend(targetIds, false); + if ($$.hasArcType()) { + $$.unexpandArc(targetIds); + } + $$.toggleFocusLegend(targetIds, false); - $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); - $$.defocusedTargetIds = targetIds; + $$.focusedTargetIds = $$.focusedTargetIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); + $$.defocusedTargetIds = targetIds; }; -Chart.prototype.revert = function (targetIds) { - var $$ = this.internal, candidates; - - targetIds = $$.mapToTargetIds(targetIds); - candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets +Chart.prototype.revert = function(targetIds) { + var $$ = this.internal, + candidates; - candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false); - if ($$.hasArcType()) { - $$.unexpandArc(targetIds); - } - if ($$.config.legend_show) { - $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); - $$.legend.selectAll($$.selectorLegends(targetIds)) - .filter(function () { - return $$.d3.select(this).classed(CLASS.legendItemFocused); - }) - .classed(CLASS.legendItemFocused, false); - } - - $$.focusedTargetIds = []; - $$.defocusedTargetIds = []; -}; - -Chart.prototype.xgrids = function (grids) { - var $$ = this.internal, config = $$.config; - if (! grids) { return config.grid_x_lines; } - config.grid_x_lines = grids; - $$.redrawWithoutRescale(); - return config.grid_x_lines; -}; -Chart.prototype.xgrids.add = function (grids) { - var $$ = this.internal; - return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : [])); -}; -Chart.prototype.xgrids.remove = function (params) { // TODO: multiple - var $$ = this.internal; - $$.removeGridLines(params, true); -}; + targetIds = $$.mapToTargetIds(targetIds); + candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets -Chart.prototype.ygrids = function (grids) { - var $$ = this.internal, config = $$.config; - if (! grids) { return config.grid_y_lines; } - config.grid_y_lines = grids; - $$.redrawWithoutRescale(); - return config.grid_y_lines; -}; -Chart.prototype.ygrids.add = function (grids) { - var $$ = this.internal; - return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : [])); -}; -Chart.prototype.ygrids.remove = function (params) { // TODO: multiple - var $$ = this.internal; - $$.removeGridLines(params, false); -}; + candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false); + if ($$.hasArcType()) { + $$.unexpandArc(targetIds); + } + if ($$.config.legend_show) { + $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); + $$.legend + .selectAll($$.selectorLegends(targetIds)) + .filter(function() { + return $$.d3.select(this).classed(CLASS.legendItemFocused) + }) + .classed(CLASS.legendItemFocused, false); + } -Chart.prototype.groups = function (groups) { - var $$ = this.internal, config = $$.config; - if (isUndefined(groups)) { return config.data_groups; } - config.data_groups = groups; - $$.redraw(); - return config.data_groups; + $$.focusedTargetIds = []; + $$.defocusedTargetIds = []; }; -Chart.prototype.legend = function () {}; -Chart.prototype.legend.show = function (targetIds) { - var $$ = this.internal; - $$.showLegend($$.mapToTargetIds(targetIds)); - $$.updateAndRedraw({withLegend: true}); -}; -Chart.prototype.legend.hide = function (targetIds) { - var $$ = this.internal; - $$.hideLegend($$.mapToTargetIds(targetIds)); - $$.updateAndRedraw({withLegend: false}); +Chart.prototype.xgrids = function(grids) { + var $$ = this.internal, + config = $$.config; + if (!grids) { + return config.grid_x_lines + } + config.grid_x_lines = grids; + $$.redrawWithoutRescale(); + return config.grid_x_lines }; - -Chart.prototype.load = function (args) { - var $$ = this.internal, config = $$.config; - // update xs if specified - if (args.xs) { - $$.addXs(args.xs); - } - // update names if exists - if ('names' in args) { - Chart.prototype.data.names.bind(this)(args.names); - } - // update classes if exists - if ('classes' in args) { - Object.keys(args.classes).forEach(function (id) { - config.data_classes[id] = args.classes[id]; - }); - } - // update categories if exists - if ('categories' in args && $$.isCategorized()) { - config.axis_x_categories = args.categories; - } - // update axes if exists - if ('axes' in args) { - Object.keys(args.axes).forEach(function (id) { - config.data_axes[id] = args.axes[id]; - }); - } - // update colors if exists - if ('colors' in args) { - Object.keys(args.colors).forEach(function (id) { - config.data_colors[id] = args.colors[id]; - }); - } - // use cache if exists - if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) { - $$.load($$.getCaches(args.cacheIds), args.done); - return; - } - // unload if needed - if (args.unload) { - // TODO: do not unload if target will load (included in url/rows/columns) - $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), function () { - $$.loadFromArgs(args); - }); - } else { - $$.loadFromArgs(args); - } +Chart.prototype.xgrids.add = function(grids) { + var $$ = this.internal; + return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : [])) +}; +Chart.prototype.xgrids.remove = function(params) { + // TODO: multiple + var $$ = this.internal; + $$.removeGridLines(params, true); }; -Chart.prototype.unload = function (args) { - var $$ = this.internal; - args = args || {}; - if (args instanceof Array) { - args = {ids: args}; - } else if (typeof args === 'string') { - args = {ids: [args]}; - } - $$.unload($$.mapToTargetIds(args.ids), function () { - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); - if (args.done) { args.done(); } - }); +Chart.prototype.ygrids = function(grids) { + var $$ = this.internal, + config = $$.config; + if (!grids) { + return config.grid_y_lines + } + config.grid_y_lines = grids; + $$.redrawWithoutRescale(); + return config.grid_y_lines +}; +Chart.prototype.ygrids.add = function(grids) { + var $$ = this.internal; + return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : [])) +}; +Chart.prototype.ygrids.remove = function(params) { + // TODO: multiple + var $$ = this.internal; + $$.removeGridLines(params, false); }; -Chart.prototype.pie = function() {}; +Chart.prototype.groups = function(groups) { + var $$ = this.internal, + config = $$.config; + if (isUndefined(groups)) { + return config.data_groups + } + config.data_groups = groups; + $$.redraw(); + return config.data_groups +}; -Chart.prototype.pie.padAngle = function (padAngle) { - if (padAngle === undefined) { - return this.internal.config.pie_padAngle; - } - this.internal.config.pie_padAngle = padAngle; - this.flush(); +Chart.prototype.legend = function() {}; +Chart.prototype.legend.show = function(targetIds) { + var $$ = this.internal; + $$.showLegend($$.mapToTargetIds(targetIds)); + $$.updateAndRedraw({ withLegend: true }); +}; +Chart.prototype.legend.hide = function(targetIds) { + var $$ = this.internal; + $$.hideLegend($$.mapToTargetIds(targetIds)); + $$.updateAndRedraw({ withLegend: false }); }; -Chart.prototype.regions = function (regions) { - var $$ = this.internal, config = $$.config; - if (!regions) { return config.regions; } - config.regions = regions; - $$.redrawWithoutRescale(); - return config.regions; +Chart.prototype.load = function(args) { + var $$ = this.internal, + config = $$.config; + // update xs if specified + if (args.xs) { + $$.addXs(args.xs); + } + // update names if exists + if ('names' in args) { + Chart.prototype.data.names.bind(this)(args.names); + } + // update classes if exists + if ('classes' in args) { + Object.keys(args.classes).forEach(function(id) { + config.data_classes[id] = args.classes[id]; + }); + } + // update categories if exists + if ('categories' in args && $$.isCategorized()) { + config.axis_x_categories = args.categories; + } + // update axes if exists + if ('axes' in args) { + Object.keys(args.axes).forEach(function(id) { + config.data_axes[id] = args.axes[id]; + }); + } + // update colors if exists + if ('colors' in args) { + Object.keys(args.colors).forEach(function(id) { + config.data_colors[id] = args.colors[id]; + }); + } + // use cache if exists + if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) { + $$.load($$.getCaches(args.cacheIds), args.done); + return + } + // unload if needed + if (args.unload) { + // TODO: do not unload if target will load (included in url/rows/columns) + $$.unload( + $$.mapToTargetIds(args.unload === true ? null : args.unload), + function() { + $$.loadFromArgs(args); + } + ); + } else { + $$.loadFromArgs(args); + } }; -Chart.prototype.regions.add = function (regions) { - var $$ = this.internal, config = $$.config; - if (!regions) { return config.regions; } - config.regions = config.regions.concat(regions); - $$.redrawWithoutRescale(); - return config.regions; + +Chart.prototype.unload = function(args) { + var $$ = this.internal; + args = args || {}; + if (args instanceof Array) { + args = { ids: args }; + } else if (typeof args === 'string') { + args = { ids: [args] }; + } + $$.unload($$.mapToTargetIds(args.ids), function() { + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); + if (args.done) { + args.done(); + } + }); }; -Chart.prototype.regions.remove = function (options) { - var $$ = this.internal, config = $$.config, - duration, classes, regions; - options = options || {}; - duration = getOption(options, "duration", config.transition_duration); - classes = getOption(options, "classes", [CLASS.region]); +Chart.prototype.pie = function() {}; - regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) { return '.' + c; })); - (duration ? regions.transition().duration(duration) : regions) - .style('opacity', 0) - .remove(); +Chart.prototype.pie.padAngle = function(padAngle) { + if (padAngle === undefined) { + return this.internal.config.pie_padAngle + } + this.internal.config.pie_padAngle = padAngle; + this.flush(); +}; - config.regions = config.regions.filter(function (region) { - var found = false; - if (!region['class']) { - return true; - } - region['class'].split(' ').forEach(function (c) { - if (classes.indexOf(c) >= 0) { found = true; } - }); - return !found; +Chart.prototype.regions = function(regions) { + var $$ = this.internal, + config = $$.config; + if (!regions) { + return config.regions + } + config.regions = regions; + $$.redrawWithoutRescale(); + return config.regions +}; +Chart.prototype.regions.add = function(regions) { + var $$ = this.internal, + config = $$.config; + if (!regions) { + return config.regions + } + config.regions = config.regions.concat(regions); + $$.redrawWithoutRescale(); + return config.regions +}; +Chart.prototype.regions.remove = function(options) { + var $$ = this.internal, + config = $$.config, + duration, + classes, + regions; + + options = options || {}; + duration = getOption(options, 'duration', config.transition_duration); + classes = getOption(options, 'classes', [CLASS.region]); + + regions = $$.main.select('.' + CLASS.regions).selectAll( + classes.map(function(c) { + return '.' + c + }) + ) + ;(duration ? regions.transition().duration(duration) : regions) + .style('opacity', 0) + .remove(); + + config.regions = config.regions.filter(function(region) { + var found = false; + if (!region['class']) { + return true + } + region['class'].split(' ').forEach(function(c) { + if (classes.indexOf(c) >= 0) { + found = true; + } }); - - return config.regions; -}; - -Chart.prototype.selected = function (targetId) { - var $$ = this.internal, d3 = $$.d3; - return $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape) - .filter(function () { return d3.select(this).classed(CLASS.SELECTED); }) - .nodes() - .map(function (d) { var data = d.__data__; return data.data ? data.data : data;}); -}; -Chart.prototype.select = function (ids, indices, resetOther) { - var $$ = this.internal, d3 = $$.d3, config = $$.config; - if (! config.data_selection_enabled) { return; } - $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { - var shape = d3.select(this), id = d.data ? d.data.id : d.id, - toggle = $$.getToggle(this, d).bind($$), - isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, - isTargetIndex = !indices || indices.indexOf(i) >= 0, - isSelected = shape.classed(CLASS.SELECTED); - // line/area selection not supported yet - if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { - return; - } - if (isTargetId && isTargetIndex) { - if (config.data_selection_isselectable(d) && !isSelected) { - toggle(true, shape.classed(CLASS.SELECTED, true), d, i); - } - } else if (isDefined(resetOther) && resetOther) { - if (isSelected) { - toggle(false, shape.classed(CLASS.SELECTED, false), d, i); - } - } + return !found + }); + + return config.regions +}; + +Chart.prototype.selected = function(targetId) { + var $$ = this.internal, + d3 = $$.d3; + return $$.main + .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)) + .selectAll('.' + CLASS.shape) + .filter(function() { + return d3.select(this).classed(CLASS.SELECTED) + }) + .nodes() + .map(function(d) { + var data = d.__data__; + return data.data ? data.data : data + }) +}; +Chart.prototype.select = function(ids, indices, resetOther) { + var $$ = this.internal, + d3 = $$.d3, + config = $$.config; + if (!config.data_selection_enabled) { + return + } + $$.main + .selectAll('.' + CLASS.shapes) + .selectAll('.' + CLASS.shape) + .each(function(d, i) { + var shape = d3.select(this), + id = d.data ? d.data.id : d.id, + toggle = $$.getToggle(this, d).bind($$), + isTargetId = + config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, + isTargetIndex = !indices || indices.indexOf(i) >= 0, + isSelected = shape.classed(CLASS.SELECTED); + // line/area selection not supported yet + if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { + return + } + if (isTargetId && isTargetIndex) { + if (config.data_selection_isselectable(d) && !isSelected) { + toggle(true, shape.classed(CLASS.SELECTED, true), d, i); + } + } else if (isDefined(resetOther) && resetOther) { + if (isSelected) { + toggle(false, shape.classed(CLASS.SELECTED, false), d, i); + } + } }); }; -Chart.prototype.unselect = function (ids, indices) { - var $$ = this.internal, d3 = $$.d3, config = $$.config; - if (! config.data_selection_enabled) { return; } - $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { - var shape = d3.select(this), id = d.data ? d.data.id : d.id, - toggle = $$.getToggle(this, d).bind($$), - isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, - isTargetIndex = !indices || indices.indexOf(i) >= 0, - isSelected = shape.classed(CLASS.SELECTED); - // line/area selection not supported yet - if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { - return; - } - if (isTargetId && isTargetIndex) { - if (config.data_selection_isselectable(d)) { - if (isSelected) { - toggle(false, shape.classed(CLASS.SELECTED, false), d, i); - } - } - } +Chart.prototype.unselect = function(ids, indices) { + var $$ = this.internal, + d3 = $$.d3, + config = $$.config; + if (!config.data_selection_enabled) { + return + } + $$.main + .selectAll('.' + CLASS.shapes) + .selectAll('.' + CLASS.shape) + .each(function(d, i) { + var shape = d3.select(this), + id = d.data ? d.data.id : d.id, + toggle = $$.getToggle(this, d).bind($$), + isTargetId = + config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, + isTargetIndex = !indices || indices.indexOf(i) >= 0, + isSelected = shape.classed(CLASS.SELECTED); + // line/area selection not supported yet + if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) { + return + } + if (isTargetId && isTargetIndex) { + if (config.data_selection_isselectable(d)) { + if (isSelected) { + toggle(false, shape.classed(CLASS.SELECTED, false), d, i); + } + } + } }); }; -Chart.prototype.show = function (targetIds, options) { - var $$ = this.internal, targets; +Chart.prototype.show = function(targetIds, options) { + var $$ = this.internal, + targets; - targetIds = $$.mapToTargetIds(targetIds); - options = options || {}; + targetIds = $$.mapToTargetIds(targetIds); + options = options || {}; - $$.removeHiddenTargetIds(targetIds); - targets = $$.svg.selectAll($$.selectorTargets(targetIds)); + $$.removeHiddenTargetIds(targetIds); + targets = $$.svg.selectAll($$.selectorTargets(targetIds)); - targets.transition() - .style('display', isIE() ? 'block' : 'initial', 'important') - .style('opacity', 1, 'important') - .call($$.endall, function () { - targets.style('opacity', null).style('opacity', 1); - }); + targets + .transition() + .style('display', isIE() ? 'block' : 'initial', 'important') + .style('opacity', 1, 'important') + .call($$.endall, function() { + targets.style('opacity', null).style('opacity', 1); + }); - if (options.withLegend) { - $$.showLegend(targetIds); - } + if (options.withLegend) { + $$.showLegend(targetIds); + } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); }; -Chart.prototype.hide = function (targetIds, options) { - var $$ = this.internal, targets; +Chart.prototype.hide = function(targetIds, options) { + var $$ = this.internal, + targets; - targetIds = $$.mapToTargetIds(targetIds); - options = options || {}; + targetIds = $$.mapToTargetIds(targetIds); + options = options || {}; - $$.addHiddenTargetIds(targetIds); - targets = $$.svg.selectAll($$.selectorTargets(targetIds)); + $$.addHiddenTargetIds(targetIds); + targets = $$.svg.selectAll($$.selectorTargets(targetIds)); - targets.transition() - .style('opacity', 0, 'important') - .call($$.endall, function () { - targets.style('opacity', null).style('opacity', 0); - targets.style('display', 'none'); - }); + targets + .transition() + .style('opacity', 0, 'important') + .call($$.endall, function() { + targets.style('opacity', null).style('opacity', 0); + targets.style('display', 'none'); + }); - if (options.withLegend) { - $$.hideLegend(targetIds); - } + if (options.withLegend) { + $$.hideLegend(targetIds); + } - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); }; -Chart.prototype.toggle = function (targetIds, options) { - var that = this, $$ = this.internal; - $$.mapToTargetIds(targetIds).forEach(function (targetId) { - $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options); - }); +Chart.prototype.toggle = function(targetIds, options) { + var that = this, + $$ = this.internal; + $$.mapToTargetIds(targetIds).forEach(function(targetId) { + $$.isTargetToShow(targetId) + ? that.hide(targetId, options) + : that.show(targetId, options); + }); }; -Chart.prototype.subchart = function () {}; +Chart.prototype.subchart = function() {}; Chart.prototype.subchart.isShown = function() { - const $$ = this.internal; + const $$ = this.internal; - return $$.config.subchart_show; + return $$.config.subchart_show }; -Chart.prototype.subchart.show = function () { - const $$ = this.internal; +Chart.prototype.subchart.show = function() { + const $$ = this.internal; - if ($$.config.subchart_show) { - return; - } + if ($$.config.subchart_show) { + return + } - $$.config.subchart_show = true; + $$.config.subchart_show = true; - // insert DOM - $$.initSubchart(); + // insert DOM + $$.initSubchart(); - // update dimensions with sub chart now visible - $$.updateDimension(); + // update dimensions with sub chart now visible + $$.updateDimension(); - // insert brush (depends on sizes previously updated) - $$.initSubchartBrush(); + // insert brush (depends on sizes previously updated) + $$.initSubchartBrush(); - // attach data - $$.updateTargetsForSubchart($$.getTargets()); + // attach data + $$.updateTargetsForSubchart($$.getTargets()); - // reset fade-in state - $$.mapToIds($$.data.targets).forEach(function(id) { - $$.withoutFadeIn[id] = false; - }); + // reset fade-in state + $$.mapToIds($$.data.targets).forEach(function(id) { + $$.withoutFadeIn[id] = false; + }); - // redraw chart ! - $$.updateAndRedraw(); + // redraw chart ! + $$.updateAndRedraw(); - // update visible targets ! - $$.showTargets(); + // update visible targets ! + $$.showTargets(); }; -Chart.prototype.subchart.hide = function () { - const $$ = this.internal; +Chart.prototype.subchart.hide = function() { + const $$ = this.internal; - if (!$$.config.subchart_show) { - return; - } + if (!$$.config.subchart_show) { + return + } - $$.config.subchart_show = false; + $$.config.subchart_show = false; - // remove DOM - $$.removeSubchart(); + // remove DOM + $$.removeSubchart(); - // re-render chart - $$.redraw(); + // re-render chart + $$.redraw(); }; -Chart.prototype.tooltip = function () {}; -Chart.prototype.tooltip.show = function (args) { - var $$ = this.internal, targets, data, mouse = {}; +Chart.prototype.tooltip = function() {}; +Chart.prototype.tooltip.show = function(args) { + var $$ = this.internal, + targets, + data, + mouse = {}; - // determine mouse position on the chart - if (args.mouse) { - mouse = args.mouse; - } - else { - // determine focus data - if (args.data) { - data = args.data; - } - else if (typeof args.x !== 'undefined') { - if (args.id) { - targets = $$.data.targets.filter(function(t){ return t.id === args.id; }); - } else { - targets = $$.data.targets; - } - data = $$.filterByX(targets, args.x).slice(0,1)[0]; - } - mouse = data ? $$.getMousePosition(data) : null; + // determine mouse position on the chart + if (args.mouse) { + mouse = args.mouse; + } else { + // determine focus data + if (args.data) { + data = args.data; + } else if (typeof args.x !== 'undefined') { + if (args.id) { + targets = $$.data.targets.filter(function(t) { + return t.id === args.id + }); + } else { + targets = $$.data.targets; + } + data = $$.filterByX(targets, args.x).slice(0, 1)[0]; } + mouse = data ? $$.getMousePosition(data) : null; + } - // emulate mouse events to show - $$.dispatchEvent('mousemove', mouse); - - $$.config.tooltip_onshow.call($$, data); -}; -Chart.prototype.tooltip.hide = function () { - // TODO: get target data by checking the state of focus - this.internal.dispatchEvent('mouseout', 0); + // emulate mouse events to show + $$.dispatchEvent('mousemove', mouse); - this.internal.config.tooltip_onhide.call(this); + $$.config.tooltip_onshow.call($$, data); }; +Chart.prototype.tooltip.hide = function() { + // TODO: get target data by checking the state of focus + this.internal.dispatchEvent('mouseout', 0); -Chart.prototype.transform = function (type, targetIds) { - var $$ = this.internal, - options = ['pie', 'donut'].indexOf(type) >= 0 ? {withTransform: true} : null; - $$.transformTo(targetIds, type, options); + this.internal.config.tooltip_onhide.call(this); }; -ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) { - var $$ = this, - withTransitionForAxis = !$$.hasArcType(), - options = optionsForRedraw || {withTransitionForAxis: withTransitionForAxis}; - options.withTransitionForTransform = false; - $$.transiting = false; - $$.setTargetType(targetIds, type); - $$.updateTargets($$.data.targets); // this is needed when transforming to arc - $$.updateAndRedraw(options); +Chart.prototype.transform = function(type, targetIds) { + var $$ = this.internal, + options = + ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null; + $$.transformTo(targetIds, type, options); }; -Chart.prototype.x = function (x) { - var $$ = this.internal; - if (arguments.length) { - $$.updateTargetX($$.data.targets, x); - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); - } - return $$.data.xs; +ChartInternal.prototype.transformTo = function( + targetIds, + type, + optionsForRedraw +) { + var $$ = this, + withTransitionForAxis = !$$.hasArcType(), + options = optionsForRedraw || { + withTransitionForAxis: withTransitionForAxis + }; + options.withTransitionForTransform = false; + $$.transiting = false; + $$.setTargetType(targetIds, type); + $$.updateTargets($$.data.targets); // this is needed when transforming to arc + $$.updateAndRedraw(options); +}; + +Chart.prototype.x = function(x) { + var $$ = this.internal; + if (arguments.length) { + $$.updateTargetX($$.data.targets, x); + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } + return $$.data.xs }; -Chart.prototype.xs = function (xs) { - var $$ = this.internal; - if (arguments.length) { - $$.updateTargetXs($$.data.targets, xs); - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true}); - } - return $$.data.xs; +Chart.prototype.xs = function(xs) { + var $$ = this.internal; + if (arguments.length) { + $$.updateTargetXs($$.data.targets, xs); + $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true }); + } + return $$.data.xs }; -Chart.prototype.zoom = function (domain) { - var $$ = this.internal; - if (domain) { - if ($$.isTimeSeries()) { - domain = domain.map(function (x) { return $$.parseDate(x); }); - } - if ($$.config.subchart_show) { - $$.brush.selectionAsValue(domain, true); - } - else { - $$.updateXDomain(null, true, false, false, domain); - $$.redraw({withY: $$.config.zoom_rescale, withSubchart: false}); - } - $$.config.zoom_onzoom.call(this, $$.x.orgDomain()); - return domain; +Chart.prototype.zoom = function(domain) { + var $$ = this.internal; + if (domain) { + if ($$.isTimeSeries()) { + domain = domain.map(function(x) { + return $$.parseDate(x) + }); + } + if ($$.config.subchart_show) { + $$.brush.selectionAsValue(domain, true); } else { - return $$.x.domain(); + $$.updateXDomain(null, true, false, false, domain); + $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false }); } + $$.config.zoom_onzoom.call(this, $$.x.orgDomain()); + return domain + } else { + return $$.x.domain() + } }; -Chart.prototype.zoom.enable = function (enabled) { - var $$ = this.internal; - $$.config.zoom_enabled = enabled; - $$.updateAndRedraw(); +Chart.prototype.zoom.enable = function(enabled) { + var $$ = this.internal; + $$.config.zoom_enabled = enabled; + $$.updateAndRedraw(); +}; +Chart.prototype.unzoom = function() { + var $$ = this.internal; + if ($$.config.subchart_show) { + $$.brush.clear(); + } else { + $$.updateXDomain(null, true, false, false, $$.subX.domain()); + $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false }); + } }; -Chart.prototype.unzoom = function () { - var $$ = this.internal; - if ($$.config.subchart_show) { - $$.brush.clear(); - } - else { - $$.updateXDomain(null, true, false, false, $$.subX.domain()); - $$.redraw({withY: $$.config.zoom_rescale, withSubchart: false}); - } + +Chart.prototype.zoom.max = function(max) { + var $$ = this.internal, + config = $$.config, + d3 = $$.d3; + if (max === 0 || max) { + config.zoom_x_max = d3.max([$$.orgXDomain[1], max]); + } else { + return config.zoom_x_max + } }; -Chart.prototype.zoom.max = function (max) { - var $$ = this.internal, config = $$.config, d3 = $$.d3; - if (max === 0 || max) { - config.zoom_x_max = d3.max([$$.orgXDomain[1], max]); - } - else { - return config.zoom_x_max; - } +Chart.prototype.zoom.min = function(min) { + var $$ = this.internal, + config = $$.config, + d3 = $$.d3; + if (min === 0 || min) { + config.zoom_x_min = d3.min([$$.orgXDomain[0], min]); + } else { + return config.zoom_x_min + } }; -Chart.prototype.zoom.min = function (min) { - var $$ = this.internal, config = $$.config, d3 = $$.d3; - if (min === 0 || min) { - config.zoom_x_min = d3.min([$$.orgXDomain[0], min]); +Chart.prototype.zoom.range = function(range) { + if (arguments.length) { + if (isDefined(range.max)) { + this.domain.max(range.max); } - else { - return config.zoom_x_min; + if (isDefined(range.min)) { + this.domain.min(range.min); } -}; - -Chart.prototype.zoom.range = function (range) { - if (arguments.length) { - if (isDefined(range.max)) { this.domain.max(range.max); } - if (isDefined(range.min)) { this.domain.min(range.min); } - } else { - return { - max: this.domain.max(), - min: this.domain.min() - }; + } else { + return { + max: this.domain.max(), + min: this.domain.min() } + } }; -ChartInternal.prototype.initPie = function () { - var $$ = this, d3 = $$.d3; - $$.pie = d3.pie().padAngle(this.getPadAngle.bind(this)).value(function (d) { - return d.values.reduce(function (a, b) { return a + b.value; }, 0); +ChartInternal.prototype.initPie = function() { + var $$ = this, + d3 = $$.d3; + $$.pie = d3 + .pie() + .padAngle(this.getPadAngle.bind(this)) + .value(function(d) { + return d.values.reduce(function(a, b) { + return a + b.value + }, 0) }); - let orderFct = $$.getOrderFunction(); - - // we need to reverse the returned order if asc or desc to have the slice in expected order. - if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) { - let defaultSort = orderFct; - orderFct = (t1, t2) => defaultSort(t1, t2) * -1; - } + let orderFct = $$.getOrderFunction(); - $$.pie.sort(orderFct || null); -}; + // we need to reverse the returned order if asc or desc to have the slice in expected order. + if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) { + let defaultSort = orderFct; + orderFct = (t1, t2) => defaultSort(t1, t2) * -1; + } -ChartInternal.prototype.updateRadius = function () { - var $$ = this, config = $$.config, - w = config.gauge_width || config.donut_width, - gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth; - $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1); - $$.radius = $$.radiusExpanded * 0.95; - $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6; - $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0; - $$.gaugeArcWidth = w ? w : (gaugeArcWidth <= $$.radius - $$.innerRadius ? $$.radius - $$.innerRadius : (gaugeArcWidth <= $$.radius ? gaugeArcWidth : $$.radius)); + $$.pie.sort(orderFct || null); +}; + +ChartInternal.prototype.updateRadius = function() { + var $$ = this, + config = $$.config, + w = config.gauge_width || config.donut_width, + gaugeArcWidth = + $$.filterTargetsToShow($$.data.targets).length * + $$.config.gauge_arcs_minWidth; + $$.radiusExpanded = + (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1); + $$.radius = $$.radiusExpanded * 0.95; + $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6; + $$.innerRadius = + $$.hasType('donut') || $$.hasType('gauge') + ? $$.radius * $$.innerRadiusRatio + : 0; + $$.gaugeArcWidth = w + ? w + : gaugeArcWidth <= $$.radius - $$.innerRadius + ? $$.radius - $$.innerRadius + : gaugeArcWidth <= $$.radius + ? gaugeArcWidth + : $$.radius; }; ChartInternal.prototype.getPadAngle = function() { - if (this.hasType('pie')) { - return this.config.pie_padAngle || 0; - } else if (this.hasType('donut')) { - return this.config.donut_padAngle || 0; - } else { - return 0; - } + if (this.hasType('pie')) { + return this.config.pie_padAngle || 0 + } else if (this.hasType('donut')) { + return this.config.donut_padAngle || 0 + } else { + return 0 + } }; -ChartInternal.prototype.updateArc = function () { - var $$ = this; - $$.svgArc = $$.getSvgArc(); - $$.svgArcExpanded = $$.getSvgArcExpanded(); - $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98); +ChartInternal.prototype.updateArc = function() { + var $$ = this; + $$.svgArc = $$.getSvgArc(); + $$.svgArcExpanded = $$.getSvgArcExpanded(); + $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98); }; -ChartInternal.prototype.updateAngle = function (d) { - var $$ = this, config = $$.config, - found = false, index = 0, - gMin, gMax, gTic, gValue; +ChartInternal.prototype.updateAngle = function(d) { + var $$ = this, + config = $$.config, + found = false, + index = 0, + gMin, + gMax, + gTic, + gValue; - if (!config) { - return null; - } + if (!config) { + return null + } - $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) { - if (! found && t.data.id === d.data.id) { - found = true; - d = t; - d.index = index; - } - index++; - }); - if (isNaN(d.startAngle)) { - d.startAngle = 0; - } - if (isNaN(d.endAngle)) { - d.endAngle = d.startAngle; - } - if ($$.isGaugeType(d.data)) { - gMin = config.gauge_min; - gMax = config.gauge_max; - gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin); - gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : (gMax - gMin); - d.startAngle = config.gauge_startingAngle; - d.endAngle = d.startAngle + gTic * gValue; - } - return found ? d : null; -}; - -ChartInternal.prototype.getSvgArc = function () { - var $$ = this, hasGaugeType = $$.hasType('gauge'), - singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, - arc = $$.d3.arc().outerRadius(function(d) { - return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius; - }).innerRadius(function(d) { - return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius; - }), - newArc = function (d, withoutUpdate) { - var updated; - if (withoutUpdate) { return arc(d); } // for interpolate - updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; - }; - // TODO: extends all function - newArc.centroid = arc.centroid; - return newArc; -}; - -ChartInternal.prototype.getSvgArcExpanded = function (rate) { - rate = rate || 1; - var $$ = this, hasGaugeType = $$.hasType('gauge'), - singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, - expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100), - arc = $$.d3.arc().outerRadius(function(d){ - return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate; - }).innerRadius(function(d){ - return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius; - }); - return function (d) { - var updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; + $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function(t) { + if (!found && t.data.id === d.data.id) { + found = true; + d = t; + d.index = index; + } + index++; + }); + if (isNaN(d.startAngle)) { + d.startAngle = 0; + } + if (isNaN(d.endAngle)) { + d.endAngle = d.startAngle; + } + if ($$.isGaugeType(d.data)) { + gMin = config.gauge_min; + gMax = config.gauge_max; + gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin); + gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin; + d.startAngle = config.gauge_startingAngle; + d.endAngle = d.startAngle + gTic * gValue; + } + return found ? d : null +}; + +ChartInternal.prototype.getSvgArc = function() { + var $$ = this, + hasGaugeType = $$.hasType('gauge'), + singleArcWidth = + $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, + arc = $$.d3 + .arc() + .outerRadius(function(d) { + return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius + }) + .innerRadius(function(d) { + return hasGaugeType + ? $$.radius - singleArcWidth * (d.index + 1) + : $$.innerRadius + }), + newArc = function(d, withoutUpdate) { + var updated; + if (withoutUpdate) { + return arc(d) + } // for interpolate + updated = $$.updateAngle(d); + return updated ? arc(updated) : 'M 0 0' }; + // TODO: extends all function + newArc.centroid = arc.centroid; + return newArc +}; + +ChartInternal.prototype.getSvgArcExpanded = function(rate) { + rate = rate || 1; + var $$ = this, + hasGaugeType = $$.hasType('gauge'), + singleArcWidth = + $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, + expandWidth = Math.min( + $$.radiusExpanded * rate - $$.radius, + singleArcWidth * 0.8 - (1 - rate) * 100 + ), + arc = $$.d3 + .arc() + .outerRadius(function(d) { + return hasGaugeType + ? $$.radius - singleArcWidth * d.index + expandWidth + : $$.radiusExpanded * rate + }) + .innerRadius(function(d) { + return hasGaugeType + ? $$.radius - singleArcWidth * (d.index + 1) + : $$.innerRadius + }); + return function(d) { + var updated = $$.updateAngle(d); + return updated ? arc(updated) : 'M 0 0' + } }; -ChartInternal.prototype.getArc = function (d, withoutUpdate, force) { - return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0"; -}; - - -ChartInternal.prototype.transformForArcLabel = function (d) { - var $$ = this, config = $$.config, - updated = $$.updateAngle(d), c, x, y, h, ratio, translate = "", hasGauge = $$.hasType('gauge'); - if (updated && !hasGauge) { - c = this.svgArc.centroid(updated); - x = isNaN(c[0]) ? 0 : c[0]; - y = isNaN(c[1]) ? 0 : c[1]; - h = Math.sqrt(x * x + y * y); - if ($$.hasType('donut') && config.donut_label_ratio) { - ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio; - } else if ($$.hasType('pie') && config.pie_label_ratio) { - ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio; - } else { - ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0; - } - translate = "translate(" + (x * ratio) + ',' + (y * ratio) + ")"; - } - else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) { - var y1 = Math.sin(updated.endAngle - Math.PI / 2); - x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); - y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; - translate = "translate(" + x + ',' + y + ")"; - } - return translate; +ChartInternal.prototype.getArc = function(d, withoutUpdate, force) { + return force || this.isArcType(d.data) + ? this.svgArc(d, withoutUpdate) + : 'M 0 0' +}; + +ChartInternal.prototype.transformForArcLabel = function(d) { + var $$ = this, + config = $$.config, + updated = $$.updateAngle(d), + c, + x, + y, + h, + ratio, + translate = '', + hasGauge = $$.hasType('gauge'); + if (updated && !hasGauge) { + c = this.svgArc.centroid(updated); + x = isNaN(c[0]) ? 0 : c[0]; + y = isNaN(c[1]) ? 0 : c[1]; + h = Math.sqrt(x * x + y * y); + if ($$.hasType('donut') && config.donut_label_ratio) { + ratio = isFunction(config.donut_label_ratio) + ? config.donut_label_ratio(d, $$.radius, h) + : config.donut_label_ratio; + } else if ($$.hasType('pie') && config.pie_label_ratio) { + ratio = isFunction(config.pie_label_ratio) + ? config.pie_label_ratio(d, $$.radius, h) + : config.pie_label_ratio; + } else { + ratio = + $$.radius && h + ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * + $$.radius) / + h + : 0; + } + translate = 'translate(' + x * ratio + ',' + y * ratio + ')'; + } else if ( + updated && + hasGauge && + $$.filterTargetsToShow($$.data.targets).length > 1 + ) { + var y1 = Math.sin(updated.endAngle - Math.PI / 2); + x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); + y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; + translate = 'translate(' + x + ',' + y + ')'; + } + return translate }; /** * @deprecated Use `getRatio('arc', d)` instead. */ -ChartInternal.prototype.getArcRatio = function (d) { - return this.getRatio('arc', d); -}; - -ChartInternal.prototype.convertToArcData = function (d) { - return this.addName({ - id: d.data.id, - value: d.value, - ratio: this.getRatio('arc', d), - index: d.index - }); -}; - -ChartInternal.prototype.textForArcLabel = function (d) { - var $$ = this, - updated, value, ratio, id, format; - if (! $$.shouldShowArcLabel()) { return ""; } - updated = $$.updateAngle(d); - value = updated ? updated.value : null; - ratio = $$.getRatio('arc', updated); - id = d.data.id; - if (! $$.hasType('gauge') && ! $$.meetsArcLabelThreshold(ratio)) { return ""; } - format = $$.getArcLabelFormat(); - return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio); +ChartInternal.prototype.getArcRatio = function(d) { + return this.getRatio('arc', d) +}; + +ChartInternal.prototype.convertToArcData = function(d) { + return this.addName({ + id: d.data.id, + value: d.value, + ratio: this.getRatio('arc', d), + index: d.index + }) +}; + +ChartInternal.prototype.textForArcLabel = function(d) { + var $$ = this, + updated, + value, + ratio, + id, + format; + if (!$$.shouldShowArcLabel()) { + return '' + } + updated = $$.updateAngle(d); + value = updated ? updated.value : null; + ratio = $$.getRatio('arc', updated); + id = d.data.id; + if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) { + return '' + } + format = $$.getArcLabelFormat(); + return format + ? format(value, ratio, id) + : $$.defaultArcValueFormat(value, ratio) }; -ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) { - var $$ = this, - format = $$.getGaugeLabelExtents(); +ChartInternal.prototype.textForGaugeMinMax = function(value, isMax) { + var $$ = this, + format = $$.getGaugeLabelExtents(); - return format ? format(value, isMax) : value; + return format ? format(value, isMax) : value }; -ChartInternal.prototype.expandArc = function (targetIds) { - var $$ = this, interval; - - // MEMO: avoid to cancel transition - if ($$.transiting) { - interval = window.setInterval(function () { - if (!$$.transiting) { - window.clearInterval(interval); - if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) { - $$.expandArc(targetIds); - } - } - }, 10); - return; - } +ChartInternal.prototype.expandArc = function(targetIds) { + var $$ = this, + interval; - targetIds = $$.mapToTargetIds(targetIds); + // MEMO: avoid to cancel transition + if ($$.transiting) { + interval = window.setInterval(function() { + if (!$$.transiting) { + window.clearInterval(interval); + if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) { + $$.expandArc(targetIds); + } + } + }, 10); + return + } - $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) { - if (! $$.shouldExpand(d.data.id)) { return; } - $$.d3.select(this).selectAll('path') - .transition().duration($$.expandDuration(d.data.id)) - .attr("d", $$.svgArcExpanded) - .transition().duration($$.expandDuration(d.data.id) * 2) - .attr("d", $$.svgArcExpandedSub) - .each(function (d) { - if ($$.isDonutType(d.data)) ; - }); + targetIds = $$.mapToTargetIds(targetIds); + + $$.svg + .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)) + .each(function(d) { + if (!$$.shouldExpand(d.data.id)) { + return + } + $$.d3 + .select(this) + .selectAll('path') + .transition() + .duration($$.expandDuration(d.data.id)) + .attr('d', $$.svgArcExpanded) + .transition() + .duration($$.expandDuration(d.data.id) * 2) + .attr('d', $$.svgArcExpandedSub) + .each(function(d) { + if ($$.isDonutType(d.data)) ; + }); }); }; -ChartInternal.prototype.unexpandArc = function (targetIds) { - var $$ = this; +ChartInternal.prototype.unexpandArc = function(targetIds) { + var $$ = this; - if ($$.transiting) { return; } - - targetIds = $$.mapToTargetIds(targetIds); + if ($$.transiting) { + return + } - $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path') - .transition().duration(function(d) { - return $$.expandDuration(d.data.id); - }) - .attr("d", $$.svgArc); - $$.svg.selectAll('.' + CLASS.arc); + targetIds = $$.mapToTargetIds(targetIds); + + $$.svg + .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)) + .selectAll('path') + .transition() + .duration(function(d) { + return $$.expandDuration(d.data.id) + }) + .attr('d', $$.svgArc); + $$.svg.selectAll('.' + CLASS.arc); +}; + +ChartInternal.prototype.expandDuration = function(id) { + var $$ = this, + config = $$.config; + + if ($$.isDonutType(id)) { + return config.donut_expand_duration + } else if ($$.isGaugeType(id)) { + return config.gauge_expand_duration + } else if ($$.isPieType(id)) { + return config.pie_expand_duration + } else { + return 50 + } }; -ChartInternal.prototype.expandDuration = function (id) { - var $$ = this, config = $$.config; - - if ($$.isDonutType(id)) { - return config.donut_expand_duration; - } else if ($$.isGaugeType(id)) { - return config.gauge_expand_duration; - } else if ($$.isPieType(id)) { - return config.pie_expand_duration; +ChartInternal.prototype.shouldExpand = function(id) { + var $$ = this, + config = $$.config; + return ( + ($$.isDonutType(id) && config.donut_expand) || + ($$.isGaugeType(id) && config.gauge_expand) || + ($$.isPieType(id) && config.pie_expand) + ) +}; + +ChartInternal.prototype.shouldShowArcLabel = function() { + var $$ = this, + config = $$.config, + shouldShow = true; + if ($$.hasType('donut')) { + shouldShow = config.donut_label_show; + } else if ($$.hasType('pie')) { + shouldShow = config.pie_label_show; + } + // when gauge, always true + return shouldShow +}; + +ChartInternal.prototype.meetsArcLabelThreshold = function(ratio) { + var $$ = this, + config = $$.config, + threshold = $$.hasType('donut') + ? config.donut_label_threshold + : config.pie_label_threshold; + return ratio >= threshold +}; + +ChartInternal.prototype.getArcLabelFormat = function() { + var $$ = this, + config = $$.config, + format = config.pie_label_format; + if ($$.hasType('gauge')) { + format = config.gauge_label_format; + } else if ($$.hasType('donut')) { + format = config.donut_label_format; + } + return format +}; + +ChartInternal.prototype.getGaugeLabelExtents = function() { + var $$ = this, + config = $$.config; + return config.gauge_label_extents +}; + +ChartInternal.prototype.getArcTitle = function() { + var $$ = this; + return $$.hasType('donut') ? $$.config.donut_title : '' +}; + +ChartInternal.prototype.updateTargetsForArc = function(targets) { + var $$ = this, + main = $$.main, + mainPies, + mainPieEnter, + classChartArc = $$.classChartArc.bind($$), + classArcs = $$.classArcs.bind($$), + classFocus = $$.classFocus.bind($$); + mainPies = main + .select('.' + CLASS.chartArcs) + .selectAll('.' + CLASS.chartArc) + .data($$.pie(targets)) + .attr('class', function(d) { + return classChartArc(d) + classFocus(d.data) + }); + mainPieEnter = mainPies + .enter() + .append('g') + .attr('class', classChartArc); + mainPieEnter.append('g').attr('class', classArcs); + mainPieEnter + .append('text') + .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em') + .style('opacity', 0) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + // MEMO: can not keep same color..., but not bad to update color in redraw + //mainPieUpdate.exit().remove(); +}; + +ChartInternal.prototype.initArc = function() { + var $$ = this; + $$.arcs = $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartArcs) + .attr('transform', $$.getTranslate('arc')); + $$.arcs + .append('text') + .attr('class', CLASS.chartArcsTitle) + .style('text-anchor', 'middle') + .text($$.getArcTitle()); +}; + +ChartInternal.prototype.redrawArc = function( + duration, + durationForExit, + withTransform +) { + var $$ = this, + d3 = $$.d3, + config = $$.config, + main = $$.main, + arcs, + mainArc, + arcLabelLines, + mainArcLabelLine, + hasGaugeType = $$.hasType('gauge'); + arcs = main + .selectAll('.' + CLASS.arcs) + .selectAll('.' + CLASS.arc) + .data($$.arcData.bind($$)); + mainArc = arcs + .enter() + .append('path') + .attr('class', $$.classArc.bind($$)) + .style('fill', function(d) { + return $$.color(d.data) + }) + .style('cursor', function(d) { + return config.interaction_enabled && config.data_selection_isselectable(d) + ? 'pointer' + : null + }) + .each(function(d) { + if ($$.isGaugeType(d.data)) { + d.startAngle = d.endAngle = config.gauge_startingAngle; + } + this._current = d; + }) + .merge(arcs); + if (hasGaugeType) { + arcLabelLines = main + .selectAll('.' + CLASS.arcs) + .selectAll('.' + CLASS.arcLabelLine) + .data($$.arcData.bind($$)); + mainArcLabelLine = arcLabelLines + .enter() + .append('rect') + .attr('class', function(d) { + return ( + CLASS.arcLabelLine + + ' ' + + CLASS.target + + ' ' + + CLASS.target + + '-' + + d.data.id + ) + }) + .merge(arcLabelLines); + + if ($$.filterTargetsToShow($$.data.targets).length === 1) { + mainArcLabelLine.style('display', 'none'); } else { - return 50; - } - -}; - -ChartInternal.prototype.shouldExpand = function (id) { - var $$ = this, config = $$.config; - return ($$.isDonutType(id) && config.donut_expand) || - ($$.isGaugeType(id) && config.gauge_expand) || - ($$.isPieType(id) && config.pie_expand); -}; - -ChartInternal.prototype.shouldShowArcLabel = function () { - var $$ = this, config = $$.config, shouldShow = true; - if ($$.hasType('donut')) { - shouldShow = config.donut_label_show; - } else if ($$.hasType('pie')) { - shouldShow = config.pie_label_show; - } - // when gauge, always true - return shouldShow; -}; - -ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) { - var $$ = this, config = $$.config, - threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold; - return ratio >= threshold; -}; - -ChartInternal.prototype.getArcLabelFormat = function () { - var $$ = this, config = $$.config, - format = config.pie_label_format; - if ($$.hasType('gauge')) { - format = config.gauge_label_format; - } else if ($$.hasType('donut')) { - format = config.donut_label_format; - } - return format; -}; - -ChartInternal.prototype.getGaugeLabelExtents = function () { - var $$ = this, config = $$.config; - return config.gauge_label_extents; -}; - -ChartInternal.prototype.getArcTitle = function () { - var $$ = this; - return $$.hasType('donut') ? $$.config.donut_title : ""; -}; - -ChartInternal.prototype.updateTargetsForArc = function (targets) { - var $$ = this, main = $$.main, - mainPies, mainPieEnter, - classChartArc = $$.classChartArc.bind($$), - classArcs = $$.classArcs.bind($$), - classFocus = $$.classFocus.bind($$); - mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc) - .data($$.pie(targets)) - .attr("class", function (d) { return classChartArc(d) + classFocus(d.data); }); - mainPieEnter = mainPies.enter().append("g") - .attr("class", classChartArc); - mainPieEnter.append('g') - .attr('class', classArcs); - mainPieEnter.append("text") - .attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em") - .style("opacity", 0) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - // MEMO: can not keep same color..., but not bad to update color in redraw - //mainPieUpdate.exit().remove(); -}; - -ChartInternal.prototype.initArc = function () { - var $$ = this; - $$.arcs = $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartArcs) - .attr("transform", $$.getTranslate('arc')); - $$.arcs.append('text') - .attr('class', CLASS.chartArcsTitle) - .style("text-anchor", "middle") - .text($$.getArcTitle()); -}; - -ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) { - var $$ = this, d3 = $$.d3, config = $$.config, main = $$.main, - arcs, mainArc, - arcLabelLines, mainArcLabelLine, - hasGaugeType = $$.hasType('gauge'); - arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc) - .data($$.arcData.bind($$)); - mainArc = arcs.enter().append('path') - .attr("class", $$.classArc.bind($$)) - .style("fill", function (d) { return $$.color(d.data); }) - .style("cursor", function (d) { return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null; }) - .each(function (d) { - if ($$.isGaugeType(d.data)) { - d.startAngle = d.endAngle = config.gauge_startingAngle; - } - this._current = d; + mainArcLabelLine + .style('fill', function(d) { + return $$.levelColor + ? $$.levelColor( + d.data.values.reduce(function(total, item) { + return total + item.value + }, 0) + ) + : $$.color(d.data) }) - .merge(arcs); - if (hasGaugeType) { - arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine) - .data($$.arcData.bind($$)); - mainArcLabelLine = arcLabelLines.enter().append('rect') - .attr("class", function (d) { return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id; }) - .merge(arcLabelLines); - - if ($$.filterTargetsToShow($$.data.targets).length === 1) { - mainArcLabelLine.style("display", "none"); - } - else { - mainArcLabelLine - .style("fill", function (d) { - return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data); - }) - .style("display", config.gauge_labelLine_show ? "" : "none") - .each(function (d) { - var lineLength = 0, lineThickness = 2, x = 0, y = 0, transform = ""; - if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { - var updated = $$.updateAngle(d), - innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1), - lineAngle = updated.endAngle - Math.PI / 2, - arcInnerRadius = $$.radius - innerLineLength, - linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : (1 / arcInnerRadius)); - lineLength = $$.radiusExpanded - $$.radius + innerLineLength; - x = Math.cos(linePositioningAngle) * arcInnerRadius; - y = Math.sin(linePositioningAngle) * arcInnerRadius; - transform = "rotate(" + (lineAngle * 180 / Math.PI) + ", " + x + ", " + y + ")"; - } - d3.select(this) - .attr('x', x) - .attr('y', y) - .attr('width', lineLength) - .attr('height', lineThickness) - .attr('transform', transform) - .style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0"); - }); - } + .style('display', config.gauge_labelLine_show ? '' : 'none') + .each(function(d) { + var lineLength = 0, + lineThickness = 2, + x = 0, + y = 0, + transform = ''; + if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { + var updated = $$.updateAngle(d), + innerLineLength = + ($$.gaugeArcWidth / + $$.filterTargetsToShow($$.data.targets).length) * + (updated.index + 1), + lineAngle = updated.endAngle - Math.PI / 2, + arcInnerRadius = $$.radius - innerLineLength, + linePositioningAngle = + lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius); + lineLength = $$.radiusExpanded - $$.radius + innerLineLength; + x = Math.cos(linePositioningAngle) * arcInnerRadius; + y = Math.sin(linePositioningAngle) * arcInnerRadius; + transform = + 'rotate(' + + (lineAngle * 180) / Math.PI + + ', ' + + x + + ', ' + + y + + ')'; + } + d3.select(this) + .attr('x', x) + .attr('y', y) + .attr('width', lineLength) + .attr('height', lineThickness) + .attr('transform', transform) + .style( + 'stroke-dasharray', + '0, ' + (lineLength + lineThickness) + ', 0' + ); + }); } - mainArc - .attr("transform", function (d) { return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : ""; }) - .on('mouseover', config.interaction_enabled ? function (d) { + } + mainArc + .attr('transform', function(d) { + return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : '' + }) + .on( + 'mouseover', + config.interaction_enabled + ? function(d) { var updated, arcData; - if ($$.transiting) { // skip while transiting - return; + if ($$.transiting) { + // skip while transiting + return } updated = $$.updateAngle(d); if (updated) { - arcData = $$.convertToArcData(updated); - // transitions - $$.expandArc(updated.data.id); - $$.api.focus(updated.data.id); - $$.toggleFocusLegend(updated.data.id, true); - $$.config.data_onmouseover(arcData, this); + arcData = $$.convertToArcData(updated); + // transitions + $$.expandArc(updated.data.id); + $$.api.focus(updated.data.id); + $$.toggleFocusLegend(updated.data.id, true); + $$.config.data_onmouseover(arcData, this); } - } : null) - .on('mousemove', config.interaction_enabled ? function (d) { - var updated = $$.updateAngle(d), arcData, selectedData; + } + : null + ) + .on( + 'mousemove', + config.interaction_enabled + ? function(d) { + var updated = $$.updateAngle(d), + arcData, + selectedData; if (updated) { - arcData = $$.convertToArcData(updated), - selectedData = [arcData]; - $$.showTooltip(selectedData, this); +(arcData = $$.convertToArcData(updated)), + (selectedData = [arcData]); + $$.showTooltip(selectedData, this); } - } : null) - .on('mouseout', config.interaction_enabled ? function (d) { + } + : null + ) + .on( + 'mouseout', + config.interaction_enabled + ? function(d) { var updated, arcData; - if ($$.transiting) { // skip while transiting - return; + if ($$.transiting) { + // skip while transiting + return } updated = $$.updateAngle(d); if (updated) { - arcData = $$.convertToArcData(updated); - // transitions - $$.unexpandArc(updated.data.id); - $$.api.revert(); - $$.revertLegend(); - $$.hideTooltip(); - $$.config.data_onmouseout(arcData, this); + arcData = $$.convertToArcData(updated); + // transitions + $$.unexpandArc(updated.data.id); + $$.api.revert(); + $$.revertLegend(); + $$.hideTooltip(); + $$.config.data_onmouseout(arcData, this); } - } : null) - .on('click', config.interaction_enabled ? function (d, i) { - var updated = $$.updateAngle(d), arcData; + } + : null + ) + .on( + 'click', + config.interaction_enabled + ? function(d, i) { + var updated = $$.updateAngle(d), + arcData; if (updated) { - arcData = $$.convertToArcData(updated); - if ($$.toggleShape) { - $$.toggleShape(this, arcData, i); - } - $$.config.data_onclick.call($$.api, arcData, this); - } - } : null) - .each(function () { $$.transiting = true; }) - .transition().duration(duration) - .attrTween("d", function (d) { - var updated = $$.updateAngle(d), interpolate; - if (! updated) { - return function () { return "M 0 0"; }; - } - // if (this._current === d) { - // this._current = { - // startAngle: Math.PI*2, - // endAngle: Math.PI*2, - // }; - // } - if (isNaN(this._current.startAngle)) { - this._current.startAngle = 0; - } - if (isNaN(this._current.endAngle)) { - this._current.endAngle = this._current.startAngle; + arcData = $$.convertToArcData(updated); + if ($$.toggleShape) { + $$.toggleShape(this, arcData, i); + } + $$.config.data_onclick.call($$.api, arcData, this); } - interpolate = d3.interpolate(this._current, updated); - this._current = interpolate(0); - return function (t) { - // prevents crashing the charts once in transition and chart.destroy() has been called - if ($$.config === null) { - return "M 0 0"; - } - var interpolated = interpolate(t); - interpolated.data = d.data; // data.id will be updated by interporator - return $$.getArc(interpolated, true); - }; - }) - .attr("transform", withTransform ? "scale(1)" : "") - .style("fill", function (d) { - return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data.id); - }) // Where gauge reading color would receive customization. - .call($$.endall, function () { - $$.transiting = false; - }); - arcs.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - main.selectAll('.' + CLASS.chartArc).select('text') - .style("opacity", 0) - .attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; }) - .text($$.textForArcLabel.bind($$)) - .attr("transform", $$.transformForArcLabel.bind($$)) - .style('font-size', function (d) { return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : ''; }) - .transition().duration(duration) - .style("opacity", function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; }); - main.select('.' + CLASS.chartArcsTitle) - .style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0); - - if (hasGaugeType) { - let index = 0; - const backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets); - - backgroundArc - .enter() - .append("path") - .attr("class", (d, i) => CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground +'-'+ i) - .merge(backgroundArc) - .attr("d", d1 => { - if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { return "M 0 0"; } - - var d = { - data: [{value: config.gauge_max}], - startAngle: config.gauge_startingAngle, - endAngle: -1 * config.gauge_startingAngle * (config.gauge_fullCircle ? Math.PI : 1), - index: index++ - }; - return $$.getArc(d, true, true); - }); - - backgroundArc - .exit() - .remove(); - - $$.arcs.select('.' + CLASS.chartArcsGaugeUnit) - .attr("dy", ".75em") - .text(config.gauge_label_show ? config.gauge_units : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMin) - .attr("dx", -1 * ($$.innerRadius + (($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2))) + "px") - .attr("dy", "1.2em") - .text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMax) - .attr("dx", $$.innerRadius + (($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px") - .attr("dy", "1.2em") - .text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); - } -}; -ChartInternal.prototype.initGauge = function () { - var arcs = this.arcs; - if (this.hasType('gauge')) { - arcs.append('g') - .attr("class", CLASS.chartArcsBackground); - arcs.append("text") - .attr("class", CLASS.chartArcsGaugeUnit) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - arcs.append("text") - .attr("class", CLASS.chartArcsGaugeMin) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - arcs.append("text") - .attr("class", CLASS.chartArcsGaugeMax) - .style("text-anchor", "middle") - .style("pointer-events", "none"); - } -}; -ChartInternal.prototype.getGaugeLabelHeight = function () { - return this.config.gauge_label_show ? 20 : 0; + } + : null + ) + .each(function() { + $$.transiting = true; + }) + .transition() + .duration(duration) + .attrTween('d', function(d) { + var updated = $$.updateAngle(d), + interpolate; + if (!updated) { + return function() { + return 'M 0 0' + } + } + // if (this._current === d) { + // this._current = { + // startAngle: Math.PI*2, + // endAngle: Math.PI*2, + // }; + // } + if (isNaN(this._current.startAngle)) { + this._current.startAngle = 0; + } + if (isNaN(this._current.endAngle)) { + this._current.endAngle = this._current.startAngle; + } + interpolate = d3.interpolate(this._current, updated); + this._current = interpolate(0); + return function(t) { + // prevents crashing the charts once in transition and chart.destroy() has been called + if ($$.config === null) { + return 'M 0 0' + } + var interpolated = interpolate(t); + interpolated.data = d.data; // data.id will be updated by interporator + return $$.getArc(interpolated, true) + } + }) + .attr('transform', withTransform ? 'scale(1)' : '') + .style('fill', function(d) { + return $$.levelColor + ? $$.levelColor( + d.data.values.reduce(function(total, item) { + return total + item.value + }, 0) + ) + : $$.color(d.data.id) + }) // Where gauge reading color would receive customization. + .call($$.endall, function() { + $$.transiting = false; + }); + arcs + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + main + .selectAll('.' + CLASS.chartArc) + .select('text') + .style('opacity', 0) + .attr('class', function(d) { + return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '' + }) + .text($$.textForArcLabel.bind($$)) + .attr('transform', $$.transformForArcLabel.bind($$)) + .style('font-size', function(d) { + return $$.isGaugeType(d.data) && + $$.filterTargetsToShow($$.data.targets).length === 1 + ? Math.round($$.radius / 5) + 'px' + : '' + }) + .transition() + .duration(duration) + .style('opacity', function(d) { + return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0 + }); + main + .select('.' + CLASS.chartArcsTitle) + .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0); + + if (hasGaugeType) { + let index = 0; + const backgroundArc = $$.arcs + .select('g.' + CLASS.chartArcsBackground) + .selectAll('path.' + CLASS.chartArcsBackground) + .data($$.data.targets); + + backgroundArc + .enter() + .append('path') + .attr( + 'class', + (d, i) => + CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i + ) + .merge(backgroundArc) + .attr('d', d1 => { + if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { + return 'M 0 0' + } + + var d = { + data: [{ value: config.gauge_max }], + startAngle: config.gauge_startingAngle, + endAngle: + -1 * + config.gauge_startingAngle * + (config.gauge_fullCircle ? Math.PI : 1), + index: index++ + }; + return $$.getArc(d, true, true) + }); + + backgroundArc.exit().remove(); + + $$.arcs + .select('.' + CLASS.chartArcsGaugeUnit) + .attr('dy', '.75em') + .text(config.gauge_label_show ? config.gauge_units : ''); + $$.arcs + .select('.' + CLASS.chartArcsGaugeMin) + .attr( + 'dx', + -1 * + ($$.innerRadius + + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + + 'px' + ) + .attr('dy', '1.2em') + .text( + config.gauge_label_show + ? $$.textForGaugeMinMax(config.gauge_min, false) + : '' + ); + $$.arcs + .select('.' + CLASS.chartArcsGaugeMax) + .attr( + 'dx', + $$.innerRadius + + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + + 'px' + ) + .attr('dy', '1.2em') + .text( + config.gauge_label_show + ? $$.textForGaugeMinMax(config.gauge_max, true) + : '' + ); + } +}; +ChartInternal.prototype.initGauge = function() { + var arcs = this.arcs; + if (this.hasType('gauge')) { + arcs.append('g').attr('class', CLASS.chartArcsBackground); + arcs + .append('text') + .attr('class', CLASS.chartArcsGaugeUnit) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + arcs + .append('text') + .attr('class', CLASS.chartArcsGaugeMin) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + arcs + .append('text') + .attr('class', CLASS.chartArcsGaugeMax) + .style('text-anchor', 'middle') + .style('pointer-events', 'none'); + } +}; +ChartInternal.prototype.getGaugeLabelHeight = function() { + return this.config.gauge_label_show ? 20 : 0 }; /** @@ -5484,8 +7096,8 @@ ChartInternal.prototype.getGaugeLabelHeight = function () { * @param key * @param value */ -ChartInternal.prototype.addToCache = function (key, value) { - this.cache[`$${key}`] = value; +ChartInternal.prototype.addToCache = function(key, value) { + this.cache[`$${key}`] = value; }; /** @@ -5494,614 +7106,688 @@ ChartInternal.prototype.addToCache = function (key, value) { * @param key * @return {*} */ -ChartInternal.prototype.getFromCache = function (key) { - return this.cache[`$${key}`]; +ChartInternal.prototype.getFromCache = function(key) { + return this.cache[`$${key}`] }; /** * Reset cached data */ ChartInternal.prototype.resetCache = function() { - Object.keys(this.cache) - .filter((key) => /^\$/.test(key)) - .forEach((key) => { - delete this.cache[key]; - }); + Object.keys(this.cache) + .filter(key => /^\$/.test(key)) + .forEach(key => { + delete this.cache[key]; + }); }; // Old API that stores Targets -ChartInternal.prototype.hasCaches = function (ids) { - for (var i = 0; i < ids.length; i++) { - if (! (ids[i] in this.cache)) { return false; } +ChartInternal.prototype.hasCaches = function(ids) { + for (var i = 0; i < ids.length; i++) { + if (!(ids[i] in this.cache)) { + return false } - return true; + } + return true }; -ChartInternal.prototype.addCache = function (id, target) { - this.cache[id] = this.cloneTarget(target); +ChartInternal.prototype.addCache = function(id, target) { + this.cache[id] = this.cloneTarget(target); }; -ChartInternal.prototype.getCaches = function (ids) { - var targets = [], i; - for (i = 0; i < ids.length; i++) { - if (ids[i] in this.cache) { targets.push(this.cloneTarget(this.cache[ids[i]])); } +ChartInternal.prototype.getCaches = function(ids) { + var targets = [], + i; + for (i = 0; i < ids.length; i++) { + if (ids[i] in this.cache) { + targets.push(this.cloneTarget(this.cache[ids[i]])); } - return targets; + } + return targets }; -ChartInternal.prototype.categoryName = function (i) { - var config = this.config; - return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i; +ChartInternal.prototype.categoryName = function(i) { + var config = this.config; + return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i }; -ChartInternal.prototype.generateTargetClass = function (targetId) { - return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : ''; -}; -ChartInternal.prototype.generateClass = function (prefix, targetId) { - return " " + prefix + " " + prefix + this.generateTargetClass(targetId); -}; -ChartInternal.prototype.classText = function (d) { - return this.generateClass(CLASS.text, d.index); -}; -ChartInternal.prototype.classTexts = function (d) { - return this.generateClass(CLASS.texts, d.id); -}; -ChartInternal.prototype.classShape = function (d) { - return this.generateClass(CLASS.shape, d.index); -}; -ChartInternal.prototype.classShapes = function (d) { - return this.generateClass(CLASS.shapes, d.id); -}; -ChartInternal.prototype.classLine = function (d) { - return this.classShape(d) + this.generateClass(CLASS.line, d.id); +ChartInternal.prototype.generateTargetClass = function(targetId) { + return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : '' }; -ChartInternal.prototype.classLines = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.lines, d.id); +ChartInternal.prototype.generateClass = function(prefix, targetId) { + return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId) }; -ChartInternal.prototype.classCircle = function (d) { - return this.classShape(d) + this.generateClass(CLASS.circle, d.index); +ChartInternal.prototype.classText = function(d) { + return this.generateClass(CLASS.text, d.index) }; -ChartInternal.prototype.classCircles = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.circles, d.id); +ChartInternal.prototype.classTexts = function(d) { + return this.generateClass(CLASS.texts, d.id) }; -ChartInternal.prototype.classBar = function (d) { - return this.classShape(d) + this.generateClass(CLASS.bar, d.index); +ChartInternal.prototype.classShape = function(d) { + return this.generateClass(CLASS.shape, d.index) }; -ChartInternal.prototype.classBars = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.bars, d.id); +ChartInternal.prototype.classShapes = function(d) { + return this.generateClass(CLASS.shapes, d.id) }; -ChartInternal.prototype.classArc = function (d) { - return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id); -}; -ChartInternal.prototype.classArcs = function (d) { - return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id); -}; -ChartInternal.prototype.classArea = function (d) { - return this.classShape(d) + this.generateClass(CLASS.area, d.id); -}; -ChartInternal.prototype.classAreas = function (d) { - return this.classShapes(d) + this.generateClass(CLASS.areas, d.id); -}; -ChartInternal.prototype.classRegion = function (d, i) { - return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : ''); -}; -ChartInternal.prototype.classEvent = function (d) { - return this.generateClass(CLASS.eventRect, d.index); -}; -ChartInternal.prototype.classTarget = function (id) { - var $$ = this; - var additionalClassSuffix = $$.config.data_classes[id], additionalClass = ''; - if (additionalClassSuffix) { - additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix; - } - return $$.generateClass(CLASS.target, id) + additionalClass; -}; -ChartInternal.prototype.classFocus = function (d) { - return this.classFocused(d) + this.classDefocused(d); -}; -ChartInternal.prototype.classFocused = function (d) { - return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : ''); -}; -ChartInternal.prototype.classDefocused = function (d) { - return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : ''); -}; -ChartInternal.prototype.classChartText = function (d) { - return CLASS.chartText + this.classTarget(d.id); -}; -ChartInternal.prototype.classChartLine = function (d) { - return CLASS.chartLine + this.classTarget(d.id); -}; -ChartInternal.prototype.classChartBar = function (d) { - return CLASS.chartBar + this.classTarget(d.id); -}; -ChartInternal.prototype.classChartArc = function (d) { - return CLASS.chartArc + this.classTarget(d.data.id); -}; -ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) { - const targetClass = this.generateTargetClass(targetId); - if (window.CSS && window.CSS.escape) { - return window.CSS.escape(targetClass); - } - - // fallback on imperfect method for old browsers (does not handles unicode) - return targetClass.replace(/([?!@#$%^&*()=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1'); +ChartInternal.prototype.classLine = function(d) { + return this.classShape(d) + this.generateClass(CLASS.line, d.id) }; -ChartInternal.prototype.selectorTarget = function (id, prefix) { - return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id); +ChartInternal.prototype.classLines = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.lines, d.id) }; -ChartInternal.prototype.selectorTargets = function (ids, prefix) { - var $$ = this; - ids = ids || []; - return ids.length ? ids.map(function (id) { return $$.selectorTarget(id, prefix); }) : null; +ChartInternal.prototype.classCircle = function(d) { + return this.classShape(d) + this.generateClass(CLASS.circle, d.index) }; -ChartInternal.prototype.selectorLegend = function (id) { - return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id); +ChartInternal.prototype.classCircles = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.circles, d.id) }; -ChartInternal.prototype.selectorLegends = function (ids) { - var $$ = this; - return ids && ids.length ? ids.map(function (id) { return $$.selectorLegend(id); }) : null; +ChartInternal.prototype.classBar = function(d) { + return this.classShape(d) + this.generateClass(CLASS.bar, d.index) }; - -ChartInternal.prototype.getClipPath = function (id) { - return "url(" + (isIE(9) ? "" : document.URL.split('#')[0]) + "#" + id + ")"; +ChartInternal.prototype.classBars = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.bars, d.id) }; -ChartInternal.prototype.appendClip = function (parent, id) { - return parent.append("clipPath").attr("id", id).append("rect"); +ChartInternal.prototype.classArc = function(d) { + return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id) }; -ChartInternal.prototype.getAxisClipX = function (forHorizontal) { - // axis line width + padding for left - var left = Math.max(30, this.margin.left); - return forHorizontal ? -(1 + left) : -(left - 1); +ChartInternal.prototype.classArcs = function(d) { + return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id) }; -ChartInternal.prototype.getAxisClipY = function (forHorizontal) { - return forHorizontal ? -20 : -this.margin.top; +ChartInternal.prototype.classArea = function(d) { + return this.classShape(d) + this.generateClass(CLASS.area, d.id) }; -ChartInternal.prototype.getXAxisClipX = function () { - var $$ = this; - return $$.getAxisClipX(!$$.config.axis_rotated); +ChartInternal.prototype.classAreas = function(d) { + return this.classShapes(d) + this.generateClass(CLASS.areas, d.id) }; -ChartInternal.prototype.getXAxisClipY = function () { - var $$ = this; - return $$.getAxisClipY(!$$.config.axis_rotated); +ChartInternal.prototype.classRegion = function(d, i) { + return ( + this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '') + ) }; -ChartInternal.prototype.getYAxisClipX = function () { - var $$ = this; - return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated); +ChartInternal.prototype.classEvent = function(d) { + return this.generateClass(CLASS.eventRect, d.index) }; -ChartInternal.prototype.getYAxisClipY = function () { - var $$ = this; - return $$.getAxisClipY($$.config.axis_rotated); +ChartInternal.prototype.classTarget = function(id) { + var $$ = this; + var additionalClassSuffix = $$.config.data_classes[id], + additionalClass = ''; + if (additionalClassSuffix) { + additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix; + } + return $$.generateClass(CLASS.target, id) + additionalClass }; -ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) { - var $$ = this, - left = Math.max(30, $$.margin.left), - right = Math.max(30, $$.margin.right); - // width + axis line width + padding for left/right - return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20; +ChartInternal.prototype.classFocus = function(d) { + return this.classFocused(d) + this.classDefocused(d) }; -ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) { - // less than 20 is not enough to show the axis label 'outer' without legend - return (forHorizontal ? this.margin.bottom : (this.margin.top + this.height)) + 20; +ChartInternal.prototype.classFocused = function(d) { + return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '') }; -ChartInternal.prototype.getXAxisClipWidth = function () { - var $$ = this; - return $$.getAxisClipWidth(!$$.config.axis_rotated); +ChartInternal.prototype.classDefocused = function(d) { + return ( + ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '') + ) }; -ChartInternal.prototype.getXAxisClipHeight = function () { - var $$ = this; - return $$.getAxisClipHeight(!$$.config.axis_rotated); +ChartInternal.prototype.classChartText = function(d) { + return CLASS.chartText + this.classTarget(d.id) }; -ChartInternal.prototype.getYAxisClipWidth = function () { - var $$ = this; - return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0); +ChartInternal.prototype.classChartLine = function(d) { + return CLASS.chartLine + this.classTarget(d.id) }; -ChartInternal.prototype.getYAxisClipHeight = function () { - var $$ = this; - return $$.getAxisClipHeight($$.config.axis_rotated); +ChartInternal.prototype.classChartBar = function(d) { + return CLASS.chartBar + this.classTarget(d.id) }; - -ChartInternal.prototype.generateColor = function () { - var $$ = this, config = $$.config, d3 = $$.d3, - colors = config.data_colors, - pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.schemeCategory10, - callback = config.data_color, - ids = []; - - return function (d) { - var id = d.id || (d.data && d.data.id) || d, color; - - // if callback function is provided - if (colors[id] instanceof Function) { - color = colors[id](d); - } - // if specified, choose that color - else if (colors[id]) { - color = colors[id]; - } - // if not specified, choose from pattern - else { - if (ids.indexOf(id) < 0) { ids.push(id); } - color = pattern[ids.indexOf(id) % pattern.length]; - colors[id] = color; - } - return callback instanceof Function ? callback(color, d) : color; - }; -}; -ChartInternal.prototype.generateLevelColor = function () { - var $$ = this, config = $$.config, - colors = config.color_pattern, - threshold = config.color_threshold, - asValue = threshold.unit === 'value', - values = threshold.values && threshold.values.length ? threshold.values : [], - max = threshold.max || 100; - return notEmpty(threshold) && notEmpty(colors) ? function (value) { - var i, v, color = colors[colors.length - 1]; - for (i = 0; i < values.length; i++) { - v = asValue ? value : (value * 100 / max); - if (v < values[i]) { - color = colors[i]; - break; - } - } - return color; - } : null; -}; - -ChartInternal.prototype.getDefaultConfig = function () { - var config = { - bindto: '#chart', - svg_classname: undefined, - size_width: undefined, - size_height: undefined, - padding_left: undefined, - padding_right: undefined, - padding_top: undefined, - padding_bottom: undefined, - resize_auto: true, - zoom_enabled: false, - zoom_initialRange: undefined, - zoom_type: 'scroll', - zoom_disableDefaultBehavior: false, - zoom_privileged: false, - zoom_rescale: false, - zoom_onzoom: function () {}, - zoom_onzoomstart: function () {}, - zoom_onzoomend: function () {}, - zoom_x_min: undefined, - zoom_x_max: undefined, - interaction_brighten: true, - interaction_enabled: true, - onmouseover: function () {}, - onmouseout: function () {}, - onresize: function () {}, - onresized: function () {}, - oninit: function () {}, - onrendered: function () {}, - transition_duration: 350, - data_epochs: 'epochs', - data_x: undefined, - data_xs: {}, - data_xFormat: '%Y-%m-%d', - data_xLocaltime: true, - data_xSort: true, - data_idConverter: function (id) { return id; }, - data_names: {}, - data_classes: {}, - data_groups: [], - data_axes: {}, - data_type: undefined, - data_types: {}, - data_labels: {}, - data_order: 'desc', - data_regions: {}, - data_color: undefined, - data_colors: {}, - data_hide: false, - data_filter: undefined, - data_selection_enabled: false, - data_selection_grouped: false, - data_selection_isselectable: function () { return true; }, - data_selection_multiple: true, - data_selection_draggable: false, - data_stack_normalize: false, - data_onclick: function () {}, - data_onmouseover: function () {}, - data_onmouseout: function () {}, - data_onselected: function () {}, - data_onunselected: function () {}, - data_url: undefined, - data_headers: undefined, - data_json: undefined, - data_rows: undefined, - data_columns: undefined, - data_mimeType: undefined, - data_keys: undefined, - // configuration for no plot-able data supplied. - data_empty_label_text: "", - // subchart - subchart_show: false, - subchart_size_height: 60, - subchart_axis_x_show: true, - subchart_onbrush: function () {}, - // color - color_pattern: [], - color_threshold: {}, - // legend - legend_show: true, - legend_hide: false, - legend_position: 'bottom', - legend_inset_anchor: 'top-left', - legend_inset_x: 10, - legend_inset_y: 0, - legend_inset_step: undefined, - legend_item_onclick: undefined, - legend_item_onmouseover: undefined, - legend_item_onmouseout: undefined, - legend_equally: false, - legend_padding: 0, - legend_item_tile_width: 10, - legend_item_tile_height: 10, - // axis - axis_rotated: false, - axis_x_show: true, - axis_x_type: 'indexed', - axis_x_localtime: true, - axis_x_categories: [], - axis_x_tick_centered: false, - axis_x_tick_format: undefined, - axis_x_tick_culling: {}, - axis_x_tick_culling_max: 10, - axis_x_tick_count: undefined, - axis_x_tick_fit: true, - axis_x_tick_values: null, - axis_x_tick_rotate: 0, - axis_x_tick_outer: true, - axis_x_tick_multiline: true, - axis_x_tick_multilineMax: 0, - axis_x_tick_width: null, - axis_x_max: undefined, - axis_x_min: undefined, - axis_x_padding: {}, - axis_x_height: undefined, - axis_x_selection: undefined, - axis_x_label: {}, - axis_x_inner: undefined, - axis_y_show: true, - axis_y_type: 'linear', - axis_y_max: undefined, - axis_y_min: undefined, - axis_y_inverted: false, - axis_y_center: undefined, - axis_y_inner: undefined, - axis_y_label: {}, - axis_y_tick_format: undefined, - axis_y_tick_outer: true, - axis_y_tick_values: null, - axis_y_tick_rotate: 0, - axis_y_tick_count: undefined, - axis_y_tick_time_type: undefined, - axis_y_tick_time_interval: undefined, - axis_y_padding: {}, - axis_y_default: undefined, - axis_y2_show: false, - axis_y2_type: 'linear', - axis_y2_max: undefined, - axis_y2_min: undefined, - axis_y2_inverted: false, - axis_y2_center: undefined, - axis_y2_inner: undefined, - axis_y2_label: {}, - axis_y2_tick_format: undefined, - axis_y2_tick_outer: true, - axis_y2_tick_values: null, - axis_y2_tick_count: undefined, - axis_y2_padding: {}, - axis_y2_default: undefined, - // grid - grid_x_show: false, - grid_x_type: 'tick', - grid_x_lines: [], - grid_y_show: false, - // not used - // grid_y_type: 'tick', - grid_y_lines: [], - grid_y_ticks: 10, - grid_focus_show: true, - grid_lines_front: true, - // point - point of each data - point_show: true, - point_r: 2.5, - point_sensitivity: 10, - point_focus_expand_enabled: true, - point_focus_expand_r: undefined, - point_select_r: undefined, - // line - line_connectNull: false, - line_step_type: 'step', - // bar - bar_width: undefined, - bar_width_ratio: 0.6, - bar_width_max: undefined, - bar_zerobased: true, - bar_space: 0, - // area - area_zerobased: true, - area_above: false, - // pie - pie_label_show: true, - pie_label_format: undefined, - pie_label_threshold: 0.05, - pie_label_ratio: undefined, - pie_expand: {}, - pie_expand_duration: 50, - pie_padAngle: 0, - // gauge - gauge_fullCircle: false, - gauge_label_show: true, - gauge_labelLine_show: true, - gauge_label_format: undefined, - gauge_min: 0, - gauge_max: 100, - gauge_startingAngle: -1 * Math.PI/2, - gauge_label_extents: undefined, - gauge_units: undefined, - gauge_width: undefined, - gauge_arcs_minWidth: 5, - gauge_expand: {}, - gauge_expand_duration: 50, - // donut - donut_label_show: true, - donut_label_format: undefined, - donut_label_threshold: 0.05, - donut_label_ratio: undefined, - donut_width: undefined, - donut_title: "", - donut_expand: {}, - donut_expand_duration: 50, - donut_padAngle: 0, - // spline - spline_interpolation_type: 'cardinal', - // stanford - stanford_lines: [], - stanford_regions: [], - stanford_texts: [], - stanford_scaleMin: undefined, - stanford_scaleMax: undefined, - stanford_scaleWidth: undefined, - stanford_scaleFormat: undefined, - stanford_scaleValues: undefined, - stanford_colors: undefined, - stanford_padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - }, - // region - region to change style - regions: [], - // tooltip - show when mouseover on each data - tooltip_show: true, - tooltip_grouped: true, - tooltip_order: undefined, - tooltip_format_title: undefined, - tooltip_format_name: undefined, - tooltip_format_value: undefined, - tooltip_horizontal: undefined, - tooltip_position: undefined, - tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) { - return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : ''; - }, - tooltip_init_show: false, - tooltip_init_x: 0, - tooltip_init_position: {top: '0px', left: '50px'}, - tooltip_onshow: function () {}, - tooltip_onhide: function () {}, - // title - title_text: undefined, - title_padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - }, - title_position: 'top-center' - }; - - Object.keys(this.additionalConfig).forEach(function (key) { - config[key] = this.additionalConfig[key]; - }, this); - - return config; +ChartInternal.prototype.classChartArc = function(d) { + return CLASS.chartArc + this.classTarget(d.data.id) }; -ChartInternal.prototype.additionalConfig = {}; +ChartInternal.prototype.getTargetSelectorSuffix = function(targetId) { + const targetClass = this.generateTargetClass(targetId); + if (window.CSS && window.CSS.escape) { + return window.CSS.escape(targetClass) + } -ChartInternal.prototype.loadConfig = function (config) { - var this_config = this.config, target, keys, read; - function find() { - var key = keys.shift(); -// console.log("key =>", key, ", target =>", target); - if (key && target && typeof target === 'object' && key in target) { - target = target[key]; - return find(); - } - else if (!key) { - return target; - } - else { - return undefined; - } + // fallback on imperfect method for old browsers (does not handles unicode) + return targetClass.replace(/([?!@#$%^&*()=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1') +}; +ChartInternal.prototype.selectorTarget = function(id, prefix) { + return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id) +}; +ChartInternal.prototype.selectorTargets = function(ids, prefix) { + var $$ = this; + ids = ids || []; + return ids.length + ? ids.map(function(id) { + return $$.selectorTarget(id, prefix) + }) + : null +}; +ChartInternal.prototype.selectorLegend = function(id) { + return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id) +}; +ChartInternal.prototype.selectorLegends = function(ids) { + var $$ = this; + return ids && ids.length + ? ids.map(function(id) { + return $$.selectorLegend(id) + }) + : null +}; + +ChartInternal.prototype.getClipPath = function(id) { + return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')' +}; +ChartInternal.prototype.appendClip = function(parent, id) { + return parent + .append('clipPath') + .attr('id', id) + .append('rect') +}; +ChartInternal.prototype.getAxisClipX = function(forHorizontal) { + // axis line width + padding for left + var left = Math.max(30, this.margin.left); + return forHorizontal ? -(1 + left) : -(left - 1) +}; +ChartInternal.prototype.getAxisClipY = function(forHorizontal) { + return forHorizontal ? -20 : -this.margin.top +}; +ChartInternal.prototype.getXAxisClipX = function() { + var $$ = this; + return $$.getAxisClipX(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getXAxisClipY = function() { + var $$ = this; + return $$.getAxisClipY(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getYAxisClipX = function() { + var $$ = this; + return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated) +}; +ChartInternal.prototype.getYAxisClipY = function() { + var $$ = this; + return $$.getAxisClipY($$.config.axis_rotated) +}; +ChartInternal.prototype.getAxisClipWidth = function(forHorizontal) { + var $$ = this, + left = Math.max(30, $$.margin.left), + right = Math.max(30, $$.margin.right); + // width + axis line width + padding for left/right + return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20 +}; +ChartInternal.prototype.getAxisClipHeight = function(forHorizontal) { + // less than 20 is not enough to show the axis label 'outer' without legend + return ( + (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20 + ) +}; +ChartInternal.prototype.getXAxisClipWidth = function() { + var $$ = this; + return $$.getAxisClipWidth(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getXAxisClipHeight = function() { + var $$ = this; + return $$.getAxisClipHeight(!$$.config.axis_rotated) +}; +ChartInternal.prototype.getYAxisClipWidth = function() { + var $$ = this; + return ( + $$.getAxisClipWidth($$.config.axis_rotated) + + ($$.config.axis_y_inner ? 20 : 0) + ) +}; +ChartInternal.prototype.getYAxisClipHeight = function() { + var $$ = this; + return $$.getAxisClipHeight($$.config.axis_rotated) +}; + +ChartInternal.prototype.generateColor = function() { + var $$ = this, + config = $$.config, + d3 = $$.d3, + colors = config.data_colors, + pattern = notEmpty(config.color_pattern) + ? config.color_pattern + : d3.schemeCategory10, + callback = config.data_color, + ids = []; + + return function(d) { + var id = d.id || (d.data && d.data.id) || d, + color; + + // if callback function is provided + if (colors[id] instanceof Function) { + color = colors[id](d); + } + // if specified, choose that color + else if (colors[id]) { + color = colors[id]; + } + // if not specified, choose from pattern + else { + if (ids.indexOf(id) < 0) { + ids.push(id); + } + color = pattern[ids.indexOf(id) % pattern.length]; + colors[id] = color; } - Object.keys(this_config).forEach(function (key) { - target = config; - keys = key.split('_'); - read = find(); -// console.log("CONFIG : ", key, read); - if (isDefined(read)) { - this_config[key] = read; - } - }); + return callback instanceof Function ? callback(color, d) : color + } }; +ChartInternal.prototype.generateLevelColor = function() { + var $$ = this, + config = $$.config, + colors = config.color_pattern, + threshold = config.color_threshold, + asValue = threshold.unit === 'value', + values = + threshold.values && threshold.values.length ? threshold.values : [], + max = threshold.max || 100; + return notEmpty(threshold) && notEmpty(colors) + ? function(value) { + var i, + v, + color = colors[colors.length - 1]; + for (i = 0; i < values.length; i++) { + v = asValue ? value : (value * 100) / max; + if (v < values[i]) { + color = colors[i]; + break + } + } + return color + } + : null +}; + +ChartInternal.prototype.getDefaultConfig = function() { + var config = { + bindto: '#chart', + svg_classname: undefined, + size_width: undefined, + size_height: undefined, + padding_left: undefined, + padding_right: undefined, + padding_top: undefined, + padding_bottom: undefined, + resize_auto: true, + zoom_enabled: false, + zoom_initialRange: undefined, + zoom_type: 'scroll', + zoom_disableDefaultBehavior: false, + zoom_privileged: false, + zoom_rescale: false, + zoom_onzoom: function() {}, + zoom_onzoomstart: function() {}, + zoom_onzoomend: function() {}, + zoom_x_min: undefined, + zoom_x_max: undefined, + interaction_brighten: true, + interaction_enabled: true, + onmouseover: function() {}, + onmouseout: function() {}, + onresize: function() {}, + onresized: function() {}, + oninit: function() {}, + onrendered: function() {}, + transition_duration: 350, + data_epochs: 'epochs', + data_x: undefined, + data_xs: {}, + data_xFormat: '%Y-%m-%d', + data_xLocaltime: true, + data_xSort: true, + data_idConverter: function(id) { + return id + }, + data_names: {}, + data_classes: {}, + data_groups: [], + data_axes: {}, + data_type: undefined, + data_types: {}, + data_labels: {}, + data_order: 'desc', + data_regions: {}, + data_color: undefined, + data_colors: {}, + data_hide: false, + data_filter: undefined, + data_selection_enabled: false, + data_selection_grouped: false, + data_selection_isselectable: function() { + return true + }, + data_selection_multiple: true, + data_selection_draggable: false, + data_stack_normalize: false, + data_onclick: function() {}, + data_onmouseover: function() {}, + data_onmouseout: function() {}, + data_onselected: function() {}, + data_onunselected: function() {}, + data_url: undefined, + data_headers: undefined, + data_json: undefined, + data_rows: undefined, + data_columns: undefined, + data_mimeType: undefined, + data_keys: undefined, + // configuration for no plot-able data supplied. + data_empty_label_text: '', + // subchart + subchart_show: false, + subchart_size_height: 60, + subchart_axis_x_show: true, + subchart_onbrush: function() {}, + // color + color_pattern: [], + color_threshold: {}, + // legend + legend_show: true, + legend_hide: false, + legend_position: 'bottom', + legend_inset_anchor: 'top-left', + legend_inset_x: 10, + legend_inset_y: 0, + legend_inset_step: undefined, + legend_item_onclick: undefined, + legend_item_onmouseover: undefined, + legend_item_onmouseout: undefined, + legend_equally: false, + legend_padding: 0, + legend_item_tile_width: 10, + legend_item_tile_height: 10, + // axis + axis_rotated: false, + axis_x_show: true, + axis_x_type: 'indexed', + axis_x_localtime: true, + axis_x_categories: [], + axis_x_tick_centered: false, + axis_x_tick_format: undefined, + axis_x_tick_culling: {}, + axis_x_tick_culling_max: 10, + axis_x_tick_count: undefined, + axis_x_tick_fit: true, + axis_x_tick_values: null, + axis_x_tick_rotate: 0, + axis_x_tick_outer: true, + axis_x_tick_multiline: true, + axis_x_tick_multilineMax: 0, + axis_x_tick_width: null, + axis_x_max: undefined, + axis_x_min: undefined, + axis_x_padding: {}, + axis_x_height: undefined, + axis_x_selection: undefined, + axis_x_label: {}, + axis_x_inner: undefined, + axis_y_show: true, + axis_y_type: 'linear', + axis_y_max: undefined, + axis_y_min: undefined, + axis_y_inverted: false, + axis_y_center: undefined, + axis_y_inner: undefined, + axis_y_label: {}, + axis_y_tick_format: undefined, + axis_y_tick_outer: true, + axis_y_tick_values: null, + axis_y_tick_rotate: 0, + axis_y_tick_count: undefined, + axis_y_tick_time_type: undefined, + axis_y_tick_time_interval: undefined, + axis_y_padding: {}, + axis_y_default: undefined, + axis_y2_show: false, + axis_y2_type: 'linear', + axis_y2_max: undefined, + axis_y2_min: undefined, + axis_y2_inverted: false, + axis_y2_center: undefined, + axis_y2_inner: undefined, + axis_y2_label: {}, + axis_y2_tick_format: undefined, + axis_y2_tick_outer: true, + axis_y2_tick_values: null, + axis_y2_tick_count: undefined, + axis_y2_padding: {}, + axis_y2_default: undefined, + // grid + grid_x_show: false, + grid_x_type: 'tick', + grid_x_lines: [], + grid_y_show: false, + // not used + // grid_y_type: 'tick', + grid_y_lines: [], + grid_y_ticks: 10, + grid_focus_show: true, + grid_lines_front: true, + // point - point of each data + point_show: true, + point_r: 2.5, + point_sensitivity: 10, + point_focus_expand_enabled: true, + point_focus_expand_r: undefined, + point_select_r: undefined, + // line + line_connectNull: false, + line_step_type: 'step', + // bar + bar_width: undefined, + bar_width_ratio: 0.6, + bar_width_max: undefined, + bar_zerobased: true, + bar_space: 0, + // area + area_zerobased: true, + area_above: false, + // pie + pie_label_show: true, + pie_label_format: undefined, + pie_label_threshold: 0.05, + pie_label_ratio: undefined, + pie_expand: {}, + pie_expand_duration: 50, + pie_padAngle: 0, + // gauge + gauge_fullCircle: false, + gauge_label_show: true, + gauge_labelLine_show: true, + gauge_label_format: undefined, + gauge_min: 0, + gauge_max: 100, + gauge_startingAngle: (-1 * Math.PI) / 2, + gauge_label_extents: undefined, + gauge_units: undefined, + gauge_width: undefined, + gauge_arcs_minWidth: 5, + gauge_expand: {}, + gauge_expand_duration: 50, + // donut + donut_label_show: true, + donut_label_format: undefined, + donut_label_threshold: 0.05, + donut_label_ratio: undefined, + donut_width: undefined, + donut_title: '', + donut_expand: {}, + donut_expand_duration: 50, + donut_padAngle: 0, + // spline + spline_interpolation_type: 'cardinal', + // stanford + stanford_lines: [], + stanford_regions: [], + stanford_texts: [], + stanford_scaleMin: undefined, + stanford_scaleMax: undefined, + stanford_scaleWidth: undefined, + stanford_scaleFormat: undefined, + stanford_scaleValues: undefined, + stanford_colors: undefined, + stanford_padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + // region - region to change style + regions: [], + // tooltip - show when mouseover on each data + tooltip_show: true, + tooltip_grouped: true, + tooltip_order: undefined, + tooltip_format_title: undefined, + tooltip_format_name: undefined, + tooltip_format_value: undefined, + tooltip_horizontal: undefined, + tooltip_position: undefined, + tooltip_contents: function( + d, + defaultTitleFormat, + defaultValueFormat, + color + ) { + return this.getTooltipContent + ? this.getTooltipContent( + d, + defaultTitleFormat, + defaultValueFormat, + color + ) + : '' + }, + tooltip_init_show: false, + tooltip_init_x: 0, + tooltip_init_position: { top: '0px', left: '50px' }, + tooltip_onshow: function() {}, + tooltip_onhide: function() {}, + // title + title_text: undefined, + title_padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + title_position: 'top-center' + }; -ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) { - var $$ = this, type = mimeType ? mimeType : 'csv', f, converter; + Object.keys(this.additionalConfig).forEach(function(key) { + config[key] = this.additionalConfig[key]; + }, this); - if (type === 'json') { - f = $$.d3.json; - converter = $$.convertJsonToData; - } else if (type === 'tsv') { - f = $$.d3.tsv; - converter = $$.convertXsvToData; + return config +}; +ChartInternal.prototype.additionalConfig = {}; + +ChartInternal.prototype.loadConfig = function(config) { + var this_config = this.config, + target, + keys, + read; + function find() { + var key = keys.shift(); + // console.log("key =>", key, ", target =>", target); + if (key && target && typeof target === 'object' && key in target) { + target = target[key]; + return find() + } else if (!key) { + return target } else { - f = $$.d3.csv; - converter = $$.convertXsvToData; + return undefined } + } + Object.keys(this_config).forEach(function(key) { + target = config; + keys = key.split('_'); + read = find(); + // console.log("CONFIG : ", key, read); + if (isDefined(read)) { + this_config[key] = read; + } + }); +}; + +ChartInternal.prototype.convertUrlToData = function( + url, + mimeType, + headers, + keys, + done +) { + var $$ = this, + type = mimeType ? mimeType : 'csv', + f, + converter; + + if (type === 'json') { + f = $$.d3.json; + converter = $$.convertJsonToData; + } else if (type === 'tsv') { + f = $$.d3.tsv; + converter = $$.convertXsvToData; + } else { + f = $$.d3.csv; + converter = $$.convertXsvToData; + } - f(url, headers).then(function (data) { - done.call($$, converter.call($$, data, keys)); - }).catch(function (error) { - throw error; + f(url, headers) + .then(function(data) { + done.call($$, converter.call($$, data, keys)); + }) + .catch(function(error) { + throw error }); }; -ChartInternal.prototype.convertXsvToData = function (xsv) { - var keys = xsv.columns, rows = xsv; - if (rows.length === 0) { - return { keys, rows: [ keys.reduce((row, key) => Object.assign(row, { [key]: null }), {}) ] }; - } else { - // [].concat() is to convert result into a plain array otherwise - // test is not happy because rows have properties. - return { keys, rows: [].concat(xsv) }; - } -}; -ChartInternal.prototype.convertJsonToData = function (json, keys) { - var $$ = this, - new_rows = [], targetKeys, data; - if (keys) { // when keys specified, json would be an array that includes objects - if (keys.x) { - targetKeys = keys.value.concat(keys.x); - $$.config.data_x = keys.x; - } else { - targetKeys = keys.value; - } - new_rows.push(targetKeys); - json.forEach(function (o) { - var new_row = []; - targetKeys.forEach(function (key) { - // convert undefined to null because undefined data will be removed in convertDataToTargets() - var v = $$.findValueInJson(o, key); - if (isUndefined(v)) { - v = null; - } - new_row.push(v); - }); - new_rows.push(new_row); - }); - data = $$.convertRowsToData(new_rows); - } else { - Object.keys(json).forEach(function (key) { - new_rows.push([key].concat(json[key])); - }); - data = $$.convertColumnsToData(new_rows); +ChartInternal.prototype.convertXsvToData = function(xsv) { + var keys = xsv.columns, + rows = xsv; + if (rows.length === 0) { + return { + keys, + rows: [keys.reduce((row, key) => Object.assign(row, { [key]: null }), {})] } - return data; + } else { + // [].concat() is to convert result into a plain array otherwise + // test is not happy because rows have properties. + return { keys, rows: [].concat(xsv) } + } +}; +ChartInternal.prototype.convertJsonToData = function(json, keys) { + var $$ = this, + new_rows = [], + targetKeys, + data; + if (keys) { + // when keys specified, json would be an array that includes objects + if (keys.x) { + targetKeys = keys.value.concat(keys.x); + $$.config.data_x = keys.x; + } else { + targetKeys = keys.value; + } + new_rows.push(targetKeys); + json.forEach(function(o) { + var new_row = []; + targetKeys.forEach(function(key) { + // convert undefined to null because undefined data will be removed in convertDataToTargets() + var v = $$.findValueInJson(o, key); + if (isUndefined(v)) { + v = null; + } + new_row.push(v); + }); + new_rows.push(new_row); + }); + data = $$.convertRowsToData(new_rows); + } else { + Object.keys(json).forEach(function(key) { + new_rows.push([key].concat(json[key])); + }); + data = $$.convertColumnsToData(new_rows); + } + return data }; /** * Finds value from the given nested object by the given path. @@ -6109,26 +7795,26 @@ ChartInternal.prototype.convertJsonToData = function (json, keys) { * @param {Object} object the object * @param {string} path the path */ -ChartInternal.prototype.findValueInJson = function (object, path) { - if (path in object) { - // If object has a key that contains . or [], return the key's value - // instead of searching for an inner object. - // See https://github.com/c3js/c3/issues/1691 for details. - return object[path]; - } - - path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .) - path = path.replace(/^\./, ''); // strip a leading dot - var pathArray = path.split('.'); - for (var i = 0; i < pathArray.length; ++i) { - var k = pathArray[i]; - if (k in object) { - object = object[k]; - } else { - return; - } +ChartInternal.prototype.findValueInJson = function(object, path) { + if (path in object) { + // If object has a key that contains . or [], return the key's value + // instead of searching for an inner object. + // See https://github.com/c3js/c3/issues/1691 for details. + return object[path] + } + + path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .) + path = path.replace(/^\./, ''); // strip a leading dot + var pathArray = path.split('.'); + for (var i = 0; i < pathArray.length; ++i) { + var k = pathArray[i]; + if (k in object) { + object = object[k]; + } else { + return } - return object; + } + return object }; /** @@ -6136,21 +7822,23 @@ ChartInternal.prototype.findValueInJson = function (object, path) { * @param {any[][]} rows The row data * @return {Object} */ -ChartInternal.prototype.convertRowsToData = (rows) => { - const newRows = []; - const keys = rows[0]; - - for (let i = 1; i < rows.length; i++) { - const newRow = {}; - for (let j = 0; j < rows[i].length; j++) { - if (isUndefined(rows[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); - } - newRow[keys[j]] = rows[i][j]; - } - newRows.push(newRow); - } - return { keys, rows: newRows }; +ChartInternal.prototype.convertRowsToData = rows => { + const newRows = []; + const keys = rows[0]; + + for (let i = 1; i < rows.length; i++) { + const newRow = {}; + for (let j = 0; j < rows[i].length; j++) { + if (isUndefined(rows[i][j])) { + throw new Error( + 'Source data is missing a component at (' + i + ',' + j + ')!' + ) + } + newRow[keys[j]] = rows[i][j]; + } + newRows.push(newRow); + } + return { keys, rows: newRows } }; /** @@ -6158,25 +7846,27 @@ ChartInternal.prototype.convertRowsToData = (rows) => { * @param {any[][]} columns The column data * @return {Object} */ -ChartInternal.prototype.convertColumnsToData = (columns) => { - const newRows = []; - const keys = []; - - for (let i = 0; i < columns.length; i++) { - const key = columns[i][0]; - for (let j = 1; j < columns[i].length; j++) { - if (isUndefined(newRows[j - 1])) { - newRows[j - 1] = {}; - } - if (isUndefined(columns[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); - } - newRows[j - 1][key] = columns[i][j]; - } - keys.push(key); - } +ChartInternal.prototype.convertColumnsToData = columns => { + const newRows = []; + const keys = []; + + for (let i = 0; i < columns.length; i++) { + const key = columns[i][0]; + for (let j = 1; j < columns[i].length; j++) { + if (isUndefined(newRows[j - 1])) { + newRows[j - 1] = {}; + } + if (isUndefined(columns[i][j])) { + throw new Error( + 'Source data is missing a component at (' + i + ',' + j + ')!' + ) + } + newRows[j - 1][key] = columns[i][j]; + } + keys.push(key); + } - return { keys, rows: newRows }; + return { keys, rows: newRows } }; /** @@ -6187,156 +7877,189 @@ ChartInternal.prototype.convertColumnsToData = (columns) => { * @param {boolean} appendXs True to append to $$.data.xs, False to replace. * @return {!Array} */ -ChartInternal.prototype.convertDataToTargets = function (data, appendXs) { - var $$ = this, config = $$.config, targets, ids, xs, keys, epochs; +ChartInternal.prototype.convertDataToTargets = function(data, appendXs) { + var $$ = this, + config = $$.config, + targets, + ids, + xs, + keys, + epochs; + + // handles format where keys are not orderly provided + if (isArray(data)) { + keys = Object.keys(data[0]); + } else { + keys = data.keys; + data = data.rows; + } - // handles format where keys are not orderly provided - if (isArray(data)) { - keys = Object.keys(data[ 0 ]); - } else { - keys = data.keys; - data = data.rows; - } + xs = keys.filter($$.isX, $$); - xs = keys.filter($$.isX, $$); + if (!$$.isStanfordGraphType()) { + ids = keys.filter($$.isNotX, $$); + } else { + epochs = keys.filter($$.isEpochs, $$); + ids = keys.filter($$.isNotXAndNotEpochs, $$); - if(!$$.isStanfordGraphType()) { - ids = keys.filter($$.isNotX, $$); - } else { - epochs = keys.filter($$.isEpochs, $$); - ids = keys.filter($$.isNotXAndNotEpochs, $$); + if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) { + throw new Error( + "You must define the 'x' key name and the 'epochs' for Stanford Diagrams" + ) + } + } - if(xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) { - throw new Error('You must define the \'x\' key name and the \'epochs\' for Stanford Diagrams'); - } + // save x for update data by load when custom x and c3.x API + ids.forEach(function(id) { + var xKey = $$.getXKey(id); + + if ($$.isCustomX() || $$.isTimeSeries()) { + // if included in input data + if (xs.indexOf(xKey) >= 0) { + $$.data.xs[id] = (appendXs && $$.data.xs[id] + ? $$.data.xs[id] + : [] + ).concat( + data + .map(function(d) { + return d[xKey] + }) + .filter(isValue) + .map(function(rawX, i) { + return $$.generateTargetX(rawX, id, i) + }) + ); + } + // if not included in input data, find from preloaded data of other id's x + else if (config.data_x) { + $$.data.xs[id] = $$.getOtherTargetXs(); + } + // if not included in input data, find from preloaded data + else if (notEmpty(config.data_xs)) { + $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets); + } + // MEMO: if no x included, use same x of current will be used + } else { + $$.data.xs[id] = data.map(function(d, i) { + return i + }); } + }); - // save x for update data by load when custom x and c3.x API - ids.forEach(function (id) { - var xKey = $$.getXKey(id); + // check x is defined + ids.forEach(function(id) { + if (!$$.data.xs[id]) { + throw new Error('x is not defined for id = "' + id + '".') + } + }); - if ($$.isCustomX() || $$.isTimeSeries()) { - // if included in input data - if (xs.indexOf(xKey) >= 0) { - $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat( - data.map(function (d) { return d[xKey]; }) - .filter(isValue) - .map(function (rawX, i) { return $$.generateTargetX(rawX, id, i); }) - ); - } - // if not included in input data, find from preloaded data of other id's x - else if (config.data_x) { - $$.data.xs[id] = $$.getOtherTargetXs(); + // convert to target + targets = ids.map(function(id, index) { + var convertedId = config.data_idConverter(id); + return { + id: convertedId, + id_org: id, + values: data + .map(function(d, i) { + var xKey = $$.getXKey(id), + rawX = d[xKey], + value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, + x, + returnData; + // use x as categories if custom x and categorized + if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) { + if (index === 0 && i === 0) { + config.axis_x_categories = []; } - // if not included in input data, find from preloaded data - else if (notEmpty(config.data_xs)) { - $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets); + x = config.axis_x_categories.indexOf(rawX); + if (x === -1) { + x = config.axis_x_categories.length; + config.axis_x_categories.push(rawX); } - // MEMO: if no x included, use same x of current will be used - } else { - $$.data.xs[id] = data.map(function (d, i) { return i; }); - } - }); - - // check x is defined - ids.forEach(function (id) { - if (!$$.data.xs[id]) { - throw new Error('x is not defined for id = "' + id + '".'); - } - }); + } else { + x = $$.generateTargetX(rawX, id, i); + } + // mark as x = undefined if value is undefined and filter to remove after mapped + if (isUndefined(d[id]) || $$.data.xs[id].length <= i) { + x = undefined; + } - // convert to target - targets = ids.map(function (id, index) { - var convertedId = config.data_idConverter(id); - return { - id: convertedId, - id_org: id, - values: data.map(function (d, i) { - var xKey = $$.getXKey(id), rawX = d[xKey], - value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, x, returnData; - // use x as categories if custom x and categorized - if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) { - if (index === 0 && i === 0) { - config.axis_x_categories = []; - } - x = config.axis_x_categories.indexOf(rawX); - if (x === -1) { - x = config.axis_x_categories.length; - config.axis_x_categories.push(rawX); - } - } else { - x = $$.generateTargetX(rawX, id, i); - } - // mark as x = undefined if value is undefined and filter to remove after mapped - if (isUndefined(d[id]) || $$.data.xs[id].length <= i) { - x = undefined; - } + returnData = { x: x, value: value, id: convertedId }; - returnData = {x: x, value: value, id: convertedId}; - - if($$.isStanfordGraphType()) { - returnData.epochs = d[epochs]; - } + if ($$.isStanfordGraphType()) { + returnData.epochs = d[epochs]; + } - return returnData; - }).filter(function (v) { return isDefined(v.x); }) - }; + return returnData + }) + .filter(function(v) { + return isDefined(v.x) + }) + } + }); + + // finish targets + targets.forEach(function(t) { + var i; + // sort values by its x + if (config.data_xSort) { + t.values = t.values.sort(function(v1, v2) { + var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, + x2 = v2.x || v2.x === 0 ? v2.x : Infinity; + return x1 - x2 + }); + } + // indexing each value + i = 0; + t.values.forEach(function(v) { + v.index = i++; }); - - // finish targets - targets.forEach(function (t) { - var i; - // sort values by its x - if (config.data_xSort) { - t.values = t.values.sort(function (v1, v2) { - var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, - x2 = v2.x || v2.x === 0 ? v2.x : Infinity; - return x1 - x2; - }); - } - // indexing each value - i = 0; - t.values.forEach(function (v) { - v.index = i++; - }); - // this needs to be sorted because its index and value.index is identical - $$.data.xs[t.id].sort(function (v1, v2) { - return v1 - v2; - }); + // this needs to be sorted because its index and value.index is identical + $$.data.xs[t.id].sort(function(v1, v2) { + return v1 - v2 }); + }); + + // cache information about values + $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets); + $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); + + // set target types + if (config.data_type) { + $$.setTargetType( + $$.mapToIds(targets).filter(function(id) { + return !(id in config.data_types) + }), + config.data_type + ); + } - // cache information about values - $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets); - $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); - - // set target types - if (config.data_type) { - $$.setTargetType($$.mapToIds(targets).filter(function (id) { return ! (id in config.data_types); }), config.data_type); - } - - // cache as original id keyed - targets.forEach(function (d) { - $$.addCache(d.id_org, d); - }); + // cache as original id keyed + targets.forEach(function(d) { + $$.addCache(d.id_org, d); + }); - return targets; + return targets }; -ChartInternal.prototype.isEpochs = function (key) { - var $$ = this, - config = $$.config; - return (config.data_epochs && key === config.data_epochs); +ChartInternal.prototype.isEpochs = function(key) { + var $$ = this, + config = $$.config; + return config.data_epochs && key === config.data_epochs }; -ChartInternal.prototype.isX = function (key) { - var $$ = this, - config = $$.config; - return (config.data_x && key === config.data_x) || (notEmpty(config.data_xs) && hasValue(config.data_xs, key)); +ChartInternal.prototype.isX = function(key) { + var $$ = this, + config = $$.config; + return ( + (config.data_x && key === config.data_x) || + (notEmpty(config.data_xs) && hasValue(config.data_xs, key)) + ) }; -ChartInternal.prototype.isNotX = function (key) { - return !this.isX(key); +ChartInternal.prototype.isNotX = function(key) { + return !this.isX(key) }; -ChartInternal.prototype.isNotXAndNotEpochs = function (key) { - return !this.isX(key) && !this.isEpochs(key); +ChartInternal.prototype.isNotXAndNotEpochs = function(key) { + return !this.isX(key) && !this.isEpochs(key) }; /** @@ -6347,7 +8070,7 @@ ChartInternal.prototype.isNotXAndNotEpochs = function (key) { * @return {boolean} */ ChartInternal.prototype.isStackNormalized = function() { - return this.config.data_stack_normalize && this.config.data_groups.length > 0; + return this.config.data_stack_normalize && this.config.data_groups.length > 0 }; /** @@ -6360,15 +8083,16 @@ ChartInternal.prototype.isStackNormalized = function() { * @return {Boolean} */ ChartInternal.prototype.isAxisNormalized = function(axisId) { - const $$ = this; + const $$ = this; - if (!$$.isStackNormalized()) { // shortcut - return false; - } + if (!$$.isStackNormalized()) { + // shortcut + return false + } - return $$.data.targets - .filter((target) => $$.axis.getId(target.id) === axisId) - .some((target) => $$.isTargetNormalized(target.id)); + return $$.data.targets + .filter(target => $$.axis.getId(target.id) === axisId) + .some(target => $$.isTargetNormalized(target.id)) }; /** @@ -6381,15 +8105,22 @@ ChartInternal.prototype.isAxisNormalized = function(axisId) { * @return {Boolean} True if the target is normalized, false otherwise. */ ChartInternal.prototype.isTargetNormalized = function(targetId) { - const $$ = this; + const $$ = this; - return $$.isStackNormalized() && $$.config.data_groups.some((group) => group.includes(targetId)); + return ( + $$.isStackNormalized() && + $$.config.data_groups.some(group => group.includes(targetId)) + ) }; -ChartInternal.prototype.getXKey = function (id) { - var $$ = this, - config = $$.config; - return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null; +ChartInternal.prototype.getXKey = function(id) { + var $$ = this, + config = $$.config; + return config.data_x + ? config.data_x + : notEmpty(config.data_xs) + ? config.data_xs[id] + : null }; /** @@ -6402,41 +8133,41 @@ ChartInternal.prototype.getXKey = function (id) { * @return {Array} */ ChartInternal.prototype.getTotalPerIndex = function(axisId) { - const $$ = this; + const $$ = this; - if (!$$.isStackNormalized()) { - return null; - } + if (!$$.isStackNormalized()) { + return null + } - const cached = $$.getFromCache('getTotalPerIndex'); - if (cached !== undefined) { - return cached[axisId]; - } + const cached = $$.getFromCache('getTotalPerIndex'); + if (cached !== undefined) { + return cached[axisId] + } - const sum = { y: [], y2: [] }; + const sum = { y: [], y2: [] }; - $$.data.targets - // keep only target that are normalized - .filter((target) => $$.isTargetNormalized(target.id)) + $$.data.targets + // keep only target that are normalized + .filter(target => $$.isTargetNormalized(target.id)) - // keep only target that are visible - .filter((target) => $$.isTargetToShow(target.id)) + // keep only target that are visible + .filter(target => $$.isTargetToShow(target.id)) - // compute sum per axis - .forEach(target => { - const sumByAxis = sum[$$.axis.getId(target.id)]; + // compute sum per axis + .forEach(target => { + const sumByAxis = sum[$$.axis.getId(target.id)]; - target.values.forEach((v, i) => { - if (!sumByAxis[i]) { - sumByAxis[i] = 0; - } - sumByAxis[i] += isNumber(v.value) ? v.value : 0; - }); - }); + target.values.forEach((v, i) => { + if (!sumByAxis[i]) { + sumByAxis[i] = 0; + } + sumByAxis[i] += isNumber(v.value) ? v.value : 0; + }); + }); - $$.addToCache('getTotalPerIndex', sum); + $$.addToCache('getTotalPerIndex', sum); - return sum[axisId]; + return sum[axisId] }; /** @@ -6449,141 +8180,145 @@ ChartInternal.prototype.getTotalPerIndex = function(axisId) { * @return {Number} */ ChartInternal.prototype.getTotalDataSum = function() { - const $$ = this; - - const cached = $$.getFromCache('getTotalDataSum'); - if (cached !== undefined) { - return cached; - } - - const totalDataSum = flattenArray($$.data.targets - .filter(target => $$.isTargetToShow(target.id)) - .map(target => target.values) - ) - .map(d => d.value) - .reduce((p, c) => p + c, 0); - - $$.addToCache('getTotalDataSum', totalDataSum); + const $$ = this; - return totalDataSum; -}; + const cached = $$.getFromCache('getTotalDataSum'); + if (cached !== undefined) { + return cached + } -ChartInternal.prototype.getXValuesOfXKey = function (key, targets) { - var $$ = this, - xValues, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []; - ids.forEach(function (id) { - if ($$.getXKey(id) === key) { - xValues = $$.data.xs[id]; - } - }); - return xValues; -}; -ChartInternal.prototype.getXValue = function (id, i) { - var $$ = this; - return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i; -}; -ChartInternal.prototype.getOtherTargetXs = function () { - var $$ = this, - idsForX = Object.keys($$.data.xs); - return idsForX.length ? $$.data.xs[idsForX[0]] : null; -}; -ChartInternal.prototype.getOtherTargetX = function (index) { - var xs = this.getOtherTargetXs(); - return xs && index < xs.length ? xs[index] : null; -}; -ChartInternal.prototype.addXs = function (xs) { - var $$ = this; - Object.keys(xs).forEach(function (id) { - $$.config.data_xs[id] = xs[id]; - }); -}; -ChartInternal.prototype.addName = function (data) { - var $$ = this, - name; - if (data) { - name = $$.config.data_names[data.id]; - data.name = name !== undefined ? name : data.id; - } - return data; -}; -ChartInternal.prototype.getValueOnIndex = function (values, index) { - var valueOnIndex = values.filter(function (v) { - return v.index === index; - }); - return valueOnIndex.length ? valueOnIndex[0] : null; -}; -ChartInternal.prototype.updateTargetX = function (targets, x) { - var $$ = this; - targets.forEach(function (t) { - t.values.forEach(function (v, i) { - v.x = $$.generateTargetX(x[i], t.id, i); - }); - $$.data.xs[t.id] = x; - }); -}; -ChartInternal.prototype.updateTargetXs = function (targets, xs) { - var $$ = this; - targets.forEach(function (t) { - if (xs[t.id]) { - $$.updateTargetX([t], xs[t.id]); - } + const totalDataSum = flattenArray( + $$.data.targets + .filter(target => $$.isTargetToShow(target.id)) + .map(target => target.values) + ) + .map(d => d.value) + .reduce((p, c) => p + c, 0); + + $$.addToCache('getTotalDataSum', totalDataSum); + + return totalDataSum +}; + +ChartInternal.prototype.getXValuesOfXKey = function(key, targets) { + var $$ = this, + xValues, + ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []; + ids.forEach(function(id) { + if ($$.getXKey(id) === key) { + xValues = $$.data.xs[id]; + } + }); + return xValues +}; +ChartInternal.prototype.getXValue = function(id, i) { + var $$ = this; + return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) + ? $$.data.xs[id][i] + : i +}; +ChartInternal.prototype.getOtherTargetXs = function() { + var $$ = this, + idsForX = Object.keys($$.data.xs); + return idsForX.length ? $$.data.xs[idsForX[0]] : null +}; +ChartInternal.prototype.getOtherTargetX = function(index) { + var xs = this.getOtherTargetXs(); + return xs && index < xs.length ? xs[index] : null +}; +ChartInternal.prototype.addXs = function(xs) { + var $$ = this; + Object.keys(xs).forEach(function(id) { + $$.config.data_xs[id] = xs[id]; + }); +}; +ChartInternal.prototype.addName = function(data) { + var $$ = this, + name; + if (data) { + name = $$.config.data_names[data.id]; + data.name = name !== undefined ? name : data.id; + } + return data +}; +ChartInternal.prototype.getValueOnIndex = function(values, index) { + var valueOnIndex = values.filter(function(v) { + return v.index === index + }); + return valueOnIndex.length ? valueOnIndex[0] : null +}; +ChartInternal.prototype.updateTargetX = function(targets, x) { + var $$ = this; + targets.forEach(function(t) { + t.values.forEach(function(v, i) { + v.x = $$.generateTargetX(x[i], t.id, i); }); + $$.data.xs[t.id] = x; + }); +}; +ChartInternal.prototype.updateTargetXs = function(targets, xs) { + var $$ = this; + targets.forEach(function(t) { + if (xs[t.id]) { + $$.updateTargetX([t], xs[t.id]); + } + }); +}; +ChartInternal.prototype.generateTargetX = function(rawX, id, index) { + var $$ = this, + x; + if ($$.isTimeSeries()) { + x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index)); + } else if ($$.isCustomX() && !$$.isCategorized()) { + x = isValue(rawX) ? +rawX : $$.getXValue(id, index); + } else { + x = index; + } + return x +}; +ChartInternal.prototype.cloneTarget = function(target) { + return { + id: target.id, + id_org: target.id_org, + values: target.values.map(function(d) { + return { + x: d.x, + value: d.value, + id: d.id + } + }) + } }; -ChartInternal.prototype.generateTargetX = function (rawX, id, index) { - var $$ = this, - x; - if ($$.isTimeSeries()) { - x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index)); - } else if ($$.isCustomX() && !$$.isCategorized()) { - x = isValue(rawX) ? +rawX : $$.getXValue(id, index); - } else { - x = index; - } - return x; -}; -ChartInternal.prototype.cloneTarget = function (target) { - return { - id: target.id, - id_org: target.id_org, - values: target.values.map(function (d) { - return { - x: d.x, - value: d.value, - id: d.id - }; - }) - }; -}; -ChartInternal.prototype.getMaxDataCount = function () { - var $$ = this; - return $$.d3.max($$.data.targets, function (t) { - return t.values.length; - }); +ChartInternal.prototype.getMaxDataCount = function() { + var $$ = this; + return $$.d3.max($$.data.targets, function(t) { + return t.values.length + }) }; -ChartInternal.prototype.mapToIds = function (targets) { - return targets.map(function (d) { - return d.id; - }); +ChartInternal.prototype.mapToIds = function(targets) { + return targets.map(function(d) { + return d.id + }) }; -ChartInternal.prototype.mapToTargetIds = function (ids) { - var $$ = this; - return ids ? [].concat(ids) : $$.mapToIds($$.data.targets); +ChartInternal.prototype.mapToTargetIds = function(ids) { + var $$ = this; + return ids ? [].concat(ids) : $$.mapToIds($$.data.targets) }; -ChartInternal.prototype.hasTarget = function (targets, id) { - var ids = this.mapToIds(targets), - i; - for (i = 0; i < ids.length; i++) { - if (ids[i] === id) { - return true; - } +ChartInternal.prototype.hasTarget = function(targets, id) { + var ids = this.mapToIds(targets), + i; + for (i = 0; i < ids.length; i++) { + if (ids[i] === id) { + return true } - return false; + } + return false }; -ChartInternal.prototype.isTargetToShow = function (targetId) { - return this.hiddenTargetIds.indexOf(targetId) < 0; +ChartInternal.prototype.isTargetToShow = function(targetId) { + return this.hiddenTargetIds.indexOf(targetId) < 0 }; -ChartInternal.prototype.isLegendToShow = function (targetId) { - return this.hiddenLegendIds.indexOf(targetId) < 0; +ChartInternal.prototype.isLegendToShow = function(targetId) { + return this.hiddenLegendIds.indexOf(targetId) < 0 }; /** @@ -6594,15 +8329,15 @@ ChartInternal.prototype.isLegendToShow = function (targetId) { * @return {Array} */ ChartInternal.prototype.getTargetsToShow = function() { - const $$ = this; - return $$.filterTargetsToShow($$.data.targets); + const $$ = this; + return $$.filterTargetsToShow($$.data.targets) }; -ChartInternal.prototype.filterTargetsToShow = function (targets) { - var $$ = this; - return targets.filter(function (t) { - return $$.isTargetToShow(t.id); - }); +ChartInternal.prototype.filterTargetsToShow = function(targets) { + var $$ = this; + return targets.filter(function(t) { + return $$.isTargetToShow(t.id) + }) }; /** @@ -6610,123 +8345,139 @@ ChartInternal.prototype.filterTargetsToShow = function (targets) { */ ChartInternal.prototype.getTargets = function() { const $$ = this; - return $$.data.targets; -}; - -ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) { - var $$ = this; - var xs = $$.d3.set($$.d3.merge(targets.map(function (t) { - return t.values.map(function (v) { - return +v.x; - }); - }))).values(); - xs = $$.isTimeSeries() ? xs.map(function (x) { - return new Date(+x); - }) : xs.map(function (x) { - return +x; - }); - return xs.sort(function (a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - }); -}; -ChartInternal.prototype.addHiddenTargetIds = function (targetIds) { - targetIds = (targetIds instanceof Array) ? targetIds : new Array(targetIds); - for (var i = 0; i < targetIds.length; i++) { - if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) { - this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]); - } + return $$.data.targets +}; + +ChartInternal.prototype.mapTargetsToUniqueXs = function(targets) { + var $$ = this; + var xs = $$.d3 + .set( + $$.d3.merge( + targets.map(function(t) { + return t.values.map(function(v) { + return +v.x + }) + }) + ) + ) + .values(); + xs = $$.isTimeSeries() + ? xs.map(function(x) { + return new Date(+x) + }) + : xs.map(function(x) { + return +x + }); + return xs.sort(function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN + }) +}; +ChartInternal.prototype.addHiddenTargetIds = function(targetIds) { + targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds); + for (var i = 0; i < targetIds.length; i++) { + if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) { + this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]); } - this.resetCache(); + } + this.resetCache(); }; -ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) { - this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); - this.resetCache(); +ChartInternal.prototype.removeHiddenTargetIds = function(targetIds) { + this.hiddenTargetIds = this.hiddenTargetIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); + this.resetCache(); }; -ChartInternal.prototype.addHiddenLegendIds = function (targetIds) { - targetIds = (targetIds instanceof Array) ? targetIds : new Array(targetIds); - for (var i = 0; i < targetIds.length; i++) { - if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) { - this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]); - } +ChartInternal.prototype.addHiddenLegendIds = function(targetIds) { + targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds); + for (var i = 0; i < targetIds.length; i++) { + if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) { + this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]); } + } }; -ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) { - this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) { - return targetIds.indexOf(id) < 0; - }); -}; -ChartInternal.prototype.getValuesAsIdKeyed = function (targets) { - var ys = {}; - targets.forEach(function (t) { - ys[t.id] = []; - t.values.forEach(function (v) { - ys[t.id].push(v.value); - }); +ChartInternal.prototype.removeHiddenLegendIds = function(targetIds) { + this.hiddenLegendIds = this.hiddenLegendIds.filter(function(id) { + return targetIds.indexOf(id) < 0 + }); +}; +ChartInternal.prototype.getValuesAsIdKeyed = function(targets) { + var ys = {}; + targets.forEach(function(t) { + ys[t.id] = []; + t.values.forEach(function(v) { + ys[t.id].push(v.value); }); - return ys; -}; -ChartInternal.prototype.checkValueInTargets = function (targets, checker) { - var ids = Object.keys(targets), - i, j, values; - for (i = 0; i < ids.length; i++) { - values = targets[ids[i]].values; - for (j = 0; j < values.length; j++) { - if (checker(values[j].value)) { - return true; - } - } + }); + return ys +}; +ChartInternal.prototype.checkValueInTargets = function(targets, checker) { + var ids = Object.keys(targets), + i, + j, + values; + for (i = 0; i < ids.length; i++) { + values = targets[ids[i]].values; + for (j = 0; j < values.length; j++) { + if (checker(values[j].value)) { + return true + } } - return false; -}; -ChartInternal.prototype.hasNegativeValueInTargets = function (targets) { - return this.checkValueInTargets(targets, function (v) { - return v < 0; - }); -}; -ChartInternal.prototype.hasPositiveValueInTargets = function (targets) { - return this.checkValueInTargets(targets, function (v) { - return v > 0; - }); -}; -ChartInternal.prototype.isOrderDesc = function () { - var config = this.config; - return typeof (config.data_order) === 'string' && config.data_order.toLowerCase() === 'desc'; -}; -ChartInternal.prototype.isOrderAsc = function () { - var config = this.config; - return typeof (config.data_order) === 'string' && config.data_order.toLowerCase() === 'asc'; -}; -ChartInternal.prototype.getOrderFunction = function () { - var $$ = this, - config = $$.config, - orderAsc = $$.isOrderAsc(), - orderDesc = $$.isOrderDesc(); - if (orderAsc || orderDesc) { - var reducer = function (p, c) { - return p + Math.abs(c.value); - }; - return function (t1, t2) { - var t1Sum = t1.values.reduce(reducer, 0), - t2Sum = t2.values.reduce(reducer, 0); - return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum; - }; - } else if (isFunction(config.data_order)) { - return config.data_order; - } else if (isArray(config.data_order)) { - var order = config.data_order; - return function (t1, t2) { - return order.indexOf(t1.id) - order.indexOf(t2.id); - }; + } + return false +}; +ChartInternal.prototype.hasNegativeValueInTargets = function(targets) { + return this.checkValueInTargets(targets, function(v) { + return v < 0 + }) +}; +ChartInternal.prototype.hasPositiveValueInTargets = function(targets) { + return this.checkValueInTargets(targets, function(v) { + return v > 0 + }) +}; +ChartInternal.prototype.isOrderDesc = function() { + var config = this.config; + return ( + typeof config.data_order === 'string' && + config.data_order.toLowerCase() === 'desc' + ) +}; +ChartInternal.prototype.isOrderAsc = function() { + var config = this.config; + return ( + typeof config.data_order === 'string' && + config.data_order.toLowerCase() === 'asc' + ) +}; +ChartInternal.prototype.getOrderFunction = function() { + var $$ = this, + config = $$.config, + orderAsc = $$.isOrderAsc(), + orderDesc = $$.isOrderDesc(); + if (orderAsc || orderDesc) { + var reducer = function(p, c) { + return p + Math.abs(c.value) + }; + return function(t1, t2) { + var t1Sum = t1.values.reduce(reducer, 0), + t2Sum = t2.values.reduce(reducer, 0); + return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum + } + } else if (isFunction(config.data_order)) { + return config.data_order + } else if (isArray(config.data_order)) { + var order = config.data_order; + return function(t1, t2) { + return order.indexOf(t1.id) - order.indexOf(t2.id) } + } }; -ChartInternal.prototype.orderTargets = function (targets) { - var fct = this.getOrderFunction(); - if (fct) { - targets.sort(fct); - } - return targets; +ChartInternal.prototype.orderTargets = function(targets) { + var fct = this.getOrderFunction(); + if (fct) { + targets.sort(fct); + } + return targets }; /** @@ -6736,65 +8487,77 @@ ChartInternal.prototype.orderTargets = function (targets) { * @param {Number} index * @return {Array} */ -ChartInternal.prototype.filterByIndex = function (targets, index) { - return this.d3.merge(targets.map((t) => t.values.filter((v) => v.index === index))); -}; - -ChartInternal.prototype.filterByX = function (targets, x) { - return this.d3.merge(targets.map(function (t) { - return t.values; - })).filter(function (v) { - return v.x - x === 0; - }); -}; -ChartInternal.prototype.filterRemoveNull = function (data) { - return data.filter(function (d) { - return isValue(d.value); - }); +ChartInternal.prototype.filterByIndex = function(targets, index) { + return this.d3.merge( + targets.map(t => t.values.filter(v => v.index === index)) + ) +}; + +ChartInternal.prototype.filterByX = function(targets, x) { + return this.d3 + .merge( + targets.map(function(t) { + return t.values + }) + ) + .filter(function(v) { + return v.x - x === 0 + }) }; -ChartInternal.prototype.filterByXDomain = function (targets, xDomain) { - return targets.map(function (t) { - return { - id: t.id, - id_org: t.id_org, - values: t.values.filter(function (v) { - return xDomain[0] <= v.x && v.x <= xDomain[1]; - }) - }; - }); +ChartInternal.prototype.filterRemoveNull = function(data) { + return data.filter(function(d) { + return isValue(d.value) + }) }; -ChartInternal.prototype.hasDataLabel = function () { - var config = this.config; - if (typeof config.data_labels === 'boolean' && config.data_labels) { - return true; - } else if (typeof config.data_labels === 'object' && notEmpty(config.data_labels)) { - return true; - } - return false; -}; -ChartInternal.prototype.getDataLabelLength = function (min, max, key) { - var $$ = this, - lengths = [0, 0], - paddingCoef = 1.3; - $$.selectChart.select('svg').selectAll('.dummy') - .data([min, max]) - .enter().append('text') - .text(function (d) { - return $$.dataLabelFormat(d.id)(d); - }) - .each(function (d, i) { - lengths[i] = getBBox(this)[key] * paddingCoef; - }) - .remove(); - return lengths; +ChartInternal.prototype.filterByXDomain = function(targets, xDomain) { + return targets.map(function(t) { + return { + id: t.id, + id_org: t.id_org, + values: t.values.filter(function(v) { + return xDomain[0] <= v.x && v.x <= xDomain[1] + }) + } + }) +}; +ChartInternal.prototype.hasDataLabel = function() { + var config = this.config; + if (typeof config.data_labels === 'boolean' && config.data_labels) { + return true + } else if ( + typeof config.data_labels === 'object' && + notEmpty(config.data_labels) + ) { + return true + } + return false +}; +ChartInternal.prototype.getDataLabelLength = function(min, max, key) { + var $$ = this, + lengths = [0, 0], + paddingCoef = 1.3; + $$.selectChart + .select('svg') + .selectAll('.dummy') + .data([min, max]) + .enter() + .append('text') + .text(function(d) { + return $$.dataLabelFormat(d.id)(d) + }) + .each(function(d, i) { + lengths[i] = getBBox(this)[key] * paddingCoef; + }) + .remove(); + return lengths }; /** * Returns true if the given data point is not arc type, otherwise false. * @param {Object} d The data point * @return {boolean} */ -ChartInternal.prototype.isNoneArc = function (d) { - return this.hasTarget(this.data.targets, d.id); +ChartInternal.prototype.isNoneArc = function(d) { + return this.hasTarget(this.data.targets, d.id) }; /** @@ -6802,8 +8565,8 @@ ChartInternal.prototype.isNoneArc = function (d) { * @param {Object} d The data point * @return {boolean} */ -ChartInternal.prototype.isArc = function (d) { - return 'data' in d && this.hasTarget(this.data.targets, d.data.id); +ChartInternal.prototype.isArc = function(d) { + return 'data' in d && this.hasTarget(this.data.targets, d.data.id) }; /** @@ -6814,22 +8577,31 @@ ChartInternal.prototype.isArc = function (d) { * @param {Array} pos An [x,y] coordinate * @return {Object|undefined} */ -ChartInternal.prototype.findClosestFromTargets = function (targets, pos) { - const $$ = this; - - // for each target, find the closest point - const candidates = targets - .map((t) => $$.findClosest(t.values, pos, $$.config.tooltip_horizontal ? $$.horizontalDistance.bind($$) : $$.dist.bind($$), $$.config.point_sensitivity)) - .filter((v) => v); - - // returns the closest of candidates - if (candidates.length === 0) { - return undefined; - } else if (candidates.length === 1) { - return candidates[0]; - } else { - return $$.findClosest(candidates, pos, $$.dist.bind($$)); - } +ChartInternal.prototype.findClosestFromTargets = function(targets, pos) { + const $$ = this; + + // for each target, find the closest point + const candidates = targets + .map(t => + $$.findClosest( + t.values, + pos, + $$.config.tooltip_horizontal + ? $$.horizontalDistance.bind($$) + : $$.dist.bind($$), + $$.config.point_sensitivity + ) + ) + .filter(v => v); + + // returns the closest of candidates + if (candidates.length === 0) { + return undefined + } else if (candidates.length === 1) { + return candidates[0] + } else { + return $$.findClosest(candidates, pos, $$.dist.bind($$)) + } }; /** @@ -6839,23 +8611,22 @@ ChartInternal.prototype.findClosestFromTargets = function (targets, pos) { * @param {Array} x A value on X axis * @return {Object|undefined} */ -ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) { - let closest; - let diff; - - targets - .forEach((t) => { - t.values.forEach((d) => { - let newDiff = Math.abs(x - d.x); - - if (diff === undefined || newDiff < diff) { - closest = d; - diff = newDiff; - } - }); - }); +ChartInternal.prototype.findClosestFromTargetsByX = function(targets, x) { + let closest; + let diff; + + targets.forEach(t => { + t.values.forEach(d => { + let newDiff = Math.abs(x - d.x); + + if (diff === undefined || newDiff < diff) { + closest = d; + diff = newDiff; + } + }); + }); - return closest; + return closest }; /** @@ -6870,77 +8641,92 @@ ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) { * @param {Number} minDist Minimal distance to satisfy * @return {Object|undefined} Closest data point */ -ChartInternal.prototype.findClosest = function (dataPoints, pos, computeDist, minDist = Infinity) { - const $$ = this; - - let closest; - - // find closest bar - dataPoints - .filter((v) => v && $$.isBarType(v.id)) - .forEach(function (v) { - if (!closest) { - const shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node(); - if ($$.isWithinBar(pos, shape)) { - closest = v; - } - } - }); +ChartInternal.prototype.findClosest = function( + dataPoints, + pos, + computeDist, + minDist = Infinity +) { + const $$ = this; - // find closest point from non-bar - dataPoints - .filter((v) => v && !$$.isBarType(v.id)) - .forEach((v) => { - let d = computeDist(v, pos); - if (d < minDist) { - minDist = d; - closest = v; - } - }); + let closest; + + // find closest bar + dataPoints + .filter(v => v && $$.isBarType(v.id)) + .forEach(function(v) { + if (!closest) { + const shape = $$.main + .select( + '.' + + CLASS.bars + + $$.getTargetSelectorSuffix(v.id) + + ' .' + + CLASS.bar + + '-' + + v.index + ) + .node(); + if ($$.isWithinBar(pos, shape)) { + closest = v; + } + } + }); - return closest; + // find closest point from non-bar + dataPoints + .filter(v => v && !$$.isBarType(v.id)) + .forEach(v => { + let d = computeDist(v, pos); + if (d < minDist) { + minDist = d; + closest = v; + } + }); + + return closest }; -ChartInternal.prototype.dist = function (data, pos) { - var $$ = this, - config = $$.config, - xIndex = config.axis_rotated ? 1 : 0, - yIndex = config.axis_rotated ? 0 : 1, - y = $$.circleY(data, data.index), - x = $$.x(data.x); - return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2)); +ChartInternal.prototype.dist = function(data, pos) { + var $$ = this, + config = $$.config, + xIndex = config.axis_rotated ? 1 : 0, + yIndex = config.axis_rotated ? 0 : 1, + y = $$.circleY(data, data.index), + x = $$.x(data.x); + return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2)) }; ChartInternal.prototype.horizontalDistance = function(data, pos) { - var $$ = this, - config = $$.config, - xIndex = config.axis_rotated ? 1 : 0, - x = $$.x(data.x); + var $$ = this, + config = $$.config, + xIndex = config.axis_rotated ? 1 : 0, + x = $$.x(data.x); - return Math.abs(x - pos[xIndex]); + return Math.abs(x - pos[xIndex]) }; -ChartInternal.prototype.convertValuesToStep = function (values) { - var converted = [].concat(values), - i; +ChartInternal.prototype.convertValuesToStep = function(values) { + var converted = [].concat(values), + i; - if (!this.isCategorized()) { - return values; - } + if (!this.isCategorized()) { + return values + } - for (i = values.length + 1; 0 < i; i--) { - converted[i] = converted[i - 1]; - } + for (i = values.length + 1; 0 < i; i--) { + converted[i] = converted[i - 1]; + } - converted[0] = { - x: converted[0].x - 1, - value: converted[0].value, - id: converted[0].id - }; - converted[values.length + 1] = { - x: converted[values.length].x + 1, - value: converted[values.length].value, - id: converted[values.length].id - }; + converted[0] = { + x: converted[0].x - 1, + value: converted[0].value, + id: converted[0].id + }; + converted[values.length + 1] = { + x: converted[values.length].x + 1, + value: converted[values.length].value, + id: converted[values.length].id + }; - return converted; + return converted }; /** @@ -6953,906 +8739,1292 @@ ChartInternal.prototype.convertValuesToStep = function (values) { * @private */ ChartInternal.prototype.getRatio = function(type, d, asPercent = false) { - const $$ = this; - const api = $$.api; - let ratio = 0; - - if (d && api.data.shown.call(api).length) { - ratio = d.ratio || d.value; - - if (type === "arc") { - if ($$.hasType('gauge')) { - ratio = (d.endAngle - d.startAngle) / (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1)); - } else { - const total = $$.getTotalDataSum(); - - ratio = d.value / total; - } - } else if (type === "index") { - const total = $$.getTotalPerIndex($$.axis.getId(d.id)); - - d.ratio = isNumber(d.value) && total && total[d.index] > 0 ? - d.value / total[d.index] : 0; - - ratio = d.ratio; - } - } - - return asPercent && ratio ? ratio * 100 : ratio; -}; - -ChartInternal.prototype.updateDataAttributes = function (name, attrs) { - var $$ = this, - config = $$.config, - current = config['data_' + name]; - if (typeof attrs === 'undefined') { - return current; - } - Object.keys(attrs).forEach(function (id) { - current[id] = attrs[id]; - }); - $$.redraw({ - withLegend: true - }); - return current; -}; - -ChartInternal.prototype.load = function (targets, args) { - var $$ = this; - if (targets) { - // filter loading targets if needed - if (args.filter) { - targets = targets.filter(args.filter); - } - // set type if args.types || args.type specified - if (args.type || args.types) { - targets.forEach(function (t) { - var type = args.types && args.types[t.id] ? args.types[t.id] : args.type; - $$.setTargetType(t.id, type); - }); - } - // Update/Add data - $$.data.targets.forEach(function (d) { - for (var i = 0; i < targets.length; i++) { - if (d.id === targets[i].id) { - d.values = targets[i].values; - targets.splice(i, 1); - break; - } - } - }); - $$.data.targets = $$.data.targets.concat(targets); // add remained - } - - // Set targets - $$.updateTargets($$.data.targets); - - // Redraw with new targets - $$.redraw({withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true}); - - if (args.done) { args.done(); } -}; -ChartInternal.prototype.loadFromArgs = function (args) { - var $$ = this; - - $$.resetCache(); + const $$ = this; + const api = $$.api; + let ratio = 0; - if (args.data) { - $$.load($$.convertDataToTargets(args.data), args); - } - else if (args.url) { - $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) { - $$.load($$.convertDataToTargets(data), args); - }); - } - else if (args.json) { - $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args); - } - else if (args.rows) { - $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args); - } - else if (args.columns) { - $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args); - } - else { - $$.load(null, args); - } -}; -ChartInternal.prototype.unload = function (targetIds, done) { - var $$ = this; + if (d && api.data.shown.call(api).length) { + ratio = d.ratio || d.value; - $$.resetCache(); + if (type === 'arc') { + if ($$.hasType('gauge')) { + ratio = + (d.endAngle - d.startAngle) / + (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1)); + } else { + const total = $$.getTotalDataSum(); - if (!done) { - done = function () {}; - } - // filter existing target - targetIds = targetIds.filter(function (id) { return $$.hasTarget($$.data.targets, id); }); - // If no target, call done and return - if (!targetIds || targetIds.length === 0) { - done(); - return; - } - $$.svg.selectAll(targetIds.map(function (id) { return $$.selectorTarget(id); })) - .transition() - .style('opacity', 0) - .remove() - .call($$.endall, done); - targetIds.forEach(function (id) { - // Reset fadein for future load - $$.withoutFadeIn[id] = false; - // Remove target's elements - if ($$.legend) { - $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove(); - } - // Remove target - $$.data.targets = $$.data.targets.filter(function (t) { - return t.id !== id; - }); - }); -}; + ratio = d.value / total; + } + } else if (type === 'index') { + const total = $$.getTotalPerIndex($$.axis.getId(d.id)); -ChartInternal.prototype.getYDomainMin = function (targets) { - var $$ = this, config = $$.config, - ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), - j, k, baseId, idsInGroup, id, hasNegativeValue; - if (config.data_groups.length > 0) { - hasNegativeValue = $$.hasNegativeValueInTargets(targets); - for (j = 0; j < config.data_groups.length; j++) { - // Determine baseId - idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; }); - if (idsInGroup.length === 0) { continue; } - baseId = idsInGroup[0]; - // Consider negative values - if (hasNegativeValue && ys[baseId]) { - ys[baseId].forEach(function (v, i) { - ys[baseId][i] = v < 0 ? v : 0; - }); - } - // Compute min - for (k = 1; k < idsInGroup.length; k++) { - id = idsInGroup[k]; - if (! ys[id]) { continue; } - ys[id].forEach(function (v, i) { - if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) { - ys[baseId][i] += +v; - } - }); - } - } - } - return $$.d3.min(Object.keys(ys).map(function (key) { return $$.d3.min(ys[key]); })); -}; -ChartInternal.prototype.getYDomainMax = function (targets) { - var $$ = this, config = $$.config, - ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), - j, k, baseId, idsInGroup, id, hasPositiveValue; - if (config.data_groups.length > 0) { - hasPositiveValue = $$.hasPositiveValueInTargets(targets); - for (j = 0; j < config.data_groups.length; j++) { - // Determine baseId - idsInGroup = config.data_groups[j].filter(function (id) { return ids.indexOf(id) >= 0; }); - if (idsInGroup.length === 0) { continue; } - baseId = idsInGroup[0]; - // Consider positive values - if (hasPositiveValue && ys[baseId]) { - ys[baseId].forEach(function (v, i) { - ys[baseId][i] = v > 0 ? v : 0; - }); - } - // Compute max - for (k = 1; k < idsInGroup.length; k++) { - id = idsInGroup[k]; - if (! ys[id]) { continue; } - ys[id].forEach(function (v, i) { - if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) { - ys[baseId][i] += +v; - } - }); - } - } + d.ratio = + isNumber(d.value) && total && total[d.index] > 0 + ? d.value / total[d.index] + : 0; + + ratio = d.ratio; } - return $$.d3.max(Object.keys(ys).map(function (key) { return $$.d3.max(ys[key]); })); + } + + return asPercent && ratio ? ratio * 100 : ratio }; -ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) { - var $$ = this, config = $$.config; - if ($$.isAxisNormalized(axisId)) { - return [0, 100]; +ChartInternal.prototype.updateDataAttributes = function(name, attrs) { + var $$ = this, + config = $$.config, + current = config['data_' + name]; + if (typeof attrs === 'undefined') { + return current + } + Object.keys(attrs).forEach(function(id) { + current[id] = attrs[id]; + }); + $$.redraw({ + withLegend: true + }); + return current +}; + +ChartInternal.prototype.load = function(targets, args) { + var $$ = this; + if (targets) { + // filter loading targets if needed + if (args.filter) { + targets = targets.filter(args.filter); + } + // set type if args.types || args.type specified + if (args.type || args.types) { + targets.forEach(function(t) { + var type = args.types && args.types[t.id] ? args.types[t.id] : args.type; + $$.setTargetType(t.id, type); + }); } + // Update/Add data + $$.data.targets.forEach(function(d) { + for (var i = 0; i < targets.length; i++) { + if (d.id === targets[i].id) { + d.values = targets[i].values; + targets.splice(i, 1); + break + } + } + }); + $$.data.targets = $$.data.targets.concat(targets); // add remained + } - var targetsByAxisId = targets.filter(function (t) { return $$.axis.getId(t.id) === axisId; }), - yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId, - yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, - yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, - yDomainMin = $$.getYDomainMin(yTargets), - yDomainMax = $$.getYDomainMax(yTargets), - domain, domainLength, padding_top, padding_bottom, - center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, - yDomainAbs, lengths, diff, ratio, isAllPositive, isAllNegative, - isZeroBased = ($$.hasType('bar', yTargets) && config.bar_zerobased) || ($$.hasType('area', yTargets) && config.area_zerobased), - isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, - showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, - showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; + // Set targets + $$.updateTargets($$.data.targets); - // MEMO: avoid inverting domain unexpectedly - yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? (yDomainMin < yMax ? yDomainMin : yMax - 10) : yDomainMin; - yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? (yMin < yDomainMax ? yDomainMax : yMin + 10) : yDomainMax; + // Redraw with new targets + $$.redraw({ + withUpdateOrgXDomain: true, + withUpdateXDomain: true, + withLegend: true + }); - if (yTargets.length === 0) { // use current domain if target of axisId is none - return axisId === 'y2' ? $$.y2.domain() : $$.y.domain(); - } - if (isNaN(yDomainMin)) { // set minimum to zero when not number - yDomainMin = 0; - } - if (isNaN(yDomainMax)) { // set maximum to have same value as yDomainMin - yDomainMax = yDomainMin; + if (args.done) { + args.done(); + } +}; +ChartInternal.prototype.loadFromArgs = function(args) { + var $$ = this; + + $$.resetCache(); + + if (args.data) { + $$.load($$.convertDataToTargets(args.data), args); + } else if (args.url) { + $$.convertUrlToData( + args.url, + args.mimeType, + args.headers, + args.keys, + function(data) { + $$.load($$.convertDataToTargets(data), args); + } + ); + } else if (args.json) { + $$.load( + $$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), + args + ); + } else if (args.rows) { + $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args); + } else if (args.columns) { + $$.load( + $$.convertDataToTargets($$.convertColumnsToData(args.columns)), + args + ); + } else { + $$.load(null, args); + } +}; +ChartInternal.prototype.unload = function(targetIds, done) { + var $$ = this; + + $$.resetCache(); + + if (!done) { + done = function() {}; + } + // filter existing target + targetIds = targetIds.filter(function(id) { + return $$.hasTarget($$.data.targets, id) + }); + // If no target, call done and return + if (!targetIds || targetIds.length === 0) { + done(); + return + } + $$.svg + .selectAll( + targetIds.map(function(id) { + return $$.selectorTarget(id) + }) + ) + .transition() + .style('opacity', 0) + .remove() + .call($$.endall, done); + targetIds.forEach(function(id) { + // Reset fadein for future load + $$.withoutFadeIn[id] = false; + // Remove target's elements + if ($$.legend) { + $$.legend + .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)) + .remove(); } - if (yDomainMin === yDomainMax) { - yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0; + // Remove target + $$.data.targets = $$.data.targets.filter(function(t) { + return t.id !== id + }); + }); +}; + +ChartInternal.prototype.getYDomainMin = function(targets) { + var $$ = this, + config = $$.config, + ids = $$.mapToIds(targets), + ys = $$.getValuesAsIdKeyed(targets), + j, + k, + baseId, + idsInGroup, + id, + hasNegativeValue; + if (config.data_groups.length > 0) { + hasNegativeValue = $$.hasNegativeValueInTargets(targets); + for (j = 0; j < config.data_groups.length; j++) { + // Determine baseId + idsInGroup = config.data_groups[j].filter(function(id) { + return ids.indexOf(id) >= 0 + }); + if (idsInGroup.length === 0) { + continue + } + baseId = idsInGroup[0]; + // Consider negative values + if (hasNegativeValue && ys[baseId]) { + ys[baseId].forEach(function(v, i) { + ys[baseId][i] = v < 0 ? v : 0; + }); + } + // Compute min + for (k = 1; k < idsInGroup.length; k++) { + id = idsInGroup[k]; + if (!ys[id]) { + continue + } + ys[id].forEach(function(v, i) { + if ( + $$.axis.getId(id) === $$.axis.getId(baseId) && + ys[baseId] && + !(hasNegativeValue && +v > 0) + ) { + ys[baseId][i] += +v; + } + }); + } } - isAllPositive = yDomainMin >= 0 && yDomainMax >= 0; - isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; - - // Cancel zerobased if axis_*_min / axis_*_max specified - if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) { - isZeroBased = false; + } + return $$.d3.min( + Object.keys(ys).map(function(key) { + return $$.d3.min(ys[key]) + }) + ) +}; +ChartInternal.prototype.getYDomainMax = function(targets) { + var $$ = this, + config = $$.config, + ids = $$.mapToIds(targets), + ys = $$.getValuesAsIdKeyed(targets), + j, + k, + baseId, + idsInGroup, + id, + hasPositiveValue; + if (config.data_groups.length > 0) { + hasPositiveValue = $$.hasPositiveValueInTargets(targets); + for (j = 0; j < config.data_groups.length; j++) { + // Determine baseId + idsInGroup = config.data_groups[j].filter(function(id) { + return ids.indexOf(id) >= 0 + }); + if (idsInGroup.length === 0) { + continue + } + baseId = idsInGroup[0]; + // Consider positive values + if (hasPositiveValue && ys[baseId]) { + ys[baseId].forEach(function(v, i) { + ys[baseId][i] = v > 0 ? v : 0; + }); + } + // Compute max + for (k = 1; k < idsInGroup.length; k++) { + id = idsInGroup[k]; + if (!ys[id]) { + continue + } + ys[id].forEach(function(v, i) { + if ( + $$.axis.getId(id) === $$.axis.getId(baseId) && + ys[baseId] && + !(hasPositiveValue && +v < 0) + ) { + ys[baseId][i] += +v; + } + }); + } } + } + return $$.d3.max( + Object.keys(ys).map(function(key) { + return $$.d3.max(ys[key]) + }) + ) +}; +ChartInternal.prototype.getYDomain = function(targets, axisId, xDomain) { + var $$ = this, + config = $$.config; + + if ($$.isAxisNormalized(axisId)) { + return [0, 100] + } - // Bar/Area chart should be 0-based if all positive|negative - if (isZeroBased) { - if (isAllPositive) { yDomainMin = 0; } - if (isAllNegative) { yDomainMax = 0; } - } + var targetsByAxisId = targets.filter(function(t) { + return $$.axis.getId(t.id) === axisId + }), + yTargets = xDomain + ? $$.filterByXDomain(targetsByAxisId, xDomain) + : targetsByAxisId, + yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, + yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, + yDomainMin = $$.getYDomainMin(yTargets), + yDomainMax = $$.getYDomainMax(yTargets), + domain, + domainLength, + padding_top, + padding_bottom, + center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, + yDomainAbs, + lengths, + diff, + ratio, + isAllPositive, + isAllNegative, + isZeroBased = + ($$.hasType('bar', yTargets) && config.bar_zerobased) || + ($$.hasType('area', yTargets) && config.area_zerobased), + isInverted = + axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, + showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, + showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; + + // MEMO: avoid inverting domain unexpectedly + yDomainMin = isValue(yMin) + ? yMin + : isValue(yMax) + ? yDomainMin < yMax + ? yDomainMin + : yMax - 10 + : yDomainMin; + yDomainMax = isValue(yMax) + ? yMax + : isValue(yMin) + ? yMin < yDomainMax + ? yDomainMax + : yMin + 10 + : yDomainMax; + + if (yTargets.length === 0) { + // use current domain if target of axisId is none + return axisId === 'y2' ? $$.y2.domain() : $$.y.domain() + } + if (isNaN(yDomainMin)) { + // set minimum to zero when not number + yDomainMin = 0; + } + if (isNaN(yDomainMax)) { + // set maximum to have same value as yDomainMin + yDomainMax = yDomainMin; + } + if (yDomainMin === yDomainMax) { + yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0); + } + isAllPositive = yDomainMin >= 0 && yDomainMax >= 0; + isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; - domainLength = Math.abs(yDomainMax - yDomainMin); - padding_top = padding_bottom = domainLength * 0.1; + // Cancel zerobased if axis_*_min / axis_*_max specified + if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) { + isZeroBased = false; + } - if (typeof center !== 'undefined') { - yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); - yDomainMax = center + yDomainAbs; - yDomainMin = center - yDomainAbs; + // Bar/Area chart should be 0-based if all positive|negative + if (isZeroBased) { + if (isAllPositive) { + yDomainMin = 0; + } + if (isAllNegative) { + yDomainMax = 0; } - // add padding for data label - if (showHorizontalDataLabel) { - lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width'); - diff = diffDomain($$.y.range()); - ratio = [lengths[0] / diff, lengths[1] / diff]; - padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1])); - padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1])); - } else if (showVerticalDataLabel) { - lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height'); + } - const pixelsToAxisPadding = $$.getY( - config[`axis_${axisId}_type`], - // input domain as pixels - [0, config.axis_rotated ? $$.width : $$.height ], - // output range as axis padding - [ 0, domainLength ] - ); + domainLength = Math.abs(yDomainMax - yDomainMin); + padding_top = padding_bottom = domainLength * 0.1; - padding_top += pixelsToAxisPadding(lengths[1]); - padding_bottom += pixelsToAxisPadding(lengths[0]); - } - if (axisId === 'y' && notEmpty(config.axis_y_padding)) { - padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength); - padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength); - } - if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) { - padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength); - padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength); - } - // Bar/Area chart should be 0-based if all positive|negative - if (isZeroBased) { - if (isAllPositive) { padding_bottom = yDomainMin; } - if (isAllNegative) { padding_top = -yDomainMax; } - } - domain = [yDomainMin - padding_bottom, yDomainMax + padding_top]; - return isInverted ? domain.reverse() : domain; -}; -ChartInternal.prototype.getXDomainMin = function (targets) { - var $$ = this, config = $$.config; - return isDefined(config.axis_x_min) ? - ($$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min) : - $$.d3.min(targets, function (t) { return $$.d3.min(t.values, function (v) { return v.x; }); }); -}; -ChartInternal.prototype.getXDomainMax = function (targets) { - var $$ = this, config = $$.config; - return isDefined(config.axis_x_max) ? - ($$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max) : - $$.d3.max(targets, function (t) { return $$.d3.max(t.values, function (v) { return v.x; }); }); -}; -ChartInternal.prototype.getXDomainPadding = function (domain) { - var $$ = this, config = $$.config, - diff = domain[1] - domain[0], - maxDataCount, padding, paddingLeft, paddingRight; - if ($$.isCategorized()) { - padding = 0; - } else if ($$.hasType('bar')) { - maxDataCount = $$.getMaxDataCount(); - padding = maxDataCount > 1 ? (diff / (maxDataCount - 1)) / 2 : 0.5; - } else { - padding = diff * 0.01; + if (typeof center !== 'undefined') { + yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax)); + yDomainMax = center + yDomainAbs; + yDomainMin = center - yDomainAbs; + } + // add padding for data label + if (showHorizontalDataLabel) { + lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width'); + diff = diffDomain($$.y.range()); + ratio = [lengths[0] / diff, lengths[1] / diff]; + padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1])); + padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1])); + } else if (showVerticalDataLabel) { + lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height'); + + const pixelsToAxisPadding = $$.getY( + config[`axis_${axisId}_type`], + // input domain as pixels + [0, config.axis_rotated ? $$.width : $$.height], + // output range as axis padding + [0, domainLength] + ); + + padding_top += pixelsToAxisPadding(lengths[1]); + padding_bottom += pixelsToAxisPadding(lengths[0]); + } + if (axisId === 'y' && notEmpty(config.axis_y_padding)) { + padding_top = $$.axis.getPadding( + config.axis_y_padding, + 'top', + padding_top, + domainLength + ); + padding_bottom = $$.axis.getPadding( + config.axis_y_padding, + 'bottom', + padding_bottom, + domainLength + ); + } + if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) { + padding_top = $$.axis.getPadding( + config.axis_y2_padding, + 'top', + padding_top, + domainLength + ); + padding_bottom = $$.axis.getPadding( + config.axis_y2_padding, + 'bottom', + padding_bottom, + domainLength + ); + } + // Bar/Area chart should be 0-based if all positive|negative + if (isZeroBased) { + if (isAllPositive) { + padding_bottom = yDomainMin; + } + if (isAllNegative) { + padding_top = -yDomainMax; } - if (typeof config.axis_x_padding === 'object' && notEmpty(config.axis_x_padding)) { - paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding; - paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding; - } else if (typeof config.axis_x_padding === 'number') { - paddingLeft = paddingRight = config.axis_x_padding; + } + domain = [yDomainMin - padding_bottom, yDomainMax + padding_top]; + return isInverted ? domain.reverse() : domain +}; +ChartInternal.prototype.getXDomainMin = function(targets) { + var $$ = this, + config = $$.config; + return isDefined(config.axis_x_min) + ? $$.isTimeSeries() + ? this.parseDate(config.axis_x_min) + : config.axis_x_min + : $$.d3.min(targets, function(t) { + return $$.d3.min(t.values, function(v) { + return v.x + }) + }) +}; +ChartInternal.prototype.getXDomainMax = function(targets) { + var $$ = this, + config = $$.config; + return isDefined(config.axis_x_max) + ? $$.isTimeSeries() + ? this.parseDate(config.axis_x_max) + : config.axis_x_max + : $$.d3.max(targets, function(t) { + return $$.d3.max(t.values, function(v) { + return v.x + }) + }) +}; +ChartInternal.prototype.getXDomainPadding = function(domain) { + var $$ = this, + config = $$.config, + diff = domain[1] - domain[0], + maxDataCount, + padding, + paddingLeft, + paddingRight; + if ($$.isCategorized()) { + padding = 0; + } else if ($$.hasType('bar')) { + maxDataCount = $$.getMaxDataCount(); + padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5; + } else { + padding = diff * 0.01; + } + if ( + typeof config.axis_x_padding === 'object' && + notEmpty(config.axis_x_padding) + ) { + paddingLeft = isValue(config.axis_x_padding.left) + ? config.axis_x_padding.left + : padding; + paddingRight = isValue(config.axis_x_padding.right) + ? config.axis_x_padding.right + : padding; + } else if (typeof config.axis_x_padding === 'number') { + paddingLeft = paddingRight = config.axis_x_padding; + } else { + paddingLeft = paddingRight = padding; + } + return { left: paddingLeft, right: paddingRight } +}; +ChartInternal.prototype.getXDomain = function(targets) { + var $$ = this, + xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], + firstX = xDomain[0], + lastX = xDomain[1], + padding = $$.getXDomainPadding(xDomain), + min = 0, + max = 0; + // show center of x domain if min and max are the same + if (firstX - lastX === 0 && !$$.isCategorized()) { + if ($$.isTimeSeries()) { + firstX = new Date(firstX.getTime() * 0.5); + lastX = new Date(lastX.getTime() * 1.5); } else { - paddingLeft = paddingRight = padding; - } - return {left: paddingLeft, right: paddingRight}; -}; -ChartInternal.prototype.getXDomain = function (targets) { - var $$ = this, - xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], - firstX = xDomain[0], lastX = xDomain[1], - padding = $$.getXDomainPadding(xDomain), - min = 0, max = 0; - // show center of x domain if min and max are the same - if ((firstX - lastX) === 0 && !$$.isCategorized()) { - if ($$.isTimeSeries()) { - firstX = new Date(firstX.getTime() * 0.5); - lastX = new Date(lastX.getTime() * 1.5); - } else { - firstX = firstX === 0 ? 1 : (firstX * 0.5); - lastX = lastX === 0 ? -1 : (lastX * 1.5); - } + firstX = firstX === 0 ? 1 : firstX * 0.5; + lastX = lastX === 0 ? -1 : lastX * 1.5; } - if (firstX || firstX === 0) { - min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left; - } - if (lastX || lastX === 0) { - max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right; - } - return [min, max]; -}; -ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) { - var $$ = this, config = $$.config; - - if (withUpdateOrgXDomain) { - $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets))); - $$.orgXDomain = $$.x.domain(); - if (config.zoom_enabled) { $$.zoom.update(); } - $$.subX.domain($$.x.domain()); - if ($$.brush) { $$.brush.updateScale($$.subX); } - } - if (withUpdateXDomain) { - $$.x.domain(domain ? domain : (!$$.brush || $$.brush.empty()) ? $$.orgXDomain : $$.brush.selectionAsValue()); - } - - // Trim domain when too big by zoom mousemove event - if (withTrim) { $$.x.domain($$.trimXDomain($$.x.orgDomain())); } - - return $$.x.domain(); -}; -ChartInternal.prototype.trimXDomain = function (domain) { - var zoomDomain = this.getZoomDomain(), - min = zoomDomain[0], max = zoomDomain[1]; - if (domain[0] <= min) { - domain[1] = +domain[1] + (min - domain[0]); - domain[0] = min; - } - if (max <= domain[1]) { - domain[0] = +domain[0] - (domain[1] - max); - domain[1] = max; - } - return domain; -}; - -ChartInternal.prototype.drag = function (mouse) { - var $$ = this, config = $$.config, main = $$.main, d3 = $$.d3; - var sx, sy, mx, my, minX, maxX, minY, maxY; - - if ($$.hasArcType()) { return; } - if (!config.data_selection_enabled) { return; } // do nothing if not selectable - if (!config.data_selection_multiple) { return; } // skip when single selection because drag is used for multiple selection - - sx = $$.dragStart[0]; - sy = $$.dragStart[1]; - mx = mouse[0]; - my = mouse[1]; - minX = Math.min(sx, mx); - maxX = Math.max(sx, mx); - minY = (config.data_selection_grouped) ? $$.margin.top : Math.min(sy, my); - maxY = (config.data_selection_grouped) ? $$.height : Math.max(sy, my); - - main.select('.' + CLASS.dragarea) - .attr('x', minX) - .attr('y', minY) - .attr('width', maxX - minX) - .attr('height', maxY - minY); - // TODO: binary search when multiple xs - main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape) - .filter(function (d) { return config.data_selection_isselectable(d); }) - .each(function (d, i) { - var shape = d3.select(this), - isSelected = shape.classed(CLASS.SELECTED), - isIncluded = shape.classed(CLASS.INCLUDED), - _x, _y, _w, _h, toggle, isWithin = false, box; - if (shape.classed(CLASS.circle)) { - _x = shape.attr("cx") * 1; - _y = shape.attr("cy") * 1; - toggle = $$.togglePoint; - isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; - } - else if (shape.classed(CLASS.bar)) { - box = getPathBox(this); - _x = box.x; - _y = box.y; - _w = box.width; - _h = box.height; - toggle = $$.togglePath; - isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY); - } else { - // line/area selection not supported yet - return; - } - if (isWithin ^ isIncluded) { - shape.classed(CLASS.INCLUDED, !isIncluded); - // TODO: included/unincluded callback here - shape.classed(CLASS.SELECTED, !isSelected); - toggle.call($$, !isSelected, shape, d, i); - } - }); + } + if (firstX || firstX === 0) { + min = $$.isTimeSeries() + ? new Date(firstX.getTime() - padding.left) + : firstX - padding.left; + } + if (lastX || lastX === 0) { + max = $$.isTimeSeries() + ? new Date(lastX.getTime() + padding.right) + : lastX + padding.right; + } + return [min, max] +}; +ChartInternal.prototype.updateXDomain = function( + targets, + withUpdateXDomain, + withUpdateOrgXDomain, + withTrim, + domain +) { + var $$ = this, + config = $$.config; + + if (withUpdateOrgXDomain) { + $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets))); + $$.orgXDomain = $$.x.domain(); + if (config.zoom_enabled) { + $$.zoom.update(); + } + $$.subX.domain($$.x.domain()); + if ($$.brush) { + $$.brush.updateScale($$.subX); + } + } + if (withUpdateXDomain) { + $$.x.domain( + domain + ? domain + : !$$.brush || $$.brush.empty() + ? $$.orgXDomain + : $$.brush.selectionAsValue() + ); + } + + // Trim domain when too big by zoom mousemove event + if (withTrim) { + $$.x.domain($$.trimXDomain($$.x.orgDomain())); + } + + return $$.x.domain() +}; +ChartInternal.prototype.trimXDomain = function(domain) { + var zoomDomain = this.getZoomDomain(), + min = zoomDomain[0], + max = zoomDomain[1]; + if (domain[0] <= min) { + domain[1] = +domain[1] + (min - domain[0]); + domain[0] = min; + } + if (max <= domain[1]) { + domain[0] = +domain[0] - (domain[1] - max); + domain[1] = max; + } + return domain }; -ChartInternal.prototype.dragstart = function (mouse) { - var $$ = this, config = $$.config; - if ($$.hasArcType()) { return; } - if (! config.data_selection_enabled) { return; } // do nothing if not selectable - $$.dragStart = mouse; - $$.main.select('.' + CLASS.chart).append('rect') - .attr('class', CLASS.dragarea) - .style('opacity', 0.1); - $$.dragging = true; -}; - -ChartInternal.prototype.dragend = function () { - var $$ = this, config = $$.config; - if ($$.hasArcType()) { return; } - if (! config.data_selection_enabled) { return; } // do nothing if not selectable - $$.main.select('.' + CLASS.dragarea) - .transition().duration(100) - .style('opacity', 0) - .remove(); - $$.main.selectAll('.' + CLASS.shape) - .classed(CLASS.INCLUDED, false); - $$.dragging = false; -}; - -ChartInternal.prototype.getYFormat = function (forArc) { - var $$ = this, - formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, - formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format; - return function (v, ratio, id) { - var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY; - return format.call($$, v, ratio); - }; -}; -ChartInternal.prototype.yFormat = function (v) { - var $$ = this, config = $$.config, - format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat; - return format(v); -}; -ChartInternal.prototype.y2Format = function (v) { - var $$ = this, config = $$.config, - format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat; - return format(v); -}; -ChartInternal.prototype.defaultValueFormat = function (v) { - return isValue(v) ? +v : ""; -}; -ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) { - return (ratio * 100).toFixed(1) + '%'; -}; -ChartInternal.prototype.dataLabelFormat = function (targetId) { - var $$ = this, data_labels = $$.config.data_labels, - format, defaultFormat = function (v) { return isValue(v) ? +v : ""; }; - // find format according to axis id - if (typeof data_labels.format === 'function') { - format = data_labels.format; - } else if (typeof data_labels.format === 'object') { - if (data_labels.format[targetId]) { - format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId]; - } else { - format = function () { return ''; }; - } - } else { - format = defaultFormat; - } - return format; -}; - -ChartInternal.prototype.initGrid = function () { - var $$ = this, config = $$.config, d3 = $$.d3; - $$.grid = $$.main.append('g') - .attr("clip-path", $$.clipPathForGrid) - .attr('class', CLASS.grid); - if (config.grid_x_show) { - $$.grid.append("g").attr("class", CLASS.xgrids); - } - if (config.grid_y_show) { - $$.grid.append('g').attr('class', CLASS.ygrids); - } - if (config.grid_focus_show) { - $$.grid.append('g') - .attr("class", CLASS.xgridFocus) - .append('line') - .attr('class', CLASS.xgridFocus); - } - $$.xgrid = d3.selectAll([]); - if (!config.grid_lines_front) { $$.initGridLines(); } -}; -ChartInternal.prototype.initGridLines = function () { - var $$ = this, d3 = $$.d3; - $$.gridLines = $$.main.append('g') - .attr("clip-path", $$.clipPathForGrid) - .attr('class', CLASS.grid + ' ' + CLASS.gridLines); - $$.gridLines.append('g').attr("class", CLASS.xgridLines); - $$.gridLines.append('g').attr('class', CLASS.ygridLines); - $$.xgridLines = d3.selectAll([]); -}; -ChartInternal.prototype.updateXGrid = function (withoutUpdate) { - var $$ = this, config = $$.config, d3 = $$.d3, - xgridData = $$.generateGridData(config.grid_x_type, $$.x), - tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; - - $$.xgridAttr = config.axis_rotated ? { - 'x1': 0, - 'x2': $$.width, - 'y1': function (d) { return $$.x(d) - tickOffset; }, - 'y2': function (d) { return $$.x(d) - tickOffset; } - } : { - 'x1': function (d) { return $$.x(d) + tickOffset; }, - 'x2': function (d) { return $$.x(d) + tickOffset; }, - 'y1': 0, - 'y2': $$.height - }; - $$.xgridAttr.opacity = function () { - var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1'); - return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1; - }; - - var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid) - .data(xgridData); - var xgridEnter = xgrid.enter().append('line') - .attr("class", CLASS.xgrid) - .attr('x1', $$.xgridAttr.x1) - .attr('x2', $$.xgridAttr.x2) - .attr('y1', $$.xgridAttr.y1) - .attr('y2', $$.xgridAttr.y2) - .style("opacity", 0); - $$.xgrid = xgridEnter.merge(xgrid); - if (!withoutUpdate) { - $$.xgrid - .attr('x1', $$.xgridAttr.x1) - .attr('x2', $$.xgridAttr.x2) - .attr('y1', $$.xgridAttr.y1) - .attr('y2', $$.xgridAttr.y2) - .style("opacity", $$.xgridAttr.opacity); - } - xgrid.exit().remove(); -}; - -ChartInternal.prototype.updateYGrid = function () { - var $$ = this, config = $$.config, - gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks); - var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid) - .data(gridValues); - var ygridEnter = ygrid.enter().append('line') - // TODO: x1, x2, y1, y2, opacity need to be set here maybe - .attr('class', CLASS.ygrid); - $$.ygrid = ygridEnter.merge(ygrid); - $$.ygrid - .attr("x1", config.axis_rotated ? $$.y : 0) - .attr("x2", config.axis_rotated ? $$.y : $$.width) - .attr("y1", config.axis_rotated ? 0 : $$.y) - .attr("y2", config.axis_rotated ? $$.height : $$.y); - ygrid.exit().remove(); - $$.smoothLines($$.ygrid, 'grid'); -}; - -ChartInternal.prototype.gridTextAnchor = function (d) { - return d.position ? d.position : "end"; -}; -ChartInternal.prototype.gridTextDx = function (d) { - return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4; -}; -ChartInternal.prototype.xGridTextX = function (d) { - return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0; -}; -ChartInternal.prototype.yGridTextX = function (d) { - return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width; -}; -ChartInternal.prototype.updateGrid = function (duration) { - var $$ = this, main = $$.main, config = $$.config, - xgridLine, xgridLineEnter, ygridLine, ygridLineEnter, - xv = $$.xv.bind($$), yv = $$.yv.bind($$), - xGridTextX = $$.xGridTextX.bind($$), yGridTextX = $$.yGridTextX.bind($$); - - // hide if arc type - $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); - - main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); - if (config.grid_x_show) { - $$.updateXGrid(); - } - xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine) - .data(config.grid_x_lines); - // enter - xgridLineEnter = xgridLine.enter().append('g') - .attr("class", function (d) { return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : ''); }); - xgridLineEnter.append('line') - .attr("x1", config.axis_rotated ? 0 : xv) - .attr("x2", config.axis_rotated ? $$.width : xv) - .attr("y1", config.axis_rotated ? xv : 0) - .attr("y2", config.axis_rotated ? xv : $$.height) - .style("opacity", 0); - xgridLineEnter.append('text') - .attr("text-anchor", $$.gridTextAnchor) - .attr("transform", config.axis_rotated ? "" : "rotate(-90)") - .attr("x", config.axis_rotated ? yGridTextX : xGridTextX) - .attr("y", xv) - .attr('dx', $$.gridTextDx) - .attr('dy', -5) - .style("opacity", 0); - // udpate - $$.xgridLines = xgridLineEnter.merge(xgridLine); - // done in d3.transition() of the end of this function - // exit - xgridLine.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); +ChartInternal.prototype.drag = function(mouse) { + var $$ = this, + config = $$.config, + main = $$.main, + d3 = $$.d3; + var sx, sy, mx, my, minX, maxX, minY, maxY; - // Y-Grid - if (config.grid_y_show) { - $$.updateYGrid(); - } - ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine) - .data(config.grid_y_lines); - // enter - ygridLineEnter = ygridLine.enter().append('g') - .attr("class", function (d) { return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : ''); }); - ygridLineEnter.append('line') - .attr("x1", config.axis_rotated ? yv : 0) - .attr("x2", config.axis_rotated ? yv : $$.width) - .attr("y1", config.axis_rotated ? 0 : yv) - .attr("y2", config.axis_rotated ? $$.height : yv) - .style("opacity", 0); - ygridLineEnter.append('text') - .attr("text-anchor", $$.gridTextAnchor) - .attr("transform", config.axis_rotated ? "rotate(-90)" : "") - .attr("x", config.axis_rotated ? xGridTextX : yGridTextX) - .attr("y", yv) - .attr('dx', $$.gridTextDx) - .attr('dy', -5) - .style("opacity", 0); - // update - $$.ygridLines = ygridLineEnter.merge(ygridLine); - $$.ygridLines.select('line') - .transition().duration(duration) - .attr("x1", config.axis_rotated ? yv : 0) - .attr("x2", config.axis_rotated ? yv : $$.width) - .attr("y1", config.axis_rotated ? 0 : yv) - .attr("y2", config.axis_rotated ? $$.height : yv) - .style("opacity", 1); - $$.ygridLines.select('text') - .transition().duration(duration) - .attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)) - .attr("y", yv) - .text(function (d) { return d.text; }) - .style("opacity", 1); - // exit - ygridLine.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); + if ($$.hasArcType()) { + return + } + if (!config.data_selection_enabled) { + return + } // do nothing if not selectable + if (!config.data_selection_multiple) { + return + } // skip when single selection because drag is used for multiple selection + + sx = $$.dragStart[0]; + sy = $$.dragStart[1]; + mx = mouse[0]; + my = mouse[1]; + minX = Math.min(sx, mx); + maxX = Math.max(sx, mx); + minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my); + maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my); + + main + .select('.' + CLASS.dragarea) + .attr('x', minX) + .attr('y', minY) + .attr('width', maxX - minX) + .attr('height', maxY - minY); + // TODO: binary search when multiple xs + main + .selectAll('.' + CLASS.shapes) + .selectAll('.' + CLASS.shape) + .filter(function(d) { + return config.data_selection_isselectable(d) + }) + .each(function(d, i) { + var shape = d3.select(this), + isSelected = shape.classed(CLASS.SELECTED), + isIncluded = shape.classed(CLASS.INCLUDED), + _x, + _y, + _w, + _h, + toggle, + isWithin = false, + box; + if (shape.classed(CLASS.circle)) { + _x = shape.attr('cx') * 1; + _y = shape.attr('cy') * 1; + toggle = $$.togglePoint; + isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; + } else if (shape.classed(CLASS.bar)) { + box = getPathBox(this); + _x = box.x; + _y = box.y; + _w = box.width; + _h = box.height; + toggle = $$.togglePath; + isWithin = + !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY); + } else { + // line/area selection not supported yet + return + } + if (isWithin ^ isIncluded) { + shape.classed(CLASS.INCLUDED, !isIncluded); + // TODO: included/unincluded callback here + shape.classed(CLASS.SELECTED, !isSelected); + toggle.call($$, !isSelected, shape, d, i); + } + }); }; -ChartInternal.prototype.redrawGrid = function (withTransition, transition) { - var $$ = this, config = $$.config, xv = $$.xv.bind($$), - lines = $$.xgridLines.select('line'), - texts = $$.xgridLines.select('text'); - return [ - (withTransition ? lines.transition(transition) : lines) - .attr("x1", config.axis_rotated ? 0 : xv) - .attr("x2", config.axis_rotated ? $$.width : xv) - .attr("y1", config.axis_rotated ? xv : 0) - .attr("y2", config.axis_rotated ? xv : $$.height) - .style("opacity", 1), - (withTransition ? texts.transition(transition) : texts) - .attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)) - .attr("y", xv) - .text(function (d) { return d.text; }) - .style("opacity", 1) - ]; -}; -ChartInternal.prototype.showXGridFocus = function (selectedData) { - var $$ = this, config = $$.config, - dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); }), - focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), - xx = $$.xx.bind($$); - if (! config.tooltip_show) { return; } - // Hide when stanford plot exists - if ($$.hasType('stanford') || $$.hasArcType()) { return; } - focusEl - .style("visibility", "visible") - .data([dataToShow[0]]) - .attr(config.axis_rotated ? 'y1' : 'x1', xx) - .attr(config.axis_rotated ? 'y2' : 'x2', xx); - $$.smoothLines(focusEl, 'grid'); -}; -ChartInternal.prototype.hideXGridFocus = function () { - this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); -}; -ChartInternal.prototype.updateXgridFocus = function () { - var $$ = this, config = $$.config; - $$.main.select('line.' + CLASS.xgridFocus) - .attr("x1", config.axis_rotated ? 0 : -10) - .attr("x2", config.axis_rotated ? $$.width : -10) - .attr("y1", config.axis_rotated ? -10 : 0) - .attr("y2", config.axis_rotated ? -10 : $$.height); -}; -ChartInternal.prototype.generateGridData = function (type, scale) { - var $$ = this, - gridData = [], xDomain, firstYear, lastYear, i, - tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size(); - if (type === 'year') { - xDomain = $$.getXDomain(); - firstYear = xDomain[0].getFullYear(); - lastYear = xDomain[1].getFullYear(); - for (i = firstYear; i <= lastYear; i++) { - gridData.push(new Date(i + '-01-01 00:00:00')); - } - } else { - gridData = scale.ticks(10); - if (gridData.length > tickNum) { // use only int - gridData = gridData.filter(function (d) { return ("" + d).indexOf('.') < 0; }); - } - } - return gridData; + +ChartInternal.prototype.dragstart = function(mouse) { + var $$ = this, + config = $$.config; + if ($$.hasArcType()) { + return + } + if (!config.data_selection_enabled) { + return + } // do nothing if not selectable + $$.dragStart = mouse; + $$.main + .select('.' + CLASS.chart) + .append('rect') + .attr('class', CLASS.dragarea) + .style('opacity', 0.1); + $$.dragging = true; +}; + +ChartInternal.prototype.dragend = function() { + var $$ = this, + config = $$.config; + if ($$.hasArcType()) { + return + } + if (!config.data_selection_enabled) { + return + } // do nothing if not selectable + $$.main + .select('.' + CLASS.dragarea) + .transition() + .duration(100) + .style('opacity', 0) + .remove(); + $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false); + $$.dragging = false; +}; + +ChartInternal.prototype.getYFormat = function(forArc) { + var $$ = this, + formatForY = + forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, + formatForY2 = + forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format; + return function(v, ratio, id) { + var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY; + return format.call($$, v, ratio) + } }; -ChartInternal.prototype.getGridFilterToRemove = function (params) { - return params ? function (line) { - var found = false; - [].concat(params).forEach(function (param) { - if ((('value' in param && line.value === param.value) || ('class' in param && line['class'] === param['class']))) { - found = true; - } - }); - return found; - } : function () { return true; }; -}; -ChartInternal.prototype.removeGridLines = function (params, forX) { - var $$ = this, config = $$.config, - toRemove = $$.getGridFilterToRemove(params), - toShow = function (line) { return !toRemove(line); }, - classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, - classLine = forX ? CLASS.xgridLine : CLASS.ygridLine; - $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove) - .transition().duration(config.transition_duration) - .style('opacity', 0).remove(); - if (forX) { - config.grid_x_lines = config.grid_x_lines.filter(toShow); +ChartInternal.prototype.yFormat = function(v) { + var $$ = this, + config = $$.config, + format = config.axis_y_tick_format + ? config.axis_y_tick_format + : $$.defaultValueFormat; + return format(v) +}; +ChartInternal.prototype.y2Format = function(v) { + var $$ = this, + config = $$.config, + format = config.axis_y2_tick_format + ? config.axis_y2_tick_format + : $$.defaultValueFormat; + return format(v) +}; +ChartInternal.prototype.defaultValueFormat = function(v) { + return isValue(v) ? +v : '' +}; +ChartInternal.prototype.defaultArcValueFormat = function(v, ratio) { + return (ratio * 100).toFixed(1) + '%' +}; +ChartInternal.prototype.dataLabelFormat = function(targetId) { + var $$ = this, + data_labels = $$.config.data_labels, + format, + defaultFormat = function(v) { + return isValue(v) ? +v : '' + }; + // find format according to axis id + if (typeof data_labels.format === 'function') { + format = data_labels.format; + } else if (typeof data_labels.format === 'object') { + if (data_labels.format[targetId]) { + format = + data_labels.format[targetId] === true + ? defaultFormat + : data_labels.format[targetId]; } else { - config.grid_y_lines = config.grid_y_lines.filter(toShow); + format = function() { + return '' + }; } + } else { + format = defaultFormat; + } + return format +}; + +ChartInternal.prototype.initGrid = function() { + var $$ = this, + config = $$.config, + d3 = $$.d3; + $$.grid = $$.main + .append('g') + .attr('clip-path', $$.clipPathForGrid) + .attr('class', CLASS.grid); + if (config.grid_x_show) { + $$.grid.append('g').attr('class', CLASS.xgrids); + } + if (config.grid_y_show) { + $$.grid.append('g').attr('class', CLASS.ygrids); + } + if (config.grid_focus_show) { + $$.grid + .append('g') + .attr('class', CLASS.xgridFocus) + .append('line') + .attr('class', CLASS.xgridFocus); + } + $$.xgrid = d3.selectAll([]); + if (!config.grid_lines_front) { + $$.initGridLines(); + } }; - -ChartInternal.prototype.initEventRect = function () { - var $$ = this, config = $$.config; - - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.eventRects) - .style('fill-opacity', 0); - $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect') - .attr('class', CLASS.eventRect); - - // event rect handle zoom event as well - if (config.zoom_enabled && $$.zoom) { - $$.eventRect.call($$.zoom).on("dblclick.zoom", null); - if (config.zoom_initialRange) { - // WORKAROUND: Add transition to apply transform immediately when no subchart - $$.eventRect.transition().duration(0).call( - $$.zoom.transform, $$.zoomTransform(config.zoom_initialRange) - ); +ChartInternal.prototype.initGridLines = function() { + var $$ = this, + d3 = $$.d3; + $$.gridLines = $$.main + .append('g') + .attr('clip-path', $$.clipPathForGrid) + .attr('class', CLASS.grid + ' ' + CLASS.gridLines); + $$.gridLines.append('g').attr('class', CLASS.xgridLines); + $$.gridLines.append('g').attr('class', CLASS.ygridLines); + $$.xgridLines = d3.selectAll([]); +}; +ChartInternal.prototype.updateXGrid = function(withoutUpdate) { + var $$ = this, + config = $$.config, + d3 = $$.d3, + xgridData = $$.generateGridData(config.grid_x_type, $$.x), + tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; + + $$.xgridAttr = config.axis_rotated + ? { + x1: 0, + x2: $$.width, + y1: function(d) { + return $$.x(d) - tickOffset + }, + y2: function(d) { + return $$.x(d) - tickOffset } + } + : { + x1: function(d) { + return $$.x(d) + tickOffset + }, + x2: function(d) { + return $$.x(d) + tickOffset + }, + y1: 0, + y2: $$.height + }; + $$.xgridAttr.opacity = function() { + var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1'); + return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1 + }; + + var xgrid = $$.main + .select('.' + CLASS.xgrids) + .selectAll('.' + CLASS.xgrid) + .data(xgridData); + var xgridEnter = xgrid + .enter() + .append('line') + .attr('class', CLASS.xgrid) + .attr('x1', $$.xgridAttr.x1) + .attr('x2', $$.xgridAttr.x2) + .attr('y1', $$.xgridAttr.y1) + .attr('y2', $$.xgridAttr.y2) + .style('opacity', 0); + $$.xgrid = xgridEnter.merge(xgrid); + if (!withoutUpdate) { + $$.xgrid + .attr('x1', $$.xgridAttr.x1) + .attr('x2', $$.xgridAttr.x2) + .attr('y1', $$.xgridAttr.y1) + .attr('y2', $$.xgridAttr.y2) + .style('opacity', $$.xgridAttr.opacity); + } + xgrid.exit().remove(); +}; + +ChartInternal.prototype.updateYGrid = function() { + var $$ = this, + config = $$.config, + gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks); + var ygrid = $$.main + .select('.' + CLASS.ygrids) + .selectAll('.' + CLASS.ygrid) + .data(gridValues); + var ygridEnter = ygrid + .enter() + .append('line') + // TODO: x1, x2, y1, y2, opacity need to be set here maybe + .attr('class', CLASS.ygrid); + $$.ygrid = ygridEnter.merge(ygrid); + $$.ygrid + .attr('x1', config.axis_rotated ? $$.y : 0) + .attr('x2', config.axis_rotated ? $$.y : $$.width) + .attr('y1', config.axis_rotated ? 0 : $$.y) + .attr('y2', config.axis_rotated ? $$.height : $$.y); + ygrid.exit().remove(); + $$.smoothLines($$.ygrid, 'grid'); +}; + +ChartInternal.prototype.gridTextAnchor = function(d) { + return d.position ? d.position : 'end' +}; +ChartInternal.prototype.gridTextDx = function(d) { + return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4 +}; +ChartInternal.prototype.xGridTextX = function(d) { + return d.position === 'start' + ? -this.height + : d.position === 'middle' + ? -this.height / 2 + : 0 +}; +ChartInternal.prototype.yGridTextX = function(d) { + return d.position === 'start' + ? 0 + : d.position === 'middle' + ? this.width / 2 + : this.width +}; +ChartInternal.prototype.updateGrid = function(duration) { + var $$ = this, + main = $$.main, + config = $$.config, + xgridLine, + xgridLineEnter, + ygridLine, + ygridLineEnter, + xv = $$.xv.bind($$), + yv = $$.yv.bind($$), + xGridTextX = $$.xGridTextX.bind($$), + yGridTextX = $$.yGridTextX.bind($$); + + // hide if arc type + $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); + + main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); + if (config.grid_x_show) { + $$.updateXGrid(); + } + xgridLine = main + .select('.' + CLASS.xgridLines) + .selectAll('.' + CLASS.xgridLine) + .data(config.grid_x_lines); + // enter + xgridLineEnter = xgridLine + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '') + }); + xgridLineEnter + .append('line') + .attr('x1', config.axis_rotated ? 0 : xv) + .attr('x2', config.axis_rotated ? $$.width : xv) + .attr('y1', config.axis_rotated ? xv : 0) + .attr('y2', config.axis_rotated ? xv : $$.height) + .style('opacity', 0); + xgridLineEnter + .append('text') + .attr('text-anchor', $$.gridTextAnchor) + .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') + .attr('x', config.axis_rotated ? yGridTextX : xGridTextX) + .attr('y', xv) + .attr('dx', $$.gridTextDx) + .attr('dy', -5) + .style('opacity', 0); + // udpate + $$.xgridLines = xgridLineEnter.merge(xgridLine); + // done in d3.transition() of the end of this function + // exit + xgridLine + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); + + // Y-Grid + if (config.grid_y_show) { + $$.updateYGrid(); + } + ygridLine = main + .select('.' + CLASS.ygridLines) + .selectAll('.' + CLASS.ygridLine) + .data(config.grid_y_lines); + // enter + ygridLineEnter = ygridLine + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '') + }); + ygridLineEnter + .append('line') + .attr('x1', config.axis_rotated ? yv : 0) + .attr('x2', config.axis_rotated ? yv : $$.width) + .attr('y1', config.axis_rotated ? 0 : yv) + .attr('y2', config.axis_rotated ? $$.height : yv) + .style('opacity', 0); + ygridLineEnter + .append('text') + .attr('text-anchor', $$.gridTextAnchor) + .attr('transform', config.axis_rotated ? 'rotate(-90)' : '') + .attr('x', config.axis_rotated ? xGridTextX : yGridTextX) + .attr('y', yv) + .attr('dx', $$.gridTextDx) + .attr('dy', -5) + .style('opacity', 0); + // update + $$.ygridLines = ygridLineEnter.merge(ygridLine); + $$.ygridLines + .select('line') + .transition() + .duration(duration) + .attr('x1', config.axis_rotated ? yv : 0) + .attr('x2', config.axis_rotated ? yv : $$.width) + .attr('y1', config.axis_rotated ? 0 : yv) + .attr('y2', config.axis_rotated ? $$.height : yv) + .style('opacity', 1); + $$.ygridLines + .select('text') + .transition() + .duration(duration) + .attr( + 'x', + config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$) + ) + .attr('y', yv) + .text(function(d) { + return d.text + }) + .style('opacity', 1); + // exit + ygridLine + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); +}; +ChartInternal.prototype.redrawGrid = function(withTransition, transition) { + var $$ = this, + config = $$.config, + xv = $$.xv.bind($$), + lines = $$.xgridLines.select('line'), + texts = $$.xgridLines.select('text'); + return [ + (withTransition ? lines.transition(transition) : lines) + .attr('x1', config.axis_rotated ? 0 : xv) + .attr('x2', config.axis_rotated ? $$.width : xv) + .attr('y1', config.axis_rotated ? xv : 0) + .attr('y2', config.axis_rotated ? xv : $$.height) + .style('opacity', 1), + (withTransition ? texts.transition(transition) : texts) + .attr( + 'x', + config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$) + ) + .attr('y', xv) + .text(function(d) { + return d.text + }) + .style('opacity', 1) + ] +}; +ChartInternal.prototype.showXGridFocus = function(selectedData) { + var $$ = this, + config = $$.config, + dataToShow = selectedData.filter(function(d) { + return d && isValue(d.value) + }), + focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), + xx = $$.xx.bind($$); + if (!config.tooltip_show) { + return + } + // Hide when stanford plot exists + if ($$.hasType('stanford') || $$.hasArcType()) { + return + } + focusEl + .style('visibility', 'visible') + .data([dataToShow[0]]) + .attr(config.axis_rotated ? 'y1' : 'x1', xx) + .attr(config.axis_rotated ? 'y2' : 'x2', xx); + $$.smoothLines(focusEl, 'grid'); +}; +ChartInternal.prototype.hideXGridFocus = function() { + this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); +}; +ChartInternal.prototype.updateXgridFocus = function() { + var $$ = this, + config = $$.config; + $$.main + .select('line.' + CLASS.xgridFocus) + .attr('x1', config.axis_rotated ? 0 : -10) + .attr('x2', config.axis_rotated ? $$.width : -10) + .attr('y1', config.axis_rotated ? -10 : 0) + .attr('y2', config.axis_rotated ? -10 : $$.height); +}; +ChartInternal.prototype.generateGridData = function(type, scale) { + var $$ = this, + gridData = [], + xDomain, + firstYear, + lastYear, + i, + tickNum = $$.main + .select('.' + CLASS.axisX) + .selectAll('.tick') + .size(); + if (type === 'year') { + xDomain = $$.getXDomain(); + firstYear = xDomain[0].getFullYear(); + lastYear = xDomain[1].getFullYear(); + for (i = firstYear; i <= lastYear; i++) { + gridData.push(new Date(i + '-01-01 00:00:00')); + } + } else { + gridData = scale.ticks(10); + if (gridData.length > tickNum) { + // use only int + gridData = gridData.filter(function(d) { + return ('' + d).indexOf('.') < 0 + }); } + } + return gridData +}; +ChartInternal.prototype.getGridFilterToRemove = function(params) { + return params + ? function(line) { + var found = false + ;[].concat(params).forEach(function(param) { + if ( + ('value' in param && line.value === param.value) || + ('class' in param && line['class'] === param['class']) + ) { + found = true; + } + }); + return found + } + : function() { + return true + } +}; +ChartInternal.prototype.removeGridLines = function(params, forX) { + var $$ = this, + config = $$.config, + toRemove = $$.getGridFilterToRemove(params), + toShow = function(line) { + return !toRemove(line) + }, + classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, + classLine = forX ? CLASS.xgridLine : CLASS.ygridLine; + $$.main + .select('.' + classLines) + .selectAll('.' + classLine) + .filter(toRemove) + .transition() + .duration(config.transition_duration) + .style('opacity', 0) + .remove(); + if (forX) { + config.grid_x_lines = config.grid_x_lines.filter(toShow); + } else { + config.grid_y_lines = config.grid_y_lines.filter(toShow); + } }; -ChartInternal.prototype.redrawEventRect = function () { - const $$ = this, d3 = $$.d3, config = $$.config; - function mouseout() { - $$.svg.select('.' + CLASS.eventRect).style('cursor', null); - $$.hideXGridFocus(); - $$.hideTooltip(); - $$.unexpandCircles(); - $$.unexpandBars(); +ChartInternal.prototype.initEventRect = function() { + var $$ = this, + config = $$.config; + + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.eventRects) + .style('fill-opacity', 0); + $$.eventRect = $$.main + .select('.' + CLASS.eventRects) + .append('rect') + .attr('class', CLASS.eventRect); + + // event rect handle zoom event as well + if (config.zoom_enabled && $$.zoom) { + $$.eventRect.call($$.zoom).on('dblclick.zoom', null); + if (config.zoom_initialRange) { + // WORKAROUND: Add transition to apply transform immediately when no subchart + $$.eventRect + .transition() + .duration(0) + .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange)); } + } +}; +ChartInternal.prototype.redrawEventRect = function() { + const $$ = this, + d3 = $$.d3, + config = $$.config; + + function mouseout() { + $$.svg.select('.' + CLASS.eventRect).style('cursor', null); + $$.hideXGridFocus(); + $$.hideTooltip(); + $$.unexpandCircles(); + $$.unexpandBars(); + } - const isHoveringDataPoint = (mouse, closest) => - closest && ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity); - - const withName = (d) => - d ? $$.addName(Object.assign({}, d)) : null; - - // rects for mouseover - $$.main.select('.' + CLASS.eventRects) - .style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null); - - $$.eventRect - .attr('x', 0) - .attr('y', 0) - .attr('width', $$.width) - .attr('height', $$.height) - .on('mouseout', config.interaction_enabled ? function () { - if (!config) { return; } // chart is destroyed - if ($$.hasArcType()) { return; } - if ($$.mouseover){ + const isHoveringDataPoint = (mouse, closest) => + closest && + ($$.isBarType(closest.id) || + $$.dist(closest, mouse) < config.point_sensitivity); + + const withName = d => (d ? $$.addName(Object.assign({}, d)) : null); + + // rects for mouseover + $$.main + .select('.' + CLASS.eventRects) + .style( + 'cursor', + config.zoom_enabled + ? config.axis_rotated + ? 'ns-resize' + : 'ew-resize' + : null + ); + + $$.eventRect + .attr('x', 0) + .attr('y', 0) + .attr('width', $$.width) + .attr('height', $$.height) + .on( + 'mouseout', + config.interaction_enabled + ? function() { + if (!config) { + return + } // chart is destroyed + if ($$.hasArcType()) { + return + } + if ($$.mouseover) { config.data_onmouseout.call($$.api, $$.mouseover); $$.mouseover = undefined; } mouseout(); - } : null) - .on('mousemove', config.interaction_enabled ? function () { + } + : null + ) + .on( + 'mousemove', + config.interaction_enabled + ? function() { // do nothing when dragging if ($$.dragging) { - return; + return } const targetsToShow = $$.getTargetsToShow(); // do nothing if arc type if ($$.hasArcType(targetsToShow)) { - return; + return } const mouse = d3.mouse(this); - const closest = withName($$.findClosestFromTargets(targetsToShow, mouse)); + const closest = withName( + $$.findClosestFromTargets(targetsToShow, mouse) + ); const isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest); // ensure onmouseout is always called if mousemove switch between 2 targets - if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id || closest.index !== $$.mouseover.index)) { - config.data_onmouseout.call($$.api, $$.mouseover); - $$.mouseover = undefined; + if ( + $$.mouseover && + (!closest || + closest.id !== $$.mouseover.id || + closest.index !== $$.mouseover.index) + ) { + config.data_onmouseout.call($$.api, $$.mouseover); + $$.mouseover = undefined; } if (closest && !$$.mouseover) { - config.data_onmouseover.call($$.api, closest); - $$.mouseover = closest; + config.data_onmouseover.call($$.api, closest); + $$.mouseover = closest; } // show cursor as pointer if we're hovering a data point close enough - $$.svg.select('.' + CLASS.eventRect).style('cursor', isMouseCloseToDataPoint ? 'pointer' : null); + $$.svg + .select('.' + CLASS.eventRect) + .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null); // if tooltip not grouped, we want to display only data from closest data point - const showSingleDataPoint = !config.tooltip_grouped || $$.hasType('stanford', targetsToShow); + const showSingleDataPoint = + !config.tooltip_grouped || $$.hasType('stanford', targetsToShow); // find data to highlight let selectedData; if (showSingleDataPoint) { - if (closest) { - selectedData = [ closest ]; - } + if (closest) { + selectedData = [closest]; + } } else { - let closestByX; - if (closest) { - // reuse closest value - closestByX = closest; - } else { - // try to find the closest value by X values from the mouse position - const mouseX = config.axis_rotated ? mouse[1] : mouse[0]; - closestByX = $$.findClosestFromTargetsByX(targetsToShow, $$.x.invert(mouseX)); - } + let closestByX; + if (closest) { + // reuse closest value + closestByX = closest; + } else { + // try to find the closest value by X values from the mouse position + const mouseX = config.axis_rotated ? mouse[1] : mouse[0]; + closestByX = $$.findClosestFromTargetsByX( + targetsToShow, + $$.x.invert(mouseX) + ); + } - // highlight all data for this 'x' value - if (closestByX) { - selectedData = $$.filterByX(targetsToShow, closestByX.x); - } + // highlight all data for this 'x' value + if (closestByX) { + selectedData = $$.filterByX(targetsToShow, closestByX.x); + } } // ensure we have data to show if (!selectedData || selectedData.length === 0) { - return mouseout(); + return mouseout() } // inject names for each point @@ -7863,650 +10035,919 @@ ChartInternal.prototype.redrawEventRect = function () { // expand points if (config.point_focus_expand_enabled) { - $$.unexpandCircles(); - selectedData.forEach(function (d) { - $$.expandCircles(d.index, d.id, false); - }); + $$.unexpandCircles(); + selectedData.forEach(function(d) { + $$.expandCircles(d.index, d.id, false); + }); } // expand bars $$.unexpandBars(); - selectedData.forEach(function (d) { - $$.expandBars(d.index, d.id, false); + selectedData.forEach(function(d) { + $$.expandBars(d.index, d.id, false); }); // Show xgrid focus line $$.showXGridFocus(selectedData); - } : null) - .on('click', config.interaction_enabled ? function () { + } + : null + ) + .on( + 'click', + config.interaction_enabled + ? function() { const targetsToShow = $$.getTargetsToShow(); if ($$.hasArcType(targetsToShow)) { - return; + return } const mouse = d3.mouse(this); - const closest = withName($$.findClosestFromTargets(targetsToShow, mouse)); + const closest = withName( + $$.findClosestFromTargets(targetsToShow, mouse) + ); if (!isHoveringDataPoint(mouse, closest)) { - return; + return } // select if selection enabled let sameXData; if (!config.data_selection_grouped || $$.isStanfordType(closest)) { - sameXData = [closest]; + sameXData = [closest]; } else { - sameXData = $$.filterByX(targetsToShow, closest.x); + sameXData = $$.filterByX(targetsToShow, closest.x); } // toggle selected state - sameXData.forEach(function (d) { - $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () { - if (config.data_selection_grouped || $$.isWithinShape(this, d)) { - $$.toggleShape(this, d, d.index); - } + sameXData.forEach(function(d) { + $$.main + .selectAll( + '.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id) + ) + .selectAll('.' + CLASS.shape + '-' + d.index) + .each(function() { + if ( + config.data_selection_grouped || + $$.isWithinShape(this, d) + ) { + $$.toggleShape(this, d, d.index); + } }); }); // call data_onclick on the closest data point if (closest) { - const shape = $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).select('.' + CLASS.shape + '-' + closest.index); - config.data_onclick.call($$.api, closest, shape.node()); + const shape = $$.main + .selectAll( + '.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id) + ) + .select('.' + CLASS.shape + '-' + closest.index); + config.data_onclick.call($$.api, closest, shape.node()); } - - } : null) - .call( - config.interaction_enabled && config.data_selection_draggable && $$.drag ? ( - d3.drag() - .on('drag', function () { $$.drag(d3.mouse(this)); }) - .on('start', function () { $$.dragstart(d3.mouse(this)); }) - .on('end', function () { $$.dragend(); }) - ) : function () {} - ); -}; -ChartInternal.prototype.getMousePosition = function (data) { - var $$ = this; - return [$$.x(data.x), $$.getYScale(data.id)(data.value)]; -}; -ChartInternal.prototype.dispatchEvent = function (type, mouse) { - var $$ = this, - selector = '.' + CLASS.eventRect, - eventRect = $$.main.select(selector).node(), - box = eventRect.getBoundingClientRect(), - x = box.left + (mouse ? mouse[0] : 0), - y = box.top + (mouse ? mouse[1] : 0), - event = document.createEvent("MouseEvents"); - - event.initMouseEvent(type, true, true, window, 0, x, y, x, y, - false, false, false, false, 0, null); - eventRect.dispatchEvent(event); -}; - -ChartInternal.prototype.initLegend = function () { - var $$ = this; - $$.legendItemTextBox = {}; - $$.legendHasRendered = false; - $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend')); - if (!$$.config.legend_show) { - $$.legend.style('visibility', 'hidden'); - $$.hiddenLegendIds = $$.mapToIds($$.data.targets); - return; - } - // MEMO: call here to update legend box and tranlate for all - // MEMO: translate will be updated by this, so transform not needed in updateLegend() - $$.updateLegendWithDefaults(); -}; -ChartInternal.prototype.updateLegendWithDefaults = function () { - var $$ = this; - $$.updateLegend($$.mapToIds($$.data.targets), {withTransform: false, withTransitionForTransform: false, withTransition: false}); -}; -ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) { - var $$ = this, config = $$.config, insetLegendPosition = { - top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y, - left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5 - }; - - $$.margin3 = { - top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight, - right: NaN, - bottom: 0, - left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0 + } + : null + ) + .call( + config.interaction_enabled && config.data_selection_draggable && $$.drag + ? d3 + .drag() + .on('drag', function() { + $$.drag(d3.mouse(this)); + }) + .on('start', function() { + $$.dragstart(d3.mouse(this)); + }) + .on('end', function() { + $$.dragend(); + }) + : function() {} + ); +}; +ChartInternal.prototype.getMousePosition = function(data) { + var $$ = this; + return [$$.x(data.x), $$.getYScale(data.id)(data.value)] +}; +ChartInternal.prototype.dispatchEvent = function(type, mouse) { + var $$ = this, + selector = '.' + CLASS.eventRect, + eventRect = $$.main.select(selector).node(), + box = eventRect.getBoundingClientRect(), + x = box.left + (mouse ? mouse[0] : 0), + y = box.top + (mouse ? mouse[1] : 0), + event = document.createEvent('MouseEvents'); + + event.initMouseEvent( + type, + true, + true, + window, + 0, + x, + y, + x, + y, + false, + false, + false, + false, + 0, + null + ); + eventRect.dispatchEvent(event); +}; + +ChartInternal.prototype.initLegend = function() { + var $$ = this; + $$.legendItemTextBox = {}; + $$.legendHasRendered = false; + $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend')); + if (!$$.config.legend_show) { + $$.legend.style('visibility', 'hidden'); + $$.hiddenLegendIds = $$.mapToIds($$.data.targets); + return + } + // MEMO: call here to update legend box and tranlate for all + // MEMO: translate will be updated by this, so transform not needed in updateLegend() + $$.updateLegendWithDefaults(); +}; +ChartInternal.prototype.updateLegendWithDefaults = function() { + var $$ = this; + $$.updateLegend($$.mapToIds($$.data.targets), { + withTransform: false, + withTransitionForTransform: false, + withTransition: false + }); +}; +ChartInternal.prototype.updateSizeForLegend = function( + legendHeight, + legendWidth +) { + var $$ = this, + config = $$.config, + insetLegendPosition = { + top: $$.isLegendTop + ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 + : $$.currentHeight - + legendHeight - + $$.getCurrentPaddingBottom() - + config.legend_inset_y, + left: $$.isLegendLeft + ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 + : $$.currentWidth - + legendWidth - + $$.getCurrentPaddingRight() - + config.legend_inset_x + + 0.5 }; -}; -ChartInternal.prototype.transformLegend = function (withTransition) { - var $$ = this; - (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend')); -}; -ChartInternal.prototype.updateLegendStep = function (step) { - this.legendStep = step; -}; -ChartInternal.prototype.updateLegendItemWidth = function (w) { - this.legendItemWidth = w; -}; -ChartInternal.prototype.updateLegendItemHeight = function (h) { - this.legendItemHeight = h; -}; -ChartInternal.prototype.getLegendWidth = function () { - var $$ = this; - return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0; -}; -ChartInternal.prototype.getLegendHeight = function () { - var $$ = this, h = 0; - if ($$.config.legend_show) { - if ($$.isLegendRight) { - h = $$.currentHeight; - } else { - h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1); - } + + $$.margin3 = { + top: $$.isLegendRight + ? 0 + : $$.isLegendInset + ? insetLegendPosition.top + : $$.currentHeight - legendHeight, + right: NaN, + bottom: 0, + left: $$.isLegendRight + ? $$.currentWidth - legendWidth + : $$.isLegendInset + ? insetLegendPosition.left + : 0 + }; +}; +ChartInternal.prototype.transformLegend = function(withTransition) { + var $$ = this + ;(withTransition ? $$.legend.transition() : $$.legend).attr( + 'transform', + $$.getTranslate('legend') + ); +}; +ChartInternal.prototype.updateLegendStep = function(step) { + this.legendStep = step; +}; +ChartInternal.prototype.updateLegendItemWidth = function(w) { + this.legendItemWidth = w; +}; +ChartInternal.prototype.updateLegendItemHeight = function(h) { + this.legendItemHeight = h; +}; +ChartInternal.prototype.getLegendWidth = function() { + var $$ = this; + return $$.config.legend_show + ? $$.isLegendRight || $$.isLegendInset + ? $$.legendItemWidth * ($$.legendStep + 1) + : $$.currentWidth + : 0 +}; +ChartInternal.prototype.getLegendHeight = function() { + var $$ = this, + h = 0; + if ($$.config.legend_show) { + if ($$.isLegendRight) { + h = $$.currentHeight; + } else { + h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1); } - return h; -}; -ChartInternal.prototype.opacityForLegend = function (legendItem) { - return legendItem.classed(CLASS.legendItemHidden) ? null : 1; -}; -ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) { - return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3; + } + return h +}; +ChartInternal.prototype.opacityForLegend = function(legendItem) { + return legendItem.classed(CLASS.legendItemHidden) ? null : 1 +}; +ChartInternal.prototype.opacityForUnfocusedLegend = function(legendItem) { + return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3 +}; +ChartInternal.prototype.toggleFocusLegend = function(targetIds, focus) { + var $$ = this; + targetIds = $$.mapToTargetIds(targetIds); + $$.legend + .selectAll('.' + CLASS.legendItem) + .filter(function(id) { + return targetIds.indexOf(id) >= 0 + }) + .classed(CLASS.legendItemFocused, focus) + .transition() + .duration(100) + .style('opacity', function() { + var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend; + return opacity.call($$, $$.d3.select(this)) + }); }; -ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) { - var $$ = this; - targetIds = $$.mapToTargetIds(targetIds); - $$.legend.selectAll('.' + CLASS.legendItem) - .filter(function (id) { return targetIds.indexOf(id) >= 0; }) - .classed(CLASS.legendItemFocused, focus) - .transition().duration(100) - .style('opacity', function () { - var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend; - return opacity.call($$, $$.d3.select(this)); - }); +ChartInternal.prototype.revertLegend = function() { + var $$ = this, + d3 = $$.d3; + $$.legend + .selectAll('.' + CLASS.legendItem) + .classed(CLASS.legendItemFocused, false) + .transition() + .duration(100) + .style('opacity', function() { + return $$.opacityForLegend(d3.select(this)) + }); }; -ChartInternal.prototype.revertLegend = function () { - var $$ = this, d3 = $$.d3; - $$.legend.selectAll('.' + CLASS.legendItem) - .classed(CLASS.legendItemFocused, false) - .transition().duration(100) - .style('opacity', function () { return $$.opacityForLegend(d3.select(this)); }); -}; -ChartInternal.prototype.showLegend = function (targetIds) { - var $$ = this, config = $$.config; - if (!config.legend_show) { - config.legend_show = true; - $$.legend.style('visibility', 'visible'); - if (!$$.legendHasRendered) { - $$.updateLegendWithDefaults(); - } +ChartInternal.prototype.showLegend = function(targetIds) { + var $$ = this, + config = $$.config; + if (!config.legend_show) { + config.legend_show = true; + $$.legend.style('visibility', 'visible'); + if (!$$.legendHasRendered) { + $$.updateLegendWithDefaults(); } - $$.removeHiddenLegendIds(targetIds); - $$.legend.selectAll($$.selectorLegends(targetIds)) - .style('visibility', 'visible') - .transition() - .style('opacity', function () { return $$.opacityForLegend($$.d3.select(this)); }); -}; -ChartInternal.prototype.hideLegend = function (targetIds) { - var $$ = this, config = $$.config; - if (config.legend_show && isEmpty(targetIds)) { - config.legend_show = false; - $$.legend.style('visibility', 'hidden'); - } - $$.addHiddenLegendIds(targetIds); - $$.legend.selectAll($$.selectorLegends(targetIds)) - .style('opacity', 0) - .style('visibility', 'hidden'); -}; -ChartInternal.prototype.clearLegendItemTextBoxCache = function () { - this.legendItemTextBox = {}; -}; -ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) { - var $$ = this, config = $$.config; - var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile; - var paddingTop = 4, paddingRight = 10, maxWidth = 0, maxHeight = 0, posMin = 10, tileWidth = config.legend_item_tile_width + 5; - var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0; - var withTransition, withTransitionForTransform; - var texts, rects, tiles, background; - - // Skip elements when their name is set to null - targetIds = targetIds.filter(function(id) { - return !isDefined(config.data_names[id]) || config.data_names[id] !== null; + } + $$.removeHiddenLegendIds(targetIds); + $$.legend + .selectAll($$.selectorLegends(targetIds)) + .style('visibility', 'visible') + .transition() + .style('opacity', function() { + return $$.opacityForLegend($$.d3.select(this)) }); +}; +ChartInternal.prototype.hideLegend = function(targetIds) { + var $$ = this, + config = $$.config; + if (config.legend_show && isEmpty(targetIds)) { + config.legend_show = false; + $$.legend.style('visibility', 'hidden'); + } + $$.addHiddenLegendIds(targetIds); + $$.legend + .selectAll($$.selectorLegends(targetIds)) + .style('opacity', 0) + .style('visibility', 'hidden'); +}; +ChartInternal.prototype.clearLegendItemTextBoxCache = function() { + this.legendItemTextBox = {}; +}; +ChartInternal.prototype.updateLegend = function( + targetIds, + options, + transitions +) { + var $$ = this, + config = $$.config; + var xForLegend, + xForLegendText, + xForLegendRect, + yForLegend, + yForLegendText, + yForLegendRect, + x1ForLegendTile, + x2ForLegendTile, + yForLegendTile; + var paddingTop = 4, + paddingRight = 10, + maxWidth = 0, + maxHeight = 0, + posMin = 10, + tileWidth = config.legend_item_tile_width + 5; + var l, + totalLength = 0, + offsets = {}, + widths = {}, + heights = {}, + margins = [0], + steps = {}, + step = 0; + var withTransition, withTransitionForTransform; + var texts, rects, tiles, background; + + // Skip elements when their name is set to null + targetIds = targetIds.filter(function(id) { + return !isDefined(config.data_names[id]) || config.data_names[id] !== null + }); + + options = options || {}; + withTransition = getOption(options, 'withTransition', true); + withTransitionForTransform = getOption( + options, + 'withTransitionForTransform', + true + ); + + function getTextBox(textElement, id) { + if (!$$.legendItemTextBox[id]) { + $$.legendItemTextBox[id] = $$.getTextRect( + textElement.textContent, + CLASS.legendItem, + textElement + ); + } + return $$.legendItemTextBox[id] + } - options = options || {}; - withTransition = getOption(options, "withTransition", true); - withTransitionForTransform = getOption(options, "withTransitionForTransform", true); - - function getTextBox(textElement, id) { - if (!$$.legendItemTextBox[id]) { - $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement); - } - return $$.legendItemTextBox[id]; - } - - function updatePositions(textElement, id, index) { - var reset = index === 0, isLast = index === targetIds.length - 1, - box = getTextBox(textElement, id), - itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding, - itemHeight = box.height + paddingTop, - itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, - areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(), - margin, maxLength; - - // MEMO: care about condifion of step, totalLength - function updateValues(id, withoutStep) { - if (!withoutStep) { - margin = (areaLength - totalLength - itemLength) / 2; - if (margin < posMin) { - margin = (areaLength - itemLength) / 2; - totalLength = 0; - step++; - } - } - steps[id] = step; - margins[step] = $$.isLegendInset ? 10 : margin; - offsets[id] = totalLength; - totalLength += itemLength; - } - - if (reset) { - totalLength = 0; - step = 0; - maxWidth = 0; - maxHeight = 0; - } - - if (config.legend_show && !$$.isLegendToShow(id)) { - widths[id] = heights[id] = steps[id] = offsets[id] = 0; - return; - } - - widths[id] = itemWidth; - heights[id] = itemHeight; - - if (!maxWidth || itemWidth >= maxWidth) { maxWidth = itemWidth; } - if (!maxHeight || itemHeight >= maxHeight) { maxHeight = itemHeight; } - maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth; - - if (config.legend_equally) { - Object.keys(widths).forEach(function (id) { widths[id] = maxWidth; }); - Object.keys(heights).forEach(function (id) { heights[id] = maxHeight; }); - margin = (areaLength - maxLength * targetIds.length) / 2; - if (margin < posMin) { - totalLength = 0; - step = 0; - targetIds.forEach(function (id) { updateValues(id); }); - } - else { - updateValues(id, true); - } - } else { - updateValues(id); - } + function updatePositions(textElement, id, index) { + var reset = index === 0, + isLast = index === targetIds.length - 1, + box = getTextBox(textElement, id), + itemWidth = + box.width + + tileWidth + + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + + config.legend_padding, + itemHeight = box.height + paddingTop, + itemLength = + $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, + areaLength = + $$.isLegendRight || $$.isLegendInset + ? $$.getLegendHeight() + : $$.getLegendWidth(), + margin, + maxLength; + + // MEMO: care about condifion of step, totalLength + function updateValues(id, withoutStep) { + if (!withoutStep) { + margin = (areaLength - totalLength - itemLength) / 2; + if (margin < posMin) { + margin = (areaLength - itemLength) / 2; + totalLength = 0; + step++; + } + } + steps[id] = step; + margins[step] = $$.isLegendInset ? 10 : margin; + offsets[id] = totalLength; + totalLength += itemLength; + } + + if (reset) { + totalLength = 0; + step = 0; + maxWidth = 0; + maxHeight = 0; + } + + if (config.legend_show && !$$.isLegendToShow(id)) { + widths[id] = heights[id] = steps[id] = offsets[id] = 0; + return + } + + widths[id] = itemWidth; + heights[id] = itemHeight; + + if (!maxWidth || itemWidth >= maxWidth) { + maxWidth = itemWidth; + } + if (!maxHeight || itemHeight >= maxHeight) { + maxHeight = itemHeight; + } + maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth; + + if (config.legend_equally) { + Object.keys(widths).forEach(function(id) { + widths[id] = maxWidth; + }); + Object.keys(heights).forEach(function(id) { + heights[id] = maxHeight; + }); + margin = (areaLength - maxLength * targetIds.length) / 2; + if (margin < posMin) { + totalLength = 0; + step = 0; + targetIds.forEach(function(id) { + updateValues(id); + }); + } else { + updateValues(id, true); + } + } else { + updateValues(id); } + } - if ($$.isLegendInset) { - step = config.legend_inset_step ? config.legend_inset_step : targetIds.length; - $$.updateLegendStep(step); - } + if ($$.isLegendInset) { + step = config.legend_inset_step + ? config.legend_inset_step + : targetIds.length; + $$.updateLegendStep(step); + } - if ($$.isLegendRight) { - xForLegend = function (id) { return maxWidth * steps[id]; }; - yForLegend = function (id) { return margins[steps[id]] + offsets[id]; }; - } else if ($$.isLegendInset) { - xForLegend = function (id) { return maxWidth * steps[id] + 10; }; - yForLegend = function (id) { return margins[steps[id]] + offsets[id]; }; - } else { - xForLegend = function (id) { return margins[steps[id]] + offsets[id]; }; - yForLegend = function (id) { return maxHeight * steps[id]; }; - } - xForLegendText = function (id, i) { return xForLegend(id, i) + 4 + config.legend_item_tile_width; }; - yForLegendText = function (id, i) { return yForLegend(id, i) + 9; }; - xForLegendRect = function (id, i) { return xForLegend(id, i); }; - yForLegendRect = function (id, i) { return yForLegend(id, i) - 5; }; - x1ForLegendTile = function (id, i) { return xForLegend(id, i) - 2; }; - x2ForLegendTile = function (id, i) { return xForLegend(id, i) - 2 + config.legend_item_tile_width; }; - yForLegendTile = function (id, i) { return yForLegend(id, i) + 4; }; - - // Define g for legend area - l = $$.legend.selectAll('.' + CLASS.legendItem) - .data(targetIds) - .enter().append('g') - .attr('class', function (id) { return $$.generateClass(CLASS.legendItem, id); }) - .style('visibility', function (id) { return $$.isLegendToShow(id) ? 'visible' : 'hidden'; }) - .style('cursor', 'pointer') - .on('click', function (id) { + if ($$.isLegendRight) { + xForLegend = function(id) { + return maxWidth * steps[id] + }; + yForLegend = function(id) { + return margins[steps[id]] + offsets[id] + }; + } else if ($$.isLegendInset) { + xForLegend = function(id) { + return maxWidth * steps[id] + 10 + }; + yForLegend = function(id) { + return margins[steps[id]] + offsets[id] + }; + } else { + xForLegend = function(id) { + return margins[steps[id]] + offsets[id] + }; + yForLegend = function(id) { + return maxHeight * steps[id] + }; + } + xForLegendText = function(id, i) { + return xForLegend(id, i) + 4 + config.legend_item_tile_width + }; + yForLegendText = function(id, i) { + return yForLegend(id, i) + 9 + }; + xForLegendRect = function(id, i) { + return xForLegend(id, i) + }; + yForLegendRect = function(id, i) { + return yForLegend(id, i) - 5 + }; + x1ForLegendTile = function(id, i) { + return xForLegend(id, i) - 2 + }; + x2ForLegendTile = function(id, i) { + return xForLegend(id, i) - 2 + config.legend_item_tile_width + }; + yForLegendTile = function(id, i) { + return yForLegend(id, i) + 4 + }; + + // Define g for legend area + l = $$.legend + .selectAll('.' + CLASS.legendItem) + .data(targetIds) + .enter() + .append('g') + .attr('class', function(id) { + return $$.generateClass(CLASS.legendItem, id) + }) + .style('visibility', function(id) { + return $$.isLegendToShow(id) ? 'visible' : 'hidden' + }) + .style('cursor', function() { + return config.interaction_enabled ? 'pointer' : 'auto' + }) + .on('click', + config.interaction_enabled + ? function(id) { if (config.legend_item_onclick) { - config.legend_item_onclick.call($$, id); + config.legend_item_onclick.call($$, id); } else { - if ($$.d3.event.altKey) { - $$.api.hide(); - $$.api.show(id); - } else { - $$.api.toggle(id); - $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); - } + if ($$.d3.event.altKey) { + $$.api.hide(); + $$.api.show(id); + } else { + $$.api.toggle(id); + $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); + } } - }) - .on('mouseover', function (id) { + } + : null + ) + .on('mouseover', + config.interaction_enabled + ? function(id) { if (config.legend_item_onmouseover) { - config.legend_item_onmouseover.call($$, id); - } - else { - $$.d3.select(this).classed(CLASS.legendItemFocused, true); - if (!$$.transiting && $$.isTargetToShow(id)) { - $$.api.focus(id); - } + config.legend_item_onmouseover.call($$, id); + } else { + $$.d3.select(this).classed(CLASS.legendItemFocused, true); + if (!$$.transiting && $$.isTargetToShow(id)) { + $$.api.focus(id); + } } - }) - .on('mouseout', function (id) { + } + : null + ) + .on('mouseout', + config.interaction_enabled + ? function(id) { if (config.legend_item_onmouseout) { - config.legend_item_onmouseout.call($$, id); - } - else { - $$.d3.select(this).classed(CLASS.legendItemFocused, false); - $$.api.revert(); + config.legend_item_onmouseout.call($$, id); + } else { + $$.d3.select(this).classed(CLASS.legendItemFocused, false); + $$.api.revert(); } - }); - l.append('text') - .text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }) - .each(function (id, i) { updatePositions(this, id, i); }) - .style("pointer-events", "none") - .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200) - .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); - l.append('rect') - .attr("class", CLASS.legendItemEvent) - .style('fill-opacity', 0) - .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200) - .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); - l.append('line') - .attr('class', CLASS.legendItemTile) - .style('stroke', $$.color) - .style("pointer-events", "none") - .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200) - .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) - .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200) - .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) - .attr('stroke-width', config.legend_item_tile_height); - - // Set background for inset legend - background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); - if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { - background = $$.legend.insert('g', '.' + CLASS.legendItem) - .attr("class", CLASS.legendBackground) - .append('rect'); - } - - texts = $$.legend.selectAll('text') - .data(targetIds) - .text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }) // MEMO: needed for update - .each(function (id, i) { updatePositions(this, id, i); }); - (withTransition ? texts.transition() : texts) - .attr('x', xForLegendText) - .attr('y', yForLegendText); - - rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent) - .data(targetIds); - (withTransition ? rects.transition() : rects) - .attr('width', function (id) { return widths[id]; }) - .attr('height', function (id) { return heights[id]; }) - .attr('x', xForLegendRect) - .attr('y', yForLegendRect); - - tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile) - .data(targetIds); - (withTransition ? tiles.transition() : tiles) - .style('stroke', $$.levelColor ? function(id) { - return $$.levelColor($$.cache[id].values.reduce(function (total, item) { return total + item.value; }, 0)); - } : $$.color) - .attr('x1', x1ForLegendTile) - .attr('y1', yForLegendTile) - .attr('x2', x2ForLegendTile) - .attr('y2', yForLegendTile); - - if (background) { - (withTransition ? background.transition() : background) - .attr('height', $$.getLegendHeight() - 12) - .attr('width', maxWidth * (step + 1) + 10); - } - - // toggle legend state - $$.legend.selectAll('.' + CLASS.legendItem) - .classed(CLASS.legendItemHidden, function (id) { return !$$.isTargetToShow(id); }); - - // Update all to reflect change of legend - $$.updateLegendItemWidth(maxWidth); - $$.updateLegendItemHeight(maxHeight); - $$.updateLegendStep(step); - // Update size and scale - $$.updateSizes(); - $$.updateScales(); - $$.updateSvgSize(); - // Update g positions - $$.transformAll(withTransitionForTransform, transitions); - $$.legendHasRendered = true; -}; - -ChartInternal.prototype.initRegion = function () { - var $$ = this; - $$.region = $$.main.append('g') - .attr("clip-path", $$.clipPath) - .attr("class", CLASS.regions); -}; -ChartInternal.prototype.updateRegion = function (duration) { - var $$ = this, config = $$.config; - - // hide if arc type - $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); - - var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region) - .data(config.regions); - var g = mainRegion.enter().append('g'); - g.append('rect') - .attr("x", $$.regionX.bind($$)) - .attr("y", $$.regionY.bind($$)) - .attr("width", $$.regionWidth.bind($$)) - .attr("height", $$.regionHeight.bind($$)) - .style("fill-opacity", function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }); - g.append('text') - .text($$.labelRegion.bind($$)); - $$.mainRegion = g.merge(mainRegion) - .attr('class', $$.classRegion.bind($$)); - mainRegion.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); -}; -ChartInternal.prototype.redrawRegion = function (withTransition, transition) { - var $$ = this, - regions = $$.mainRegion, - regionLabels = $$.mainRegion.selectAll('text'); - return [ - (withTransition ? regions.transition(transition) : regions) - .attr("x", $$.regionX.bind($$)) - .attr("y", $$.regionY.bind($$)) - .attr("width", $$.regionWidth.bind($$)) - .attr("height", $$.regionHeight.bind($$)) - .style("fill-opacity", function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }), - (withTransition ? regionLabels.transition(transition) : regionLabels) - .attr("x", $$.labelOffsetX.bind($$)) - .attr("y", $$.labelOffsetY.bind($$)) - .attr("transform", $$.labelTransform.bind($$)) - .attr("style", 'text-anchor: left;') - ]; -}; -ChartInternal.prototype.regionX = function (d) { - var $$ = this, config = $$.config, - xPos, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0; - } else { - xPos = config.axis_rotated ? 0 : ('start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0); - } - return xPos; -}; -ChartInternal.prototype.regionY = function (d) { - var $$ = this, config = $$.config, - yPos, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - yPos = config.axis_rotated ? 0 : ('end' in d ? yScale(d.end) : 0); - } else { - yPos = config.axis_rotated ? ('start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0) : 0; - } - return yPos; -}; -ChartInternal.prototype.regionWidth = function (d) { - var $$ = this, config = $$.config, - start = $$.regionX(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - end = config.axis_rotated ? ('end' in d ? yScale(d.end) : $$.width) : $$.width; - } else { - end = config.axis_rotated ? $$.width : ('end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width); - } - return end < start ? 0 : end - start; -}; -ChartInternal.prototype.regionHeight = function (d) { - var $$ = this, config = $$.config, - start = this.regionY(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2; - if (d.axis === 'y' || d.axis === 'y2') { - end = config.axis_rotated ? $$.height : ('start' in d ? yScale(d.start) : $$.height); - } else { - end = config.axis_rotated ? ('end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height) : $$.height; - } - return end < start ? 0 : end - start; + } + : null + ); + + l.append('text') + .text(function(id) { + return isDefined(config.data_names[id]) ? config.data_names[id] : id + }) + .each(function(id, i) { + updatePositions(this, id, i); + }) + .style('pointer-events', 'none') + .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200) + .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); + + l.append('rect') + .attr('class', CLASS.legendItemEvent) + .style('fill-opacity', 0) + .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200) + .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); + + l.append('line') + .attr('class', CLASS.legendItemTile) + .style('stroke', $$.color) + .style('pointer-events', 'none') + .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200) + .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) + .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200) + .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile) + .attr('stroke-width', config.legend_item_tile_height); + + // Set background for inset legend + background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); + if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { + background = $$.legend + .insert('g', '.' + CLASS.legendItem) + .attr('class', CLASS.legendBackground) + .append('rect'); + } + + texts = $$.legend + .selectAll('text') + .data(targetIds) + .text(function(id) { + return isDefined(config.data_names[id]) ? config.data_names[id] : id + }) // MEMO: needed for update + .each(function(id, i) { + updatePositions(this, id, i); + }) + ;(withTransition ? texts.transition() : texts) + .attr('x', xForLegendText) + .attr('y', yForLegendText); + + rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds) + ;(withTransition ? rects.transition() : rects) + .attr('width', function(id) { + return widths[id] + }) + .attr('height', function(id) { + return heights[id] + }) + .attr('x', xForLegendRect) + .attr('y', yForLegendRect); + + tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds) + ;(withTransition ? tiles.transition() : tiles) + .style( + 'stroke', + $$.levelColor + ? function(id) { + return $$.levelColor( + $$.cache[id].values.reduce(function(total, item) { + return total + item.value + }, 0) + ) + } + : $$.color + ) + .attr('x1', x1ForLegendTile) + .attr('y1', yForLegendTile) + .attr('x2', x2ForLegendTile) + .attr('y2', yForLegendTile); + + if (background) { +(withTransition ? background.transition() : background) + .attr('height', $$.getLegendHeight() - 12) + .attr('width', maxWidth * (step + 1) + 10); + } + + // toggle legend state + $$.legend + .selectAll('.' + CLASS.legendItem) + .classed(CLASS.legendItemHidden, function(id) { + return !$$.isTargetToShow(id) + }); + + // Update all to reflect change of legend + $$.updateLegendItemWidth(maxWidth); + $$.updateLegendItemHeight(maxHeight); + $$.updateLegendStep(step); + // Update size and scale + $$.updateSizes(); + $$.updateScales(); + $$.updateSvgSize(); + // Update g positions + $$.transformAll(withTransitionForTransform, transitions); + $$.legendHasRendered = true; +}; + +ChartInternal.prototype.initRegion = function() { + var $$ = this; + $$.region = $$.main + .append('g') + .attr('clip-path', $$.clipPath) + .attr('class', CLASS.regions); +}; +ChartInternal.prototype.updateRegion = function(duration) { + var $$ = this, + config = $$.config; + + // hide if arc type + $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); + + var mainRegion = $$.main + .select('.' + CLASS.regions) + .selectAll('.' + CLASS.region) + .data(config.regions); + var g = mainRegion.enter().append('g'); + g.append('rect') + .attr('x', $$.regionX.bind($$)) + .attr('y', $$.regionY.bind($$)) + .attr('width', $$.regionWidth.bind($$)) + .attr('height', $$.regionHeight.bind($$)) + .style('fill-opacity', function(d) { + return isValue(d.opacity) ? d.opacity : 0.1 + }); + g.append('text').text($$.labelRegion.bind($$)); + $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$)); + mainRegion + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); +}; +ChartInternal.prototype.redrawRegion = function(withTransition, transition) { + var $$ = this, + regions = $$.mainRegion, + regionLabels = $$.mainRegion.selectAll('text'); + return [ + (withTransition ? regions.transition(transition) : regions) + .attr('x', $$.regionX.bind($$)) + .attr('y', $$.regionY.bind($$)) + .attr('width', $$.regionWidth.bind($$)) + .attr('height', $$.regionHeight.bind($$)) + .style('fill-opacity', function(d) { + return isValue(d.opacity) ? d.opacity : 0.1 + }), + (withTransition ? regionLabels.transition(transition) : regionLabels) + .attr('x', $$.labelOffsetX.bind($$)) + .attr('y', $$.labelOffsetY.bind($$)) + .attr('transform', $$.labelTransform.bind($$)) + .attr('style', 'text-anchor: left;') + ] +}; +ChartInternal.prototype.regionX = function(d) { + var $$ = this, + config = $$.config, + xPos, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0; + } else { + xPos = config.axis_rotated + ? 0 + : 'start' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) + : 0; + } + return xPos +}; +ChartInternal.prototype.regionY = function(d) { + var $$ = this, + config = $$.config, + yPos, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0; + } else { + yPos = config.axis_rotated + ? 'start' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) + : 0 + : 0; + } + return yPos +}; +ChartInternal.prototype.regionWidth = function(d) { + var $$ = this, + config = $$.config, + start = $$.regionX(d), + end, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + end = config.axis_rotated + ? 'end' in d + ? yScale(d.end) + : $$.width + : $$.width; + } else { + end = config.axis_rotated + ? $$.width + : 'end' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) + : $$.width; + } + return end < start ? 0 : end - start +}; +ChartInternal.prototype.regionHeight = function(d) { + var $$ = this, + config = $$.config, + start = this.regionY(d), + end, + yScale = d.axis === 'y' ? $$.y : $$.y2; + if (d.axis === 'y' || d.axis === 'y2') { + end = config.axis_rotated + ? $$.height + : 'start' in d + ? yScale(d.start) + : $$.height; + } else { + end = config.axis_rotated + ? 'end' in d + ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) + : $$.height + : $$.height; + } + return end < start ? 0 : end - start }; -ChartInternal.prototype.isRegionOnX = function (d) { - return !d.axis || d.axis === 'x'; +ChartInternal.prototype.isRegionOnX = function(d) { + return !d.axis || d.axis === 'x' }; -ChartInternal.prototype.labelRegion = function (d) { - return 'label' in d ? d.label : ''; +ChartInternal.prototype.labelRegion = function(d) { + return 'label' in d ? d.label : '' }; -ChartInternal.prototype.labelTransform = function (d) { - return ('vertical' in d && d.vertical) ? "rotate(90)" : ""; +ChartInternal.prototype.labelTransform = function(d) { + return 'vertical' in d && d.vertical ? 'rotate(90)' : '' }; -ChartInternal.prototype.labelOffsetX = function (d) { - var paddingX = 'paddingX' in d ? d.paddingX : 3; - var paddingY = 'paddingY' in d ? d.paddingY : 3; - return ('vertical' in d && d.vertical) ? this.regionY(d) + paddingY : (this.regionX(d) + paddingX); +ChartInternal.prototype.labelOffsetX = function(d) { + var paddingX = 'paddingX' in d ? d.paddingX : 3; + var paddingY = 'paddingY' in d ? d.paddingY : 3; + return 'vertical' in d && d.vertical + ? this.regionY(d) + paddingY + : this.regionX(d) + paddingX }; -ChartInternal.prototype.labelOffsetY = function (d) { - var paddingX = 'paddingX' in d ? d.paddingX : 3; - var paddingY = 'paddingY' in d ? d.paddingY : 3; - return ('vertical' in d && d.vertical) ? -(this.regionX(d) + paddingX) : this.regionY(d) + 10 + paddingY; +ChartInternal.prototype.labelOffsetY = function(d) { + var paddingX = 'paddingX' in d ? d.paddingX : 3; + var paddingY = 'paddingY' in d ? d.paddingY : 3; + return 'vertical' in d && d.vertical + ? -(this.regionX(d) + paddingX) + : this.regionY(d) + 10 + paddingY }; function c3LogScale(d3, linearScale, logScale) { - var PROJECTION = [0.01, 10]; + var PROJECTION = [0.01, 10]; - if (!linearScale) { - linearScale = d3.scaleLinear(); - linearScale.range(PROJECTION); - } + if (!linearScale) { + linearScale = d3.scaleLinear(); + linearScale.range(PROJECTION); + } - if (!logScale) { - logScale = d3.scaleLog(); - logScale.domain(PROJECTION); - logScale.nice(); - } + if (!logScale) { + logScale = d3.scaleLog(); + logScale.domain(PROJECTION); + logScale.nice(); + } - // copied from https://github.com/compute-io/logspace - function logspace( a, b, len ) { - var arr, - end, - tmp, - d; + // copied from https://github.com/compute-io/logspace + function logspace(a, b, len) { + var arr, end, tmp, d; - if ( arguments.length < 3 ) { - len = 10; - } else { - if ( len === 0 ) { - return []; - } - } - // Calculate the increment: - end = len - 1; - d = ( b-a ) / end; - - // Build the output array... - arr = new Array( len ); - tmp = a; - arr[ 0 ] = Math.pow( 10, tmp ); - for ( var i = 1; i < end; i++ ) { - tmp += d; - arr[ i ] = Math.pow( 10, tmp ); - } - arr[ end ] = Math.pow( 10, b ); - return arr; - } + if (arguments.length < 3) { + len = 10; + } else { + if (len === 0) { + return [] + } + } + // Calculate the increment: + end = len - 1; + d = (b - a) / end; + + // Build the output array... + arr = new Array(len); + tmp = a; + arr[0] = Math.pow(10, tmp); + for (var i = 1; i < end; i++) { + tmp += d; + arr[i] = Math.pow(10, tmp); + } + arr[end] = Math.pow(10, b); + return arr + } - function scale(x) { - return logScale(linearScale(x)); - } + function scale(x) { + return logScale(linearScale(x)) + } - scale.domain = function(x) { - if (!arguments.length) { - return linearScale.domain(); - } - linearScale.domain(x); - return scale; - }; + scale.domain = function(x) { + if (!arguments.length) { + return linearScale.domain() + } + linearScale.domain(x); + return scale + }; - scale.range = function(x) { - if (!arguments.length) { - return logScale.range(); - } - logScale.range(x); - return scale; - }; + scale.range = function(x) { + if (!arguments.length) { + return logScale.range() + } + logScale.range(x); + return scale + }; - scale.ticks = function(m) { - return logspace(-2, 1, m || 10).map(function (v) { - return linearScale.invert(v); - }); - }; + scale.ticks = function(m) { + return logspace(-2, 1, m || 10).map(function(v) { + return linearScale.invert(v) + }) + }; - scale.copy = function() { - return c3LogScale(d3, linearScale.copy(), logScale.copy()); - }; + scale.copy = function() { + return c3LogScale(d3, linearScale.copy(), logScale.copy()) + }; - return scale; + return scale } - -ChartInternal.prototype.getScale = function (min, max, forTimeseries) { - return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([min, max]); -}; -ChartInternal.prototype.getX = function (min, max, domain, offset) { - var $$ = this, - scale = $$.getScale(min, max, $$.isTimeSeries()), - _scale = domain ? scale.domain(domain) : scale, key; - // Define customized scale if categorized axis - if ($$.isCategorized()) { - offset = offset || function () { return 0; }; - scale = function (d, raw) { - var v = _scale(d) + offset(d); - return raw ? v : Math.ceil(v); - }; - } else { - scale = function (d, raw) { - var v = _scale(d); - return raw ? v : Math.ceil(v); - }; - } - // define functions - for (key in _scale) { - scale[key] = _scale[key]; - } - scale.orgDomain = function () { - return _scale.domain(); +ChartInternal.prototype.getScale = function(min, max, forTimeseries) { + return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([ + min, + max + ]) +}; +ChartInternal.prototype.getX = function(min, max, domain, offset) { + var $$ = this, + scale = $$.getScale(min, max, $$.isTimeSeries()), + _scale = domain ? scale.domain(domain) : scale, + key; + // Define customized scale if categorized axis + if ($$.isCategorized()) { + offset = + offset || + function() { + return 0 + }; + scale = function(d, raw) { + var v = _scale(d) + offset(d); + return raw ? v : Math.ceil(v) }; - // define custom domain() for categorized axis - if ($$.isCategorized()) { - scale.domain = function (domain) { - if (!arguments.length) { - domain = this.orgDomain(); - return [domain[0], domain[1] + 1]; - } - _scale.domain(domain); - return scale; - }; - } - return scale; + } else { + scale = function(d, raw) { + var v = _scale(d); + return raw ? v : Math.ceil(v) + }; + } + // define functions + for (key in _scale) { + scale[key] = _scale[key]; + } + scale.orgDomain = function() { + return _scale.domain() + }; + // define custom domain() for categorized axis + if ($$.isCategorized()) { + scale.domain = function(domain) { + if (!arguments.length) { + domain = this.orgDomain(); + return [domain[0], domain[1] + 1] + } + _scale.domain(domain); + return scale + }; + } + return scale }; /** @@ -8520,270 +10961,419 @@ ChartInternal.prototype.getX = function (min, max, domain, offset) { * * @return A d3-scale instance */ -ChartInternal.prototype.getY = function (type, domain, range) { - let scale; - if (type === 'timeseries' || type === 'time') { - scale = this.d3.scaleTime(); - } else if (type === 'log') { - scale = c3LogScale(this.d3); - } else if (type === 'linear' || type === undefined) { - scale = this.d3.scaleLinear(); - } else { - throw new Error(`Invalid Y axis type: "${type}"`); - } - - if (domain) { - scale.domain(domain); - } - - if (range) { - scale.range(range); - } - - return scale; -}; -ChartInternal.prototype.getYScale = function (id) { - return this.axis.getId(id) === 'y2' ? this.y2 : this.y; -}; -ChartInternal.prototype.getSubYScale = function (id) { - return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY; -}; -ChartInternal.prototype.updateScales = function () { - var $$ = this, config = $$.config, - forInit = !$$.x; - // update edges - $$.xMin = config.axis_rotated ? 1 : 0; - $$.xMax = config.axis_rotated ? $$.height : $$.width; - $$.yMin = config.axis_rotated ? 0 : $$.height; - $$.yMax = config.axis_rotated ? $$.width : 1; - $$.subXMin = $$.xMin; - $$.subXMax = $$.xMax; - $$.subYMin = config.axis_rotated ? 0 : $$.height2; - $$.subYMax = config.axis_rotated ? $$.width2 : 1; - // update scales - $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () { return $$.xAxis.tickOffset(); }); - $$.y = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.y.domain(), [ $$.yMin, $$.yMax ]); - $$.y2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.y2.domain(), [ $$.yMin, $$.yMax ]); - $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) { return d % 1 ? 0 : $$.subXAxis.tickOffset(); }); - $$.subY = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.subY.domain(), [ $$.subYMin, $$.subYMax ]); - $$.subY2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.subY2.domain(), [ $$.subYMin, $$.subYMax ]); - // update axes - $$.xAxisTickFormat = $$.axis.getXAxisTickFormat(); - $$.xAxisTickValues = $$.axis.getXAxisTickValues(); - $$.yAxisTickValues = $$.axis.getYAxisTickValues(); - $$.y2AxisTickValues = $$.axis.getY2AxisTickValues(); - - $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer); - $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer); - $$.yAxis = $$.axis.getYAxis('y', $$.y, $$.yOrient, $$.yAxisTickValues, config.axis_y_tick_outer); - $$.y2Axis = $$.axis.getYAxis('y2', $$.y2, $$.y2Orient, $$.y2AxisTickValues, config.axis_y2_tick_outer); - - // Set initialized scales to brush and zoom - if (!forInit) { - if ($$.brush) { $$.brush.updateScale($$.subX); } - } - // update for arc - if ($$.updateArc) { $$.updateArc(); } -}; - -ChartInternal.prototype.selectPoint = function (target, d, i) { - var $$ = this, config = $$.config, - cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), - cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), - r = $$.pointSelectR.bind($$); - config.data_onselected.call($$.api, d, target.node()); - // add selected-circle on low layer g - $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i) - .data([d]) - .enter().append('circle') - .attr("class", function () { return $$.generateClass(CLASS.selectedCircle, i); }) - .attr("cx", cx) - .attr("cy", cy) - .attr("stroke", function () { return $$.color(d); }) - .attr("r", function (d) { return $$.pointSelectR(d) * 1.4; }) - .transition().duration(100) - .attr("r", r); -}; -ChartInternal.prototype.unselectPoint = function (target, d, i) { - var $$ = this; - $$.config.data_onunselected.call($$.api, d, target.node()); - // remove selected-circle from low layer g - $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i) - .transition().duration(100).attr('r', 0) - .remove(); -}; -ChartInternal.prototype.togglePoint = function (selected, target, d, i) { - selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i); -}; -ChartInternal.prototype.selectPath = function (target, d) { - var $$ = this; - $$.config.data_onselected.call($$, d, target.node()); - if ($$.config.interaction_brighten) { - target.transition().duration(100) - .style("fill", function () { return $$.d3.rgb($$.color(d)).brighter(0.75); }); +ChartInternal.prototype.getY = function(type, domain, range) { + let scale; + if (type === 'timeseries' || type === 'time') { + scale = this.d3.scaleTime(); + } else if (type === 'log') { + scale = c3LogScale(this.d3); + } else if (type === 'linear' || type === undefined) { + scale = this.d3.scaleLinear(); + } else { + throw new Error(`Invalid Y axis type: "${type}"`) + } + + if (domain) { + scale.domain(domain); + } + + if (range) { + scale.range(range); + } + + return scale +}; +ChartInternal.prototype.getYScale = function(id) { + return this.axis.getId(id) === 'y2' ? this.y2 : this.y +}; +ChartInternal.prototype.getSubYScale = function(id) { + return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY +}; +ChartInternal.prototype.updateScales = function() { + var $$ = this, + config = $$.config, + forInit = !$$.x; + // update edges + $$.xMin = config.axis_rotated ? 1 : 0; + $$.xMax = config.axis_rotated ? $$.height : $$.width; + $$.yMin = config.axis_rotated ? 0 : $$.height; + $$.yMax = config.axis_rotated ? $$.width : 1; + $$.subXMin = $$.xMin; + $$.subXMax = $$.xMax; + $$.subYMin = config.axis_rotated ? 0 : $$.height2; + $$.subYMax = config.axis_rotated ? $$.width2 : 1; + // update scales + $$.x = $$.getX( + $$.xMin, + $$.xMax, + forInit ? undefined : $$.x.orgDomain(), + function() { + return $$.xAxis.tickOffset() + } + ); + $$.y = $$.getY( + config.axis_y_type, + forInit ? config.axis_y_default : $$.y.domain(), + [$$.yMin, $$.yMax] + ); + $$.y2 = $$.getY( + config.axis_y2_type, + forInit ? config.axis_y2_default : $$.y2.domain(), + [$$.yMin, $$.yMax] + ); + $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function(d) { + return d % 1 ? 0 : $$.subXAxis.tickOffset() + }); + $$.subY = $$.getY( + config.axis_y_type, + forInit ? config.axis_y_default : $$.subY.domain(), + [$$.subYMin, $$.subYMax] + ); + $$.subY2 = $$.getY( + config.axis_y2_type, + forInit ? config.axis_y2_default : $$.subY2.domain(), + [$$.subYMin, $$.subYMax] + ); + // update axes + $$.xAxisTickFormat = $$.axis.getXAxisTickFormat(); + $$.xAxisTickValues = $$.axis.getXAxisTickValues(); + $$.yAxisTickValues = $$.axis.getYAxisTickValues(); + $$.y2AxisTickValues = $$.axis.getY2AxisTickValues(); + + $$.xAxis = $$.axis.getXAxis( + $$.x, + $$.xOrient, + $$.xAxisTickFormat, + $$.xAxisTickValues, + config.axis_x_tick_outer + ); + $$.subXAxis = $$.axis.getXAxis( + $$.subX, + $$.subXOrient, + $$.xAxisTickFormat, + $$.xAxisTickValues, + config.axis_x_tick_outer + ); + $$.yAxis = $$.axis.getYAxis( + 'y', + $$.y, + $$.yOrient, + $$.yAxisTickValues, + config.axis_y_tick_outer + ); + $$.y2Axis = $$.axis.getYAxis( + 'y2', + $$.y2, + $$.y2Orient, + $$.y2AxisTickValues, + config.axis_y2_tick_outer + ); + + // Set initialized scales to brush and zoom + if (!forInit) { + if ($$.brush) { + $$.brush.updateScale($$.subX); } + } + // update for arc + if ($$.updateArc) { + $$.updateArc(); + } }; -ChartInternal.prototype.unselectPath = function (target, d) { - var $$ = this; - $$.config.data_onunselected.call($$, d, target.node()); - if ($$.config.interaction_brighten) { - target.transition().duration(100) - .style("fill", function () { return $$.color(d); }); - } + +ChartInternal.prototype.selectPoint = function(target, d, i) { + var $$ = this, + config = $$.config, + cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), + cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), + r = $$.pointSelectR.bind($$); + config.data_onselected.call($$.api, d, target.node()); + // add selected-circle on low layer g + $$.main + .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)) + .selectAll('.' + CLASS.selectedCircle + '-' + i) + .data([d]) + .enter() + .append('circle') + .attr('class', function() { + return $$.generateClass(CLASS.selectedCircle, i) + }) + .attr('cx', cx) + .attr('cy', cy) + .attr('stroke', function() { + return $$.color(d) + }) + .attr('r', function(d) { + return $$.pointSelectR(d) * 1.4 + }) + .transition() + .duration(100) + .attr('r', r); +}; +ChartInternal.prototype.unselectPoint = function(target, d, i) { + var $$ = this; + $$.config.data_onunselected.call($$.api, d, target.node()); + // remove selected-circle from low layer g + $$.main + .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)) + .selectAll('.' + CLASS.selectedCircle + '-' + i) + .transition() + .duration(100) + .attr('r', 0) + .remove(); +}; +ChartInternal.prototype.togglePoint = function(selected, target, d, i) { + selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i); +}; +ChartInternal.prototype.selectPath = function(target, d) { + var $$ = this; + $$.config.data_onselected.call($$, d, target.node()); + if ($$.config.interaction_brighten) { + target + .transition() + .duration(100) + .style('fill', function() { + return $$.d3.rgb($$.color(d)).brighter(0.75) + }); + } +}; +ChartInternal.prototype.unselectPath = function(target, d) { + var $$ = this; + $$.config.data_onunselected.call($$, d, target.node()); + if ($$.config.interaction_brighten) { + target + .transition() + .duration(100) + .style('fill', function() { + return $$.color(d) + }); + } }; -ChartInternal.prototype.togglePath = function (selected, target, d, i) { - selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i); +ChartInternal.prototype.togglePath = function(selected, target, d, i) { + selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i); }; -ChartInternal.prototype.getToggle = function (that, d) { - var $$ = this, toggle; - if (that.nodeName === 'circle') { - if ($$.isStepType(d)) { - // circle is hidden in step chart, so treat as within the click area - toggle = function () {}; // TODO: how to select step chart? - } else { - toggle = $$.togglePoint; - } +ChartInternal.prototype.getToggle = function(that, d) { + var $$ = this, + toggle; + if (that.nodeName === 'circle') { + if ($$.isStepType(d)) { + // circle is hidden in step chart, so treat as within the click area + toggle = function() {}; // TODO: how to select step chart? + } else { + toggle = $$.togglePoint; } - else if (that.nodeName === 'path') { - toggle = $$.togglePath; + } else if (that.nodeName === 'path') { + toggle = $$.togglePath; + } + return toggle +}; +ChartInternal.prototype.toggleShape = function(that, d, i) { + var $$ = this, + d3 = $$.d3, + config = $$.config, + shape = d3.select(that), + isSelected = shape.classed(CLASS.SELECTED), + toggle = $$.getToggle(that, d).bind($$); + + if (config.data_selection_enabled && config.data_selection_isselectable(d)) { + if (!config.data_selection_multiple) { + $$.main + .selectAll( + '.' + + CLASS.shapes + + (config.data_selection_grouped + ? $$.getTargetSelectorSuffix(d.id) + : '') + ) + .selectAll('.' + CLASS.shape) + .each(function(d, i) { + var shape = d3.select(this); + if (shape.classed(CLASS.SELECTED)) { + toggle(false, shape.classed(CLASS.SELECTED, false), d, i); + } + }); } - return toggle; + shape.classed(CLASS.SELECTED, !isSelected); + toggle(!isSelected, shape, d, i); + } }; -ChartInternal.prototype.toggleShape = function (that, d, i) { - var $$ = this, d3 = $$.d3, config = $$.config, - shape = d3.select(that), isSelected = shape.classed(CLASS.SELECTED), - toggle = $$.getToggle(that, d).bind($$); - if (config.data_selection_enabled && config.data_selection_isselectable(d)) { - if (!config.data_selection_multiple) { - $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) { - var shape = d3.select(this); - if (shape.classed(CLASS.SELECTED)) { toggle(false, shape.classed(CLASS.SELECTED, false), d, i); } - }); - } - shape.classed(CLASS.SELECTED, !isSelected); - toggle(!isSelected, shape, d, i); - } -}; - -ChartInternal.prototype.initBar = function () { - var $$ = this; - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartBars); -}; -ChartInternal.prototype.updateTargetsForBar = function (targets) { - var $$ = this, config = $$.config, - mainBars, mainBarEnter, - classChartBar = $$.classChartBar.bind($$), - classBars = $$.classBars.bind($$), - classFocus = $$.classFocus.bind($$); - mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar) - .data(targets) - .attr('class', function (d) { return classChartBar(d) + classFocus(d); }); - mainBarEnter = mainBars.enter().append('g') - .attr('class', classChartBar) - .style("pointer-events", "none"); - // Bars for each data - mainBarEnter.append('g') - .attr("class", classBars) - .style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; }); - -}; -ChartInternal.prototype.updateBar = function (durationForExit) { - var $$ = this, - barData = $$.barData.bind($$), - classBar = $$.classBar.bind($$), - initialOpacity = $$.initialOpacity.bind($$), - color = function (d) { return $$.color(d.id); }; - var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar) - .data(barData); - var mainBarEnter = mainBar.enter().append('path') - .attr("class", classBar) - .style("stroke", color) - .style("fill", color); - $$.mainBar = mainBarEnter.merge(mainBar) - .style("opacity", initialOpacity); - mainBar.exit().transition().duration(durationForExit) - .style("opacity", 0); -}; -ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) { - const $$ = this; +ChartInternal.prototype.initBar = function() { + var $$ = this; + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartBars); +}; +ChartInternal.prototype.updateTargetsForBar = function(targets) { + var $$ = this, + config = $$.config, + mainBars, + mainBarEnter, + classChartBar = $$.classChartBar.bind($$), + classBars = $$.classBars.bind($$), + classFocus = $$.classFocus.bind($$); + mainBars = $$.main + .select('.' + CLASS.chartBars) + .selectAll('.' + CLASS.chartBar) + .data(targets) + .attr('class', function(d) { + return classChartBar(d) + classFocus(d) + }); + mainBarEnter = mainBars + .enter() + .append('g') + .attr('class', classChartBar) + .style('pointer-events', 'none'); + // Bars for each data + mainBarEnter + .append('g') + .attr('class', classBars) + .style('cursor', function(d) { + return config.data_selection_isselectable(d) ? 'pointer' : null + }); +}; +ChartInternal.prototype.updateBar = function(durationForExit) { + var $$ = this, + barData = $$.barData.bind($$), + classBar = $$.classBar.bind($$), + initialOpacity = $$.initialOpacity.bind($$), + color = function(d) { + return $$.color(d.id) + }; + var mainBar = $$.main + .selectAll('.' + CLASS.bars) + .selectAll('.' + CLASS.bar) + .data(barData); + var mainBarEnter = mainBar + .enter() + .append('path') + .attr('class', classBar) + .style('stroke', color) + .style('fill', color); + $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity); + mainBar + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0); +}; +ChartInternal.prototype.redrawBar = function( + drawBar, + withTransition, + transition +) { + const $$ = this; - return [ - (withTransition ? this.mainBar.transition(transition) : this.mainBar) - .attr('d', drawBar) - .style("stroke", this.color) - .style("fill", this.color) - .style("opacity", (d) => $$.isTargetToShow(d.id) ? 1 : 0) - ]; -}; -ChartInternal.prototype.getBarW = function (axis, barTargetsNum) { - var $$ = this, config = $$.config, - w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum : 0; - return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w; -}; -ChartInternal.prototype.getBars = function (i, id) { - var $$ = this; - return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')); -}; -ChartInternal.prototype.expandBars = function (i, id, reset) { - var $$ = this; - if (reset) { $$.unexpandBars(); } - $$.getBars(i, id).classed(CLASS.EXPANDED, true); -}; -ChartInternal.prototype.unexpandBars = function (i) { - var $$ = this; - $$.getBars(i).classed(CLASS.EXPANDED, false); -}; -ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) { - var $$ = this, config = $$.config, - getPoints = $$.generateGetBarPoints(barIndices, isSub); - return function (d, i) { - // 4 points that make a bar - var points = getPoints(d, i); - - // switch points if axis is rotated, not applicable for sub chart - var indexX = config.axis_rotated ? 1 : 0; - var indexY = config.axis_rotated ? 0 : 1; - - var path = 'M ' + points[0][indexX] + ',' + points[0][indexY] + ' ' + - 'L' + points[1][indexX] + ',' + points[1][indexY] + ' ' + - 'L' + points[2][indexX] + ',' + points[2][indexY] + ' ' + - 'L' + points[3][indexX] + ',' + points[3][indexY] + ' ' + - 'z'; - - return path; - }; -}; -ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) { - var $$ = this, - axis = isSub ? $$.subXAxis : $$.xAxis, - barTargetsNum = barIndices.__max__ + 1, - barW = $$.getBarW(axis, barTargetsNum), - barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), - barY = $$.getShapeY(!!isSub), - barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), - barSpaceOffset = barW * ($$.config.bar_space / 2), - yScale = isSub ? $$.getSubYScale : $$.getYScale; - return function (d, i) { - var y0 = yScale.call($$, d.id)(0), - offset = barOffset(d, i) || y0, // offset is for stacked bar chart - posX = barX(d), posY = barY(d); - // fix posY not to overflow opposite quadrant - if ($$.config.axis_rotated) { - if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; } - } + return [ + (withTransition ? this.mainBar.transition(transition) : this.mainBar) + .attr('d', drawBar) + .style('stroke', this.color) + .style('fill', this.color) + .style('opacity', d => ($$.isTargetToShow(d.id) ? 1 : 0)) + ] +}; +ChartInternal.prototype.getBarW = function(axis, barTargetsNum) { + var $$ = this, + config = $$.config, + w = + typeof config.bar_width === 'number' + ? config.bar_width + : barTargetsNum + ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum + : 0; + return config.bar_width_max && w > config.bar_width_max + ? config.bar_width_max + : w +}; +ChartInternal.prototype.getBars = function(i, id) { + var $$ = this; + return (id + ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) + : $$.main + ).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')) +}; +ChartInternal.prototype.expandBars = function(i, id, reset) { + var $$ = this; + if (reset) { + $$.unexpandBars(); + } + $$.getBars(i, id).classed(CLASS.EXPANDED, true); +}; +ChartInternal.prototype.unexpandBars = function(i) { + var $$ = this; + $$.getBars(i).classed(CLASS.EXPANDED, false); +}; +ChartInternal.prototype.generateDrawBar = function(barIndices, isSub) { + var $$ = this, + config = $$.config, + getPoints = $$.generateGetBarPoints(barIndices, isSub); + return function(d, i) { + // 4 points that make a bar + var points = getPoints(d, i); + + // switch points if axis is rotated, not applicable for sub chart + var indexX = config.axis_rotated ? 1 : 0; + var indexY = config.axis_rotated ? 0 : 1; + + var path = + 'M ' + + points[0][indexX] + + ',' + + points[0][indexY] + + ' ' + + 'L' + + points[1][indexX] + + ',' + + points[1][indexY] + + ' ' + + 'L' + + points[2][indexX] + + ',' + + points[2][indexY] + + ' ' + + 'L' + + points[3][indexX] + + ',' + + points[3][indexY] + + ' ' + + 'z'; + + return path + } +}; +ChartInternal.prototype.generateGetBarPoints = function(barIndices, isSub) { + var $$ = this, + axis = isSub ? $$.subXAxis : $$.xAxis, + barTargetsNum = barIndices.__max__ + 1, + barW = $$.getBarW(axis, barTargetsNum), + barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), + barY = $$.getShapeY(!!isSub), + barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), + barSpaceOffset = barW * ($$.config.bar_space / 2), + yScale = isSub ? $$.getSubYScale : $$.getYScale; + return function(d, i) { + var y0 = yScale.call($$, d.id)(0), + offset = barOffset(d, i) || y0, // offset is for stacked bar chart + posX = barX(d), + posY = barY(d); + // fix posY not to overflow opposite quadrant + if ($$.config.axis_rotated) { + if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { + posY = y0; + } + } - posY -= (y0 - offset); + posY -= y0 - offset; - // 4 points that make a bar - return [ - [posX + barSpaceOffset, offset], - [posX + barSpaceOffset, posY], - [posX + barW - barSpaceOffset, posY], - [posX + barW - barSpaceOffset, offset] - ]; - }; + // 4 points that make a bar + return [ + [posX + barSpaceOffset, offset], + [posX + barSpaceOffset, posY], + [posX + barW - barSpaceOffset, posY], + [posX + barW - barSpaceOffset, offset] + ] + } }; /** @@ -8793,1954 +11383,2641 @@ ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) { * @param barShape * @return {boolean} */ -ChartInternal.prototype.isWithinBar = function (mouse, barShape) { - return isWithinBox(mouse, getBBox(barShape), 2); -}; - -ChartInternal.prototype.getShapeIndices = function (typeFilter) { - var $$ = this, config = $$.config, - indices = {}, i = 0, j, k; - $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) { - for (j = 0; j < config.data_groups.length; j++) { - if (config.data_groups[j].indexOf(d.id) < 0) { continue; } - for (k = 0; k < config.data_groups[j].length; k++) { - if (config.data_groups[j][k] in indices) { - indices[d.id] = indices[config.data_groups[j][k]]; - break; - } - } - } - if (isUndefined(indices[d.id])) { indices[d.id] = i++; } - }); - indices.__max__ = i - 1; - return indices; -}; -ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) { - var $$ = this, scale = isSub ? $$.subX : $$.x; - return function (d) { - var index = d.id in indices ? indices[d.id] : 0; - return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0; - }; -}; -ChartInternal.prototype.getShapeY = function (isSub) { - const $$ = this; - - return function (d) { - const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id); - return scale($$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value); - }; -}; -ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) { - var $$ = this, - targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))), - targetIds = targets.map(function (t) { return t.id; }); - return function (d, i) { - var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), - y0 = scale(0), offset = y0; - targets.forEach(function (t) { - const rowValues = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values; - const isTargetNormalized = $$.isTargetNormalized(d.id); - const values = rowValues.map(v => (isTargetNormalized ? $$.getRatio("index", v, true) : v.value)); - - if (t.id === d.id || indices[t.id] !== indices[d.id]) { return; } - if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) { - // check if the x values line up - if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) { // "+" for timeseries - // if not, try to find the value that does line up - i = -1; - rowValues.forEach(function (v, j) { - const x1 = v.x.constructor === Date ? +v.x : v.x; - const x2 = d.x.constructor === Date ? +d.x : d.x; - - if (x1 === x2) { - i = j; - } - }); - } - if (i in rowValues && rowValues[i].value * d.value >= 0) { - offset += scale(values[i]) - y0; - } - } - }); - return offset; - }; -}; -ChartInternal.prototype.isWithinShape = function (that, d) { - var $$ = this, - shape = $$.d3.select(that), isWithin; - if (!$$.isTargetToShow(d.id)) { - isWithin = false; - } - else if (that.nodeName === 'circle') { - isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5); - } - else if (that.nodeName === 'path') { - isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar($$.d3.mouse(that), that) : true; - } - return isWithin; +ChartInternal.prototype.isWithinBar = function(mouse, barShape) { + return isWithinBox(mouse, getBBox(barShape), 2) +}; + +ChartInternal.prototype.getShapeIndices = function(typeFilter) { + var $$ = this, + config = $$.config, + indices = {}, + i = 0, + j, + k; + $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach( + function(d) { + for (j = 0; j < config.data_groups.length; j++) { + if (config.data_groups[j].indexOf(d.id) < 0) { + continue + } + for (k = 0; k < config.data_groups[j].length; k++) { + if (config.data_groups[j][k] in indices) { + indices[d.id] = indices[config.data_groups[j][k]]; + break + } + } + } + if (isUndefined(indices[d.id])) { + indices[d.id] = i++; + } + } + ); + indices.__max__ = i - 1; + return indices +}; +ChartInternal.prototype.getShapeX = function( + offset, + targetsNum, + indices, + isSub +) { + var $$ = this, + scale = isSub ? $$.subX : $$.x; + return function(d) { + var index = d.id in indices ? indices[d.id] : 0; + return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0 + } }; +ChartInternal.prototype.getShapeY = function(isSub) { + const $$ = this; - -ChartInternal.prototype.getInterpolate = function (d) { - var $$ = this, d3 = $$.d3, - types = { - 'linear': d3.curveLinear, - 'linear-closed': d3.curveLinearClosed, - 'basis': d3.curveBasis, - 'basis-open': d3.curveBasisOpen, - 'basis-closed': d3.curveBasisClosed, - 'bundle': d3.curveBundle, - 'cardinal': d3.curveCardinal, - 'cardinal-open': d3.curveCardinalOpen, - 'cardinal-closed': d3.curveCardinalClosed, - 'monotone': d3.curveMonotoneX, - 'step': d3.curveStep, - 'step-before': d3.curveStepBefore, - 'step-after': d3.curveStepAfter - }, - type; - - if ($$.isSplineType(d)) { - type = types[$$.config.spline_interpolation_type] || types.cardinal; - } - else if ($$.isStepType(d)) { - type = types[$$.config.line_step_type]; - } - else { - type = types.linear; - } - return type; -}; - -ChartInternal.prototype.initLine = function () { - var $$ = this; - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartLines); -}; -ChartInternal.prototype.updateTargetsForLine = function (targets) { - var $$ = this, config = $$.config, - mainLines, mainLineEnter, - classChartLine = $$.classChartLine.bind($$), - classLines = $$.classLines.bind($$), - classAreas = $$.classAreas.bind($$), - classCircles = $$.classCircles.bind($$), - classFocus = $$.classFocus.bind($$); - mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine) - .data(targets) - .attr('class', function (d) { return classChartLine(d) + classFocus(d); }); - mainLineEnter = mainLines.enter().append('g') - .attr('class', classChartLine) - .style('opacity', 0) - .style("pointer-events", "none"); - // Lines for each data - mainLineEnter.append('g') - .attr("class", classLines); - // Areas - mainLineEnter.append('g') - .attr('class', classAreas); - // Circles for each data point on lines - mainLineEnter.append('g') - .attr("class", function (d) { return $$.generateClass(CLASS.selectedCircles, d.id); }); - mainLineEnter.append('g') - .attr("class", classCircles) - .style("cursor", function (d) { return config.data_selection_isselectable(d) ? "pointer" : null; }); - // Update date for selected circles - targets.forEach(function (t) { - $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) { - d.value = t.values[d.index].value; - }); + return function(d) { + const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id); + return scale( + $$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value + ) + } +}; +ChartInternal.prototype.getShapeOffset = function(typeFilter, indices, isSub) { + var $$ = this, + targets = $$.orderTargets( + $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)) + ), + targetIds = targets.map(function(t) { + return t.id }); - // MEMO: can not keep same color... - //mainLineUpdate.exit().remove(); -}; -ChartInternal.prototype.updateLine = function (durationForExit) { - var $$ = this; - var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line) - .data($$.lineData.bind($$)); - var mainLineEnter = mainLine.enter().append('path') - .attr('class', $$.classLine.bind($$)) - .style("stroke", $$.color); - $$.mainLine = mainLineEnter.merge(mainLine) - .style("opacity", $$.initialOpacity.bind($$)) - .style('shape-rendering', function (d) { return $$.isStepType(d) ? 'crispEdges' : ''; }) - .attr('transform', null); - mainLine.exit().transition().duration(durationForExit) - .style('opacity', 0); -}; -ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) { - return [ - (withTransition ? this.mainLine.transition(transition) : this.mainLine) - .attr("d", drawLine) - .style("stroke", this.color) - .style("opacity", 1) - ]; -}; -ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) { - var $$ = this, config = $$.config, - line = $$.d3.line(), - getPoints = $$.generateGetLinePoints(lineIndices, isSub), - yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, - xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); }, - yValue = function (d, i) { - return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value); - }; - - line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue); - if (!config.line_connectNull) { line = line.defined(function (d) { return d.value != null; }); } - return function (d) { - var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values, - x = isSub ? $$.subX : $$.x, y = yScaleGetter.call($$, d.id), x0 = 0, y0 = 0, path; - if ($$.isLineType(d)) { - if (config.data_regions[d.id]) { - path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]); - } else { - if ($$.isStepType(d)) { values = $$.convertValuesToStep(values); } - path = line.curve($$.getInterpolate(d))(values); - } - } else { - if (values[0]) { - x0 = x(values[0].x); - y0 = y(values[0].value); + return function(d, i) { + var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), + y0 = scale(0), + offset = y0; + targets.forEach(function(t) { + const rowValues = $$.isStepType(d) + ? $$.convertValuesToStep(t.values) + : t.values; + const isTargetNormalized = $$.isTargetNormalized(d.id); + const values = rowValues.map(v => + isTargetNormalized ? $$.getRatio('index', v, true) : v.value + ); + + if (t.id === d.id || indices[t.id] !== indices[d.id]) { + return + } + if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) { + // check if the x values line up + if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) { + // "+" for timeseries + // if not, try to find the value that does line up + i = -1; + rowValues.forEach(function(v, j) { + const x1 = v.x.constructor === Date ? +v.x : v.x; + const x2 = d.x.constructor === Date ? +d.x : d.x; + + if (x1 === x2) { + i = j; } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; + }); } - return path ? path : "M 0 0"; - }; -}; -ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) { // partial duplication of generateGetBarPoints - var $$ = this, config = $$.config, - lineTargetsNum = lineIndices.__max__ + 1, - x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), - y = $$.getShapeY(!!isSub), - lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), - yScale = isSub ? $$.getSubYScale : $$.getYScale; - return function (d, i) { - var y0 = yScale.call($$, d.id)(0), - offset = lineOffset(d, i) || y0, // offset is for stacked area chart - posX = x(d), posY = y(d); - // fix posY not to overflow opposite quadrant - if (config.axis_rotated) { - if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; } + if (i in rowValues && rowValues[i].value * d.value >= 0) { + offset += scale(values[i]) - y0; } - // 1 point that marks the line position - return [ - [posX, posY - (y0 - offset)], - [posX, posY - (y0 - offset)], // needed for compatibility - [posX, posY - (y0 - offset)], // needed for compatibility - [posX, posY - (y0 - offset)] // needed for compatibility - ]; - }; + } + }); + return offset + } }; +ChartInternal.prototype.isWithinShape = function(that, d) { + var $$ = this, + shape = $$.d3.select(that), + isWithin; + if (!$$.isTargetToShow(d.id)) { + isWithin = false; + } else if (that.nodeName === 'circle') { + isWithin = $$.isStepType(d) + ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) + : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5); + } else if (that.nodeName === 'path') { + isWithin = shape.classed(CLASS.bar) + ? $$.isWithinBar($$.d3.mouse(that), that) + : true; + } + return isWithin +}; + +ChartInternal.prototype.getInterpolate = function(d) { + var $$ = this, + d3 = $$.d3, + types = { + linear: d3.curveLinear, + 'linear-closed': d3.curveLinearClosed, + basis: d3.curveBasis, + 'basis-open': d3.curveBasisOpen, + 'basis-closed': d3.curveBasisClosed, + bundle: d3.curveBundle, + cardinal: d3.curveCardinal, + 'cardinal-open': d3.curveCardinalOpen, + 'cardinal-closed': d3.curveCardinalClosed, + monotone: d3.curveMonotoneX, + step: d3.curveStep, + 'step-before': d3.curveStepBefore, + 'step-after': d3.curveStepAfter + }, + type; + + if ($$.isSplineType(d)) { + type = types[$$.config.spline_interpolation_type] || types.cardinal; + } else if ($$.isStepType(d)) { + type = types[$$.config.line_step_type]; + } else { + type = types.linear; + } + return type +}; + +ChartInternal.prototype.initLine = function() { + var $$ = this; + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartLines); +}; +ChartInternal.prototype.updateTargetsForLine = function(targets) { + var $$ = this, + config = $$.config, + mainLines, + mainLineEnter, + classChartLine = $$.classChartLine.bind($$), + classLines = $$.classLines.bind($$), + classAreas = $$.classAreas.bind($$), + classCircles = $$.classCircles.bind($$), + classFocus = $$.classFocus.bind($$); + mainLines = $$.main + .select('.' + CLASS.chartLines) + .selectAll('.' + CLASS.chartLine) + .data(targets) + .attr('class', function(d) { + return classChartLine(d) + classFocus(d) + }); + mainLineEnter = mainLines + .enter() + .append('g') + .attr('class', classChartLine) + .style('opacity', 0) + .style('pointer-events', 'none'); + // Lines for each data + mainLineEnter.append('g').attr('class', classLines); + // Areas + mainLineEnter.append('g').attr('class', classAreas); + // Circles for each data point on lines + mainLineEnter.append('g').attr('class', function(d) { + return $$.generateClass(CLASS.selectedCircles, d.id) + }); + mainLineEnter + .append('g') + .attr('class', classCircles) + .style('cursor', function(d) { + return config.data_selection_isselectable(d) ? 'pointer' : null + }); + // Update date for selected circles + targets.forEach(function(t) { + $$.main + .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)) + .selectAll('.' + CLASS.selectedCircle) + .each(function(d) { + d.value = t.values[d.index].value; + }); + }); + // MEMO: can not keep same color... + //mainLineUpdate.exit().remove(); +}; +ChartInternal.prototype.updateLine = function(durationForExit) { + var $$ = this; + var mainLine = $$.main + .selectAll('.' + CLASS.lines) + .selectAll('.' + CLASS.line) + .data($$.lineData.bind($$)); + var mainLineEnter = mainLine + .enter() + .append('path') + .attr('class', $$.classLine.bind($$)) + .style('stroke', $$.color); + $$.mainLine = mainLineEnter + .merge(mainLine) + .style('opacity', $$.initialOpacity.bind($$)) + .style('shape-rendering', function(d) { + return $$.isStepType(d) ? 'crispEdges' : '' + }) + .attr('transform', null); + mainLine + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0); +}; +ChartInternal.prototype.redrawLine = function( + drawLine, + withTransition, + transition +) { + return [ + (withTransition ? this.mainLine.transition(transition) : this.mainLine) + .attr('d', drawLine) + .style('stroke', this.color) + .style('opacity', 1) + ] +}; +ChartInternal.prototype.generateDrawLine = function(lineIndices, isSub) { + var $$ = this, + config = $$.config, + line = $$.d3.line(), + getPoints = $$.generateGetLinePoints(lineIndices, isSub), + yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, + xValue = function(d) { + return (isSub ? $$.subxx : $$.xx).call($$, d) + }, + yValue = function(d, i) { + return config.data_groups.length > 0 + ? getPoints(d, i)[0][1] + : yScaleGetter.call($$, d.id)(d.value) + }; - -ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) { - var $$ = this, config = $$.config, - prev = -1, i, j, - s = "M", sWithRegion, - xp, yp, dx, dy, dd, diff, diffx2, - xOffset = $$.isCategorized() ? 0.5 : 0, - xValue, yValue, - regions = []; - - function isWithinRegions(x, regions) { - var i; - for (i = 0; i < regions.length; i++) { - if (regions[i].start < x && x <= regions[i].end) { return true; } - } - return false; - } - - // Check start/end of regions - if (isDefined(_regions)) { - for (i = 0; i < _regions.length; i++) { - regions[i] = {}; - if (isUndefined(_regions[i].start)) { - regions[i].start = d[0].x; - } else { - regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start; - } - if (isUndefined(_regions[i].end)) { - regions[i].end = d[d.length - 1].x; - } else { - regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end; - } + line = config.axis_rotated + ? line.x(yValue).y(xValue) + : line.x(xValue).y(yValue); + if (!config.line_connectNull) { + line = line.defined(function(d) { + return d.value != null + }); + } + return function(d) { + var values = config.line_connectNull + ? $$.filterRemoveNull(d.values) + : d.values, + x = isSub ? $$.subX : $$.x, + y = yScaleGetter.call($$, d.id), + x0 = 0, + y0 = 0, + path; + if ($$.isLineType(d)) { + if (config.data_regions[d.id]) { + path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]); + } else { + if ($$.isStepType(d)) { + values = $$.convertValuesToStep(values); } - } - - // Set scales - xValue = config.axis_rotated ? function (d) { return y(d.value); } : function (d) { return x(d.x); }; - yValue = config.axis_rotated ? function (d) { return x(d.x); } : function (d) { return y(d.value); }; - - // Define svg generator function for region - function generateM(points) { - return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1]; - } - if ($$.isTimeSeries()) { - sWithRegion = function (d0, d1, j, diff) { - var x0 = d0.x.getTime(), x_diff = d1.x - d0.x, - xv0 = new Date(x0 + x_diff * j), - xv1 = new Date(x0 + x_diff * (j + diff)), - points; - if (config.axis_rotated) { - points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]]; - } else { - points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]]; - } - return generateM(points); - }; + path = line.curve($$.getInterpolate(d))(values); + } } else { - sWithRegion = function (d0, d1, j, diff) { - var points; - if (config.axis_rotated) { - points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]]; - } else { - points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]]; - } - return generateM(points); - }; + if (values[0]) { + x0 = x(values[0].x); + y0 = y(values[0].value); + } + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } - - // Generate - for (i = 0; i < d.length; i++) { - - // Draw as normal - if (isUndefined(regions) || ! isWithinRegions(d[i].x, regions)) { - s += " " + xValue(d[i]) + " " + yValue(d[i]); - } - // Draw with region // TODO: Fix for horizotal charts - else { - xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries()); - yp = $$.getScale(d[i - 1].value, d[i].value); - - dx = x(d[i].x) - x(d[i - 1].x); - dy = y(d[i].value) - y(d[i - 1].value); - dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); - diff = 2 / dd; - diffx2 = diff * 2; - - for (j = diff; j <= 1; j += diffx2) { - s += sWithRegion(d[i - 1], d[i], j, diff); - } - } - prev = d[i].x; + return path ? path : 'M 0 0' + } +}; +ChartInternal.prototype.generateGetLinePoints = function(lineIndices, isSub) { + // partial duplication of generateGetBarPoints + var $$ = this, + config = $$.config, + lineTargetsNum = lineIndices.__max__ + 1, + x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), + y = $$.getShapeY(!!isSub), + lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), + yScale = isSub ? $$.getSubYScale : $$.getYScale; + return function(d, i) { + var y0 = yScale.call($$, d.id)(0), + offset = lineOffset(d, i) || y0, // offset is for stacked area chart + posX = x(d), + posY = y(d); + // fix posY not to overflow opposite quadrant + if (config.axis_rotated) { + if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { + posY = y0; + } } - - return s; + // 1 point that marks the line position + return [ + [posX, posY - (y0 - offset)], + [posX, posY - (y0 - offset)], // needed for compatibility + [posX, posY - (y0 - offset)], // needed for compatibility + [posX, posY - (y0 - offset)] // needed for compatibility + ] + } }; +ChartInternal.prototype.lineWithRegions = function(d, x, y, _regions) { + var $$ = this, + config = $$.config, + prev = -1, + i, + j, + s = 'M', + sWithRegion, + xp, + yp, + dx, + dy, + dd, + diff, + diffx2, + xOffset = $$.isCategorized() ? 0.5 : 0, + xValue, + yValue, + regions = []; + + function isWithinRegions(x, regions) { + var i; + for (i = 0; i < regions.length; i++) { + if (regions[i].start < x && x <= regions[i].end) { + return true + } + } + return false + } -ChartInternal.prototype.updateArea = function (durationForExit) { - var $$ = this, d3 = $$.d3; - var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area) - .data($$.lineData.bind($$)); - var mainAreaEnter = mainArea.enter().append('path') - .attr("class", $$.classArea.bind($$)) - .style("fill", $$.color) - .style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); - $$.mainArea = mainAreaEnter.merge(mainArea) - .style("opacity", $$.orgAreaOpacity); - mainArea.exit().transition().duration(durationForExit) - .style('opacity', 0); -}; -ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) { - return [ - (withTransition ? this.mainArea.transition(transition) : this.mainArea) - .attr("d", drawArea) - .style("fill", this.color) - .style("opacity", this.orgAreaOpacity) - ]; -}; -ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) { - var $$ = this, config = $$.config, area = $$.d3.area(), - getPoints = $$.generateGetAreaPoints(areaIndices, isSub), - yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, - xValue = function (d) { return (isSub ? $$.subxx : $$.xx).call($$, d); }, - value0 = function (d, i) { - return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id)); - }, - value1 = function (d, i) { - return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value); - }; - - area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1); - if (!config.line_connectNull) { - area = area.defined(function (d) { return d.value !== null; }); + // Check start/end of regions + if (isDefined(_regions)) { + for (i = 0; i < _regions.length; i++) { + regions[i] = {}; + if (isUndefined(_regions[i].start)) { + regions[i].start = d[0].x; + } else { + regions[i].start = $$.isTimeSeries() + ? $$.parseDate(_regions[i].start) + : _regions[i].start; + } + if (isUndefined(_regions[i].end)) { + regions[i].end = d[d.length - 1].x; + } else { + regions[i].end = $$.isTimeSeries() + ? $$.parseDate(_regions[i].end) + : _regions[i].end; + } } + } - return function (d) { - var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values, - x0 = 0, y0 = 0, path; - if ($$.isAreaType(d)) { - if ($$.isStepType(d)) { values = $$.convertValuesToStep(values); } - path = area.curve($$.getInterpolate(d))(values); - } else { - if (values[0]) { - x0 = $$.x(values[0].x); - y0 = $$.getYScale(d.id)(values[0].value); - } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; - } - return path ? path : "M 0 0"; - }; -}; -ChartInternal.prototype.getAreaBaseValue = function () { - return 0; -}; -ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) { // partial duplication of generateGetBarPoints - var $$ = this, config = $$.config, - areaTargetsNum = areaIndices.__max__ + 1, - x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), - y = $$.getShapeY(!!isSub), - areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), - yScale = isSub ? $$.getSubYScale : $$.getYScale; - return function (d, i) { - var y0 = yScale.call($$, d.id)(0), - offset = areaOffset(d, i) || y0, // offset is for stacked area chart - posX = x(d), posY = y(d); - // fix posY not to overflow opposite quadrant - if (config.axis_rotated) { - if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; } - } - // 1 point that marks the area position - return [ - [posX, offset], - [posX, posY - (y0 - offset)], - [posX, posY - (y0 - offset)], // needed for compatibility - [posX, offset] // needed for compatibility + // Set scales + xValue = config.axis_rotated + ? function(d) { + return y(d.value) + } + : function(d) { + return x(d.x) + }; + yValue = config.axis_rotated + ? function(d) { + return x(d.x) + } + : function(d) { + return y(d.value) + }; + + // Define svg generator function for region + function generateM(points) { + return ( + 'M' + + points[0][0] + + ' ' + + points[0][1] + + ' ' + + points[1][0] + + ' ' + + points[1][1] + ) + } + if ($$.isTimeSeries()) { + sWithRegion = function(d0, d1, j, diff) { + var x0 = d0.x.getTime(), + x_diff = d1.x - d0.x, + xv0 = new Date(x0 + x_diff * j), + xv1 = new Date(x0 + x_diff * (j + diff)), + points; + if (config.axis_rotated) { + points = [ + [y(yp(j)), x(xv0)], + [y(yp(j + diff)), x(xv1)] + ]; + } else { + points = [ + [x(xv0), y(yp(j))], + [x(xv1), y(yp(j + diff))] ]; + } + return generateM(points) }; -}; - - -ChartInternal.prototype.updateCircle = function (cx, cy) { - var $$ = this; - var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle) - .data($$.lineOrScatterOrStanfordData.bind($$)); + } else { + sWithRegion = function(d0, d1, j, diff) { + var points; + if (config.axis_rotated) { + points = [ + [y(yp(j), true), x(xp(j))], + [y(yp(j + diff), true), x(xp(j + diff))] + ]; + } else { + points = [ + [x(xp(j), true), y(yp(j))], + [x(xp(j + diff), true), y(yp(j + diff))] + ]; + } + return generateM(points) + }; + } - var mainCircleEnter = mainCircle.enter().append("circle") - .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '') - .attr("class", $$.classCircle.bind($$)) - .attr("cx", cx) - .attr("cy", cy) - .attr("r", $$.pointR.bind($$)) - .style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color); + // Generate + for (i = 0; i < d.length; i++) { + // Draw as normal + if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) { + s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]); + } + // Draw with region // TODO: Fix for horizotal charts + else { + xp = $$.getScale( + d[i - 1].x + xOffset, + d[i].x + xOffset, + $$.isTimeSeries() + ); + yp = $$.getScale(d[i - 1].value, d[i].value); + + dx = x(d[i].x) - x(d[i - 1].x); + dy = y(d[i].value) - y(d[i - 1].value); + dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + diff = 2 / dd; + diffx2 = diff * 2; + + for (j = diff; j <= 1; j += diffx2) { + s += sWithRegion(d[i - 1], d[i], j, diff); + } + } + prev = d[i].x; + } - $$.mainCircle = mainCircleEnter.merge(mainCircle) - .style("opacity", $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)); + return s +}; + +ChartInternal.prototype.updateArea = function(durationForExit) { + var $$ = this, + d3 = $$.d3; + var mainArea = $$.main + .selectAll('.' + CLASS.areas) + .selectAll('.' + CLASS.area) + .data($$.lineData.bind($$)); + var mainAreaEnter = mainArea + .enter() + .append('path') + .attr('class', $$.classArea.bind($$)) + .style('fill', $$.color) + .style('opacity', function() { + $$.orgAreaOpacity = +d3.select(this).style('opacity'); + return 0 + }); + $$.mainArea = mainAreaEnter + .merge(mainArea) + .style('opacity', $$.orgAreaOpacity); + mainArea + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0); +}; +ChartInternal.prototype.redrawArea = function( + drawArea, + withTransition, + transition +) { + return [ + (withTransition ? this.mainArea.transition(transition) : this.mainArea) + .attr('d', drawArea) + .style('fill', this.color) + .style('opacity', this.orgAreaOpacity) + ] +}; +ChartInternal.prototype.generateDrawArea = function(areaIndices, isSub) { + var $$ = this, + config = $$.config, + area = $$.d3.area(), + getPoints = $$.generateGetAreaPoints(areaIndices, isSub), + yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, + xValue = function(d) { + return (isSub ? $$.subxx : $$.xx).call($$, d) + }, + value0 = function(d, i) { + return config.data_groups.length > 0 + ? getPoints(d, i)[0][1] + : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id)) + }, + value1 = function(d, i) { + return config.data_groups.length > 0 + ? getPoints(d, i)[1][1] + : yScaleGetter.call($$, d.id)(d.value) + }; - mainCircle.exit() - .style("opacity", 0); -}; -ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) { - var $$ = this, - selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); - return [ - (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle) - .style('opacity', this.opacityForCircle.bind($$)) - .style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color) - .attr("cx", cx) - .attr("cy", cy), - (withTransition ? selectedCircles.transition(transition) : selectedCircles) - .attr("cx", cx) - .attr("cy", cy) - ]; -}; -ChartInternal.prototype.circleX = function (d) { - return d.x || d.x === 0 ? this.x(d.x) : null; -}; -ChartInternal.prototype.updateCircleY = function () { - var $$ = this, lineIndices, getPoints; - if ($$.config.data_groups.length > 0) { - lineIndices = $$.getShapeIndices($$.isLineType), - getPoints = $$.generateGetLinePoints(lineIndices); - $$.circleY = function (d, i) { - return getPoints(d, i)[0][1]; - }; - } else { - $$.circleY = function (d) { - return $$.getYScale(d.id)(d.value); - }; - } -}; -ChartInternal.prototype.getCircles = function (i, id) { - var $$ = this; - return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')); -}; -ChartInternal.prototype.expandCircles = function (i, id, reset) { - var $$ = this, - r = $$.pointExpandedR.bind($$); - if (reset) { $$.unexpandCircles(); } - $$.getCircles(i, id) - .classed(CLASS.EXPANDED, true) - .attr('r', r); -}; -ChartInternal.prototype.unexpandCircles = function (i) { - var $$ = this, - r = $$.pointR.bind($$); - $$.getCircles(i) - .filter(function () { return $$.d3.select(this).classed(CLASS.EXPANDED); }) - .classed(CLASS.EXPANDED, false) - .attr('r', r); -}; -ChartInternal.prototype.pointR = function (d) { - var $$ = this, config = $$.config; - return $$.isStepType(d) ? 0 : (isFunction(config.point_r) ? config.point_r(d) : config.point_r); -}; -ChartInternal.prototype.pointExpandedR = function (d) { - var $$ = this, config = $$.config; - if (config.point_focus_expand_enabled) { - return isFunction(config.point_focus_expand_r) ? config.point_focus_expand_r(d) : ((config.point_focus_expand_r) ? config.point_focus_expand_r : $$.pointR(d) * 1.75); - } else { - return $$.pointR(d); - } -}; -ChartInternal.prototype.pointSelectR = function (d) { - var $$ = this, config = $$.config; - return isFunction(config.point_select_r) ? config.point_select_r(d) : ((config.point_select_r) ? config.point_select_r : $$.pointR(d) * 4); -}; -ChartInternal.prototype.isWithinCircle = function (that, r) { - var d3 = this.d3, - mouse = d3.mouse(that), d3_this = d3.select(that), - cx = +d3_this.attr("cx"), cy = +d3_this.attr("cy"); - return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r; -}; -ChartInternal.prototype.isWithinStep = function (that, y) { - return Math.abs(y - this.d3.mouse(that)[1]) < 30; -}; + area = config.axis_rotated + ? area + .x0(value0) + .x1(value1) + .y(xValue) + : area + .x(xValue) + .y0(config.area_above ? 0 : value0) + .y1(value1); + if (!config.line_connectNull) { + area = area.defined(function(d) { + return d.value !== null + }); + } -ChartInternal.prototype.getCurrentWidth = function () { - var $$ = this, config = $$.config; - return config.size_width ? config.size_width : $$.getParentWidth(); -}; -ChartInternal.prototype.getCurrentHeight = function () { - var $$ = this, config = $$.config, - h = config.size_height ? config.size_height : $$.getParentHeight(); - return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1); -}; -ChartInternal.prototype.getCurrentPaddingTop = function () { - var $$ = this, - config = $$.config, - padding = isValue(config.padding_top) ? config.padding_top : 0; - if ($$.title && $$.title.node()) { - padding += $$.getTitlePadding(); - } - return padding; -}; -ChartInternal.prototype.getCurrentPaddingBottom = function () { - var config = this.config; - return isValue(config.padding_bottom) ? config.padding_bottom : 0; -}; -ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) { - var $$ = this, config = $$.config; - if (isValue(config.padding_left)) { - return config.padding_left; - } else if (config.axis_rotated) { - return (!config.axis_x_show || config.axis_x_inner) ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40); - } else if (!config.axis_y_show || config.axis_y_inner) { // && !config.axis_rotated - return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1; + return function(d) { + var values = config.line_connectNull + ? $$.filterRemoveNull(d.values) + : d.values, + x0 = 0, + y0 = 0, + path; + if ($$.isAreaType(d)) { + if ($$.isStepType(d)) { + values = $$.convertValuesToStep(values); + } + path = area.curve($$.getInterpolate(d))(values); } else { - return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute)); + if (values[0]) { + x0 = $$.x(values[0].x); + y0 = $$.getYScale(d.id)(values[0].value); + } + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } + return path ? path : 'M 0 0' + } }; -ChartInternal.prototype.getCurrentPaddingRight = function () { - var $$ = this, config = $$.config, padding = 0, - defaultPadding = 10, legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0; - - if (isValue(config.padding_right)) { - padding = config.padding_right + 1; // 1 is needed not to hide tick line - } else if (config.axis_rotated) { - padding = defaultPadding + legendWidthOnRight; - } else if (!config.axis_y2_show || config.axis_y2_inner) { // && !config.axis_rotated - padding = 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0); - } else { - padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight; - } - - if ($$.colorScale && $$.colorScale.node()) { - padding += $$.getColorScalePadding(); +ChartInternal.prototype.getAreaBaseValue = function() { + return 0 +}; +ChartInternal.prototype.generateGetAreaPoints = function(areaIndices, isSub) { + // partial duplication of generateGetBarPoints + var $$ = this, + config = $$.config, + areaTargetsNum = areaIndices.__max__ + 1, + x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), + y = $$.getShapeY(!!isSub), + areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), + yScale = isSub ? $$.getSubYScale : $$.getYScale; + return function(d, i) { + var y0 = yScale.call($$, d.id)(0), + offset = areaOffset(d, i) || y0, // offset is for stacked area chart + posX = x(d), + posY = y(d); + // fix posY not to overflow opposite quadrant + if (config.axis_rotated) { + if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { + posY = y0; + } } - - return padding; + // 1 point that marks the area position + return [ + [posX, offset], + [posX, posY - (y0 - offset)], + [posX, posY - (y0 - offset)], // needed for compatibility + [posX, offset] // needed for compatibility + ] + } }; -ChartInternal.prototype.getParentRectValue = function (key) { - var parent = this.selectChart.node(), v; - while (parent && parent.tagName !== 'BODY') { - try { - v = parent.getBoundingClientRect()[key]; - } catch(e) { - if (key === 'width') { - // In IE in certain cases getBoundingClientRect - // will cause an "unspecified error" - v = parent.offsetWidth; - } - } - if (v) { - break; - } - parent = parent.parentNode; - } - return v; +ChartInternal.prototype.updateCircle = function(cx, cy) { + var $$ = this; + var mainCircle = $$.main + .selectAll('.' + CLASS.circles) + .selectAll('.' + CLASS.circle) + .data($$.lineOrScatterOrStanfordData.bind($$)); + + var mainCircleEnter = mainCircle + .enter() + .append('circle') + .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '') + .attr('class', $$.classCircle.bind($$)) + .attr('cx', cx) + .attr('cy', cy) + .attr('r', $$.pointR.bind($$)) + .style( + 'color', + $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color + ); + + $$.mainCircle = mainCircleEnter + .merge(mainCircle) + .style( + 'opacity', + $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$) + ); + + mainCircle.exit().style('opacity', 0); +}; +ChartInternal.prototype.redrawCircle = function( + cx, + cy, + withTransition, + transition +) { + var $$ = this, + selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); + return [ + (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle) + .style('opacity', this.opacityForCircle.bind($$)) + .style( + 'color', + $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color + ) + .attr('cx', cx) + .attr('cy', cy), + (withTransition ? selectedCircles.transition(transition) : selectedCircles) + .attr('cx', cx) + .attr('cy', cy) + ] +}; +ChartInternal.prototype.circleX = function(d) { + return d.x || d.x === 0 ? this.x(d.x) : null +}; +ChartInternal.prototype.updateCircleY = function() { + var $$ = this, + lineIndices, + getPoints; + if ($$.config.data_groups.length > 0) { +(lineIndices = $$.getShapeIndices($$.isLineType)), + (getPoints = $$.generateGetLinePoints(lineIndices)); + $$.circleY = function(d, i) { + return getPoints(d, i)[0][1] + }; + } else { + $$.circleY = function(d) { + return $$.getYScale(d.id)(d.value) + }; + } }; -ChartInternal.prototype.getParentWidth = function () { - return this.getParentRectValue('width'); +ChartInternal.prototype.getCircles = function(i, id) { + var $$ = this; + return (id + ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) + : $$.main + ).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')) +}; +ChartInternal.prototype.expandCircles = function(i, id, reset) { + var $$ = this, + r = $$.pointExpandedR.bind($$); + if (reset) { + $$.unexpandCircles(); + } + $$.getCircles(i, id) + .classed(CLASS.EXPANDED, true) + .attr('r', r); +}; +ChartInternal.prototype.unexpandCircles = function(i) { + var $$ = this, + r = $$.pointR.bind($$); + $$.getCircles(i) + .filter(function() { + return $$.d3.select(this).classed(CLASS.EXPANDED) + }) + .classed(CLASS.EXPANDED, false) + .attr('r', r); +}; +ChartInternal.prototype.pointR = function(d) { + var $$ = this, + config = $$.config; + return $$.isStepType(d) + ? 0 + : isFunction(config.point_r) + ? config.point_r(d) + : config.point_r +}; +ChartInternal.prototype.pointExpandedR = function(d) { + var $$ = this, + config = $$.config; + if (config.point_focus_expand_enabled) { + return isFunction(config.point_focus_expand_r) + ? config.point_focus_expand_r(d) + : config.point_focus_expand_r + ? config.point_focus_expand_r + : $$.pointR(d) * 1.75 + } else { + return $$.pointR(d) + } }; -ChartInternal.prototype.getParentHeight = function () { - var h = this.selectChart.style('height'); - return h.indexOf('px') > 0 ? +h.replace('px', '') : 0; +ChartInternal.prototype.pointSelectR = function(d) { + var $$ = this, + config = $$.config; + return isFunction(config.point_select_r) + ? config.point_select_r(d) + : config.point_select_r + ? config.point_select_r + : $$.pointR(d) * 4 +}; +ChartInternal.prototype.isWithinCircle = function(that, r) { + var d3 = this.d3, + mouse = d3.mouse(that), + d3_this = d3.select(that), + cx = +d3_this.attr('cx'), + cy = +d3_this.attr('cy'); + return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r +}; +ChartInternal.prototype.isWithinStep = function(that, y) { + return Math.abs(y - this.d3.mouse(that)[1]) < 30 +}; + +ChartInternal.prototype.getCurrentWidth = function() { + var $$ = this, + config = $$.config; + return config.size_width ? config.size_width : $$.getParentWidth() +}; +ChartInternal.prototype.getCurrentHeight = function() { + var $$ = this, + config = $$.config, + h = config.size_height ? config.size_height : $$.getParentHeight(); + return h > 0 + ? h + : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1) +}; +ChartInternal.prototype.getCurrentPaddingTop = function() { + var $$ = this, + config = $$.config, + padding = isValue(config.padding_top) ? config.padding_top : 0; + if ($$.title && $$.title.node()) { + padding += $$.getTitlePadding(); + } + return padding +}; +ChartInternal.prototype.getCurrentPaddingBottom = function() { + var config = this.config; + return isValue(config.padding_bottom) ? config.padding_bottom : 0 +}; +ChartInternal.prototype.getCurrentPaddingLeft = function(withoutRecompute) { + var $$ = this, + config = $$.config; + if (isValue(config.padding_left)) { + return config.padding_left + } else if (config.axis_rotated) { + return !config.axis_x_show || config.axis_x_inner + ? 1 + : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40) + } else if (!config.axis_y_show || config.axis_y_inner) { + // && !config.axis_rotated + return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1 + } else { + return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute)) + } }; +ChartInternal.prototype.getCurrentPaddingRight = function() { + var $$ = this, + config = $$.config, + padding = 0, + defaultPadding = 10, + legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0; + + if (isValue(config.padding_right)) { + padding = config.padding_right + 1; // 1 is needed not to hide tick line + } else if (config.axis_rotated) { + padding = defaultPadding + legendWidthOnRight; + } else if (!config.axis_y2_show || config.axis_y2_inner) { + // && !config.axis_rotated + padding = + 2 + + legendWidthOnRight + + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0); + } else { + padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight; + } + if ($$.colorScale && $$.colorScale.node()) { + padding += $$.getColorScalePadding(); + } -ChartInternal.prototype.getSvgLeft = function (withoutRecompute) { - var $$ = this, config = $$.config, - hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), - leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, - leftAxis = $$.main.select('.' + leftAxisClass).node(), - svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {right: 0}, - chartRect = $$.selectChart.node().getBoundingClientRect(), - hasArc = $$.hasArcType(), - svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute)); - return svgLeft > 0 ? svgLeft : 0; + return padding }; - -ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) { - var $$ = this, position = $$.axis.getLabelPositionById(id); - return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40); -}; -ChartInternal.prototype.getHorizontalAxisHeight = function (axisId) { - var $$ = this, config = $$.config, h = 30; - if (axisId === 'x' && !config.axis_x_show) { return 8; } - if (axisId === 'x' && config.axis_x_height) { return config.axis_x_height; } - if (axisId === 'y' && !config.axis_y_show) { - return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1; +ChartInternal.prototype.getParentRectValue = function(key) { + var parent = this.selectChart.node(), + v; + while (parent && parent.tagName !== 'BODY') { + try { + v = parent.getBoundingClientRect()[key]; + } catch (e) { + if (key === 'width') { + // In IE in certain cases getBoundingClientRect + // will cause an "unspecified error" + v = parent.offsetWidth; + } } - if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; } - // Calculate x axis height when tick rotated - if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { - h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_x_tick_rotate)) / 180); - } - // Calculate y axis height when tick rotated - if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) { - h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_y_tick_rotate)) / 180); - } - return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0); -}; - -ChartInternal.prototype.initBrush = function (scale) { - var $$ = this, d3 = $$.d3; - // TODO: dynamically change brushY/brushX according to axis_rotated. - $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () { - var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { return; } - $$.redrawForBrush(); - }).on("end", function () { - var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { return; } - if ($$.brush.empty() && event && event.type !== 'end') { $$.brush.clear(); } - }); - $$.brush.updateExtent = function () { - var range = this.scale.range(), extent; - if ($$.config.axis_rotated) { - extent = [[0, range[0]], [$$.width2, range[1]]]; - } - else { - extent = [[range[0], 0], [range[1], $$.height2]]; - } - this.extent(extent); - return this; - }; - $$.brush.updateScale = function (scale) { - this.scale = scale; - return this; - }; - $$.brush.update = function (scale) { - this.updateScale(scale || $$.subX).updateExtent(); - $$.context.select('.' + CLASS.brush).call(this); - }; - $$.brush.clear = function () { - $$.context.select('.' + CLASS.brush).call($$.brush.move, null); - }; - $$.brush.selection = function () { - return d3.brushSelection($$.context.select('.' + CLASS.brush).node()); - }; - $$.brush.selectionAsValue = function (selectionAsValue, withTransition) { - var selection, brush; - if (selectionAsValue) { - if ($$.context) { - selection = [this.scale(selectionAsValue[0]), this.scale(selectionAsValue[1])]; - brush = $$.context.select('.' + CLASS.brush); - if (withTransition) { brush = brush.transition(); } - $$.brush.move(brush, selection); - } - return []; - } - selection = $$.brush.selection() || [0,0]; - return [this.scale.invert(selection[0]), this.scale.invert(selection[1])]; - }; - $$.brush.empty = function () { - var selection = $$.brush.selection(); - return !selection || selection[0] === selection[1]; - }; - return $$.brush.updateScale(scale); -}; -ChartInternal.prototype.initSubchart = function () { - var $$ = this, config = $$.config, - context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')); - - // set style - context.style('visibility', 'visible'); - - // Define g for chart area - context.append('g') - .attr("clip-path", $$.clipPathForSubchart) - .attr('class', CLASS.chart); - - // Define g for bar chart area - context.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartBars); - - // Define g for line chart area - context.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartLines); - - // Add extent rect for Brush - context.append("g") - .attr("clip-path", $$.clipPath) - .attr("class", CLASS.brush); - - // ATTENTION: This must be called AFTER chart added - // Add Axis - $$.axes.subx = context.append("g") - .attr("class", CLASS.axisX) - .attr("transform", $$.getTranslate('subx')) - .attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis); -}; -ChartInternal.prototype.initSubchartBrush = function () { - var $$ = this; - // Add extent rect for Brush - $$.initBrush($$.subX).updateExtent(); - $$.context.select('.' + CLASS.brush).call($$.brush); -}; -ChartInternal.prototype.updateTargetsForSubchart = function (targets) { - var $$ = this, context = $$.context, config = $$.config, - contextLineEnter, contextLine, contextBarEnter, contextBar, - classChartBar = $$.classChartBar.bind($$), - classBars = $$.classBars.bind($$), - classChartLine = $$.classChartLine.bind($$), - classLines = $$.classLines.bind($$), - classAreas = $$.classAreas.bind($$); - - //-- Bar --// - contextBar = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar) - .data(targets); - contextBarEnter = contextBar.enter().append('g') - .style('opacity', 0); - contextBarEnter.merge(contextBar) - .attr('class', classChartBar); - // Bars for each data - contextBarEnter.append('g') - .attr("class", classBars); - - //-- Line --// - contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine) - .data(targets); - contextLineEnter = contextLine.enter().append('g') - .style('opacity', 0); - contextLineEnter.merge(contextLine) - .attr('class', classChartLine); - // Lines for each data - contextLineEnter.append("g") - .attr("class", classLines); - // Area - contextLineEnter.append("g") - .attr("class", classAreas); - - //-- Brush --// - context.selectAll('.' + CLASS.brush + ' rect') - .attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2); -}; -ChartInternal.prototype.updateBarForSubchart = function (durationForExit) { - var $$ = this; - var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar) - .data($$.barData.bind($$)); - var contextBarEnter = contextBar.enter().append('path') - .attr("class", $$.classBar.bind($$)) - .style("stroke", 'none') - .style("fill", $$.color); - contextBar.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - $$.contextBar = contextBarEnter.merge(contextBar) - .style("opacity", $$.initialOpacity.bind($$)); -}; -ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) { - (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar) - .attr('d', drawBarOnSub) - .style('opacity', 1); -}; -ChartInternal.prototype.updateLineForSubchart = function (durationForExit) { - var $$ = this; - var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line) - .data($$.lineData.bind($$)); - var contextLineEnter = contextLine.enter().append('path') - .attr('class', $$.classLine.bind($$)) - .style('stroke', $$.color); - contextLine.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - $$.contextLine = contextLineEnter.merge(contextLine) - .style("opacity", $$.initialOpacity.bind($$)); -}; -ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) { - (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine) - .attr("d", drawLineOnSub) - .style('opacity', 1); -}; -ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) { - var $$ = this, d3 = $$.d3; - var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area) - .data($$.lineData.bind($$)); - var contextAreaEnter = contextArea.enter().append('path') - .attr("class", $$.classArea.bind($$)) - .style("fill", $$.color) - .style("opacity", function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); - contextArea.exit().transition().duration(durationForExit) - .style('opacity', 0) - .remove(); - $$.contextArea = contextAreaEnter.merge(contextArea) - .style("opacity", 0); -}; -ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) { - (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea) - .attr("d", drawAreaOnSub) - .style("fill", this.color) - .style("opacity", this.orgAreaOpacity); -}; -ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) { - var $$ = this, d3 = $$.d3, - drawAreaOnSub, drawBarOnSub, drawLineOnSub; - - // reflect main chart to extent on subchart if zoomed - if (d3.event && d3.event.type === 'zoom') { - $$.brush.selectionAsValue($$.x.orgDomain()); - } - // update subchart elements if needed - if (withSubchart) { - // extent rect - if (!$$.brush.empty()) { - $$.brush.selectionAsValue($$.x.orgDomain()); - } - // setup drawer - MEMO: this must be called after axis updated - drawAreaOnSub = $$.generateDrawArea(areaIndices, true); - drawBarOnSub = $$.generateDrawBar(barIndices, true); - drawLineOnSub = $$.generateDrawLine(lineIndices, true); - - $$.updateBarForSubchart(duration); - $$.updateLineForSubchart(duration); - $$.updateAreaForSubchart(duration); - - $$.redrawBarForSubchart(drawBarOnSub, duration, duration); - $$.redrawLineForSubchart(drawLineOnSub, duration, duration); - $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration); + if (v) { + break } -}; -ChartInternal.prototype.redrawForBrush = function () { - var $$ = this, x = $$.x, d3 = $$.d3, s; - $$.redraw({ - withTransition: false, - withY: $$.config.zoom_rescale, - withSubchart: false, - withUpdateXDomain: true, - withEventRect: false, - withDimension: false + parent = parent.parentNode; + } + return v +}; +ChartInternal.prototype.getParentWidth = function() { + return this.getParentRectValue('width') +}; +ChartInternal.prototype.getParentHeight = function() { + var h = this.selectChart.style('height'); + return h.indexOf('px') > 0 ? +h.replace('px', '') : 0 +}; + +ChartInternal.prototype.getSvgLeft = function(withoutRecompute) { + var $$ = this, + config = $$.config, + hasLeftAxisRect = + config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), + leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, + leftAxis = $$.main.select('.' + leftAxisClass).node(), + svgRect = + leftAxis && hasLeftAxisRect + ? leftAxis.getBoundingClientRect() + : { right: 0 }, + chartRect = $$.selectChart.node().getBoundingClientRect(), + hasArc = $$.hasArcType(), + svgLeft = + svgRect.right - + chartRect.left - + (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute)); + return svgLeft > 0 ? svgLeft : 0 +}; + +ChartInternal.prototype.getAxisWidthByAxisId = function(id, withoutRecompute) { + var $$ = this, + position = $$.axis.getLabelPositionById(id); + return ( + $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40) + ) +}; +ChartInternal.prototype.getHorizontalAxisHeight = function(axisId) { + var $$ = this, + config = $$.config, + h = 30; + if (axisId === 'x' && !config.axis_x_show) { + return 8 + } + if (axisId === 'x' && config.axis_x_height) { + return config.axis_x_height + } + if (axisId === 'y' && !config.axis_y_show) { + return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1 + } + if (axisId === 'y2' && !config.axis_y2_show) { + return $$.rotated_padding_top + } + // Calculate x axis height when tick rotated + if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { + h = + 30 + + $$.axis.getMaxTickWidth(axisId) * + Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180); + } + // Calculate y axis height when tick rotated + if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) { + h = + 30 + + $$.axis.getMaxTickWidth(axisId) * + Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180); + } + return ( + h + + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + + (axisId === 'y2' ? -10 : 0) + ) +}; + +ChartInternal.prototype.initBrush = function(scale) { + var $$ = this, + d3 = $$.d3; + // TODO: dynamically change brushY/brushX according to axis_rotated. + $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()) + .on('brush', function() { + var event = d3.event.sourceEvent; + if (event && event.type === 'zoom') { + return + } + $$.redrawForBrush(); + }) + .on('end', function() { + var event = d3.event.sourceEvent; + if (event && event.type === 'zoom') { + return + } + if ($$.brush.empty() && event && event.type !== 'end') { + $$.brush.clear(); + } }); - // update zoom transation binded to event rect - s = d3.event.selection || $$.brush.scale.range(); - $$.main.select('.' + CLASS.eventRect).call($$.zoom.transform, d3.zoomIdentity - .scale($$.width / (s[1] - s[0])) - .translate(-s[0], 0)); - $$.config.subchart_onbrush.call($$.api, x.orgDomain()); -}; -ChartInternal.prototype.transformContext = function (withTransition, transitions) { - var $$ = this, subXAxis; - if (transitions && transitions.axisSubX) { - subXAxis = transitions.axisSubX; + $$.brush.updateExtent = function() { + var range = this.scale.range(), + extent; + if ($$.config.axis_rotated) { + extent = [ + [0, range[0]], + [$$.width2, range[1]] + ]; } else { - subXAxis = $$.context.select('.' + CLASS.axisX); - if (withTransition) { subXAxis = subXAxis.transition(); } - } - $$.context.attr("transform", $$.getTranslate('context')); - subXAxis.attr("transform", $$.getTranslate('subx')); + extent = [ + [range[0], 0], + [range[1], $$.height2] + ]; + } + this.extent(extent); + return this + }; + $$.brush.updateScale = function(scale) { + this.scale = scale; + return this + }; + $$.brush.update = function(scale) { + this.updateScale(scale || $$.subX).updateExtent(); + $$.context.select('.' + CLASS.brush).call(this); + }; + $$.brush.clear = function() { + $$.context.select('.' + CLASS.brush).call($$.brush.move, null); + }; + $$.brush.selection = function() { + return d3.brushSelection($$.context.select('.' + CLASS.brush).node()) + }; + $$.brush.selectionAsValue = function(selectionAsValue, withTransition) { + var selection, brush; + if (selectionAsValue) { + if ($$.context) { + selection = [ + this.scale(selectionAsValue[0]), + this.scale(selectionAsValue[1]) + ]; + brush = $$.context.select('.' + CLASS.brush); + if (withTransition) { + brush = brush.transition(); + } + $$.brush.move(brush, selection); + } + return [] + } + selection = $$.brush.selection() || [0, 0]; + return [this.scale.invert(selection[0]), this.scale.invert(selection[1])] + }; + $$.brush.empty = function() { + var selection = $$.brush.selection(); + return !selection || selection[0] === selection[1] + }; + return $$.brush.updateScale(scale) +}; +ChartInternal.prototype.initSubchart = function() { + var $$ = this, + config = $$.config, + context = ($$.context = $$.svg + .append('g') + .attr('transform', $$.getTranslate('context'))); + + // set style + context.style('visibility', 'visible'); + + // Define g for chart area + context + .append('g') + .attr('clip-path', $$.clipPathForSubchart) + .attr('class', CLASS.chart); + + // Define g for bar chart area + context + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartBars); + + // Define g for line chart area + context + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartLines); + + // Add extent rect for Brush + context + .append('g') + .attr('clip-path', $$.clipPath) + .attr('class', CLASS.brush); + + // ATTENTION: This must be called AFTER chart added + // Add Axis + $$.axes.subx = context + .append('g') + .attr('class', CLASS.axisX) + .attr('transform', $$.getTranslate('subx')) + .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis); +}; +ChartInternal.prototype.initSubchartBrush = function() { + var $$ = this; + // Add extent rect for Brush + $$.initBrush($$.subX).updateExtent(); + $$.context.select('.' + CLASS.brush).call($$.brush); +}; +ChartInternal.prototype.updateTargetsForSubchart = function(targets) { + var $$ = this, + context = $$.context, + config = $$.config, + contextLineEnter, + contextLine, + contextBarEnter, + contextBar, + classChartBar = $$.classChartBar.bind($$), + classBars = $$.classBars.bind($$), + classChartLine = $$.classChartLine.bind($$), + classLines = $$.classLines.bind($$), + classAreas = $$.classAreas.bind($$); + + //-- Bar --// + contextBar = context + .select('.' + CLASS.chartBars) + .selectAll('.' + CLASS.chartBar) + .data(targets); + contextBarEnter = contextBar + .enter() + .append('g') + .style('opacity', 0); + contextBarEnter.merge(contextBar).attr('class', classChartBar); + // Bars for each data + contextBarEnter.append('g').attr('class', classBars); + + //-- Line --// + contextLine = context + .select('.' + CLASS.chartLines) + .selectAll('.' + CLASS.chartLine) + .data(targets); + contextLineEnter = contextLine + .enter() + .append('g') + .style('opacity', 0); + contextLineEnter.merge(contextLine).attr('class', classChartLine); + // Lines for each data + contextLineEnter.append('g').attr('class', classLines); + // Area + contextLineEnter.append('g').attr('class', classAreas); + + //-- Brush --// + context + .selectAll('.' + CLASS.brush + ' rect') + .attr( + config.axis_rotated ? 'width' : 'height', + config.axis_rotated ? $$.width2 : $$.height2 + ); +}; +ChartInternal.prototype.updateBarForSubchart = function(durationForExit) { + var $$ = this; + var contextBar = $$.context + .selectAll('.' + CLASS.bars) + .selectAll('.' + CLASS.bar) + .data($$.barData.bind($$)); + var contextBarEnter = contextBar + .enter() + .append('path') + .attr('class', $$.classBar.bind($$)) + .style('stroke', 'none') + .style('fill', $$.color); + contextBar + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + $$.contextBar = contextBarEnter + .merge(contextBar) + .style('opacity', $$.initialOpacity.bind($$)); +}; +ChartInternal.prototype.redrawBarForSubchart = function( + drawBarOnSub, + withTransition, + duration +) { +(withTransition + ? this.contextBar.transition(Math.random().toString()).duration(duration) + : this.contextBar + ) + .attr('d', drawBarOnSub) + .style('opacity', 1); +}; +ChartInternal.prototype.updateLineForSubchart = function(durationForExit) { + var $$ = this; + var contextLine = $$.context + .selectAll('.' + CLASS.lines) + .selectAll('.' + CLASS.line) + .data($$.lineData.bind($$)); + var contextLineEnter = contextLine + .enter() + .append('path') + .attr('class', $$.classLine.bind($$)) + .style('stroke', $$.color); + contextLine + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + $$.contextLine = contextLineEnter + .merge(contextLine) + .style('opacity', $$.initialOpacity.bind($$)); +}; +ChartInternal.prototype.redrawLineForSubchart = function( + drawLineOnSub, + withTransition, + duration +) { +(withTransition + ? this.contextLine.transition(Math.random().toString()).duration(duration) + : this.contextLine + ) + .attr('d', drawLineOnSub) + .style('opacity', 1); +}; +ChartInternal.prototype.updateAreaForSubchart = function(durationForExit) { + var $$ = this, + d3 = $$.d3; + var contextArea = $$.context + .selectAll('.' + CLASS.areas) + .selectAll('.' + CLASS.area) + .data($$.lineData.bind($$)); + var contextAreaEnter = contextArea + .enter() + .append('path') + .attr('class', $$.classArea.bind($$)) + .style('fill', $$.color) + .style('opacity', function() { + $$.orgAreaOpacity = +d3.select(this).style('opacity'); + return 0 + }); + contextArea + .exit() + .transition() + .duration(durationForExit) + .style('opacity', 0) + .remove(); + $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0); +}; +ChartInternal.prototype.redrawAreaForSubchart = function( + drawAreaOnSub, + withTransition, + duration +) { +(withTransition + ? this.contextArea.transition(Math.random().toString()).duration(duration) + : this.contextArea + ) + .attr('d', drawAreaOnSub) + .style('fill', this.color) + .style('opacity', this.orgAreaOpacity); +}; +ChartInternal.prototype.redrawSubchart = function( + withSubchart, + transitions, + duration, + durationForExit, + areaIndices, + barIndices, + lineIndices +) { + var $$ = this, + d3 = $$.d3, + drawAreaOnSub, + drawBarOnSub, + drawLineOnSub; + + // reflect main chart to extent on subchart if zoomed + if (d3.event && d3.event.type === 'zoom') { + $$.brush.selectionAsValue($$.x.orgDomain()); + } + // update subchart elements if needed + if (withSubchart) { + // extent rect + if (!$$.brush.empty()) { + $$.brush.selectionAsValue($$.x.orgDomain()); + } + // setup drawer - MEMO: this must be called after axis updated + drawAreaOnSub = $$.generateDrawArea(areaIndices, true); + drawBarOnSub = $$.generateDrawBar(barIndices, true); + drawLineOnSub = $$.generateDrawLine(lineIndices, true); + + $$.updateBarForSubchart(duration); + $$.updateLineForSubchart(duration); + $$.updateAreaForSubchart(duration); + + $$.redrawBarForSubchart(drawBarOnSub, duration, duration); + $$.redrawLineForSubchart(drawLineOnSub, duration, duration); + $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration); + } }; -ChartInternal.prototype.getDefaultSelection = function () { - var $$ = this, config = $$.config, - selection = isFunction(config.axis_x_selection) ? config.axis_x_selection($$.getXDomain($$.data.targets)) : config.axis_x_selection; - if ($$.isTimeSeries()) { - selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])]; +ChartInternal.prototype.redrawForBrush = function() { + var $$ = this, + x = $$.x, + d3 = $$.d3, + s; + $$.redraw({ + withTransition: false, + withY: $$.config.zoom_rescale, + withSubchart: false, + withUpdateXDomain: true, + withEventRect: false, + withDimension: false + }); + // update zoom transation binded to event rect + s = d3.event.selection || $$.brush.scale.range(); + $$.main + .select('.' + CLASS.eventRect) + .call( + $$.zoom.transform, + d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0) + ); + $$.config.subchart_onbrush.call($$.api, x.orgDomain()); +}; +ChartInternal.prototype.transformContext = function( + withTransition, + transitions +) { + var $$ = this, + subXAxis; + if (transitions && transitions.axisSubX) { + subXAxis = transitions.axisSubX; + } else { + subXAxis = $$.context.select('.' + CLASS.axisX); + if (withTransition) { + subXAxis = subXAxis.transition(); } - return selection; + } + $$.context.attr('transform', $$.getTranslate('context')); + subXAxis.attr('transform', $$.getTranslate('subx')); +}; +ChartInternal.prototype.getDefaultSelection = function() { + var $$ = this, + config = $$.config, + selection = isFunction(config.axis_x_selection) + ? config.axis_x_selection($$.getXDomain($$.data.targets)) + : config.axis_x_selection; + if ($$.isTimeSeries()) { + selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])]; + } + return selection }; ChartInternal.prototype.removeSubchart = function() { - const $$ = this; - - $$.brush = null; - $$.context.remove(); - $$.context = null; -}; - -ChartInternal.prototype.initText = function () { - var $$ = this; - $$.main.select('.' + CLASS.chart).append("g") - .attr("class", CLASS.chartTexts); - $$.mainText = $$.d3.selectAll([]); -}; -ChartInternal.prototype.updateTargetsForText = function (targets) { - var $$ = this, - classChartText = $$.classChartText.bind($$), - classTexts = $$.classTexts.bind($$), - classFocus = $$.classFocus.bind($$); - var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText) - .data(targets); - var mainTextEnter = mainText.enter().append('g') - .attr('class', classChartText) - .style('opacity', 0) - .style("pointer-events", "none"); - mainTextEnter.append('g') - .attr('class', classTexts); - mainTextEnter.merge(mainText) - .attr('class', function (d) { return classChartText(d) + classFocus(d); }); -}; -ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) { - var $$ = this, config = $$.config, - barOrLineData = $$.barOrLineData.bind($$), - classText = $$.classText.bind($$); - var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text) - .data(barOrLineData); - var mainTextEnter = mainText.enter().append('text') - .attr("class", classText) - .attr('text-anchor', function (d) { return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; }) - .style("stroke", 'none') - .attr('x', xForText) - .attr('y', yForText) - .style("fill", function (d) { return $$.color(d); }) - .style("fill-opacity", 0); - $$.mainText = mainTextEnter.merge(mainText) - .text(function (d, i, j) { return $$.dataLabelFormat(d.id)(d.value, d.id, i, j); }); - mainText.exit() - .transition().duration(durationForExit) - .style('fill-opacity', 0) - .remove(); + const $$ = this; + + $$.brush = null; + $$.context.remove(); + $$.context = null; +}; + +ChartInternal.prototype.initText = function() { + var $$ = this; + $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.chartTexts); + $$.mainText = $$.d3.selectAll([]); +}; +ChartInternal.prototype.updateTargetsForText = function(targets) { + var $$ = this, + classChartText = $$.classChartText.bind($$), + classTexts = $$.classTexts.bind($$), + classFocus = $$.classFocus.bind($$); + var mainText = $$.main + .select('.' + CLASS.chartTexts) + .selectAll('.' + CLASS.chartText) + .data(targets); + var mainTextEnter = mainText + .enter() + .append('g') + .attr('class', classChartText) + .style('opacity', 0) + .style('pointer-events', 'none'); + mainTextEnter.append('g').attr('class', classTexts); + mainTextEnter.merge(mainText).attr('class', function(d) { + return classChartText(d) + classFocus(d) + }); +}; +ChartInternal.prototype.updateText = function( + xForText, + yForText, + durationForExit +) { + var $$ = this, + config = $$.config, + barOrLineData = $$.barOrLineData.bind($$), + classText = $$.classText.bind($$); + var mainText = $$.main + .selectAll('.' + CLASS.texts) + .selectAll('.' + CLASS.text) + .data(barOrLineData); + var mainTextEnter = mainText + .enter() + .append('text') + .attr('class', classText) + .attr('text-anchor', function(d) { + return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle' + }) + .style('stroke', 'none') + .attr('x', xForText) + .attr('y', yForText) + .style('fill', function(d) { + return $$.color(d) + }) + .style('fill-opacity', 0); + $$.mainText = mainTextEnter.merge(mainText).text(function(d, i, j) { + return $$.dataLabelFormat(d.id)(d.value, d.id, i, j) + }); + mainText + .exit() + .transition() + .duration(durationForExit) + .style('fill-opacity', 0) + .remove(); +}; +ChartInternal.prototype.redrawText = function( + xForText, + yForText, + forFlow, + withTransition, + transition +) { + return [ + (withTransition ? this.mainText.transition(transition) : this.mainText) + .attr('x', xForText) + .attr('y', yForText) + .style('fill', this.color) + .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this)) + ] +}; +ChartInternal.prototype.getTextRect = function(text, cls, element) { + var dummy = this.d3 + .select('body') + .append('div') + .classed('c3', true), + svg = dummy + .append('svg') + .style('visibility', 'hidden') + .style('position', 'fixed') + .style('top', 0) + .style('left', 0), + font = this.d3.select(element).style('font'), + rect; + svg + .selectAll('.dummy') + .data([text]) + .enter() + .append('text') + .classed(cls ? cls : '', true) + .style('font', font) + .text(text) + .each(function() { + rect = getBBox(this); + }); + dummy.remove(); + return rect +}; +ChartInternal.prototype.generateXYForText = function( + areaIndices, + barIndices, + lineIndices, + forX +) { + var $$ = this, + getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), + getBarPoints = $$.generateGetBarPoints(barIndices, false), + getLinePoints = $$.generateGetLinePoints(lineIndices, false), + getter = forX ? $$.getXForText : $$.getYForText; + return function(d, i) { + var getPoints = $$.isAreaType(d) + ? getAreaPoints + : $$.isBarType(d) + ? getBarPoints + : getLinePoints; + return getter.call($$, getPoints(d, i), d, this) + } }; -ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) { - return [ - (withTransition ? this.mainText.transition(transition) : this.mainText) - .attr('x', xForText) - .attr('y', yForText) - .style("fill", this.color) - .style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this)) - ]; -}; -ChartInternal.prototype.getTextRect = function (text, cls, element) { - var dummy = this.d3.select('body').append('div').classed('c3', true), - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), - font = this.d3.select(element).style('font'), - rect; - svg.selectAll('.dummy') - .data([text]) - .enter().append('text') - .classed(cls ? cls : "", true) - .style('font', font) - .text(text) - .each(function () { rect = getBBox(this); }); - dummy.remove(); - return rect; -}; -ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) { - var $$ = this, - getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), - getBarPoints = $$.generateGetBarPoints(barIndices, false), - getLinePoints = $$.generateGetLinePoints(lineIndices, false), - getter = forX ? $$.getXForText : $$.getYForText; - return function (d, i) { - var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints; - return getter.call($$, getPoints(d, i), d, this); - }; -}; -ChartInternal.prototype.getXForText = function (points, d, textElement) { - var $$ = this, - box = getBBox(textElement), xPos, padding; - if ($$.config.axis_rotated) { - padding = $$.isBarType(d) ? 4 : 6; - xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1); - } else { - xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0]; - } - // show labels regardless of the domain if value is null - if (d.value === null) { - if (xPos > $$.width) { - xPos = $$.width - box.width; - } else if (xPos < 0) { - xPos = 4; - } +ChartInternal.prototype.getXForText = function(points, d, textElement) { + var $$ = this, + box = getBBox(textElement), + xPos, + padding; + if ($$.config.axis_rotated) { + padding = $$.isBarType(d) ? 4 : 6; + xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1); + } else { + xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0]; + } + // show labels regardless of the domain if value is null + if (d.value === null) { + if (xPos > $$.width) { + xPos = $$.width - box.width; + } else if (xPos < 0) { + xPos = 4; } - return xPos; -}; -ChartInternal.prototype.getYForText = function (points, d, textElement) { - var $$ = this, - box = getBBox(textElement), - yPos; - if ($$.config.axis_rotated) { - yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2; + } + return xPos +}; +ChartInternal.prototype.getYForText = function(points, d, textElement) { + var $$ = this, + box = getBBox(textElement), + yPos; + if ($$.config.axis_rotated) { + yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2; + } else { + yPos = points[2][1]; + if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) { + yPos += box.height; + if ($$.isBarType(d) && $$.isSafari()) { + yPos -= 3; + } else if (!$$.isBarType(d) && $$.isChrome()) { + yPos += 3; + } } else { - yPos = points[2][1]; - if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) { - yPos += box.height; - if ($$.isBarType(d) && $$.isSafari()) { - yPos -= 3; - } - else if (!$$.isBarType(d) && $$.isChrome()) { - yPos += 3; - } - } else { - yPos += $$.isBarType(d) ? -3 : -6; - } - } - // show labels regardless of the domain if value is null - if (d.value === null && !$$.config.axis_rotated) { - if (yPos < box.height) { - yPos = box.height; - } else if (yPos > this.height) { - yPos = this.height - 4; - } + yPos += $$.isBarType(d) ? -3 : -6; } - return yPos; -}; - -ChartInternal.prototype.initTitle = function () { - var $$ = this; - $$.title = $$.svg.append("text") - .text($$.config.title_text) - .attr("class", $$.CLASS.title); -}; -ChartInternal.prototype.redrawTitle = function () { - var $$ = this; - $$.title - .attr("x", $$.xForTitle.bind($$)) - .attr("y", $$.yForTitle.bind($$)); -}; -ChartInternal.prototype.xForTitle = function () { - var $$ = this, - config = $$.config, - position = config.title_position || 'left', - x; - if (position.indexOf('right') >= 0) { - x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right; - } else if (position.indexOf('center') >= 0) { - x = Math.max(($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2, 0); - } else { // left - x = config.title_padding.left; + } + // show labels regardless of the domain if value is null + if (d.value === null && !$$.config.axis_rotated) { + if (yPos < box.height) { + yPos = box.height; + } else if (yPos > this.height) { + yPos = this.height - 4; } - return x; + } + return yPos +}; + +ChartInternal.prototype.initTitle = function() { + var $$ = this; + $$.title = $$.svg + .append('text') + .text($$.config.title_text) + .attr('class', $$.CLASS.title); +}; +ChartInternal.prototype.redrawTitle = function() { + var $$ = this; + $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$)); +}; +ChartInternal.prototype.xForTitle = function() { + var $$ = this, + config = $$.config, + position = config.title_position || 'left', + x; + if (position.indexOf('right') >= 0) { + x = + $$.currentWidth - + $$.getTextRect( + $$.title.node().textContent, + $$.CLASS.title, + $$.title.node() + ).width - + config.title_padding.right; + } else if (position.indexOf('center') >= 0) { + x = Math.max( + ($$.currentWidth - + $$.getTextRect( + $$.title.node().textContent, + $$.CLASS.title, + $$.title.node() + ).width) / + 2, + 0 + ); + } else { + // left + x = config.title_padding.left; + } + return x }; -ChartInternal.prototype.yForTitle = function () { - var $$ = this; - return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height; +ChartInternal.prototype.yForTitle = function() { + var $$ = this; + return ( + $$.config.title_padding.top + + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()) + .height + ) }; -ChartInternal.prototype.getTitlePadding = function () { - var $$ = this; - return $$.yForTitle() + $$.config.title_padding.bottom; +ChartInternal.prototype.getTitlePadding = function() { + var $$ = this; + return $$.yForTitle() + $$.config.title_padding.bottom }; function powerOfTen(d) { - return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1; + return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1 } -ChartInternal.prototype.drawColorScale = function () { - var $$ = this, - d3 = $$.d3, - config = $$.config, - target = $$.data.targets[0], - barWidth, barHeight, axis, - points, legendAxis, axisScale, inverseScale, height; - - barWidth = !isNaN(config.stanford_scaleWidth) ? config.stanford_scaleWidth : 20; - barHeight = 5; - - if(barHeight < 0 || barWidth < 0) { - throw Error("Colorscale's barheight and barwidth must be greater than 0."); - } - - height = $$.height - config.stanford_padding.bottom - config.stanford_padding.top; - - points = d3.range(config.stanford_padding.bottom, height, barHeight); - - inverseScale = d3.scaleSequential(target.colors) - .domain([points[points.length - 1], points[0]]); - - if($$.colorScale) { - $$.colorScale.remove(); - } +ChartInternal.prototype.drawColorScale = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + target = $$.data.targets[0], + barWidth, + barHeight, + axis, + points, + legendAxis, + axisScale, + inverseScale, + height; + + barWidth = !isNaN(config.stanford_scaleWidth) + ? config.stanford_scaleWidth + : 20; + barHeight = 5; + + if (barHeight < 0 || barWidth < 0) { + throw Error("Colorscale's barheight and barwidth must be greater than 0.") + } - $$.colorScale = $$.svg.append("g") - .attr('width', 50) - .attr('height', height) - .attr('class', CLASS.colorScale); + height = + $$.height - config.stanford_padding.bottom - config.stanford_padding.top; - $$.colorScale.append('g') - .attr('transform', `translate(0, ${config.stanford_padding.top})`) - .selectAll('bars') - .data(points) - .enter() - .append('rect') - .attr('y', (d, i) => i * barHeight) - .attr('x', 0) - .attr('width', barWidth) - .attr('height', barHeight) - .attr('fill', function (d) { - return inverseScale(d); - }); + points = d3.range(config.stanford_padding.bottom, height, barHeight); - // Legend Axis - axisScale = d3.scaleLog() - .domain([target.minEpochs, target.maxEpochs]) - .range([ - points[0] + config.stanford_padding.top + points[points.length - 1] + barHeight - 1, - points[0] + config.stanford_padding.top - ]); + inverseScale = d3 + .scaleSequential(target.colors) + .domain([points[points.length - 1], points[0]]); - legendAxis = d3.axisRight(axisScale); + if ($$.colorScale) { + $$.colorScale.remove(); + } - if(config.stanford_scaleFormat === 'pow10') { - legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]); - } else if(isFunction(config.stanford_scaleFormat)) { - legendAxis.tickFormat(config.stanford_scaleFormat); - } else { - legendAxis.tickFormat(d3.format("d")); - } + $$.colorScale = $$.svg + .append('g') + .attr('width', 50) + .attr('height', height) + .attr('class', CLASS.colorScale); + + $$.colorScale + .append('g') + .attr('transform', `translate(0, ${config.stanford_padding.top})`) + .selectAll('bars') + .data(points) + .enter() + .append('rect') + .attr('y', (d, i) => i * barHeight) + .attr('x', 0) + .attr('width', barWidth) + .attr('height', barHeight) + .attr('fill', function(d) { + return inverseScale(d) + }); - if(isFunction(config.stanford_scaleValues)) { - legendAxis.tickValues(config.stanford_scaleValues(target.minEpochs, target.maxEpochs)); - } + // Legend Axis + axisScale = d3 + .scaleLog() + .domain([target.minEpochs, target.maxEpochs]) + .range([ + points[0] + + config.stanford_padding.top + + points[points.length - 1] + + barHeight - + 1, + points[0] + config.stanford_padding.top + ]); + + legendAxis = d3.axisRight(axisScale); + + if (config.stanford_scaleFormat === 'pow10') { + legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]); + } else if (isFunction(config.stanford_scaleFormat)) { + legendAxis.tickFormat(config.stanford_scaleFormat); + } else { + legendAxis.tickFormat(d3.format('d')); + } - // Draw Axis - axis = $$.colorScale.append("g") - .attr("class", "legend axis") - .attr("transform", `translate(${barWidth},0)`) - .call(legendAxis); + if (isFunction(config.stanford_scaleValues)) { + legendAxis.tickValues( + config.stanford_scaleValues(target.minEpochs, target.maxEpochs) + ); + } - if(config.stanford_scaleFormat === 'pow10') { - axis.selectAll(".tick text") - .text(null) - .filter(powerOfTen) - .text(10) - .append("tspan") - .attr("dy", "-.7em") // https://bl.ocks.org/mbostock/6738229 - .text(function(d) { - return Math.round(Math.log(d) / Math.LN10); - }); - } + // Draw Axis + axis = $$.colorScale + .append('g') + .attr('class', 'legend axis') + .attr('transform', `translate(${barWidth},0)`) + .call(legendAxis); + + if (config.stanford_scaleFormat === 'pow10') { + axis + .selectAll('.tick text') + .text(null) + .filter(powerOfTen) + .text(10) + .append('tspan') + .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229 + .text(function(d) { + return Math.round(Math.log(d) / Math.LN10) + }); + } - $$.colorScale.attr('transform', `translate(${$$.currentWidth - $$.xForColorScale()}, 0)`); + $$.colorScale.attr( + 'transform', + `translate(${$$.currentWidth - $$.xForColorScale()}, 0)` + ); }; -ChartInternal.prototype.xForColorScale = function () { - var $$ = this; +ChartInternal.prototype.xForColorScale = function() { + var $$ = this; - return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width; + return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width }; -ChartInternal.prototype.getColorScalePadding = function () { - var $$ = this; - return $$.xForColorScale() + $$.config.stanford_padding.left + 20; +ChartInternal.prototype.getColorScalePadding = function() { + var $$ = this; + return $$.xForColorScale() + $$.config.stanford_padding.left + 20 }; -ChartInternal.prototype.isStanfordGraphType = function () { - var $$ = this; +ChartInternal.prototype.isStanfordGraphType = function() { + var $$ = this; - return $$.config.data_type === 'stanford'; + return $$.config.data_type === 'stanford' }; -ChartInternal.prototype.initStanfordData = function () { - var $$ = this, - d3 = $$.d3, - config = $$.config, - target = $$.data.targets[0], - epochs, - maxEpochs, - minEpochs; +ChartInternal.prototype.initStanfordData = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + target = $$.data.targets[0], + epochs, + maxEpochs, + minEpochs; - // Make larger values appear on top - target.values.sort(compareEpochs); + // Make larger values appear on top + target.values.sort(compareEpochs); - // Get array of epochs - epochs = target.values.map(a => a.epochs); + // Get array of epochs + epochs = target.values.map(a => a.epochs); - minEpochs = !isNaN(config.stanford_scaleMin) ? config.stanford_scaleMin : d3.min(epochs); - maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs); + minEpochs = !isNaN(config.stanford_scaleMin) + ? config.stanford_scaleMin + : d3.min(epochs); + maxEpochs = !isNaN(config.stanford_scaleMax) + ? config.stanford_scaleMax + : d3.max(epochs); - if (minEpochs > maxEpochs) { - throw Error("Number of minEpochs has to be smaller than maxEpochs"); - } + if (minEpochs > maxEpochs) { + throw Error('Number of minEpochs has to be smaller than maxEpochs') + } - target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)); + target.colors = isFunction(config.stanford_colors) + ? config.stanford_colors + : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)); - target.colorscale = d3.scaleSequentialLog(target.colors) - .domain([minEpochs, maxEpochs]); + target.colorscale = d3 + .scaleSequentialLog(target.colors) + .domain([minEpochs, maxEpochs]); - target.minEpochs = minEpochs; - target.maxEpochs = maxEpochs; + target.minEpochs = minEpochs; + target.maxEpochs = maxEpochs; }; -ChartInternal.prototype.getStanfordPointColor = function (d) { - var $$ = this, - target = $$.data.targets[0]; +ChartInternal.prototype.getStanfordPointColor = function(d) { + var $$ = this, + target = $$.data.targets[0]; - return target.colorscale(d.epochs); + return target.colorscale(d.epochs) }; // http://jsfiddle.net/Xotic750/KtzLq/ -ChartInternal.prototype.getCentroid = function (points) { - var area = getRegionArea(points); - - var x = 0, - y = 0, - i, - j, - f, - point1, - point2; - - for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { - point1 = points[i]; - point2 = points[j]; - f = point1.x * point2.y - point2.x * point1.y; - x += (point1.x + point2.x) * f; - y += (point1.y + point2.y) * f; - } +ChartInternal.prototype.getCentroid = function(points) { + var area = getRegionArea(points); + + var x = 0, + y = 0, + i, + j, + f, + point1, + point2; + + for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { + point1 = points[i]; + point2 = points[j]; + f = point1.x * point2.y - point2.x * point1.y; + x += (point1.x + point2.x) * f; + y += (point1.y + point2.y) * f; + } - f = area * 6; + f = area * 6; - return { - x: x / f, - y: y / f - }; + return { + x: x / f, + y: y / f + } }; -ChartInternal.prototype.getStanfordTooltipTitle = function (d) { - var $$ = this, - labelX = $$.axis.getLabelText('x'), - labelY = $$.axis.getLabelText('y'); +ChartInternal.prototype.getStanfordTooltipTitle = function(d) { + var $$ = this, + labelX = $$.axis.getLabelText('x'), + labelY = $$.axis.getLabelText('y'); - return ` - ${labelX ? sanitise(labelX) : "x"}${d.x} - ${labelY ? sanitise(labelY) : "y"}${d.value} - `; + return ` + ${labelX ? sanitise(labelX) : 'x'}${ + d.x + } + ${labelY ? sanitise(labelY) : 'y'}${ + d.value + } + ` }; -ChartInternal.prototype.countEpochsInRegion = function (region) { - var $$ = this, - target = $$.data.targets[0], - total, count; +ChartInternal.prototype.countEpochsInRegion = function(region) { + var $$ = this, + target = $$.data.targets[0], + total, + count; - total = target.values.reduce((accumulator, currentValue) => accumulator + Number(currentValue.epochs), 0); + total = target.values.reduce( + (accumulator, currentValue) => accumulator + Number(currentValue.epochs), + 0 + ); - count = target.values.reduce((accumulator, currentValue) => { - if(pointInRegion(currentValue, region)) { - return accumulator + Number(currentValue.epochs); - } + count = target.values.reduce((accumulator, currentValue) => { + if (pointInRegion(currentValue, region)) { + return accumulator + Number(currentValue.epochs) + } - return accumulator; - }, 0); + return accumulator + }, 0); - return { - value: count, - percentage: count !== 0 ? (count / total * 100).toFixed(1) : 0 - }; + return { + value: count, + percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0 + } }; -var getRegionArea = function(points) { // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript - var area = 0, - i, - j, - point1, - point2; +var getRegionArea = function(points) { + // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript + var area = 0, + i, + j, + point1, + point2; - for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { - point1 = points[i]; - point2 = points[j]; - area += point1.x * point2.y; - area -= point1.y * point2.x; - } + for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { + point1 = points[i]; + point2 = points[j]; + area += point1.x * point2.y; + area -= point1.y * point2.x; + } - area /= 2; + area /= 2; - return area; + return area }; -var pointInRegion = function(point, region) { // thanks to: http://bl.ocks.org/bycoffe/5575904 - // ray-casting algorithm based on - // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html - let xi, yi, yj, xj, intersect, - x = point.x, - y = point.value, - inside = false; - - for (let i = 0, j = region.length - 1; i < region.length; j = i++) { +var pointInRegion = function(point, region) { + // thanks to: http://bl.ocks.org/bycoffe/5575904 + // ray-casting algorithm based on + // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + let xi, + yi, + yj, + xj, + intersect, + x = point.x, + y = point.value, + inside = false; - xi = region[i].x; - yi = region[i].y; + for (let i = 0, j = region.length - 1; i < region.length; j = i++) { + xi = region[i].x; + yi = region[i].y; - xj = region[j].x; - yj = region[j].y; + xj = region[j].x; + yj = region[j].y; - intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); + intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi; - if (intersect) { - inside = !inside; - } + if (intersect) { + inside = !inside; } + } - return inside; + return inside }; var compareEpochs = function(a, b) { - if (a.epochs < b.epochs) { - return -1; - } - if (a.epochs > b.epochs) { - return 1; - } - - return 0; -}; - -ChartInternal.prototype.initStanfordElements = function () { - var $$ = this; - - // Avoid blocking eventRect - $$.stanfordElements = $$.main.select('.' + CLASS.chart) - .append('g').attr('class', CLASS.stanfordElements); - - $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines); - $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts); - $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions); -}; - -ChartInternal.prototype.updateStanfordElements = function (duration) { - var $$ = this, main = $$.main, config = $$.config, - stanfordLine, stanfordLineEnter, stanfordRegion, stanfordRegionEnter, stanfordText, stanfordTextEnter, - xvCustom = $$.xvCustom.bind($$), yvCustom = $$.yvCustom.bind($$), countPointsInRegion = $$.countEpochsInRegion.bind($$); - - // Stanford-Lines - stanfordLine = main.select('.' + CLASS.stanfordLines) - .style('shape-rendering', 'geometricprecision') - .selectAll('.' + CLASS.stanfordLine) - .data(config.stanford_lines); - - // enter - stanfordLineEnter = stanfordLine.enter().append('g') - .attr("class", function (d) { return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordLineEnter.append('line') - .attr("x1", (d) => config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')) - .attr("x2", (d) => config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')) - .attr("y1", (d) => config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')) - .attr("y2", (d) => config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')) - .style("opacity", 0); - - // update - $$.stanfordLines = stanfordLineEnter.merge(stanfordLine); - $$.stanfordLines.select('line') - .transition().duration(duration) - .attr("x1", (d) => config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')) - .attr("x2", (d) => config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')) - .attr("y1", (d) => config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')) - .attr("y2", (d) => config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')) - .style("opacity", 1); - - // exit - stanfordLine.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); - - // Stanford-Text - stanfordText = main.select('.' + CLASS.stanfordTexts).selectAll('.' + CLASS.stanfordText) - .data(config.stanford_texts); - - // enter - stanfordTextEnter = stanfordText.enter().append('g') - .attr("class", function (d) { return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordTextEnter.append('text') - .attr("x", (d) => config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')) - .attr("y", (d) => config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')) - .style("opacity", 0); - - // update - $$.stanfordTexts = stanfordTextEnter.merge(stanfordText); - $$.stanfordTexts.select('text') - .transition().duration(duration) - .attr("x", (d) => config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')) - .attr("y", (d) => config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')) - .text(function (d) { return d.content; }) - .style("opacity", 1); - - // exit - stanfordText.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); + if (a.epochs < b.epochs) { + return -1 + } + if (a.epochs > b.epochs) { + return 1 + } - // Stanford-Regions - stanfordRegion = main.select('.' + CLASS.stanfordRegions).selectAll('.' + CLASS.stanfordRegion) - .data(config.stanford_regions); - - // enter - stanfordRegionEnter = stanfordRegion.enter().append('g') - .attr("class", function (d) { return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordRegionEnter.append('polygon') - .attr("points", (d) => { - return d.points.map(value => { - return [ - config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), - config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') - ].join(","); - }).join(" "); - }) - .style("opacity", 0); - stanfordRegionEnter.append('text') - .attr("x", (d) => $$.getCentroid(d.points).x) - .attr("y", (d) => $$.getCentroid(d.points).y) - .style("opacity", 0); - - // update - $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion); - $$.stanfordRegions.select('polygon') - .transition().duration(duration) - .attr("points", (d) => { - return d.points.map(value => { - return [ - config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), - config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') - ].join(","); - }).join(" "); + return 0 +}; + +ChartInternal.prototype.initStanfordElements = function() { + var $$ = this; + + // Avoid blocking eventRect + $$.stanfordElements = $$.main + .select('.' + CLASS.chart) + .append('g') + .attr('class', CLASS.stanfordElements); + + $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines); + $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts); + $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions); +}; + +ChartInternal.prototype.updateStanfordElements = function(duration) { + var $$ = this, + main = $$.main, + config = $$.config, + stanfordLine, + stanfordLineEnter, + stanfordRegion, + stanfordRegionEnter, + stanfordText, + stanfordTextEnter, + xvCustom = $$.xvCustom.bind($$), + yvCustom = $$.yvCustom.bind($$), + countPointsInRegion = $$.countEpochsInRegion.bind($$); + + // Stanford-Lines + stanfordLine = main + .select('.' + CLASS.stanfordLines) + .style('shape-rendering', 'geometricprecision') + .selectAll('.' + CLASS.stanfordLine) + .data(config.stanford_lines); + + // enter + stanfordLineEnter = stanfordLine + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '') + }); + stanfordLineEnter + .append('line') + .attr('x1', d => + config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1') + ) + .attr('x2', d => + config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2') + ) + .attr('y1', d => + config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1') + ) + .attr('y2', d => + config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2') + ) + .style('opacity', 0); + + // update + $$.stanfordLines = stanfordLineEnter.merge(stanfordLine); + $$.stanfordLines + .select('line') + .transition() + .duration(duration) + .attr('x1', d => + config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1') + ) + .attr('x2', d => + config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2') + ) + .attr('y1', d => + config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1') + ) + .attr('y2', d => + config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2') + ) + .style('opacity', 1); + + // exit + stanfordLine + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); + + // Stanford-Text + stanfordText = main + .select('.' + CLASS.stanfordTexts) + .selectAll('.' + CLASS.stanfordText) + .data(config.stanford_texts); + + // enter + stanfordTextEnter = stanfordText + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '') + }); + stanfordTextEnter + .append('text') + .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'))) + .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'))) + .style('opacity', 0); + + // update + $$.stanfordTexts = stanfordTextEnter.merge(stanfordText); + $$.stanfordTexts + .select('text') + .transition() + .duration(duration) + .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'))) + .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'))) + .text(function(d) { + return d.content + }) + .style('opacity', 1); + + // exit + stanfordText + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); + + // Stanford-Regions + stanfordRegion = main + .select('.' + CLASS.stanfordRegions) + .selectAll('.' + CLASS.stanfordRegion) + .data(config.stanford_regions); + + // enter + stanfordRegionEnter = stanfordRegion + .enter() + .append('g') + .attr('class', function(d) { + return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '') + }); + stanfordRegionEnter + .append('polygon') + .attr('points', d => { + return d.points + .map(value => { + return [ + config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), + config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') + ].join(',') }) - .style("opacity", (d) => { return d.opacity ? d.opacity : 0.2; }); - $$.stanfordRegions.select('text') - .transition().duration(duration) - .attr("x", (d) => config.axis_rotated ? yvCustom($$.getCentroid(d.points), 'y') : xvCustom($$.getCentroid(d.points), 'x')) - .attr("y", (d) => config.axis_rotated ? xvCustom($$.getCentroid(d.points), 'x') : yvCustom($$.getCentroid(d.points), 'y')) - .text(function (d) { - if(d.text) { - var value, percentage, temp; - - if($$.isStanfordGraphType()) { - temp = countPointsInRegion(d.points); - value = temp.value; - percentage = temp.percentage; - } - - return d.text(value, percentage); - } - - return ""; + .join(' ') + }) + .style('opacity', 0); + stanfordRegionEnter + .append('text') + .attr('x', d => $$.getCentroid(d.points).x) + .attr('y', d => $$.getCentroid(d.points).y) + .style('opacity', 0); + + // update + $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion); + $$.stanfordRegions + .select('polygon') + .transition() + .duration(duration) + .attr('points', d => { + return d.points + .map(value => { + return [ + config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), + config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y') + ].join(',') }) - .attr("text-anchor", "middle") - .attr("dominant-baseline", "middle") - .style("opacity", 1); - // exit - stanfordRegion.exit().transition().duration(duration) - .style("opacity", 0) - .remove(); + .join(' ') + }) + .style('opacity', d => { + return d.opacity ? d.opacity : 0.2 + }); + $$.stanfordRegions + .select('text') + .transition() + .duration(duration) + .attr('x', d => + config.axis_rotated + ? yvCustom($$.getCentroid(d.points), 'y') + : xvCustom($$.getCentroid(d.points), 'x') + ) + .attr('y', d => + config.axis_rotated + ? xvCustom($$.getCentroid(d.points), 'x') + : yvCustom($$.getCentroid(d.points), 'y') + ) + .text(function(d) { + if (d.text) { + var value, percentage, temp; + + if ($$.isStanfordGraphType()) { + temp = countPointsInRegion(d.points); + value = temp.value; + percentage = temp.percentage; + } + + return d.text(value, percentage) + } + + return '' + }) + .attr('text-anchor', 'middle') + .attr('dominant-baseline', 'middle') + .style('opacity', 1); + // exit + stanfordRegion + .exit() + .transition() + .duration(duration) + .style('opacity', 0) + .remove(); +}; + +ChartInternal.prototype.initTooltip = function() { + var $$ = this, + config = $$.config, + i; + $$.tooltip = $$.selectChart + .style('position', 'relative') + .append('div') + .attr('class', CLASS.tooltipContainer) + .style('position', 'absolute') + .style('pointer-events', 'none') + .style('display', 'none'); + // Show tooltip if needed + if (config.tooltip_init_show) { + if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { + config.tooltip_init_x = $$.parseDate(config.tooltip_init_x); + for (i = 0; i < $$.data.targets[0].values.length; i++) { + if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) { + break + } + } + config.tooltip_init_x = i; + } + $$.tooltip.html( + config.tooltip_contents.call( + $$, + $$.data.targets.map(function(d) { + return $$.addName(d.values[config.tooltip_init_x]) + }), + $$.axis.getXAxisTickFormat(), + $$.getYFormat($$.hasArcType()), + $$.color + ) + ); + $$.tooltip + .style('top', config.tooltip_init_position.top) + .style('left', config.tooltip_init_position.left) + .style('display', 'block'); + } }; +ChartInternal.prototype.getTooltipSortFunction = function() { + var $$ = this, + config = $$.config; -ChartInternal.prototype.initTooltip = function () { - var $$ = this, - config = $$.config, - i; - $$.tooltip = $$.selectChart - .style("position", "relative") - .append("div") - .attr('class', CLASS.tooltipContainer) - .style("position", "absolute") - .style("pointer-events", "none") - .style("display", "none"); - // Show tooltip if needed - if (config.tooltip_init_show) { - if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { - config.tooltip_init_x = $$.parseDate(config.tooltip_init_x); - for (i = 0; i < $$.data.targets[0].values.length; i++) { - if (($$.data.targets[0].values[i].x - config.tooltip_init_x) === 0) { - break; - } - } - config.tooltip_init_x = i; - } - $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) { - return $$.addName(d.values[config.tooltip_init_x]); - }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color)); - $$.tooltip.style("top", config.tooltip_init_position.top) - .style("left", config.tooltip_init_position.left) - .style("display", "block"); - } -}; -ChartInternal.prototype.getTooltipSortFunction = function () { - var $$ = this, - config = $$.config; + if (config.data_groups.length === 0 || config.tooltip_order !== undefined) { + // if data are not grouped or if an order is specified + // for the tooltip values we sort them by their values - if (config.data_groups.length === 0 || config.tooltip_order !== undefined) { - // if data are not grouped or if an order is specified - // for the tooltip values we sort them by their values + var order = config.tooltip_order; + if (order === undefined) { + order = config.data_order; + } - var order = config.tooltip_order; - if (order === undefined) { - order = config.data_order; - } + var valueOf = function(obj) { + return obj ? obj.value : null + }; - var valueOf = function (obj) { - return obj ? obj.value : null; + // if data are not grouped, we sort them by their value + if (isString(order) && order.toLowerCase() === 'asc') { + return function(a, b) { + return valueOf(a) - valueOf(b) + } + } else if (isString(order) && order.toLowerCase() === 'desc') { + return function(a, b) { + return valueOf(b) - valueOf(a) + } + } else if (isFunction(order)) { + // if the function is from data_order we need + // to wrap the returned function in order to format + // the sorted value to the expected format + + var sortFunction = order; + + if (config.tooltip_order === undefined) { + sortFunction = function(a, b) { + return order( + a + ? { + id: a.id, + values: [a] + } + : null, + b + ? { + id: b.id, + values: [b] + } + : null + ) }; + } - // if data are not grouped, we sort them by their value - if (isString(order) && order.toLowerCase() === 'asc') { - return function (a, b) { - return valueOf(a) - valueOf(b); - }; - } else if (isString(order) && order.toLowerCase() === 'desc') { - return function (a, b) { - return valueOf(b) - valueOf(a); - }; - } else if (isFunction(order)) { - - // if the function is from data_order we need - // to wrap the returned function in order to format - // the sorted value to the expected format - - var sortFunction = order; - - if (config.tooltip_order === undefined) { - sortFunction = function (a, b) { - return order(a ? { - id: a.id, - values: [a] - } : null, b ? { - id: b.id, - values: [b] - } : null); - }; - } - - return sortFunction; - - } else if (isArray(order)) { - return function (a, b) { - return order.indexOf(a.id) - order.indexOf(b.id); - }; - } - } else { - // if data are grouped, we follow the order of grouped targets - var ids = $$.orderTargets($$.data.targets).map(function (i) { - return i.id; - }); - - // if it was either asc or desc we need to invert the order - // returned by orderTargets - if ($$.isOrderAsc() || $$.isOrderDesc()) { - ids = ids.reverse(); - } - - return function (a, b) { - return ids.indexOf(a.id) - ids.indexOf(b.id); - }; + return sortFunction + } else if (isArray(order)) { + return function(a, b) { + return order.indexOf(a.id) - order.indexOf(b.id) + } } -}; -ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) { - var $$ = this, - config = $$.config, - titleFormat = config.tooltip_format_title || defaultTitleFormat, - nameFormat = config.tooltip_format_name || function (name) { - return name; - }, - text, i, title, value, name, bgcolor; + } else { + // if data are grouped, we follow the order of grouped targets + var ids = $$.orderTargets($$.data.targets).map(function(i) { + return i.id + }); - var valueFormat = config.tooltip_format_value; - if (!valueFormat) { - valueFormat = $$.isTargetNormalized(d.id) ? ((v, ratio) => `${(ratio * 100).toFixed(2)}%`) : defaultValueFormat; + // if it was either asc or desc we need to invert the order + // returned by orderTargets + if ($$.isOrderAsc() || $$.isOrderDesc()) { + ids = ids.reverse(); } - var tooltipSortFunction = this.getTooltipSortFunction(); - if (tooltipSortFunction) { - d.sort(tooltipSortFunction); + return function(a, b) { + return ids.indexOf(a.id) - ids.indexOf(b.id) } + } +}; +ChartInternal.prototype.getTooltipContent = function( + d, + defaultTitleFormat, + defaultValueFormat, + color +) { + var $$ = this, + config = $$.config, + titleFormat = config.tooltip_format_title || defaultTitleFormat, + nameFormat = + config.tooltip_format_name || + function(name) { + return name + }, + text, + i, + title, + value, + name, + bgcolor; + + var valueFormat = config.tooltip_format_value; + if (!valueFormat) { + valueFormat = $$.isTargetNormalized(d.id) + ? (v, ratio) => `${(ratio * 100).toFixed(2)}%` + : defaultValueFormat; + } - for (i = 0; i < d.length; i++) { - if (!(d[i] && (d[i].value || d[i].value === 0))) { - continue; - } - - if($$.isStanfordGraphType()) { - // Custom tooltip for stanford plots - if (!text) { - title = $$.getStanfordTooltipTitle(d[i]); - text = "" + title; - } - - bgcolor = $$.getStanfordPointColor(d[i]); - name = sanitise(config.data_epochs); // Epochs key name - value = d[i].epochs; - } else { - // Regular tooltip - if (!text) { - title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x); - text = "
" + (title || title === 0 ? "" : ""); - } - - value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)); - if (value !== undefined) { - // Skip elements when their name is set to null - if (d[i].name === null) { - continue; - } + var tooltipSortFunction = this.getTooltipSortFunction(); + if (tooltipSortFunction) { + d.sort(tooltipSortFunction); + } - name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index)); - bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id); - } - } + for (i = 0; i < d.length; i++) { + if (!(d[i] && (d[i].value || d[i].value === 0))) { + continue + } - if(value !== undefined) { - text += ""; - text += ""; - text += ""; - text += ""; - } + if ($$.isStanfordGraphType()) { + // Custom tooltip for stanford plots + if (!text) { + title = $$.getStanfordTooltipTitle(d[i]); + text = "
" + title + "
" + name + "" + value + "
" + title; + } + + bgcolor = $$.getStanfordPointColor(d[i]); + name = sanitise(config.data_epochs); // Epochs key name + value = d[i].epochs; + } else { + // Regular tooltip + if (!text) { + title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x); + text = + "
" + + (title || title === 0 + ? "' + : ''); + } + + value = sanitise( + valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d) + ); + if (value !== undefined) { + // Skip elements when their name is set to null + if (d[i].name === null) { + continue + } + + name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index)); + bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id); + } + } + + if (value !== undefined) { + text += + ""; + text += + "'; + text += "'; + text += ''; } - return text + "
" + title + '
" + + name + + '" + value + '
"; -}; -ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) { - var $$ = this, - config = $$.config, - d3 = $$.d3; - var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight; - var forArc = $$.hasArcType(), - mouse = d3.mouse(element); - // Determin tooltip position - if (forArc) { - tooltipLeft = (($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2) + mouse[0]; - tooltipTop = ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20; + } + return text + '' +}; +ChartInternal.prototype.tooltipPosition = function( + dataToShow, + tWidth, + tHeight, + element +) { + var $$ = this, + config = $$.config, + d3 = $$.d3; + var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight; + var forArc = $$.hasArcType(), + mouse = d3.mouse(element); + // Determin tooltip position + if (forArc) { + tooltipLeft = + ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0]; + tooltipTop = + ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20; + } else { + svgLeft = $$.getSvgLeft(true); + if (config.axis_rotated) { + tooltipLeft = svgLeft + mouse[0] + 100; + tooltipRight = tooltipLeft + tWidth; + chartRight = $$.currentWidth - $$.getCurrentPaddingRight(); + tooltipTop = $$.x(dataToShow[0].x) + 20; } else { - svgLeft = $$.getSvgLeft(true); - if (config.axis_rotated) { - tooltipLeft = svgLeft + mouse[0] + 100; - tooltipRight = tooltipLeft + tWidth; - chartRight = $$.currentWidth - $$.getCurrentPaddingRight(); - tooltipTop = $$.x(dataToShow[0].x) + 20; - } else { - tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20; - tooltipRight = tooltipLeft + tWidth; - chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight(); - tooltipTop = mouse[1] + 15; - } - - if (tooltipRight > chartRight) { - // 20 is needed for Firefox to keep tooltip width - tooltipLeft -= tooltipRight - chartRight + 20; - } - if (tooltipTop + tHeight > $$.currentHeight) { - tooltipTop -= tHeight + 30; - } + tooltipLeft = + svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20; + tooltipRight = tooltipLeft + tWidth; + chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight(); + tooltipTop = mouse[1] + 15; } - if (tooltipTop < 0) { - tooltipTop = 0; + + if (tooltipRight > chartRight) { + // 20 is needed for Firefox to keep tooltip width + tooltipLeft -= tooltipRight - chartRight + 20; } - return { - top: tooltipTop, - left: tooltipLeft - }; -}; -ChartInternal.prototype.showTooltip = function (selectedData, element) { - var $$ = this, - config = $$.config; - var tWidth, tHeight, position; - var forArc = $$.hasArcType(), - dataToShow = selectedData.filter(function (d) { - return d && isValue(d.value); - }), - positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition; - if (dataToShow.length === 0 || !config.tooltip_show) { - return; + if (tooltipTop + tHeight > $$.currentHeight) { + tooltipTop -= tHeight + 30; } - $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); - - // Get tooltip dimensions - tWidth = $$.tooltip.property('offsetWidth'); - tHeight = $$.tooltip.property('offsetHeight'); - - position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); - // Set tooltip - $$.tooltip - .style("top", position.top + "px") - .style("left", position.left + 'px'); + } + if (tooltipTop < 0) { + tooltipTop = 0; + } + return { + top: tooltipTop, + left: tooltipLeft + } }; -ChartInternal.prototype.hideTooltip = function () { - this.tooltip.style("display", "none"); +ChartInternal.prototype.showTooltip = function(selectedData, element) { + var $$ = this, + config = $$.config; + var tWidth, tHeight, position; + var forArc = $$.hasArcType(), + dataToShow = selectedData.filter(function(d) { + return d && isValue(d.value) + }), + positionFunction = + config.tooltip_position || ChartInternal.prototype.tooltipPosition; + if (dataToShow.length === 0 || !config.tooltip_show) { + return + } + $$.tooltip + .html( + config.tooltip_contents.call( + $$, + selectedData, + $$.axis.getXAxisTickFormat(), + $$.getYFormat(forArc), + $$.color + ) + ) + .style('display', 'block'); + + // Get tooltip dimensions + tWidth = $$.tooltip.property('offsetWidth'); + tHeight = $$.tooltip.property('offsetHeight'); + + position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); + // Set tooltip + $$.tooltip + .style('top', position.top + 'px') + .style('left', position.left + 'px'); +}; +ChartInternal.prototype.hideTooltip = function() { + this.tooltip.style('display', 'none'); +}; + +ChartInternal.prototype.setTargetType = function(targetIds, type) { + var $$ = this, + config = $$.config; + $$.mapToTargetIds(targetIds).forEach(function(id) { + $$.withoutFadeIn[id] = type === config.data_types[id]; + config.data_types[id] = type; + }); + if (!targetIds) { + config.data_type = type; + } }; - -ChartInternal.prototype.setTargetType = function (targetIds, type) { - var $$ = this, config = $$.config; - $$.mapToTargetIds(targetIds).forEach(function (id) { - $$.withoutFadeIn[id] = (type === config.data_types[id]); - config.data_types[id] = type; +ChartInternal.prototype.hasType = function(type, targets) { + var $$ = this, + types = $$.config.data_types, + has = false; + targets = targets || $$.data.targets; + if (targets && targets.length) { + targets.forEach(function(target) { + var t = types[target.id]; + if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) { + has = true; + } }); - if (!targetIds) { - config.data_type = type; - } -}; -ChartInternal.prototype.hasType = function (type, targets) { - var $$ = this, types = $$.config.data_types, has = false; - targets = targets || $$.data.targets; - if (targets && targets.length) { - targets.forEach(function (target) { - var t = types[target.id]; - if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) { - has = true; - } - }); - } else if (Object.keys(types).length) { - Object.keys(types).forEach(function (id) { - if (types[id] === type) { has = true; } - }); - } else { - has = $$.config.data_type === type; - } - return has; -}; -ChartInternal.prototype.hasArcType = function (targets) { - return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets); -}; -ChartInternal.prototype.isLineType = function (d) { - var config = this.config, id = isString(d) ? d : d.id; - return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isStepType = function (d) { - var id = isString(d) ? d : d.id; - return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isSplineType = function (d) { - var id = isString(d) ? d : d.id; - return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isAreaType = function (d) { - var id = isString(d) ? d : d.id; - return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0; -}; -ChartInternal.prototype.isBarType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'bar'; -}; -ChartInternal.prototype.isScatterType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'scatter'; -}; -ChartInternal.prototype.isStanfordType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'stanford'; -}; -ChartInternal.prototype.isPieType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'pie'; -}; -ChartInternal.prototype.isGaugeType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'gauge'; -}; -ChartInternal.prototype.isDonutType = function (d) { - var id = isString(d) ? d : d.id; - return this.config.data_types[id] === 'donut'; -}; -ChartInternal.prototype.isArcType = function (d) { - return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d); -}; -ChartInternal.prototype.lineData = function (d) { - return this.isLineType(d) ? [d] : []; -}; -ChartInternal.prototype.arcData = function (d) { - return this.isArcType(d.data) ? [d] : []; + } else if (Object.keys(types).length) { + Object.keys(types).forEach(function(id) { + if (types[id] === type) { + has = true; + } + }); + } else { + has = $$.config.data_type === type; + } + return has +}; +ChartInternal.prototype.hasArcType = function(targets) { + return ( + this.hasType('pie', targets) || + this.hasType('donut', targets) || + this.hasType('gauge', targets) + ) +}; +ChartInternal.prototype.isLineType = function(d) { + var config = this.config, + id = isString(d) ? d : d.id; + return ( + !config.data_types[id] || + ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf( + config.data_types[id] + ) >= 0 + ) +}; +ChartInternal.prototype.isStepType = function(d) { + var id = isString(d) ? d : d.id; + return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0 +}; +ChartInternal.prototype.isSplineType = function(d) { + var id = isString(d) ? d : d.id; + return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0 +}; +ChartInternal.prototype.isAreaType = function(d) { + var id = isString(d) ? d : d.id; + return ( + ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= + 0 + ) +}; +ChartInternal.prototype.isBarType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'bar' +}; +ChartInternal.prototype.isScatterType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'scatter' +}; +ChartInternal.prototype.isStanfordType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'stanford' +}; +ChartInternal.prototype.isPieType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'pie' +}; +ChartInternal.prototype.isGaugeType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'gauge' +}; +ChartInternal.prototype.isDonutType = function(d) { + var id = isString(d) ? d : d.id; + return this.config.data_types[id] === 'donut' +}; +ChartInternal.prototype.isArcType = function(d) { + return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d) +}; +ChartInternal.prototype.lineData = function(d) { + return this.isLineType(d) ? [d] : [] +}; +ChartInternal.prototype.arcData = function(d) { + return this.isArcType(d.data) ? [d] : [] }; /* not used function scatterData(d) { return isScatterType(d) ? d.values : []; } */ -ChartInternal.prototype.barData = function (d) { - return this.isBarType(d) ? d.values : []; -}; -ChartInternal.prototype.lineOrScatterOrStanfordData = function (d) { - return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d) ? d.values : []; -}; -ChartInternal.prototype.barOrLineData = function (d) { - return this.isBarType(d) || this.isLineType(d) ? d.values : []; -}; - -ChartInternal.prototype.isSafari = function () { - var ua = window.navigator.userAgent; - return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0; -}; -ChartInternal.prototype.isChrome = function () { - var ua = window.navigator.userAgent; - return ua.indexOf('Chrome') >= 0; -}; - -ChartInternal.prototype.initZoom = function () { - var $$ = this, d3 = $$.d3, config = $$.config, startEvent; - - $$.zoom = d3.zoom() - .on("start", function () { - if (config.zoom_type !== 'scroll') { - return; - } - - var e = d3.event.sourceEvent; - if (e && e.type === "brush") { return; } - startEvent = e; - config.zoom_onzoomstart.call($$.api, e); - }) - .on("zoom", function () { - if (config.zoom_type !== 'scroll') { - return; - } - - var e = d3.event.sourceEvent; - if (e && e.type === "brush") { return; } - - $$.redrawForZoom(); - - config.zoom_onzoom.call($$.api, $$.x.orgDomain()); - }) - .on('end', function () { - if (config.zoom_type !== 'scroll') { - return; - } - - var e = d3.event.sourceEvent; - if (e && e.type === "brush") { return; } - // if click, do nothing. otherwise, click interaction will be canceled. - if (e && startEvent.clientX === e.clientX && startEvent.clientY === e.clientY) { - return; - } - config.zoom_onzoomend.call($$.api, $$.x.orgDomain()); - }); - - $$.zoom.updateDomain = function () { - if (d3.event && d3.event.transform) { - $$.x.domain(d3.event.transform.rescaleX($$.subX).domain()); - } - return this; - }; - $$.zoom.updateExtent = function () { - this.scaleExtent([1, Infinity]) - .translateExtent([[0, 0], [$$.width, $$.height]]) - .extent([[0, 0], [$$.width, $$.height]]); - return this; - }; - $$.zoom.update = function () { - return this.updateExtent().updateDomain(); - }; - - return $$.zoom.updateExtent(); -}; -ChartInternal.prototype.zoomTransform = function (range) { - var $$ = this, s = [$$.x(range[0]), $$.x(range[1])]; - return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0); -}; - -ChartInternal.prototype.initDragZoom = function () { - const $$ = this; - const d3 = $$.d3; - const config = $$.config; - const context = $$.context = $$.svg; - const brushXPos = $$.margin.left + 20.5; - const brushYPos = $$.margin.top + 0.5; - - if (!(config.zoom_type === 'drag' && config.zoom_enabled)) { - return; - } - - const getZoomedDomain = selection => selection && selection.map(x => $$.x.invert(x)); - - const brush = $$.dragZoomBrush = d3.brushX() - .on("start", () => { - $$.api.unzoom(); - - $$.svg - .select("." + CLASS.dragZoom) - .classed("disabled", false); - - config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); - }) - .on("brush", () => { - config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection)); - }) - .on("end", () => { - if (d3.event.selection == null) { - return; - } - - const zoomedDomain = getZoomedDomain(d3.event.selection); - - if (!config.zoom_disableDefaultBehavior) { - $$.api.zoom(zoomedDomain); - } - - $$.svg - .select("." + CLASS.dragZoom) - .classed("disabled", true); - - config.zoom_onzoomend.call($$.api, zoomedDomain); - }); +ChartInternal.prototype.barData = function(d) { + return this.isBarType(d) ? d.values : [] +}; +ChartInternal.prototype.lineOrScatterOrStanfordData = function(d) { + return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d) + ? d.values + : [] +}; +ChartInternal.prototype.barOrLineData = function(d) { + return this.isBarType(d) || this.isLineType(d) ? d.values : [] +}; + +ChartInternal.prototype.isSafari = function() { + var ua = window.navigator.userAgent; + return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0 +}; +ChartInternal.prototype.isChrome = function() { + var ua = window.navigator.userAgent; + return ua.indexOf('Chrome') >= 0 +}; + +ChartInternal.prototype.initZoom = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + startEvent; + + $$.zoom = d3 + .zoom() + .on('start', function() { + if (config.zoom_type !== 'scroll') { + return + } + + var e = d3.event.sourceEvent; + if (e && e.type === 'brush') { + return + } + startEvent = e; + config.zoom_onzoomstart.call($$.api, e); + }) + .on('zoom', function() { + if (config.zoom_type !== 'scroll') { + return + } + + var e = d3.event.sourceEvent; + if (e && e.type === 'brush') { + return + } + + $$.redrawForZoom(); + + config.zoom_onzoom.call($$.api, $$.x.orgDomain()); + }) + .on('end', function() { + if (config.zoom_type !== 'scroll') { + return + } + + var e = d3.event.sourceEvent; + if (e && e.type === 'brush') { + return + } + // if click, do nothing. otherwise, click interaction will be canceled. + if ( + e && + startEvent.clientX === e.clientX && + startEvent.clientY === e.clientY + ) { + return + } + config.zoom_onzoomend.call($$.api, $$.x.orgDomain()); + }); - context - .append("g") - .classed(CLASS.dragZoom, true) - .attr("clip-path", $$.clipPath) - .attr("transform", "translate(" + brushXPos + "," + brushYPos + ")") - .call(brush); -}; + $$.zoom.updateDomain = function() { + if (d3.event && d3.event.transform) { + $$.x.domain(d3.event.transform.rescaleX($$.subX).domain()); + } + return this + }; + $$.zoom.updateExtent = function() { + this.scaleExtent([1, Infinity]) + .translateExtent([ + [0, 0], + [$$.width, $$.height] + ]) + .extent([ + [0, 0], + [$$.width, $$.height] + ]); + return this + }; + $$.zoom.update = function() { + return this.updateExtent().updateDomain() + }; + + return $$.zoom.updateExtent() +}; +ChartInternal.prototype.zoomTransform = function(range) { + var $$ = this, + s = [$$.x(range[0]), $$.x(range[1])]; + return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0) +}; + +ChartInternal.prototype.initDragZoom = function() { + const $$ = this; + const d3 = $$.d3; + const config = $$.config; + const context = ($$.context = $$.svg); + const brushXPos = $$.margin.left + 20.5; + const brushYPos = $$.margin.top + 0.5; + + if (!(config.zoom_type === 'drag' && config.zoom_enabled)) { + return + } -ChartInternal.prototype.getZoomDomain = function () { - var $$ = this, config = $$.config, d3 = $$.d3, - min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), - max = d3.max([$$.orgXDomain[1], config.zoom_x_max]); - return [min, max]; -}; -ChartInternal.prototype.redrawForZoom = function () { - var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x; - if (!config.zoom_enabled) { - return; - } - if ($$.filterTargetsToShow($$.data.targets).length === 0) { - return; - } + const getZoomedDomain = selection => + selection && selection.map(x => $$.x.invert(x)); + + const brush = ($$.dragZoomBrush = d3 + .brushX() + .on('start', () => { + $$.api.unzoom(); + + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false); + + config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); + }) + .on('brush', () => { + config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection)); + }) + .on('end', () => { + if (d3.event.selection == null) { + return + } + + const zoomedDomain = getZoomedDomain(d3.event.selection); + + if (!config.zoom_disableDefaultBehavior) { + $$.api.zoom(zoomedDomain); + } + + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true); + + config.zoom_onzoomend.call($$.api, zoomedDomain); + })); + + context + .append('g') + .classed(CLASS.dragZoom, true) + .attr('clip-path', $$.clipPath) + .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')') + .call(brush); +}; + +ChartInternal.prototype.getZoomDomain = function() { + var $$ = this, + config = $$.config, + d3 = $$.d3, + min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), + max = d3.max([$$.orgXDomain[1], config.zoom_x_max]); + return [min, max] +}; +ChartInternal.prototype.redrawForZoom = function() { + var $$ = this, + d3 = $$.d3, + config = $$.config, + zoom = $$.zoom, + x = $$.x; + if (!config.zoom_enabled) { + return + } + if ($$.filterTargetsToShow($$.data.targets).length === 0) { + return + } - zoom.update(); + zoom.update(); - if (config.zoom_disableDefaultBehavior) { - return; - } + if (config.zoom_disableDefaultBehavior) { + return + } - if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) { - x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]); - } + if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) { + x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]); + } - $$.redraw({ - withTransition: false, - withY: config.zoom_rescale, - withSubchart: false, - withEventRect: false, - withDimension: false - }); + $$.redraw({ + withTransition: false, + withY: config.zoom_rescale, + withSubchart: false, + withEventRect: false, + withDimension: false + }); - if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') { - $$.cancelClick = true; - } + if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') { + $$.cancelClick = true; + } }; export default c3; diff --git a/docs/js/c3.js b/docs/js/c3.js index 5684f9d9c..d536ea849 100644 --- a/docs/js/c3.js +++ b/docs/js/c3.js @@ -1,4 +1,4 @@ -/* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */ +/* @license C3.js v0.7.16 | (c) C3 Team and other contributors | http://c3js.org/ */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : @@ -6,6 +6,8 @@ }(this, (function () { 'use strict'; function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; @@ -41,23 +43,36 @@ } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ChartInternal(api) { @@ -66,7 +81,7 @@ // TODO: Maybe we should check that the modification by rollup-plugin-modify // is valid during unit tests. - $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined; + $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require('d3') : undefined; $$.api = api; $$.config = $$.getDefaultConfig(); $$.data = {}; @@ -85,7 +100,8 @@ this.internal.loadConfig(config); this.internal.beforeInit(config); this.internal.init(); - this.internal.afterInit(config); // bind "this" to nested API + this.internal.afterInit(config) // bind "this" to nested API + ; (function bindThis(fn, target, argThis) { Object.keys(fn).forEach(function (key) { @@ -249,7 +265,7 @@ internal.d3 = component.d3; internal.scale = internal.d3.scaleLinear(); internal.range; - internal.orient = "bottom"; + internal.orient = 'bottom'; internal.innerTickSize = 6; internal.outerTickSize = this.params.withOuterTick ? 6 : 0; internal.tickPadding = 3; @@ -266,14 +282,14 @@ } AxisInternal.prototype.axisX = function (selection, x, tickOffset) { - selection.attr("transform", function (d) { - return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)"; + selection.attr('transform', function (d) { + return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)'; }); }; AxisInternal.prototype.axisY = function (selection, y) { - selection.attr("transform", function (d) { - return "translate(0," + Math.ceil(y(d)) + ")"; + selection.attr('transform', function (d) { + return 'translate(0,' + Math.ceil(y(d)) + ')'; }); }; @@ -389,7 +405,7 @@ textWidth, splitted = []; - if (Object.prototype.toString.call(tickText) === "[object Array]") { + if (Object.prototype.toString.call(tickText) === '[object Array]') { return tickText; } @@ -416,7 +432,7 @@ return splitted.concat(text); } - return split(splitted, tickText + ""); + return split(splitted, tickText + ''); }; AxisInternal.prototype.ellipsify = function (splitted, max) { @@ -460,13 +476,13 @@ AxisInternal.prototype.textTransform = function () { var internal = this, rotate = internal.tickTextRotate; - return rotate ? "rotate(" + rotate + ")" : ""; + return rotate ? 'rotate(' + rotate + ')' : ''; }; AxisInternal.prototype.textTextAnchor = function () { var internal = this, rotate = internal.tickTextRotate; - return rotate ? rotate > 0 ? "start" : "end" : "middle"; + return rotate ? rotate > 0 ? 'start' : 'end' : 'middle'; }; AxisInternal.prototype.tspanDx = function () { @@ -483,7 +499,7 @@ if (internal.isVertical()) { dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3); } else { - dy = ".71em"; + dy = '.71em'; } } @@ -502,8 +518,8 @@ var scale0 = this.__chart__ || internal.scale, scale1 = this.__chart__ = internal.copyScale(); var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1), - ticks = g.selectAll(".tick").data(ticksValues, scale1), - tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), + ticks = g.selectAll('.tick').data(ticksValues, scale1), + tickEnter = ticks.enter().insert('g', '.domain').attr('class', 'tick').style('opacity', 1e-6), // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks. tickExit = ticks.exit().remove(), tickUpdate = ticks.merge(tickEnter), @@ -522,8 +538,8 @@ internal.updateRange(); internal.updateTickLength(); internal.updateTickTextCharSize(g.select('.tick')); - var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")), - textUpdate = tickUpdate.select("text").merge(tickEnter.append("text")); + var lineUpdate = tickUpdate.select('line').merge(tickEnter.append('line')), + textUpdate = tickUpdate.select('text').merge(tickEnter.append('text')); var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) { return internal.tspanData(d, i, scale1); }), @@ -532,76 +548,76 @@ return d.splitted; }); tspans.exit().remove(); - var path = g.selectAll(".domain").data([0]), - pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); // TODO: each attr should be one function and change its behavior by internal.orient, probably + var path = g.selectAll('.domain').data([0]), + pathUpdate = path.enter().append('path').merge(path).attr('class', 'domain'); // TODO: each attr should be one function and change its behavior by internal.orient, probably switch (internal.orient) { - case "bottom": + case 'bottom': { tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) { + lineUpdate.attr('x1', tickX).attr('x2', tickX).attr('y2', function (d, i) { return internal.lineY2(d, i); }); - textUpdate.attr("x", 0).attr("y", function (d, i) { + textUpdate.attr('x', 0).attr('y', function (d, i) { return internal.textY(d, i); - }).attr("transform", function (d, i) { + }).attr('transform', function (d, i) { return internal.textTransform(d, i); - }).style("text-anchor", function (d, i) { + }).style('text-anchor', function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0).attr("dy", function (d, i) { + tspanUpdate.attr('x', 0).attr('dy', function (d, i) { return internal.tspanDy(d, i); }).attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize); + pathUpdate.attr('d', 'M' + internal.range[0] + ',' + internal.outerTickSize + 'V0H' + internal.range[1] + 'V' + internal.outerTickSize); break; } - case "top": + case 'top': { // TODO: rotated tick text tickTransform = internal.axisX; - lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) { + lineUpdate.attr('x1', tickX).attr('x2', tickX).attr('y2', function (d, i) { return -1 * internal.lineY2(d, i); }); - textUpdate.attr("x", 0).attr("y", function (d, i) { + textUpdate.attr('x', 0).attr('y', function (d, i) { return -1 * internal.textY(d, i) - (params.isCategory ? 2 : internal.tickLength - 2); - }).attr("transform", function (d, i) { + }).attr('transform', function (d, i) { return internal.textTransform(d, i); - }).style("text-anchor", function (d, i) { + }).style('text-anchor', function (d, i) { return internal.textTextAnchor(d, i); }); - tspanUpdate.attr('x', 0).attr("dy", function (d, i) { + tspanUpdate.attr('x', 0).attr('dy', function (d, i) { return internal.tspanDy(d, i); }).attr('dx', function (d, i) { return internal.tspanDx(d, i); }); - pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize); + pathUpdate.attr('d', 'M' + internal.range[0] + ',' + -internal.outerTickSize + 'V0H' + internal.range[1] + 'V' + -internal.outerTickSize); break; } - case "left": + case 'left': { tickTransform = internal.axisY; - lineUpdate.attr("x2", -internal.innerTickSize).attr("y1", tickY).attr("y2", tickY); - textUpdate.attr("x", -internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "end"); - tspanUpdate.attr('x', -internal.tickLength).attr("dy", function (d, i) { + lineUpdate.attr('x2', -internal.innerTickSize).attr('y1', tickY).attr('y2', tickY); + textUpdate.attr('x', -internal.tickLength).attr('y', internal.tickOffset).style('text-anchor', 'end'); + tspanUpdate.attr('x', -internal.tickLength).attr('dy', function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize); + pathUpdate.attr('d', 'M' + -internal.outerTickSize + ',' + internal.range[0] + 'H0V' + internal.range[1] + 'H' + -internal.outerTickSize); break; } - case "right": + case 'right': { tickTransform = internal.axisY; - lineUpdate.attr("x2", internal.innerTickSize).attr("y1", tickY).attr("y2", tickY); - textUpdate.attr("x", internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "start"); - tspanUpdate.attr('x', internal.tickLength).attr("dy", function (d, i) { + lineUpdate.attr('x2', internal.innerTickSize).attr('y1', tickY).attr('y2', tickY); + textUpdate.attr('x', internal.tickLength).attr('y', internal.tickOffset).style('text-anchor', 'start'); + tspanUpdate.attr('x', internal.tickLength).attr('dy', function (d, i) { return internal.tspanDy(d, i); }); - pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize); + pathUpdate.attr('d', 'M' + internal.outerTickSize + ',' + internal.range[0] + 'H0V' + internal.range[1] + 'H' + internal.outerTickSize); break; } } @@ -644,7 +660,7 @@ right: 1, bottom: 1, left: 1 - } ? x + "" : "bottom"; + } ? x + '' : 'bottom'; return axis; }; @@ -820,13 +836,13 @@ var $$ = this.owner, config = $$.config, main = $$.main; - $$.axes.x = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisX).attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis).attr("transform", $$.getTranslate('x')).style("visibility", config.axis_x_show ? 'visible' : 'hidden'); - $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this)); - $$.axes.y = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY).attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis).attr("transform", $$.getTranslate('y')).style("visibility", config.axis_y_show ? 'visible' : 'hidden'); - $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this)); - $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2) // clip-path? - .attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden'); - $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this)); + $$.axes.x = main.append('g').attr('class', CLASS.axis + ' ' + CLASS.axisX).attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis).attr('transform', $$.getTranslate('x')).style('visibility', config.axis_x_show ? 'visible' : 'hidden'); + $$.axes.x.append('text').attr('class', CLASS.axisXLabel).attr('transform', config.axis_rotated ? 'rotate(-90)' : '').style('text-anchor', this.textAnchorForXAxisLabel.bind(this)); + $$.axes.y = main.append('g').attr('class', CLASS.axis + ' ' + CLASS.axisY).attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis).attr('transform', $$.getTranslate('y')).style('visibility', config.axis_y_show ? 'visible' : 'hidden'); + $$.axes.y.append('text').attr('class', CLASS.axisYLabel).attr('transform', config.axis_rotated ? '' : 'rotate(-90)').style('text-anchor', this.textAnchorForYAxisLabel.bind(this)); + $$.axes.y2 = main.append('g').attr('class', CLASS.axis + ' ' + CLASS.axisY2) // clip-path? + .attr('transform', $$.getTranslate('y2')).style('visibility', config.axis_y2_show ? 'visible' : 'hidden'); + $$.axes.y2.append('text').attr('class', CLASS.axisY2Label).attr('transform', config.axis_rotated ? '' : 'rotate(-90)').style('text-anchor', this.textAnchorForY2AxisLabel.bind(this)); }; Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) { @@ -843,7 +859,7 @@ }, axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient); - if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") { + if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') { tickValues = tickValues.map(function (v) { return $$.parseDate(v); }); @@ -931,7 +947,7 @@ format = config.axis_x_tick_format; } else if ($$.isTimeSeries()) { format = function format(date) { - return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ""; + return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ''; }; } } @@ -1051,9 +1067,9 @@ Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) { if (forHorizontal) { - return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0"; + return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0'; } else { - return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0"; + return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0'; } }; @@ -1095,9 +1111,9 @@ position = this.getXAxisLabelPosition(); if (config.axis_rotated) { - return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); + return position.isInner ? '1.2em' : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x')); } else { - return position.isInner ? "-0.5em" : $$.getHorizontalAxisHeight('x') - 10; + return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10; } }; @@ -1106,9 +1122,9 @@ position = this.getYAxisLabelPosition(); if ($$.config.axis_rotated) { - return position.isInner ? "-0.5em" : "3em"; + return position.isInner ? '-0.5em' : '3em'; } else { - return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10); + return position.isInner ? '1.2em' : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10); } }; @@ -1117,9 +1133,9 @@ position = this.getY2AxisLabelPosition(); if ($$.config.axis_rotated) { - return position.isInner ? "1.2em" : "-2.2em"; + return position.isInner ? '1.2em' : '-2.2em'; } else { - return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15); + return position.isInner ? '-0.5em' : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15); } }; @@ -1167,7 +1183,7 @@ } dummy = $$.d3.select('body').append('div').classed('c3', true); - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () { + svg = dummy.append('svg').style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () { $$.d3.select(this).selectAll('text').each(function () { var box = getBBox(this); @@ -1188,9 +1204,9 @@ var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label); - (withTransition ? axisXLabel.transition() : axisXLabel).attr("x", this.xForXAxisLabel.bind(this)).attr("dx", this.dxForXAxisLabel.bind(this)).attr("dy", this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this)); - (withTransition ? axisYLabel.transition() : axisYLabel).attr("x", this.xForYAxisLabel.bind(this)).attr("dx", this.dxForYAxisLabel.bind(this)).attr("dy", this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this)); - (withTransition ? axisY2Label.transition() : axisY2Label).attr("x", this.xForY2AxisLabel.bind(this)).attr("dx", this.dxForY2AxisLabel.bind(this)).attr("dy", this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this)); + (withTransition ? axisXLabel.transition() : axisXLabel).attr('x', this.xForXAxisLabel.bind(this)).attr('dx', this.dxForXAxisLabel.bind(this)).attr('dy', this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this)); + (withTransition ? axisYLabel.transition() : axisYLabel).attr('x', this.xForYAxisLabel.bind(this)).attr('dx', this.dxForYAxisLabel.bind(this)).attr('dy', this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this)); + (withTransition ? axisY2Label.transition() : axisY2Label).attr('x', this.xForY2AxisLabel.bind(this)).attr('dx', this.dxForY2AxisLabel.bind(this)).attr('dy', this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this)); }; Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) { @@ -1271,14 +1287,14 @@ Axis.prototype.redraw = function redraw(duration, isHidden) { var $$ = this.owner, transition = duration ? $$.d3.transition().duration(duration) : null; - $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition); - $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition); - $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition); - $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition); + $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition); + $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition); + $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition); + $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition); }; var c3 = { - version: "0.7.15", + version: '0.7.16', chart: { fn: Chart.prototype, internal: { @@ -1325,7 +1341,7 @@ d3 = $$.d3, config = $$.config; // MEMO: clipId needs to be unique because it conflicts when multiple charts exist - $$.clipId = "c3-" + +new Date() + '-clip'; + $$.clipId = 'c3-' + new Date().valueOf() + '-clip'; $$.clipIdForXAxis = $$.clipId + '-xaxis'; $$.clipIdForYAxis = $$.clipId + '-yaxis'; $$.clipIdForGrid = $$.clipId + '-grid'; @@ -1348,44 +1364,44 @@ $$.defaultAxisTimeFormat = function (date) { if (date.getMilliseconds()) { - return d3.timeFormat(".%L")(date); + return d3.timeFormat('.%L')(date); } if (date.getSeconds()) { - return d3.timeFormat(":%S")(date); + return d3.timeFormat(':%S')(date); } if (date.getMinutes()) { - return d3.timeFormat("%I:%M")(date); + return d3.timeFormat('%I:%M')(date); } if (date.getHours()) { - return d3.timeFormat("%I %p")(date); + return d3.timeFormat('%I %p')(date); } if (date.getDay() && date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); + return d3.timeFormat('%-m/%-d')(date); } if (date.getDate() !== 1) { - return d3.timeFormat("%-m/%-d")(date); + return d3.timeFormat('%-m/%-d')(date); } if (date.getMonth()) { - return d3.timeFormat("%-m/%-d")(date); + return d3.timeFormat('%-m/%-d')(date); } - return d3.timeFormat("%Y/%-m/%-d")(date); + return d3.timeFormat('%Y/%-m/%-d')(date); }; $$.hiddenTargetIds = []; $$.hiddenLegendIds = []; $$.focusedTargetIds = []; $$.defocusedTargetIds = []; - $$.xOrient = config.axis_rotated ? config.axis_x_inner ? "right" : "left" : config.axis_x_inner ? "top" : "bottom"; - $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left"; - $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right"; - $$.subXOrient = config.axis_rotated ? "left" : "bottom"; + $$.xOrient = config.axis_rotated ? config.axis_x_inner ? 'right' : 'left' : config.axis_x_inner ? 'top' : 'bottom'; + $$.yOrient = config.axis_rotated ? config.axis_y_inner ? 'top' : 'bottom' : config.axis_y_inner ? 'right' : 'left'; + $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? 'bottom' : 'top' : config.axis_y2_inner ? 'left' : 'right'; + $$.subXOrient = config.axis_rotated ? 'left' : 'bottom'; $$.isLegendRight = config.legend_position === 'right'; $$.isLegendInset = config.legend_position === 'inset'; $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right'; @@ -1451,7 +1467,7 @@ binding = false; } - $$.selectChart.html("").classed("c3", true); // Init data as targets + $$.selectChart.html('').classed('c3', true); // Init data as targets $$.data.xs = {}; $$.data.targets = $$.convertDataToTargets(data); @@ -1488,7 +1504,7 @@ /*-- Basic Elements --*/ // Define svgs - $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () { + $$.svg = $$.selectChart.append('svg').style('overflow', 'hidden').on('mouseenter', function () { return config.onmouseover.call($$); }).on('mouseleave', function () { return config.onmouseout.call($$); @@ -1499,7 +1515,7 @@ } // Define defs - defs = $$.svg.append("defs"); + defs = $$.svg.append('defs'); $$.clipChart = $$.appendClip(defs, $$.clipId); $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis); $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis); @@ -1507,7 +1523,7 @@ $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart); $$.updateSvgSize(); // Define regions - main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main')); + main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main')); if ($$.initPie) { $$.initPie(); @@ -1550,15 +1566,15 @@ // text when empty - main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers. - .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE. + main.append('text').attr('class', CLASS.text + ' ' + CLASS.empty).attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers. + .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE. // Regions $$.initRegion(); // Grids $$.initGrid(); // Define g for chart area - main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart); // Grid lines + main.append('g').attr('clip-path', $$.clipPath).attr('class', CLASS.chart); // Grid lines if (config.grid_lines_front) { $$.initGridLines(); @@ -1610,10 +1626,10 @@ y1 = g.attr('y1'), y2 = g.attr('y2'); g.attr({ - 'x1': Math.ceil(x1), - 'x2': Math.ceil(x2), - 'y1': Math.ceil(y1), - 'y2': Math.ceil(y2) + x1: Math.ceil(x1), + x2: Math.ceil(x2), + y1: Math.ceil(y1), + y2: Math.ceil(y2) }); }); } @@ -1736,7 +1752,7 @@ var $$ = this; $$.svg.selectAll('.' + CLASS.target).filter(function (d) { return $$.isTargetToShow(d.id); - }).transition().duration($$.config.transition_duration).style("opacity", 1); + }).transition().duration($$.config.transition_duration).style('opacity', 1); }; ChartInternal.prototype.redraw = function (options, transitions) { @@ -1761,19 +1777,19 @@ cx, cy; options = options || {}; - withY = getOption(options, "withY", true); - withSubchart = getOption(options, "withSubchart", true); - withTransition = getOption(options, "withTransition", true); - withTransform = getOption(options, "withTransform", false); - withUpdateXDomain = getOption(options, "withUpdateXDomain", false); - withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false); - withTrimXDomain = getOption(options, "withTrimXDomain", true); - withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain); - withLegend = getOption(options, "withLegend", false); - withEventRect = getOption(options, "withEventRect", true); - withDimension = getOption(options, "withDimension", true); - withTransitionForExit = getOption(options, "withTransitionForExit", withTransition); - withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition); + withY = getOption(options, 'withY', true); + withSubchart = getOption(options, 'withSubchart', true); + withTransition = getOption(options, 'withTransition', true); + withTransform = getOption(options, 'withTransform', false); + withUpdateXDomain = getOption(options, 'withUpdateXDomain', false); + withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false); + withTrimXDomain = getOption(options, 'withTrimXDomain', true); + withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain); + withLegend = getOption(options, 'withLegend', false); + withEventRect = getOption(options, 'withEventRect', true); + withDimension = getOption(options, 'withDimension', true); + withTransitionForExit = getOption(options, 'withTransitionForExit', withTransition); + withTransitionForAxis = getOption(options, 'withTransitionForAxis', withTransition); duration = withTransition ? config.transition_duration : 0; durationForExit = withTransitionForExit ? duration : 0; durationForAxis = withTransitionForAxis ? duration : 0; @@ -1864,7 +1880,7 @@ $$.updateXgridFocus(); // Data empty label positioning and text. - main.select("text." + CLASS.text + '.' + CLASS.empty).attr("x", $$.width / 2).attr("y", $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); // event rect + main.select('text.' + CLASS.text + '.' + CLASS.empty).attr('x', $$.width / 2).attr('y', $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); // event rect if (withEventRect) { $$.redrawEventRect(); @@ -1978,14 +1994,14 @@ transitions; options = options || {}; // same with redraw - options.withTransition = getOption(options, "withTransition", true); - options.withTransform = getOption(options, "withTransform", false); - options.withLegend = getOption(options, "withLegend", false); // NOT same with redraw + options.withTransition = getOption(options, 'withTransition', true); + options.withTransform = getOption(options, 'withTransform', false); + options.withLegend = getOption(options, 'withLegend', false); // NOT same with redraw - options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true); - options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true); + options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true); + options.withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', true); options.withTransitionForExit = false; - options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) + options.withTransitionForTransform = getOption(options, 'withTransitionForTransform', options.withTransition); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called) $$.updateSizes(); // MEMO: called in updateLegend in redraw if withLegend @@ -2061,7 +2077,7 @@ y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label } - return "translate(" + x + "," + y + ")"; + return 'translate(' + x + ',' + y + ')'; }; ChartInternal.prototype.initialOpacity = function (d) { @@ -2164,12 +2180,11 @@ y2Axis = y2Axis.transition(); } } - - (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main')); - xAxis.attr("transform", $$.getTranslate('x')); - yAxis.attr("transform", $$.getTranslate('y')); - y2Axis.attr("transform", $$.getTranslate('y2')); - $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); + (withTransition ? $$.main.transition() : $$.main).attr('transform', $$.getTranslate('main')); + xAxis.attr('transform', $$.getTranslate('x')); + yAxis.attr('transform', $$.getTranslate('y')); + y2Axis.attr('transform', $$.getTranslate('y2')); + $$.main.select('.' + CLASS.chartArcs).attr('transform', $$.getTranslate('arc')); }; ChartInternal.prototype.transformAll = function (withTransition, transitions) { @@ -2194,7 +2209,7 @@ $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$)); $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() && brush.attr('height') || 0); // MEMO: parent div's height will be bigger than svg when - $$.selectChart.style('max-height', $$.currentHeight + "px"); + $$.selectChart.style('max-height', $$.currentHeight + 'px'); }; ChartInternal.prototype.updateDimension = function (withoutAxis) { @@ -2221,7 +2236,7 @@ observer; if (typeof MutationObserver === 'undefined') { - window.console.error("MutationObserver not defined."); + window.console.error('MutationObserver not defined.'); return; } @@ -2399,7 +2414,7 @@ var n = 0; transition.each(function () { ++n; - }).on("end", function () { + }).on('end', function () { if (! --n) { callback.apply(this, arguments); } @@ -2476,15 +2491,10 @@ ChartInternal.prototype.CLASS = CLASS; /* jshint ignore:start */ - // SVGPathSeg API polyfill - // https://github.com/progers/pathseg - // - // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from - // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec - // changes which were implemented in Firefox 43 and Chrome 46. + (function () { - if (!("SVGPathSeg" in window)) { + if (!('SVGPathSeg' in window)) { // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) { this.pathSegType = type; @@ -2492,7 +2502,7 @@ this._owningPathSegList = owningPathSegList; }; - window.SVGPathSeg.prototype.classname = "SVGPathSeg"; + window.SVGPathSeg.prototype.classname = 'SVGPathSeg'; window.SVGPathSeg.PATHSEG_UNKNOWN = 0; window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; @@ -2519,13 +2529,13 @@ }; window.SVGPathSegClosePath = function (owningPathSegList) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, 'z', owningPathSegList); }; window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegClosePath.prototype.toString = function () { - return "[object SVGPathSegClosePath]"; + return '[object SVGPathSegClosePath]'; }; window.SVGPathSegClosePath.prototype._asPathString = function () { @@ -2537,7 +2547,7 @@ }; window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, 'M', owningPathSegList); this._x = x; this._y = y; }; @@ -2545,18 +2555,18 @@ window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegMovetoAbs.prototype.toString = function () { - return "[object SVGPathSegMovetoAbs]"; + return '[object SVGPathSegMovetoAbs]'; }; window.SVGPathSegMovetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegMovetoAbs.prototype.clone = function () { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2567,7 +2577,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2580,7 +2590,7 @@ }); window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, 'm', owningPathSegList); this._x = x; this._y = y; }; @@ -2588,18 +2598,18 @@ window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegMovetoRel.prototype.toString = function () { - return "[object SVGPathSegMovetoRel]"; + return '[object SVGPathSegMovetoRel]'; }; window.SVGPathSegMovetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegMovetoRel.prototype.clone = function () { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2610,7 +2620,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', { get: function get() { return this._y; }, @@ -2623,7 +2633,7 @@ }); window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, 'L', owningPathSegList); this._x = x; this._y = y; }; @@ -2631,18 +2641,18 @@ window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoAbs]"; + return '[object SVGPathSegLinetoAbs]'; }; window.SVGPathSegLinetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegLinetoAbs.prototype.clone = function () { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2653,7 +2663,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2666,7 +2676,7 @@ }); window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, 'l', owningPathSegList); this._x = x; this._y = y; }; @@ -2674,18 +2684,18 @@ window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoRel.prototype.toString = function () { - return "[object SVGPathSegLinetoRel]"; + return '[object SVGPathSegLinetoRel]'; }; window.SVGPathSegLinetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegLinetoRel.prototype.clone = function () { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2696,7 +2706,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', { get: function get() { return this._y; }, @@ -2709,7 +2719,7 @@ }); window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, 'C', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2721,18 +2731,18 @@ window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicAbs]"; + return '[object SVGPathSegCurvetoCubicAbs]'; }; window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2743,7 +2753,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2754,7 +2764,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', { get: function get() { return this._x1; }, @@ -2765,7 +2775,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', { get: function get() { return this._y1; }, @@ -2776,7 +2786,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', { get: function get() { return this._x2; }, @@ -2787,7 +2797,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', { get: function get() { return this._y2; }, @@ -2800,7 +2810,7 @@ }); window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, 'c', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2812,18 +2822,18 @@ window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicRel]"; + return '[object SVGPathSegCurvetoCubicRel]'; }; window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2834,7 +2844,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', { get: function get() { return this._y; }, @@ -2845,7 +2855,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', { get: function get() { return this._x1; }, @@ -2856,7 +2866,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', { get: function get() { return this._y1; }, @@ -2867,7 +2877,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', { get: function get() { return this._x2; }, @@ -2878,7 +2888,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', { get: function get() { return this._y2; }, @@ -2891,7 +2901,7 @@ }); window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, 'Q', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2901,18 +2911,18 @@ window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticAbs]"; + return '[object SVGPathSegCurvetoQuadraticAbs]'; }; window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -2923,7 +2933,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -2934,7 +2944,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x1', { get: function get() { return this._x1; }, @@ -2945,7 +2955,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y1', { get: function get() { return this._y1; }, @@ -2958,7 +2968,7 @@ }); window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, 'q', owningPathSegList); this._x = x; this._y = y; this._x1 = x1; @@ -2968,18 +2978,18 @@ window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticRel]"; + return '[object SVGPathSegCurvetoQuadraticRel]'; }; window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x1 + ' ' + this._y1 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', { get: function get() { return this._x; }, @@ -2990,7 +3000,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3001,7 +3011,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x1', { get: function get() { return this._x1; }, @@ -3012,7 +3022,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y1', { get: function get() { return this._y1; }, @@ -3025,7 +3035,7 @@ }); window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, 'A', owningPathSegList); this._x = x; this._y = y; this._r1 = r1; @@ -3038,18 +3048,18 @@ window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegArcAbs.prototype.toString = function () { - return "[object SVGPathSegArcAbs]"; + return '[object SVGPathSegArcAbs]'; }; window.SVGPathSegArcAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegArcAbs.prototype.clone = function () { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }; - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3060,7 +3070,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3071,7 +3081,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', { get: function get() { return this._r1; }, @@ -3082,7 +3092,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', { get: function get() { return this._r2; }, @@ -3093,7 +3103,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', { get: function get() { return this._angle; }, @@ -3104,7 +3114,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', { get: function get() { return this._largeArcFlag; }, @@ -3115,7 +3125,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { + Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', { get: function get() { return this._sweepFlag; }, @@ -3128,7 +3138,7 @@ }); window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, 'a', owningPathSegList); this._x = x; this._y = y; this._r1 = r1; @@ -3141,18 +3151,18 @@ window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegArcRel.prototype.toString = function () { - return "[object SVGPathSegArcRel]"; + return '[object SVGPathSegArcRel]'; }; window.SVGPathSegArcRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._r1 + ' ' + this._r2 + ' ' + this._angle + ' ' + (this._largeArcFlag ? '1' : '0') + ' ' + (this._sweepFlag ? '1' : '0') + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegArcRel.prototype.clone = function () { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }; - Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3163,7 +3173,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3174,7 +3184,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', { get: function get() { return this._r1; }, @@ -3185,7 +3195,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', { get: function get() { return this._r2; }, @@ -3196,7 +3206,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', { get: function get() { return this._angle; }, @@ -3207,7 +3217,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', { get: function get() { return this._largeArcFlag; }, @@ -3218,7 +3228,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { + Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', { get: function get() { return this._sweepFlag; }, @@ -3231,25 +3241,25 @@ }); window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, 'H', owningPathSegList); this._x = x; }; window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalAbs]"; + return '[object SVGPathSegLinetoHorizontalAbs]'; }; window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; + return this.pathSegTypeAsLetter + ' ' + this._x; }; window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3262,25 +3272,25 @@ }); window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, 'h', owningPathSegList); this._x = x; }; window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalRel]"; + return '[object SVGPathSegLinetoHorizontalRel]'; }; window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; + return this.pathSegTypeAsLetter + ' ' + this._x; }; window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); }; - Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3293,25 +3303,25 @@ }); window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, 'V', owningPathSegList); this._y = y; }; window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalAbs]"; + return '[object SVGPathSegLinetoVerticalAbs]'; }; window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._y; }; window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3324,25 +3334,25 @@ }); window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, 'v', owningPathSegList); this._y = y; }; window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalRel]"; + return '[object SVGPathSegLinetoVerticalRel]'; }; window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._y; }; window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); }; - Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3355,7 +3365,7 @@ }); window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, 'S', owningPathSegList); this._x = x; this._y = y; this._x2 = x2; @@ -3365,18 +3375,18 @@ window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothAbs]"; + return '[object SVGPathSegCurvetoCubicSmoothAbs]'; }; window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3387,7 +3397,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3398,7 +3408,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x2', { get: function get() { return this._x2; }, @@ -3409,7 +3419,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y2', { get: function get() { return this._y2; }, @@ -3422,7 +3432,7 @@ }); window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, 's', owningPathSegList); this._x = x; this._y = y; this._x2 = x2; @@ -3432,18 +3442,18 @@ window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothRel]"; + return '[object SVGPathSegCurvetoCubicSmoothRel]'; }; window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x2 + ' ' + this._y2 + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); }; - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3454,7 +3464,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3465,7 +3475,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x2', { get: function get() { return this._x2; }, @@ -3476,7 +3486,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { + Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y2', { get: function get() { return this._y2; }, @@ -3489,7 +3499,7 @@ }); window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, 'T', owningPathSegList); this._x = x; this._y = y; }; @@ -3497,18 +3507,18 @@ window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; + return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'; }; window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'x', { get: function get() { return this._x; }, @@ -3519,7 +3529,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'y', { get: function get() { return this._y; }, @@ -3532,7 +3542,7 @@ }); window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList); + window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, 't', owningPathSegList); this._x = x; this._y = y; }; @@ -3540,18 +3550,18 @@ window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; + return '[object SVGPathSegCurvetoQuadraticSmoothRel]'; }; window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; + return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y; }; window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); }; - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'x', { get: function get() { return this._x; }, @@ -3562,7 +3572,7 @@ }, enumerable: true }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { + Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'y', { get: function get() { return this._y; }, @@ -3651,14 +3661,14 @@ return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); }; - if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) { + if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) { // Add getPathSegAtLength to SVGPathElement. // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm. window.SVGPathElement.prototype.getPathSegAtLength = function (distance) { - if (distance === undefined || !isFinite(distance)) throw "Invalid arguments."; - var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); - measurementElement.setAttribute("d", this.getAttribute("d")); + if (distance === undefined || !isFinite(distance)) throw 'Invalid arguments.'; + var measurementElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + measurementElement.setAttribute('d', this.getAttribute('d')); var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; // If the path is empty, return 0. if (lastPathSegment <= 0) return 0; @@ -3674,23 +3684,23 @@ } } - if (!("SVGPathSegList" in window)) { + if (!('SVGPathSegList' in window)) { // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList window.SVGPathSegList = function (pathElement) { this._pathElement = pathElement; - this._list = this._parsePath(this._pathElement.getAttribute("d")); // Use a MutationObserver to catch changes to the path's "d" attribute. + this._list = this._parsePath(this._pathElement.getAttribute('d')); // Use a MutationObserver to catch changes to the path's "d" attribute. this._mutationObserverConfig = { - "attributes": true, - "attributeFilter": ["d"] + attributes: true, + attributeFilter: ['d'] }; this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this)); this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); }; - window.SVGPathSegList.prototype.classname = "SVGPathSegList"; - Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", { + window.SVGPathSegList.prototype.classname = 'SVGPathSegList'; + Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', { get: function get() { this._checkPathSynchronizedToList(); @@ -3700,7 +3710,7 @@ }); // Add the pathSegList accessors to window.SVGPathElement. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData - Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', { get: function get() { if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this); return this._pathSegList; @@ -3708,19 +3718,19 @@ enumerable: true }); // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList. - Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'normalizedPathSegList', { get: function get() { return this.pathSegList; }, enumerable: true }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'animatedPathSegList', { get: function get() { return this.pathSegList; }, enumerable: true }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { + Object.defineProperty(window.SVGPathElement.prototype, 'animatedNormalizedPathSegList', { get: function get() { return this.pathSegList; }, @@ -3737,16 +3747,16 @@ if (!this._pathElement) return; var hasPathMutations = false; mutationRecords.forEach(function (record) { - if (record.attributeName == "d") hasPathMutations = true; + if (record.attributeName == 'd') hasPathMutations = true; }); - if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d")); + if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute('d')); }; // Serialize the list and update the path's 'd' attribute. window.SVGPathSegList.prototype._writeListToPath = function () { this._pathElementMutationObserver.disconnect(); - this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list)); + this._pathElement.setAttribute('d', window.SVGPathSegList._pathSegArrayAsString(this._list)); this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); }; // When a path segment changes the list needs to be synchronized back to the path element. @@ -3780,7 +3790,7 @@ }; window.SVGPathSegList.prototype._checkValidIndex = function (index) { - if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR"; + if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw 'INDEX_SIZE_ERR'; }; window.SVGPathSegList.prototype.getItem = function (index) { @@ -3861,14 +3871,14 @@ }; window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) { - var string = ""; + var string = ''; var first = true; pathSegArray.forEach(function (pathSeg) { if (first) { first = false; string += pathSeg._asPathString(); } else { - string += " " + pathSeg._asPathString(); + string += ' ' + pathSeg._asPathString(); } }); return string; @@ -3898,7 +3908,7 @@ Source.prototype._isCurrentSpace = function () { var character = this._string[this._currentIndex]; - return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f"); + return character <= ' ' && (character == ' ' || character == '\n' || character == '\t' || character == '\r' || character == '\f'); }; Source.prototype._skipOptionalSpaces = function () { @@ -3910,10 +3920,10 @@ }; Source.prototype._skipOptionalSpacesOrDelimiter = function () { - if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false; + if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ',') return false; if (this._skipOptionalSpaces()) { - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") { + if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ',') { this._currentIndex++; this._skipOptionalSpaces(); @@ -3934,62 +3944,62 @@ Source.prototype._pathSegTypeFromChar = function (lookahead) { switch (lookahead) { - case "Z": - case "z": + case 'Z': + case 'z': return window.SVGPathSeg.PATHSEG_CLOSEPATH; - case "M": + case 'M': return window.SVGPathSeg.PATHSEG_MOVETO_ABS; - case "m": + case 'm': return window.SVGPathSeg.PATHSEG_MOVETO_REL; - case "L": + case 'L': return window.SVGPathSeg.PATHSEG_LINETO_ABS; - case "l": + case 'l': return window.SVGPathSeg.PATHSEG_LINETO_REL; - case "C": + case 'C': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS; - case "c": + case 'c': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL; - case "Q": + case 'Q': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS; - case "q": + case 'q': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL; - case "A": + case 'A': return window.SVGPathSeg.PATHSEG_ARC_ABS; - case "a": + case 'a': return window.SVGPathSeg.PATHSEG_ARC_REL; - case "H": + case 'H': return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS; - case "h": + case 'h': return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL; - case "V": + case 'V': return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS; - case "v": + case 'v': return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL; - case "S": + case 'S': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; - case "s": + case 's': return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL; - case "T": + case 'T': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; - case "t": + case 't': return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; default: @@ -3999,7 +4009,7 @@ Source.prototype._nextCommandHelper = function (lookahead, previousCommand) { // Check for remaining coordinates in the current command. - if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { + if ((lookahead == '+' || lookahead == '-' || lookahead == '.' || lookahead >= '0' && lookahead <= '9') && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS; if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL; return previousCommand; @@ -4030,16 +4040,16 @@ this._skipOptionalSpaces(); // Read the sign. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") { + if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == '+') this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == '-') { this._currentIndex++; sign = -1; } - if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") // The first character of a number must be one of [0-9+-.]. + if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') && this._string.charAt(this._currentIndex) != '.') // The first character of a number must be one of [0-9+-.]. return undefined; // Read the integer part, build right-to-left. var startIntPartIndex = this._currentIndex; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { + while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') { this._currentIndex++; } // Advance to first non-digit. @@ -4049,41 +4059,41 @@ var multiplier = 1; while (scanIntPartIndex >= startIntPartIndex) { - integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0"); + integer += multiplier * (this._string.charAt(scanIntPartIndex--) - '0'); multiplier *= 10; } } // Read the decimals. - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") { + if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == '.') { this._currentIndex++; // There must be a least one digit following the . - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; + if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') return undefined; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { + while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') { frac *= 10; - decimal += (this._string.charAt(this._currentIndex) - "0") / frac; + decimal += (this._string.charAt(this._currentIndex) - '0') / frac; this._currentIndex += 1; } } // Read the exponent part. - if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m") { + if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == 'e' || this._string.charAt(this._currentIndex) == 'E') && this._string.charAt(this._currentIndex + 1) != 'x' && this._string.charAt(this._currentIndex + 1) != 'm') { this._currentIndex++; // Read the sign of the exponent. - if (this._string.charAt(this._currentIndex) == "+") { + if (this._string.charAt(this._currentIndex) == '+') { this._currentIndex++; - } else if (this._string.charAt(this._currentIndex) == "-") { + } else if (this._string.charAt(this._currentIndex) == '-') { this._currentIndex++; expsign = -1; } // There must be an exponent. - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; + if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < '0' || this._string.charAt(this._currentIndex) > '9') return undefined; - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { + while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= '0' && this._string.charAt(this._currentIndex) <= '9') { exponent *= 10; - exponent += this._string.charAt(this._currentIndex) - "0"; + exponent += this._string.charAt(this._currentIndex) - '0'; this._currentIndex++; } } @@ -4104,7 +4114,7 @@ var flagChar = this._string.charAt(this._currentIndex++); - if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined; + if (flagChar == '0') flag = false;else if (flagChar == '1') flag = true;else return undefined; this._skipOptionalSpacesOrDelimiter(); @@ -4246,7 +4256,7 @@ return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); default: - throw "Unknown path seg type."; + throw 'Unknown path seg type.'; } }; @@ -4293,7 +4303,7 @@ if (typeof Object.assign !== 'function') { // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { + Object.defineProperty(Object, 'assign', { value: function assign(target, varArgs) { if (target === null || target === undefined) { @@ -4510,7 +4520,7 @@ $$.resizeFunction.remove(); // Unbinds from the window focus event $$.unbindWindowFocus(); - $$.selectChart.classed('c3', false).html(""); // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. + $$.selectChart.classed('c3', false).html(''); // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen. Object.keys($$).forEach(function (key) { $$[key] = null; @@ -4873,17 +4883,17 @@ } // draw again for removing flowed elements and reverting attr - xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity); + xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style('opacity', $$.xgridAttr.opacity); xgridLines.attr('transform', null); - xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv); - xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv); - mainBar.attr('transform', null).attr("d", drawBar); - mainLine.attr('transform', null).attr("d", drawLine); - mainArea.attr('transform', null).attr("d", drawArea); - mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy); + xgridLines.select('line').attr('x1', config.axis_rotated ? 0 : xv).attr('x2', config.axis_rotated ? $$.width : xv); + xgridLines.select('text').attr('x', config.axis_rotated ? $$.width : 0).attr('y', xv); + mainBar.attr('transform', null).attr('d', drawBar); + mainLine.attr('transform', null).attr('d', drawLine); + mainArea.attr('transform', null).attr('d', drawArea); + mainCircle.attr('transform', null).attr('cx', cx).attr('cy', cy); mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$)); mainRegion.attr('transform', null); - mainRegion.filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$)); // callback for end of flow + mainRegion.filter($$.isRegionOnX).attr('x', $$.regionX.bind($$)).attr('width', $$.regionWidth.bind($$)); // callback for end of flow done(); $$.flowing = false; @@ -5156,8 +5166,8 @@ classes, regions; options = options || {}; - duration = getOption(options, "duration", config.transition_duration); - classes = getOption(options, "classes", [CLASS.region]); + duration = getOption(options, 'duration', config.transition_duration); + classes = getOption(options, 'classes', [CLASS.region]); regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) { return '.' + c; })); @@ -5644,7 +5654,7 @@ updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; + return updated ? arc(updated) : 'M 0 0'; }; // TODO: extends all function @@ -5665,12 +5675,12 @@ }); return function (d) { var updated = $$.updateAngle(d); - return updated ? arc(updated) : "M 0 0"; + return updated ? arc(updated) : 'M 0 0'; }; }; ChartInternal.prototype.getArc = function (d, withoutUpdate, force) { - return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0"; + return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : 'M 0 0'; }; ChartInternal.prototype.transformForArcLabel = function (d) { @@ -5682,7 +5692,7 @@ y, h, ratio, - translate = "", + translate = '', hasGauge = $$.hasType('gauge'); if (updated && !hasGauge) { @@ -5699,12 +5709,12 @@ ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0; } - translate = "translate(" + x * ratio + ',' + y * ratio + ")"; + translate = 'translate(' + x * ratio + ',' + y * ratio + ')'; } else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) { var y1 = Math.sin(updated.endAngle - Math.PI / 2); x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; - translate = "translate(" + x + ',' + y + ")"; + translate = 'translate(' + x + ',' + y + ')'; } return translate; @@ -5736,7 +5746,7 @@ format; if (!$$.shouldShowArcLabel()) { - return ""; + return ''; } updated = $$.updateAngle(d); @@ -5745,7 +5755,7 @@ id = d.data.id; if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) { - return ""; + return ''; } format = $$.getArcLabelFormat(); @@ -5781,7 +5791,7 @@ return; } - $$.d3.select(this).selectAll('path').transition().duration($$.expandDuration(d.data.id)).attr("d", $$.svgArcExpanded).transition().duration($$.expandDuration(d.data.id) * 2).attr("d", $$.svgArcExpandedSub).each(function (d) { + $$.d3.select(this).selectAll('path').transition().duration($$.expandDuration(d.data.id)).attr('d', $$.svgArcExpanded).transition().duration($$.expandDuration(d.data.id) * 2).attr('d', $$.svgArcExpandedSub).each(function (d) { if ($$.isDonutType(d.data)) ; }); }); @@ -5797,7 +5807,7 @@ targetIds = $$.mapToTargetIds(targetIds); $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) { return $$.expandDuration(d.data.id); - }).attr("d", $$.svgArc); + }).attr('d', $$.svgArc); $$.svg.selectAll('.' + CLASS.arc); }; @@ -5866,7 +5876,7 @@ ChartInternal.prototype.getArcTitle = function () { var $$ = this; - return $$.hasType('donut') ? $$.config.donut_title : ""; + return $$.hasType('donut') ? $$.config.donut_title : ''; }; ChartInternal.prototype.updateTargetsForArc = function (targets) { @@ -5877,19 +5887,19 @@ classChartArc = $$.classChartArc.bind($$), classArcs = $$.classArcs.bind($$), classFocus = $$.classFocus.bind($$); - mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) { + mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr('class', function (d) { return classChartArc(d) + classFocus(d.data); }); - mainPieEnter = mainPies.enter().append("g").attr("class", classChartArc); + mainPieEnter = mainPies.enter().append('g').attr('class', classChartArc); mainPieEnter.append('g').attr('class', classArcs); - mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none"); // MEMO: can not keep same color..., but not bad to update color in redraw + mainPieEnter.append('text').attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em').style('opacity', 0).style('text-anchor', 'middle').style('pointer-events', 'none'); // MEMO: can not keep same color..., but not bad to update color in redraw //mainPieUpdate.exit().remove(); }; ChartInternal.prototype.initArc = function () { var $$ = this; - $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc')); - $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle()); + $$.arcs = $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartArcs).attr('transform', $$.getTranslate('arc')); + $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style('text-anchor', 'middle').text($$.getArcTitle()); }; ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) { @@ -5903,10 +5913,10 @@ mainArcLabelLine, hasGaugeType = $$.hasType('gauge'); arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$)); - mainArc = arcs.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) { + mainArc = arcs.enter().append('path').attr('class', $$.classArc.bind($$)).style('fill', function (d) { return $$.color(d.data); - }).style("cursor", function (d) { - return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null; + }).style('cursor', function (d) { + return config.interaction_enabled && config.data_selection_isselectable(d) ? 'pointer' : null; }).each(function (d) { if ($$.isGaugeType(d.data)) { d.startAngle = d.endAngle = config.gauge_startingAngle; @@ -5917,23 +5927,23 @@ if (hasGaugeType) { arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine).data($$.arcData.bind($$)); - mainArcLabelLine = arcLabelLines.enter().append('rect').attr("class", function (d) { + mainArcLabelLine = arcLabelLines.enter().append('rect').attr('class', function (d) { return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id; }).merge(arcLabelLines); if ($$.filterTargetsToShow($$.data.targets).length === 1) { - mainArcLabelLine.style("display", "none"); + mainArcLabelLine.style('display', 'none'); } else { - mainArcLabelLine.style("fill", function (d) { + mainArcLabelLine.style('fill', function (d) { return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data); - }).style("display", config.gauge_labelLine_show ? "" : "none").each(function (d) { + }).style('display', config.gauge_labelLine_show ? '' : 'none').each(function (d) { var lineLength = 0, lineThickness = 2, x = 0, y = 0, - transform = ""; + transform = ''; if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { var updated = $$.updateAngle(d), @@ -5944,16 +5954,16 @@ lineLength = $$.radiusExpanded - $$.radius + innerLineLength; x = Math.cos(linePositioningAngle) * arcInnerRadius; y = Math.sin(linePositioningAngle) * arcInnerRadius; - transform = "rotate(" + lineAngle * 180 / Math.PI + ", " + x + ", " + y + ")"; + transform = 'rotate(' + lineAngle * 180 / Math.PI + ', ' + x + ', ' + y + ')'; } - d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0"); + d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style('stroke-dasharray', '0, ' + (lineLength + lineThickness) + ', 0'); }); } } - mainArc.attr("transform", function (d) { - return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : ""; + mainArc.attr('transform', function (d) { + return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : ''; }).on('mouseover', config.interaction_enabled ? function (d) { var updated, arcData; @@ -6015,13 +6025,13 @@ } } : null).each(function () { $$.transiting = true; - }).transition().duration(duration).attrTween("d", function (d) { + }).transition().duration(duration).attrTween('d', function (d) { var updated = $$.updateAngle(d), interpolate; if (!updated) { return function () { - return "M 0 0"; + return 'M 0 0'; }; } // if (this._current === d) { // this._current = { @@ -6044,7 +6054,7 @@ return function (t) { // prevents crashing the charts once in transition and chart.destroy() has been called if ($$.config === null) { - return "M 0 0"; + return 'M 0 0'; } var interpolated = interpolate(t); @@ -6052,7 +6062,7 @@ return $$.getArc(interpolated, true); }; - }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) { + }).attr('transform', withTransform ? 'scale(1)' : '').style('fill', function (d) { return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) { return total + item.value; }, 0)) : $$.color(d.data.id); @@ -6061,23 +6071,23 @@ $$.transiting = false; }); arcs.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) { + main.selectAll('.' + CLASS.chartArc).select('text').style('opacity', 0).attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; - }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) { + }).text($$.textForArcLabel.bind($$)).attr('transform', $$.transformForArcLabel.bind($$)).style('font-size', function (d) { return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : ''; - }).transition().duration(duration).style("opacity", function (d) { + }).transition().duration(duration).style('opacity', function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; }); - main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0); + main.select('.' + CLASS.chartArcsTitle).style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0); if (hasGaugeType) { var index = 0; var backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets); - backgroundArc.enter().append("path").attr("class", function (d, i) { + backgroundArc.enter().append('path').attr('class', function (d, i) { return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i; - }).merge(backgroundArc).attr("d", function (d1) { + }).merge(backgroundArc).attr('d', function (d1) { if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { - return "M 0 0"; + return 'M 0 0'; } var d = { @@ -6091,9 +6101,9 @@ return $$.getArc(d, true, true); }); backgroundArc.exit().remove(); - $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMin).attr("dx", -1 * ($$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); - $$.arcs.select('.' + CLASS.chartArcsGaugeMax).attr("dx", $$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); + $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr('dy', '.75em').text(config.gauge_label_show ? config.gauge_units : ''); + $$.arcs.select('.' + CLASS.chartArcsGaugeMin).attr('dx', -1 * ($$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + 'px').attr('dy', '1.2em').text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : ''); + $$.arcs.select('.' + CLASS.chartArcsGaugeMax).attr('dx', $$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + 'px').attr('dy', '1.2em').text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : ''); } }; @@ -6101,10 +6111,10 @@ var arcs = this.arcs; if (this.hasType('gauge')) { - arcs.append('g').attr("class", CLASS.chartArcsBackground); - arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none"); - arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none"); - arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none"); + arcs.append('g').attr('class', CLASS.chartArcsBackground); + arcs.append('text').attr('class', CLASS.chartArcsGaugeUnit).style('text-anchor', 'middle').style('pointer-events', 'none'); + arcs.append('text').attr('class', CLASS.chartArcsGaugeMin).style('text-anchor', 'middle').style('pointer-events', 'none'); + arcs.append('text').attr('class', CLASS.chartArcsGaugeMax).style('text-anchor', 'middle').style('pointer-events', 'none'); } }; @@ -6186,7 +6196,7 @@ }; ChartInternal.prototype.generateClass = function (prefix, targetId) { - return " " + prefix + " " + prefix + this.generateTargetClass(targetId); + return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId); }; ChartInternal.prototype.classText = function (d) { @@ -6328,11 +6338,11 @@ }; ChartInternal.prototype.getClipPath = function (id) { - return "url(" + (isIE(9) ? "" : document.URL.split('#')[0]) + "#" + id + ")"; + return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')'; }; ChartInternal.prototype.appendClip = function (parent, id) { - return parent.append("clipPath").attr("id", id).append("rect"); + return parent.append('clipPath').attr('id', id).append('rect'); }; ChartInternal.prototype.getAxisClipX = function (forHorizontal) { @@ -6529,7 +6539,7 @@ data_mimeType: undefined, data_keys: undefined, // configuration for no plot-able data supplied. - data_empty_label_text: "", + data_empty_label_text: '', // subchart subchart_show: false, subchart_size_height: 60, @@ -6667,7 +6677,7 @@ donut_label_threshold: 0.05, donut_label_ratio: undefined, donut_width: undefined, - donut_title: "", + donut_title: '', donut_expand: {}, donut_expand_duration: 50, donut_padAngle: 0, @@ -6894,7 +6904,7 @@ for (var j = 0; j < rows[i].length; j++) { if (isUndefined(rows[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); + throw new Error('Source data is missing a component at (' + i + ',' + j + ')!'); } newRow[keys[j]] = rows[i][j]; @@ -6928,7 +6938,7 @@ } if (isUndefined(columns[i][j])) { - throw new Error("Source data is missing a component at (" + i + "," + j + ")!"); + throw new Error('Source data is missing a component at (' + i + ',' + j + ')!'); } newRows[j - 1][key] = columns[i][j]; @@ -6977,7 +6987,7 @@ ids = keys.filter($$.isNotXAndNotEpochs, $$); if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) { - throw new Error('You must define the \'x\' key name and the \'epochs\' for Stanford Diagrams'); + throw new Error("You must define the 'x' key name and the 'epochs' for Stanford Diagrams"); } } // save x for update data by load when custom x and c3.x API @@ -7812,14 +7822,14 @@ if (d && api.data.shown.call(api).length) { ratio = d.ratio || d.value; - if (type === "arc") { + if (type === 'arc') { if ($$.hasType('gauge')) { ratio = (d.endAngle - d.startAngle) / (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1)); } else { var total = $$.getTotalDataSum(); ratio = d.value / total; } - } else if (type === "index") { + } else if (type === 'index') { var _total = $$.getTotalPerIndex($$.axis.getId(d.id)); d.ratio = isNumber(d.value) && _total && _total[d.index] > 0 ? d.value / _total[d.index] : 0; @@ -8359,8 +8369,8 @@ box; if (shape.classed(CLASS.circle)) { - _x = shape.attr("cx") * 1; - _y = shape.attr("cy") * 1; + _x = shape.attr('cx') * 1; + _y = shape.attr('cy') * 1; toggle = $$.togglePoint; isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY; } else if (shape.classed(CLASS.bar)) { @@ -8446,7 +8456,7 @@ }; ChartInternal.prototype.defaultValueFormat = function (v) { - return isValue(v) ? +v : ""; + return isValue(v) ? +v : ''; }; ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) { @@ -8458,7 +8468,7 @@ data_labels = $$.config.data_labels, format, defaultFormat = function defaultFormat(v) { - return isValue(v) ? +v : ""; + return isValue(v) ? +v : ''; }; // find format according to axis id @@ -8483,10 +8493,10 @@ var $$ = this, config = $$.config, d3 = $$.d3; - $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid); + $$.grid = $$.main.append('g').attr('clip-path', $$.clipPathForGrid).attr('class', CLASS.grid); if (config.grid_x_show) { - $$.grid.append("g").attr("class", CLASS.xgrids); + $$.grid.append('g').attr('class', CLASS.xgrids); } if (config.grid_y_show) { @@ -8494,7 +8504,7 @@ } if (config.grid_focus_show) { - $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus); + $$.grid.append('g').attr('class', CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus); } $$.xgrid = d3.selectAll([]); @@ -8507,8 +8517,8 @@ ChartInternal.prototype.initGridLines = function () { var $$ = this, d3 = $$.d3; - $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines); - $$.gridLines.append('g').attr("class", CLASS.xgridLines); + $$.gridLines = $$.main.append('g').attr('clip-path', $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines); + $$.gridLines.append('g').attr('class', CLASS.xgridLines); $$.gridLines.append('g').attr('class', CLASS.ygridLines); $$.xgridLines = d3.selectAll([]); }; @@ -8520,23 +8530,23 @@ xgridData = $$.generateGridData(config.grid_x_type, $$.x), tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0; $$.xgridAttr = config.axis_rotated ? { - 'x1': 0, - 'x2': $$.width, - 'y1': function y1(d) { + x1: 0, + x2: $$.width, + y1: function y1(d) { return $$.x(d) - tickOffset; }, - 'y2': function y2(d) { + y2: function y2(d) { return $$.x(d) - tickOffset; } } : { - 'x1': function x1(d) { + x1: function x1(d) { return $$.x(d) + tickOffset; }, - 'x2': function x2(d) { + x2: function x2(d) { return $$.x(d) + tickOffset; }, - 'y1': 0, - 'y2': $$.height + y1: 0, + y2: $$.height }; $$.xgridAttr.opacity = function () { @@ -8545,11 +8555,11 @@ }; var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData); - var xgridEnter = xgrid.enter().append('line').attr("class", CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", 0); + var xgridEnter = xgrid.enter().append('line').attr('class', CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style('opacity', 0); $$.xgrid = xgridEnter.merge(xgrid); if (!withoutUpdate) { - $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity); + $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style('opacity', $$.xgridAttr.opacity); } xgrid.exit().remove(); @@ -8563,13 +8573,13 @@ var ygridEnter = ygrid.enter().append('line') // TODO: x1, x2, y1, y2, opacity need to be set here maybe .attr('class', CLASS.ygrid); $$.ygrid = ygridEnter.merge(ygrid); - $$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0).attr("x2", config.axis_rotated ? $$.y : $$.width).attr("y1", config.axis_rotated ? 0 : $$.y).attr("y2", config.axis_rotated ? $$.height : $$.y); + $$.ygrid.attr('x1', config.axis_rotated ? $$.y : 0).attr('x2', config.axis_rotated ? $$.y : $$.width).attr('y1', config.axis_rotated ? 0 : $$.y).attr('y2', config.axis_rotated ? $$.height : $$.y); ygrid.exit().remove(); $$.smoothLines($$.ygrid, 'grid'); }; ChartInternal.prototype.gridTextAnchor = function (d) { - return d.position ? d.position : "end"; + return d.position ? d.position : 'end'; }; ChartInternal.prototype.gridTextDx = function (d) { @@ -8598,7 +8608,7 @@ yGridTextX = $$.yGridTextX.bind($$); // hide if arc type $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); - main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); + main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); if (config.grid_x_show) { $$.updateXGrid(); @@ -8606,16 +8616,16 @@ xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines); // enter - xgridLineEnter = xgridLine.enter().append('g').attr("class", function (d) { + xgridLineEnter = xgridLine.enter().append('g').attr('class', function (d) { return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : ''); }); - xgridLineEnter.append('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 0); - xgridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "" : "rotate(-90)").attr("x", config.axis_rotated ? yGridTextX : xGridTextX).attr("y", xv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // udpate + xgridLineEnter.append('line').attr('x1', config.axis_rotated ? 0 : xv).attr('x2', config.axis_rotated ? $$.width : xv).attr('y1', config.axis_rotated ? xv : 0).attr('y2', config.axis_rotated ? xv : $$.height).style('opacity', 0); + xgridLineEnter.append('text').attr('text-anchor', $$.gridTextAnchor).attr('transform', config.axis_rotated ? '' : 'rotate(-90)').attr('x', config.axis_rotated ? yGridTextX : xGridTextX).attr('y', xv).attr('dx', $$.gridTextDx).attr('dy', -5).style('opacity', 0); // udpate $$.xgridLines = xgridLineEnter.merge(xgridLine); // done in d3.transition() of the end of this function // exit - xgridLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Y-Grid + xgridLine.exit().transition().duration(duration).style('opacity', 0).remove(); // Y-Grid if (config.grid_y_show) { $$.updateYGrid(); @@ -8623,19 +8633,19 @@ ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines); // enter - ygridLineEnter = ygridLine.enter().append('g').attr("class", function (d) { + ygridLineEnter = ygridLine.enter().append('g').attr('class', function (d) { return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : ''); }); - ygridLineEnter.append('line').attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 0); - ygridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "rotate(-90)" : "").attr("x", config.axis_rotated ? xGridTextX : yGridTextX).attr("y", yv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // update + ygridLineEnter.append('line').attr('x1', config.axis_rotated ? yv : 0).attr('x2', config.axis_rotated ? yv : $$.width).attr('y1', config.axis_rotated ? 0 : yv).attr('y2', config.axis_rotated ? $$.height : yv).style('opacity', 0); + ygridLineEnter.append('text').attr('text-anchor', $$.gridTextAnchor).attr('transform', config.axis_rotated ? 'rotate(-90)' : '').attr('x', config.axis_rotated ? xGridTextX : yGridTextX).attr('y', yv).attr('dx', $$.gridTextDx).attr('dy', -5).style('opacity', 0); // update $$.ygridLines = ygridLineEnter.merge(ygridLine); - $$.ygridLines.select('line').transition().duration(duration).attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 1); - $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) { + $$.ygridLines.select('line').transition().duration(duration).attr('x1', config.axis_rotated ? yv : 0).attr('x2', config.axis_rotated ? yv : $$.width).attr('y1', config.axis_rotated ? 0 : yv).attr('y2', config.axis_rotated ? $$.height : yv).style('opacity', 1); + $$.ygridLines.select('text').transition().duration(duration).attr('x', config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr('y', yv).text(function (d) { return d.text; - }).style("opacity", 1); // exit + }).style('opacity', 1); // exit - ygridLine.exit().transition().duration(duration).style("opacity", 0).remove(); + ygridLine.exit().transition().duration(duration).style('opacity', 0).remove(); }; ChartInternal.prototype.redrawGrid = function (withTransition, transition) { @@ -8644,9 +8654,9 @@ xv = $$.xv.bind($$), lines = $$.xgridLines.select('line'), texts = $$.xgridLines.select('text'); - return [(withTransition ? lines.transition(transition) : lines).attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 1), (withTransition ? texts.transition(transition) : texts).attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr("y", xv).text(function (d) { + return [(withTransition ? lines.transition(transition) : lines).attr('x1', config.axis_rotated ? 0 : xv).attr('x2', config.axis_rotated ? $$.width : xv).attr('y1', config.axis_rotated ? xv : 0).attr('y2', config.axis_rotated ? xv : $$.height).style('opacity', 1), (withTransition ? texts.transition(transition) : texts).attr('x', config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr('y', xv).text(function (d) { return d.text; - }).style("opacity", 1)]; + }).style('opacity', 1)]; }; ChartInternal.prototype.showXGridFocus = function (selectedData) { @@ -8667,18 +8677,18 @@ return; } - focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx); + focusEl.style('visibility', 'visible').data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx); $$.smoothLines(focusEl, 'grid'); }; ChartInternal.prototype.hideXGridFocus = function () { - this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden"); + this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden'); }; ChartInternal.prototype.updateXgridFocus = function () { var $$ = this, config = $$.config; - $$.main.select('line.' + CLASS.xgridFocus).attr("x1", config.axis_rotated ? 0 : -10).attr("x2", config.axis_rotated ? $$.width : -10).attr("y1", config.axis_rotated ? -10 : 0).attr("y2", config.axis_rotated ? -10 : $$.height); + $$.main.select('line.' + CLASS.xgridFocus).attr('x1', config.axis_rotated ? 0 : -10).attr('x2', config.axis_rotated ? $$.width : -10).attr('y1', config.axis_rotated ? -10 : 0).attr('y2', config.axis_rotated ? -10 : $$.height); }; ChartInternal.prototype.generateGridData = function (type, scale) { @@ -8688,7 +8698,7 @@ firstYear, lastYear, i, - tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size(); + tickNum = $$.main.select('.' + CLASS.axisX).selectAll('.tick').size(); if (type === 'year') { xDomain = $$.getXDomain(); @@ -8704,7 +8714,7 @@ if (gridData.length > tickNum) { // use only int gridData = gridData.filter(function (d) { - return ("" + d).indexOf('.') < 0; + return ('' + d).indexOf('.') < 0; }); } } @@ -8748,11 +8758,11 @@ ChartInternal.prototype.initEventRect = function () { var $$ = this, config = $$.config; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.eventRects).style('fill-opacity', 0); $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect').attr('class', CLASS.eventRect); // event rect handle zoom event as well if (config.zoom_enabled && $$.zoom) { - $$.eventRect.call($$.zoom).on("dblclick.zoom", null); + $$.eventRect.call($$.zoom).on('dblclick.zoom', null); if (config.zoom_initialRange) { // WORKAROUND: Add transition to apply transform immediately when no subchart @@ -8936,7 +8946,7 @@ box = eventRect.getBoundingClientRect(), x = box.left + (mouse ? mouse[0] : 0), y = box.top + (mouse ? mouse[1] : 0), - event = document.createEvent("MouseEvents"); + event = document.createEvent('MouseEvents'); event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null); eventRect.dispatchEvent(event); }; @@ -8945,7 +8955,7 @@ var $$ = this; $$.legendItemTextBox = {}; $$.legendHasRendered = false; - $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend')); + $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend')); if (!$$.config.legend_show) { $$.legend.style('visibility', 'hidden'); @@ -8984,7 +8994,7 @@ ChartInternal.prototype.transformLegend = function (withTransition) { var $$ = this; - (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend')); + (withTransition ? $$.legend.transition() : $$.legend).attr('transform', $$.getTranslate('legend')); }; ChartInternal.prototype.updateLegendStep = function (step) { @@ -9107,8 +9117,8 @@ return !isDefined(config.data_names[id]) || config.data_names[id] !== null; }); options = options || {}; - withTransition = getOption(options, "withTransition", true); - withTransitionForTransform = getOption(options, "withTransitionForTransform", true); + withTransition = getOption(options, 'withTransition', true); + withTransitionForTransform = getOption(options, 'withTransitionForTransform', true); function getTextBox(textElement, id) { if (!$$.legendItemTextBox[id]) { @@ -9258,7 +9268,9 @@ return $$.generateClass(CLASS.legendItem, id); }).style('visibility', function (id) { return $$.isLegendToShow(id) ? 'visible' : 'hidden'; - }).style('cursor', 'pointer').on('click', function (id) { + }).style('cursor', function () { + return config.interaction_enabled ? 'pointer' : 'auto'; + }).on('click', config.interaction_enabled ? function (id) { if (config.legend_item_onclick) { config.legend_item_onclick.call($$, id); } else { @@ -9270,7 +9282,7 @@ $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert(); } } - }).on('mouseover', function (id) { + } : null).on('mouseover', config.interaction_enabled ? function (id) { if (config.legend_item_onmouseover) { config.legend_item_onmouseover.call($$, id); } else { @@ -9280,26 +9292,26 @@ $$.api.focus(id); } } - }).on('mouseout', function (id) { + } : null).on('mouseout', config.interaction_enabled ? function (id) { if (config.legend_item_onmouseout) { config.legend_item_onmouseout.call($$, id); } else { $$.d3.select(this).classed(CLASS.legendItemFocused, false); $$.api.revert(); } - }); + } : null); l.append('text').text(function (id) { return isDefined(config.data_names[id]) ? config.data_names[id] : id; }).each(function (id, i) { updatePositions(this, id, i); - }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); - l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); - l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style("pointer-events", "none").attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); // Set background for inset legend + }).style('pointer-events', 'none').attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText); + l.append('rect').attr('class', CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect); + l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style('pointer-events', 'none').attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); // Set background for inset legend background = $$.legend.select('.' + CLASS.legendBackground + ' rect'); if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) { - background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect'); + background = $$.legend.insert('g', '.' + CLASS.legendItem).attr('class', CLASS.legendBackground).append('rect'); } texts = $$.legend.selectAll('text').data(targetIds).text(function (id) { @@ -9345,7 +9357,7 @@ ChartInternal.prototype.initRegion = function () { var $$ = this; - $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions); + $$.region = $$.main.append('g').attr('clip-path', $$.clipPath).attr('class', CLASS.regions); }; ChartInternal.prototype.updateRegion = function (duration) { @@ -9355,21 +9367,21 @@ $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible'); var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions); var g = mainRegion.enter().append('g'); - g.append('rect').attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) { + g.append('rect').attr('x', $$.regionX.bind($$)).attr('y', $$.regionY.bind($$)).attr('width', $$.regionWidth.bind($$)).attr('height', $$.regionHeight.bind($$)).style('fill-opacity', function (d) { return isValue(d.opacity) ? d.opacity : 0.1; }); g.append('text').text($$.labelRegion.bind($$)); $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$)); - mainRegion.exit().transition().duration(duration).style("opacity", 0).remove(); + mainRegion.exit().transition().duration(duration).style('opacity', 0).remove(); }; ChartInternal.prototype.redrawRegion = function (withTransition, transition) { var $$ = this, regions = $$.mainRegion, regionLabels = $$.mainRegion.selectAll('text'); - return [(withTransition ? regions.transition(transition) : regions).attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) { + return [(withTransition ? regions.transition(transition) : regions).attr('x', $$.regionX.bind($$)).attr('y', $$.regionY.bind($$)).attr('width', $$.regionWidth.bind($$)).attr('height', $$.regionHeight.bind($$)).style('fill-opacity', function (d) { return isValue(d.opacity) ? d.opacity : 0.1; - }), (withTransition ? regionLabels.transition(transition) : regionLabels).attr("x", $$.labelOffsetX.bind($$)).attr("y", $$.labelOffsetY.bind($$)).attr("transform", $$.labelTransform.bind($$)).attr("style", 'text-anchor: left;')]; + }), (withTransition ? regionLabels.transition(transition) : regionLabels).attr('x', $$.labelOffsetX.bind($$)).attr('y', $$.labelOffsetY.bind($$)).attr('transform', $$.labelTransform.bind($$)).attr('style', 'text-anchor: left;')]; }; ChartInternal.prototype.regionX = function (d) { @@ -9443,7 +9455,7 @@ }; ChartInternal.prototype.labelTransform = function (d) { - return 'vertical' in d && d.vertical ? "rotate(90)" : ""; + return 'vertical' in d && d.vertical ? 'rotate(90)' : ''; }; ChartInternal.prototype.labelOffsetX = function (d) { @@ -9688,13 +9700,13 @@ r = $$.pointSelectR.bind($$); config.data_onselected.call($$.api, d, target.node()); // add selected-circle on low layer g - $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () { + $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr('class', function () { return $$.generateClass(CLASS.selectedCircle, i); - }).attr("cx", cx).attr("cy", cy).attr("stroke", function () { + }).attr('cx', cx).attr('cy', cy).attr('stroke', function () { return $$.color(d); - }).attr("r", function (d) { + }).attr('r', function (d) { return $$.pointSelectR(d) * 1.4; - }).transition().duration(100).attr("r", r); + }).transition().duration(100).attr('r', r); }; ChartInternal.prototype.unselectPoint = function (target, d, i) { @@ -9713,7 +9725,7 @@ $$.config.data_onselected.call($$, d, target.node()); if ($$.config.interaction_brighten) { - target.transition().duration(100).style("fill", function () { + target.transition().duration(100).style('fill', function () { return $$.d3.rgb($$.color(d)).brighter(0.75); }); } @@ -9724,7 +9736,7 @@ $$.config.data_onunselected.call($$, d, target.node()); if ($$.config.interaction_brighten) { - target.transition().duration(100).style("fill", function () { + target.transition().duration(100).style('fill', function () { return $$.color(d); }); } @@ -9763,7 +9775,7 @@ if (config.data_selection_enabled && config.data_selection_isselectable(d)) { if (!config.data_selection_multiple) { - $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) { + $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : '')).selectAll('.' + CLASS.shape).each(function (d, i) { var shape = d3.select(this); if (shape.classed(CLASS.SELECTED)) { @@ -9779,7 +9791,7 @@ ChartInternal.prototype.initBar = function () { var $$ = this; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartBars); }; ChartInternal.prototype.updateTargetsForBar = function (targets) { @@ -9793,10 +9805,10 @@ mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) { return classChartBar(d) + classFocus(d); }); - mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style("pointer-events", "none"); // Bars for each data + mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style('pointer-events', 'none'); // Bars for each data - mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) { - return config.data_selection_isselectable(d) ? "pointer" : null; + mainBarEnter.append('g').attr('class', classBars).style('cursor', function (d) { + return config.data_selection_isselectable(d) ? 'pointer' : null; }); }; @@ -9810,14 +9822,14 @@ }; var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData); - var mainBarEnter = mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color); - $$.mainBar = mainBarEnter.merge(mainBar).style("opacity", initialOpacity); - mainBar.exit().transition().duration(durationForExit).style("opacity", 0); + var mainBarEnter = mainBar.enter().append('path').attr('class', classBar).style('stroke', color).style('fill', color); + $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity); + mainBar.exit().transition().duration(durationForExit).style('opacity', 0); }; ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) { var $$ = this; - return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style("stroke", this.color).style("fill", this.color).style("opacity", function (d) { + return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style('stroke', this.color).style('fill', this.color).style('opacity', function (d) { return $$.isTargetToShow(d.id) ? 1 : 0; })]; }; @@ -9965,7 +9977,7 @@ var rowValues = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values; var isTargetNormalized = $$.isTargetNormalized(d.id); var values = rowValues.map(function (v) { - return isTargetNormalized ? $$.getRatio("index", v, true) : v.value; + return isTargetNormalized ? $$.getRatio('index', v, true) : v.value; }); if (t.id === d.id || indices[t.id] !== indices[d.id]) { @@ -10017,17 +10029,17 @@ var $$ = this, d3 = $$.d3, types = { - 'linear': d3.curveLinear, + linear: d3.curveLinear, 'linear-closed': d3.curveLinearClosed, - 'basis': d3.curveBasis, + basis: d3.curveBasis, 'basis-open': d3.curveBasisOpen, 'basis-closed': d3.curveBasisClosed, - 'bundle': d3.curveBundle, - 'cardinal': d3.curveCardinal, + bundle: d3.curveBundle, + cardinal: d3.curveCardinal, 'cardinal-open': d3.curveCardinalOpen, 'cardinal-closed': d3.curveCardinalClosed, - 'monotone': d3.curveMonotoneX, - 'step': d3.curveStep, + monotone: d3.curveMonotoneX, + step: d3.curveStep, 'step-before': d3.curveStepBefore, 'step-after': d3.curveStepAfter }, @@ -10046,7 +10058,7 @@ ChartInternal.prototype.initLine = function () { var $$ = this; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartLines); }; ChartInternal.prototype.updateTargetsForLine = function (targets) { @@ -10062,17 +10074,17 @@ mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) { return classChartLine(d) + classFocus(d); }); - mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none"); // Lines for each data + mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style('pointer-events', 'none'); // Lines for each data - mainLineEnter.append('g').attr("class", classLines); // Areas + mainLineEnter.append('g').attr('class', classLines); // Areas mainLineEnter.append('g').attr('class', classAreas); // Circles for each data point on lines - mainLineEnter.append('g').attr("class", function (d) { + mainLineEnter.append('g').attr('class', function (d) { return $$.generateClass(CLASS.selectedCircles, d.id); }); - mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) { - return config.data_selection_isselectable(d) ? "pointer" : null; + mainLineEnter.append('g').attr('class', classCircles).style('cursor', function (d) { + return config.data_selection_isselectable(d) ? 'pointer' : null; }); // Update date for selected circles targets.forEach(function (t) { @@ -10086,15 +10098,15 @@ ChartInternal.prototype.updateLine = function (durationForExit) { var $$ = this; var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$)); - var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color); - $$.mainLine = mainLineEnter.merge(mainLine).style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) { + var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color); + $$.mainLine = mainLineEnter.merge(mainLine).style('opacity', $$.initialOpacity.bind($$)).style('shape-rendering', function (d) { return $$.isStepType(d) ? 'crispEdges' : ''; }).attr('transform', null); mainLine.exit().transition().duration(durationForExit).style('opacity', 0); }; ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) { - return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)]; + return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr('d', drawLine).style('stroke', this.color).style('opacity', 1)]; }; ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) { @@ -10142,10 +10154,10 @@ y0 = y(values[0].value); } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } - return path ? path : "M 0 0"; + return path ? path : 'M 0 0'; }; }; @@ -10185,7 +10197,7 @@ prev = -1, i, j, - s = "M", + s = 'M', sWithRegion, xp, yp, @@ -10280,7 +10292,7 @@ for (i = 0; i < d.length; i++) { // Draw as normal if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) { - s += " " + xValue(d[i]) + " " + yValue(d[i]); + s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]); } // Draw with region // TODO: Fix for horizotal charts else { xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries()); @@ -10306,16 +10318,16 @@ var $$ = this, d3 = $$.d3; var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$)); - var mainAreaEnter = mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () { + var mainAreaEnter = mainArea.enter().append('path').attr('class', $$.classArea.bind($$)).style('fill', $$.color).style('opacity', function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); - $$.mainArea = mainAreaEnter.merge(mainArea).style("opacity", $$.orgAreaOpacity); + $$.mainArea = mainAreaEnter.merge(mainArea).style('opacity', $$.orgAreaOpacity); mainArea.exit().transition().duration(durationForExit).style('opacity', 0); }; ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) { - return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)]; + return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr('d', drawArea).style('fill', this.color).style('opacity', this.orgAreaOpacity)]; }; ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) { @@ -10360,10 +10372,10 @@ y0 = $$.getYScale(d.id)(values[0].value); } - path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0; + path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0; } - return path ? path : "M 0 0"; + return path ? path : 'M 0 0'; }; }; @@ -10403,15 +10415,15 @@ ChartInternal.prototype.updateCircle = function (cx, cy) { var $$ = this; var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterOrStanfordData.bind($$)); - var mainCircleEnter = mainCircle.enter().append("circle").attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '').attr("class", $$.classCircle.bind($$)).attr("cx", cx).attr("cy", cy).attr("r", $$.pointR.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color); - $$.mainCircle = mainCircleEnter.merge(mainCircle).style("opacity", $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)); - mainCircle.exit().style("opacity", 0); + var mainCircleEnter = mainCircle.enter().append('circle').attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '').attr('class', $$.classCircle.bind($$)).attr('cx', cx).attr('cy', cy).attr('r', $$.pointR.bind($$)).style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color); + $$.mainCircle = mainCircleEnter.merge(mainCircle).style('opacity', $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)); + mainCircle.exit().style('opacity', 0); }; ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) { var $$ = this, selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle); - return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr("cx", cx).attr("cy", cy)]; + return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color).attr('cx', cx).attr('cy', cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr('cx', cx).attr('cy', cy)]; }; ChartInternal.prototype.circleX = function (d) { @@ -10487,8 +10499,8 @@ var d3 = this.d3, mouse = d3.mouse(that), d3_this = d3.select(that), - cx = +d3_this.attr("cx"), - cy = +d3_this.attr("cy"); + cx = +d3_this.attr('cx'), + cy = +d3_this.attr('cy'); return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r; }; @@ -10660,18 +10672,18 @@ var $$ = this, d3 = $$.d3; // TODO: dynamically change brushY/brushX according to axis_rotated. - $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () { + $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on('brush', function () { var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { + if (event && event.type === 'zoom') { return; } $$.redrawForBrush(); - }).on("end", function () { + }).on('end', function () { var event = d3.event.sourceEvent; - if (event && event.type === "zoom") { + if (event && event.type === 'zoom') { return; } @@ -10745,20 +10757,20 @@ ChartInternal.prototype.initSubchart = function () { var $$ = this, config = $$.config, - context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')); // set style + context = $$.context = $$.svg.append('g').attr('transform', $$.getTranslate('context')); // set style context.style('visibility', 'visible'); // Define g for chart area - context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart); // Define g for bar chart area + context.append('g').attr('clip-path', $$.clipPathForSubchart).attr('class', CLASS.chart); // Define g for bar chart area - context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); // Define g for line chart area + context.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartBars); // Define g for line chart area - context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); // Add extent rect for Brush + context.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartLines); // Add extent rect for Brush - context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush); // ATTENTION: This must be called AFTER chart added + context.append('g').attr('clip-path', $$.clipPath).attr('class', CLASS.brush); // ATTENTION: This must be called AFTER chart added // Add Axis - $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis); + $$.axes.subx = context.append('g').attr('class', CLASS.axisX).attr('transform', $$.getTranslate('subx')).attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis); }; ChartInternal.prototype.initSubchartBrush = function () { @@ -10786,25 +10798,25 @@ contextBarEnter = contextBar.enter().append('g').style('opacity', 0); contextBarEnter.merge(contextBar).attr('class', classChartBar); // Bars for each data - contextBarEnter.append('g').attr("class", classBars); //-- Line --// + contextBarEnter.append('g').attr('class', classBars); //-- Line --// contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets); contextLineEnter = contextLine.enter().append('g').style('opacity', 0); contextLineEnter.merge(contextLine).attr('class', classChartLine); // Lines for each data - contextLineEnter.append("g").attr("class", classLines); // Area + contextLineEnter.append('g').attr('class', classLines); // Area - contextLineEnter.append("g").attr("class", classAreas); //-- Brush --// + contextLineEnter.append('g').attr('class', classAreas); //-- Brush --// - context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2); + context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? 'width' : 'height', config.axis_rotated ? $$.width2 : $$.height2); }; ChartInternal.prototype.updateBarForSubchart = function (durationForExit) { var $$ = this; var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$)); - var contextBarEnter = contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color); + var contextBarEnter = contextBar.enter().append('path').attr('class', $$.classBar.bind($$)).style('stroke', 'none').style('fill', $$.color); contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - $$.contextBar = contextBarEnter.merge(contextBar).style("opacity", $$.initialOpacity.bind($$)); + $$.contextBar = contextBarEnter.merge(contextBar).style('opacity', $$.initialOpacity.bind($$)); }; ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) { @@ -10816,27 +10828,27 @@ var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$)); var contextLineEnter = contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color); contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - $$.contextLine = contextLineEnter.merge(contextLine).style("opacity", $$.initialOpacity.bind($$)); + $$.contextLine = contextLineEnter.merge(contextLine).style('opacity', $$.initialOpacity.bind($$)); }; ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) { - (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1); + (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr('d', drawLineOnSub).style('opacity', 1); }; ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) { var $$ = this, d3 = $$.d3; var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$)); - var contextAreaEnter = contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () { + var contextAreaEnter = contextArea.enter().append('path').attr('class', $$.classArea.bind($$)).style('fill', $$.color).style('opacity', function () { $$.orgAreaOpacity = +d3.select(this).style('opacity'); return 0; }); contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove(); - $$.contextArea = contextAreaEnter.merge(contextArea).style("opacity", 0); + $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0); }; ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) { - (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity); + (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr('d', drawAreaOnSub).style('fill', this.color).style('opacity', this.orgAreaOpacity); }; ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) { @@ -10903,8 +10915,8 @@ } } - $$.context.attr("transform", $$.getTranslate('context')); - subXAxis.attr("transform", $$.getTranslate('subx')); + $$.context.attr('transform', $$.getTranslate('context')); + subXAxis.attr('transform', $$.getTranslate('subx')); }; ChartInternal.prototype.getDefaultSelection = function () { @@ -10928,7 +10940,7 @@ ChartInternal.prototype.initText = function () { var $$ = this; - $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts); + $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.chartTexts); $$.mainText = $$.d3.selectAll([]); }; @@ -10938,7 +10950,7 @@ classTexts = $$.classTexts.bind($$), classFocus = $$.classFocus.bind($$); var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets); - var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none"); + var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style('pointer-events', 'none'); mainTextEnter.append('g').attr('class', classTexts); mainTextEnter.merge(mainText).attr('class', function (d) { return classChartText(d) + classFocus(d); @@ -10951,11 +10963,11 @@ barOrLineData = $$.barOrLineData.bind($$), classText = $$.classText.bind($$); var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData); - var mainTextEnter = mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) { + var mainTextEnter = mainText.enter().append('text').attr('class', classText).attr('text-anchor', function (d) { return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle'; - }).style("stroke", 'none').attr('x', xForText).attr('y', yForText).style("fill", function (d) { + }).style('stroke', 'none').attr('x', xForText).attr('y', yForText).style('fill', function (d) { return $$.color(d); - }).style("fill-opacity", 0); + }).style('fill-opacity', 0); $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) { return $$.dataLabelFormat(d.id)(d.value, d.id, i, j); }); @@ -10963,15 +10975,15 @@ }; ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) { - return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style("fill", this.color).style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))]; + return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style('fill', this.color).style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))]; }; ChartInternal.prototype.getTextRect = function (text, cls, element) { var dummy = this.d3.select('body').append('div').classed('c3', true), - svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), + svg = dummy.append('svg').style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), font = this.d3.select(element).style('font'), rect; - svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () { + svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : '', true).style('font', font).text(text).each(function () { rect = getBBox(this); }); dummy.remove(); @@ -11052,12 +11064,12 @@ ChartInternal.prototype.initTitle = function () { var $$ = this; - $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title); + $$.title = $$.svg.append('text').text($$.config.title_text).attr('class', $$.CLASS.title); }; ChartInternal.prototype.redrawTitle = function () { var $$ = this; - $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$)); + $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$)); }; ChartInternal.prototype.xForTitle = function () { @@ -11120,7 +11132,7 @@ $$.colorScale.remove(); } - $$.colorScale = $$.svg.append("g").attr('width', 50).attr('height', height).attr('class', CLASS.colorScale); + $$.colorScale = $$.svg.append('g').attr('width', 50).attr('height', height).attr('class', CLASS.colorScale); $$.colorScale.append('g').attr('transform', "translate(0, ".concat(config.stanford_padding.top, ")")).selectAll('bars').data(points).enter().append('rect').attr('y', function (d, i) { return i * barHeight; }).attr('x', 0).attr('width', barWidth).attr('height', barHeight).attr('fill', function (d) { @@ -11135,7 +11147,7 @@ } else if (isFunction(config.stanford_scaleFormat)) { legendAxis.tickFormat(config.stanford_scaleFormat); } else { - legendAxis.tickFormat(d3.format("d")); + legendAxis.tickFormat(d3.format('d')); } if (isFunction(config.stanford_scaleValues)) { @@ -11143,10 +11155,10 @@ } // Draw Axis - axis = $$.colorScale.append("g").attr("class", "legend axis").attr("transform", "translate(".concat(barWidth, ",0)")).call(legendAxis); + axis = $$.colorScale.append('g').attr('class', 'legend axis').attr('transform', "translate(".concat(barWidth, ",0)")).call(legendAxis); if (config.stanford_scaleFormat === 'pow10') { - axis.selectAll(".tick text").text(null).filter(powerOfTen).text(10).append("tspan").attr("dy", "-.7em") // https://bl.ocks.org/mbostock/6738229 + axis.selectAll('.tick text').text(null).filter(powerOfTen).text(10).append('tspan').attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229 .text(function (d) { return Math.round(Math.log(d) / Math.LN10); }); @@ -11188,7 +11200,7 @@ maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs); if (minEpochs > maxEpochs) { - throw Error("Number of minEpochs has to be smaller than maxEpochs"); + throw Error('Number of minEpochs has to be smaller than maxEpochs'); } target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)); @@ -11233,7 +11245,7 @@ var $$ = this, labelX = $$.axis.getLabelText('x'), labelY = $$.axis.getLabelText('y'); - return "\n ".concat(labelX ? sanitise(labelX) : "x", "").concat(d.x, "\n ").concat(labelY ? sanitise(labelY) : "y", "").concat(d.value, "\n "); + return "\n ".concat(labelX ? sanitise(labelX) : 'x', "").concat(d.x, "\n ").concat(labelY ? sanitise(labelY) : 'y', "").concat(d.value, "\n "); }; ChartInternal.prototype.countEpochsInRegion = function (region) { @@ -11339,81 +11351,81 @@ stanfordLine = main.select('.' + CLASS.stanfordLines).style('shape-rendering', 'geometricprecision').selectAll('.' + CLASS.stanfordLine).data(config.stanford_lines); // enter - stanfordLineEnter = stanfordLine.enter().append('g').attr("class", function (d) { + stanfordLineEnter = stanfordLine.enter().append('g').attr('class', function (d) { return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordLineEnter.append('line').attr("x1", function (d) { + stanfordLineEnter.append('line').attr('x1', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1'); - }).attr("x2", function (d) { + }).attr('x2', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2'); - }).attr("y1", function (d) { + }).attr('y1', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1'); - }).attr("y2", function (d) { + }).attr('y2', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2'); - }).style("opacity", 0); // update + }).style('opacity', 0); // update $$.stanfordLines = stanfordLineEnter.merge(stanfordLine); - $$.stanfordLines.select('line').transition().duration(duration).attr("x1", function (d) { + $$.stanfordLines.select('line').transition().duration(duration).attr('x1', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1'); - }).attr("x2", function (d) { + }).attr('x2', function (d) { return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2'); - }).attr("y1", function (d) { + }).attr('y1', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1'); - }).attr("y2", function (d) { + }).attr('y2', function (d) { return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2'); - }).style("opacity", 1); // exit + }).style('opacity', 1); // exit - stanfordLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Text + stanfordLine.exit().transition().duration(duration).style('opacity', 0).remove(); // Stanford-Text stanfordText = main.select('.' + CLASS.stanfordTexts).selectAll('.' + CLASS.stanfordText).data(config.stanford_texts); // enter - stanfordTextEnter = stanfordText.enter().append('g').attr("class", function (d) { + stanfordTextEnter = stanfordText.enter().append('g').attr('class', function (d) { return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordTextEnter.append('text').attr("x", function (d) { + stanfordTextEnter.append('text').attr('x', function (d) { return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'); - }).attr("y", function (d) { + }).attr('y', function (d) { return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'); - }).style("opacity", 0); // update + }).style('opacity', 0); // update $$.stanfordTexts = stanfordTextEnter.merge(stanfordText); - $$.stanfordTexts.select('text').transition().duration(duration).attr("x", function (d) { + $$.stanfordTexts.select('text').transition().duration(duration).attr('x', function (d) { return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x'); - }).attr("y", function (d) { + }).attr('y', function (d) { return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y'); }).text(function (d) { return d.content; - }).style("opacity", 1); // exit + }).style('opacity', 1); // exit - stanfordText.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Regions + stanfordText.exit().transition().duration(duration).style('opacity', 0).remove(); // Stanford-Regions stanfordRegion = main.select('.' + CLASS.stanfordRegions).selectAll('.' + CLASS.stanfordRegion).data(config.stanford_regions); // enter - stanfordRegionEnter = stanfordRegion.enter().append('g').attr("class", function (d) { + stanfordRegionEnter = stanfordRegion.enter().append('g').attr('class', function (d) { return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : ''); }); - stanfordRegionEnter.append('polygon').attr("points", function (d) { + stanfordRegionEnter.append('polygon').attr('points', function (d) { return d.points.map(function (value) { - return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(","); - }).join(" "); - }).style("opacity", 0); - stanfordRegionEnter.append('text').attr("x", function (d) { + return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(','); + }).join(' '); + }).style('opacity', 0); + stanfordRegionEnter.append('text').attr('x', function (d) { return $$.getCentroid(d.points).x; - }).attr("y", function (d) { + }).attr('y', function (d) { return $$.getCentroid(d.points).y; - }).style("opacity", 0); // update + }).style('opacity', 0); // update $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion); - $$.stanfordRegions.select('polygon').transition().duration(duration).attr("points", function (d) { + $$.stanfordRegions.select('polygon').transition().duration(duration).attr('points', function (d) { return d.points.map(function (value) { - return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(","); - }).join(" "); - }).style("opacity", function (d) { + return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(','); + }).join(' '); + }).style('opacity', function (d) { return d.opacity ? d.opacity : 0.2; }); - $$.stanfordRegions.select('text').transition().duration(duration).attr("x", function (d) { + $$.stanfordRegions.select('text').transition().duration(duration).attr('x', function (d) { return config.axis_rotated ? yvCustom($$.getCentroid(d.points), 'y') : xvCustom($$.getCentroid(d.points), 'x'); - }).attr("y", function (d) { + }).attr('y', function (d) { return config.axis_rotated ? xvCustom($$.getCentroid(d.points), 'x') : yvCustom($$.getCentroid(d.points), 'y'); }).text(function (d) { if (d.text) { @@ -11428,17 +11440,17 @@ return d.text(value, percentage); } - return ""; - }).attr("text-anchor", "middle").attr("dominant-baseline", "middle").style("opacity", 1); // exit + return ''; + }).attr('text-anchor', 'middle').attr('dominant-baseline', 'middle').style('opacity', 1); // exit - stanfordRegion.exit().transition().duration(duration).style("opacity", 0).remove(); + stanfordRegion.exit().transition().duration(duration).style('opacity', 0).remove(); }; ChartInternal.prototype.initTooltip = function () { var $$ = this, config = $$.config, i; - $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none"); // Show tooltip if needed + $$.tooltip = $$.selectChart.style('position', 'relative').append('div').attr('class', CLASS.tooltipContainer).style('position', 'absolute').style('pointer-events', 'none').style('display', 'none'); // Show tooltip if needed if (config.tooltip_init_show) { if ($$.isTimeSeries() && isString(config.tooltip_init_x)) { @@ -11456,7 +11468,7 @@ $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) { return $$.addName(d.values[config.tooltip_init_x]); }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color)); - $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block"); + $$.tooltip.style('top', config.tooltip_init_position.top).style('left', config.tooltip_init_position.left).style('display', 'block'); } }; @@ -11575,7 +11587,7 @@ // Regular tooltip if (!text) { title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x); - text = "" + (title || title === 0 ? "" : ""); + text = "
" + title + "
" + (title || title === 0 ? "' : ''); } value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)); @@ -11592,14 +11604,14 @@ } if (value !== undefined) { - text += ""; - text += ""; - text += ""; - text += ""; + text += ""; + text += "'; + text += "'; + text += ''; } } - return text + "
" + title + '
" + name + "" + value + "
" + name + '" + value + '
"; + return text + ''; }; ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) { @@ -11662,17 +11674,17 @@ return; } - $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); // Get tooltip dimensions + $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style('display', 'block'); // Get tooltip dimensions tWidth = $$.tooltip.property('offsetWidth'); tHeight = $$.tooltip.property('offsetHeight'); position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); // Set tooltip - $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px'); + $$.tooltip.style('top', position.top + 'px').style('left', position.left + 'px'); }; ChartInternal.prototype.hideTooltip = function () { - this.tooltip.style("display", "none"); + this.tooltip.style('display', 'none'); }; ChartInternal.prototype.setTargetType = function (targetIds, type) { @@ -11815,27 +11827,27 @@ d3 = $$.d3, config = $$.config, startEvent; - $$.zoom = d3.zoom().on("start", function () { + $$.zoom = d3.zoom().on('start', function () { if (config.zoom_type !== 'scroll') { return; } var e = d3.event.sourceEvent; - if (e && e.type === "brush") { + if (e && e.type === 'brush') { return; } startEvent = e; config.zoom_onzoomstart.call($$.api, e); - }).on("zoom", function () { + }).on('zoom', function () { if (config.zoom_type !== 'scroll') { return; } var e = d3.event.sourceEvent; - if (e && e.type === "brush") { + if (e && e.type === 'brush') { return; } @@ -11848,7 +11860,7 @@ var e = d3.event.sourceEvent; - if (e && e.type === "brush") { + if (e && e.type === 'brush') { return; } // if click, do nothing. otherwise, click interaction will be canceled. @@ -11904,13 +11916,13 @@ }); }; - var brush = $$.dragZoomBrush = d3.brushX().on("start", function () { + var brush = $$.dragZoomBrush = d3.brushX().on('start', function () { $$.api.unzoom(); - $$.svg.select("." + CLASS.dragZoom).classed("disabled", false); + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false); config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); - }).on("brush", function () { + }).on('brush', function () { config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection)); - }).on("end", function () { + }).on('end', function () { if (d3.event.selection == null) { return; } @@ -11921,10 +11933,10 @@ $$.api.zoom(zoomedDomain); } - $$.svg.select("." + CLASS.dragZoom).classed("disabled", true); + $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true); config.zoom_onzoomend.call($$.api, zoomedDomain); }); - context.append("g").classed(CLASS.dragZoom, true).attr("clip-path", $$.clipPath).attr("transform", "translate(" + brushXPos + "," + brushYPos + ")").call(brush); + context.append('g').classed(CLASS.dragZoom, true).attr('clip-path', $$.clipPath).attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')').call(brush); }; ChartInternal.prototype.getZoomDomain = function () { diff --git a/docs/js/c3.min.js b/docs/js/c3.min.js index ed9aca193..a971317ac 100644 --- a/docs/js/c3.min.js +++ b/docs/js/c3.min.js @@ -1,2 +1,2 @@ -/* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).c3=e()}(this,function(){"use strict";function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t){return function(t){if(Array.isArray(t)){for(var e=0,i=new Array(t.length);e/g,">"):t}function g(t){var e=function(t){void 0===t&&(t=window.navigator.userAgent);var e=t.indexOf("MSIE ");return 0e.getTotalLength())break;i--}while(0=this.numberOfItems)throw"INDEX_SIZE_ERR"},window.SVGPathSegList.prototype.getItem=function(t){return this._checkPathSynchronizedToList(),this._checkValidIndex(t),this._list[t]},window.SVGPathSegList.prototype.insertItemBefore=function(t,e){return this._checkPathSynchronizedToList(),e>this.numberOfItems&&(e=this.numberOfItems),t._owningPathSegList&&(t=t.clone()),this._list.splice(e,0,t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.replaceItem=function(t,e){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._checkValidIndex(e),((this._list[e]=t)._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.removeItem=function(t){this._checkPathSynchronizedToList(),this._checkValidIndex(t);var e=this._list[t];return this._list.splice(t,1),this._writeListToPath(),e},window.SVGPathSegList.prototype.appendItem=function(t){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._list.push(t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList._pathSegArrayAsString=function(t){var e="",i=!0;return t.forEach(function(t){i?(i=!1,e+=t._asPathString()):e+=" "+t._asPathString()}),e},window.SVGPathSegList.prototype._parsePath=function(t){if(!t||0==t.length)return[];function e(){this.pathSegList=[]}var n=this;e.prototype.appendSegment=function(t){this.pathSegList.push(t)};function i(t){this._string=t,this._currentIndex=0,this._endIndex=this._string.length,this._previousCommand=window.SVGPathSeg.PATHSEG_UNKNOWN,this._skipOptionalSpaces()}i.prototype._isCurrentSpace=function(){var t=this._string[this._currentIndex];return t<=" "&&(" "==t||"\n"==t||"\t"==t||"\r"==t||"\f"==t)},i.prototype._skipOptionalSpaces=function(){for(;this._currentIndex=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex)){var t=!1,e=this._string.charAt(this._currentIndex++);if("0"==e)t=!1;else{if("1"!=e)return;t=!0}return this._skipOptionalSpacesOrDelimiter(),t}},i.prototype.parseSegment=function(){var t=this._string[this._currentIndex],e=this._pathSegTypeFromChar(t);if(e==window.SVGPathSeg.PATHSEG_UNKNOWN){if(this._previousCommand==window.SVGPathSeg.PATHSEG_UNKNOWN)return null;if((e=this._nextCommandHelper(t,this._previousCommand))==window.SVGPathSeg.PATHSEG_UNKNOWN)return null}else this._currentIndex++;switch(this._previousCommand=e){case window.SVGPathSeg.PATHSEG_MOVETO_REL:return new window.SVGPathSegMovetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_MOVETO_ABS:return new window.SVGPathSegMovetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_REL:return new window.SVGPathSegLinetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_ABS:return new window.SVGPathSegLinetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:return new window.SVGPathSegLinetoHorizontalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:return new window.SVGPathSegLinetoHorizontalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:return new window.SVGPathSegLinetoVerticalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:return new window.SVGPathSegLinetoVerticalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_CLOSEPATH:return this._skipOptionalSpaces(),new window.SVGPathSegClosePath(n);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:var i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicRel(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicAbs(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothRel(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothAbs(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticRel(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticAbs(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:return new window.SVGPathSegCurvetoQuadraticSmoothRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:return new window.SVGPathSegCurvetoQuadraticSmoothAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_ARC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcRel(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);case window.SVGPathSeg.PATHSEG_ARC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcAbs(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);default:throw"Unknown path seg type."}};var r=new e,a=new i(t);if(!a.initialCommandIsMoveTo())return[];for(;a.hasMoreData();){var o=a.parseSegment();if(!o)return[];r.appendSegment(o)}return r.pathSegList}),String.prototype.padEnd||(String.prototype.padEnd=function(t,e){return t>>=0,e=String(void 0!==e?e:" "),this.length>t?String(this):((t-=this.length)>e.length&&(e+=e.repeat(t/e.length)),String(this)+e.slice(0,t))}),"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(t,e){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),n=1;n'":;\[\]\/|~`{}\\])/g,"\\$1")},l.prototype.selectorTarget=function(t,e){return(e||"")+"."+Y.target+this.getTargetSelectorSuffix(t)},l.prototype.selectorTargets=function(t,e){var i=this;return(t=t||[]).length?t.map(function(t){return i.selectorTarget(t,e)}):null},l.prototype.selectorLegend=function(t){return"."+Y.legendItem+this.getTargetSelectorSuffix(t)},l.prototype.selectorLegends=function(t){var e=this;return t&&t.length?t.map(function(t){return e.selectorLegend(t)}):null},l.prototype.getClipPath=function(t){return"url("+(g(9)?"":document.URL.split("#")[0])+"#"+t+")"},l.prototype.appendClip=function(t,e){return t.append("clipPath").attr("id",e).append("rect")},l.prototype.getAxisClipX=function(t){var e=Math.max(30,this.margin.left);return t?-(1+e):-(e-1)},l.prototype.getAxisClipY=function(t){return t?-20:-this.margin.top},l.prototype.getXAxisClipX=function(){return this.getAxisClipX(!this.config.axis_rotated)},l.prototype.getXAxisClipY=function(){return this.getAxisClipY(!this.config.axis_rotated)},l.prototype.getYAxisClipX=function(){return this.config.axis_y_inner?-1:this.getAxisClipX(this.config.axis_rotated)},l.prototype.getYAxisClipY=function(){return this.getAxisClipY(this.config.axis_rotated)},l.prototype.getAxisClipWidth=function(t){var e=Math.max(30,this.margin.left),i=Math.max(30,this.margin.right);return t?this.width+2+e+i:this.margin.left+20},l.prototype.getAxisClipHeight=function(t){return(t?this.margin.bottom:this.margin.top+this.height)+20},l.prototype.getXAxisClipWidth=function(){return this.getAxisClipWidth(!this.config.axis_rotated)},l.prototype.getXAxisClipHeight=function(){return this.getAxisClipHeight(!this.config.axis_rotated)},l.prototype.getYAxisClipWidth=function(){return this.getAxisClipWidth(this.config.axis_rotated)+(this.config.axis_y_inner?20:0)},l.prototype.getYAxisClipHeight=function(){return this.getAxisClipHeight(this.config.axis_rotated)},l.prototype.generateColor=function(){var t=this.config,e=this.d3,n=t.data_colors,r=L(t.color_pattern)?t.color_pattern:e.schemeCategory10,a=t.data_color,o=[];return function(t){var e,i=t.id||t.data&&t.data.id||t;return n[i]instanceof Function?e=n[i](t):n[i]?e=n[i]:(o.indexOf(i)<0&&o.push(i),e=r[o.indexOf(i)%r.length],n[i]=e),a instanceof Function?a(e,t):e}},l.prototype.generateLevelColor=function(){var t=this.config,n=t.color_pattern,e=t.color_threshold,r="value"===e.unit,a=e.values&&e.values.length?e.values:[],o=e.max||100;return L(e)&&L(n)?function(t){var e,i=n[n.length-1];for(e=0;es&&(o=o.filter(function(t){return(""+t).indexOf(".")<0}));return o},l.prototype.getGridFilterToRemove=function(t){return t?function(e){var i=!1;return[].concat(t).forEach(function(t){("value"in t&&e.value===t.value||"class"in t&&e.class===t.class)&&(i=!0)}),i}:function(){return!0}},l.prototype.removeGridLines=function(t,e){function i(t){return!r(t)}var n=this.config,r=this.getGridFilterToRemove(t),a=e?Y.xgridLines:Y.ygridLines,o=e?Y.xgridLine:Y.ygridLine;this.main.select("."+a).selectAll("."+o).filter(r).transition().duration(n.transition_duration).style("opacity",0).remove(),e?n.grid_x_lines=n.grid_x_lines.filter(i):n.grid_y_lines=n.grid_y_lines.filter(i)},l.prototype.initEventRect=function(){var t=this,e=t.config;t.main.select("."+Y.chart).append("g").attr("class",Y.eventRects).style("fill-opacity",0),t.eventRect=t.main.select("."+Y.eventRects).append("rect").attr("class",Y.eventRect),e.zoom_enabled&&t.zoom&&(t.eventRect.call(t.zoom).on("dblclick.zoom",null),e.zoom_initialRange&&t.eventRect.transition().duration(0).call(t.zoom.transform,t.zoomTransform(e.zoom_initialRange)))},l.prototype.redrawEventRect=function(){var s=this,c=s.d3,d=s.config;function l(){s.svg.select("."+Y.eventRect).style("cursor",null),s.hideXGridFocus(),s.hideTooltip(),s.unexpandCircles(),s.unexpandBars()}function u(t,e){return e&&(s.isBarType(e.id)||s.dist(e,t)i.bar_width_max?i.bar_width_max:n},l.prototype.getBars=function(t,e){return(e?this.main.selectAll("."+Y.bars+this.getTargetSelectorSuffix(e)):this.main).selectAll("."+Y.bar+(C(t)?"-"+t:""))},l.prototype.expandBars=function(t,e,i){i&&this.unexpandBars(),this.getBars(t,e).classed(Y.EXPANDED,!0)},l.prototype.unexpandBars=function(t){this.getBars(t).classed(Y.EXPANDED,!1)},l.prototype.generateDrawBar=function(t,e){var a=this.config,o=this.generateGetBarPoints(t,e);return function(t,e){var i=o(t,e),n=a.axis_rotated?1:0,r=a.axis_rotated?0:1;return"M "+i[0][n]+","+i[0][r]+" L"+i[1][n]+","+i[1][r]+" L"+i[2][n]+","+i[2][r]+" L"+i[3][n]+","+i[3][r]+" z"}},l.prototype.generateGetBarPoints=function(t,e){var o=this,i=e?o.subXAxis:o.xAxis,n=t.__max__+1,s=o.getBarW(i,n),c=o.getShapeX(s,n,t,!!e),d=o.getShapeY(!!e),l=o.getShapeOffset(o.isBarType,t,!!e),u=s*(o.config.bar_space/2),h=e?o.getSubYScale:o.getYScale;return function(t,e){var i=h.call(o,t.id)(0),n=l(t,e)||i,r=c(t),a=d(t);return o.config.axis_rotated&&(0a.width?n=a.width-o.width:n<0&&(n=4)),n},l.prototype.getYForText=function(t,e,i){var n,r=this,a=p(i);return r.config.axis_rotated?n=(t[0][0]+t[2][0]+.6*a.height)/2:(n=t[2][1],e.value<0||0===e.value&&!r.hasPositiveValue?(n+=a.height,r.isBarType(e)&&r.isSafari()?n-=3:!r.isBarType(e)&&r.isChrome()&&(n+=3)):n+=r.isBarType(e)?-3:-6),null!==e.value||r.config.axis_rotated||(nthis.height&&(n=this.height-4)),n},l.prototype.initTitle=function(){this.title=this.svg.append("text").text(this.config.title_text).attr("class",this.CLASS.title)},l.prototype.redrawTitle=function(){var t=this;t.title.attr("x",t.xForTitle.bind(t)).attr("y",t.yForTitle.bind(t))},l.prototype.xForTitle=function(){var t=this,e=t.config,i=e.title_position||"left";return 0<=i.indexOf("right")?t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width-e.title_padding.right:0<=i.indexOf("center")?Math.max((t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width)/2,0):e.title_padding.left},l.prototype.yForTitle=function(){var t=this;return t.config.title_padding.top+t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).height},l.prototype.getTitlePadding=function(){return this.yForTitle()+this.config.title_padding.bottom},l.prototype.drawColorScale=function(){var t,e,i,n,r,a,o,s=this,c=s.d3,d=s.config,l=s.data.targets[0];if(t=isNaN(d.stanford_scaleWidth)?20:d.stanford_scaleWidth,t<0)throw Error("Colorscale's barheight and barwidth must be greater than 0.");o=s.height-d.stanford_padding.bottom-d.stanford_padding.top,i=c.range(d.stanford_padding.bottom,o,5),a=c.scaleSequential(l.colors).domain([i[i.length-1],i[0]]),s.colorScale&&s.colorScale.remove(),s.colorScale=s.svg.append("g").attr("width",50).attr("height",o).attr("class",Y.colorScale),s.colorScale.append("g").attr("transform","translate(0, ".concat(d.stanford_padding.top,")")).selectAll("bars").data(i).enter().append("rect").attr("y",function(t,e){return 5*e}).attr("x",0).attr("width",t).attr("height",5).attr("fill",function(t){return a(t)}),r=c.scaleLog().domain([l.minEpochs,l.maxEpochs]).range([i[0]+d.stanford_padding.top+i[i.length-1]+5-1,i[0]+d.stanford_padding.top]),n=c.axisRight(r),"pow10"===d.stanford_scaleFormat?n.tickValues([1,10,100,1e3,1e4,1e5,1e6,1e7]):h(d.stanford_scaleFormat)?n.tickFormat(d.stanford_scaleFormat):n.tickFormat(c.format("d")),h(d.stanford_scaleValues)&&n.tickValues(d.stanford_scaleValues(l.minEpochs,l.maxEpochs)),e=s.colorScale.append("g").attr("class","legend axis").attr("transform","translate(".concat(t,",0)")).call(n),"pow10"===d.stanford_scaleFormat&&e.selectAll(".tick text").text(null).filter(S).text(10).append("tspan").attr("dy","-.7em").text(function(t){return Math.round(Math.log(t)/Math.LN10)}),s.colorScale.attr("transform","translate(".concat(s.currentWidth-s.xForColorScale(),", 0)"))},l.prototype.xForColorScale=function(){return this.config.stanford_padding.right+p(this.colorScale.node()).width},l.prototype.getColorScalePadding=function(){return this.xForColorScale()+this.config.stanford_padding.left+20},l.prototype.isStanfordGraphType=function(){return"stanford"===this.config.data_type},l.prototype.initStanfordData=function(){var t,e,i,n=this.d3,r=this.config,a=this.data.targets[0];if(a.values.sort(T),t=a.values.map(function(t){return t.epochs}),i=isNaN(r.stanford_scaleMin)?n.min(t):r.stanford_scaleMin,(e=isNaN(r.stanford_scaleMax)?n.max(t):r.stanford_scaleMax)".concat(e?_(e):"x","").concat(t.x,"\n ").concat(i?_(i):"y","").concat(t.value,"\n ")},l.prototype.countEpochsInRegion=function(i){var t,e,n=this.data.targets[0];return t=n.values.reduce(function(t,e){return t+Number(e.epochs)},0),{value:e=n.values.reduce(function(t,e){return b(e,i)?t+Number(e.epochs):t},0),percentage:0!==e?(e/t*100).toFixed(1):0}};var w=function(t){var e,i,n,r,a=0;for(e=0,i=t.length-1;ee.epochs?1:0};return l.prototype.initStanfordElements=function(){var t=this;t.stanfordElements=t.main.select("."+Y.chart).append("g").attr("class",Y.stanfordElements),t.stanfordElements.append("g").attr("class",Y.stanfordLines),t.stanfordElements.append("g").attr("class",Y.stanfordTexts),t.stanfordElements.append("g").attr("class",Y.stanfordRegions)},l.prototype.updateStanfordElements=function(t){var e,i,n,r,a,o,s=this,c=s.main,d=s.config,l=s.xvCustom.bind(s),u=s.yvCustom.bind(s),h=s.countEpochsInRegion.bind(s);(i=(e=c.select("."+Y.stanfordLines).style("shape-rendering","geometricprecision").selectAll("."+Y.stanfordLine).data(d.stanford_lines)).enter().append("g").attr("class",function(t){return Y.stanfordLine+(t.class?" "+t.class:"")})).append("line").attr("x1",function(t){return d.axis_rotated?u(t,"value_y1"):l(t,"value_x1")}).attr("x2",function(t){return d.axis_rotated?u(t,"value_y2"):l(t,"value_x2")}).attr("y1",function(t){return d.axis_rotated?l(t,"value_x1"):u(t,"value_y1")}).attr("y2",function(t){return d.axis_rotated?l(t,"value_x2"):u(t,"value_y2")}).style("opacity",0),s.stanfordLines=i.merge(e),s.stanfordLines.select("line").transition().duration(t).attr("x1",function(t){return d.axis_rotated?u(t,"value_y1"):l(t,"value_x1")}).attr("x2",function(t){return d.axis_rotated?u(t,"value_y2"):l(t,"value_x2")}).attr("y1",function(t){return d.axis_rotated?l(t,"value_x1"):u(t,"value_y1")}).attr("y2",function(t){return d.axis_rotated?l(t,"value_x2"):u(t,"value_y2")}).style("opacity",1),e.exit().transition().duration(t).style("opacity",0).remove(),(o=(a=c.select("."+Y.stanfordTexts).selectAll("."+Y.stanfordText).data(d.stanford_texts)).enter().append("g").attr("class",function(t){return Y.stanfordText+(t.class?" "+t.class:"")})).append("text").attr("x",function(t){return d.axis_rotated?u(t,"y"):l(t,"x")}).attr("y",function(t){return d.axis_rotated?l(t,"x"):u(t,"y")}).style("opacity",0),s.stanfordTexts=o.merge(a),s.stanfordTexts.select("text").transition().duration(t).attr("x",function(t){return d.axis_rotated?u(t,"y"):l(t,"x")}).attr("y",function(t){return d.axis_rotated?l(t,"x"):u(t,"y")}).text(function(t){return t.content}).style("opacity",1),a.exit().transition().duration(t).style("opacity",0).remove(),(r=(n=c.select("."+Y.stanfordRegions).selectAll("."+Y.stanfordRegion).data(d.stanford_regions)).enter().append("g").attr("class",function(t){return Y.stanfordRegion+(t.class?" "+t.class:"")})).append("polygon").attr("points",function(t){return t.points.map(function(t){return[d.axis_rotated?u(t,"y"):l(t,"x"),d.axis_rotated?l(t,"x"):u(t,"y")].join(",")}).join(" ")}).style("opacity",0),r.append("text").attr("x",function(t){return s.getCentroid(t.points).x}).attr("y",function(t){return s.getCentroid(t.points).y}).style("opacity",0),s.stanfordRegions=r.merge(n),s.stanfordRegions.select("polygon").transition().duration(t).attr("points",function(t){return t.points.map(function(t){return[d.axis_rotated?u(t,"y"):l(t,"x"),d.axis_rotated?l(t,"x"):u(t,"y")].join(",")}).join(" ")}).style("opacity",function(t){return t.opacity?t.opacity:.2}),s.stanfordRegions.select("text").transition().duration(t).attr("x",function(t){return d.axis_rotated?u(s.getCentroid(t.points),"y"):l(s.getCentroid(t.points),"x")}).attr("y",function(t){return d.axis_rotated?l(s.getCentroid(t.points),"x"):u(s.getCentroid(t.points),"y")}).text(function(t){var e,i,n;return t.text?(s.isStanfordGraphType()&&(e=(n=h(t.points)).value,i=n.percentage),t.text(e,i)):""}).attr("text-anchor","middle").attr("dominant-baseline","middle").style("opacity",1),n.exit().transition().duration(t).style("opacity",0).remove()},l.prototype.initTooltip=function(){var t,e=this,i=e.config;if(e.tooltip=e.selectChart.style("position","relative").append("div").attr("class",Y.tooltipContainer).style("position","absolute").style("pointer-events","none").style("display","none"),i.tooltip_init_show){if(e.isTimeSeries()&&f(i.tooltip_init_x)){for(i.tooltip_init_x=e.parseDate(i.tooltip_init_x),t=0;t"+o),d=l.getStanfordPointColor(t[a]),c=_(u.data_epochs),s=t[a].epochs;else if(r||(o=_(h?h(t[a].x,t[a].index):t[a].x),r=""+(o||0===o?"":"")),void 0!==(s=_(p(t[a].value,t[a].ratio,t[a].id,t[a].index,t)))){if(null===t[a].name)continue;c=_(g(t[a].name,t[a].ratio,t[a].id,t[a].index)),d=l.levelColor?l.levelColor(t[a].value):n(t[a].id)}void 0!==s&&(r+="",r+="",r+="",r+="")}return r+"
"+o+"
"+c+""+s+"
"},l.prototype.tooltipPosition=function(t,e,i,n){var r,a,o,s,c,d=this,l=d.config,u=d.d3,h=d.hasArcType(),g=u.mouse(n);return h?(a=(d.width-(d.isLegendRight?d.getLegendWidth():0))/2+g[0],s=(d.hasType("gauge")?d.height:d.height/2)+g[1]+20):(r=d.getSvgLeft(!0),s=l.axis_rotated?(o=(a=r+g[0]+100)+e,c=d.currentWidth-d.getCurrentPaddingRight(),d.x(t[0].x)+20):(o=(a=r+d.getCurrentPaddingLeft(!0)+d.x(t[0].x)+20)+e,c=r+d.currentWidth-d.getCurrentPaddingRight(),g[1]+15),cd.currentHeight&&(s-=i+30)),s<0&&(s=0),{top:s,left:a}},l.prototype.showTooltip=function(t,e){var i,n,r,a=this,o=a.config,s=a.hasArcType(),c=t.filter(function(t){return t&&C(t.value)}),d=o.tooltip_position||l.prototype.tooltipPosition;0!==c.length&&o.tooltip_show&&(a.tooltip.html(o.tooltip_contents.call(a,t,a.axis.getXAxisTickFormat(),a.getYFormat(s),a.color)).style("display","block"),i=a.tooltip.property("offsetWidth"),n=a.tooltip.property("offsetHeight"),r=d.call(this,c,i,n,e),a.tooltip.style("top",r.top+"px").style("left",r.left+"px"))},l.prototype.hideTooltip=function(){this.tooltip.style("display","none")},l.prototype.setTargetType=function(t,e){var i=this,n=i.config;i.mapToTargetIds(t).forEach(function(t){i.withoutFadeIn[t]=e===n.data_types[t],n.data_types[t]=e}),t||(n.data_type=e)},l.prototype.hasType=function(i,t){var n=this.config.data_types,r=!1;return(t=t||this.data.targets)&&t.length?t.forEach(function(t){var e=n[t.id];(e&&0<=e.indexOf(i)||!e&&"line"===i)&&(r=!0)}):Object.keys(n).length?Object.keys(n).forEach(function(t){n[t]===i&&(r=!0)}):r=this.config.data_type===i,r},l.prototype.hasArcType=function(t){return this.hasType("pie",t)||this.hasType("donut",t)||this.hasType("gauge",t)},l.prototype.isLineType=function(t){var e=this.config,i=f(t)?t:t.id;return!e.data_types[i]||0<=["line","spline","area","area-spline","step","area-step"].indexOf(e.data_types[i])},l.prototype.isStepType=function(t){var e=f(t)?t:t.id;return 0<=["step","area-step"].indexOf(this.config.data_types[e])},l.prototype.isSplineType=function(t){var e=f(t)?t:t.id;return 0<=["spline","area-spline"].indexOf(this.config.data_types[e])},l.prototype.isAreaType=function(t){var e=f(t)?t:t.id;return 0<=["area","area-spline","area-step"].indexOf(this.config.data_types[e])},l.prototype.isBarType=function(t){var e=f(t)?t:t.id;return"bar"===this.config.data_types[e]},l.prototype.isScatterType=function(t){var e=f(t)?t:t.id;return"scatter"===this.config.data_types[e]},l.prototype.isStanfordType=function(t){var e=f(t)?t:t.id;return"stanford"===this.config.data_types[e]},l.prototype.isPieType=function(t){var e=f(t)?t:t.id;return"pie"===this.config.data_types[e]},l.prototype.isGaugeType=function(t){var e=f(t)?t:t.id;return"gauge"===this.config.data_types[e]},l.prototype.isDonutType=function(t){var e=f(t)?t:t.id;return"donut"===this.config.data_types[e]},l.prototype.isArcType=function(t){return this.isPieType(t)||this.isDonutType(t)||this.isGaugeType(t)},l.prototype.lineData=function(t){return this.isLineType(t)?[t]:[]},l.prototype.arcData=function(t){return this.isArcType(t.data)?[t]:[]},l.prototype.barData=function(t){return this.isBarType(t)?t.values:[]},l.prototype.lineOrScatterOrStanfordData=function(t){return this.isLineType(t)||this.isScatterType(t)||this.isStanfordType(t)?t.values:[]},l.prototype.barOrLineData=function(t){return this.isBarType(t)||this.isLineType(t)?t.values:[]},l.prototype.isSafari=function(){var t=window.navigator.userAgent;return 0<=t.indexOf("Safari")&&t.indexOf("Chrome")<0},l.prototype.isChrome=function(){return 0<=window.navigator.userAgent.indexOf("Chrome")},l.prototype.initZoom=function(){var e,i=this,n=i.d3,r=i.config;return i.zoom=n.zoom().on("start",function(){if("scroll"===r.zoom_type){var t=n.event.sourceEvent;t&&"brush"===t.type||(e=t,r.zoom_onzoomstart.call(i.api,t))}}).on("zoom",function(){if("scroll"===r.zoom_type){var t=n.event.sourceEvent;t&&"brush"===t.type||(i.redrawForZoom(),r.zoom_onzoom.call(i.api,i.x.orgDomain()))}}).on("end",function(){if("scroll"===r.zoom_type){var t=n.event.sourceEvent;t&&"brush"===t.type||t&&e.clientX===t.clientX&&e.clientY===t.clientY||r.zoom_onzoomend.call(i.api,i.x.orgDomain())}}),i.zoom.updateDomain=function(){return n.event&&n.event.transform&&i.x.domain(n.event.transform.rescaleX(i.subX).domain()),this},i.zoom.updateExtent=function(){return this.scaleExtent([1,1/0]).translateExtent([[0,0],[i.width,i.height]]).extent([[0,0],[i.width,i.height]]),this},i.zoom.update=function(){return this.updateExtent().updateDomain()},i.zoom.updateExtent()},l.prototype.zoomTransform=function(t){var e=[this.x(t[0]),this.x(t[1])];return this.d3.zoomIdentity.scale(this.width/(e[1]-e[0])).translate(-e[0],0)},l.prototype.initDragZoom=function(){var e=this,i=e.d3,n=e.config,t=e.context=e.svg,r=e.margin.left+20.5,a=e.margin.top+.5;if("drag"===n.zoom_type&&n.zoom_enabled){var o=function(t){return t&&t.map(function(t){return e.x.invert(t)})},s=e.dragZoomBrush=i.brushX().on("start",function(){e.api.unzoom(),e.svg.select("."+Y.dragZoom).classed("disabled",!1),n.zoom_onzoomstart.call(e.api,i.event.sourceEvent)}).on("brush",function(){n.zoom_onzoom.call(e.api,o(i.event.selection))}).on("end",function(){if(null!=i.event.selection){var t=o(i.event.selection);n.zoom_disableDefaultBehavior||e.api.zoom(t),e.svg.select("."+Y.dragZoom).classed("disabled",!0),n.zoom_onzoomend.call(e.api,t)}});t.append("g").classed(Y.dragZoom,!0).attr("clip-path",e.clipPath).attr("transform","translate("+r+","+a+")").call(s)}},l.prototype.getZoomDomain=function(){var t=this.config,e=this.d3;return[e.min([this.orgXDomain[0],t.zoom_x_min]),e.max([this.orgXDomain[1],t.zoom_x_max])]},l.prototype.redrawForZoom=function(){var t=this,e=t.d3,i=t.config,n=t.zoom,r=t.x;i.zoom_enabled&&0!==t.filterTargetsToShow(t.data.targets).length&&(n.update(),i.zoom_disableDefaultBehavior||(t.isCategorized()&&r.orgDomain()[0]===t.orgXDomain[0]&&r.domain([t.orgXDomain[0]-1e-10,r.orgDomain()[1]]),t.redraw({withTransition:!1,withY:i.zoom_rescale,withSubchart:!1,withEventRect:!1,withDimension:!1}),e.event.sourceEvent&&"mousemove"===e.event.sourceEvent.type&&(t.cancelClick=!0)))},t}); \ No newline at end of file +/* @license C3.js v0.7.16 | (c) C3 Team and other contributors | http://c3js.org/ */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).c3=e()}(this,function(){"use strict";function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t){return function(t){if(Array.isArray(t))return n(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return n(t,e);var i=Object.prototype.toString.call(t).slice(8,-1);"Object"===i&&t.constructor&&(i=t.constructor.name);if("Map"===i||"Set"===i)return Array.from(t);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return n(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(t,e){(null==e||e>t.length)&&(e=t.length);for(var i=0,n=new Array(e);i/g,">"):t}function p(t){var e=function(t){void 0===t&&(t=window.navigator.userAgent);var e=t.indexOf("MSIE ");return 0e.getTotalLength())break;i--}while(0=this.numberOfItems)throw"INDEX_SIZE_ERR"},window.SVGPathSegList.prototype.getItem=function(t){return this._checkPathSynchronizedToList(),this._checkValidIndex(t),this._list[t]},window.SVGPathSegList.prototype.insertItemBefore=function(t,e){return this._checkPathSynchronizedToList(),e>this.numberOfItems&&(e=this.numberOfItems),t._owningPathSegList&&(t=t.clone()),this._list.splice(e,0,t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.replaceItem=function(t,e){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._checkValidIndex(e),((this._list[e]=t)._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList.prototype.removeItem=function(t){this._checkPathSynchronizedToList(),this._checkValidIndex(t);var e=this._list[t];return this._list.splice(t,1),this._writeListToPath(),e},window.SVGPathSegList.prototype.appendItem=function(t){return this._checkPathSynchronizedToList(),t._owningPathSegList&&(t=t.clone()),this._list.push(t),(t._owningPathSegList=this)._writeListToPath(),t},window.SVGPathSegList._pathSegArrayAsString=function(t){var e="",i=!0;return t.forEach(function(t){i?(i=!1,e+=t._asPathString()):e+=" "+t._asPathString()}),e},window.SVGPathSegList.prototype._parsePath=function(t){if(!t||0==t.length)return[];function e(){this.pathSegList=[]}var n=this;e.prototype.appendSegment=function(t){this.pathSegList.push(t)};function i(t){this._string=t,this._currentIndex=0,this._endIndex=this._string.length,this._previousCommand=window.SVGPathSeg.PATHSEG_UNKNOWN,this._skipOptionalSpaces()}i.prototype._isCurrentSpace=function(){var t=this._string[this._currentIndex];return t<=" "&&(" "==t||"\n"==t||"\t"==t||"\r"==t||"\f"==t)},i.prototype._skipOptionalSpaces=function(){for(;this._currentIndex=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex||this._string.charAt(this._currentIndex)<"0"||"9"=this._endIndex)){var t=!1,e=this._string.charAt(this._currentIndex++);if("0"==e)t=!1;else{if("1"!=e)return;t=!0}return this._skipOptionalSpacesOrDelimiter(),t}},i.prototype.parseSegment=function(){var t=this._string[this._currentIndex],e=this._pathSegTypeFromChar(t);if(e==window.SVGPathSeg.PATHSEG_UNKNOWN){if(this._previousCommand==window.SVGPathSeg.PATHSEG_UNKNOWN)return null;if((e=this._nextCommandHelper(t,this._previousCommand))==window.SVGPathSeg.PATHSEG_UNKNOWN)return null}else this._currentIndex++;switch(this._previousCommand=e){case window.SVGPathSeg.PATHSEG_MOVETO_REL:return new window.SVGPathSegMovetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_MOVETO_ABS:return new window.SVGPathSegMovetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_REL:return new window.SVGPathSegLinetoRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_ABS:return new window.SVGPathSegLinetoAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:return new window.SVGPathSegLinetoHorizontalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:return new window.SVGPathSegLinetoHorizontalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:return new window.SVGPathSegLinetoVerticalRel(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:return new window.SVGPathSegLinetoVerticalAbs(n,this._parseNumber());case window.SVGPathSeg.PATHSEG_CLOSEPATH:return this._skipOptionalSpaces(),new window.SVGPathSegClosePath(n);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:var i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicRel(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicAbs(n,i.x,i.y,i.x1,i.y1,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothRel(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:i={x2:this._parseNumber(),y2:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoCubicSmoothAbs(n,i.x,i.y,i.x2,i.y2);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticRel(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegCurvetoQuadraticAbs(n,i.x,i.y,i.x1,i.y1);case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:return new window.SVGPathSegCurvetoQuadraticSmoothRel(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:return new window.SVGPathSegCurvetoQuadraticSmoothAbs(n,this._parseNumber(),this._parseNumber());case window.SVGPathSeg.PATHSEG_ARC_REL:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcRel(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);case window.SVGPathSeg.PATHSEG_ARC_ABS:i={x1:this._parseNumber(),y1:this._parseNumber(),arcAngle:this._parseNumber(),arcLarge:this._parseArcFlag(),arcSweep:this._parseArcFlag(),x:this._parseNumber(),y:this._parseNumber()};return new window.SVGPathSegArcAbs(n,i.x,i.y,i.x1,i.y1,i.arcAngle,i.arcLarge,i.arcSweep);default:throw"Unknown path seg type."}};var r=new e,a=new i(t);if(!a.initialCommandIsMoveTo())return[];for(;a.hasMoreData();){var o=a.parseSegment();if(!o)return[];r.appendSegment(o)}return r.pathSegList}),String.prototype.padEnd||(String.prototype.padEnd=function(t,e){return t>>=0,e=String(void 0!==e?e:" "),this.length>t?String(this):((t-=this.length)>e.length&&(e+=e.repeat(t/e.length)),String(this)+e.slice(0,t))}),"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(t,e){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),n=1;n'":;\[\]\/|~`{}\\])/g,"\\$1")},l.prototype.selectorTarget=function(t,e){return(e||"")+"."+Y.target+this.getTargetSelectorSuffix(t)},l.prototype.selectorTargets=function(t,e){var i=this;return(t=t||[]).length?t.map(function(t){return i.selectorTarget(t,e)}):null},l.prototype.selectorLegend=function(t){return"."+Y.legendItem+this.getTargetSelectorSuffix(t)},l.prototype.selectorLegends=function(t){var e=this;return t&&t.length?t.map(function(t){return e.selectorLegend(t)}):null},l.prototype.getClipPath=function(t){return"url("+(p(9)?"":document.URL.split("#")[0])+"#"+t+")"},l.prototype.appendClip=function(t,e){return t.append("clipPath").attr("id",e).append("rect")},l.prototype.getAxisClipX=function(t){var e=Math.max(30,this.margin.left);return t?-(1+e):-(e-1)},l.prototype.getAxisClipY=function(t){return t?-20:-this.margin.top},l.prototype.getXAxisClipX=function(){return this.getAxisClipX(!this.config.axis_rotated)},l.prototype.getXAxisClipY=function(){return this.getAxisClipY(!this.config.axis_rotated)},l.prototype.getYAxisClipX=function(){return this.config.axis_y_inner?-1:this.getAxisClipX(this.config.axis_rotated)},l.prototype.getYAxisClipY=function(){return this.getAxisClipY(this.config.axis_rotated)},l.prototype.getAxisClipWidth=function(t){var e=Math.max(30,this.margin.left),i=Math.max(30,this.margin.right);return t?this.width+2+e+i:this.margin.left+20},l.prototype.getAxisClipHeight=function(t){return(t?this.margin.bottom:this.margin.top+this.height)+20},l.prototype.getXAxisClipWidth=function(){return this.getAxisClipWidth(!this.config.axis_rotated)},l.prototype.getXAxisClipHeight=function(){return this.getAxisClipHeight(!this.config.axis_rotated)},l.prototype.getYAxisClipWidth=function(){return this.getAxisClipWidth(this.config.axis_rotated)+(this.config.axis_y_inner?20:0)},l.prototype.getYAxisClipHeight=function(){return this.getAxisClipHeight(this.config.axis_rotated)},l.prototype.generateColor=function(){var t=this.config,e=this.d3,n=t.data_colors,r=L(t.color_pattern)?t.color_pattern:e.schemeCategory10,a=t.data_color,o=[];return function(t){var e,i=t.id||t.data&&t.data.id||t;return n[i]instanceof Function?e=n[i](t):n[i]?e=n[i]:(o.indexOf(i)<0&&o.push(i),e=r[o.indexOf(i)%r.length],n[i]=e),a instanceof Function?a(e,t):e}},l.prototype.generateLevelColor=function(){var t=this.config,n=t.color_pattern,e=t.color_threshold,r="value"===e.unit,a=e.values&&e.values.length?e.values:[],o=e.max||100;return L(e)&&L(n)?function(t){for(var e=n[n.length-1],i=0;is&&(o=o.filter(function(t){return(""+t).indexOf(".")<0}));return o},l.prototype.getGridFilterToRemove=function(t){return t?function(e){var i=!1;return[].concat(t).forEach(function(t){("value"in t&&e.value===t.value||"class"in t&&e.class===t.class)&&(i=!0)}),i}:function(){return!0}},l.prototype.removeGridLines=function(t,e){function i(t){return!r(t)}var n=this.config,r=this.getGridFilterToRemove(t),a=e?Y.xgridLines:Y.ygridLines,o=e?Y.xgridLine:Y.ygridLine;this.main.select("."+a).selectAll("."+o).filter(r).transition().duration(n.transition_duration).style("opacity",0).remove(),e?n.grid_x_lines=n.grid_x_lines.filter(i):n.grid_y_lines=n.grid_y_lines.filter(i)},l.prototype.initEventRect=function(){var t=this,e=t.config;t.main.select("."+Y.chart).append("g").attr("class",Y.eventRects).style("fill-opacity",0),t.eventRect=t.main.select("."+Y.eventRects).append("rect").attr("class",Y.eventRect),e.zoom_enabled&&t.zoom&&(t.eventRect.call(t.zoom).on("dblclick.zoom",null),e.zoom_initialRange&&t.eventRect.transition().duration(0).call(t.zoom.transform,t.zoomTransform(e.zoom_initialRange)))},l.prototype.redrawEventRect=function(){var s=this,c=s.d3,d=s.config;function l(){s.svg.select("."+Y.eventRect).style("cursor",null),s.hideXGridFocus(),s.hideTooltip(),s.unexpandCircles(),s.unexpandBars()}function u(t,e){return e&&(s.isBarType(e.id)||s.dist(e,t)i.bar_width_max?i.bar_width_max:n},l.prototype.getBars=function(t,e){return(e?this.main.selectAll("."+Y.bars+this.getTargetSelectorSuffix(e)):this.main).selectAll("."+Y.bar+(C(t)?"-"+t:""))},l.prototype.expandBars=function(t,e,i){i&&this.unexpandBars(),this.getBars(t,e).classed(Y.EXPANDED,!0)},l.prototype.unexpandBars=function(t){this.getBars(t).classed(Y.EXPANDED,!1)},l.prototype.generateDrawBar=function(t,e){var a=this.config,o=this.generateGetBarPoints(t,e);return function(t,e){var i=o(t,e),n=a.axis_rotated?1:0,r=a.axis_rotated?0:1;return"M "+i[0][n]+","+i[0][r]+" L"+i[1][n]+","+i[1][r]+" L"+i[2][n]+","+i[2][r]+" L"+i[3][n]+","+i[3][r]+" z"}},l.prototype.generateGetBarPoints=function(t,e){var o=this,i=e?o.subXAxis:o.xAxis,n=t.__max__+1,s=o.getBarW(i,n),c=o.getShapeX(s,n,t,!!e),d=o.getShapeY(!!e),l=o.getShapeOffset(o.isBarType,t,!!e),u=s*(o.config.bar_space/2),h=e?o.getSubYScale:o.getYScale;return function(t,e){var i=h.call(o,t.id)(0),n=l(t,e)||i,r=c(t),a=d(t);return o.config.axis_rotated&&(0r.width?o=r.width-a.width:o<0&&(o=4)),o},l.prototype.getYForText=function(t,e,i){var n,r=this,a=f(i);return r.config.axis_rotated?n=(t[0][0]+t[2][0]+.6*a.height)/2:(n=t[2][1],e.value<0||0===e.value&&!r.hasPositiveValue?(n+=a.height,r.isBarType(e)&&r.isSafari()?n-=3:!r.isBarType(e)&&r.isChrome()&&(n+=3)):n+=r.isBarType(e)?-3:-6),null!==e.value||r.config.axis_rotated||(nthis.height&&(n=this.height-4)),n},l.prototype.initTitle=function(){this.title=this.svg.append("text").text(this.config.title_text).attr("class",this.CLASS.title)},l.prototype.redrawTitle=function(){var t=this;t.title.attr("x",t.xForTitle.bind(t)).attr("y",t.yForTitle.bind(t))},l.prototype.xForTitle=function(){var t=this,e=t.config,i=e.title_position||"left",n=0<=i.indexOf("right")?t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width-e.title_padding.right:0<=i.indexOf("center")?Math.max((t.currentWidth-t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).width)/2,0):e.title_padding.left;return n},l.prototype.yForTitle=function(){var t=this;return t.config.title_padding.top+t.getTextRect(t.title.node().textContent,t.CLASS.title,t.title.node()).height},l.prototype.getTitlePadding=function(){return this.yForTitle()+this.config.title_padding.bottom},l.prototype.drawColorScale=function(){var t,e,i,n,r,a,o=this,s=o.d3,c=o.config,d=o.data.targets[0],l=isNaN(c.stanford_scaleWidth)?20:c.stanford_scaleWidth;if(l<0)throw Error("Colorscale's barheight and barwidth must be greater than 0.");a=o.height-c.stanford_padding.bottom-c.stanford_padding.top,e=s.range(c.stanford_padding.bottom,a,5),r=s.scaleSequential(d.colors).domain([e[e.length-1],e[0]]),o.colorScale&&o.colorScale.remove(),o.colorScale=o.svg.append("g").attr("width",50).attr("height",a).attr("class",Y.colorScale),o.colorScale.append("g").attr("transform","translate(0, ".concat(c.stanford_padding.top,")")).selectAll("bars").data(e).enter().append("rect").attr("y",function(t,e){return 5*e}).attr("x",0).attr("width",l).attr("height",5).attr("fill",function(t){return r(t)}),n=s.scaleLog().domain([d.minEpochs,d.maxEpochs]).range([e[0]+c.stanford_padding.top+e[e.length-1]+5-1,e[0]+c.stanford_padding.top]),i=s.axisRight(n),"pow10"===c.stanford_scaleFormat?i.tickValues([1,10,100,1e3,1e4,1e5,1e6,1e7]):g(c.stanford_scaleFormat)?i.tickFormat(c.stanford_scaleFormat):i.tickFormat(s.format("d")),g(c.stanford_scaleValues)&&i.tickValues(c.stanford_scaleValues(d.minEpochs,d.maxEpochs)),t=o.colorScale.append("g").attr("class","legend axis").attr("transform","translate(".concat(l,",0)")).call(i),"pow10"===c.stanford_scaleFormat&&t.selectAll(".tick text").text(null).filter(v).text(10).append("tspan").attr("dy","-.7em").text(function(t){return Math.round(Math.log(t)/Math.LN10)}),o.colorScale.attr("transform","translate(".concat(o.currentWidth-o.xForColorScale(),", 0)"))},l.prototype.xForColorScale=function(){return this.config.stanford_padding.right+f(this.colorScale.node()).width},l.prototype.getColorScalePadding=function(){return this.xForColorScale()+this.config.stanford_padding.left+20},l.prototype.isStanfordGraphType=function(){return"stanford"===this.config.data_type},l.prototype.initStanfordData=function(){var t,e,i,n=this.d3,r=this.config,a=this.data.targets[0];if(a.values.sort(A),t=a.values.map(function(t){return t.epochs}),i=isNaN(r.stanford_scaleMin)?n.min(t):r.stanford_scaleMin,(e=isNaN(r.stanford_scaleMax)?n.max(t):r.stanford_scaleMax)".concat(e?_(e):"x","").concat(t.x,"\n ").concat(i?_(i):"y","").concat(t.value,"\n ")},l.prototype.countEpochsInRegion=function(i){var t=this.data.targets[0],e=t.values.reduce(function(t,e){return t+Number(e.epochs)},0),n=t.values.reduce(function(t,e){return T(e,i)?t+Number(e.epochs):t},0);return{value:n,percentage:0!==n?(n/e*100).toFixed(1):0}};var b=function(t){for(var e,i,n=0,r=0,a=t.length-1;re.epochs?1:0};return l.prototype.initStanfordElements=function(){var t=this;t.stanfordElements=t.main.select("."+Y.chart).append("g").attr("class",Y.stanfordElements),t.stanfordElements.append("g").attr("class",Y.stanfordLines),t.stanfordElements.append("g").attr("class",Y.stanfordTexts),t.stanfordElements.append("g").attr("class",Y.stanfordRegions)},l.prototype.updateStanfordElements=function(t){var e,i,n,r,a=this,o=a.main,s=a.config,c=a.xvCustom.bind(a),d=a.yvCustom.bind(a),l=a.countEpochsInRegion.bind(a),u=o.select("."+Y.stanfordLines).style("shape-rendering","geometricprecision").selectAll("."+Y.stanfordLine).data(s.stanford_lines),h=u.enter().append("g").attr("class",function(t){return Y.stanfordLine+(t.class?" "+t.class:"")});h.append("line").attr("x1",function(t){return s.axis_rotated?d(t,"value_y1"):c(t,"value_x1")}).attr("x2",function(t){return s.axis_rotated?d(t,"value_y2"):c(t,"value_x2")}).attr("y1",function(t){return s.axis_rotated?c(t,"value_x1"):d(t,"value_y1")}).attr("y2",function(t){return s.axis_rotated?c(t,"value_x2"):d(t,"value_y2")}).style("opacity",0),a.stanfordLines=h.merge(u),a.stanfordLines.select("line").transition().duration(t).attr("x1",function(t){return s.axis_rotated?d(t,"value_y1"):c(t,"value_x1")}).attr("x2",function(t){return s.axis_rotated?d(t,"value_y2"):c(t,"value_x2")}).attr("y1",function(t){return s.axis_rotated?c(t,"value_x1"):d(t,"value_y1")}).attr("y2",function(t){return s.axis_rotated?c(t,"value_x2"):d(t,"value_y2")}).style("opacity",1),u.exit().transition().duration(t).style("opacity",0).remove(),(r=(n=o.select("."+Y.stanfordTexts).selectAll("."+Y.stanfordText).data(s.stanford_texts)).enter().append("g").attr("class",function(t){return Y.stanfordText+(t.class?" "+t.class:"")})).append("text").attr("x",function(t){return s.axis_rotated?d(t,"y"):c(t,"x")}).attr("y",function(t){return s.axis_rotated?c(t,"x"):d(t,"y")}).style("opacity",0),a.stanfordTexts=r.merge(n),a.stanfordTexts.select("text").transition().duration(t).attr("x",function(t){return s.axis_rotated?d(t,"y"):c(t,"x")}).attr("y",function(t){return s.axis_rotated?c(t,"x"):d(t,"y")}).text(function(t){return t.content}).style("opacity",1),n.exit().transition().duration(t).style("opacity",0).remove(),(i=(e=o.select("."+Y.stanfordRegions).selectAll("."+Y.stanfordRegion).data(s.stanford_regions)).enter().append("g").attr("class",function(t){return Y.stanfordRegion+(t.class?" "+t.class:"")})).append("polygon").attr("points",function(t){return t.points.map(function(t){return[s.axis_rotated?d(t,"y"):c(t,"x"),s.axis_rotated?c(t,"x"):d(t,"y")].join(",")}).join(" ")}).style("opacity",0),i.append("text").attr("x",function(t){return a.getCentroid(t.points).x}).attr("y",function(t){return a.getCentroid(t.points).y}).style("opacity",0),a.stanfordRegions=i.merge(e),a.stanfordRegions.select("polygon").transition().duration(t).attr("points",function(t){return t.points.map(function(t){return[s.axis_rotated?d(t,"y"):c(t,"x"),s.axis_rotated?c(t,"x"):d(t,"y")].join(",")}).join(" ")}).style("opacity",function(t){return t.opacity?t.opacity:.2}),a.stanfordRegions.select("text").transition().duration(t).attr("x",function(t){return s.axis_rotated?d(a.getCentroid(t.points),"y"):c(a.getCentroid(t.points),"x")}).attr("y",function(t){return s.axis_rotated?c(a.getCentroid(t.points),"x"):d(a.getCentroid(t.points),"y")}).text(function(t){var e,i,n;return t.text?(a.isStanfordGraphType()&&(e=(n=l(t.points)).value,i=n.percentage),t.text(e,i)):""}).attr("text-anchor","middle").attr("dominant-baseline","middle").style("opacity",1),e.exit().transition().duration(t).style("opacity",0).remove()},l.prototype.initTooltip=function(){var t,e=this,i=e.config;if(e.tooltip=e.selectChart.style("position","relative").append("div").attr("class",Y.tooltipContainer).style("position","absolute").style("pointer-events","none").style("display","none"),i.tooltip_init_show){if(e.isTimeSeries()&&x(i.tooltip_init_x)){for(i.tooltip_init_x=e.parseDate(i.tooltip_init_x),t=0;t"+o),d=l.getStanfordPointColor(t[a]),c=_(u.data_epochs),s=t[a].epochs;else if(r||(o=_(h?h(t[a].x,t[a].index):t[a].x),r=""+(o||0===o?"":"")),void 0!==(s=_(p(t[a].value,t[a].ratio,t[a].id,t[a].index,t)))){if(null===t[a].name)continue;c=_(g(t[a].name,t[a].ratio,t[a].id,t[a].index)),d=l.levelColor?l.levelColor(t[a].value):n(t[a].id)}void 0!==s&&(r+="",r+="",r+="",r+="")}return r+"
"+o+"
"+c+""+s+"
"},l.prototype.tooltipPosition=function(t,e,i,n){var r,a,o,s,c,d=this,l=d.config,u=d.d3,h=d.hasArcType(),g=u.mouse(n);return h?(a=(d.width-(d.isLegendRight?d.getLegendWidth():0))/2+g[0],s=(d.hasType("gauge")?d.height:d.height/2)+g[1]+20):(r=d.getSvgLeft(!0),s=l.axis_rotated?(o=(a=r+g[0]+100)+e,c=d.currentWidth-d.getCurrentPaddingRight(),d.x(t[0].x)+20):(o=(a=r+d.getCurrentPaddingLeft(!0)+d.x(t[0].x)+20)+e,c=r+d.currentWidth-d.getCurrentPaddingRight(),g[1]+15),cd.currentHeight&&(s-=i+30)),s<0&&(s=0),{top:s,left:a}},l.prototype.showTooltip=function(t,e){var i,n,r,a=this,o=a.config,s=a.hasArcType(),c=t.filter(function(t){return t&&C(t.value)}),d=o.tooltip_position||l.prototype.tooltipPosition;0!==c.length&&o.tooltip_show&&(a.tooltip.html(o.tooltip_contents.call(a,t,a.axis.getXAxisTickFormat(),a.getYFormat(s),a.color)).style("display","block"),i=a.tooltip.property("offsetWidth"),n=a.tooltip.property("offsetHeight"),r=d.call(this,c,i,n,e),a.tooltip.style("top",r.top+"px").style("left",r.left+"px"))},l.prototype.hideTooltip=function(){this.tooltip.style("display","none")},l.prototype.setTargetType=function(t,e){var i=this,n=i.config;i.mapToTargetIds(t).forEach(function(t){i.withoutFadeIn[t]=e===n.data_types[t],n.data_types[t]=e}),t||(n.data_type=e)},l.prototype.hasType=function(i,t){var n=this.config.data_types,r=!1;return(t=t||this.data.targets)&&t.length?t.forEach(function(t){var e=n[t.id];(e&&0<=e.indexOf(i)||!e&&"line"===i)&&(r=!0)}):Object.keys(n).length?Object.keys(n).forEach(function(t){n[t]===i&&(r=!0)}):r=this.config.data_type===i,r},l.prototype.hasArcType=function(t){return this.hasType("pie",t)||this.hasType("donut",t)||this.hasType("gauge",t)},l.prototype.isLineType=function(t){var e=this.config,i=x(t)?t:t.id;return!e.data_types[i]||0<=["line","spline","area","area-spline","step","area-step"].indexOf(e.data_types[i])},l.prototype.isStepType=function(t){var e=x(t)?t:t.id;return 0<=["step","area-step"].indexOf(this.config.data_types[e])},l.prototype.isSplineType=function(t){var e=x(t)?t:t.id;return 0<=["spline","area-spline"].indexOf(this.config.data_types[e])},l.prototype.isAreaType=function(t){var e=x(t)?t:t.id;return 0<=["area","area-spline","area-step"].indexOf(this.config.data_types[e])},l.prototype.isBarType=function(t){var e=x(t)?t:t.id;return"bar"===this.config.data_types[e]},l.prototype.isScatterType=function(t){var e=x(t)?t:t.id;return"scatter"===this.config.data_types[e]},l.prototype.isStanfordType=function(t){var e=x(t)?t:t.id;return"stanford"===this.config.data_types[e]},l.prototype.isPieType=function(t){var e=x(t)?t:t.id;return"pie"===this.config.data_types[e]},l.prototype.isGaugeType=function(t){var e=x(t)?t:t.id;return"gauge"===this.config.data_types[e]},l.prototype.isDonutType=function(t){var e=x(t)?t:t.id;return"donut"===this.config.data_types[e]},l.prototype.isArcType=function(t){return this.isPieType(t)||this.isDonutType(t)||this.isGaugeType(t)},l.prototype.lineData=function(t){return this.isLineType(t)?[t]:[]},l.prototype.arcData=function(t){return this.isArcType(t.data)?[t]:[]},l.prototype.barData=function(t){return this.isBarType(t)?t.values:[]},l.prototype.lineOrScatterOrStanfordData=function(t){return this.isLineType(t)||this.isScatterType(t)||this.isStanfordType(t)?t.values:[]},l.prototype.barOrLineData=function(t){return this.isBarType(t)||this.isLineType(t)?t.values:[]},l.prototype.isSafari=function(){var t=window.navigator.userAgent;return 0<=t.indexOf("Safari")&&t.indexOf("Chrome")<0},l.prototype.isChrome=function(){return 0<=window.navigator.userAgent.indexOf("Chrome")},l.prototype.initZoom=function(){var e,i=this,n=i.d3,r=i.config;return i.zoom=n.zoom().on("start",function(){var t;"scroll"===r.zoom_type&&((t=n.event.sourceEvent)&&"brush"===t.type||(e=t,r.zoom_onzoomstart.call(i.api,t)))}).on("zoom",function(){var t;"scroll"===r.zoom_type&&((t=n.event.sourceEvent)&&"brush"===t.type||(i.redrawForZoom(),r.zoom_onzoom.call(i.api,i.x.orgDomain())))}).on("end",function(){var t;"scroll"===r.zoom_type&&((t=n.event.sourceEvent)&&"brush"===t.type||t&&e.clientX===t.clientX&&e.clientY===t.clientY||r.zoom_onzoomend.call(i.api,i.x.orgDomain()))}),i.zoom.updateDomain=function(){return n.event&&n.event.transform&&i.x.domain(n.event.transform.rescaleX(i.subX).domain()),this},i.zoom.updateExtent=function(){return this.scaleExtent([1,1/0]).translateExtent([[0,0],[i.width,i.height]]).extent([[0,0],[i.width,i.height]]),this},i.zoom.update=function(){return this.updateExtent().updateDomain()},i.zoom.updateExtent()},l.prototype.zoomTransform=function(t){var e=[this.x(t[0]),this.x(t[1])];return this.d3.zoomIdentity.scale(this.width/(e[1]-e[0])).translate(-e[0],0)},l.prototype.initDragZoom=function(){var e,t,i=this,n=i.d3,r=i.config,a=i.context=i.svg,o=i.margin.left+20.5,s=i.margin.top+.5;"drag"===r.zoom_type&&r.zoom_enabled&&(e=function(t){return t&&t.map(function(t){return i.x.invert(t)})},t=i.dragZoomBrush=n.brushX().on("start",function(){i.api.unzoom(),i.svg.select("."+Y.dragZoom).classed("disabled",!1),r.zoom_onzoomstart.call(i.api,n.event.sourceEvent)}).on("brush",function(){r.zoom_onzoom.call(i.api,e(n.event.selection))}).on("end",function(){var t;null!=n.event.selection&&(t=e(n.event.selection),r.zoom_disableDefaultBehavior||i.api.zoom(t),i.svg.select("."+Y.dragZoom).classed("disabled",!0),r.zoom_onzoomend.call(i.api,t))}),a.append("g").classed(Y.dragZoom,!0).attr("clip-path",i.clipPath).attr("transform","translate("+o+","+s+")").call(t))},l.prototype.getZoomDomain=function(){var t=this.config,e=this.d3;return[e.min([this.orgXDomain[0],t.zoom_x_min]),e.max([this.orgXDomain[1],t.zoom_x_max])]},l.prototype.redrawForZoom=function(){var t=this,e=t.d3,i=t.config,n=t.zoom,r=t.x;i.zoom_enabled&&0!==t.filterTargetsToShow(t.data.targets).length&&(n.update(),i.zoom_disableDefaultBehavior||(t.isCategorized()&&r.orgDomain()[0]===t.orgXDomain[0]&&r.domain([t.orgXDomain[0]-1e-10,r.orgDomain()[1]]),t.redraw({withTransition:!1,withY:i.zoom_rescale,withSubchart:!1,withEventRect:!1,withDimension:!1}),e.event.sourceEvent&&"mousemove"===e.event.sourceEvent.type&&(t.cancelClick=!0)))},t}); \ No newline at end of file diff --git a/package.json b/package.json index b18f4e257..42702eedd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "c3", - "version": "0.7.15", + "version": "0.7.16", "description": "D3-based reusable chart library", "main": "c3.js", "files": [ diff --git a/src/core.js b/src/core.js index bbe8d5d6f..22e9a92e6 100644 --- a/src/core.js +++ b/src/core.js @@ -14,7 +14,7 @@ import { } from './util' var c3 = { - version: '0.7.15', + version: '0.7.16', chart: { fn: Chart.prototype, internal: {