UNPKG

@shipx/timelines-chart

Version:

A parallel (swimlanes) timelines D3 chart for representing state of time-series over time.

1,629 lines (1,390 loc) 311 kB
// Version 2.11.5 @shipx/timelines-chart - https://github.com/yoozrr/timelines-chart (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.TimelinesChart = factory()); }(this, (function () { 'use strict'; function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(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.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = ".timelines-chart {\n\n text-align: center;\n\n /* Cancel selection interaction */\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n .timelines-chart .axises line, .timelines-chart .axises path {\n stroke: #808080;\n }\n\n .timelines-chart .axises .x-axis {\n font: 12px sans-serif;\n }\n\n .timelines-chart .axises .x-grid line {\n stroke: #D3D3D3;\n }\n\n .timelines-chart .axises .y-axis line, .timelines-chart .axises .y-axis path, .timelines-chart .axises .grp-axis line, .timelines-chart .axises .grp-axis path {\n stroke: none;\n }\n\n .timelines-chart .axises .y-axis text, .timelines-chart .axises .grp-axis text {\n fill: #2F4F4F;\n }\n\n .timelines-chart line.x-axis-date-marker {\n stroke-width: 1;\n stroke: #293cb7;\n fill: \"none\";\n }\n\n .timelines-chart .series-group {\n fill-opacity: 0.6;\n stroke: #808080;\n stroke-opacity: 0.2;\n }\n\n .timelines-chart .series-segment {\n stroke: none;\n }\n\n .timelines-chart .series-group, .timelines-chart .series-segment {\n cursor: crosshair;\n }\n\n .timelines-chart .legend {\n font-family: Sans-Serif;\n }\n\n .timelines-chart .legend .legendText {\n fill: #666;\n }\n\n .timelines-chart .reset-zoom-btn {\n font-family: sans-serif;\n fill: blue;\n opacity: .6;\n cursor: pointer;\n }\n\n.brusher .grid-background {\n fill: lightgrey;\n }\n\n.brusher .axis path {\n display: none;\n }\n\n.brusher .tick text {\n text-anchor: middle;\n }\n\n.brusher .grid line, .brusher .grid path {\n stroke: #fff;\n }\n\n.chart-zoom-selection, .brusher .brush .selection {\n stroke: blue;\n stroke-opacity: 0.6;\n fill: blue;\n fill-opacity: 0.3;\n shape-rendering: crispEdges;\n}\n\n.chart-tooltip {\n color: #eee;\n background: rgba(0,0,140,0.85);\n padding: 5px;\n border-radius: 3px;\n font: 11px sans-serif;\n z-index: 4000;\n}\n\n.chart-tooltip.group-tooltip {\n font-size: 14px;\n }\n\n.chart-tooltip.line-tooltip {\n font-size: 13px;\n }\n\n.chart-tooltip.group-tooltip, .chart-tooltip.line-tooltip {\n font-weight: bold;\n }\n\n.chart-tooltip.segment-tooltip {\n text-align: center;\n }"; styleInject(css_248z); /** * Returns a function, that, as long as it continues to be invoked, will not * be triggered. The function will be called after it stops being called for * N milliseconds. If `immediate` is passed, trigger the function on the * leading edge, instead of the trailing. The function also has a property 'clear' * that is a function which will clear the timer to prevent previously scheduled executions. * * @source underscore.js * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ * @param {Function} function to wrap * @param {Number} timeout in ms (`100`) * @param {Boolean} whether to execute at the beginning (`false`) * @api public */ function debounce(func, wait, immediate){ var timeout, args, context, timestamp, result; if (null == wait) wait = 100; function later() { var last = Date.now() - timestamp; if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) { result = func.apply(context, args); context = args = null; } } } var debounced = function(){ context = this; args = arguments; timestamp = Date.now(); var callNow = immediate && !timeout; if (!timeout) timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); context = args = null; } return result; }; debounced.clear = function() { if (timeout) { clearTimeout(timeout); timeout = null; } }; debounced.flush = function() { if (timeout) { result = func.apply(context, args); context = args = null; clearTimeout(timeout); timeout = null; } }; return debounced; } // Adds compatibility for ES modules debounce.debounce = debounce; var debounce_1 = debounce; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var Prop = function Prop(name, _ref) { var _ref$default = _ref["default"], defaultVal = _ref$default === void 0 ? null : _ref$default, _ref$triggerUpdate = _ref.triggerUpdate, triggerUpdate = _ref$triggerUpdate === void 0 ? true : _ref$triggerUpdate, _ref$onChange = _ref.onChange, onChange = _ref$onChange === void 0 ? function (newVal, state) {} : _ref$onChange; _classCallCheck(this, Prop); this.name = name; this.defaultVal = defaultVal; this.triggerUpdate = triggerUpdate; this.onChange = onChange; }; function index (_ref2) { var _ref2$stateInit = _ref2.stateInit, stateInit = _ref2$stateInit === void 0 ? function () { return {}; } : _ref2$stateInit, _ref2$props = _ref2.props, rawProps = _ref2$props === void 0 ? {} : _ref2$props, _ref2$methods = _ref2.methods, methods = _ref2$methods === void 0 ? {} : _ref2$methods, _ref2$aliases = _ref2.aliases, aliases = _ref2$aliases === void 0 ? {} : _ref2$aliases, _ref2$init = _ref2.init, initFn = _ref2$init === void 0 ? function () {} : _ref2$init, _ref2$update = _ref2.update, updateFn = _ref2$update === void 0 ? function () {} : _ref2$update; // Parse props into Prop instances var props = Object.keys(rawProps).map(function (propName) { return new Prop(propName, rawProps[propName]); }); return function () { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; // Holds component state var state = Object.assign({}, stateInit instanceof Function ? stateInit(options) : stateInit, // Support plain objects for backwards compatibility { initialised: false }); // keeps track of which props triggered an update var changedProps = {}; // Component constructor function comp(nodeElement) { initStatic(nodeElement, options); digest(); return comp; } var initStatic = function initStatic(nodeElement, options) { initFn.call(comp, nodeElement, state, options); state.initialised = true; }; var digest = debounce_1(function () { if (!state.initialised) { return; } updateFn.call(comp, state, changedProps); changedProps = {}; }, 1); // Getter/setter methods props.forEach(function (prop) { comp[prop.name] = getSetProp(prop); function getSetProp(_ref3) { var prop = _ref3.name, _ref3$triggerUpdate = _ref3.triggerUpdate, redigest = _ref3$triggerUpdate === void 0 ? false : _ref3$triggerUpdate, _ref3$onChange = _ref3.onChange, onChange = _ref3$onChange === void 0 ? function (newVal, state) {} : _ref3$onChange, _ref3$defaultVal = _ref3.defaultVal, defaultVal = _ref3$defaultVal === void 0 ? null : _ref3$defaultVal; return function (_) { var curVal = state[prop]; if (!arguments.length) { return curVal; } // Getter mode var val = _ === undefined ? defaultVal : _; // pick default if value passed is undefined state[prop] = val; onChange.call(comp, val, state, curVal); // track changed props !changedProps.hasOwnProperty(prop) && (changedProps[prop] = curVal); if (redigest) { digest(); } return comp; }; } }); // Other methods Object.keys(methods).forEach(function (methodName) { comp[methodName] = function () { var _methods$methodName; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return (_methods$methodName = methods[methodName]).call.apply(_methods$methodName, [comp, state].concat(args)); }; }); // Link aliases Object.entries(aliases).forEach(function (_ref4) { var _ref5 = _slicedToArray(_ref4, 2), alias = _ref5[0], target = _ref5[1]; return comp[alias] = comp[target]; }); // Reset all component props to their default value comp.resetProps = function () { props.forEach(function (prop) { comp[prop.name](prop.defaultVal); }); return comp; }; // comp.resetProps(); // Apply all prop defaults state._rerender = digest; // Expose digest method return comp; }; } function d3Ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } function bisector(f) { let delta = f; let compare = f; if (f.length === 1) { delta = (d, x) => f(d) - x; compare = ascendingComparator(f); } function left(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; while (lo < hi) { const mid = (lo + hi) >>> 1; if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; } return lo; } function right(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; while (lo < hi) { const mid = (lo + hi) >>> 1; if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; } return lo; } function center(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; const i = left(a, x, lo, hi - 1); return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; } return {left, center, right}; } function ascendingComparator(f) { return (d, x) => d3Ascending(f(d), x); } function number(x) { return x === null ? NaN : +x; } const ascendingBisect = bisector(d3Ascending); const bisectRight = ascendingBisect.right; const bisectCenter = bisector(number).center; var e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2); function ticks(start, stop, count) { var reverse, i = -1, n, ticks, step; stop = +stop, start = +start, count = +count; if (start === stop && count > 0) return [start]; if (reverse = stop < start) n = start, start = stop, stop = n; if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; if (step > 0) { start = Math.ceil(start / step); stop = Math.floor(stop / step); ticks = new Array(n = Math.ceil(stop - start + 1)); while (++i < n) ticks[i] = (start + i) * step; } else { step = -step; start = Math.ceil(start * step); stop = Math.floor(stop * step); ticks = new Array(n = Math.ceil(stop - start + 1)); while (++i < n) ticks[i] = (start + i) / step; } if (reverse) ticks.reverse(); return ticks; } function tickIncrement(start, stop, count) { var step = (stop - start) / Math.max(0, count), power = Math.floor(Math.log(step) / Math.LN10), error = step / Math.pow(10, power); return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); } function tickStep(start, stop, count) { var step0 = Math.abs(stop - start) / Math.max(0, count), step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), error = step0 / step1; if (error >= e10) step1 *= 10; else if (error >= e5) step1 *= 5; else if (error >= e2) step1 *= 2; return stop < start ? -step1 : step1; } function max(values, valueof) { let max; if (valueof === undefined) { for (const value of values) { if (value != null && (max < value || (max === undefined && value >= value))) { max = value; } } } else { let index = -1; for (let value of values) { if ((value = valueof(value, ++index, values)) != null && (max < value || (max === undefined && value >= value))) { max = value; } } } return max; } function min(values, valueof) { let min; if (valueof === undefined) { for (const value of values) { if (value != null && (min > value || (min === undefined && value >= value))) { min = value; } } } else { let index = -1; for (let value of values) { if ((value = valueof(value, ++index, values)) != null && (min > value || (min === undefined && value >= value))) { min = value; } } } return min; } function d3Range(start, stop, step) { start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0, range = new Array(n); while (++i < n) { range[i] = start + i * step; } return range; } var slice = Array.prototype.slice; function identity(x) { return x; } var top = 1, right = 2, bottom = 3, left = 4, epsilon = 1e-6; function translateX(x) { return "translate(" + (x + 0.5) + ",0)"; } function translateY(y) { return "translate(0," + (y + 0.5) + ")"; } function number$1(scale) { return d => +scale(d); } function center(scale) { var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset. if (scale.round()) offset = Math.round(offset); return function(d) { return +scale(d) + offset; }; } function entering() { return !this.__axis; } function axis(orient, scale) { var tickArguments = [], tickValues = null, tickFormat = null, tickSizeInner = 6, tickSizeOuter = 6, tickPadding = 3, k = orient === top || orient === left ? -1 : 1, x = orient === left || orient === right ? "x" : "y", transform = orient === top || orient === bottom ? translateX : translateY; function axis(context) { var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues, format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : tickFormat, spacing = Math.max(tickSizeInner, 0) + tickPadding, range = scale.range(), range0 = +range[0] + 0.5, range1 = +range[range.length - 1] + 0.5, position = (scale.bandwidth ? center : number$1)(scale.copy()), selection = context.selection ? context.selection() : context, path = selection.selectAll(".domain").data([null]), tick = selection.selectAll(".tick").data(values, scale).order(), tickExit = tick.exit(), tickEnter = tick.enter().append("g").attr("class", "tick"), line = tick.select("line"), text = tick.select("text"); path = path.merge(path.enter().insert("path", ".tick") .attr("class", "domain") .attr("stroke", "currentColor")); tick = tick.merge(tickEnter); line = line.merge(tickEnter.append("line") .attr("stroke", "currentColor") .attr(x + "2", k * tickSizeInner)); text = text.merge(tickEnter.append("text") .attr("fill", "currentColor") .attr(x, k * spacing) .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); if (context !== selection) { path = path.transition(context); tick = tick.transition(context); line = line.transition(context); text = text.transition(context); tickExit = tickExit.transition(context) .attr("opacity", epsilon) .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); }); tickEnter .attr("opacity", epsilon) .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); }); } tickExit.remove(); path .attr("d", orient === left || orient == right ? (tickSizeOuter ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter : "M0.5," + range0 + "V" + range1) : (tickSizeOuter ? "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter : "M" + range0 + ",0.5H" + range1)); tick .attr("opacity", 1) .attr("transform", function(d) { return transform(position(d)); }); line .attr(x + "2", k * tickSizeInner); text .attr(x, k * spacing) .text(format); selection.filter(entering) .attr("fill", "none") .attr("font-size", 10) .attr("font-family", "sans-serif") .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); selection .each(function() { this.__axis = position; }); } axis.scale = function(_) { return arguments.length ? (scale = _, axis) : scale; }; axis.ticks = function() { return tickArguments = slice.call(arguments), axis; }; axis.tickArguments = function(_) { return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice(); }; axis.tickValues = function(_) { return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice(); }; axis.tickFormat = function(_) { return arguments.length ? (tickFormat = _, axis) : tickFormat; }; axis.tickSize = function(_) { return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; }; axis.tickSizeInner = function(_) { return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; }; axis.tickSizeOuter = function(_) { return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; }; axis.tickPadding = function(_) { return arguments.length ? (tickPadding = +_, axis) : tickPadding; }; return axis; } function axisTop(scale) { return axis(top, scale); } function axisRight(scale) { return axis(right, scale); } function axisBottom(scale) { return axis(bottom, scale); } function axisLeft(scale) { return axis(left, scale); } function initRange(domain, range) { switch (arguments.length) { case 0: break; case 1: this.range(domain); break; default: this.range(range).domain(domain); break; } return this; } function initInterpolator(domain, interpolator) { switch (arguments.length) { case 0: break; case 1: { if (typeof domain === "function") this.interpolator(domain); else this.range(domain); break; } default: { this.domain(domain); if (typeof interpolator === "function") this.interpolator(interpolator); else this.range(interpolator); break; } } return this; } const implicit = Symbol("implicit"); function ordinal() { var index = new Map(), domain = [], range = [], unknown = implicit; function scale(d) { var key = d + "", i = index.get(key); if (!i) { if (unknown !== implicit) return unknown; index.set(key, i = domain.push(d)); } return range[(i - 1) % range.length]; } scale.domain = function(_) { if (!arguments.length) return domain.slice(); domain = [], index = new Map(); for (const value of _) { const key = value + ""; if (index.has(key)) continue; index.set(key, domain.push(value)); } return scale; }; scale.range = function(_) { return arguments.length ? (range = Array.from(_), scale) : range.slice(); }; scale.unknown = function(_) { return arguments.length ? (unknown = _, scale) : unknown; }; scale.copy = function() { return ordinal(domain, range).unknown(unknown); }; initRange.apply(scale, arguments); return scale; } function band() { var scale = ordinal().unknown(undefined), domain = scale.domain, ordinalRange = scale.range, r0 = 0, r1 = 1, step, bandwidth, round = false, paddingInner = 0, paddingOuter = 0, align = 0.5; delete scale.unknown; function rescale() { var n = domain().length, reverse = r1 < r0, start = reverse ? r1 : r0, stop = reverse ? r0 : r1; step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); if (round) step = Math.floor(step); start += (stop - start - step * (n - paddingInner)) * align; bandwidth = step * (1 - paddingInner); if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); var values = d3Range(n).map(function(i) { return start + step * i; }); return ordinalRange(reverse ? values.reverse() : values); } scale.domain = function(_) { return arguments.length ? (domain(_), rescale()) : domain(); }; scale.range = function(_) { return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1]; }; scale.rangeRound = function(_) { return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale(); }; scale.bandwidth = function() { return bandwidth; }; scale.step = function() { return step; }; scale.round = function(_) { return arguments.length ? (round = !!_, rescale()) : round; }; scale.padding = function(_) { return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner; }; scale.paddingInner = function(_) { return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner; }; scale.paddingOuter = function(_) { return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter; }; scale.align = function(_) { return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; }; scale.copy = function() { return band(domain(), [r0, r1]) .round(round) .paddingInner(paddingInner) .paddingOuter(paddingOuter) .align(align); }; return initRange.apply(rescale(), arguments); } function pointish(scale) { var copy = scale.copy; scale.padding = scale.paddingOuter; delete scale.paddingInner; delete scale.paddingOuter; scale.copy = function() { return pointish(copy()); }; return scale; } function point() { return pointish(band.apply(null, arguments).paddingInner(1)); } function define(constructor, factory, prototype) { constructor.prototype = factory.prototype = prototype; prototype.constructor = constructor; } function extend(parent, definition) { var prototype = Object.create(parent.prototype); for (var key in definition) prototype[key] = definition[key]; return prototype; } function Color() {} var darker = 0.7; var brighter = 1 / darker; var reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", reHex = /^#([0-9a-f]{3,8})$/, reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); var named = { aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4, azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000, blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a, burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e, coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c, cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b, darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b, darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc, darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b, darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3, deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969, dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22, fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700, goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f, grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c, indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa, lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6, lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3, lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a, lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899, lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32, linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa, mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371, mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585, midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5, navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000, olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6, palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093, papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb, plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399, red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513, salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee, sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd, slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f, steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8, tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3, white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32 }; define(Color, color, { copy: function(channels) { return Object.assign(new this.constructor, this, channels); }, displayable: function() { return this.rgb().displayable(); }, hex: color_formatHex, // Deprecated! Use color.formatHex. formatHex: color_formatHex, formatHsl: color_formatHsl, formatRgb: color_formatRgb, toString: color_formatRgb }); function color_formatHex() { return this.rgb().formatHex(); } function color_formatHsl() { return hslConvert(this).formatHsl(); } function color_formatRgb() { return this.rgb().formatRgb(); } function color(format) { var m, l; format = (format + "").trim().toLowerCase(); return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 : null) // invalid hex : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null; } function rgbn(n) { return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); } function rgba(r, g, b, a) { if (a <= 0) r = g = b = NaN; return new Rgb(r, g, b, a); } function rgbConvert(o) { if (!(o instanceof Color)) o = color(o); if (!o) return new Rgb; o = o.rgb(); return new Rgb(o.r, o.g, o.b, o.opacity); } function rgb(r, g, b, opacity) { return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); } function Rgb(r, g, b, opacity) { this.r = +r; this.g = +g; this.b = +b; this.opacity = +opacity; } define(Rgb, rgb, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, rgb: function() { return this; }, displayable: function() { return (-0.5 <= this.r && this.r < 255.5) && (-0.5 <= this.g && this.g < 255.5) && (-0.5 <= this.b && this.b < 255.5) && (0 <= this.opacity && this.opacity <= 1); }, hex: rgb_formatHex, // Deprecated! Use color.formatHex. formatHex: rgb_formatHex, formatRgb: rgb_formatRgb, toString: rgb_formatRgb })); function rgb_formatHex() { return "#" + hex(this.r) + hex(this.g) + hex(this.b); } function rgb_formatRgb() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")"); } function hex(value) { value = Math.max(0, Math.min(255, Math.round(value) || 0)); return (value < 16 ? "0" : "") + value.toString(16); } function hsla(h, s, l, a) { if (a <= 0) h = s = l = NaN; else if (l <= 0 || l >= 1) h = s = NaN; else if (s <= 0) h = NaN; return new Hsl(h, s, l, a); } function hslConvert(o) { if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); if (!(o instanceof Color)) o = color(o); if (!o) return new Hsl; if (o instanceof Hsl) return o; o = o.rgb(); var r = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r, g, b), max = Math.max(r, g, b), h = NaN, s = max - min, l = (max + min) / 2; if (s) { if (r === max) h = (g - b) / s + (g < b) * 6; else if (g === max) h = (b - r) / s + 2; else h = (r - g) / s + 4; s /= l < 0.5 ? max + min : 2 - max - min; h *= 60; } else { s = l > 0 && l < 1 ? 0 : h; } return new Hsl(h, s, l, o.opacity); } function hsl(h, s, l, opacity) { return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); } function Hsl(h, s, l, opacity) { this.h = +h; this.s = +s; this.l = +l; this.opacity = +opacity; } define(Hsl, hsl, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, rgb: function() { var h = this.h % 360 + (this.h < 0) * 360, s = isNaN(h) || isNaN(this.s) ? 0 : this.s, l = this.l, m2 = l + (l < 0.5 ? l : 1 - l) * s, m1 = 2 * l - m2; return new Rgb( hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity ); }, displayable: function() { return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && (0 <= this.l && this.l <= 1) && (0 <= this.opacity && this.opacity <= 1); }, formatHsl: function() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "hsl(" : "hsla(") + (this.h || 0) + ", " + (this.s || 0) * 100 + "%, " + (this.l || 0) * 100 + "%" + (a === 1 ? ")" : ", " + a + ")"); } })); /* From FvD 13.37, CSS Color Module Level 3 */ function hsl2rgb(h, m1, m2) { return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255; } function basis(t1, v0, v1, v2, v3) { var t2 = t1 * t1, t3 = t2 * t1; return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + (4 - 6 * t2 + 3 * t3) * v1 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + t3 * v3) / 6; } function basis$1(values) { var n = values.length - 1; return function(t) { var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), v1 = values[i], v2 = values[i + 1], v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; return basis((t - i / n) * n, v0, v1, v2, v3); }; } var constant = x => () => x; function linear(a, d) { return function(t) { return a + t * d; }; } function exponential(a, b, y) { return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { return Math.pow(a + t * b, y); }; } function gamma(y) { return (y = +y) === 1 ? nogamma : function(a, b) { return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a); }; } function nogamma(a, b) { var d = b - a; return d ? linear(a, d) : constant(isNaN(a) ? b : a); } var interpolateRgb = (function rgbGamma(y) { var color = gamma(y); function rgb$1(start, end) { var r = color((start = rgb(start)).r, (end = rgb(end)).r), g = color(start.g, end.g), b = color(start.b, end.b), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.r = r(t); start.g = g(t); start.b = b(t); start.opacity = opacity(t); return start + ""; }; } rgb$1.gamma = rgbGamma; return rgb$1; })(1); function rgbSpline(spline) { return function(colors) { var n = colors.length, r = new Array(n), g = new Array(n), b = new Array(n), i, color; for (i = 0; i < n; ++i) { color = rgb(colors[i]); r[i] = color.r || 0; g[i] = color.g || 0; b[i] = color.b || 0; } r = spline(r); g = spline(g); b = spline(b); color.opacity = 1; return function(t) { color.r = r(t); color.g = g(t); color.b = b(t); return color + ""; }; }; } var rgbBasis = rgbSpline(basis$1); function numberArray(a, b) { if (!b) b = []; var n = a ? Math.min(b.length, a.length) : 0, c = b.slice(), i; return function(t) { for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t; return c; }; } function isNumberArray(x) { return ArrayBuffer.isView(x) && !(x instanceof DataView); } function genericArray(a, b) { var nb = b ? b.length : 0, na = a ? Math.min(nb, a.length) : 0, x = new Array(na), c = new Array(nb), i; for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]); for (; i < nb; ++i) c[i] = b[i]; return function(t) { for (i = 0; i < na; ++i) c[i] = x[i](t); return c; }; } function date(a, b) { var d = new Date; return a = +a, b = +b, function(t) { return d.setTime(a * (1 - t) + b * t), d; }; } function interpolateNumber(a, b) { return a = +a, b = +b, function(t) { return a * (1 - t) + b * t; }; } function object(a, b) { var i = {}, c = {}, k; if (a === null || typeof a !== "object") a = {}; if (b === null || typeof b !== "object") b = {}; for (k in b) { if (k in a) { i[k] = interpolate(a[k], b[k]); } else { c[k] = b[k]; } } return function(t) { for (k in i) c[k] = i[k](t); return c; }; } var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, reB = new RegExp(reA.source, "g"); function zero(b) { return function() { return b; }; } function one(b) { return function(t) { return b(t) + ""; }; } function interpolateString(a, b) { var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b am, // current match in a bm, // current match in b bs, // string preceding current number in b, if any i = -1, // index in s s = [], // string constants and placeholders q = []; // number interpolators // Coerce inputs to strings. a = a + "", b = b + ""; // Interpolate pairs of numbers in a & b. while ((am = reA.exec(a)) && (bm = reB.exec(b))) { if ((bs = bm.index) > bi) { // a string precedes the next number in b bs = b.slice(bi, bs); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match if (s[i]) s[i] += bm; // coalesce with previous string else s[++i] = bm; } else { // interpolate non-matching numbers s[++i] = null; q.push({i: i, x: interpolateNumber(am, bm)}); } bi = reB.lastIndex; } // Add remains of b. if (bi < b.length) { bs = b.slice(bi); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } // Special optimization for only a single match. // Otherwise, interpolate each of the numbers and rejoin the string. return s.length < 2 ? (q[0] ? one(q[0].x) : zero(b)) : (b = q.length, function(t) { for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); return s.join(""); }); } function interpolate(a, b) { var t = typeof b, c; return b == null || t === "boolean" ? constant(b) : (t === "number" ? interpolateNumber : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) : b instanceof color ? interpolateRgb : b instanceof Date ? date : isNumberArray(b) ? numberArray : Array.isArray(b) ? genericArray : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object : interpolateNumber)(a, b); } function interpolateRound(a, b) { return a = +a, b = +b, function(t) { return Math.round(a * (1 - t) + b * t); }; } var degrees = 180 / Math.PI; var identity$1 = { translateX: 0, translateY: 0, rotate: 0, skewX: 0, scaleX: 1, scaleY: 1 }; function decompose(a, b, c, d, e, f) { var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * degrees, skewX: Math.atan(skewX) * degrees, scaleX: scaleX, scaleY: scaleY }; } var svgNode; /* eslint-disable no-undef */ function parseCss(value) { const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + ""); return m.isIdentity ? identity$1 : decompose(m.a, m.b, m.c, m.d, m.e, m.f); } function parseSvg(value) { if (value == null) return identity$1; if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); svgNode.setAttribute("transform", value); if (!(value = svgNode.transform.baseVal.consolidate())) return identity$1; value = value.matrix; return decompose(value.a, value.b, value.c, value.d, value.e, value.f); } function interpolateTransform(parse, pxComma, pxParen, degParen) { function pop(s) { return s.length ? s.pop() + " " : ""; } function translate(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push("translate(", null, pxComma, null, pxParen); q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); } else if (xb || yb) { s.push("translate(" + xb + pxComma + yb + pxParen); } } function rotate(a, b, s, q) { if (a !== b) { if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)}); } else if (b) { s.push(pop(s) + "rotate(" + b + degParen); } } function skewX(a, b, s, q) { if (a !== b) { q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)}); } else if (b) { s.push(pop(s) + "skewX(" + b + degParen); } } function scale(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push(pop(s) + "scale(", null, ",", null, ")"); q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); } else if (xb !== 1 || yb !== 1) { s.push(pop(s) + "scale(" + xb + "," + yb + ")"); } } return function(a, b) { var s = [], // string constants and placeholders q = []; // number interpolators a = parse(a), b = parse(b); translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); rotate(a.rotate, b.rotate, s, q); skewX(a.skewX, b.skewX, s, q); scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); a = b = null; // gc return function(t) { var i = -1, n = q.length, o; while (++i < n) s[(o = q[i]).i] = o.x(t); return s.join(""); }; }; } var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); function constants(x) { return function() { return x; }; } function number$2(x) { return +x; } var unit = [0, 1]; function identity$2(x) { return x; } function normalize(a, b) { return (b -= (a = +a)) ? function(x) { return (x - a) / b; } : constants(isNaN(b) ? NaN : 0.5); } function clamper(a, b) { var t; if (a > b) t = a, a = b, b = t; return function(x) { return Math.max(a, Math.min(b, x)); }; } // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. // interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. function bimap(domain, range, interpolate) { var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0); else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); return function(x) { return r0(d0(x)); }; } function polymap(domain, range, interpolate) { var j = Math.min(domain.length, range.length) - 1, d = new Array(j), r = new Array(j), i = -1; // Reverse descending domains. if (domain[j] < domain[0]) { domain = domain.slice().reverse(); range = range.slice().reverse(); } while (++i < j) { d[i] = normalize(domain[i], domain[i + 1]); r[i] = interpolate(range[i], range[i + 1]); } return function(x) { var i = bisectRight(domain, x, 1, j) - 1; return r[i](d[i](x)); }; } function copy(source, target) { return target .domain(source.domain()) .range(source.range()) .interpolate(source.interpolate()