` element to the body.
* @name bindto
* @memberof Options
* @property {string|HTMLElement|d3.selection|object} [bindto="#chart"] Specify the element where chart will be drawn.
* @property {string|HTMLElement|d3.selection} bindto.element="#chart" Specify the element where chart will be drawn.
* @property {string} [bindto.classname=bb] Specify the class name of bind element.
* **NOTE:** When class name isn't `bb`, then you also need to update the default CSS to be rendered correctly.
* @default #chart
* @example
* bindto: "#myContainer"
*
* // or HTMLElement
* bindto: document.getElementById("myContainer")
*
* // or D3 selection object
* bindto: d3.select("#myContainer")
*
* // or to change default classname
* bindto: {
* element: "#chart",
* classname: "bill-board" // ex)
* }
*/
bindto: "#chart",
/**
* Set chart background.
* @name background
* @memberof Options
* @property {object} background background object
* @property {string} background.class Specify the class name for background element.
* @property {string} background.color Specify the fill color for background element.
**NOTE:** Will be ignored if `imgUrl` option is set.
* @property {string} background.imgUrl Specify the image url string for background.
* @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.Background)
* @example
* background: {
* class: "myClass",
* color: "red",
*
* // Set image url for background.
* // If specified, 'color' option will be ignored.
* imgUrl: "https://naver.github.io/billboard.js/img/logo/billboard.js.svg",
* }
*/
background: {},
/**
* Set 'clip-path' attribute for chart element
* - **NOTE:**
* > When is false, chart node element is positioned after the axis node in DOM tree hierarchy.
* > Is to make chart element positioned over axis element.
* @name clipPath
* @memberof Options
* @type {boolean}
* @default true
* @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.clipPath)
* @example
* // don't set 'clip-path' attribute
* clipPath: false
*/
clipPath: !0,
/**
* Set svg element's class name
* @name svg
* @memberof Options
* @type {object}
* @property {object} [svg] svg object
* @property {string} [svg.classname] class name for svg element
* @example
* svg: {
* classname: "test_class"
* }
*/
svg_classname: undefined,
/**
* The desired size of the chart element.
* If value is not specified, the width of the chart will be calculated by the size of the parent element it's appended to.
* @name size
* @memberof Options
* @type {object}
* @property {object} [size] size object
* @property {number} [size.width] width of the chart element
* @property {number} [size.height] height of the chart element
* @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.ChartSize)
* @example
* size: {
* width: 640,
* height: 480
* }
*/
size_width: undefined,
size_height: undefined,
/**
* The padding of the chart element.
* - **NOTE:** for more information, see the "[`Understanding padding`](https://github.com/naver/billboard.js/wiki/Understanding-padding)"" wiki documentaion.
* @name padding
* @memberof Options
* @type {object}
* @property {object|boolean} [padding=true] Set padding of chart, and accepts object or boolean type.
* - `Object`: Specify each side's padding.
* - `false`: Remove padding completely and make shape to fully occupy the container element.
* - In this case, axes and subchart will be hidden.
* - To adjust some padding from this state, use `axis.[x|y].padding` option.
* @property {string} [padding.mode] padding mode
* - `"fit"`: Reduce padding as much as possible to make chart fit to the container element for chart types w/axis.
When specified, all padding values will be relative from fitted value.
* @property {number} [padding.top] padding on the top of chart
* @property {number} [padding.right] padding on the right of chart
* @property {number} [padding.bottom] padding on the bottom of chart
* @property {number} [padding.left] padding on the left of chart
* @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.Padding)
* @see [Demo: Fit padding](https://naver.github.io/billboard.js/demo/#ChartOptions.FitPadding)
* @example
* // remove padding completely.
* padding: false,
*
* padding: {
* // specifying mode value, will reduce padding and make fit to the container element.
* mode: "fit"
*
* // when mode is "fit", all padding values will be relative from fitted value.
* // so, 0 will be initial fitted value.
* top: 20,
* right: 20,
* bottom: 20,
* left: 20
* }
*
* // or specify padding value for each side
* padding: {
* top: 20,
* right: 20,
* bottom: 20,
* left: 20
* }
*/
padding: !0,
padding_mode: undefined,
padding_left: undefined,
padding_right: undefined,
padding_top: undefined,
padding_bottom: undefined,
/**
* Set chart resize options
* @name resize
* @memberof Options
* @type {object}
* @property {object} [resize] resize object
* @property {boolean} [resize.auto=true] Set chart resize automatically on viewport changes.
* @property {boolean|number} [resize.timer=true] Set resize timer option.
* - **NOTE:**
* - The resize function will be called using:
* - true: `setTimeout()`
* - false: `requestIdleCallback()`
* - Given number(delay in ms) value, resize function will be triggered using `setTimer()` with given delay.
* @example
* resize: {
* auto: false,
*
* // set resize function will be triggered using `setTimer()`
* timer: true,
*
* // set resize function will be triggered using `requestIdleCallback()`
* timer: false,
*
* // set resize function will be triggered using `setTimer()` with a delay of `100ms`.
* timer: 100
* }
*/
resize_auto: !0,
resize_timer: !0,
/**
* Set a callback to execute when the chart is clicked.
* @name onclick
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onclick: function(event) {
* this; // chart instance itself
* event; // native event object
* ...
* }
*/
onclick: undefined,
/**
* Set a callback to execute when mouse/touch enters the chart.
* @name onover
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onover: function(event) {
* this; // chart instance itself
* event; // native event object
* ...
* }
*/
onover: undefined,
/**
* Set a callback to execute when mouse/touch leaves the chart.
* @name onout
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onout: function(event) {
* this; // chart instance itself
* event; // native event object
* ...
* }
*/
onout: undefined,
/**
* Set a callback to execute when user resizes the screen.
* @name onresize
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onresize: function() {
* this; // chart instance itself
* ...
* }
*/
onresize: undefined,
/**
* Set a callback to execute when screen resize finished.
* @name onresized
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onresized: function() {
* this; // chart instance itself
* ...
* }
*/
onresized: undefined,
/**
* Set a callback to execute before the chart is initialized
* @name onbeforeinit
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onbeforeinit: function() {
* this; // chart instance itself
* ...
* }
*/
onbeforeinit: undefined,
/**
* Set a callback to execute when the chart is initialized.
* @name oninit
* @memberof Options
* @type {Function}
* @default undefined
* @example
* oninit: function() {
* this; // chart instance itself
* ...
* }
*/
oninit: undefined,
/**
* Set a callback to execute after the chart is initialized
* @name onafterinit
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onafterinit: function() {
* this; // chart instance itself
* ...
* }
*/
onafterinit: undefined,
/**
* Set a callback which is executed when the chart is rendered. Basically, this callback will be called in each time when the chart is redrawed.
* @name onrendered
* @memberof Options
* @type {Function}
* @default undefined
* @example
* onrendered: function() {
* this; // chart instance itself
* ...
* }
*/
onrendered: undefined,
/**
* Set duration of transition (in milliseconds) for chart animation.
* - **NOTE:** If `0 `or `null` set, transition will be skipped. So, this makes initial rendering faster especially in case you have a lot of data.
* @name transition
* @memberof Options
* @type {object}
* @property {object} [transition] transition object
* @property {number} [transition.duration=350] duration in milliseconds
* @example
* transition: {
* duration: 500
* }
*/
transition_duration: 250,
/**
* Set plugins
* @name plugins
* @memberof Options
* @type {Array}
* @example
* plugins: [
* new bb.plugin.stanford({ ... }),
* new PluginA(),
* ...
* ]
*/
plugins: [],
/**
* Control the render timing
* @name render
* @memberof Options
* @type {object}
* @property {object} [render] render object
* @property {boolean} [render.lazy=true] Make to not render at initialization (enabled by default when bind element's visibility is hidden).
* @property {boolean} [render.observe=true] Observe bind element's visibility(`display` or `visiblity` inline css property or class value) & render when is visible automatically (for IEs, only works IE11+). When set to **false**, call [`.flush()`](./Chart.html#flush) to render.
* @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.LazyRender)
* @example
* render: {
* lazy: true,
* observe: true
* }
*
* @example
* //
* // (a)
* // (b)
*
* // render.lazy enabled by default when element is hidden
* var chart = bb.generate({ ... });
*
* // chart will be rendered automatically when element's visibility changes
* // Note: works only for inlined css property or class attribute changes
* document.getElementById('chart').classList.remove('hide') // (a)
* document.getElementById('chart').style.display = 'block'; // (b)
*
* @example
* // chart won't be rendered and not observing bind element's visiblity changes
* var chart = bb.generate({
* render: {
* lazy: true,
* observe: false
* }
* });
*
* // call at any point when you want to render
* chart.flush();
*/
render: {},
/**
* Show rectangles inside the chart.
* This option accepts array including object that has axis, start, end and class.
* The keys start, end and class are optional.
* axis must be x, y or y2. start and end should be the value where regions start and end.
* If not specified, the edge values will be used.
* If timeseries x axis, date string, Date object and unixtime integer can be used.
* If class is set, the region element will have it as class.
* @name regions
* @memberof Options
* @type {Array}
* @default []
* @see [Demo](https://naver.github.io/billboard.js/demo/#Region.RegionLabel)
* @example
* regions: [
* {
* axis: "x",
* start: 1,
* end: 4,
* class: "region-1-4",
* label: {
* text: "Region Text",
* x: 5, // position relative of the initial x coordinate
* y: 5, // position relative of the initial y coordinate
* color: "red", // color string
* rotated: true // make text to show in vertical or horizontal
* }
* }
* ]
*/
regions: []
});
;// CONCATENATED MODULE: ./src/config/Options/common/boost.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* boost config options
*/
/* harmony default export */ var boost = ({
/**
* Set boost options
* @name boost
* @memberof Options
* @type {object}
* @property {object} boost boost object
* @property {boolean} [boost.useCssRule=false] Avoid setting inline styles for each shape elements.
* - **NOTE:**
* - Will append <style> to the head tag and will add shpes' CSS rules dynamically.
* - For now, covers colors related properties (fill, stroke, etc.) only.
* @property {boolean} [boost.useWorker=false] Use Web Worker as possible for processing.
* - **NOTE:**
* - For now, only applies for data conversion at the initial time.
* - As of Web Worker's async nature, handling chart instance synchrously is not recommended.
* @example
* boost: {
* useCssRule: true,
* useWorker: false
* }
*/
boost_useCssRule: !1,
boost_useWorker: !1
});
;// CONCATENATED MODULE: ./src/config/Options/data/data.ts
var data_this = undefined;
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* data config options
*/
/* harmony default export */ var data_data = ({
/**
* Specify the key of x values in the data.
* We can show the data with non-index x values by this option. This option is required when the type of x axis is timeseries. If this option is set on category axis, the values of the data on the key will be used for category names.
* @name data․x
* @memberof Options
* @type {string}
* @default undefined
* @example
* data: {
* x: "date"
* }
*/
data_x: undefined,
/**
* Converts data id value
* @name data․idConverter
* @memberof Options
* @type {Function}
* @default function(id) { return id; }
* @example
* data: {
* idConverter: function(id) {
* // when id is 'data1', converts to be 'data2'
* // 'data2' should be given as the initial data value
* if (id === "data1") {
* return "data2";
* } else {
* return id;
* }
* }
* }
*/
data_idConverter: function data_idConverter(id) {
_newArrowCheck(this, data_this);
return id;
}.bind(undefined),
/**
* Set custom data name.
* If a name is set to `null`, the series is omitted from the legend.
* @name data․names
* @memberof Options
* @type {object}
* @default {}
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataName)
* @example
* data: {
* names: {
* data1: "Data Name 1",
* data2: "Data Name 2"
* }
* }
*/
data_names: {},
/**
* Set custom data class.
* If this option is specified, the element g for the data has an additional class that has the prefix 'bb-target-' (eg. bb-target-additional-data1-class).
* @name data․classes
* @memberof Options
* @type {object}
* @default {}
* @example
* data: {
* classes: {
* data1: "additional-data1-class",
* data2: "additional-data2-class"
* }
* }
*/
data_classes: {},
/**
* Set chart type at once.
* If this option is specified, the type will be applied to every data. This setting can be overwritten by data.types.
* **Available Values:**
* - area
* - area-line-range
* - area-spline
* - area-spline-range
* - area-step
* - bar
* - bubble
* - candlestick
* - donut
* - gauge
* - line
* - pie
* - polar
* - radar
* - scatter
* - spline
* - step
* - treemap
* @name data․type
* @memberof Options
* @type {string}
* @default "line"
NOTE: When importing shapes by ESM, `line()` should be specified for type.
* @example
* data: {
* type: "bar"
* }
* @example
* // Generate chart by importing ESM
* // Import types to be used only, where this will make smaller bundle size.
* import bb, {
* area,
* areaLineRange,
* areaSpline,
* areaSplineRange,
* areaStep,
* bar,
* bubble,
* candlestick,
* donut,
* gauge,
* line,
* pie,
* polar,
* radar,
* scatter,
* spline,
* step,
* treemap
* }
*
* bb.generate({
* ...,
* data: {
* type: bar()
* }
* });
*/
data_type: undefined,
/**
* Set chart type for each data.
* This setting overwrites data.type setting.
* - **NOTE:** `radar` and `treemap` type can't be combined with other types.
* @name data․types
* @memberof Options
* @type {object}
* @default {}
* @example
* data: {
* types: {
* data1: "bar",
* data2: "spline"
* }
* }
* @example
* // Generate chart by importing ESM
* // Import types to be used only, where this will make smaller bundle size.
* import bb, {
* area,
* areaLineRange,
* areaSpline,
* areaSplineRange,
* areaStep,
* bar,
* bubble,
* candlestick,
* donut,
* gauge,
* line,
* pie,
* polar,
* radar,
* scatter,
* spline,
* step,
* treemap
* }
*
* bb.generate({
* ...,
* data: {
* types: {
* data1: bar(),
* data1: spline()
* }
* }
* });
*/
data_types: {},
/**
* This option changes the order of stacking data and pieces of pie/donut.
* - If `null` specified, it will be the order the data loaded.
* - If function specified, it will be used as [Array.sort compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters)
*
* **Available Values:**
* - `desc`: In descending order
* - `asc`: In ascending order
* - `null`: It keeps the data load order
* - `function(data1, data2) { ... }`: Array.sort compareFunction
*
* **NOTE**: order function, only works for Axis based types & Arc types, except `Radar` type.
* @name data․order
* @memberof Options
* @type {string|Function|null}
* @default desc
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataOrder)
* @example
* data: {
* // in descending order (default)
* order: "desc"
*
* // in ascending order
* order: "asc"
*
* // keeps data input order
* order: null
*
* // specifying sort function
* order: function(a, b) {
* // param data passed format
* // {
* // id: "data1", id_org: "data1", values: [
* // {x: 5, value: 250, id: "data1", index: 5, name: "data1"},
* // ...
* // ]
* // }
*
* const reducer = (p, c) => p + Math.abs(c.value);
* const aSum = a.values.reduce(reducer, 0);
* const bSum = b.values.reduce(reducer, 0);
*
* // ascending order
* return aSum - bSum;
*
* // descending order
* // return bSum - aSum;
* }
* }
*/
data_order: "desc",
/**
* Set groups for the data for stacking.
* @name data․groups
* @memberof Options
* @type {Array}
* @default []
* @example
* data: {
* groups: [
* ["data1", "data2"],
* ["data3"]
* ]
* }
*/
data_groups: [],
/**
* Set how zero value will be treated on groups.
* Possible values:
* - `zero`: 0 will be positioned at absolute axis zero point.
* - `positive`: 0 will be positioned at the top of a stack.
* - `negative`: 0 will be positioned at the bottom of a stack.
* @name data․groupsZeroAs
* @memberof Options
* @type {string}
* @default "positive"
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.Groups)
* @example
* data: {
* groupsZeroAs: "zero" // "positive" or "negative"
* }
*/
data_groupsZeroAs: "positive",
/**
* Set color converter function.
* This option should a function and the specified function receives color (e.g. '#ff0000') and d that has data parameters like id, value, index, etc. And it must return a string that represents color (e.g. '#00ff00').
* @name data․color
* @memberof Options
* @type {Function}
* @default undefined
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataColor)
* @example
* data: {
* color: function(color, d) { ... }
* }
*/
data_color: undefined,
/**
* Set color for each data.
* @name data․colors
* @memberof Options
* @type {object}
* @default {}
* @example
* data: {
* colors: {
* data1: "#ff0000",
* data2: function(d) {
* return "#000";
* }
* ...
* }
* }
*/
data_colors: {},
/**
* Set labels options
* @name data․labels
* @memberof Options
* @type {object}
* @property {object} data Data object
* @property {boolean} [data.labels=false] Show or hide labels on each data points
* @property {boolean} [data.labels.centered=false] Centerize labels on `bar` shape. (**NOTE:** works only for 'bar' type)
* @property {Function} [data.labels.format] Set formatter function for data labels.
* The formatter function receives 4 arguments such as `v, id, i, texts` and it **must return a string** (`\n` character will be used as line break) that will be shown as the label.
* The arguments are:
* - `v` is the value of the data point where the label is shown.
* - `id` is the id of the data where the label is shown.
* - `i` is the index of the data series point where the label is shown.
* - `texts` is the array of whole corresponding data series' text labels.
* Formatter function can be defined for each data by specifying as an object and D3 formatter function can be set (ex. d3.format('$'))
* @property {string|object} [data.labels.backgroundColors] Set label text background colors.
* @property {string|object|Function} [data.labels.colors] Set label text colors.
* @property {object|Function} [data.labels.position] Set each dataset position, relative the original.
* When function is specified, will receives 5 arguments such as `type, v, id, i, texts` and it must return a position number.
* The arguments are:
* - `type` coordinate type string, which will be 'x' or 'y'.
* - `v` is the value of the data point where the label is shown.
* - `id` is the id of the data where the label is shown.
* - `i` is the index of the data series point where the label is shown.
* - `texts` is the array of whole corresponding data series' text labels.
* @property {number} [data.labels.position.x=0] x coordinate position, relative the original.
* @property {number} [data.labels.position.y=0] y coordinate position, relative the original.
* @property {object} [data.labels.rotate] Rotate label text. Specify degree value in a range of `0 ~ 360`.
* - **NOTE:** Depend on rotate value, text position need to be adjusted manually(using `data.labels.position` option) to be shown nicely.
* @memberof Options
* @type {object}
* @default {}
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataLabel)
* @see [Demo: label colors](https://naver.github.io/billboard.js/demo/#Data.DataLabelColors)
* @see [Demo: label format](https://naver.github.io/billboard.js/demo/#Data.DataLabelFormat)
* @see [Demo: label multiline](https://naver.github.io/billboard.js/demo/#Data.DataLabelMultiline)
* @see [Demo: label overlap](https://naver.github.io/billboard.js/demo/#Data.DataLabelOverlap)
* @see [Demo: label position](https://naver.github.io/billboard.js/demo/#Data.DataLabelPosition)
* @see [Demo: label rotate](https://naver.github.io/billboard.js/demo/#Data.DataLabelRotate)
* @example
* data: {
* labels: true,
*
* // or set specific options
* labels: {
* format: function(v, id, i, texts) {
* ...
* // to multiline, return with '\n' character
* return "Line1\nLine2";
* },
*
* // it's possible to set for each data
* format: {
* data1: function(v, id, i, texts) { ... },
* ...
* },
*
* // align text to center of the 'bar' shape (works only for 'bar' type)
* centered: true,
*
* // apply backgound color for label texts
* backgroundColors: "red",
*
* // set differenct backround colors per dataset
* backgroundColors: {
* data1: "green",
* data2: "yellow"
* }
*
* // apply for all label texts
* colors: "red",
*
* // set different colors per dataset
* // for not specified dataset, will have the default color value
* colors: {
* data1: "yellow",
* data3: "green"
* },
*
* // call back for label text color
* colors: function(color, d) {
* // color: the default data label color string
* // data: ex) {x: 0, value: 200, id: "data3", index: 0}
* ....
* return d.value > 200 ? "cyan" : color;
* },
*
* // return x, y coordinate position
* // apt to handle each text position manually
* position: function(type, v, id, i, texts) {
* ...
* return type == "x" ? 10 : 20;
* },
*
* // set x, y coordinate position
* position: {
* x: -10,
* y: 10
* },
*
* // or set x, y coordinate position by each dataset
* position: {
* data1: {x: 5, y: 5},
* data2: {x: 10, y: -20}
* },
*
* // rotate degree for label text
* rotate: 90
* }
* }
*/
data_labels: {},
data_labels_backgroundColors: undefined,
data_labels_colors: undefined,
data_labels_position: {},
/**
* Hide each data when the chart appears.
* If true specified, all of data will be hidden. If multiple ids specified as an array, those will be hidden.
* @name data․hide
* @memberof Options
* @type {boolean|Array}
* @default false
* @example
* data: {
* // all of data will be hidden
* hide: true
*
* // specified data will be hidden
* hide: ["data1", ...]
* }
*/
data_hide: !1,
/**
* Filter values to be shown
* The data value is the same as the returned by `.data()`.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
* @name data․filter
* @memberof Options
* @type {Function}
* @default undefined
* @example
* data: {
* // filter for id value
* filter: function(v) {
* // v: [{id: "data1", id_org: "data1", values: [
* // {x: 0, value: 130, id: "data2", index: 0}, ...]
* // }, ...]
* return v.id !== "data1";
* }
*/
data_filter: undefined,
/**
* Set a callback for click event on each data point.
* This callback will be called when each data point clicked and will receive `d` and element as the arguments.
* - `d` is the data clicked and element is the element clicked.
* - `element` is the current interacting svg element.
* - In this callback, `this` will be the Chart object.
* @name data․onclick
* @memberof Options
* @type {Function}
* @default function() {}
* @example
* data: {
* onclick: function(d, element) {
* // d - ex) {x: 4, value: 150, id: "data1", index: 4, name: "data1"}
* // element -
* ...
* }
* }
*/
data_onclick: function data_onclick() {
_newArrowCheck(this, data_this);
}.bind(undefined),
/**
* Set a callback for mouse/touch over event on each data point.
* This callback will be called when mouse cursor or via touch moves onto each data point and will receive `d` and `element` as the argument.
* - `d` is the data where mouse cursor moves onto.
* - `element` is the current interacting svg element.
* - In this callback, `this` will be the Chart object.
* @name data․onover
* @memberof Options
* @type {Function}
* @default function() {}
* @example
* data: {
* onover: function(d, element) {
* // d - ex) {x: 4, value: 150, id: "data1", index: 4}
* // element -
* ...
* }
* }
*/
data_onover: function data_onover() {
_newArrowCheck(this, data_this);
}.bind(undefined),
/**
* Set a callback for mouse/touch out event on each data point.
* This callback will be called when mouse cursor or via touch moves out each data point and will receive `d` as the argument.
* - `d` is the data where mouse cursor moves out.
* - `element` is the current interacting svg element.
* - In this callback, `this` will be the Chart object.
* @name data․onout
* @memberof Options
* @type {Function}
* @default function() {}
* @example
* data: {
* onout: function(d, element) {
* // d - ex) {x: 4, value: 150, id: "data1", index: 4}
* // element -
* ...
* }
* }
*/
data_onout: function data_onout() {
_newArrowCheck(this, data_this);
}.bind(undefined),
/**
* Set a callback for when data is shown.
* The callback will receive shown data ids in array.
* @name data․onshown
* @memberof Options
* @type {Function}
* @default undefined
* @example
* data: {
* onshown: function(ids) {
* // ids - ["data1", "data2", ...]
* ...
* }
* }
*/
data_onshown: undefined,
/**
* Set a callback for when data is hidden.
* The callback will receive hidden data ids in array.
* @name data․onhidden
* @memberof Options
* @type {Function}
* @default undefined
* @example
* data: {
* onhidden: function(ids) {
* // ids - ["data1", "data2", ...]
* ...
* }
* }
*/
data_onhidden: undefined,
/**
* Set a callback for minimum data
* - **NOTE:** For 'area-line-range' and 'area-spline-range', `mid` data will be taken for the comparison
* @name data․onmin
* @memberof Options
* @type {Function}
* @default undefined
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.OnMinMaxCallback)
* @example
* onmin: function(data) {
* // data - ex) [{x: 3, value: 400, id: "data1", index: 3}, ... ]
* ...
* }
*/
data_onmin: undefined,
/**
* Set a callback for maximum data
* - **NOTE:** For 'area-line-range' and 'area-spline-range', `mid` data will be taken for the comparison
* @name data․onmax
* @memberof Options
* @type {Function}
* @default undefined
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.OnMinMaxCallback)
* @example
* onmax: function(data) {
* // data - ex) [{x: 3, value: 400, id: "data1", index: 3}, ... ]
* ...
* }
*/
data_onmax: undefined,
/**
* Load a CSV or JSON file from a URL. NOTE that this will not work if loading via the "file://" protocol as the most browsers will block XMLHTTPRequests.
* @name data․url
* @memberof Options
* @type {string}
* @default undefined
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.LoadData)
* @example
* data: {
* url: "/data/test.csv"
* }
*/
data_url: undefined,
/**
* XHR header value
* - **NOTE:** Should be used with `data.url` option
* @name data․headers
* @memberof Options
* @type {string}
* @default undefined
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
* @example
* data: {
* url: "/data/test.csv",
* headers: {
* "Content-Type": "text/xml",
* ...
* }
* }
*/
data_headers: undefined,
/**
* Parse a JSON object for data. See also data.keys.
* @name data․json
* @memberof Options
* @type {Array}
* @default undefined
* @see [data․keys](#.data%25E2%2580%25A4keys)
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.JSONData)
* @example
* data: {
* json: [
* {name: "www.site1.com", upload: 200, download: 200, total: 400},
* {name: "www.site2.com", upload: 100, download: 300, total: 400},
* {name: "www.site3.com", upload: 300, download: 200, total: 500},
* {name: "www.site4.com", upload: 400, download: 100, total: 500}
* ],
* keys: {
* // case 1: specify 'x' key for category axis
* x: "name", // 'name' key will be used as category x axis values
* value: ["upload", "download"]
*
* // case 2: without 'x' key for non-category axis
* value: ["upload", "download"]
* }
* }
*/
data_json: undefined,
/**
* Load data from a multidimensional array, with the first element containing the data names, the following containing related data in that order.
* @name data․rows
* @memberof Options
* @type {Array}
* @default undefined
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.RowOrientedData)
* @example
* data: {
* rows: [
* ["A", "B", "C"],
* [90, 120, 300],
* [40, 160, 240],
* [50, 200, 290],
* [120, 160, 230],
* [80, 130, 300],
* [90, 220, 320]
* ]
* }
*
* // for 'bar' type, data can contain:
* // - an array of [start, end] data following the order
* data: {
* rows: [
* ["data1", "data2"],
* [[100, 150], 120],
* [[200, 300], 55],
* [[-400, 500], 60]
* ],
* type: "bar"
* }
*
* // for 'range' types('area-line-range' or 'area-spline-range'), data should contain:
* // - an array of [high, mid, low] data following the order
* // - or an object with 'high', 'mid' and 'low' key value
* data: {
* rows: [
* ["data1", "data2"],
* [
* // or {high:150, mid: 140, low: 110}, 120
* [150, 140, 110], 120
* ],
* [[155, 130, 115], 55],
* [[160, 135, 120], 60]
* ],
* types: {
* data1: "area-line-range",
* data2: "line"
* }
* }
*
* // for 'bubble' type, data can contain dimension value:
* // - an array of [y, z] data following the order
* // - or an object with 'y' and 'z' key value
* // 'y' is for y axis coordination and 'z' is the bubble radius value
* data: {
* rows: [
* ["data1", "data2"],
* [
* // or {y:10, z: 140}, 120
* [10, 140], 120
* ],
* [[100, 30], 55],
* [[50, 100], 60]
* ],
* types: {
* data1: "bubble",
* data2: "line"
* }
* }
*
* // for 'canlestick' type, data should contain:
* // - an array of [open, high, low, close, volume(optional)] data following the order
* // - or an object with 'open', 'high', 'low', 'close' and 'value'(optional) key value
* data: {
* rows: [
* ["data1", "data2"],
* [
* // open, high, low, close, volume (optional)
* {open: 1300, high: 1369, low: 1200, close: 1339, volume: 100},
* [1000, 1100, 850, 870]
* ],
* [
* {open: 1348, high: 1371, low: 1271, close: 1320},
* [870, 1250, 830, 1200, 50]
* ]
* ],
* type: "candlestick"
* }
*/
data_rows: undefined,
/**
* Load data from a multidimensional array, with each element containing an array consisting of a datum name and associated data values.
* @name data․columns
* @memberof Options
* @type {Array}
* @default undefined
* @see [Demo](https://naver.github.io/billboard.js/demo/#Data.ColumnOrientedData)
* @example
* data: {
* columns: [
* ["data1", 30, 20, 50, 40, 60, 50],
* ["data2", 200, 130, 90, 240, 130, 220],
* ["data3", 300, 200, 160, 400, 250, 250]
* ]
* }
*
* // for 'bar' type, data can contain:
* // - an array of [start, end] data following the order
* data: {
* columns: [
* ["data1", -100, 50, [100, 200], [200, 300]],
* ["data2", -200, 300, [-100, 100], [-50, -30]],
* ],
* type: "bar"
* }
*
* // for 'range' types('area-line-range' or 'area-spline-range'), data should contain:
* // - an array of [high, mid, low] data following the order
* // - or an object with 'high', 'mid' and 'low' key value
* data: {
* columns: [
* ["data1",
* [150, 140, 110], // or {high:150, mid: 140, low: 110}
* [150, 140, 110],
* [150, 140, 110]
* ]
* ],
* type: "area-line-range"
* }
*
* // for 'bubble' type, data can contain dimension value:
* // - an array of [y, z] data following the order
* // - or an object with 'y' and 'z' key value
* // 'y' is for y axis coordination and 'z' is the bubble radius value
* data: {
* columns: [
* ["data1",
* [10, 140], // or {y:10, z: 140}
* [100, 30],
* [50, 100]
* ]
* ],
* type: "bubble"
* }
*
* // for 'canlestick' type, data should contain:
* // - an array of [open, high, low, close, volume(optional)] data following the order
* // - or an object with 'open', 'high', 'low', 'close' and 'value'(optional) key value
* data: {
* columns: [
* ["data1",
* [1000, 1100, 850, 870, 100], // or {open:1000, high: 1100, low: 870, volume: 100}
* [870, 1250, 830, 1200] // 'volume' can be omitted
* ]
* ],
* type: "candlestick"
* }
*/
data_columns: undefined,
/**
* Used if loading JSON via data.url.
* - **Available Values:**
* - json
* - csv
* - tsv
* @name data․mimeType
* @memberof Options
* @type {string}
* @default csv
* @example
* data: {
* mimeType: "json"
* }
*/
data_mimeType: "csv",
/**
* Choose which JSON object keys correspond to desired data.
* - **NOTE:** Only for JSON object given as array.
* @name data․keys
* @memberof Options
* @type {string}
* @default undefined
* @example
* data: {
* json: [
* {name: "www.site1.com", upload: 200, download: 200, total: 400},
* {name: "www.site2.com", upload: 100, download: 300, total: 400},
* {name: "www.site3.com", upload: 300, download: 200, total: 500},
* {name: "www.site4.com", upload: 400, download: 100, total: 500}
* ],
* keys: {
* // case 1: specify 'x' key for category axis
* x: "name", // 'name' key will be used as category x axis values
* value: ["upload", "download"]
*
* // case 2: without 'x' key for non-category axis
* value: ["upload", "download"]
* }
* }
*/
data_keys: undefined,
/**
* Set text label to be displayed when there's no data to show.
* - ex. Toggling all visible data to not be shown, unloading all current data, etc.
* @name data․empty․label․text
* @memberof Options
* @type {string}
* @default ""
* @example
* data: {
* empty: {
* label: {
* text: "No Data"
* }
* }
* }
*/
data_empty_label_text: ""
});
;// CONCATENATED MODULE: ./src/config/Options/common/color.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* color config options
*/
/* harmony default export */ var common_color = ({
/**
* Set color of the data values
* @name color
* @memberof Options
* @type {object}
* @property {object} color color object
* @property {string|object|Function} [color.onover] Set the color value for each data point when mouse/touch onover event occurs.
* @property {Array|null} [color.pattern=[]] Set custom color pattern. Passing `null` will not set a color for these elements, which requires the usage of custom CSS-based theming to work.
* @property {Function} [color.tiles] if defined, allows use svg's patterns to fill data area. It should return an array of [SVGPatternElement](https://developer.mozilla.org/en-US/docs/Web/API/SVGPatternElement).
* - **NOTE:** The pattern element's id will be defined as `bb-colorize-pattern-$COLOR-VALUE`.
* ex. When color pattern value is `['red', '#fff']` and defined 2 patterns,then ids for pattern elements are:
* - `bb-colorize-pattern-red`
* - `bb-colorize-pattern-fff`
* @property {object} [color.threshold] color threshold for gauge and tooltip color
* @property {string} [color.threshold.unit] If set to `value`, the threshold will be based on the data value. Otherwise it'll be based on equation of the `threshold.max` option value.
* @property {Array} [color.threshold.values] Threshold values for each steps
* @property {number} [color.threshold.max=100] The base value to determine threshold step value condition. When the given value is 15 and max 10, then the value for threshold is `15*100/10`.
* @example
* color: {
* pattern: ["#1f77b4", "#aec7e8", ...],
*
* // Set colors' patterns
* // it should return an array of SVGPatternElement
* tiles: function() {
* var pattern = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
* var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
* var circle1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
*
* pattern.setAttribute("patternUnits", "userSpaceOnUse");
* pattern.setAttribute("width", "32");
* pattern.setAttribute("height", "32");
*
* g.style.fill = "#000";
* g.style.opacity = "0.2";
*
* circle1.setAttribute("cx", "3");
* circle1.setAttribute("cy", "3");
* circle1.setAttribute("r", "3");
*
* g.appendChild(circle1);
* pattern.appendChild(g);
*
* return [pattern];
* },
*
* // for threshold usage, pattern values should be set for each steps
* pattern: ["grey", "green", "yellow", "orange", "red"],
* threshold: {
* unit: "value",
*
* // when value is 20 => 'green', value is 40 => 'orange' will be set.
* values: [10, 20, 30, 40, 50],
*
* // the equation for max:
* // - unit == 'value': max => 30
* // - unit != 'value': max => value*100/30
* max: 30
* },
*
* // set all data to 'red'
* onover: "red",
*
* // set different color for data
* onover: {
* data1: "red",
* data2: "yellow"
* },
*
* // will pass data object to the callback
* onover: function(d) {
* return d.id === "data1" ? "red" : "green";
* }
* }
*/
color_pattern: [],
color_tiles: undefined,
color_threshold: {},
color_onover: undefined
});
;// CONCATENATED MODULE: ./src/config/Options/interaction/interaction.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* interaction config options
*/
/* harmony default export */ var interaction = ({
/**
* Interaction options
* @name interaction
* @memberof Options
* @type {object}
* @property {object} interaction Intersection object
* @property {boolean} [interaction.enabled=true] Indicate if the chart should have interactions.
* If `false` is set, all of interactions (showing/hiding tooltip, selection, mouse events, etc) will be disabled.
* @property {boolean} [interaction.brighten=true] Make brighter for the selected area (ex. 'pie' type data selected area)
* @property {boolean} [interaction.inputType.mouse=true] enable or disable mouse interaction
* @property {boolean} [interaction.inputType.touch=true] enable or disable touch interaction
* @property {boolean|number} [interaction.inputType.touch.preventDefault=false] enable or disable to call event.preventDefault on touchstart & touchmove event. It's usually used to prevent document scrolling.
* @see [Demo: touch.preventDefault](https://naver.github.io/billboard.js/demo/#Interaction.PreventScrollOnTouch)
* @example
* interaction: {
* enabled: false,
* brighten: false,
* inputType: {
* mouse: true,
* touch: false
*
* // or declare preventDefault explicitly.
* // In this case touch inputType is enabled by default
* touch: {
* preventDefault: true
*
* // or threshold pixel value (pixel moved from touchstart to touchmove)
* preventDefault: 5
* }
* }
* }
*/
interaction_enabled: !0,
interaction_brighten: !0,
interaction_inputType_mouse: !0,
interaction_inputType_touch: {}
});
;// CONCATENATED MODULE: ./src/config/Options/common/legend.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* legend config options
*/
/* harmony default export */ var legend = ({
/**
* Legend options
* @name legend
* @memberof Options
* @type {object}
* @property {object} legend Legend object
* @property {boolean} [legend.show=true] Show or hide legend.
* @property {boolean} [legend.hide=false] Hide legend
* If true given, all legend will be hidden. If string or array given, only the legend that has the id will be hidden.
* @property {string|HTMLElement} [legend.contents.bindto=undefined] Set CSS selector or element reference to bind legend items.
* - **NOTE:** Should be used along with `legend.contents.template`.
* @property {string|Function} [legend.contents.template="{=TITLE}"] Set item's template.
* - If set `string` value, within template the 'color' and 'title' can be replaced using template-like syntax string:
* - {=COLOR}: data color value
* - {=TITLE}: data title value
* - If set `function` value, will pass following arguments to the given function:
* - title {string}: data's id value
* - color {string}: color string
* - data {Array}: data array
* @property {string} [legend.position=bottom] Change the position of legend.
* Available values are: `bottom`, `right` and `inset` are supported.
* @property {object} [legend.inset={anchor: 'top-left',x: 10,y: 0,step: undefined}] Change inset legend attributes.
* This option accepts object that has the keys `anchor`, `x`, `y` and `step`.
* - **anchor** decides the position of the legend:
* - top-left
* - top-right
* - bottom-left
* - bottom-right
* - **x** and **y**:
* - set the position of the legend based on the anchor.
* - **step**:
* - defines the max step the legend has (e.g. If 2 set and legend has 3 legend item, the legend 2 columns).
* @property {boolean} [legend.equally=false] Set to all items have same width size.
* @property {number} [legend.padding=0] Set padding value
* @property {boolean} [legend.item.interaction=true] Set legend item interaction.
* - **NOTE:**
* - This setting will not have effect on `.toggle()` method.
* - `legend.item.onXXX` listener options will work if set, regardless of this option value.
* @property {boolean} [legend.item.interaction.dblclick=false] Set legend item to interact on double click.
* - **NOTE:**
* - Double clicking will make focused clicked dataseries only, hiding all others.
* - for single click case, `click + altKey(Win)/optionKey(Mac OS)` to have same effect.
* - To return initial state(which all dataseries are showing), double click current focused legend item again.
* - for single click case, `click + altKey(Win)/optionKey(Mac OS)` to have same effect.
* - In this case, default `click` interaction will be disabled.
* @property {Function} [legend.item.onclick=undefined] Set click event handler to the legend item.
* - **NOTE:**
* - When set, default `click` interaction will be disabled.
* - When `interaction.dblclick=true` is set, will be called on double click.
* @property {Function} [legend.item.onover=undefined] Set mouse/touch over event handler to the legend item.
* - **NOTE:** When set, default `mouseover` interaction will be disabled.
* @property {Function} [legend.item.onout=undefined] Set mouse/touch out event handler to the legend item.
* - **NOTE:** When set, default `mouseout` interaction will be disabled.
* @property {number} [legend.item.tile.width=10] Set width for 'rectangle' legend item tile element.
* @property {number} [legend.item.tile.height=10] Set height for 'rectangle' legend item tile element.
* @property {number} [legend.item.tile.r=5] Set the radius for 'circle' legend item tile type.
* @property {string} [legend.item.tile.type="rectangle"] Set legend item shape type.
* - **Available Values:**
* - circle
* - rectangle
* @property {boolean} [legend.format] Set formatter function for legend text.
* The argument:
* - `id`: legend text value. When `data.names` is specified, will pass from it, otherwise will pass data id.
* @property {boolean} [legend.tooltip=false] Show full legend text value using system tooltip(via `` element).
* @property {boolean} [legend.usePoint=false] Whether to use custom points in legend.
* @see [Demo: format](https://naver.github.io/billboard.js/demo/#Legend.LegendFormat)
* @see [Demo: item.interaction](https://naver.github.io/billboard.js/demo/#Legend.LegendItemInteraction)
* @see [Demo: item.tile.type](https://naver.github.io/billboard.js/demo/#Legend.LegendItemTileType)
* @see [Demo: position](https://naver.github.io/billboard.js/demo/#Legend.LegendPosition)
* @see [Demo: contents.template](https://naver.github.io/billboard.js/demo/#Legend.LegendTemplate1)
* @see [Demo: usePoint](https://naver.github.io/billboard.js/demo/#Legend.usePoint)
* @example
* legend: {
* show: true,
* hide: true,
* //or hide: "data1"
* //or hide: ["data1", "data2"]
* contents: {
* bindto: "#legend", //
*
* // will be as: data1
* template: "{=TITLE}"
*
* // or using function
* template: function(id, color, data) {
* // if you want omit some legend, return falsy value
* if (id !== "data1") {
* return " 5
* // to get full legend value, combine with 'legend.tooltip=true'
* if (id.length > 5) {
* id = id.substr(0, 5) + "...";
* }
*
* return id;
* },
* tooltip: true,
* usePoint: true
* }
*/
legend_contents_bindto: undefined,
legend_contents_template: "{=TITLE}",
legend_equally: !1,
legend_hide: !1,
legend_inset_anchor: "top-left",
legend_inset_x: 10,
legend_inset_y: 0,
legend_inset_step: undefined,
legend_item_interaction: !0,
legend_item_dblclick: !1,
legend_item_onclick: undefined,
legend_item_onover: undefined,
legend_item_onout: undefined,
legend_item_tile_width: 10,
legend_item_tile_height: 10,
legend_item_tile_r: 5,
legend_item_tile_type: "rectangle",
legend_format: undefined,
legend_padding: 0,
legend_position: "bottom",
legend_show: !0,
legend_tooltip: !1,
legend_usePoint: !1
});
;// CONCATENATED MODULE: ./src/config/Options/common/title.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* title config options
*/
/* harmony default export */ var title = ({
/**
* Set title options
* @name title
* @memberof Options
* @type {object}
* @property {object} title Title object
* @property {string} [title.text] Title text. If contains `\n`, it's used as line break allowing multiline title.
* @property {number} [title.padding.top=0] Top padding value.
* @property {number} [title.padding.right=0] Right padding value.
* @property {number} [title.padding.bottom=0] Bottom padding value.
* @property {number} [title.padding.left=0] Left padding value.
* @property {string} [title.position=center] Available values are: 'center', 'right' and 'left'.
* @see [Demo](https://naver.github.io/billboard.js/demo/#Title.MultilinedTitle)
* @example
* title: {
* text: "Title Text",
*
* // or Multiline title text
* text: "Main title text\nSub title text",
*
* padding: {
* top: 10,
* right: 10,
* bottom: 10,
* left: 10
* },
* position: "center"
* }
*/
title_text: undefined,
title_padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
},
title_position: "center"
});
;// CONCATENATED MODULE: ./src/config/Options/common/tooltip.ts
var tooltip_this = undefined;
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* tooltip config options
*/
/* harmony default export */ var tooltip = ({
/**
* Tooltip options
* @name tooltip
* @memberof Options
* @type {object}
* @property {object} tooltip Tooltip object
* @property {boolean} [tooltip.show=true] Show or hide tooltip.
* @property {boolean} [tooltip.doNotHide=false] Make tooltip keep showing not hiding on interaction.
* @property {boolean} [tooltip.grouped=true] Set if tooltip is grouped or not for the data points.
* - **NOTE:** The overlapped data points will be displayed as grouped even if set false.
* @property {boolean} [tooltip.linked=false] Set if tooltips on all visible charts with like x points are shown together when one is shown.
* @property {string} [tooltip.linked.name=""] Groping name for linked tooltip.
If specified, linked tooltip will be groped interacting to be worked only with the same name.
* @property {Function} [tooltip.format.title] Set format for the title of tooltip.
* Specified function receives x of the data point to show.
* @property {Function} [tooltip.format.name] Set format for the name of each data in tooltip.
* Specified function receives name, ratio, id and index of the data point to show. ratio will be undefined if the chart is not donut/pie/gauge.
* @property {Function} [tooltip.format.value] Set format for the value of each data value in tooltip. If undefined returned, the row of that value will be skipped to be called.
* - Will pass following arguments to the given function:
* - `value {string}`: Value of the data point. If data row contains multiple or ranged(ex. candlestick, area range, etc.) value, formatter will be called as value length.
* - `ratio {number}`: Ratio of the data point in the `pie/donut/gauge` and `area/bar` when contains grouped data. Otherwise is `undefined`.
* - `id {string}`: id of the data point
* - `index {number}`: Index of the data point
* @property {Function} [tooltip.position] Set custom position function for the tooltip.
* This option can be used to modify the tooltip position by returning object that has top and left.
* - Will pass following arguments to the given function:
* - `data {Array}`: Current selected data array object.
* - `width {number}`: Width of tooltip.
* - `height {number}`: Height of tooltip.
* - `element {SVGElement}`: Tooltip event bound element
* - `pos {object}`: Current position of the tooltip.
* @property {Function|object} [tooltip.contents] Set custom HTML for the tooltip.
* If tooltip.grouped is true, data includes multiple data points.
* Specified function receives `data` array and `defaultTitleFormat`, `defaultValueFormat` and `color` functions of the data point to show.
* - **Note:**
* - defaultTitleFormat:
* - if `axis.x.tick.format` option will be used if set.
* - otherwise, will return function based on tick format type(category, timeseries).
* - defaultValueFormat:
* - for Arc type (except gauge, radar), the function will return value from `(ratio * 100).toFixed(1)`.
* - for Axis based types, will be used `axis.[y|y2].tick.format` option value if is set.
* - otherwise, will parse value and return as number.
* @property {string|HTMLElement} [tooltip.contents.bindto=undefined] Set CSS selector or element reference to bind tooltip.
* - **NOTE:** When is specified, will not be updating tooltip's position.
* @property {string} [tooltip.contents.template=undefined] Set tooltip's template.
* Within template, below syntax will be replaced using template-like syntax string:
* - **{{ ... }}**: the doubly curly brackets indicate loop block for data rows.
* - **{=CLASS_TOOLTIP}**: default tooltip class name `bb-tooltip`.
* - **{=CLASS_TOOLTIP_NAME}**: default tooltip data class name (ex. `bb-tooltip-name-data1`)
* - **{=TITLE}**: title value.
* - **{=COLOR}**: data color.
* - **{=NAME}**: data id value.
* - **{=VALUE}**: data value.
* @property {object} [tooltip.contents.text=undefined] Set additional text content within data loop, using template syntax.
* - **NOTE:** It should contain `{ key: Array, ... }` value
* - 'key' name is used as substitution within template as '{=KEY}'
* - The value array length should match with the data length
* @property {boolean} [tooltip.init.show=false] Show tooltip at the initialization.
* @property {number} [tooltip.init.x=0] Set x Axis index(or index for Arc(donut, gauge, pie) types) to be shown at the initialization.
* @property {object} [tooltip.init.position] Set the position of tooltip at the initialization.
* @property {Function} [tooltip.onshow] Set a callback that will be invoked before the tooltip is shown.
* @property {Function} [tooltip.onhide] Set a callback that will be invoked before the tooltip is hidden.
* @property {Function} [tooltip.onshown] Set a callback that will be invoked after the tooltip is shown
* @property {Function} [tooltip.onhidden] Set a callback that will be invoked after the tooltip is hidden.
* @property {string|Function|null} [tooltip.order=null] Set tooltip data display order.
* **Available Values:**
* - `desc`: In descending data value order
* - `asc`: In ascending data value order
* - `null`: It keeps the data display order
* **NOTE:** When `data.groups` is set, the order will follow as the stacked graph order.
* If want to order as data bound, set any value rather than asc, desc or null. (ex. empty string "")
* - `function(data1, data2) { ... }`: [Array.sort compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters)
* @see [Demo: Hide Tooltip](https://naver.github.io/billboard.js/demo/#Tooltip.HideTooltip)
* @see [Demo: Tooltip Grouping](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipGrouping)
* @see [Demo: Tooltip Format](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipFormat)
* @see [Demo: Linked Tooltip](https://naver.github.io/billboard.js/demo/#Tooltip.LinkedTooltips)
* @see [Demo: Tooltip Position](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipPosition)
* @see [Demo: Tooltip Template](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipTemplate)
* @example
* tooltip: {
* show: true,
* doNotHide: true,
* grouped: false,
* format: {
* title: function(x) { return "Data " + x; },
* name: function(name, ratio, id, index) { return name; },
*
* // If data row contains multiple or ranged(ex. candlestick, area range, etc.) value,
* // formatter will be called as value length times.
* value: function(value, ratio, id, index) { return ratio; }
* },
* position: function(data, width, height, element, pos) {
* // data: [{x, index, id, name, value}, ...]
* // width: Tooltip width
* // height: Tooltip height
* // element: Tooltip event bound element
* // pos: {
* // x: Current mouse event x position,
* // y: Current mouse event y position,
* // xAxis: Current x Axis position (the value is given for axis based chart type only)
* // yAxis: Current y Axis position value or function(the value is given for axis based chart type only)
* // }
*
* // yAxis will work differently per data lenghts
* // - a) Single data: `yAxis` will return `number` value
* // - b) Multiple data: `yAxis` will return a function with property value
*
* // a) Single data:
* // Get y coordinate
* pos.yAxis; // y axis coordinate value of current data point
*
* // b) Multiple data:
* // Get y coordinate of value 500, where 'data1' scales(y or y2).
* // When 'data.axes' option is used, data can bound to different axes.
* // - when "data.axes={data1: 'y'}", wil return y value from y axis scale.
* // - when "data.axes={data1: 'y2'}", wil return y value from y2 axis scale.
* pos.yAxis(500, "data1"); // will return y coordinate value of data1
*
* pos.yAxis(500); // get y coordinate with value of 500, using y axis scale
* pos.yAxis(500, null, "y2"); // get y coordinate with value of 500, using y2 axis scale
*
* return {
* top: 0,
* left: 0
* }
* },
*
* contents: function(d, defaultTitleFormat, defaultValueFormat, color) {
* return ... // formatted html as you want
* },
*
* // specify tooltip contents using template
* // - example of HTML returned:
* //
* contents: {
* bindto: "#tooltip",
* template: ''
* }
*
* // with additional text value
* // - example of HTML returned:
* //
* contents: {
* bindto: "#tooltip",
* text: {
* // a) 'key' name is used as substitution within template as '{=KEY}'
* // b) the length should match with the data length
* VAR1: ["text1", "text2"],
* VAR2: ["comment1", "comment2"],
* },
* template: ''
* }
*
* // sort tooltip data value display in ascending order
* order: "asc",
*
* // specifying sort function
* order: function(a, b) {
* // param data passed format
* {x: 5, value: 250, id: "data1", index: 5, name: "data1"}
* ...
* },
*
* // show at the initialization
* init: {
* show: true,
* x: 2, // x Axis index (or index for Arc(donut, gauge, pie) types)
* position: {
* top: "150px", // specify as number or as string with 'px' unit string
* left: 250 // specify as number or as string with 'px' unit string
* }
* },
*
* // fires prior tooltip is shown
* onshow: function(selectedData) {
* // current dataset selected
* // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...]
* selectedData;
* },
*
* // fires prior tooltip is hidden
* onhide: function(selectedData) {
* // current dataset selected
* // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...]
* selectedData;
* },
*
* // fires after tooltip is shown
* onshown: function(selectedData) {
* // current dataset selected
* // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...]
* selectedData;
* },
*
* // fires after tooltip is hidden
* onhidden: function(selectedData) {
* // current dataset selected
* // ==> [{x: 4, value: 150, id: "data2", index: 4, name: "data2"}, ...]
* selectedData;
* },
*
* // Link any tooltips when multiple charts are on the screen where same x coordinates are available
* // Useful for timeseries correlation
* linked: true,
*
* // Specify name to interact those with the same name only.
* linked: {
* name: "some-group"
* }
* }
*/
tooltip_show: !0,
tooltip_doNotHide: !1,
tooltip_grouped: !0,
tooltip_format_title: undefined,
tooltip_format_name: undefined,
tooltip_format_value: undefined,
tooltip_position: undefined,
tooltip_contents: {},
tooltip_init_show: !1,
tooltip_init_x: 0,
tooltip_init_position: undefined,
tooltip_linked: !1,
tooltip_linked_name: "",
tooltip_onshow: function tooltip_onshow() {
_newArrowCheck(this, tooltip_this);
}.bind(undefined),
tooltip_onhide: function tooltip_onhide() {
_newArrowCheck(this, tooltip_this);
}.bind(undefined),
tooltip_onshown: function tooltip_onshown() {
_newArrowCheck(this, tooltip_this);
}.bind(undefined),
tooltip_onhidden: function tooltip_onhidden() {
_newArrowCheck(this, tooltip_this);
}.bind(undefined),
tooltip_order: null
});
;// CONCATENATED MODULE: ./src/config/Options/Options.ts
function Options_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function Options_objectSpread(e) { for (var r = 1, t; r < arguments.length; r++) { t = null != arguments[r] ? arguments[r] : {}; r % 2 ? Options_ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : Options_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
// common
/**
* Class to set options on generating chart.
* - It's instantiated internally, not exposed for public.
* @class Options
* @see {@link bb.generate} to use these options on generating the chart
*/
let Options = /*#__PURE__*/function () {
Options.setOptions = function setOptions(options) {
var _this = this;
this.data = options.reduce(function (a, c) {
_newArrowCheck(this, _this);
return Options_objectSpread(Options_objectSpread({}, a), c);
}.bind(this), this.data);
};
function Options() {
return deepClone(main, boost, data_data, common_color, interaction, legend, title, tooltip, Options.data);
}
return Options;
}();
Options.data = {};
;// CONCATENATED MODULE: ./src/module/Cache.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Constant for cache key
* - NOTE: Prefixed with '$', will be resetted when .load() is called
* @private
*/
const KEY = {
bubbleBaseLength: "$baseLength",
colorPattern: "__colorPattern__",
dataMinMax: "$dataMinMax",
dataTotalSum: "$dataTotalSum",
dataTotalPerIndex: "$totalPerIndex",
legendItemTextBox: "legendItemTextBox",
radarPoints: "$radarPoints",
radarTextWidth: "$radarTextWidth",
setOverOut: "setOverOut",
callOverOutForTouch: "callOverOutForTouch",
textRect: "textRect"
};
let Cache = /*#__PURE__*/function () {
function Cache() {
this.cache = {};
}
var _proto = Cache.prototype;
/**
* Add cache
* @param {string} key Cache key
* @param {*} value Value to be stored
* @param {boolean} isDataType Weather the cache is data typed '{id:'data', id_org: 'data', values: [{x:0, index:0,...}, ...]}'
* @returns {*} Added data value
* @private
*/
_proto.add = function add(key, value, isDataType) {
if (isDataType === void 0) {
isDataType = !1;
}
this.cache[key] = isDataType ? this.cloneTarget(value) : value;
return this.cache[key];
}
/**
* Remove cache
* @param {string|Array} key Cache key
* @private
*/;
_proto.remove = function remove(key) {
var _this = this;
(isString(key) ? [key] : key).forEach(function (v) {
_newArrowCheck(this, _this);
return delete this.cache[v];
}.bind(this));
}
/**
* Get cahce
* @param {string|Array} key Cache key
* @param {boolean} isDataType Weather the cache is data typed '{id:'data', id_org: 'data', values: [{x:0, index:0,...}, ...]}'
* @returns {*}
* @private
*/;
_proto.get = function get(key, isDataType) {
if (isDataType === void 0) {
isDataType = !1;
}
// when is isDataType, key should be string array
if (isDataType && Array.isArray(key)) {
const targets = [];
for (let i = 0, id; id = key[i]; i++) {
if (id in this.cache) {
targets.push(this.cloneTarget(this.cache[id]));
}
}
return targets;
} else {
const value = this.cache[key];
return isValue(value) ? value : null;
}
}
/**
* Reset cached data
* @param {boolean} all true: reset all data, false: reset only '$' prefixed key data
* @private
*/;
_proto.reset = function reset(all) {
const $$ = this;
for (const x in $$.cache) {
// reset the prefixed '$' key(which is internal use data) only.
if (all || /^\$/.test(x)) {
$$.cache[x] = null;
}
}
}
/**
* Clone data target object
* @param {object} target Data object
* @returns {object}
* @private
*/
// eslint-disable-next-line camelcase
;
_proto.cloneTarget = function cloneTarget(target) {
var _this2 = this;
return {
id: target.id,
id_org: target.id_org,
values: target.values.map(function (d) {
_newArrowCheck(this, _this2);
return {
x: d.x,
value: d.value,
id: d.id
};
}.bind(this))
};
};
return Cache;
}();
;// CONCATENATED MODULE: ./src/module/generator.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
const generator_setTimeout = win.setTimeout,
generator_clearTimeout = win.clearTimeout;
/**
* Generate resize queue function
* @param {boolean|number} option Resize option
* @returns {Fucntion}
* @private
*/
function generateResize(option) {
var _this4 = this;
const fn = [];
let timeout;
const callResizeFn = function () {
var _this = this;
// Delay all resize functions call, to prevent unintended excessive call from resize event
callResizeFn.clear();
if (option === !1) {
requestIdleCallback(function () {
var _this2 = this;
_newArrowCheck(this, _this);
fn.forEach(function (f) {
_newArrowCheck(this, _this2);
return f();
}.bind(this));
}.bind(this), {
timeout: 200
});
} else {
timeout = generator_setTimeout(function () {
var _this3 = this;
_newArrowCheck(this, _this);
fn.forEach(function (f) {
_newArrowCheck(this, _this3);
return f();
}.bind(this));
}.bind(this), isNumber(option) ? option : 200);
}
};
callResizeFn.clear = function () {
_newArrowCheck(this, _this4);
if (timeout) {
generator_clearTimeout(timeout);
timeout = null;
}
}.bind(this);
callResizeFn.add = function (f) {
_newArrowCheck(this, _this4);
return fn.push(f);
}.bind(this);
callResizeFn.remove = function (f) {
_newArrowCheck(this, _this4);
return fn.splice(fn.indexOf(f), 1);
}.bind(this);
return callResizeFn;
}
/**
* Generate transition queue function
* @returns {Function}
* @private
*/
function generateWait() {
let transitionsToWait = [];
// 'f' is called as selection.call(f, ...);
const f = function (selection, callback) {
var _this5 = this;
/**
* Check if transition is complete
* @returns {boolean} Whether transition is complete
* @private
*/
function loop() {
let done = 0;
for (let i = 0, t; t = transitionsToWait[i]; i++) {
if (t === !0 || t.empty != null && t.empty()) {
done++;
continue;
}
// when tab isn't visible exit loop
if (isTabVisible() === !1) {
done = transitionsToWait.length;
break;
}
try {
t.transition();
} catch (e) {
done++;
}
}
return done === transitionsToWait.length;
}
runUntil(function () {
_newArrowCheck(this, _this5);
callback == null || callback();
}.bind(this), loop);
};
f.add = function (t) {
isArray(t) ? transitionsToWait = transitionsToWait.concat(t) : transitionsToWait.push(t);
};
return f;
}
;// CONCATENATED MODULE: ./src/module/worker.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
// Store blob in memory
const blob = {};
/**
* Get Object URL
* @param {Function} fn Function to be executed in worker
* @param {Array} depsFn Dependency functions to run given function(fn).
* @returns {string}
* @private
*/
function getObjectURL(fn, depsFn) {
const fnString = fn.toString(),
key = fnString.replace(/(function|[\s\W\n])/g, "").substring(0, 15);
if (!(key in blob)) {
var _depsFn$map$join;
// Web Worker body
blob[key] = new win.Blob([((_depsFn$map$join = depsFn == null ? void 0 : depsFn.map(String).join(";")) != null ? _depsFn$map$join : "") + "\n\n\t\t\tself.onmessage=function({data}) {\n\t\t\t\tconst result = (" + fnString + ").apply(null, data);\n\t\t\t\tself.postMessage(result);\n\t\t\t};"], {
type: "text/javascript"
});
}
return win.URL.createObjectURL(blob[key]);
}
/**
* Get WebWorker instance
* @param {string} src URL object as string
* @returns {object} WebWorker instance
* @private
*/
function getWorker(src) {
const worker = new win.Worker(src);
// handle error
worker.onerror = function (e) {
// eslint-disable-next-line no-console
console.error ? console.error(e) : console.log(e);
};
return worker;
}
/**
* Create and run on Web Worker
* @param {boolean} useWorker Use Web Worker
* @param {Function} fn Function to be executed in worker
* @param {Function} callback Callback function to receive result from worker
* @param {Array} depsFn Dependency functions to run given function(fn).
* @returns {object}
* @example
* const worker = runWorker(function(arg) {
* // do some tasks...
* console.log("param:", A(arg));
*
* return 1234;
* }, function(data) {
* // callback after worker is done
* console.log("result:", data);
* },
* [function A(){}]
* );
*
* worker(11111);
* @private
*/
function runWorker(useWorker, fn, callback, depsFn) {
if (useWorker === void 0) {
useWorker = !0;
}
let runFn = function () {
const res = fn.apply(void 0, arguments);
callback(res);
};
if (win.Worker && useWorker) {
const src = getObjectURL(fn, depsFn),
worker = getWorker(src);
runFn = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
// trigger worker
worker.postMessage(args);
// listen worker
worker.onmessage = function (e) {
// release object URL from memory
win.URL.revokeObjectURL(src);
return callback(e.data);
};
// return new Promise((resolve, reject) => {
// worker.onmessage = ({data}) => resolve(data);
// worker.onerror = reject;
// });
};
}
return runFn;
}
;// CONCATENATED MODULE: ./node_modules/d3-dsv/src/dsv.js
var EOL = {},
EOF = {},
QUOTE = 34,
NEWLINE = 10,
RETURN = 13;
function objectConverter(columns) {
return new Function("d", "return {" + columns.map(function (name, i) {
return JSON.stringify(name) + ": d[" + i + "] || \"\"";
}).join(",") + "}");
}
function customConverter(columns, f) {
var object = objectConverter(columns);
return function (row, i) {
return f(object(row), i, columns);
};
}
// Compute unique columns in order of discovery.
function inferColumns(rows) {
var columnSet = Object.create(null),
columns = [];
rows.forEach(function (row) {
for (var column in row) {
if (!(column in columnSet)) {
columns.push(columnSet[column] = column);
}
}
});
return columns;
}
function dsv_pad(value, width) {
var s = value + "",
length = s.length;
return length < width ? Array(width - length + 1).join(0) + s : s;
}
function dsv_formatYear(year) {
return year < 0 ? "-" + dsv_pad(-year, 6) : year > 9999 ? "+" + dsv_pad(year, 6) : dsv_pad(year, 4);
}
function formatDate(date) {
var hours = date.getUTCHours(),
minutes = date.getUTCMinutes(),
seconds = date.getUTCSeconds(),
milliseconds = date.getUTCMilliseconds();
return isNaN(date) ? "Invalid Date" : dsv_formatYear(date.getUTCFullYear(), 4) + "-" + dsv_pad(date.getUTCMonth() + 1, 2) + "-" + dsv_pad(date.getUTCDate(), 2) + (milliseconds ? "T" + dsv_pad(hours, 2) + ":" + dsv_pad(minutes, 2) + ":" + dsv_pad(seconds, 2) + "." + dsv_pad(milliseconds, 3) + "Z" : seconds ? "T" + dsv_pad(hours, 2) + ":" + dsv_pad(minutes, 2) + ":" + dsv_pad(seconds, 2) + "Z" : minutes || hours ? "T" + dsv_pad(hours, 2) + ":" + dsv_pad(minutes, 2) + "Z" : "");
}
/* harmony default export */ function dsv(delimiter) {
var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
DELIMITER = delimiter.charCodeAt(0);
function parseRows(text, f) {
var rows = [],
// output rows
N = text.length,
I = 0,
// current character index
n = 0,
// current line number
t,
// current token
eof = N <= 0,
// current token followed by EOF?
eol = !1; // current token followed by EOL?
// Strip the trailing newline.
if (text.charCodeAt(N - 1) === NEWLINE) --N;
if (text.charCodeAt(N - 1) === RETURN) --N;
function token() {
if (eof) return EOF;
if (eol) return eol = !1, EOL;
// Unescape quotes.
var i,
j = I,
c;
if (text.charCodeAt(j) === QUOTE) {
while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
if ((i = I) >= N) eof = !0;else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = !0;else if (c === RETURN) {
eol = !0;
if (text.charCodeAt(I) === NEWLINE) ++I;
}
return text.slice(j + 1, i - 1).replace(/""/g, "\"");
}
// Find next delimiter or newline.
while (I < N) {
if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = !0;else if (c === RETURN) {
eol = !0;
if (text.charCodeAt(I) === NEWLINE) ++I;
} else if (c !== DELIMITER) continue;
return text.slice(j, i);
}
// Return last token before EOF.
return eof = !0, text.slice(j, N);
}
while ((t = token()) !== EOF) {
var row = [];
while (t !== EOL && t !== EOF) row.push(t), t = token();
if (f && (row = f(row, n++)) == null) continue;
rows.push(row);
}
return rows;
}
function preformatBody(rows, columns) {
return rows.map(function (row) {
return columns.map(function (column) {
return formatValue(row[column]);
}).join(delimiter);
});
}
function formatRow(row) {
return row.map(formatValue).join(delimiter);
}
function formatValue(value) {
return value == null ? "" : value instanceof Date ? formatDate(value) : reFormat.test(value += "") ? "\"" + value.replace(/"/g, "\"\"") + "\"" : value;
}
return {
parse: function (text, f) {
var convert,
columns,
rows = parseRows(text, function (row, i) {
if (convert) return convert(row, i - 1);
columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
});
rows.columns = columns || [];
return rows;
},
parseRows: parseRows,
format: function (rows, columns) {
if (columns == null) columns = inferColumns(rows);
return [columns.map(formatValue).join(delimiter)].concat(preformatBody(rows, columns)).join("\n");
},
formatBody: function (rows, columns) {
if (columns == null) columns = inferColumns(rows);
return preformatBody(rows, columns).join("\n");
},
formatRows: function (rows) {
return rows.map(formatRow).join("\n");
},
formatRow: formatRow,
formatValue: formatValue
};
}
;// CONCATENATED MODULE: ./node_modules/d3-dsv/src/csv.js
var csv = dsv(",");
var csvParse = csv.parse;
var csvParseRows = csv.parseRows;
var csvFormat = csv.format;
var csvFormatBody = csv.formatBody;
var csvFormatRows = csv.formatRows;
var csvFormatRow = csv.formatRow;
var csvFormatValue = csv.formatValue;
;// CONCATENATED MODULE: ./node_modules/d3-dsv/src/tsv.js
var tsv = dsv("\t");
var tsvParse = tsv.parse;
var tsvParseRows = tsv.parseRows;
var tsvFormat = tsv.format;
var tsvFormatBody = tsv.formatBody;
var tsvFormatRows = tsv.formatRows;
var tsvFormatRow = tsv.formatRow;
var tsvFormatValue = tsv.formatValue;
;// CONCATENATED MODULE: ./src/ChartInternal/data/convert.helper.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* eslint-disable */
/***** Functions to be executed on Web Worker *****
* NOTE: Don't allowed to use
* - arrow function syntax
* - Utils functions
*/
/**
* Convert Columns data
* @param {object} columns
* @returns {Array}
* @private
*/
function columns(columns) {
const newRows = [];
columns.forEach(function (col, i) {
const key = col[0];
col.forEach(function (v, j) {
if (j > 0) {
if (typeof newRows[j - 1] === "undefined") {
newRows[j - 1] = {};
}
if (typeof v === "undefined") {
throw new Error("Source data is missing a component at (" + i + ", " + j + ")!");
}
newRows[j - 1][key] = v;
}
});
});
return newRows;
}
/**
* Convert Rows data
* @param {object} columns
* @returns {Array}
* @private
*/
function rows(rows) {
const keys = rows[0],
newRows = [];
rows.forEach(function (row, i) {
if (i > 0) {
const newRow = {};
row.forEach(function (v, j) {
if (typeof v === "undefined") {
throw new Error("Source data is missing a component at (" + i + ", " + j + ")!");
}
newRow[keys[j]] = v;
});
newRows.push(newRow);
}
});
return newRows;
}
/**
* Convert JSON data
* @param {object} columns
* @returns {Array}
* @private
*/
function json(json, keysParam) {
const newRows = [];
let targetKeys, data;
if (Array.isArray(json)) {
const findValueInJson = function (object, path) {
if (object[path] !== undefined) {
return object[path];
}
const convertedPath = path.replace(/\[(\w+)\]/g, ".$1"),
pathArray = convertedPath.replace(/^\./, "").split("."); // convert indexes to properties (replace [] with .)
// strip a leading dot
let target = object;
pathArray.some(function (k) {
return !(target = target && k in target ? target[k] : undefined);
});
return target;
};
if (keysParam.x) {
targetKeys = keysParam.value.concat(keysParam.x);
} else {
targetKeys = keysParam.value;
}
newRows.push(targetKeys);
json.forEach(function (o) {
const newRow = targetKeys.map(function (key) {
// convert undefined to null because undefined data will be removed in convertDataToTargets()
let v = findValueInJson(o, key);
if (typeof v === "undefined") {
v = null;
}
return v;
});
newRows.push(newRow);
});
data = rows(newRows);
} else {
Object.keys(json).forEach(function (key) {
const tmp = json[key].concat();
tmp.unshift == null || tmp.unshift(key);
newRows.push(tmp);
});
data = columns(newRows);
}
return data;
}
/***** Functions can't be executed on Web Worker *****/
/**
* Convert URL data
* @param {string} url Remote URL
* @param {string} mimeType MIME type string: json | csv | tsv
* @param {object} headers Header object
* @param {object} keys Key object
* @param {Function} done Callback function
* @private
*/
function url(url, mimeType, headers, keys, done) {
if (mimeType === void 0) {
mimeType = "csv";
}
const req = new XMLHttpRequest(),
converter = {
csv: convert_helper_csv,
tsv: convert_helper_tsv,
json: json
};
req.open("GET", url);
if (headers) {
Object.keys(headers).forEach(function (key) {
req.setRequestHeader(key, headers[key]);
});
}
req.onreadystatechange = function () {
if (req.readyState === 4) {
if (req.status === 200) {
const response = req.responseText;
response && done.call(this, converter[mimeType](mimeType === "json" ? JSON.parse(response) : response, keys));
} else {
throw new Error(url + ": Something went wrong loading!");
}
}
};
req.send();
}
/**
* Convert CSV/TSV data
* @param {object} parser Parser object
* @param {object} xsv Data
* @returns {object}
* @private
*/
function convertCsvTsvToData(parser, xsv) {
var _this = this;
const rows = parser.rows(xsv);
let d;
if (rows.length === 1) {
d = [{}];
rows[0].forEach(function (id) {
_newArrowCheck(this, _this);
d[0][id] = null;
}.bind(this));
} else {
d = parser.parse(xsv);
}
return d;
}
function convert_helper_csv(xsv) {
return convertCsvTsvToData({
rows: csvParseRows,
parse: csvParse
}, xsv);
}
function convert_helper_tsv(tsv) {
return convertCsvTsvToData({
rows: tsvParseRows,
parse: tsvParse
}, tsv);
}
;// CONCATENATED MODULE: ./src/ChartInternal/data/convert.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get data key for JSON
* @param {string|object} keysParam Key params
* @param {object} config Config object
* @returns {string} Data key
* @private
*/
function getDataKeyForJson(keysParam, config) {
const keys = keysParam || (config == null ? void 0 : config.data_keys);
if (keys != null && keys.x) {
config.data_x = keys.x;
}
return keys;
}
/**
* Data convert
* @memberof ChartInternal
* @private
*/
/* harmony default export */ var convert = ({
/**
* Convert data according its type
* @param {object} args data object
* @param {Function} [callback] callback for url(XHR) type loading
* @private
*/
convertData: function convertData(args, callback) {
var _this = this;
const config = this.config,
useWorker = config.boost_useWorker;
let data = args;
if (args.bindto) {
data = {};
["url", "mimeType", "headers", "keys", "json", "keys", "rows", "columns"].forEach(function (v) {
_newArrowCheck(this, _this);
const key = "data_" + v;
if (key in args) {
data[v] = args[key];
}
}.bind(this));
}
if (data.url && callback) {
url(data.url, data.mimeType, data.headers, getDataKeyForJson(data.keys, config), callback);
} else if (data.json) {
runWorker(useWorker, json, callback, [columns, rows])(data.json, getDataKeyForJson(data.keys, config));
} else if (data.rows) {
runWorker(useWorker, rows, callback)(data.rows);
} else if (data.columns) {
runWorker(useWorker, columns, callback)(data.columns);
} else if (args.bindto) {
throw Error("url or json or rows or columns is required.");
}
},
convertDataToTargets: function convertDataToTargets(data, appendXs) {
var _this2 = this;
const $$ = this,
axis = $$.axis,
config = $$.config,
state = $$.state,
chartType = config.data_type;
let isCategorized = !1,
isTimeSeries = !1,
isCustomX = !1;
if (axis) {
isCategorized = axis.isCategorized();
isTimeSeries = axis.isTimeSeries();
isCustomX = axis.isCustomX();
}
const dataKeys = Object.keys(data[0] || {}),
ids = dataKeys.length ? dataKeys.filter($$.isNotX, $$) : [],
xs = dataKeys.length ? dataKeys.filter($$.isX, $$) : [];
let xsData;
// save x for update data by load when custom x and bb.x API
ids.forEach(function (id) {
var _this3 = this;
_newArrowCheck(this, _this2);
const xKey = this.getXKey(id);
if (isCustomX || isTimeSeries) {
// if included in input data
if (xs.indexOf(xKey) >= 0) {
xsData = (appendXs && $$.data.xs[id] || []).concat(data.map(function (d) {
_newArrowCheck(this, _this3);
return d[xKey];
}.bind(this)).filter(isValue).map(function (rawX, i) {
_newArrowCheck(this, _this3);
return $$.generateTargetX(rawX, id, i);
}.bind(this)));
} else if (config.data_x) {
// if not included in input data, find from preloaded data of other id's x
xsData = this.getOtherTargetXs();
} else if (notEmpty(config.data_xs)) {
// if not included in input data, find from preloaded data
xsData = $$.getXValuesOfXKey(xKey, $$.data.targets);
}
// MEMO: if no x included, use same x of current will be used
} else {
xsData = data.map(function (d, i) {
_newArrowCheck(this, _this3);
return i;
}.bind(this));
}
xsData && (this.data.xs[id] = xsData);
}.bind(this));
// check x is defined
ids.forEach(function (id) {
_newArrowCheck(this, _this2);
if (!this.data.xs[id]) {
throw new Error("x is not defined for id = \"" + id + "\".");
}
}.bind(this));
// convert to target
const targets = ids.map(function (id, index) {
var _this4 = this;
_newArrowCheck(this, _this2);
const convertedId = config.data_idConverter.bind($$.api)(id),
xKey = $$.getXKey(id),
isCategory = isCustomX && isCategorized,
hasCategory = isCategory && data.map(function (v) {
_newArrowCheck(this, _this4);
return v.x;
}.bind(this)).every(function (v) {
_newArrowCheck(this, _this4);
return config.axis_x_categories.indexOf(v) > -1;
}.bind(this)),
isDataAppend = data.__append__,
xIndex = xKey === null && isDataAppend ? $$.api.data.values(id).length : 0; // when .load() with 'append' option is used for indexed axis
// @ts-ignore
return {
id: convertedId,
id_org: id,
values: data.map(function (d, i) {
_newArrowCheck(this, _this4);
const rawX = d[xKey];
let value = d[id],
x;
value = value !== null && !isNaN(value) && !isObject(value) ? +value : isArray(value) || isObject(value) ? value : null;
// use x as categories if custom x and categorized
if ((isCategory || state.hasRadar) && index === 0 && !isUndefined(rawX)) {
if (!hasCategory && index === 0 && i === 0 && !isDataAppend) {
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, xIndex + i);
}
// mark as x = undefined if value is undefined and filter to remove after mapped
if (isUndefined(value) || $$.data.xs[id].length <= i) {
x = undefined;
}
return {
x: x,
value: value,
id: convertedId,
index: -1
};
}.bind(this)).filter(function (v) {
_newArrowCheck(this, _this4);
return isDefined(v.x);
}.bind(this))
};
}.bind(this));
// finish targets
targets.forEach(function (t) {
var _this5 = this,
_$$$data$xs$t$id;
_newArrowCheck(this, _this2);
// sort values by its x
if (config.data_xSort) {
t.values = t.values.sort(function (v1, v2) {
_newArrowCheck(this, _this5);
const x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
return x1 - x2;
}.bind(this));
}
// indexing each value
t.values.forEach(function (v, i) {
_newArrowCheck(this, _this5);
return v.index = i;
}.bind(this));
// this needs to be sorted because its index and value.index is identical
(_$$$data$xs$t$id = $$.data.xs[t.id]) == null || _$$$data$xs$t$id.sort(function (v1, v2) {
_newArrowCheck(this, _this5);
return v1 - v2;
}.bind(this));
}.bind(this));
// cache information about values
state.hasNegativeValue = $$.hasNegativeValueInTargets(targets);
state.hasPositiveValue = $$.hasPositiveValueInTargets(targets);
// set target types
if (chartType && $$.isValidChartType(chartType)) {
const targetIds = $$.mapToIds(targets).filter(function (id) {
_newArrowCheck(this, _this2);
return !(id in config.data_types) || !$$.isValidChartType(config.data_types[id]);
}.bind(this));
$$.setTargetType(targetIds, chartType);
}
// cache as original id keyed
targets.forEach(function (d) {
_newArrowCheck(this, _this2);
return $$.cache.add(d.id_org, d, !0);
}.bind(this));
return targets;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/data/data.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var ChartInternal_data_data = ({
isX: function isX(key) {
const $$ = this,
config = $$.config,
dataKey = config.data_x && key === config.data_x,
existValue = notEmpty(config.data_xs) && hasValue(config.data_xs, key);
return dataKey || existValue;
},
isNotX: function isNotX(key) {
return !this.isX(key);
},
isStackNormalized: function isStackNormalized() {
const config = this.config;
return !!(config.data_stack_normalize && config.data_groups.length);
},
/**
* Check if given id is grouped data or has grouped data
* @param {string} id Data id value
* @returns {boolean} is grouped data or has grouped data
* @private
*/
isGrouped: function isGrouped(id) {
var _this = this;
const groups = this.config.data_groups;
return id ? groups.some(function (v) {
_newArrowCheck(this, _this);
return v.indexOf(id) >= 0 && v.length > 1;
}.bind(this)) : groups.length > 0;
},
getXKey: function getXKey(id) {
const $$ = this,
config = $$.config;
return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
},
getXValuesOfXKey: function getXValuesOfXKey(key, targets) {
var _this2 = this;
const $$ = this,
ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
let xValues;
ids.forEach(function (id) {
_newArrowCheck(this, _this2);
if ($$.getXKey(id) === key) {
xValues = $$.data.xs[id];
}
}.bind(this));
return xValues;
},
/**
* Get index number based on given x Axis value
* @param {Date|number|string} x x Axis to be compared
* @param {Array} basedX x Axis list to be based on
* @returns {number} index number
* @private
*/
getIndexByX: function getIndexByX(x, basedX) {
const $$ = this;
return basedX ? basedX.indexOf(isString(x) ? x : +x) : ($$.filterByX($$.data.targets, x)[0] || {
index: null
}).index;
},
getXValue: function getXValue(id, i) {
const $$ = this;
return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
},
getOtherTargetXs: function getOtherTargetXs() {
const $$ = this,
idsForX = Object.keys($$.data.xs);
return idsForX.length ? $$.data.xs[idsForX[0]] : null;
},
getOtherTargetX: function getOtherTargetX(index) {
const xs = this.getOtherTargetXs();
return xs && index < xs.length ? xs[index] : null;
},
addXs: function addXs(xs) {
var _this3 = this;
const $$ = this,
config = $$.config;
Object.keys(xs).forEach(function (id) {
_newArrowCheck(this, _this3);
config.data_xs[id] = xs[id];
}.bind(this));
},
isMultipleX: function isMultipleX() {
return notEmpty(this.config.data_xs) || this.hasType("bubble") || this.hasType("scatter");
},
addName: function addName(data) {
const $$ = this,
config = $$.config;
let name;
if (data) {
name = config.data_names[data.id];
data.name = name !== undefined ? name : data.id;
}
return data;
},
/**
* Get all values on given index
* @param {number} index Index
* @param {boolean} filterNull Filter nullish value
* @returns {Array}
* @private
*/
getAllValuesOnIndex: function getAllValuesOnIndex(index, filterNull) {
var _this4 = this;
if (filterNull === void 0) {
filterNull = !1;
}
const $$ = this;
let value = $$.filterTargetsToShow($$.data.targets).map(function (t) {
_newArrowCheck(this, _this4);
return $$.addName($$.getValueOnIndex(t.values, index));
}.bind(this));
if (filterNull) {
value = value.filter(function (v) {
_newArrowCheck(this, _this4);
return v && "value" in v && isValue(v.value);
}.bind(this));
}
return value;
},
getValueOnIndex: function getValueOnIndex(values, index) {
var _this5 = this;
const valueOnIndex = values.filter(function (v) {
_newArrowCheck(this, _this5);
return v.index === index;
}.bind(this));
return valueOnIndex.length ? valueOnIndex[0] : null;
},
updateTargetX: function updateTargetX(targets, x) {
var _this6 = this;
const $$ = this;
targets.forEach(function (t) {
var _this7 = this;
_newArrowCheck(this, _this6);
t.values.forEach(function (v, i) {
_newArrowCheck(this, _this7);
v.x = $$.generateTargetX(x[i], t.id, i);
}.bind(this));
$$.data.xs[t.id] = x;
}.bind(this));
},
updateTargetXs: function updateTargetXs(targets, xs) {
var _this8 = this;
const $$ = this;
targets.forEach(function (t) {
_newArrowCheck(this, _this8);
xs[t.id] && $$.updateTargetX([t], xs[t.id]);
}.bind(this));
},
generateTargetX: function generateTargetX(rawX, id, index) {
const $$ = this,
axis = $$.axis;
let x = axis != null && axis.isCategorized() ? index : rawX || index;
if (axis != null && axis.isTimeSeries()) {
const fn = parseDate.bind($$);
x = rawX ? fn(rawX) : fn($$.getXValue(id, index));
} else if (axis != null && axis.isCustomX() && !(axis != null && axis.isCategorized())) {
x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
}
return x;
},
updateXs: function updateXs(values) {
var _this9 = this;
if (values.length) {
this.axis.xs = values.map(function (v) {
_newArrowCheck(this, _this9);
return v.x;
}.bind(this));
}
},
getPrevX: function getPrevX(i) {
const x = this.axis.xs[i - 1];
return isDefined(x) ? x : null;
},
getNextX: function getNextX(i) {
const x = this.axis.xs[i + 1];
return isDefined(x) ? x : null;
},
/**
* Get base value isAreaRangeType
* @param {object} data Data object
* @returns {number}
* @private
*/
getBaseValue: function getBaseValue(data) {
const $$ = this,
hasAxis = $$.state.hasAxis;
let value = data.value;
// In case of area-range, data is given as: [low, mid, high] or {low, mid, high}
// will take the 'mid' as the base value
if (value && hasAxis) {
if ($$.isAreaRangeType(data)) {
value = $$.getRangedData(data, "mid");
} else if ($$.isBubbleZType(data)) {
value = $$.getBubbleZData(value, "y");
}
}
return value;
},
/**
* Get min/max value from the data
* @private
* @param {Array} data array data to be evaluated
* @returns {{min: {number}, max: {number}}}
*/
getMinMaxValue: function getMinMaxValue(data) {
var _this10 = this;
const getBaseValue = this.getBaseValue.bind(this);
let min, max;
(data || this.data.targets.map(function (t) {
_newArrowCheck(this, _this10);
return t.values;
}.bind(this))).forEach(function (v, i) {
_newArrowCheck(this, _this10);
const value = v.map(getBaseValue).filter(isNumber);
min = Math.min.apply(Math, [i ? min : Infinity].concat(value));
max = Math.max.apply(Math, [i ? max : -Infinity].concat(value));
}.bind(this));
return {
min: min,
max: max
};
},
/**
* Get the min/max data
* @private
* @returns {{min: Array, max: Array}}
*/
getMinMaxData: function getMinMaxData() {
var _this11 = this;
const $$ = this,
cacheKey = KEY.dataMinMax;
let minMaxData = $$.cache.get(cacheKey);
if (!minMaxData) {
const data = $$.data.targets.map(function (t) {
_newArrowCheck(this, _this11);
return t.values;
}.bind(this)),
minMax = $$.getMinMaxValue(data);
let min = [],
max = [];
data.forEach(function (v) {
_newArrowCheck(this, _this11);
const minData = $$.getFilteredDataByValue(v, minMax.min),
maxData = $$.getFilteredDataByValue(v, minMax.max);
if (minData.length) {
min = min.concat(minData);
}
if (maxData.length) {
max = max.concat(maxData);
}
}.bind(this));
// update the cached data
$$.cache.add(cacheKey, minMaxData = {
min: min,
max: max
});
}
return minMaxData;
},
/**
* Get sum of data per index
* @private
* @returns {Array}
*/
getTotalPerIndex: function getTotalPerIndex() {
var _this12 = this;
const $$ = this,
cacheKey = KEY.dataTotalPerIndex;
let sum = $$.cache.get(cacheKey);
if (($$.config.data_groups.length || $$.isStackNormalized()) && !sum) {
sum = [];
$$.data.targets.forEach(function (row) {
var _this13 = this;
_newArrowCheck(this, _this12);
row.values.forEach(function (v, i) {
_newArrowCheck(this, _this13);
if (!sum[i]) {
sum[i] = 0;
}
sum[i] += isNumber(v.value) ? v.value : 0;
}.bind(this));
}.bind(this));
}
return sum;
},
/**
* Get total data sum
* @param {boolean} subtractHidden Subtract hidden data from total
* @returns {number}
* @private
*/
getTotalDataSum: function getTotalDataSum(subtractHidden) {
var _this14 = this;
const $$ = this,
cacheKey = KEY.dataTotalSum;
let total = $$.cache.get(cacheKey);
if (!isNumber(total)) {
const sum = mergeArray($$.data.targets.map(function (t) {
_newArrowCheck(this, _this14);
return t.values;
}.bind(this))).map(function (v) {
_newArrowCheck(this, _this14);
return v.value;
}.bind(this));
total = sum.length ? sum.reduce(function (p, c) {
_newArrowCheck(this, _this14);
return p + c;
}.bind(this)) : 0;
$$.cache.add(cacheKey, total);
}
if (subtractHidden) {
total -= $$.getHiddenTotalDataSum();
}
return total;
},
/**
* Get total hidden data sum
* @returns {number}
* @private
*/
getHiddenTotalDataSum: function getHiddenTotalDataSum() {
var _this15 = this;
const $$ = this,
api = $$.api,
hiddenTargetIds = $$.state.hiddenTargetIds;
let total = 0;
if (hiddenTargetIds.length) {
total = api.data.values.bind(api)(hiddenTargetIds).reduce(function (p, c) {
_newArrowCheck(this, _this15);
return p + c;
}.bind(this));
}
return total;
},
/**
* Get filtered data by value
* @param {object} data Data
* @param {number} value Value to be filtered
* @returns {Array} filtered array data
* @private
*/
getFilteredDataByValue: function getFilteredDataByValue(data, value) {
var _this16 = this;
return data.filter(function (t) {
_newArrowCheck(this, _this16);
return this.getBaseValue(t) === value;
}.bind(this));
},
/**
* Return the max length of the data
* @returns {number} max data length
* @private
*/
getMaxDataCount: function getMaxDataCount() {
var _this17 = this;
return Math.max.apply(Math, this.data.targets.map(function (t) {
_newArrowCheck(this, _this17);
return t.values.length;
}.bind(this)).concat([0]));
},
getMaxDataCountTarget: function getMaxDataCountTarget() {
var _this18 = this;
let target = this.filterTargetsToShow() || [];
const length = target.length,
isInverted = this.config.axis_x_inverted;
if (length > 1) {
target = target.map(function (t) {
_newArrowCheck(this, _this18);
return t.values;
}.bind(this)).reduce(function (a, b) {
_newArrowCheck(this, _this18);
return a.concat(b);
}.bind(this)).map(function (v) {
_newArrowCheck(this, _this18);
return v.x;
}.bind(this));
target = sortValue(getUnique(target)).map(function (x, index, array) {
_newArrowCheck(this, _this18);
return {
x: x,
index: isInverted ? array.length - index - 1 : index
};
}.bind(this));
} else if (length) {
target = target[0].values.concat();
}
return target;
},
mapToIds: function mapToIds(targets) {
var _this19 = this;
return targets.map(function (d) {
_newArrowCheck(this, _this19);
return d.id;
}.bind(this));
},
mapToTargetIds: function mapToTargetIds(ids) {
const $$ = this;
return ids ? isArray(ids) ? ids.concat() : [ids] : $$.mapToIds($$.data.targets);
},
hasTarget: function hasTarget(targets, id) {
const ids = this.mapToIds(targets);
for (let i = 0, val; val = ids[i]; i++) {
if (val === id) {
return !0;
}
}
return !1;
},
isTargetToShow: function isTargetToShow(targetId) {
return this.state.hiddenTargetIds.indexOf(targetId) < 0;
},
isLegendToShow: function isLegendToShow(targetId) {
return this.state.hiddenLegendIds.indexOf(targetId) < 0;
},
filterTargetsToShow: function filterTargetsToShow(targets) {
var _this20 = this;
const $$ = this;
return (targets || $$.data.targets).filter(function (t) {
_newArrowCheck(this, _this20);
return $$.isTargetToShow(t.id);
}.bind(this));
},
mapTargetsToUniqueXs: function mapTargetsToUniqueXs(targets) {
var _this21 = this;
const $$ = this,
axis = $$.axis;
let xs = [];
if (targets != null && targets.length) {
xs = getUnique(mergeArray(targets.map(function (t) {
var _this22 = this;
_newArrowCheck(this, _this21);
return t.values.map(function (v) {
_newArrowCheck(this, _this22);
return +v.x;
}.bind(this));
}.bind(this))));
xs = axis != null && axis.isTimeSeries() ? xs.map(function (x) {
_newArrowCheck(this, _this21);
return new Date(+x);
}.bind(this)) : xs.map(Number);
}
return sortValue(xs);
},
/**
* Add to the state target Ids
* @param {string} type State's prop name
* @param {Array|string} targetIds Target ids array
* @private
*/
addTargetIds: function addTargetIds(type, targetIds) {
var _this23 = this;
const state = this.state,
ids = isArray(targetIds) ? targetIds : [targetIds];
ids.forEach(function (v) {
_newArrowCheck(this, _this23);
state[type].indexOf(v) < 0 && state[type].push(v);
}.bind(this));
},
/**
* Remove from the state target Ids
* @param {string} type State's prop name
* @param {Array|string} targetIds Target ids array
* @private
*/
removeTargetIds: function removeTargetIds(type, targetIds) {
var _this24 = this;
const state = this.state,
ids = isArray(targetIds) ? targetIds : [targetIds];
ids.forEach(function (v) {
_newArrowCheck(this, _this24);
const index = state[type].indexOf(v);
index >= 0 && state[type].splice(index, 1);
}.bind(this));
},
addHiddenTargetIds: function addHiddenTargetIds(targetIds) {
this.addTargetIds("hiddenTargetIds", targetIds);
},
removeHiddenTargetIds: function removeHiddenTargetIds(targetIds) {
this.removeTargetIds("hiddenTargetIds", targetIds);
},
addHiddenLegendIds: function addHiddenLegendIds(targetIds) {
this.addTargetIds("hiddenLegendIds", targetIds);
},
removeHiddenLegendIds: function removeHiddenLegendIds(targetIds) {
this.removeTargetIds("hiddenLegendIds", targetIds);
},
getValuesAsIdKeyed: function getValuesAsIdKeyed(targets) {
var _this25 = this;
const $$ = this,
hasAxis = $$.state.hasAxis,
ys = {},
isMultipleX = $$.isMultipleX(),
xs = isMultipleX ? $$.mapTargetsToUniqueXs(targets).map(function (v) {
_newArrowCheck(this, _this25);
return isString(v) ? v : +v;
}.bind(this)) : null;
targets.forEach(function (t) {
var _this26 = this;
_newArrowCheck(this, _this25);
const data = [];
t.values.filter(function (_ref) {
let value = _ref.value;
_newArrowCheck(this, _this26);
return isValue(value) || value === null;
}.bind(this)).forEach(function (v) {
_newArrowCheck(this, _this26);
let value = v.value;
// exclude 'volume' value to correct mis domain calculation
if (value !== null && $$.isCandlestickType(v)) {
value = isArray(value) ? value.slice(0, 4) : [value.open, value.high, value.low, value.close];
}
if (isArray(value)) {
data.push.apply(data, value);
} else if (isObject(value) && "high" in value) {
data.push.apply(data, Object.values(value));
} else if ($$.isBubbleZType(v)) {
data.push(hasAxis && $$.getBubbleZData(value, "y"));
} else {
if (isMultipleX) {
data[$$.getIndexByX(v.x, xs)] = value;
} else {
data.push(value);
}
}
}.bind(this));
ys[t.id] = data;
}.bind(this));
return ys;
},
checkValueInTargets: function checkValueInTargets(targets, checker) {
const ids = Object.keys(targets);
let values;
for (let i = 0; i < ids.length; i++) {
values = targets[ids[i]].values;
for (let j = 0; j < values.length; j++) {
if (checker(values[j].value)) {
return !0;
}
}
}
return !1;
},
hasMultiTargets: function hasMultiTargets() {
return this.filterTargetsToShow().length > 1;
},
hasNegativeValueInTargets: function hasNegativeValueInTargets(targets) {
var _this27 = this;
return this.checkValueInTargets(targets, function (v) {
_newArrowCheck(this, _this27);
return v < 0;
}.bind(this));
},
hasPositiveValueInTargets: function hasPositiveValueInTargets(targets) {
var _this28 = this;
return this.checkValueInTargets(targets, function (v) {
_newArrowCheck(this, _this28);
return v > 0;
}.bind(this));
},
/**
* Sort targets data
* Note: For stacked bar, will sort from the total sum of data series, not for each stacked bar
* @param {Array} targetsValue Target value
* @returns {Array}
* @private
*/
orderTargets: function orderTargets(targetsValue) {
const $$ = this,
targets = [].concat(targetsValue),
fn = $$.getSortCompareFn();
fn && targets.sort(fn);
return targets;
},
/**
* Get data.order compare function
* @param {boolean} isReversed for Arc & Treemap type sort order needs to be reversed
* @returns {Function} compare function
* @private
*/
getSortCompareFn: function getSortCompareFn(isReversed) {
var _this29 = this;
if (isReversed === void 0) {
isReversed = !1;
}
const $$ = this,
config = $$.config,
order = config.data_order,
orderAsc = /asc/i.test(order),
orderDesc = /desc/i.test(order);
let fn;
if (orderAsc || orderDesc) {
const reducer = function (p, c) {
_newArrowCheck(this, _this29);
return p + Math.abs(c.value);
}.bind(this),
sum = function (v) {
_newArrowCheck(this, _this29);
return isNumber(v) ? v : "values" in v ? v.values.reduce(reducer, 0) : v.value;
}.bind(this);
fn = function (t1, t2) {
_newArrowCheck(this, _this29);
const t1Sum = sum(t1),
t2Sum = sum(t2);
return isReversed ? orderAsc ? t1Sum - t2Sum : t2Sum - t1Sum : orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
}.bind(this);
} else if (isFunction(order)) {
fn = order.bind($$.api);
}
return fn || null;
},
filterByX: function filterByX(targets, x) {
var _this30 = this;
return mergeArray(targets.map(function (t) {
_newArrowCheck(this, _this30);
return t.values;
}.bind(this))).filter(function (v) {
_newArrowCheck(this, _this30);
return v.x - x === 0;
}.bind(this));
},
filterRemoveNull: function filterRemoveNull(data) {
var _this31 = this;
return data.filter(function (d) {
_newArrowCheck(this, _this31);
return isValue(this.getBaseValue(d));
}.bind(this));
},
filterByXDomain: function filterByXDomain(targets, xDomain) {
var _this32 = this;
return targets.map(function (t) {
var _this33 = this;
_newArrowCheck(this, _this32);
return {
id: t.id,
id_org: t.id_org,
values: t.values.filter(function (v) {
_newArrowCheck(this, _this33);
return xDomain[0] <= v.x && v.x <= xDomain[1];
}.bind(this))
};
}.bind(this));
},
hasDataLabel: function hasDataLabel() {
const dataLabels = this.config.data_labels;
return isboolean(dataLabels) && dataLabels || isObjectType(dataLabels) && notEmpty(dataLabels);
},
/**
* Get data index from the event coodinates
* @param {Event} event Event object
* @returns {number}
*/
getDataIndexFromEvent: function getDataIndexFromEvent(event) {
const $$ = this,
$el = $$.$el,
config = $$.config,
_$$$state = $$.state,
hasRadar = _$$$state.hasRadar,
inputType = _$$$state.inputType,
_$$$state$eventReceiv = _$$$state.eventReceiver,
coords = _$$$state$eventReceiv.coords,
rect = _$$$state$eventReceiv.rect;
let index;
if (hasRadar) {
let target = event.target;
// in case of multilined axis text
if (/tspan/i.test(target.tagName)) {
target = target.parentNode;
}
const d = src_select(target).datum();
index = d && Object.keys(d).length === 1 ? d.index : undefined;
} else {
const isRotated = config.axis_rotated,
scrollPos = getScrollPosition($el.chart.node()),
e = inputType === "touch" && event.changedTouches ? event.changedTouches[0] : event; // get data based on the mouse coords
index = findIndex(coords, isRotated ? e.clientY + scrollPos.y - rect.top : e.clientX + scrollPos.x - rect.left, 0, coords.length - 1, isRotated);
}
return index;
},
getDataLabelLength: function getDataLabelLength(min, max, key) {
var _this34 = this;
const $$ = this,
lengths = [0, 0];
$$.$el.chart.select("svg").selectAll(".dummy").data([min, max]).enter().append("text").text(function (d) {
_newArrowCheck(this, _this34);
return $$.dataLabelFormat(d.id)(d);
}.bind(this)).each(function (d, i) {
lengths[i] = this.getBoundingClientRect()[key] * 1.3;
}).remove();
return lengths;
},
isNoneArc: function isNoneArc(d) {
return this.hasTarget(this.data.targets, d.id);
},
isArc: function isArc(d) {
return "data" in d && this.hasTarget(this.data.targets, d.data.id);
},
findSameXOfValues: function findSameXOfValues(values, index) {
const targetX = values[index].x,
sames = [];
let i;
for (i = index - 1; i >= 0; i--) {
if (targetX !== values[i].x) {
break;
}
sames.push(values[i]);
}
for (i = index; i < values.length; i++) {
if (targetX !== values[i].x) {
break;
}
sames.push(values[i]);
}
return sames;
},
findClosestFromTargets: function findClosestFromTargets(targets, pos) {
var _this35 = this;
const $$ = this,
candidates = targets.map(function (target) {
_newArrowCheck(this, _this35);
return $$.findClosest(target.values, pos);
}.bind(this));
// map to array of closest points of each target
// decide closest point and return
return $$.findClosest(candidates, pos);
},
findClosest: function findClosest(values, pos) {
var _this36 = this;
const $$ = this,
main = $$.$el.main,
data = values.filter(function (v) {
_newArrowCheck(this, _this36);
return v && isValue(v.value);
}.bind(this));
let minDist, closest;
// find mouseovering bar/candlestick
// https://github.com/naver/billboard.js/issues/2434
data.filter(function (v) {
_newArrowCheck(this, _this36);
return $$.isBarType(v.id) || $$.isCandlestickType(v.id);
}.bind(this)).forEach(function (v) {
_newArrowCheck(this, _this36);
const selector = $$.isBarType(v.id) ? "." + $BAR.chartBar + "." + $COMMON.target + $$.getTargetSelectorSuffix(v.id) + " ." + $BAR.bar + "-" + v.index : "." + $CANDLESTICK.chartCandlestick + "." + $COMMON.target + $$.getTargetSelectorSuffix(v.id) + " ." + $CANDLESTICK.candlestick + "-" + v.index + " path";
if (!closest && $$.isWithinBar(main.select(selector).node())) {
closest = v;
}
}.bind(this));
// find closest point from non-bar/candlestick
data.filter(function (v) {
_newArrowCheck(this, _this36);
return !$$.isBarType(v.id) && !$$.isCandlestickType(v.id);
}.bind(this)).forEach(function (v) {
_newArrowCheck(this, _this36);
const d = $$.dist(v, pos);
minDist = $$.getPointSensitivity(v);
if (d < minDist) {
minDist = d;
closest = v;
}
}.bind(this));
return closest;
},
dist: function dist(data, pos) {
const $$ = this,
isRotated = $$.config.axis_rotated,
scale = $$.scale,
y = $$.circleY(data, data.index),
x = (scale.zoom || scale.x)(data.x);
// true: 1, false: 0
// true: 0, false: 1
return Math.sqrt(Math.pow(x - pos[+isRotated], 2) + Math.pow(y - pos[+!isRotated], 2));
},
/**
* Convert data for step type
* @param {Array} values Object data values
* @returns {Array}
* @private
*/
convertValuesToStep: function convertValuesToStep(values) {
const $$ = this,
axis = $$.axis,
config = $$.config,
stepType = config.line_step_type,
isCategorized = axis ? axis.isCategorized() : !1,
converted = isArray(values) ? values.concat() : [values];
if (!(isCategorized || /step\-(after|before)/.test(stepType))) {
return values;
}
// when all datas are null, return empty array
// https://github.com/naver/billboard.js/issues/3124
if (converted.length) {
// insert & append cloning first/last value to be fully rendered covering on each gap sides
const head = converted[0],
tail = converted[converted.length - 1],
id = head.id;
let x = head.x;
// insert head
converted.unshift({
x: --x,
value: head.value,
id: id
});
isCategorized && stepType === "step-after" && converted.unshift({
x: --x,
value: head.value,
id: id
});
// append tail
x = tail.x;
converted.push({
x: ++x,
value: tail.value,
id: id
});
isCategorized && stepType === "step-before" && converted.push({
x: ++x,
value: tail.value,
id: id
});
}
return converted;
},
convertValuesToRange: function convertValuesToRange(values) {
var _this37 = this;
const converted = isArray(values) ? values.concat() : [values],
ranges = [];
converted.forEach(function (range) {
_newArrowCheck(this, _this37);
const x = range.x,
id = range.id;
ranges.push({
x: x,
id: id,
value: range.value[0]
});
ranges.push({
x: x,
id: id,
value: range.value[2]
});
}.bind(this));
return ranges;
},
updateDataAttributes: function updateDataAttributes(name, attrs) {
var _this38 = this;
const $$ = this,
config = $$.config,
current = config["data_" + name];
if (isUndefined(attrs)) {
return current;
}
Object.keys(attrs).forEach(function (id) {
_newArrowCheck(this, _this38);
current[id] = attrs[id];
}.bind(this));
$$.redraw({
withLegend: !0
});
return current;
},
getRangedData: function getRangedData(d, key, type) {
var _this39 = this;
if (key === void 0) {
key = "";
}
if (type === void 0) {
type = "areaRange";
}
const value = d == null ? void 0 : d.value;
if (isArray(value)) {
if (type === "bar") {
return value.reduce(function (a, c) {
_newArrowCheck(this, _this39);
return c - a;
}.bind(this));
} else {
// @ts-ignore
const index = {
areaRange: ["high", "mid", "low"],
candlestick: ["open", "high", "low", "close", "volume"]
}[type].indexOf(key);
return index >= 0 && value ? value[index] : undefined;
}
} else if (value && key) {
return value[key];
}
return value;
},
/**
* Set ratio for grouped data
* @param {Array} data Data array
* @private
*/
setRatioForGroupedData: function setRatioForGroupedData(data) {
var _this40 = this;
const $$ = this,
config = $$.config;
// calculate ratio if grouped data exists
if (config.data_groups.length && data.some(function (d) {
_newArrowCheck(this, _this40);
return $$.isGrouped(d.id);
}.bind(this))) {
const setter = function (d) {
_newArrowCheck(this, _this40);
return $$.getRatio("index", d, !0);
}.bind(this);
data.forEach(function (v) {
_newArrowCheck(this, _this40);
"values" in v ? v.values.forEach(setter) : setter(v);
}.bind(this));
}
},
/**
* Get ratio value
* @param {string} type Ratio for given type
* @param {object} d Data value object
* @param {boolean} asPercent Convert the return as percent or not
* @returns {number} Ratio value
* @private
*/
getRatio: function getRatio(type, d, asPercent) {
var _this41 = this;
if (asPercent === void 0) {
asPercent = !1;
}
const $$ = this,
config = $$.config,
state = $$.state,
api = $$.api;
let ratio = 0;
if (d && api.data.shown().length) {
ratio = d.ratio || d.value;
if (type === "arc") {
// if has padAngle set, calculate rate based on value
if ($$.pie.padAngle()()) {
ratio = d.value / $$.getTotalDataSum(!0);
// otherwise, based on the rendered angle value
} else {
const gaugeArcLength = config.gauge_fullCircle ? $$.getArcLength() : $$.getStartingAngle() * -2,
arcLength = $$.hasType("gauge") ? gaugeArcLength : Math.PI * 2;
ratio = (d.endAngle - d.startAngle) / arcLength;
}
} else if (type === "index") {
const dataValues = api.data.values.bind(api);
let total = this.getTotalPerIndex();
if (state.hiddenTargetIds.length) {
let hiddenSum = dataValues(state.hiddenTargetIds, !1);
if (hiddenSum.length) {
hiddenSum = hiddenSum.reduce(function (acc, curr) {
var _this42 = this;
_newArrowCheck(this, _this41);
return acc.map(function (v, i) {
_newArrowCheck(this, _this42);
return (isNumber(v) ? v : 0) + curr[i];
}.bind(this));
}.bind(this));
total = total.map(function (v, i) {
_newArrowCheck(this, _this41);
return v - hiddenSum[i];
}.bind(this));
}
}
const divisor = total[d.index];
d.ratio = isNumber(d.value) && total && divisor ? d.value / divisor : 0;
ratio = d.ratio;
} else if (type === "radar") {
ratio = parseFloat(Math.max(d.value, 0) + "") / state.current.dataMax * config.radar_size_ratio;
} else if (type === "bar") {
const yScale = $$.getYScaleById.bind($$)(d.id),
max = yScale.domain().reduce(function (a, c) {
_newArrowCheck(this, _this41);
return c - a;
}.bind(this));
// when all data are 0, return 0
ratio = max === 0 ? 0 : Math.abs($$.getRangedData(d, null, type) / max);
} else if (type === "treemap") {
ratio /= $$.getTotalDataSum(!0);
}
}
return asPercent && ratio ? ratio * 100 : ratio;
},
/**
* Sort data index to be aligned with x axis.
* @param {Array} tickValues Tick array values
* @private
*/
updateDataIndexByX: function updateDataIndexByX(tickValues) {
var _this43 = this;
const $$ = this,
tickValueMap = tickValues.reduce(function (out, tick, index) {
_newArrowCheck(this, _this43);
out[+tick.x] = index;
return out;
}.bind(this), {});
$$.data.targets.forEach(function (t) {
var _this44 = this;
_newArrowCheck(this, _this43);
t.values.forEach(function (value, valueIndex) {
_newArrowCheck(this, _this44);
let index = tickValueMap[+value.x];
if (index === undefined) {
index = valueIndex;
}
value.index = index;
}.bind(this));
}.bind(this));
},
/**
* Determine if bubble has dimension data
* @param {object|Array} d data value
* @returns {boolean}
* @private
*/
isBubbleZType: function isBubbleZType(d) {
const $$ = this;
return $$.isBubbleType(d) && (isObject(d.value) && ("z" in d.value || "y" in d.value) || isArray(d.value) && d.value.length >= 2);
},
/**
* Determine if bar has ranged data
* @param {Array} d data value
* @returns {boolean}
* @private
*/
isBarRangeType: function isBarRangeType(d) {
var _this45 = this;
const $$ = this,
value = d.value;
return $$.isBarType(d) && isArray(value) && value.length >= 2 && value.every(function (v) {
_newArrowCheck(this, _this45);
return isNumber(v);
}.bind(this));
},
/**
* Get data object by id
* @param {string} id data id
* @returns {object}
* @private
*/
getDataById: function getDataById(id) {
var _d$;
const d = this.cache.get(id) || this.api.data(id);
return (_d$ = d == null ? void 0 : d[0]) != null ? _d$ : d;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/data/load.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Call done callback with resize after transition
* @param {Function} fn Callback function
* @param {boolean} resizeAfter Weather to resize chart after the load
* @private
*/
function callDone(fn, resizeAfter) {
if (resizeAfter === void 0) {
resizeAfter = !1;
}
const $$ = this,
api = $$.api;
resizeAfter && $$.api.flush(!0);
fn == null || fn.call(api);
}
/* harmony default export */ var load = ({
load: function load(rawTargets, args) {
var _this = this;
const $$ = this,
axis = $$.axis,
data = $$.data,
org = $$.org,
scale = $$.scale,
append = args.append,
zoomState = {
domain: null,
currentDomain: null,
x: null
};
let targets = rawTargets;
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 _args$types;
_newArrowCheck(this, _this);
const type = ((_args$types = args.types) == null ? void 0 : _args$types[t.id]) || args.type;
$$.setTargetType(t.id, type);
}.bind(this));
}
// Update/Add data
data.targets.forEach(function (d) {
_newArrowCheck(this, _this);
for (let i = 0; i < targets.length; i++) {
if (d.id === targets[i].id) {
d.values = append ? d.values.concat(targets[i].values) : targets[i].values;
targets.splice(i, 1);
break;
}
}
}.bind(this));
data.targets = data.targets.concat(targets); // add remained
}
// Set targets
$$.updateTargets(data.targets);
if (scale.zoom) {
zoomState.x = axis.isCategorized() ? scale.x.orgScale() : (org.xScale || scale.x).copy();
zoomState.domain = $$.getXDomain(data.targets); // get updated xDomain
zoomState.x.domain(zoomState.domain);
zoomState.currentDomain = $$.zoom.getDomain(); // current zoomed domain
// reset zoom state when new data loaded is out of range
if (!$$.withinRange(zoomState.currentDomain, undefined, zoomState.domain)) {
scale.x.domain(zoomState.domain);
scale.zoom = null;
$$.$el.eventRect.property("__zoom", null);
}
}
// Redraw with new targets
$$.redraw({
withUpdateOrgXDomain: !0,
withUpdateXDomain: !0,
withLegend: !0
});
// when load happens on zoom state
if (scale.zoom) {
// const x = (axis.isCategorized() ? scale.x.orgScale() : (org.xScale || scale.x)).copy();
org.xDomain = zoomState.domain;
org.xScale = zoomState.x;
if (axis.isCategorized()) {
zoomState.currentDomain = $$.getZoomDomainValue(zoomState.currentDomain);
org.xDomain = $$.getZoomDomainValue(org.xDomain);
org.xScale = zoomState.x.domain(org.xDomain);
}
$$.updateCurrentZoomTransform(zoomState.x, zoomState.currentDomain);
}
// Update current state chart type and elements list after redraw
$$.updateTypesElements();
callDone.call($$, args.done, args.resizeAfter);
},
loadFromArgs: function loadFromArgs(args) {
var _this2 = this;
const $$ = this;
// prevent load when chart is already destroyed
if (!$$.config) {
return;
}
// reset internally cached data
$$.cache.reset();
$$.convertData(args, function (d) {
_newArrowCheck(this, _this2);
const data = args.data || d;
args.append && (data.__append__ = !0);
data && $$.load($$.convertDataToTargets(data), args);
}.bind(this));
},
unload: function unload(rawTargetIds, customDoneCb) {
var _this3 = this;
const $$ = this,
state = $$.state,
$el = $$.$el,
$T = $$.$T,
hasLegendDefsPoint = !!($$.hasLegendDefsPoint != null && $$.hasLegendDefsPoint());
let done = customDoneCb,
targetIds = rawTargetIds;
// reset internally cached data
$$.cache.reset();
if (!done) {
done = function () {
_newArrowCheck(this, _this3);
}.bind(this);
}
// filter existing target
targetIds = targetIds.filter(function (id) {
_newArrowCheck(this, _this3);
return $$.hasTarget($$.data.targets, id);
}.bind(this));
// If no target, call done and return
if (!targetIds || targetIds.length === 0) {
done();
return;
}
const targets = $el.svg.selectAll(targetIds.map(function (id) {
_newArrowCheck(this, _this3);
return $$.selectorTarget(id);
}.bind(this)));
$T(targets).style("opacity", "0").remove().call(endall, done);
targetIds.forEach(function (id) {
var _this4 = this,
_$el$defs;
_newArrowCheck(this, _this3);
const suffixId = $$.getTargetSelectorSuffix(id);
// Reset fadein for future load
state.withoutFadeIn[id] = !1;
// Remove target's elements
if ($el.legend) {
$el.legend.selectAll("." + $LEGEND.legendItem + suffixId).remove();
}
// Remove target
$$.data.targets = $$.data.targets.filter(function (t) {
_newArrowCheck(this, _this4);
return t.id !== id;
}.bind(this));
// Remove custom point def element
hasLegendDefsPoint && ((_$el$defs = $el.defs) == null ? void 0 : _$el$defs.select("#" + $$.getDefsPointId(suffixId)).remove());
}.bind(this));
// since treemap uses different data types, it needs to be transformed
state.hasTreemap && $$.updateTargetsForTreemap($$.data.targets);
// Update current state chart type and elements list after redraw
$$.updateTypesElements();
}
});
;// CONCATENATED MODULE: ./node_modules/d3-drag/src/constant.js
var d3_drag_src_constant_this = undefined;
/* harmony default export */ var d3_drag_src_constant = ((function (x) {
var _this2 = this;
_newArrowCheck(this, d3_drag_src_constant_this);
return function () {
_newArrowCheck(this, _this2);
return x;
}.bind(this);
}).bind(undefined));
;// CONCATENATED MODULE: ./node_modules/d3-drag/src/event.js
function DragEvent(type, _ref) {
let sourceEvent = _ref.sourceEvent,
subject = _ref.subject,
target = _ref.target,
identifier = _ref.identifier,
active = _ref.active,
x = _ref.x,
y = _ref.y,
dx = _ref.dx,
dy = _ref.dy,
dispatch = _ref.dispatch;
Object.defineProperties(this, {
type: {
value: type,
enumerable: !0,
configurable: !0
},
sourceEvent: {
value: sourceEvent,
enumerable: !0,
configurable: !0
},
subject: {
value: subject,
enumerable: !0,
configurable: !0
},
target: {
value: target,
enumerable: !0,
configurable: !0
},
identifier: {
value: identifier,
enumerable: !0,
configurable: !0
},
active: {
value: active,
enumerable: !0,
configurable: !0
},
x: {
value: x,
enumerable: !0,
configurable: !0
},
y: {
value: y,
enumerable: !0,
configurable: !0
},
dx: {
value: dx,
enumerable: !0,
configurable: !0
},
dy: {
value: dy,
enumerable: !0,
configurable: !0
},
_: {
value: dispatch
}
});
}
DragEvent.prototype.on = function () {
var value = this._.on.apply(this._, arguments);
return value === this._ ? this : value;
};
;// CONCATENATED MODULE: ./node_modules/d3-drag/src/drag.js
// Ignore right-click, since that should open the context menu.
function drag_defaultFilter(event) {
return !event.ctrlKey && !event.button;
}
function defaultContainer() {
return this.parentNode;
}
function defaultSubject(event, d) {
return d == null ? {
x: event.x,
y: event.y
} : d;
}
function drag_defaultTouchable() {
return navigator.maxTouchPoints || "ontouchstart" in this;
}
/* harmony default export */ function drag() {
var filter = drag_defaultFilter,
container = defaultContainer,
subject = defaultSubject,
touchable = drag_defaultTouchable,
gestures = {},
listeners = src_dispatch("start", "drag", "end"),
active = 0,
mousedownx,
mousedowny,
mousemoving,
touchending,
clickDistance2 = 0;
function drag(selection) {
selection.on("mousedown.drag", mousedowned).filter(touchable).on("touchstart.drag", touchstarted).on("touchmove.drag", touchmoved, nonpassive).on("touchend.drag touchcancel.drag", touchended).style("touch-action", "none").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
}
function mousedowned(event, d) {
if (touchending || !filter.call(this, event, d)) return;
var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse");
if (!gesture) return;
src_select(event.view).on("mousemove.drag", mousemoved, nonpassivecapture).on("mouseup.drag", mouseupped, nonpassivecapture);
nodrag(event.view);
nopropagation(event);
mousemoving = !1;
mousedownx = event.clientX;
mousedowny = event.clientY;
gesture("start", event);
}
function mousemoved(event) {
noevent(event);
if (!mousemoving) {
var dx = event.clientX - mousedownx,
dy = event.clientY - mousedowny;
mousemoving = dx * dx + dy * dy > clickDistance2;
}
gestures.mouse("drag", event);
}
function mouseupped(event) {
src_select(event.view).on("mousemove.drag mouseup.drag", null);
yesdrag(event.view, mousemoving);
noevent(event);
gestures.mouse("end", event);
}
function touchstarted(event, d) {
if (!filter.call(this, event, d)) return;
var touches = event.changedTouches,
c = container.call(this, event, d),
n = touches.length,
i,
gesture;
for (i = 0; i < n; ++i) {
if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) {
nopropagation(event);
gesture("start", event, touches[i]);
}
}
}
function touchmoved(event) {
var touches = event.changedTouches,
n = touches.length,
i,
gesture;
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches[i].identifier]) {
noevent(event);
gesture("drag", event, touches[i]);
}
}
}
function touchended(event) {
var touches = event.changedTouches,
n = touches.length,
i,
gesture;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function () {
touchending = null;
}, 500); // Ghost clicks are delayed!
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches[i].identifier]) {
nopropagation(event);
gesture("end", event, touches[i]);
}
}
}
function beforestart(that, container, event, d, identifier, touch) {
var dispatch = listeners.copy(),
p = src_pointer(touch || event, container),
dx,
dy,
s;
if ((s = subject.call(that, new DragEvent("beforestart", {
sourceEvent: event,
target: drag,
identifier: identifier,
active: active,
x: p[0],
y: p[1],
dx: 0,
dy: 0,
dispatch: dispatch
}), d)) == null) return;
dx = s.x - p[0] || 0;
dy = s.y - p[1] || 0;
return function gesture(type, event, touch) {
var p0 = p,
n;
switch (type) {
case "start":
gestures[identifier] = gesture, n = active++;
break;
case "end":
delete gestures[identifier], --active;
// falls through
case "drag":
p = src_pointer(touch || event, container), n = active;
break;
}
dispatch.call(type, that, new DragEvent(type, {
sourceEvent: event,
subject: s,
target: drag,
identifier: identifier,
active: n,
x: p[0] + dx,
y: p[1] + dy,
dx: p[0] - p0[0],
dy: p[1] - p0[1],
dispatch: dispatch
}), d);
};
}
drag.filter = function (_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : d3_drag_src_constant(!!_), drag) : filter;
};
drag.container = function (_) {
return arguments.length ? (container = typeof _ === "function" ? _ : d3_drag_src_constant(_), drag) : container;
};
drag.subject = function (_) {
return arguments.length ? (subject = typeof _ === "function" ? _ : d3_drag_src_constant(_), drag) : subject;
};
drag.touchable = function (_) {
return arguments.length ? (touchable = typeof _ === "function" ? _ : d3_drag_src_constant(!!_), drag) : touchable;
};
drag.on = function () {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? drag : value;
};
drag.clickDistance = function (_) {
return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
};
return drag;
}
;// CONCATENATED MODULE: ./src/ChartInternal/interactions/interaction.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var interactions_interaction = ({
/**
* Expand data shape/point
* @param {number} index Index number
* @param {string} id Data id
* @param {boolean} reset Reset expand state
* @private
*/
setExpand: function setExpand(index, id, reset) {
const $$ = this,
config = $$.config,
circle = $$.$el.circle;
circle && config.point_focus_expand_enabled && $$.expandCircles(index, id, reset);
// bar, candlestick
$$.expandBarTypeShapes(!0, index, id, reset);
},
/**
* Expand/Unexpand bar type shapes
* @param {boolean} expand Expand or unexpand
* @param {number} i Shape index
* @param {string} id Data id
* @param {boolean} reset Reset expand style
* @private
*/
expandBarTypeShapes: function expandBarTypeShapes(expand, i, id, reset) {
var _this = this;
if (expand === void 0) {
expand = !0;
}
const $$ = this;
["bar", "candlestick"].filter(function (v) {
_newArrowCheck(this, _this);
return $$.$el[v];
}.bind(this)).forEach(function (v) {
_newArrowCheck(this, _this);
reset && $$.$el[v].classed($COMMON.EXPANDED, !1);
$$.getShapeByIndex(v, i, id).classed($COMMON.EXPANDED, expand);
}.bind(this));
},
/**
* Handle data.onover/out callback options
* @param {boolean} isOver Over or not
* @param {number|object} d data object
* @private
*/
setOverOut: function setOverOut(isOver, d) {
var _this3 = this;
const $$ = this,
config = $$.config,
_$$$state = $$.state,
hasRadar = _$$$state.hasRadar,
hasTreemap = _$$$state.hasTreemap,
main = $$.$el.main,
isArcTreemap = isObject(d);
// Call event handler
if (isArcTreemap || d !== -1) {
const callback = config[isOver ? "data_onover" : "data_onout"].bind($$.api);
config.color_onover && $$.setOverColor(isOver, d, isArcTreemap);
if (isArcTreemap && "id") {
const selector = hasTreemap ? $TREEMAP.treemap : $ARC.arc;
callback(d, main.select("." + selector + $$.getTargetSelectorSuffix(d.id)).node());
} else if (!config.tooltip_grouped) {
const last = $$.cache.get(KEY.setOverOut) || [],
shapesAtIndex = main.selectAll("." + $SHAPE.shape + "-" + d).filter(function (d) {
return $$.isWithinShape(this, d);
}),
shape = shapesAtIndex.filter(function () {
var _this2 = this;
return last.every(function (v) {
_newArrowCheck(this, _this2);
return v !== this;
}.bind(this));
}); // select based on the index
// filter if has new selection
// call onout callback
if (!isOver || shapesAtIndex.empty() || last.length === shape.size() && shape.nodes().every(function (v, i) {
_newArrowCheck(this, _this3);
return v !== last[i];
}.bind(this))) {
while (last.length) {
const target = last.pop();
config.data_onout.bind($$.api)(src_select(target).datum(), target);
}
}
// call onover callback
shape.each(function () {
if (isOver) {
callback(src_select(this).datum(), this);
last.push(this);
}
});
$$.cache.add(KEY.setOverOut, last);
} else {
if (isOver) {
hasRadar && $$.isPointFocusOnly() ? $$.showCircleFocus($$.getAllValuesOnIndex(d, !0)) : $$.setExpand(d, null, !0);
}
$$.isMultipleX() || main.selectAll("." + $SHAPE.shape + "-" + d).each(function (d) {
callback(d, this);
});
}
}
},
/**
* Call data.onover/out callback for touch event
* @param {number|object} d target index or data object for Arc type
* @private
*/
callOverOutForTouch: function callOverOutForTouch(d) {
const $$ = this,
last = $$.cache.get(KEY.callOverOutForTouch);
if (isObject(d) && last ? d.id !== last.id : d !== last) {
(last || isNumber(last)) && $$.setOverOut(!1, last);
(d || isNumber(d)) && $$.setOverOut(!0, d);
$$.cache.add(KEY.callOverOutForTouch, d);
}
},
/**
* Return draggable selection function
* @returns {Function}
* @private
*/
getDraggableSelection: function getDraggableSelection() {
var _this4 = this;
const $$ = this,
config = $$.config,
state = $$.state;
return config.interaction_enabled && config.data_selection_draggable && $$.drag ? drag().on("drag", function (event) {
state.event = event;
$$.drag(getPointer(event, this));
}).on("start", function (event) {
state.event = event;
$$.dragstart(getPointer(event, this));
}).on("end", function (event) {
_newArrowCheck(this, _this4);
state.event = event;
$$.dragend();
}.bind(this)) : function () {
_newArrowCheck(this, _this4);
}.bind(this);
},
/**
* Dispatch a mouse event.
* @private
* @param {string} type event type
* @param {number} index Index of eventRect
* @param {Array} mouse x and y coordinate value
*/
dispatchEvent: function dispatchEvent(type, index, mouse) {
var _ref;
const $$ = this,
config = $$.config,
_$$$state2 = $$.state,
eventReceiver = _$$$state2.eventReceiver,
hasAxis = _$$$state2.hasAxis,
hasRadar = _$$$state2.hasRadar,
hasTreemap = _$$$state2.hasTreemap,
_$$$$el = $$.$el,
eventRect = _$$$$el.eventRect,
radar = _$$$$el.radar,
treemap = _$$$$el.treemap,
element = (_ref = hasTreemap && eventReceiver.rect || hasRadar && radar.axes.select("." + $AXIS.axis + "-" + index + " text") || eventRect || ($$.getArcElementByIdOrIndex == null ? void 0 : $$.getArcElementByIdOrIndex(index))) == null ? void 0 : _ref.node();
if (element) {
const isMultipleX = $$.isMultipleX(),
isRotated = config.axis_rotated;
let _element$getBoundingC = element.getBoundingClientRect(),
width = _element$getBoundingC.width,
left = _element$getBoundingC.left,
top = _element$getBoundingC.top;
if (hasAxis && !hasRadar && !isMultipleX) {
const coords = eventReceiver.coords[index];
if (coords) {
width = coords.w;
left += coords.x;
top += coords.y;
} else {
width = 0;
left = 0;
top = 0;
}
}
const x = left + (mouse ? mouse[0] : 0) + (isMultipleX || isRotated ? 0 : width / 2),
y = top + (mouse ? mouse[1] : 0) + (isRotated ? 4 : 0); // value 4, is to adjust coordinate value set from: scale.ts - updateScales(): $$.getResettedPadding(1)
emulateEvent[/^(mouse|click)/.test(type) ? "mouse" : "touch"](hasTreemap ? treemap.node() : element, type, {
screenX: x,
screenY: y,
clientX: x,
clientY: y,
bubbles: hasRadar // radar type needs to bubble up event
});
}
},
setDragStatus: function setDragStatus(isDragging) {
this.state.dragging = isDragging;
},
/**
* Unbind zoom events
* @private
*/
unbindZoomEvent: function unbindZoomEvent() {
const $$ = this,
_$$$$el2 = $$.$el,
eventRect = _$$$$el2.eventRect,
zoomResetBtn = _$$$$el2.zoomResetBtn;
eventRect == null || eventRect.on(".zoom wheel.zoom .drag", null);
zoomResetBtn == null || zoomResetBtn.on("click", null).style("display", "none");
},
/**
* Unbind all attached events
* @private
*/
unbindAllEvents: function unbindAllEvents() {
var _this5 = this;
const $$ = this,
_$$$$el3 = $$.$el,
arcs = _$$$$el3.arcs,
eventRect = _$$$$el3.eventRect,
legend = _$$$$el3.legend,
region = _$$$$el3.region,
svg = _$$$$el3.svg,
treemap = _$$$$el3.treemap,
brush = $$.brush;
// detach all possible event types
[svg, eventRect, region == null ? void 0 : region.list, brush == null ? void 0 : brush.getSelection(), arcs == null ? void 0 : arcs.selectAll("path"), legend == null ? void 0 : legend.selectAll("g"), treemap].forEach(function (v) {
_newArrowCheck(this, _this5);
return v == null ? void 0 : v.on("wheel click mouseover mousemove mouseout touchstart touchmove touchend touchstart.eventRect touchmove.eventRect touchend.eventRect .brush .drag .zoom wheel.zoom dblclick.zoom", null);
}.bind(this));
$$.unbindZoomEvent == null || $$.unbindZoomEvent();
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/class.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var internals_class = ({
generateClass: function generateClass(prefix, targetId) {
return " " + prefix + " " + (prefix + this.getTargetSelectorSuffix(targetId));
},
/**
* Get class string
* @param {string} type Shape type
* @param {boolean} withShape Get with shape prefix
* @returns {string} Class string
* @private
*/
getClass: function getClass(type, withShape) {
var _this = this;
const isPlural = /s$/.test(type),
useIdKey = /^(area|arc|line|treemap)s?$/.test(type),
key = isPlural ? "id" : "index";
return function (d) {
_newArrowCheck(this, _this);
const data = d.data || d,
result = (withShape ? this.generateClass(classes[isPlural ? "shapes" : "shape"], data[key]) : "") + this.generateClass(classes[type], data[useIdKey ? "id" : key]);
return result.trim();
}.bind(this);
},
/**
* Get chart class string
* @param {string} type Shape type
* @returns {string} Class string
* @private
*/
getChartClass: function getChartClass(type) {
var _this2 = this;
return function (d) {
_newArrowCheck(this, _this2);
return classes["chart" + type] + this.classTarget((d.data ? d.data : d).id);
}.bind(this);
},
generateExtraLineClass: function generateExtraLineClass() {
const $$ = this,
classes = $$.config.line_classes || [],
ids = [];
return function (d) {
var _d$data;
const id = d.id || ((_d$data = d.data) == null ? void 0 : _d$data.id) || d;
if (ids.indexOf(id) < 0) {
ids.push(id);
}
return classes[ids.indexOf(id) % classes.length];
};
},
classRegion: function classRegion(d, i) {
return this.generateClass(classes.region, i) + " " + ("class" in d ? d.class : "");
},
classTarget: function classTarget(id) {
const additionalClassSuffix = this.config.data_classes[id];
let additionalClass = "";
if (additionalClassSuffix) {
additionalClass = " " + classes.target + "-" + additionalClassSuffix;
}
return this.generateClass(classes.target, id) + additionalClass;
},
classFocus: function classFocus(d) {
return this.classFocused(d) + this.classDefocused(d);
},
classFocused: function classFocused(d) {
return " " + (this.state.focusedTargetIds.indexOf(d.id) >= 0 ? classes.focused : "");
},
classDefocused: function classDefocused(d) {
return " " + (this.state.defocusedTargetIds.indexOf(d.id) >= 0 ? classes.defocused : "");
},
getTargetSelectorSuffix: function getTargetSelectorSuffix(targetId) {
const targetStr = targetId || targetId === 0 ? "-" + targetId : "";
return targetStr.replace(/([\s?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\])/g, "-");
},
selectorTarget: function selectorTarget(id, prefix, postfix) {
if (prefix === void 0) {
prefix = "";
}
if (postfix === void 0) {
postfix = "";
}
const target = this.getTargetSelectorSuffix(id);
// select target & circle
return prefix + "." + (classes.target + target) + " " + postfix + ", " + prefix + "." + (classes.circles + target) + " " + postfix;
},
selectorTargets: function selectorTargets(idsValue, prefix) {
var _this3 = this;
const ids = idsValue || [];
return ids.length ? ids.map(function (id) {
_newArrowCheck(this, _this3);
return this.selectorTarget(id, prefix);
}.bind(this)) : null;
},
selectorLegend: function selectorLegend(id) {
return "." + (classes.legendItem + this.getTargetSelectorSuffix(id));
},
selectorLegends: function selectorLegends(ids) {
var _this4 = this;
return ids != null && ids.length ? ids.map(function (id) {
_newArrowCheck(this, _this4);
return this.selectorLegend(id);
}.bind(this)) : null;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/category.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var category = ({
/**
* Category Name
* @param {number} i Index number
* @returns {string} category Name
* @private
*/
categoryName: function categoryName(i) {
var _axis_x_categories$i;
const axis_x_categories = this.config.axis_x_categories;
return (_axis_x_categories$i = axis_x_categories == null ? void 0 : axis_x_categories[i]) != null ? _axis_x_categories$i : i;
}
});
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeFunction.js
function _isNativeFunction(fn) {
try {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
} catch (e) {
return typeof fn === "function";
}
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
return !!t;
})();
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/construct.js
function _construct(t, e, r) {
if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
var o = [null];
o.push.apply(o, e);
var p = new (t.bind.apply(t, o))();
return r && _setPrototypeOf(p, r.prototype), p;
}
;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
_wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !_isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return _construct(Class, arguments, _getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return _setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
;// CONCATENATED MODULE: ./node_modules/internmap/src/index.js
function src_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = src_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: !0 }; return { done: !1, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function src_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return src_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 src_arrayLikeToArray(o, minLen); }
function src_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
let InternMap = /*#__PURE__*/function (_Map) {
_inheritsLoose(InternMap, _Map);
function InternMap(entries, key) {
var _this;
if (key === void 0) {
key = keyof;
}
_this = _Map.call(this) || this;
Object.defineProperties(_assertThisInitialized(_this), {
_intern: {
value: new Map()
},
_key: {
value: key
}
});
if (entries != null) {
for (var _iterator = src_createForOfIteratorHelperLoose(entries), _step; !(_step = _iterator()).done;) {
const _step$value = _step.value,
key = _step$value[0],
value = _step$value[1];
_this.set(key, value);
}
}
return _this;
}
var _proto = InternMap.prototype;
_proto.get = function get(key) {
return _Map.prototype.get.call(this, intern_get(this, key));
};
_proto.has = function has(key) {
return _Map.prototype.has.call(this, intern_get(this, key));
};
_proto.set = function set(key, value) {
return _Map.prototype.set.call(this, intern_set(this, key), value);
};
_proto.delete = function _delete(key) {
return _Map.prototype.delete.call(this, intern_delete(this, key));
};
return InternMap;
}( /*#__PURE__*/_wrapNativeSuper(Map));
let InternSet = /*#__PURE__*/function (_Set) {
_inheritsLoose(InternSet, _Set);
function InternSet(values, key) {
var _this2;
if (key === void 0) {
key = keyof;
}
_this2 = _Set.call(this) || this;
Object.defineProperties(_assertThisInitialized(_this2), {
_intern: {
value: new Map()
},
_key: {
value: key
}
});
if (values != null) {
for (var _iterator2 = src_createForOfIteratorHelperLoose(values), _step2; !(_step2 = _iterator2()).done;) {
const value = _step2.value;
_this2.add(value);
}
}
return _this2;
}
var _proto2 = InternSet.prototype;
_proto2.has = function has(value) {
return _Set.prototype.has.call(this, intern_get(this, value));
};
_proto2.add = function add(value) {
return _Set.prototype.add.call(this, intern_set(this, value));
};
_proto2.delete = function _delete(value) {
return _Set.prototype.delete.call(this, intern_delete(this, value));
};
return InternSet;
}( /*#__PURE__*/_wrapNativeSuper(Set));
function intern_get(_ref, value) {
let _intern = _ref._intern,
_key = _ref._key;
const key = _key(value);
return _intern.has(key) ? _intern.get(key) : value;
}
function intern_set(_ref2, value) {
let _intern = _ref2._intern,
_key = _ref2._key;
const key = _key(value);
if (_intern.has(key)) return _intern.get(key);
_intern.set(key, value);
return value;
}
function intern_delete(_ref3, value) {
let _intern = _ref3._intern,
_key = _ref3._key;
const key = _key(value);
if (_intern.has(key)) {
value = _intern.get(key);
_intern.delete(key);
}
return value;
}
function keyof(value) {
return value !== null && typeof value === "object" ? value.valueOf() : value;
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/init.js
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;
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/ordinal.js
function ordinal_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = ordinal_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: !0 }; return { done: !1, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function ordinal_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return ordinal_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 ordinal_arrayLikeToArray(o, minLen); }
function ordinal_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
const implicit = Symbol("implicit");
function ordinal() {
var index = new InternMap(),
domain = [],
range = [],
unknown = implicit;
function scale(d) {
let i = index.get(d);
if (i === undefined) {
if (unknown !== implicit) return unknown;
index.set(d, i = domain.push(d) - 1);
}
return range[i % range.length];
}
scale.domain = function (_) {
if (!arguments.length) return domain.slice();
domain = [], index = new InternMap();
for (var _iterator = ordinal_createForOfIteratorHelperLoose(_), _step; !(_step = _iterator()).done;) {
const value = _step.value;
if (index.has(value)) continue;
index.set(value, domain.push(value) - 1);
}
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;
}
;// CONCATENATED MODULE: ./src/ChartInternal/internals/color.ts
var color_this = undefined;
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Set pattern's background color
* (it adds a element to simulate bg-color)
* @param {SVGPatternElement} pattern SVG pattern element
* @param {string} color Color string
* @param {string} id ID to be set
* @returns {{id: string, node: SVGPatternElement}}
* @private
*/
const colorizePattern = function (pattern, color, id) {
_newArrowCheck(this, color_this);
const node = src_select(pattern.cloneNode(!0));
node.attr("id", id).insert("rect", ":first-child").attr("width", node.attr("width")).attr("height", node.attr("height")).style("fill", color);
return {
id: id,
node: node.node()
};
}.bind(undefined);
/**
* Get color pattern from CSS file
* CSS should be defined as: background-image: url("#00c73c;#fa7171; ...");
* @param {d3Selection} element Chart element
* @returns {Array}
* @private
*/
function getColorFromCss(element) {
var _this2 = this;
const cacheKey = KEY.colorPattern,
body = browser_doc.body;
let pattern = body[cacheKey];
if (!pattern) {
const content = element.classed($COLOR.colorPattern, !0).style("background-image");
element.classed($COLOR.colorPattern, !1);
if (content.indexOf(";") > -1) {
pattern = content.replace(/url[^#]*|["'()]|(\s|%20)/g, "").split(";").map(function (v) {
_newArrowCheck(this, _this2);
return v.trim().replace(/[\"'\s]/g, "");
}.bind(this)).filter(Boolean);
body[cacheKey] = pattern;
}
}
return pattern;
}
// Replacement of d3.schemeCategory10.
// Contained differently depend on d3 version: v4(d3-scale), v5(d3-scale-chromatic)
const schemeCategory10 = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"];
/* harmony default export */ var internals_color = ({
generateColor: function generateColor() {
var _this3 = this;
const $$ = this,
$el = $$.$el,
config = $$.config,
colors = config.data_colors,
callback = config.data_color,
ids = [];
let pattern = notEmpty(config.color_pattern) ? config.color_pattern : ordinal(getColorFromCss($el.chart) || schemeCategory10).range();
const originalColorPattern = pattern;
if (isFunction(config.color_tiles)) {
const tiles = config.color_tiles.bind($$.api)(),
colorizedPatterns = pattern.map(function (p, index) {
_newArrowCheck(this, _this3);
const color = p.replace(/[#\(\)\s,]/g, ""),
id = $$.state.datetimeId + "-pattern-" + color + "-" + index;
return colorizePattern(tiles[index % tiles.length], p, id);
}.bind(this)); // Add background color to patterns
pattern = colorizedPatterns.map(function (p) {
_newArrowCheck(this, _this3);
return "url(#" + p.id + ")";
}.bind(this));
$$.patterns = colorizedPatterns;
}
return function (d) {
var _data;
const id = d.id || ((_data = d.data) == null ? void 0 : _data.id) || d,
isLine = $$.isTypeOf(id, ["line", "spline", "step"]) || !config.data_types[id];
let color;
// if callback function is provided
if (isFunction(colors[id])) {
color = colors[id].bind($$.api)(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 = isLine ? originalColorPattern[ids.indexOf(id) % originalColorPattern.length] : pattern[ids.indexOf(id) % pattern.length];
colors[id] = color;
}
return isFunction(callback) ? callback.bind($$.api)(color, d) : color;
};
},
generateLevelColor: function generateLevelColor() {
const $$ = this,
config = $$.config,
colors = config.color_pattern,
threshold = config.color_threshold,
asValue = threshold.unit === "value",
max = threshold.max || 100,
values = threshold.values && threshold.values.length ? threshold.values : [];
return notEmpty(threshold) ? function (value) {
const v = asValue ? value : value * 100 / max;
let color = colors[colors.length - 1];
for (let i = 0, l = values.length; i < l; i++) {
if (v <= values[i]) {
color = colors[i];
break;
}
}
return color;
} : null;
},
/**
* Append data backgound color filter definition
* @param {string} color Color string
* @private
*/
generateDataLabelBackgroundColorFilter: function generateDataLabelBackgroundColorFilter(color) {
var _this4 = this;
const $$ = this,
$el = $$.$el,
config = $$.config,
state = $$.state,
backgroundColors = color || config.data_labels_backgroundColors;
if (backgroundColors) {
let ids = [];
if (isString(backgroundColors)) {
ids.push("");
} else if (isObject(backgroundColors)) {
ids = Object.keys(backgroundColors);
}
ids.forEach(function (v) {
_newArrowCheck(this, _this4);
const id = state.datetimeId + "-labels-bg" + $$.getTargetSelectorSuffix(v) + (color ? $$.getTargetSelectorSuffix(color) : "");
$el.defs.append("filter").attr("x", "0").attr("y", "0").attr("width", "1").attr("height", "1").attr("id", id).html("");
}.bind(this));
}
},
/**
* Get data gradient color url
* @param {string} id Data id
* @returns {string}
* @private
*/
getGradienColortUrl: function getGradienColortUrl(id) {
return "url(#" + this.state.datetimeId + "-gradient" + this.getTargetSelectorSuffix(id) + ")";
},
/**
* Update linear/radial gradient definition
* - linear: area & bar only
* - radial: type which has data points only
* @private
*/
updateLinearGradient: function updateLinearGradient() {
var _this5 = this;
const $$ = this,
config = $$.config,
targets = $$.data.targets,
datetimeId = $$.state.datetimeId,
defs = $$.$el.defs;
targets.forEach(function (d) {
var _this6 = this;
_newArrowCheck(this, _this5);
const id = datetimeId + "-gradient" + $$.getTargetSelectorSuffix(d.id),
radialGradient = $$.hasPointType() && config.point_radialGradient,
supportedType = $$.isAreaType(d) && "area" || $$.isBarType(d) && "bar";
if ((radialGradient || supportedType) && defs.select("#" + id).empty()) {
const color = $$.color(d),
gradient = {
defs: null,
stops: []
};
if (radialGradient) {
const _radialGradient = radialGradient,
_radialGradient$cx = _radialGradient.cx,
cx = _radialGradient$cx === void 0 ? .3 : _radialGradient$cx,
_radialGradient$cy = _radialGradient.cy,
cy = _radialGradient$cy === void 0 ? .3 : _radialGradient$cy,
_radialGradient$r = _radialGradient.r,
r = _radialGradient$r === void 0 ? .7 : _radialGradient$r,
_radialGradient$stops = _radialGradient.stops,
stops = _radialGradient$stops === void 0 ? [[.1, color, 0], [.9, color, 1]] : _radialGradient$stops;
gradient.stops = stops;
gradient.defs = defs.append("radialGradient").attr("id", "" + id).attr("cx", cx).attr("cy", cy).attr("r", r);
} else {
const isRotated = config.axis_rotated,
_config = config[supportedType + "_linearGradient"],
_config$x = _config.x,
x = _config$x === void 0 ? isRotated ? [1, 0] : [0, 0] : _config$x,
_config$y = _config.y,
y = _config$y === void 0 ? isRotated ? [0, 0] : [0, 1] : _config$y,
_config$stops = _config.stops,
stops = _config$stops === void 0 ? [[0, color, 1], [1, color, 0]] : _config$stops;
gradient.stops = stops;
gradient.defs = defs.append("linearGradient").attr("id", "" + id).attr("x1", x[0]).attr("x2", x[1]).attr("y1", y[0]).attr("y2", y[1]);
}
gradient.stops.forEach(function (v) {
_newArrowCheck(this, _this6);
const offset = v[0],
stopColor = v[1],
stopOpacity = v[2],
colorValue = isFunction(stopColor) ? stopColor.bind($$.api)(d.id) : stopColor;
gradient.defs && gradient.defs.append("stop").attr("offset", offset).attr("stop-color", colorValue || color).attr("stop-opacity", stopOpacity);
}.bind(this));
}
}.bind(this));
},
/**
* Set the data over color.
* When is out, will restate in its previous color value
* @param {boolean} isOver true: set overed color, false: restore
* @param {number|object} d target index or data object for Arc type
* @private
*/
setOverColor: function setOverColor(isOver, d) {
var _this7 = this;
const $$ = this,
config = $$.config,
main = $$.$el.main,
onover = config.color_onover;
let color = isOver ? onover : $$.color;
if (isObject(color)) {
color = function (_ref) {
let id = _ref.id;
_newArrowCheck(this, _this7);
return id in onover ? onover[id] : $$.color(id);
}.bind(this);
} else if (isString(color)) {
color = function () {
_newArrowCheck(this, _this7);
return onover;
}.bind(this);
} else if (isFunction(onover)) {
color = color.bind($$.api);
}
main.selectAll(isObject(d) ? // when is Arc type
"." + $ARC.arc + $$.getTargetSelectorSuffix(d.id) : "." + $SHAPE.shape + "-" + d).style("fill", color);
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/domain.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var domain = ({
getYDomainMinMax: function getYDomainMinMax(targets, type) {
var _this = this;
const $$ = this,
axis = $$.axis,
config = $$.config,
isMin = type === "min",
dataGroups = config.data_groups,
ids = $$.mapToIds(targets),
ys = $$.getValuesAsIdKeyed(targets);
if (dataGroups.length > 0) {
const hasValue = $$["has" + (isMin ? "Negative" : "Positive") + "ValueInTargets"](targets);
dataGroups.forEach(function (groupIds) {
var _this2 = this;
_newArrowCheck(this, _this);
// Determine baseId
const idsInGroup = groupIds.filter(function (v) {
_newArrowCheck(this, _this2);
return ids.indexOf(v) >= 0;
}.bind(this));
if (idsInGroup.length) {
const baseId = idsInGroup[0],
baseAxisId = axis.getId(baseId);
// Initialize base value. Set to 0 if not match with the condition
if (hasValue && ys[baseId]) {
ys[baseId] = ys[baseId].map(function (v) {
_newArrowCheck(this, _this2);
return (isMin ? v < 0 : v > 0) ? v : 0;
}.bind(this));
}
idsInGroup.filter(function (v, i) {
_newArrowCheck(this, _this2);
return i > 0;
}.bind(this)).forEach(function (id) {
var _this3 = this;
_newArrowCheck(this, _this2);
if (ys[id]) {
const axisId = axis.getId(id);
ys[id].forEach(function (v, i) {
_newArrowCheck(this, _this3);
const val = +v,
meetCondition = isMin ? val > 0 : val < 0;
if (axisId === baseAxisId && !(hasValue && meetCondition)) {
ys[baseId][i] += val;
}
}.bind(this));
}
}.bind(this));
}
}.bind(this));
}
return getMinMax(type, Object.keys(ys).map(function (key) {
_newArrowCheck(this, _this);
return getMinMax(type, ys[key]);
}.bind(this)));
},
/**
* Check if hidden targets bound to the given axis id
* @param {string} id ID to be checked
* @returns {boolean}
* @private
*/
isHiddenTargetWithYDomain: function isHiddenTargetWithYDomain(id) {
var _this4 = this;
const $$ = this;
return $$.state.hiddenTargetIds.some(function (v) {
_newArrowCheck(this, _this4);
return $$.axis.getId(v) === id;
}.bind(this));
},
getYDomain: function getYDomain(targets, axisId, xDomain) {
var _this5 = this;
const $$ = this,
axis = $$.axis,
config = $$.config,
scale = $$.scale,
pfx = "axis_" + axisId;
if ($$.isStackNormalized()) {
return [0, 100];
}
const isLog = (scale == null ? void 0 : scale[axisId]) && scale[axisId].type === "log",
targetsByAxisId = targets.filter(function (t) {
_newArrowCheck(this, _this5);
return axis.getId(t.id) === axisId;
}.bind(this)),
yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId;
if (yTargets.length === 0) {
// use domain of the other axis if target of axisId is none
if ($$.isHiddenTargetWithYDomain(axisId)) {
return scale[axisId].domain();
} else {
return axisId === "y2" ? scale.y.domain() :
// When all data bounds to y2, y Axis domain is called prior y2.
// So, it needs to call to get y2 domain here
$$.getYDomain(targets, "y2", xDomain);
}
}
const yMin = config[pfx + "_min"],
yMax = config[pfx + "_max"],
center = config[pfx + "_center"],
isInverted = config[pfx + "_inverted"],
showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;
let yDomainMin = $$.getYDomainMinMax(yTargets, "min"),
yDomainMax = $$.getYDomainMinMax(yTargets, "max"),
isZeroBased = [TYPE.BAR, TYPE.BUBBLE, TYPE.SCATTER].concat(TYPE_BY_CATEGORY.Line).some(function (v) {
_newArrowCheck(this, _this5);
const type = v.indexOf("area") > -1 ? "area" : v;
return $$.hasType(v, yTargets, !0) && config[type + "_zerobased"];
}.bind(this));
// 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 (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;
}
const 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 = !1;
}
// Bar/Area chart should be 0-based if all positive|negative
if (isZeroBased) {
isAllPositive && (yDomainMin = 0);
isAllNegative && (yDomainMax = 0);
}
const domainLength = Math.abs(yDomainMax - yDomainMin);
let padding = {
top: domainLength * .1,
bottom: domainLength * .1
};
if (isDefined(center)) {
const yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
yDomainMax = center + yDomainAbs;
yDomainMin = center - yDomainAbs;
}
// add padding for data label
if (showHorizontalDataLabel) {
const diff = diffDomain(scale.y.range()),
ratio = $$.getDataLabelLength(yDomainMin, yDomainMax, "width").map(function (v) {
_newArrowCheck(this, _this5);
return v / diff;
}.bind(this));
["bottom", "top"].forEach(function (v, i) {
_newArrowCheck(this, _this5);
padding[v] += domainLength * (ratio[i] / (1 - ratio[0] - ratio[1]));
}.bind(this));
} else if (showVerticalDataLabel) {
const lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, "height");
["bottom", "top"].forEach(function (v, i) {
_newArrowCheck(this, _this5);
padding[v] += $$.convertPixelToScale("y", lengths[i], domainLength);
}.bind(this));
}
padding = $$.getResettedPadding(padding);
// if padding is set, the domain will be updated relative the current domain value
// ex) $$.height=300, padding.top=150, domainLength=4 --> domain=6
const p = config[pfx + "_padding"];
if (notEmpty(p)) {
["bottom", "top"].forEach(function (v) {
_newArrowCheck(this, _this5);
padding[v] = axis.getPadding(p, v, padding[v], domainLength);
}.bind(this));
}
// Bar/Area chart should be 0-based if all positive|negative
if (isZeroBased) {
isAllPositive && (padding.bottom = yDomainMin);
isAllNegative && (padding.top = -yDomainMax);
}
const domain = isLog ? [yDomainMin, yDomainMax].map(function (v) {
_newArrowCheck(this, _this5);
return v < 0 ? 0 : v;
}.bind(this)) : [yDomainMin - padding.bottom, yDomainMax + padding.top];
return isInverted ? domain.reverse() : domain;
},
getXDomainMinMax: function getXDomainMinMax(targets, type) {
var _this6 = this,
_$$$axis;
const $$ = this,
configValue = $$.config["axis_x_" + type],
dataValue = getMinMax(type, targets.map(function (t) {
var _this7 = this;
_newArrowCheck(this, _this6);
return getMinMax(type, t.values.map(function (v) {
_newArrowCheck(this, _this7);
return v.x;
}.bind(this)));
}.bind(this)));
let value = isObject(configValue) ? configValue.value : configValue;
value = isDefined(value) && (_$$$axis = $$.axis) != null && _$$$axis.isTimeSeries() ? parseDate.bind(this)(value) : value;
if (isObject(configValue) && configValue.fit && (type === "min" && value < dataValue || type === "max" && value > dataValue)) {
value = undefined;
}
return isDefined(value) ? value : dataValue;
},
/**
* Get x Axis padding
* @param {Array} domain x Axis domain
* @param {number} tickCount Tick count
* @returns {object} Padding object values with 'left' & 'right' key
* @private
*/
getXDomainPadding: function getXDomainPadding(domain, tickCount) {
const $$ = this,
axis = $$.axis,
config = $$.config,
padding = config.axis_x_padding,
isTimeSeriesTickCount = axis.isTimeSeries() && tickCount,
diff = diffDomain(domain);
let defaultValue;
// determine default padding value
if (axis.isCategorized() || isTimeSeriesTickCount) {
defaultValue = 0;
} else if ($$.hasType("bar")) {
const maxDataCount = $$.getMaxDataCount();
defaultValue = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : .5;
} else {
defaultValue = $$.getResettedPadding(diff * .01);
}
let _ref = isNumber(padding) ? {
left: padding,
right: padding
} : padding,
_ref$left = _ref.left,
left = _ref$left === void 0 ? defaultValue : _ref$left,
_ref$right = _ref.right,
right = _ref$right === void 0 ? defaultValue : _ref$right;
// when the unit is pixel, convert pixels to axis scale value
if (padding.unit === "px") {
const domainLength = Math.abs(diff + diff * .2);
left = axis.getPadding(padding, "left", defaultValue, domainLength);
right = axis.getPadding(padding, "right", defaultValue, domainLength);
} else {
const range = diff + left + right;
if (isTimeSeriesTickCount && range) {
const relativeTickWidth = diff / tickCount / range;
left = left / range / relativeTickWidth;
right = right / range / relativeTickWidth;
}
}
return {
left: left,
right: right
};
},
/**
* Get x Axis domain
* @param {Array} targets targets
* @returns {Array} x Axis domain
* @private
*/
getXDomain: function getXDomain(targets) {
const $$ = this,
axis = $$.axis,
config = $$.config,
x = $$.scale.x,
isInverted = config.axis_x_inverted,
domain = [$$.getXDomainMinMax(targets, "min"), $$.getXDomainMinMax(targets, "max")];
let _domain$ = domain[0],
min = _domain$ === void 0 ? 0 : _domain$,
_domain$2 = domain[1],
max = _domain$2 === void 0 ? 0 : _domain$2;
if (x.type !== "log") {
const isCategorized = axis.isCategorized(),
isTimeSeries = axis.isTimeSeries(),
padding = $$.getXDomainPadding(domain);
let firstX = domain[0],
lastX = domain[1];
// show center of x domain if min and max are the same
if (firstX - lastX === 0 && !isCategorized) {
if (isTimeSeries) {
firstX = new Date(firstX.getTime() * .5);
lastX = new Date(lastX.getTime() * 1.5);
} else {
firstX = firstX === 0 ? 1 : firstX * .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 isInverted ? [max, min] : [min, max];
},
updateXDomain: function updateXDomain(targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {
const $$ = this,
config = $$.config,
org = $$.org,
_$$$scale = $$.scale,
x = _$$$scale.x,
subX = _$$$scale.subX,
zoomEnabled = config.zoom_enabled;
if (withUpdateOrgXDomain) {
var _$$$brush;
x.domain(domain || sortValue($$.getXDomain(targets), !config.axis_x_inverted));
org.xDomain = x.domain();
// zoomEnabled && $$.zoom.updateScaleExtent();
subX.domain(x.domain());
(_$$$brush = $$.brush) == null || _$$$brush.scale(subX);
}
if (withUpdateXDomain) {
const domainValue = domain || !$$.brush || brushEmpty($$) ? org.xDomain : getBrushSelection($$).map(subX.invert);
x.domain(domainValue);
// zoomEnabled && $$.zoom.updateScaleExtent();
}
if (withUpdateOrgXDomain || withUpdateXDomain) {
zoomEnabled && $$.zoom.updateScaleExtent();
}
// Trim domain when too big by zoom mousemove event
withTrim && x.domain($$.trimXDomain(x.orgDomain()));
return x.domain();
},
/**
* Trim x domain when given domain surpasses the range
* @param {Array} domain Domain value
* @returns {Array} Trimed domain if given domain is out of range
* @private
*/
trimXDomain: function trimXDomain(domain) {
const $$ = this,
isInverted = $$.config.axis_x_inverted,
zoomDomain = $$.getZoomDomain(),
_zoomDomain = zoomDomain,
min = _zoomDomain[0],
max = _zoomDomain[1];
if (isInverted ? domain[0] >= min : domain[0] <= min) {
domain[1] = +domain[1] + (min - domain[0]);
domain[0] = min;
}
if (isInverted ? domain[1] <= max : domain[1] >= max) {
domain[0] = +domain[0] - (domain[1] - max);
domain[1] = max;
}
return domain;
},
/**
* Get subchart/zoom domain
* @param {string} type "subX" or "zoom"
* @param {boolean} getCurrent Get current domain if true
* @returns {Array} zoom domain
* @private
*/
getZoomDomain: function getZoomDomain(type, getCurrent) {
if (type === void 0) {
type = "zoom";
}
if (getCurrent === void 0) {
getCurrent = !1;
}
const $$ = this,
config = $$.config,
scale = $$.scale,
org = $$.org;
let _ref2 = getCurrent && scale[type] ? scale[type].domain() : org.xDomain,
min = _ref2[0],
max = _ref2[1];
if (type === "zoom") {
if (isDefined(config.zoom_x_min)) {
min = getMinMax("min", [min, config.zoom_x_min]);
}
if (isDefined(config.zoom_x_max)) {
max = getMinMax("max", [max, config.zoom_x_max]);
}
}
return [min, max];
},
/**
* Return zoom domain from given domain
* - 'category' type need to add offset to original value
* @param {Array} domainValue domain value
* @returns {Array} Zoom domain
* @private
*/
getZoomDomainValue: function getZoomDomainValue(domainValue) {
var _this8 = this;
const $$ = this,
config = $$.config,
axis = $$.axis;
if (axis.isCategorized() && Array.isArray(domainValue)) {
const isInverted = config.axis_x_inverted,
domain = domainValue.map(function (v, i) {
_newArrowCheck(this, _this8);
return +v + (i === 0 ? +isInverted : +!isInverted);
}.bind(this)); // need to add offset to original value for 'category' type
return domain;
}
return domainValue;
},
/**
* Converts pixels to axis' scale values
* @param {string} type Axis type
* @param {number} pixels Pixels
* @param {number} domainLength Domain length
* @returns {number}
* @private
*/
convertPixelToScale: function convertPixelToScale(type, pixels, domainLength) {
const $$ = this,
config = $$.config,
state = $$.state,
isRotated = config.axis_rotated;
let length;
if (type === "x") {
length = isRotated ? "height" : "width";
} else {
length = isRotated ? "width" : "height";
}
return domainLength * (pixels / state[length]);
},
/**
* Check if the given domain is within subchart/zoom range
* @param {Array} domain Target domain value
* @param {Array} current Current subchart/zoom domain value
* @param {Array} range subchart/zoom range value
* @returns {boolean}
* @private
*/
withinRange: function withinRange(domain, current, range) {
var _this9 = this;
if (current === void 0) {
current = [0, 0];
}
const $$ = this,
isInverted = $$.config.axis_x_inverted,
_ref3 = range,
min = _ref3[0],
max = _ref3[1];
if (Array.isArray(domain)) {
const target = [].concat(domain);
isInverted && target.reverse();
if (target[0] < target[1]) {
return domain.every(function (v, i) {
var _this10 = this;
_newArrowCheck(this, _this9);
return (i === 0 ? isInverted ? +v <= min : +v >= min : isInverted ? +v >= max : +v <= max) && !domain.every(function (v, i) {
_newArrowCheck(this, _this10);
return v === current[i];
}.bind(this));
}.bind(this));
}
}
return !1;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/format.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get formatted
* @param {object} $$ Context
* @param {string} typeValue Axis type
* @param {number} v Value to be formatted
* @returns {number | string}
* @private
*/
function getFormat($$, typeValue, v) {
const config = $$.config,
type = "axis_" + typeValue + "_tick_format",
format = config[type] ? config[type] : $$.defaultValueFormat;
return format.call($$.api, v);
}
/* harmony default export */ var format = ({
yFormat: function yFormat(v) {
return getFormat(this, "y", v);
},
y2Format: function y2Format(v) {
return getFormat(this, "y2", v);
},
/**
* Get default value format function
* @returns {Function} formatter function
* @private
*/
getDefaultValueFormat: function getDefaultValueFormat() {
const $$ = this,
defaultArcValueFormat = $$.defaultArcValueFormat,
yFormat = $$.yFormat,
y2Format = $$.y2Format,
hasArc = $$.hasArcType(null, ["gauge", "polar", "radar"]);
return function (v, ratio, id) {
const format = hasArc ? defaultArcValueFormat : $$.axis && $$.axis.getId(id) === "y2" ? y2Format : yFormat;
return format.call($$, v, ratio);
};
},
defaultValueFormat: function defaultValueFormat(v) {
return isArray(v) ? v.join("~") : isValue(v) ? +v : "";
},
defaultArcValueFormat: function defaultArcValueFormat(v, ratio) {
return (ratio * 100).toFixed(1) + "%";
},
defaultPolarValueFormat: function defaultPolarValueFormat(v) {
return "" + v;
},
dataLabelFormat: function dataLabelFormat(targetId) {
var _this = this;
const $$ = this,
dataLabels = $$.config.data_labels,
defaultFormat = function (v) {
_newArrowCheck(this, _this);
const delimiter = "~";
let res = v;
if (isArray(v)) {
res = v.join(delimiter);
} else if (isObject(v)) {
res = Object.values(v).join(delimiter);
}
return res;
}.bind(this);
let format = defaultFormat;
// find format according to axis id
if (isFunction(dataLabels.format)) {
format = dataLabels.format;
} else if (isObjectType(dataLabels.format)) {
if (dataLabels.format[targetId]) {
format = dataLabels.format[targetId] === !0 ? defaultFormat : dataLabels.format[targetId];
} else {
format = function () {
_newArrowCheck(this, _this);
return "";
}.bind(this);
}
}
return format.bind($$.api);
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/legend.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get color string for given data id
* @param {string} id Data id
* @returns {string} Color string
* @private
*/
function getLegendColor(id) {
const $$ = this,
data = $$.getDataById(id),
color = $$.levelColor ? $$.levelColor(data.values[0].value) : $$.color(data);
return color;
}
/**
* Get formatted text value
* @param {string} id Legend text id
* @param {boolean} formatted Whether or not to format the text
* @returns {string} Formatted legend text
*/
function getFormattedText(id, formatted) {
var _config$data_names$id;
if (formatted === void 0) {
formatted = !0;
}
const config = this.config;
let text = (_config$data_names$id = config.data_names[id]) != null ? _config$data_names$id : id;
if (formatted && isFunction(config.legend_format)) {
text = config.legend_format(text);
}
return text;
}
/* harmony default export */ var internals_legend = ({
/**
* Initialize the legend.
* @private
*/
initLegend: function initLegend() {
const $$ = this,
config = $$.config,
$el = $$.$el;
$$.legendItemTextBox = {};
$$.state.legendHasRendered = !1;
if (config.legend_show) {
if (!config.legend_contents_bindto) {
$el.legend = $$.$el.svg.append("g").classed($LEGEND.legend, !0).attr("transform", $$.getTranslate("legend"));
}
// MEMO: call here to update legend box and translate for all
// MEMO: translate will be updated by this, so transform not needed in updateLegend()
$$.updateLegend();
} else {
$$.state.hiddenLegendIds = $$.mapToIds($$.data.targets);
}
},
/**
* Update legend element
* @param {Array} targetIds ID's of target
* @param {object} options withTransform : Whether to use the transform property / withTransitionForTransform: Whether transition is used when using the transform property / withTransition : whether or not to transition.
* @param {object} transitions Return value of the generateTransitions
* @private
*/
updateLegend: function updateLegend(targetIds, options, transitions) {
var _$el$legend;
const $$ = this,
config = $$.config,
state = $$.state,
scale = $$.scale,
$el = $$.$el,
optionz = options || {
withTransform: !1,
withTransitionForTransform: !1,
withTransition: !1
};
optionz.withTransition = getOption(optionz, "withTransition", !0);
optionz.withTransitionForTransform = getOption(optionz, "withTransitionForTransform", !0);
if (config.legend_contents_bindto && config.legend_contents_template) {
$$.updateLegendTemplate();
} else if (!state.hasTreemap) {
$$.updateLegendElement(targetIds || $$.mapToIds($$.data.targets), optionz, transitions);
}
// toggle legend state
(_$el$legend = $el.legend) == null || _$el$legend.selectAll("." + $LEGEND.legendItem).classed($LEGEND.legendItemHidden, function (id) {
const hide = !$$.isTargetToShow(id);
if (hide) {
this.style.opacity = null;
}
return hide;
});
// Update size and scale
$$.updateScales(!1, !scale.zoom);
$$.updateSvgSize();
// Update g positions
$$.transformAll(optionz.withTransitionForTransform, transitions);
state.legendHasRendered = !0;
},
/**
* Update legend using template option
* @private
*/
updateLegendTemplate: function updateLegendTemplate() {
var _this = this;
const $$ = this,
config = $$.config,
$el = $$.$el,
wrapper = src_select(config.legend_contents_bindto),
template = config.legend_contents_template;
if (!wrapper.empty()) {
const targets = $$.mapToIds($$.data.targets),
ids = [];
let html = "";
targets.forEach(function (v) {
_newArrowCheck(this, _this);
const content = isFunction(template) ? template.bind($$.api)(v, $$.color(v), $$.api.data(v)[0].values) : tplProcess(template, {
COLOR: $$.color(v),
TITLE: v
});
if (content) {
ids.push(v);
html += content;
}
}.bind(this));
const legendItem = wrapper.html(html).selectAll(function () {
return this.childNodes;
}).data(ids);
$$.setLegendItem(legendItem);
$el.legend = wrapper;
}
},
/**
* Update the size of the legend.
* @param {Obejct} size Size object
* @private
*/
updateSizeForLegend: function updateSizeForLegend(size) {
const $$ = this,
config = $$.config,
_$$$state = $$.state,
isLegendTop = _$$$state.isLegendTop,
isLegendLeft = _$$$state.isLegendLeft,
isLegendRight = _$$$state.isLegendRight,
isLegendInset = _$$$state.isLegendInset,
current = _$$$state.current,
width = size.width,
height = size.height,
insetLegendPosition = {
top: isLegendTop ? $$.getCurrentPaddingByDirection("top") + config.legend_inset_y + 5.5 : current.height - height - $$.getCurrentPaddingByDirection("bottom") - config.legend_inset_y,
left: isLegendLeft ? $$.getCurrentPaddingByDirection("left") + config.legend_inset_x + .5 : current.width - width - $$.getCurrentPaddingByDirection("right") - config.legend_inset_x + .5
};
$$.state.margin3 = {
top: isLegendRight ? 0 : isLegendInset ? insetLegendPosition.top : current.height - height,
right: NaN,
bottom: 0,
left: isLegendRight ? current.width - width : isLegendInset ? insetLegendPosition.left : 0
};
},
/**
* Transform Legend
* @param {boolean} withTransition whether or not to transition.
* @private
*/
transformLegend: function transformLegend(withTransition) {
const $$ = this,
legend = $$.$el.legend,
$T = $$.$T;
$T(legend, withTransition).attr("transform", $$.getTranslate("legend"));
},
/**
* Update the legend step
* @param {number} step Step value
* @private
*/
updateLegendStep: function updateLegendStep(step) {
this.state.legendStep = step;
},
/**
* Update legend item width
* @param {number} width Width value
* @private
*/
updateLegendItemWidth: function updateLegendItemWidth(width) {
this.state.legendItemWidth = width;
},
/**
* Update legend item height
* @param {number} height Height value
* @private
*/
updateLegendItemHeight: function updateLegendItemHeight(height) {
this.state.legendItemHeight = height;
},
/**
* Update legend item color
* @param {string} id Corresponding data ID value
* @param {string} color Color value
* @private
*/
updateLegendItemColor: function updateLegendItemColor(id, color) {
const legend = this.$el.legend;
if (legend) {
legend.select("." + $LEGEND.legendItem + "-" + id + " line").style("stroke", color);
}
},
/**
* Get the width of the legend
* @returns {number} width
* @private
*/
getLegendWidth: function getLegendWidth() {
const $$ = this,
_$$$state2 = $$.state,
width = _$$$state2.current.width,
isLegendRight = _$$$state2.isLegendRight,
isLegendInset = _$$$state2.isLegendInset,
legendItemWidth = _$$$state2.legendItemWidth,
legendStep = _$$$state2.legendStep;
return $$.config.legend_show ? isLegendRight || isLegendInset ? legendItemWidth * (legendStep + 1) : width : 0;
},
/**
* Get the height of the legend
* @returns {number} height
* @private
*/
getLegendHeight: function getLegendHeight() {
var _$$$config$padding;
const $$ = this,
_$$$state3 = $$.state,
current = _$$$state3.current,
isLegendRight = _$$$state3.isLegendRight,
legendItemHeight = _$$$state3.legendItemHeight,
legendStep = _$$$state3.legendStep,
isFitPadding = ((_$$$config$padding = $$.config.padding) == null ? void 0 : _$$$config$padding.mode) === "fit";
return $$.config.legend_show ? isLegendRight ? current.height : (isFitPadding ? 10 : Math.max(20, legendItemHeight)) * (legendStep + 1) : 0;
},
/**
* Get the opacity of the legend that is unfocused
* @param {d3.selection} legendItem Legend item node
* @returns {string|null} opacity
* @private
*/
opacityForUnfocusedLegend: function opacityForUnfocusedLegend(legendItem) {
return legendItem.classed($LEGEND.legendItemHidden) ? null : "0.3";
},
/**
* Toggles the focus of the legend
* @param {Array} targetIds ID's of target
* @param {boolean} focus whether or not to focus.
* @private
*/
toggleFocusLegend: function toggleFocusLegend(targetIds, focus) {
var _this2 = this;
const $$ = this,
legend = $$.$el.legend,
$T = $$.$T,
targetIdz = $$.mapToTargetIds(targetIds);
legend && $T(legend.selectAll("." + $LEGEND.legendItem).filter(function (id) {
_newArrowCheck(this, _this2);
return targetIdz.indexOf(id) >= 0;
}.bind(this)).classed($FOCUS.legendItemFocused, focus)).style("opacity", function () {
return focus ? null : $$.opacityForUnfocusedLegend.call($$, src_select(this));
});
},
/**
* Revert the legend to its default state
* @private
*/
revertLegend: function revertLegend() {
const $$ = this,
legend = $$.$el.legend,
$T = $$.$T;
legend && $T(legend.selectAll("." + $LEGEND.legendItem).classed($FOCUS.legendItemFocused, !1)).style("opacity", null);
},
/**
* Shows the legend
* @param {Array} targetIds ID's of target
* @private
*/
showLegend: function showLegend(targetIds) {
const $$ = this,
config = $$.config,
$el = $$.$el,
$T = $$.$T;
if (!config.legend_show) {
config.legend_show = !0;
$el.legend ? $el.legend.style("visibility", null) : $$.initLegend();
$$.state.legendHasRendered || $$.updateLegend();
}
$$.removeHiddenLegendIds(targetIds);
$T($el.legend.selectAll($$.selectorLegends(targetIds)).style("visibility", null)).style("opacity", null);
},
/**
* Hide the legend
* @param {Array} targetIds ID's of target
* @private
*/
hideLegend: function hideLegend(targetIds) {
const $$ = this,
config = $$.config,
legend = $$.$el.legend;
if (config.legend_show && isEmpty(targetIds)) {
config.legend_show = !1;
legend.style("visibility", "hidden");
}
$$.addHiddenLegendIds(targetIds);
legend.selectAll($$.selectorLegends(targetIds)).style("opacity", "0").style("visibility", "hidden");
},
/**
* Get legend item textbox dimension
* @param {string} id Data ID
* @param {HTMLElement|d3.selection} textElement Text node element
* @returns {object} Bounding rect
* @private
*/
getLegendItemTextBox: function getLegendItemTextBox(id, textElement) {
const $$ = this,
cache = $$.cache,
state = $$.state;
let data;
// do not prefix w/'$', to not be resetted cache in .load() call
const cacheKey = KEY.legendItemTextBox;
if (id) {
data = !state.redrawing && cache.get(cacheKey) || {};
if (!data[id]) {
data[id] = $$.getTextRect(textElement, $LEGEND.legendItem);
cache.add(cacheKey, data);
}
data = data[id];
}
return data;
},
/**
* Set legend item style & bind events
* @param {d3.selection} item Item node
* @private
*/
setLegendItem: function setLegendItem(item) {
var _this3 = this;
const $$ = this,
$el = $$.$el,
api = $$.api,
config = $$.config,
state = $$.state,
isTouch = state.inputType === "touch",
hasGauge = $$.hasType("gauge"),
useCssRule = config.boost_useCssRule,
interaction = config.legend_item_interaction;
item.attr("class", function (id) {
const node = src_select(this),
itemClass = !node.empty() && node.attr("class") || "";
return itemClass + $$.generateClass($LEGEND.legendItem, id);
}).style("visibility", function (id) {
_newArrowCheck(this, _this3);
return $$.isLegendToShow(id) ? null : "hidden";
}.bind(this));
if (config.interaction_enabled) {
if (useCssRule) {
[["." + $LEGEND.legendItem, "cursor:pointer"], ["." + $LEGEND.legendItem + " text", "pointer-events:none"], ["." + $LEGEND.legendItemPoint + " text", "pointer-events:none"], ["." + $LEGEND.legendItemTile, "pointer-events:none"], ["." + $LEGEND.legendItemEvent, "fill-opacity:0"]].forEach(function (v) {
_newArrowCheck(this, _this3);
const selector = v[0],
props = v[1];
$$.setCssRule(!1, selector, [props])($el.legend);
}.bind(this));
}
item.on(interaction.dblclick ? "dblclick" : "click", interaction || isFunction(config.legend_item_onclick) ? function (event, id) {
if (!callFn(config.legend_item_onclick, api, id)) {
const altKey = event.altKey,
target = event.target,
type = event.type;
if (type === "dblclick" || altKey) {
// when focused legend is clicked(with altKey or double clicked), reset all hiding.
if (state.hiddenTargetIds.length && target.parentNode.getAttribute("class").indexOf($LEGEND.legendItemHidden) === -1) {
api.show();
} else {
api.hide();
api.show(id);
}
} else {
api.toggle(id);
src_select(this).classed($FOCUS.legendItemFocused, !1);
}
}
isTouch && $$.hideTooltip();
} : null);
isTouch || item.on("mouseout", interaction || isFunction(config.legend_item_onout) ? function (event, id) {
if (!callFn(config.legend_item_onout, api, id)) {
src_select(this).classed($FOCUS.legendItemFocused, !1);
if (hasGauge) {
$$.undoMarkOverlapped($$, "." + $GAUGE.gaugeValue);
}
$$.api.revert();
}
} : null).on("mouseover", interaction || isFunction(config.legend_item_onover) ? function (event, id) {
if (!callFn(config.legend_item_onover, api, id)) {
src_select(this).classed($FOCUS.legendItemFocused, !0);
if (hasGauge) {
$$.markOverlapped(id, $$, "." + $GAUGE.gaugeValue);
}
if (!state.transiting && $$.isTargetToShow(id)) {
api.focus(id);
}
}
} : null);
// set cursor when has some interaction
!item.empty() && item.on("click mouseout mouseover") && item.style("cursor", $$.getStylePropValue("pointer"));
}
},
/**
* Update the legend
* @param {Array} targetIds ID's of target
* @param {object} options withTransform : Whether to use the transform property / withTransitionForTransform: Whether transition is used when using the transform property / withTransition : whether or not to transition.
* @private
*/
updateLegendElement: function updateLegendElement(targetIds, options) {
var _this4 = this;
const $$ = this,
config = $$.config,
state = $$.state,
legend = $$.$el.legend,
$T = $$.$T,
legendType = config.legend_item_tile_type,
isRectangle = legendType !== "circle",
legendItemR = config.legend_item_tile_r,
itemTileSize = {
width: isRectangle ? config.legend_item_tile_width : legendItemR * 2,
height: isRectangle ? config.legend_item_tile_height : legendItemR * 2
},
dimension = {
padding: {
top: 4,
right: 10
},
max: {
width: 0,
height: 0
},
posMin: 10,
step: 0,
tileWidth: itemTileSize.width + 5,
totalLength: 0
},
sizes = {
offsets: {},
widths: {},
heights: {},
margins: [0],
steps: {}
};
let xForLegend, yForLegend, background;
// Skip elements when their name is set to null
const targetIdz = targetIds.filter(function (id) {
_newArrowCheck(this, _this4);
return !isDefined(config.data_names[id]) || config.data_names[id] !== null;
}.bind(this)),
withTransition = options.withTransition,
updatePositions = $$.getUpdateLegendPositions(targetIdz, dimension, sizes);
if (state.isLegendInset) {
dimension.step = config.legend_inset_step ? config.legend_inset_step : targetIdz.length;
$$.updateLegendStep(dimension.step);
}
if (state.isLegendRight) {
xForLegend = function (id) {
_newArrowCheck(this, _this4);
return dimension.max.width * sizes.steps[id];
}.bind(this);
yForLegend = function (id) {
_newArrowCheck(this, _this4);
return sizes.margins[sizes.steps[id]] + sizes.offsets[id];
}.bind(this);
} else if (state.isLegendInset) {
xForLegend = function (id) {
_newArrowCheck(this, _this4);
return dimension.max.width * sizes.steps[id] + 10;
}.bind(this);
yForLegend = function (id) {
_newArrowCheck(this, _this4);
return sizes.margins[sizes.steps[id]] + sizes.offsets[id];
}.bind(this);
} else {
xForLegend = function (id) {
_newArrowCheck(this, _this4);
return sizes.margins[sizes.steps[id]] + sizes.offsets[id];
}.bind(this);
yForLegend = function (id) {
_newArrowCheck(this, _this4);
return dimension.max.height * sizes.steps[id];
}.bind(this);
}
const posFn = {
xText: function xText(id, i) {
_newArrowCheck(this, _this4);
return xForLegend(id, i) + 4 + itemTileSize.width;
}.bind(this),
xRect: function xRect(id, i) {
_newArrowCheck(this, _this4);
return xForLegend(id, i);
}.bind(this),
x1Tile: function x1Tile(id, i) {
_newArrowCheck(this, _this4);
return xForLegend(id, i) - 2;
}.bind(this),
x2Tile: function x2Tile(id, i) {
_newArrowCheck(this, _this4);
return xForLegend(id, i) - 2 + itemTileSize.width;
}.bind(this),
yText: function yText(id, i) {
_newArrowCheck(this, _this4);
return yForLegend(id, i) + 9;
}.bind(this),
yRect: function yRect(id, i) {
_newArrowCheck(this, _this4);
return yForLegend(id, i) - 5;
}.bind(this),
yTile: function yTile(id, i) {
_newArrowCheck(this, _this4);
return yForLegend(id, i) + 4;
}.bind(this)
};
$$.generateLegendItem(targetIdz, itemTileSize, updatePositions, posFn);
// Set background for inset legend
background = legend.select("." + $LEGEND.legendBackground + " rect");
if (state.isLegendInset && dimension.max.width > 0 && background.size() === 0) {
background = legend.insert("g", "." + $LEGEND.legendItem).attr("class", $LEGEND.legendBackground).append("rect");
}
if (config.legend_tooltip) {
legend.selectAll("title").data(targetIdz).text(function (id) {
_newArrowCheck(this, _this4);
return getFormattedText.bind($$)(id, !1);
}.bind(this));
}
const texts = legend.selectAll("text").data(targetIdz).text(function (id) {
_newArrowCheck(this, _this4);
return getFormattedText.bind($$)(id);
}.bind(this)) // MEMO: needed for update
.each(function (id, i) {
updatePositions(this, id, i);
});
$T(texts, withTransition).attr("x", posFn.xText).attr("y", posFn.yText);
const rects = legend.selectAll("rect." + $LEGEND.legendItemEvent).data(targetIdz);
$T(rects, withTransition).attr("width", function (id) {
_newArrowCheck(this, _this4);
return sizes.widths[id];
}.bind(this)).attr("height", function (id) {
_newArrowCheck(this, _this4);
return sizes.heights[id];
}.bind(this)).attr("x", posFn.xRect).attr("y", posFn.yRect);
// update legend items position
$$.updateLegendItemPos(targetIdz, withTransition, posFn);
if (background) {
$T(background, withTransition).attr("height", $$.getLegendHeight() - 12).attr("width", dimension.max.width * (dimension.step + 1) + 10);
}
// Update all to reflect change of legend
$$.updateLegendItemWidth(dimension.max.width);
$$.updateLegendItemHeight(dimension.max.height);
$$.updateLegendStep(dimension.step);
},
/**
* Get position update function
* @param {Array} targetIdz Data ids
* @param {object} dimension Dimension object
* @param {object} sizes Size object
* @returns {Function} Update position function
* @private
*/
getUpdateLegendPositions: function getUpdateLegendPositions(targetIdz, dimension, sizes) {
const $$ = this,
config = $$.config,
state = $$.state,
isLegendRightOrInset = state.isLegendRight || state.isLegendInset;
return function (textElement, id, index) {
var _this5 = this;
const isLast = index === targetIdz.length - 1,
box = $$.getLegendItemTextBox(id, textElement),
itemWidth = box.width + dimension.tileWidth + (isLast && !isLegendRightOrInset ? 0 : dimension.padding.right) + config.legend_padding,
itemHeight = box.height + dimension.padding.top,
itemLength = isLegendRightOrInset ? itemHeight : itemWidth,
areaLength = isLegendRightOrInset ? $$.getLegendHeight() : $$.getLegendWidth();
let margin;
// MEMO: care about condifion of step, totalLength
const updateValues = function (id2, withoutStep) {
if (!withoutStep) {
margin = (areaLength - dimension.totalLength - itemLength) / 2;
if (margin < dimension.posMin) {
margin = (areaLength - itemLength) / 2;
dimension.totalLength = 0;
dimension.step++;
}
}
sizes.steps[id2] = dimension.step;
sizes.margins[dimension.step] = state.isLegendInset ? 10 : margin;
sizes.offsets[id2] = dimension.totalLength;
dimension.totalLength += itemLength;
};
if (index === 0) {
dimension.totalLength = 0;
dimension.step = 0;
dimension.max.width = 0;
dimension.max.height = 0;
}
if (config.legend_show && !$$.isLegendToShow(id)) {
sizes.widths[id] = 0;
sizes.heights[id] = 0;
sizes.steps[id] = 0;
sizes.offsets[id] = 0;
return;
}
sizes.widths[id] = itemWidth;
sizes.heights[id] = itemHeight;
if (!dimension.max.width || itemWidth >= dimension.max.width) {
dimension.max.width = itemWidth;
}
if (!dimension.max.height || itemHeight >= dimension.max.height) {
dimension.max.height = itemHeight;
}
const maxLength = isLegendRightOrInset ? dimension.max.height : dimension.max.width;
if (config.legend_equally) {
Object.keys(sizes.widths).forEach(function (id2) {
_newArrowCheck(this, _this5);
return sizes.widths[id2] = dimension.max.width;
}.bind(this));
Object.keys(sizes.heights).forEach(function (id2) {
_newArrowCheck(this, _this5);
return sizes.heights[id2] = dimension.max.height;
}.bind(this));
margin = (areaLength - maxLength * targetIdz.length) / 2;
if (margin < dimension.posMin) {
dimension.totalLength = 0;
dimension.step = 0;
targetIdz.forEach(function (id2) {
_newArrowCheck(this, _this5);
return updateValues(id2);
}.bind(this));
} else {
updateValues(id, !0);
}
} else {
updateValues(id);
}
};
},
/**
* Generate legend item elements
* @param {Array} targetIdz Data ids
* @param {object} itemTileSize Item tile size {width, height}
* @param {Function} updatePositions Update position function
* @param {object} posFn Position functions
* @private
*/
generateLegendItem: function generateLegendItem(targetIdz, itemTileSize, updatePositions, posFn) {
var _this6 = this;
const $$ = this,
config = $$.config,
state = $$.state,
legend = $$.$el.legend,
usePoint = config.legend_usePoint,
legendItemR = config.legend_item_tile_r,
legendType = config.legend_item_tile_type,
isRectangle = legendType !== "circle",
isLegendRightOrInset = state.isLegendRight || state.isLegendInset,
pos = -200,
l = legend.selectAll("." + $LEGEND.legendItem).data(targetIdz).enter().append("g");
// Define g for legend area
$$.setLegendItem(l);
if (config.legend_tooltip) {
l.append("title").text(function (id) {
_newArrowCheck(this, _this6);
return id;
}.bind(this));
}
l.append("text").text(function (id) {
_newArrowCheck(this, _this6);
return getFormattedText.bind($$)(id);
}.bind(this)).each(function (id, i) {
updatePositions(this, id, i);
}).style("pointer-events", $$.getStylePropValue("none")).attr("x", isLegendRightOrInset ? posFn.xText : -200).attr("y", isLegendRightOrInset ? -200 : posFn.yText);
l.append("rect").attr("class", $LEGEND.legendItemEvent).style("fill-opacity", $$.getStylePropValue("0")).attr("x", isLegendRightOrInset ? posFn.xRect : -200).attr("y", isLegendRightOrInset ? -200 : posFn.yRect);
if (usePoint) {
const ids = [];
l.append(function (d) {
_newArrowCheck(this, _this6);
const pattern = notEmpty(config.point_pattern) ? config.point_pattern : [config.point_type];
ids.indexOf(d) === -1 && ids.push(d);
let point = pattern[ids.indexOf(d) % pattern.length];
if (point === "rectangle") {
point = "rect";
}
return browser_doc.createElementNS(namespaces.svg, "hasValidPointType" in $$ && $$.hasValidPointType(point) ? point : "use");
}.bind(this)).attr("class", $LEGEND.legendItemPoint).style("fill", getLegendColor.bind($$)).style("pointer-events", $$.getStylePropValue("none")).attr("href", function (data, idx, selection) {
_newArrowCheck(this, _this6);
const node = selection[idx],
nodeName = node.nodeName.toLowerCase(),
id = $$.getTargetSelectorSuffix(data);
return nodeName === "use" ? "#" + state.datetimeId + "-point" + id : undefined;
}.bind(this));
} else {
l.append(isRectangle ? "line" : legendType).attr("class", $LEGEND.legendItemTile).style("stroke", getLegendColor.bind($$)).style("pointer-events", $$.getStylePropValue("none")).call(function (selection) {
_newArrowCheck(this, _this6);
if (legendType === "circle") {
selection.attr("r", legendItemR).style("fill", getLegendColor.bind($$)).attr("cx", isLegendRightOrInset ? posFn.x2Tile : pos).attr("cy", isLegendRightOrInset ? pos : posFn.yTile);
} else if (isRectangle) {
selection.attr("stroke-width", itemTileSize.height).attr("x1", isLegendRightOrInset ? posFn.x1Tile : pos).attr("y1", isLegendRightOrInset ? pos : posFn.yTile).attr("x2", isLegendRightOrInset ? posFn.x2Tile : pos).attr("y2", isLegendRightOrInset ? pos : posFn.yTile);
}
}.bind(this));
}
},
/**
* Update legend item position
* @param {Array} targetIdz Data ids
* @param {boolean} withTransition Whether or not to apply transition
* @param {object} posFn Position functions
* @private
*/
updateLegendItemPos: function updateLegendItemPos(targetIdz, withTransition, posFn) {
var _this8 = this;
const $$ = this,
config = $$.config,
legend = $$.$el.legend,
$T = $$.$T,
usePoint = config.legend_usePoint,
legendType = config.legend_item_tile_type;
if (usePoint) {
const tiles = legend.selectAll("." + $LEGEND.legendItemPoint).data(targetIdz);
$T(tiles, withTransition).each(function () {
var _this7 = this;
const nodeName = this.nodeName.toLowerCase(),
pointR = config.point_r;
let x = "x",
y = "y",
xOffset = 2,
yOffset = 2.5,
radius = null,
width = null,
height = null;
if (nodeName === "circle") {
const size = pointR * .2;
x = "cx";
y = "cy";
radius = pointR + size;
xOffset = pointR * 2;
yOffset = -size;
} else if (nodeName === "rect") {
const size = pointR * 2.5;
width = size;
height = size;
yOffset = 3;
}
src_select(this).attr(x, function (d) {
_newArrowCheck(this, _this7);
return posFn.x1Tile(d) + xOffset;
}.bind(this)).attr(y, function (d) {
_newArrowCheck(this, _this7);
return posFn.yTile(d) - yOffset;
}.bind(this)).attr("r", radius).attr("width", width).attr("height", height);
});
} else {
const tiles = legend.selectAll("." + $LEGEND.legendItemTile).data(targetIdz);
$T(tiles, withTransition).style("stroke", getLegendColor.bind($$)).call(function (selection) {
var _this9 = this;
_newArrowCheck(this, _this8);
if (legendType === "circle") {
selection.attr("cx", function (d) {
_newArrowCheck(this, _this9);
const x2 = posFn.x2Tile(d);
return x2 - (x2 - posFn.x1Tile(d)) / 2;
}.bind(this)).attr("cy", posFn.yTile);
} else if (legendType !== "circle") {
selection.attr("x1", posFn.x1Tile).attr("y1", posFn.yTile).attr("x2", posFn.x2Tile).attr("y2", posFn.yTile);
}
}.bind(this));
}
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/redraw.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var redraw = ({
redraw: function redraw(options) {
var _$$$axis,
_this = this;
if (options === void 0) {
options = {};
}
const $$ = this,
config = $$.config,
state = $$.state,
$el = $$.$el,
_$el = $el,
main = _$el.main,
treemap = _$el.treemap;
state.redrawing = !0;
const targetsToShow = $$.filterTargetsToShow($$.data.targets),
_options = options,
flow = _options.flow,
initializing = _options.initializing,
wth = $$.getWithOption(options),
duration = wth.Transition ? config.transition_duration : 0,
durationForExit = wth.TransitionForExit ? duration : 0,
durationForAxis = wth.TransitionForAxis ? duration : 0,
transitions = (_$$$axis = $$.axis) == null ? void 0 : _$$$axis.generateTransitions(durationForAxis);
$$.updateSizes(initializing);
// update legend and transform each g
if (wth.Legend && config.legend_show) {
options.withTransition = !!duration;
treemap || $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
} else if (wth.Dimension) {
// 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(!0);
}
// Data empty label positioning and text.
config.data_empty_label_text && main.select("text." + $TEXT.text + "." + $COMMON.empty).attr("x", state.width / 2).attr("y", state.height / 2).text(config.data_empty_label_text).style("display", targetsToShow.length ? "none" : null);
// update axis
if (state.hasAxis) {
// @TODO: Make 'init' state to be accessible everywhere not passing as argument.
$$.axis.redrawAxis(targetsToShow, wth, transitions, flow, initializing);
// grid
$$.hasGrid() && $$.updateGrid();
// rect for regions
config.regions.length && $$.updateRegion();
["bar", "candlestick", "line", "area"].forEach(function (v) {
_newArrowCheck(this, _this);
const name = capitalize(v);
if (/^(line|area)$/.test(v) && $$.hasTypeOf(name) || $$.hasType(v)) {
$$["update" + name](wth.TransitionForExit);
}
}.bind(this));
// circles for select
$el.text && main.selectAll("." + $SELECT.selectedCircles).filter($$.isBarType.bind($$)).selectAll("circle").remove();
// event rects will redrawn when flow called
if (config.interaction_enabled && !flow && wth.EventRect) {
$$.redrawEventRect();
$$.bindZoomEvent == null || $$.bindZoomEvent();
}
} else {
// arc
$el.arcs && $$.redrawArc(duration, durationForExit, wth.Transform);
// radar
$el.radar && $$.redrawRadar();
// polar
$el.polar && $$.redrawPolar();
// treemap
treemap && $$.updateTreemap(durationForExit);
}
if (!state.resizing && !treemap && ($$.hasPointType() || state.hasRadar)) {
$$.updateCircle();
} else if ($$.hasLegendDefsPoint != null && $$.hasLegendDefsPoint()) {
$$.data.targets.forEach($$.point("create", this));
}
// text
$$.hasDataLabel() && !$$.hasArcType(null, ["radar"]) && $$.updateText();
// title
$$.redrawTitle == null || $$.redrawTitle();
initializing && $$.updateTypesElements();
$$.generateRedrawList(targetsToShow, flow, duration, wth.Subchart);
$$.updateTooltipOnRedraw();
$$.callPluginHook("$redraw", options, duration);
},
/**
* Generate redraw list
* @param {object} targets targets data to be shown
* @param {object} flow flow object
* @param {number} duration duration value
* @param {boolean} withSubchart whether or not to show subchart
* @private
*/
generateRedrawList: function generateRedrawList(targets, flow, duration, withSubchart) {
var _this2 = this;
const $$ = this,
config = $$.config,
state = $$.state,
shape = $$.getDrawShape();
if (state.hasAxis) {
// subchart
config.subchart_show && $$.redrawSubchart(withSubchart, duration, shape);
}
// generate flow
const flowFn = flow && $$.generateFlow({
targets: targets,
flow: flow,
duration: flow.duration,
shape: shape,
xv: $$.xv.bind($$)
}),
withTransition = (duration || flowFn) && isTabVisible(),
redrawList = $$.getRedrawList(shape, flow, flowFn, withTransition),
afterRedraw = function () {
_newArrowCheck(this, _this2);
flowFn && flowFn();
state.redrawing = !1;
callFn(config.onrendered, $$.api);
}.bind(this); // redraw list
// callback function after redraw ends
if (afterRedraw) {
// Only use transition when current tab is visible.
if (withTransition && redrawList.length) {
// Wait for end of transitions for callback
const waitForDraw = generateWait();
// transition should be derived from one transition
transition_transition().duration(duration).each(function () {
var _this3 = this;
_newArrowCheck(this, _this2);
redrawList.reduce(function (acc, t1) {
_newArrowCheck(this, _this3);
return acc.concat(t1);
}.bind(this), []).forEach(function (t) {
_newArrowCheck(this, _this3);
return waitForDraw.add(t);
}.bind(this));
}.bind(this)).call(waitForDraw, afterRedraw);
} else if (!state.transiting) {
afterRedraw();
}
}
// update fadein condition
$$.mapToIds($$.data.targets).forEach(function (id) {
_newArrowCheck(this, _this2);
state.withoutFadeIn[id] = !0;
}.bind(this));
},
getRedrawList: function getRedrawList(shape, flow, flowFn, withTransition) {
var _this4 = this;
const $$ = this,
config = $$.config,
_$$$state = $$.state,
hasAxis = _$$$state.hasAxis,
hasRadar = _$$$state.hasRadar,
hasTreemap = _$$$state.hasTreemap,
grid = $$.$el.grid,
_shape$pos = shape.pos,
cx = _shape$pos.cx,
cy = _shape$pos.cy,
xForText = _shape$pos.xForText,
yForText = _shape$pos.yForText,
list = [];
if (hasAxis) {
if (config.grid_x_lines.length || config.grid_y_lines.length) {
list.push($$.redrawGrid(withTransition));
}
if (config.regions.length) {
list.push($$.redrawRegion(withTransition));
}
Object.keys(shape.type).forEach(function (v) {
_newArrowCheck(this, _this4);
const name = capitalize(v),
drawFn = shape.type[v];
if (/^(area|line)$/.test(v) && $$.hasTypeOf(name) || $$.hasType(v)) {
list.push($$["redraw" + name](drawFn, withTransition));
}
}.bind(this));
!flow && grid.main && list.push($$.updateGridFocus());
}
if (!$$.hasArcType() || hasRadar) {
notEmpty(config.data_labels) && config.data_labels !== !1 && list.push($$.redrawText(xForText, yForText, flow, withTransition));
}
if (($$.hasPointType() || hasRadar) && !$$.isPointFocusOnly()) {
$$.redrawCircle && list.push($$.redrawCircle(cx, cy, withTransition, flowFn));
}
if (hasTreemap) {
list.push($$.redrawTreemap(withTransition));
}
return list;
},
updateAndRedraw: function updateAndRedraw(options) {
if (options === void 0) {
options = {};
}
const $$ = this,
config = $$.config,
state = $$.state;
let transitions;
// same with redraw
options.withTransition = getOption(options, "withTransition", !0);
options.withTransform = getOption(options, "withTransform", !1);
options.withLegend = getOption(options, "withLegend", !1);
// NOT same with redraw
options.withUpdateXDomain = !0;
options.withUpdateOrgXDomain = !0;
options.withTransitionForExit = !1;
options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition);
// MEMO: called in updateLegend in redraw if withLegend
if (!(options.withLegend && config.legend_show)) {
if (state.hasAxis) {
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);
}
});
;// CONCATENATED MODULE: ./node_modules/d3-array/src/ticks.js
const e10 = Math.sqrt(50),
e5 = Math.sqrt(10),
e2 = Math.sqrt(2);
function tickSpec(start, stop, count) {
const step = (stop - start) / Math.max(0, count),
power = Math.floor(Math.log10(step)),
error = step / Math.pow(10, power),
factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1;
let i1, i2, inc;
if (power < 0) {
inc = Math.pow(10, -power) / factor;
i1 = Math.round(start * inc);
i2 = Math.round(stop * inc);
if (i1 / inc < start) ++i1;
if (i2 / inc > stop) --i2;
inc = -inc;
} else {
inc = Math.pow(10, power) * factor;
i1 = Math.round(start / inc);
i2 = Math.round(stop / inc);
if (i1 * inc < start) ++i1;
if (i2 * inc > stop) --i2;
}
if (i2 < i1 && .5 <= count && count < 2) return tickSpec(start, stop, count * 2);
return [i1, i2, inc];
}
function ticks(start, stop, count) {
stop = +stop, start = +start, count = +count;
if (!(count > 0)) return [];
if (start === stop) return [start];
const reverse = stop < start,
_ref = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count),
i1 = _ref[0],
i2 = _ref[1],
inc = _ref[2];
if (!(i2 >= i1)) return [];
const n = i2 - i1 + 1,
ticks = Array(n);
if (reverse) {
if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) / -inc;else for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) * inc;
} else {
if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) / -inc;else for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) * inc;
}
return ticks;
}
function tickIncrement(start, stop, count) {
stop = +stop, start = +start, count = +count;
return tickSpec(start, stop, count)[2];
}
function tickStep(start, stop, count) {
stop = +stop, start = +start, count = +count;
const reverse = stop < start,
inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count);
return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);
}
;// CONCATENATED MODULE: ./node_modules/d3-array/src/ascending.js
function ascending_ascending(a, b) {
return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
;// CONCATENATED MODULE: ./node_modules/d3-array/src/descending.js
function descending(a, b) {
return a == null || b == null ? NaN : b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}
;// CONCATENATED MODULE: ./node_modules/d3-array/src/bisector.js
function bisector(f) {
var _this = this;
let compare1, compare2, delta;
// If an accessor is specified, promote it to a comparator. In this case we
// can test whether the search value is (self-) comparable. We can’t do this
// for a comparator (except for specific, known comparators) because we can’t
// tell if the comparator is symmetric, and an asymmetric comparator can’t be
// used to test whether a single value is comparable.
if (f.length !== 2) {
compare1 = ascending_ascending;
compare2 = function compare2(d, x) {
_newArrowCheck(this, _this);
return ascending_ascending(f(d), x);
}.bind(this);
delta = function delta(d, x) {
_newArrowCheck(this, _this);
return f(d) - x;
}.bind(this);
} else {
compare1 = f === ascending_ascending || f === descending ? f : bisector_zero;
compare2 = f;
delta = f;
}
function left(a, x, lo, hi) {
if (lo === void 0) {
lo = 0;
}
if (hi === void 0) {
hi = a.length;
}
if (lo < hi) {
if (compare1(x, x) !== 0) return hi;
do {
const mid = lo + hi >>> 1;
if (compare2(a[mid], x) < 0) lo = mid + 1;else hi = mid;
} while (lo < hi);
}
return lo;
}
function right(a, x, lo, hi) {
if (lo === void 0) {
lo = 0;
}
if (hi === void 0) {
hi = a.length;
}
if (lo < hi) {
if (compare1(x, x) !== 0) return hi;
do {
const mid = lo + hi >>> 1;
if (compare2(a[mid], x) <= 0) lo = mid + 1;else hi = mid;
} while (lo < hi);
}
return lo;
}
function center(a, x, lo, hi) {
if (lo === void 0) {
lo = 0;
}
if (hi === void 0) {
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: left,
center: center,
right: right
};
}
function bisector_zero() {
return 0;
}
;// CONCATENATED MODULE: ./node_modules/d3-array/src/number.js
var number_marked = /*#__PURE__*/regenerator.mark(numbers);
function number_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = number_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: !0 }; return { done: !1, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function number_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return number_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 number_arrayLikeToArray(o, minLen); }
function number_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function number_number(x) {
return x === null ? NaN : +x;
}
function numbers(values, valueof) {
var _iterator, _step, value, index, _iterator2, _step2;
return regenerator.wrap(function (_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
if (!(valueof === undefined)) {
_context.next = 11;
break;
}
_iterator = number_createForOfIteratorHelperLoose(values);
case 2:
if ((_step = _iterator()).done) {
_context.next = 9;
break;
}
value = _step.value;
if (!(value != null && (value = +value) >= value)) {
_context.next = 7;
break;
}
_context.next = 7;
return value;
case 7:
_context.next = 2;
break;
case 9:
_context.next = 20;
break;
case 11:
index = -1;
_iterator2 = number_createForOfIteratorHelperLoose(values);
case 13:
if ((_step2 = _iterator2()).done) {
_context.next = 20;
break;
}
value = _step2.value;
if (!((value = valueof(value, ++index, values)) != null && (value = +value) >= value)) {
_context.next = 18;
break;
}
_context.next = 18;
return value;
case 18:
_context.next = 13;
break;
case 20:
case "end":
return _context.stop();
}
}, number_marked);
}
;// CONCATENATED MODULE: ./node_modules/d3-array/src/bisect.js
const ascendingBisect = bisector(ascending_ascending);
const bisectRight = ascendingBisect.right;
const bisectLeft = ascendingBisect.left;
const bisectCenter = bisector(number_number).center;
/* harmony default export */ var bisect = (bisectRight);
;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/round.js
/* harmony default export */ function round(a, b) {
return a = +a, b = +b, function (t) {
return Math.round(a * (1 - t) + b * t);
};
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/constant.js
function constants(x) {
return function () {
return x;
};
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/number.js
function src_number_number(x) {
return +x;
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/continuous.js
var unit = [0, 1];
function continuous_identity(x) {
return x;
}
function normalize(a, b) {
return (b -= a = +a) ? function (x) {
return (x - a) / b;
} : constants(isNaN(b) ? NaN : .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 = Array(j),
r = 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 = bisect(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()).clamp(source.clamp()).unknown(source.unknown());
}
function transformer() {
var domain = unit,
range = unit,
interpolate = value,
transform,
untransform,
unknown,
clamp = continuous_identity,
piecewise,
output,
input;
function rescale() {
var n = Math.min(domain.length, range.length);
if (clamp !== continuous_identity) clamp = clamper(domain[0], domain[n - 1]);
piecewise = n > 2 ? polymap : bimap;
output = input = null;
return scale;
}
function scale(x) {
return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));
}
scale.invert = function (y) {
return clamp(untransform((input || (input = piecewise(range, domain.map(transform), number)))(y)));
};
scale.domain = function (_) {
return arguments.length ? (domain = Array.from(_, src_number_number), rescale()) : domain.slice();
};
scale.range = function (_) {
return arguments.length ? (range = Array.from(_), rescale()) : range.slice();
};
scale.rangeRound = function (_) {
return range = Array.from(_), interpolate = round, rescale();
};
scale.clamp = function (_) {
return arguments.length ? (clamp = _ ? !0 : continuous_identity, rescale()) : clamp !== continuous_identity;
};
scale.interpolate = function (_) {
return arguments.length ? (interpolate = _, rescale()) : interpolate;
};
scale.unknown = function (_) {
return arguments.length ? (unknown = _, scale) : unknown;
};
return function (t, u) {
transform = t, untransform = u;
return rescale();
};
}
function continuous() {
return transformer()(continuous_identity, continuous_identity);
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatSpecifier.js
// [[fill]align][sign][symbol][0][width][,][.precision][~][type]
var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;
function formatSpecifier(specifier) {
if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
var match;
return new FormatSpecifier({
fill: match[1],
align: match[2],
sign: match[3],
symbol: match[4],
zero: match[5],
width: match[6],
comma: match[7],
precision: match[8] && match[8].slice(1),
trim: match[9],
type: match[10]
});
}
formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
function FormatSpecifier(specifier) {
this.fill = specifier.fill === undefined ? " " : specifier.fill + "";
this.align = specifier.align === undefined ? ">" : specifier.align + "";
this.sign = specifier.sign === undefined ? "-" : specifier.sign + "";
this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + "";
this.zero = !!specifier.zero;
this.width = specifier.width === undefined ? undefined : +specifier.width;
this.comma = !!specifier.comma;
this.precision = specifier.precision === undefined ? undefined : +specifier.precision;
this.trim = !!specifier.trim;
this.type = specifier.type === undefined ? "" : specifier.type + "";
}
FormatSpecifier.prototype.toString = function () {
return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === undefined ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type;
};
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatDecimal.js
/* harmony default export */ function formatDecimal(x) {
return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10);
}
// Computes the decimal coefficient and exponent of the specified number x with
// significant digits p, where x is positive and p is in [1, 21] or undefined.
// For example, formatDecimalParts(1.23) returns ["123", 0].
function formatDecimalParts(x, p) {
if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
var i,
coefficient = x.slice(0, i);
// The string returned by toExponential either has the form \d\.\d+e[-+]\d+
// (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
return [coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, +x.slice(i + 1)];
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/exponent.js
/* harmony default export */ function exponent(x) {
return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/precisionPrefix.js
/* harmony default export */ function precisionPrefix(step, value) {
return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatGroup.js
/* harmony default export */ function formatGroup(grouping, thousands) {
return function (value, width) {
var i = value.length,
t = [],
j = 0,
g = grouping[0],
length = 0;
while (i > 0 && g > 0) {
if (length + g + 1 > width) g = Math.max(1, width - length);
t.push(value.substring(i -= g, i + g));
if ((length += g + 1) > width) break;
g = grouping[j = (j + 1) % grouping.length];
}
return t.reverse().join(thousands);
};
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatNumerals.js
/* harmony default export */ function formatNumerals(numerals) {
return function (value) {
return value.replace(/[0-9]/g, function (i) {
return numerals[+i];
});
};
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatTrim.js
// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.
/* harmony default export */ function formatTrim(s) {
out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {
switch (s[i]) {
case ".":
i0 = i1 = i;
break;
case "0":
if (i0 === 0) i0 = i;
i1 = i;
break;
default:
if (!+s[i]) break out;
if (i0 > 0) i0 = 0;
break;
}
}
return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatPrefixAuto.js
var prefixExponent;
/* harmony default export */ function formatPrefixAuto(x, p) {
var d = formatDecimalParts(x, p);
if (!d) return x + "";
var coefficient = d[0],
exponent = d[1],
i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
n = coefficient.length;
return i === n ? coefficient : i > n ? coefficient + Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatRounded.js
/* harmony default export */ function formatRounded(x, p) {
var d = formatDecimalParts(x, p);
if (!d) return x + "";
var coefficient = d[0],
exponent = d[1];
return exponent < 0 ? "0." + Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + Array(exponent - coefficient.length + 2).join("0");
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatTypes.js
var formatTypes_this = undefined;
/* harmony default export */ var formatTypes = ({
"%": function _(x, p) {
_newArrowCheck(this, formatTypes_this);
return (x * 100).toFixed(p);
}.bind(undefined),
"b": function b(x) {
_newArrowCheck(this, formatTypes_this);
return Math.round(x).toString(2);
}.bind(undefined),
"c": function c(x) {
_newArrowCheck(this, formatTypes_this);
return x + "";
}.bind(undefined),
"d": formatDecimal,
"e": function e(x, p) {
_newArrowCheck(this, formatTypes_this);
return x.toExponential(p);
}.bind(undefined),
"f": function f(x, p) {
_newArrowCheck(this, formatTypes_this);
return x.toFixed(p);
}.bind(undefined),
"g": function g(x, p) {
_newArrowCheck(this, formatTypes_this);
return x.toPrecision(p);
}.bind(undefined),
"o": function o(x) {
_newArrowCheck(this, formatTypes_this);
return Math.round(x).toString(8);
}.bind(undefined),
"p": function p(x, _p) {
_newArrowCheck(this, formatTypes_this);
return formatRounded(x * 100, _p);
}.bind(undefined),
"r": formatRounded,
"s": formatPrefixAuto,
"X": function X(x) {
_newArrowCheck(this, formatTypes_this);
return Math.round(x).toString(16).toUpperCase();
}.bind(undefined),
"x": function x(_x) {
_newArrowCheck(this, formatTypes_this);
return Math.round(_x).toString(16);
}.bind(undefined)
});
;// CONCATENATED MODULE: ./node_modules/d3-format/src/identity.js
/* harmony default export */ function src_identity(x) {
return x;
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/locale.js
var map = Array.prototype.map,
prefixes = ["y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"];
/* harmony default export */ function src_locale(locale) {
var group = locale.grouping === undefined || locale.thousands === undefined ? src_identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""),
currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "",
currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "",
decimal = locale.decimal === undefined ? "." : locale.decimal + "",
numerals = locale.numerals === undefined ? src_identity : formatNumerals(map.call(locale.numerals, String)),
percent = locale.percent === undefined ? "%" : locale.percent + "",
minus = locale.minus === undefined ? "−" : locale.minus + "",
nan = locale.nan === undefined ? "NaN" : locale.nan + "";
function newFormat(specifier) {
specifier = formatSpecifier(specifier);
var fill = specifier.fill,
align = specifier.align,
sign = specifier.sign,
symbol = specifier.symbol,
zero = specifier.zero,
width = specifier.width,
comma = specifier.comma,
precision = specifier.precision,
trim = specifier.trim,
type = specifier.type;
// The "n" type is an alias for ",g".
if (type === "n") comma = !0, type = "g";
// The "" type, and any invalid type, is an alias for ".12~g".
else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = !0, type = "g";
// If zero fill is specified, padding goes after sign and before digits.
if (zero || fill === "0" && align === "=") zero = !0, fill = "0", align = "=";
// Compute the prefix and suffix.
// For SI-prefix, the suffix is lazily computed.
var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : "",
formatType = formatTypes[type],
maybeSuffix = /[defgprs%]/.test(type); // What format function should we use?
// Is this an integer type?
// Can this type generate exponential notation?
// Set the default precision if not specified,
// or clamp the specified precision to the supported range.
// For significant precision, it must be in [1, 21].
// For fixed precision, it must be in [0, 20].
precision = precision === undefined ? 6 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) : Math.max(0, Math.min(20, precision));
function format(value) {
var valuePrefix = prefix,
valueSuffix = suffix,
i,
n,
c;
if (type === "c") {
valueSuffix = formatType(value) + valueSuffix;
value = "";
} else {
value = +value;
// Determine the sign. -0 is not less than 0, but 1 / -0 is!
var valueNegative = value < 0 || 1 / value < 0;
// Perform the initial formatting.
value = isNaN(value) ? nan : formatType(Math.abs(value), precision);
// Trim insignificant zeros.
if (trim) value = formatTrim(value);
// If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.
if (valueNegative && +value === 0 && sign !== "+") valueNegative = !1;
// Compute the prefix and suffix.
valuePrefix = (valueNegative ? sign === "(" ? sign : minus : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
// Break the formatted value into the integer “value” part that can be
// grouped, and fractional or exponential “suffix” part that is not.
if (maybeSuffix) {
i = -1, n = value.length;
while (++i < n) {
if (c = value.charCodeAt(i), 48 > c || c > 57) {
valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
value = value.slice(0, i);
break;
}
}
}
}
// If the fill character is not "0", grouping is applied before padding.
if (comma && !zero) value = group(value, Infinity);
// Compute the padding.
var length = valuePrefix.length + value.length + valueSuffix.length,
padding = length < width ? Array(width - length + 1).join(fill) : "";
// If the fill character is "0", grouping is applied after padding.
if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
// Reconstruct the final output based on the desired alignment.
switch (align) {
case "<":
value = valuePrefix + value + valueSuffix + padding;
break;
case "=":
value = valuePrefix + padding + value + valueSuffix;
break;
case "^":
value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
break;
default:
value = padding + valuePrefix + value + valueSuffix;
break;
}
return numerals(value);
}
format.toString = function () {
return specifier + "";
};
return format;
}
return {
format: newFormat,
formatPrefix: function (specifier, value) {
var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
k = Math.pow(10, -e),
prefix = prefixes[8 + e / 3];
return function (value) {
return f(k * value) + prefix;
};
}
};
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/defaultLocale.js
var defaultLocale_locale;
var defaultLocale_format;
var formatPrefix;
defaultLocale_defaultLocale({
thousands: ",",
grouping: [3],
currency: ["$", ""]
});
function defaultLocale_defaultLocale(definition) {
defaultLocale_locale = src_locale(definition);
defaultLocale_format = defaultLocale_locale.format;
formatPrefix = defaultLocale_locale.formatPrefix;
return defaultLocale_locale;
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/precisionRound.js
/* harmony default export */ function precisionRound(step, max) {
step = Math.abs(step), max = Math.abs(max) - step;
return Math.max(0, exponent(max) - exponent(step)) + 1;
}
;// CONCATENATED MODULE: ./node_modules/d3-format/src/precisionFixed.js
/* harmony default export */ function precisionFixed(step) {
return Math.max(0, -exponent(Math.abs(step)));
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/tickFormat.js
function tickFormat(start, stop, count, specifier) {
var step = tickStep(start, stop, count),
precision;
specifier = formatSpecifier(specifier == null ? ",f" : specifier);
switch (specifier.type) {
case "s":
{
var value = Math.max(Math.abs(start), Math.abs(stop));
if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
return formatPrefix(specifier, value);
}
case "":
case "e":
case "g":
case "p":
case "r":
{
if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
break;
}
case "f":
case "%":
{
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
break;
}
}
return defaultLocale_format(specifier);
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/linear.js
function linearish(scale) {
var domain = scale.domain;
scale.ticks = function (count) {
var d = domain();
return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
};
scale.tickFormat = function (count, specifier) {
var d = domain();
return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);
};
scale.nice = function (count) {
if (count == null) count = 10;
var d = domain(),
i0 = 0,
i1 = d.length - 1,
start = d[i0],
stop = d[i1],
prestep,
step,
maxIter = 10;
if (stop < start) {
step = start, start = stop, stop = step;
step = i0, i0 = i1, i1 = step;
}
while (maxIter-- > 0) {
step = tickIncrement(start, stop, count);
if (step === prestep) {
d[i0] = start;
d[i1] = stop;
return domain(d);
} else if (step > 0) {
start = Math.floor(start / step) * step;
stop = Math.ceil(stop / step) * step;
} else if (step < 0) {
start = Math.ceil(start * step) / step;
stop = Math.floor(stop * step) / step;
} else {
break;
}
prestep = step;
}
return scale;
};
return scale;
}
function linear_linear() {
var scale = continuous();
scale.copy = function () {
return copy(scale, linear_linear());
};
initRange.apply(scale, arguments);
return linearish(scale);
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/symlog.js
function transformSymlog(c) {
return function (x) {
return Math.sign(x) * Math.log1p(Math.abs(x / c));
};
}
function transformSymexp(c) {
return function (x) {
return Math.sign(x) * Math.expm1(Math.abs(x)) * c;
};
}
function symlogish(transform) {
var c = 1,
scale = transform(transformSymlog(c), transformSymexp(c));
scale.constant = function (_) {
return arguments.length ? transform(transformSymlog(c = +_), transformSymexp(c)) : c;
};
return linearish(scale);
}
function symlog() {
var scale = symlogish(transformer());
scale.copy = function () {
return copy(scale, symlog()).constant(scale.constant());
};
return initRange.apply(scale, arguments);
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/nice.js
function nice(domain, interval) {
domain = domain.slice();
var i0 = 0,
i1 = domain.length - 1,
x0 = domain[i0],
x1 = domain[i1],
t;
if (x1 < x0) {
t = i0, i0 = i1, i1 = t;
t = x0, x0 = x1, x1 = t;
}
domain[i0] = interval.floor(x0);
domain[i1] = interval.ceil(x1);
return domain;
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/log.js
function transformLog(x) {
return Math.log(x);
}
function transformExp(x) {
return Math.exp(x);
}
function transformLogn(x) {
return -Math.log(-x);
}
function transformExpn(x) {
return -Math.exp(-x);
}
function pow10(x) {
return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
}
function powp(base) {
var _this = this;
return base === 10 ? pow10 : base === Math.E ? Math.exp : function (x) {
_newArrowCheck(this, _this);
return Math.pow(base, x);
}.bind(this);
}
function logp(base) {
var _this2 = this;
return base === Math.E ? Math.log : base === 10 && Math.log10 || base === 2 && Math.log2 || (base = Math.log(base), function (x) {
_newArrowCheck(this, _this2);
return Math.log(x) / base;
}.bind(this));
}
function reflect(f) {
var _this3 = this;
return function (x, k) {
_newArrowCheck(this, _this3);
return -f(-x, k);
}.bind(this);
}
function loggish(transform) {
var _this4 = this;
const scale = transform(transformLog, transformExp),
domain = scale.domain;
let base = 10,
logs,
pows;
function rescale() {
logs = logp(base), pows = powp(base);
if (domain()[0] < 0) {
logs = reflect(logs), pows = reflect(pows);
transform(transformLogn, transformExpn);
} else {
transform(transformLog, transformExp);
}
return scale;
}
scale.base = function (_) {
return arguments.length ? (base = +_, rescale()) : base;
};
scale.domain = function (_) {
return arguments.length ? (domain(_), rescale()) : domain();
};
scale.ticks = function (count) {
_newArrowCheck(this, _this4);
const d = domain();
let u = d[0],
v = d[d.length - 1];
const r = v < u;
if (r) {
var _ref = [v, u];
u = _ref[0];
v = _ref[1];
}
let i = logs(u),
j = logs(v),
k,
t;
const n = count == null ? 10 : +count;
let z = [];
if (!(base % 1) && j - i < n) {
i = Math.floor(i), j = Math.ceil(j);
if (u > 0) for (; i <= j; ++i) {
for (k = 1; k < base; ++k) {
t = i < 0 ? k / pows(-i) : k * pows(i);
if (t < u) continue;
if (t > v) break;
z.push(t);
}
} else for (; i <= j; ++i) {
for (k = base - 1; k >= 1; --k) {
t = i > 0 ? k / pows(-i) : k * pows(i);
if (t < u) continue;
if (t > v) break;
z.push(t);
}
}
if (z.length * 2 < n) z = ticks(u, v, n);
} else {
z = ticks(i, j, Math.min(j - i, n)).map(pows);
}
return r ? z.reverse() : z;
}.bind(this);
scale.tickFormat = function (count, specifier) {
var _this5 = this;
_newArrowCheck(this, _this4);
if (count == null) count = 10;
if (specifier == null) specifier = base === 10 ? "s" : ",";
if (typeof specifier !== "function") {
if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = !0;
specifier = defaultLocale_format(specifier);
}
if (count === Infinity) return specifier;
const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
return function (d) {
_newArrowCheck(this, _this5);
let i = d / pows(Math.round(logs(d)));
if (i * base < base - .5) i *= base;
return i <= k ? specifier(d) : "";
}.bind(this);
}.bind(this);
scale.nice = function () {
var _this6 = this;
_newArrowCheck(this, _this4);
return domain(nice(domain(), {
floor: function floor(x) {
_newArrowCheck(this, _this6);
return pows(Math.floor(logs(x)));
}.bind(this),
ceil: function ceil(x) {
_newArrowCheck(this, _this6);
return pows(Math.ceil(logs(x)));
}.bind(this)
}));
}.bind(this);
return scale;
}
function log() {
var _this7 = this;
const scale = loggish(transformer()).domain([1, 10]);
scale.copy = function () {
_newArrowCheck(this, _this7);
return copy(scale, log()).base(scale.base());
}.bind(this);
initRange.apply(scale, arguments);
return scale;
}
;// CONCATENATED MODULE: ./node_modules/d3-time/src/millisecond.js
var millisecond_this = undefined;
const millisecond = timeInterval(function () {
_newArrowCheck(this, millisecond_this);
} // noop
.bind(undefined), function (date, step) {
_newArrowCheck(this, millisecond_this);
date.setTime(+date + step);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, millisecond_this);
return end - start;
}.bind(undefined));
// An optimized implementation for this simple case.
millisecond.every = function (k) {
var _this2 = this;
_newArrowCheck(this, millisecond_this);
k = Math.floor(k);
if (!isFinite(k) || !(k > 0)) return null;
if (!(k > 1)) return millisecond;
return timeInterval(function (date) {
_newArrowCheck(this, _this2);
date.setTime(Math.floor(date / k) * k);
}.bind(this), function (date, step) {
_newArrowCheck(this, _this2);
date.setTime(+date + step * k);
}.bind(this), function (start, end) {
_newArrowCheck(this, _this2);
return (end - start) / k;
}.bind(this));
}.bind(undefined);
const milliseconds = millisecond.range;
;// CONCATENATED MODULE: ./node_modules/d3-time/src/second.js
var second_this = undefined;
const second = timeInterval(function (date) {
_newArrowCheck(this, second_this);
date.setTime(date - date.getMilliseconds());
}.bind(undefined), function (date, step) {
_newArrowCheck(this, second_this);
date.setTime(+date + step * durationSecond);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, second_this);
return (end - start) / durationSecond;
}.bind(undefined), function (date) {
_newArrowCheck(this, second_this);
return date.getUTCSeconds();
}.bind(undefined));
const seconds = second.range;
;// CONCATENATED MODULE: ./node_modules/d3-time/src/minute.js
var minute_this = undefined;
const timeMinute = timeInterval(function (date) {
_newArrowCheck(this, minute_this);
date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);
}.bind(undefined), function (date, step) {
_newArrowCheck(this, minute_this);
date.setTime(+date + step * durationMinute);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, minute_this);
return (end - start) / durationMinute;
}.bind(undefined), function (date) {
_newArrowCheck(this, minute_this);
return date.getMinutes();
}.bind(undefined));
const timeMinutes = timeMinute.range;
const utcMinute = timeInterval(function (date) {
_newArrowCheck(this, minute_this);
date.setUTCSeconds(0, 0);
}.bind(undefined), function (date, step) {
_newArrowCheck(this, minute_this);
date.setTime(+date + step * durationMinute);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, minute_this);
return (end - start) / durationMinute;
}.bind(undefined), function (date) {
_newArrowCheck(this, minute_this);
return date.getUTCMinutes();
}.bind(undefined));
const utcMinutes = utcMinute.range;
;// CONCATENATED MODULE: ./node_modules/d3-time/src/hour.js
var hour_this = undefined;
const timeHour = timeInterval(function (date) {
_newArrowCheck(this, hour_this);
date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);
}.bind(undefined), function (date, step) {
_newArrowCheck(this, hour_this);
date.setTime(+date + step * durationHour);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, hour_this);
return (end - start) / durationHour;
}.bind(undefined), function (date) {
_newArrowCheck(this, hour_this);
return date.getHours();
}.bind(undefined));
const timeHours = timeHour.range;
const utcHour = timeInterval(function (date) {
_newArrowCheck(this, hour_this);
date.setUTCMinutes(0, 0, 0);
}.bind(undefined), function (date, step) {
_newArrowCheck(this, hour_this);
date.setTime(+date + step * durationHour);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, hour_this);
return (end - start) / durationHour;
}.bind(undefined), function (date) {
_newArrowCheck(this, hour_this);
return date.getUTCHours();
}.bind(undefined));
const utcHours = utcHour.range;
;// CONCATENATED MODULE: ./node_modules/d3-time/src/month.js
var month_this = undefined;
const timeMonth = timeInterval(function (date) {
_newArrowCheck(this, month_this);
date.setDate(1);
date.setHours(0, 0, 0, 0);
}.bind(undefined), function (date, step) {
_newArrowCheck(this, month_this);
date.setMonth(date.getMonth() + step);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, month_this);
return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
}.bind(undefined), function (date) {
_newArrowCheck(this, month_this);
return date.getMonth();
}.bind(undefined));
const timeMonths = timeMonth.range;
const utcMonth = timeInterval(function (date) {
_newArrowCheck(this, month_this);
date.setUTCDate(1);
date.setUTCHours(0, 0, 0, 0);
}.bind(undefined), function (date, step) {
_newArrowCheck(this, month_this);
date.setUTCMonth(date.getUTCMonth() + step);
}.bind(undefined), function (start, end) {
_newArrowCheck(this, month_this);
return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
}.bind(undefined), function (date) {
_newArrowCheck(this, month_this);
return date.getUTCMonth();
}.bind(undefined));
const utcMonths = utcMonth.range;
;// CONCATENATED MODULE: ./node_modules/d3-time/src/ticks.js
function ticker(year, month, week, day, hour, minute) {
const tickIntervals = [[second, 1, durationSecond], [second, 5, 5 * durationSecond], [second, 15, 15 * durationSecond], [second, 30, 30 * durationSecond], [minute, 1, durationMinute], [minute, 5, 5 * durationMinute], [minute, 15, 15 * durationMinute], [minute, 30, 30 * durationMinute], [hour, 1, durationHour], [hour, 3, 3 * durationHour], [hour, 6, 6 * durationHour], [hour, 12, 12 * durationHour], [day, 1, durationDay], [day, 2, 2 * durationDay], [week, 1, durationWeek], [month, 1, durationMonth], [month, 3, 3 * durationMonth], [year, 1, durationYear]];
function ticks(start, stop, count) {
const reverse = stop < start;
if (reverse) {
var _ref = [stop, start];
start = _ref[0];
stop = _ref[1];
}
const interval = count && typeof count.range === "function" ? count : tickInterval(start, stop, count),
ticks = interval ? interval.range(start, +stop + 1) : [];
// inclusive stop
return reverse ? ticks.reverse() : ticks;
}
function tickInterval(start, stop, count) {
var _this = this;
const target = Math.abs(stop - start) / count,
i = bisector(function (_ref2) {
let step = _ref2[2];
_newArrowCheck(this, _this);
return step;
}.bind(this)).right(tickIntervals, target);
if (i === tickIntervals.length) return year.every(tickStep(start / durationYear, stop / durationYear, count));
if (i === 0) return millisecond.every(Math.max(tickStep(start, stop, count), 1));
const _tickIntervals = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i],
t = _tickIntervals[0],
step = _tickIntervals[1];
return t.every(step);
}
return [ticks, tickInterval];
}
const _ticker = ticker(utcYear, utcMonth, utcSunday, unixDay, utcHour, utcMinute),
utcTicks = _ticker[0],
utcTickInterval = _ticker[1],
_ticker2 = ticker(timeYear, timeMonth, timeSunday, timeDay, timeHour, timeMinute),
timeTicks = _ticker2[0],
timeTickInterval = _ticker2[1];
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/time.js
function time_date(t) {
return new Date(t);
}
function time_number(t) {
return t instanceof Date ? +t : +new Date(+t);
}
function calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format) {
var scale = continuous(),
invert = scale.invert,
domain = scale.domain,
formatMillisecond = format(".%L"),
formatSecond = format(":%S"),
formatMinute = format("%I:%M"),
formatHour = format("%I %p"),
formatDay = format("%a %d"),
formatWeek = format("%b %d"),
formatMonth = format("%B"),
formatYear = format("%Y");
function tickFormat(date) {
return (second(date) < date ? formatMillisecond : minute(date) < date ? formatSecond : hour(date) < date ? formatMinute : day(date) < date ? formatHour : month(date) < date ? week(date) < date ? formatDay : formatWeek : year(date) < date ? formatMonth : formatYear)(date);
}
scale.invert = function (y) {
return new Date(invert(y));
};
scale.domain = function (_) {
return arguments.length ? domain(Array.from(_, time_number)) : domain().map(time_date);
};
scale.ticks = function (interval) {
var d = domain();
return ticks(d[0], d[d.length - 1], interval == null ? 10 : interval);
};
scale.tickFormat = function (count, specifier) {
return specifier == null ? tickFormat : format(specifier);
};
scale.nice = function (interval) {
var d = domain();
if (!interval || typeof interval.range !== "function") interval = tickInterval(d[0], d[d.length - 1], interval == null ? 10 : interval);
return interval ? domain(nice(d, interval)) : scale;
};
scale.copy = function () {
return copy(scale, calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format));
};
return scale;
}
function time() {
return initRange.apply(calendar(timeTicks, timeTickInterval, timeYear, timeMonth, timeSunday, timeDay, timeHour, timeMinute, second, timeFormat).domain([new Date(2e3, 0, 1), new Date(2e3, 0, 2)]), arguments);
}
;// CONCATENATED MODULE: ./node_modules/d3-scale/src/utcTime.js
function utcTime() {
return initRange.apply(calendar(utcTicks, utcTickInterval, utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, utcFormat).domain([Date.UTC(2e3, 0, 1), Date.UTC(2e3, 0, 2)]), arguments);
}
;// CONCATENATED MODULE: ./src/ChartInternal/internals/scale.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get scale
* @param {string} [type='linear'] Scale type
* @param {number} [min] Min range
* @param {number} [max] Max range
* @returns {d3.scaleLinear|d3.scaleTime} scale
* @private
*/
function getScale(type, min, max) {
if (type === void 0) {
type = "linear";
}
if (min === void 0) {
min = 0;
}
if (max === void 0) {
max = 1;
}
const scale = {
linear: linear_linear,
log: symlog,
_log: log,
time: time,
utc: utcTime
}[type]();
scale.type = type;
/_?log/.test(type) && scale.clamp(!0);
return scale.range([min, max]);
}
/* harmony default export */ var scale = ({
/**
* Get x Axis scale function
* @param {number} min Min range value
* @param {number} max Max range value
* @param {Array} domain Domain value
* @param {Function} offset The offset getter to be sum
* @returns {Function} scale
* @private
*/
getXScale: function getXScale(min, max, domain, offset) {
const $$ = this,
scale = $$.state.loading !== "append" && $$.scale.zoom || getScale($$.axis.getAxisType("x"), min, max);
return $$.getCustomizedXScale(domain ? scale.domain(domain) : scale, offset);
},
/**
* Get y Axis scale function
* @param {string} id Axis id: 'y' or 'y2'
* @param {number} min Min value
* @param {number} max Max value
* @param {Array} domain Domain value
* @returns {Function} Scale function
* @private
*/
getYScale: function getYScale(id, min, max, domain) {
const $$ = this,
scale = getScale($$.axis.getAxisType(id), min, max);
domain && scale.domain(domain);
return scale;
},
/**
* Get y Axis scale
* @param {string} id Axis id
* @param {boolean} isSub Weather is sub Axis
* @returns {Function} Scale function
* @private
*/
getYScaleById: function getYScaleById(id, isSub) {
var _this$axis;
if (isSub === void 0) {
isSub = !1;
}
const isY2 = ((_this$axis = this.axis) == null ? void 0 : _this$axis.getId(id)) === "y2",
key = isSub ? isY2 ? "subY2" : "subY" : isY2 ? "y2" : "y";
return this.scale[key];
},
/**
* Get customized x axis scale
* @param {d3.scaleLinear|d3.scaleTime} scaleValue Scale function
* @param {Function} offsetValue Offset getter to be sum
* @returns {Function} Scale function
* @private
*/
getCustomizedXScale: function getCustomizedXScale(scaleValue, offsetValue) {
var _this = this;
const $$ = this,
offset = offsetValue || function () {
_newArrowCheck(this, _this);
return $$.axis.x.tickOffset();
}.bind(this),
isInverted = $$.config.axis_x_inverted,
scale = function (d, raw) {
const v = scaleValue(d) + offset();
return raw ? v : Math.ceil(v);
};
// copy original scale methods
for (const key in scaleValue) {
scale[key] = scaleValue[key];
}
scale.orgDomain = function () {
_newArrowCheck(this, _this);
return scaleValue.domain();
}.bind(this);
scale.orgScale = function () {
_newArrowCheck(this, _this);
return scaleValue;
}.bind(this);
// define custom domain() for categorized axis
if ($$.axis.isCategorized()) {
scale.domain = function (domainValue) {
let domain = domainValue;
if (!arguments.length) {
domain = this.orgDomain();
return isInverted ? [domain[0] + 1, domain[1]] : [domain[0], domain[1] + 1];
}
scaleValue.domain(domain);
return scale;
};
}
return scale;
},
/**
* Update scale
* @param {boolean} isInit Param is given at the init rendering
* @param {boolean} updateXDomain If update x domain
* @private
*/
updateScales: function updateScales(isInit, updateXDomain) {
var _this2 = this;
if (updateXDomain === void 0) {
updateXDomain = !0;
}
const $$ = this,
axis = $$.axis,
config = $$.config,
format = $$.format,
org = $$.org,
scale = $$.scale,
_$$$state = $$.state,
current = _$$$state.current,
width = _$$$state.width,
height = _$$$state.height,
width2 = _$$$state.width2,
height2 = _$$$state.height2,
hasAxis = _$$$state.hasAxis,
hasTreemap = _$$$state.hasTreemap;
if (hasAxis) {
var _scale$x;
const isRotated = config.axis_rotated,
resettedPadding = $$.getResettedPadding(1),
min = {
x: isRotated ? resettedPadding : 0,
y: isRotated ? 0 : height,
subX: isRotated ? 1 : 0,
subY: isRotated ? 0 : height2
},
max = {
x: isRotated ? height : width,
y: isRotated ? width : resettedPadding,
subX: isRotated ? height : width,
subY: isRotated ? width2 : 1
},
xDomain = updateXDomain && ((_scale$x = scale.x) == null ? void 0 : _scale$x.orgDomain()),
xSubDomain = updateXDomain && org.xDomain; // update edges
// update scales
// x Axis
scale.x = $$.getXScale(min.x, max.x, xDomain, function () {
_newArrowCheck(this, _this2);
return axis.x.tickOffset();
}.bind(this));
scale.subX = $$.getXScale(min.x, max.x, xSubDomain, function (d) {
var _axis$subX;
_newArrowCheck(this, _this2);
return d % 1 ? 0 : ((_axis$subX = axis.subX) != null ? _axis$subX : axis.x).tickOffset();
}.bind(this));
format.xAxisTick = axis.getXAxisTickFormat();
format.subXAxisTick = axis.getXAxisTickFormat(!0);
axis.setAxis("x", scale.x, config.axis_x_tick_outer, isInit);
if (config.subchart_show) {
axis.setAxis("subX", scale.subX, config.axis_x_tick_outer, isInit);
}
// y Axis
scale.y = $$.getYScale("y", min.y, max.y, scale.y ? scale.y.domain() : config.axis_y_default);
scale.subY = $$.getYScale("y", min.subY, max.subY, scale.subY ? scale.subY.domain() : config.axis_y_default);
axis.setAxis("y", scale.y, config.axis_y_tick_outer, isInit);
// y2 Axis
if (config.axis_y2_show) {
scale.y2 = $$.getYScale("y2", min.y, max.y, scale.y2 ? scale.y2.domain() : config.axis_y2_default);
scale.subY2 = $$.getYScale("y2", min.subY, max.subY, scale.subY2 ? scale.subY2.domain() : config.axis_y2_default);
axis.setAxis("y2", scale.y2, config.axis_y2_tick_outer, isInit);
}
} else if (hasTreemap) {
const padding = $$.getCurrentPadding();
scale.x = linear_linear().rangeRound([padding.left, current.width - padding.right]);
scale.y = linear_linear().rangeRound([padding.top, current.height - padding.bottom]);
} else {
// update for arc
$$.updateArc == null || $$.updateArc();
}
},
/**
* Get the zoom or unzoomed scaled value
* @param {Date|number|object} d Data value
* @returns {number|null}
* @private
*/
xx: function xx(d) {
const $$ = this,
config = $$.config,
_$$$scale = $$.scale,
x = _$$$scale.x,
zoom = _$$$scale.zoom,
fn = config.zoom_enabled && zoom ? zoom : x;
return d ? fn(isValue(d.x) ? d.x : d) : null;
},
xv: function xv(d) {
const $$ = this,
axis = $$.axis,
config = $$.config,
_$$$scale2 = $$.scale,
x = _$$$scale2.x,
zoom = _$$$scale2.zoom,
fn = config.zoom_enabled && zoom ? zoom : x;
let value = $$.getBaseValue(d);
if (axis.isTimeSeries()) {
value = parseDate.call($$, value);
} else if (axis.isCategorized() && isString(value)) {
value = config.axis_x_categories.indexOf(value);
}
return Math.ceil(fn(value));
},
yv: function yv(d) {
const $$ = this,
_$$$scale3 = $$.scale,
y = _$$$scale3.y,
y2 = _$$$scale3.y2,
yScale = d.axis && d.axis === "y2" ? y2 : y;
return Math.ceil(yScale($$.getBaseValue(d)));
},
subxx: function subxx(d) {
return d ? this.scale.subX(d.x) : null;
}
});
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/basis.js
function _point(that, x, y) {
that._context.bezierCurveTo((2 * that._x0 + that._x1) / 3, (2 * that._y0 + that._y1) / 3, (that._x0 + 2 * that._x1) / 3, (that._y0 + 2 * that._y1) / 3, (that._x0 + 4 * that._x1 + x) / 6, (that._y0 + 4 * that._y1 + y) / 6);
}
function Basis(context) {
this._context = context;
}
Basis.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 3:
_point(this, this._x1, this._y1);
// falls through
case 2:
this._context.lineTo(this._x1, this._y1);
break;
}
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3;
this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6);
// falls through
default:
_point(this, x, y);
break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
/* harmony default export */ function curve_basis(context) {
return new Basis(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/noop.js
/* harmony default export */ function src_noop() {}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/basisClosed.js
function BasisClosed(context) {
this._context = context;
}
BasisClosed.prototype = {
areaStart: src_noop,
areaEnd: src_noop,
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 1:
{
this._context.moveTo(this._x2, this._y2);
this._context.closePath();
break;
}
case 2:
{
this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
this._context.closePath();
break;
}
case 3:
{
this.point(this._x2, this._y2);
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
break;
}
}
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._x2 = x, this._y2 = y;
break;
case 1:
this._point = 2;
this._x3 = x, this._y3 = y;
break;
case 2:
this._point = 3;
this._x4 = x, this._y4 = y;
this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6);
break;
default:
_point(this, x, y);
break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
/* harmony default export */ function curve_basisClosed(context) {
return new BasisClosed(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/basisOpen.js
function BasisOpen(context) {
this._context = context;
}
BasisOpen.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
if (this._line || this._line !== 0 && this._point === 3) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3;
var x0 = (this._x0 + 4 * this._x1 + x) / 6,
y0 = (this._y0 + 4 * this._y1 + y) / 6;
this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0);
break;
case 3:
this._point = 4;
// falls through
default:
_point(this, x, y);
break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
/* harmony default export */ function basisOpen(context) {
return new BasisOpen(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/bundle.js
function Bundle(context, beta) {
this._basis = new Basis(context);
this._beta = beta;
}
Bundle.prototype = {
lineStart: function lineStart() {
this._x = [];
this._y = [];
this._basis.lineStart();
},
lineEnd: function lineEnd() {
var x = this._x,
y = this._y,
j = x.length - 1;
if (j > 0) {
var x0 = x[0],
y0 = y[0],
dx = x[j] - x0,
dy = y[j] - y0,
i = -1,
t;
while (++i <= j) {
t = i / j;
this._basis.point(this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), this._beta * y[i] + (1 - this._beta) * (y0 + t * dy));
}
}
this._x = this._y = null;
this._basis.lineEnd();
},
point: function point(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
/* harmony default export */ var bundle = ((function custom(beta) {
function bundle(context) {
return beta === 1 ? new Basis(context) : new Bundle(context, beta);
}
bundle.beta = function (beta) {
return custom(+beta);
};
return bundle;
})(.85));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/cardinal.js
function cardinal_point(that, x, y) {
that._context.bezierCurveTo(that._x1 + that._k * (that._x2 - that._x0), that._y1 + that._k * (that._y2 - that._y0), that._x2 + that._k * (that._x1 - x), that._y2 + that._k * (that._y1 - y), that._x2, that._y2);
}
function Cardinal(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
Cardinal.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 2:
this._context.lineTo(this._x2, this._y2);
break;
case 3:
cardinal_point(this, this._x1, this._y1);
break;
}
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
break;
case 1:
this._point = 2;
this._x1 = x, this._y1 = y;
break;
case 2:
this._point = 3;
// falls through
default:
cardinal_point(this, x, y);
break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
/* harmony default export */ var cardinal = ((function custom(tension) {
function cardinal(context) {
return new Cardinal(context, tension);
}
cardinal.tension = function (tension) {
return custom(+tension);
};
return cardinal;
})(0));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/cardinalClosed.js
function CardinalClosed(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
CardinalClosed.prototype = {
areaStart: src_noop,
areaEnd: src_noop,
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 1:
{
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2:
{
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3:
{
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._x3 = x, this._y3 = y;
break;
case 1:
this._point = 2;
this._context.moveTo(this._x4 = x, this._y4 = y);
break;
case 2:
this._point = 3;
this._x5 = x, this._y5 = y;
break;
default:
cardinal_point(this, x, y);
break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
/* harmony default export */ var cardinalClosed = ((function custom(tension) {
function cardinal(context) {
return new CardinalClosed(context, tension);
}
cardinal.tension = function (tension) {
return custom(+tension);
};
return cardinal;
})(0));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/cardinalOpen.js
function CardinalOpen(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
CardinalOpen.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
if (this._line || this._line !== 0 && this._point === 3) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3;
this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2);
break;
case 3:
this._point = 4;
// falls through
default:
cardinal_point(this, x, y);
break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
/* harmony default export */ var cardinalOpen = ((function custom(tension) {
function cardinal(context) {
return new CardinalOpen(context, tension);
}
cardinal.tension = function (tension) {
return custom(+tension);
};
return cardinal;
})(0));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/math.js
const math_abs = Math.abs;
const atan2 = Math.atan2;
const cos = Math.cos;
const math_max = Math.max;
const math_min = Math.min;
const sin = Math.sin;
const sqrt = Math.sqrt;
const epsilon = 1e-12;
const pi = Math.PI;
const halfPi = pi / 2;
const tau = 2 * pi;
function acos(x) {
return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
}
function asin(x) {
return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/catmullRom.js
function catmullRom_point(that, x, y) {
var x1 = that._x1,
y1 = that._y1,
x2 = that._x2,
y2 = that._y2;
if (that._l01_a > epsilon) {
var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
n = 3 * that._l01_a * (that._l01_a + that._l12_a);
x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
}
if (that._l23_a > epsilon) {
var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
m = 3 * that._l23_a * (that._l23_a + that._l12_a);
x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
}
that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
}
function CatmullRom(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRom.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 2:
this._context.lineTo(this._x2, this._y2);
break;
case 3:
this.point(this._x2, this._y2);
break;
}
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3;
// falls through
default:
catmullRom_point(this, x, y);
break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
/* harmony default export */ var catmullRom = ((function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
}
catmullRom.alpha = function (alpha) {
return custom(+alpha);
};
return catmullRom;
})(.5));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/catmullRomClosed.js
function CatmullRomClosed(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomClosed.prototype = {
areaStart: src_noop,
areaEnd: src_noop,
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 1:
{
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2:
{
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3:
{
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function point(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0:
this._point = 1;
this._x3 = x, this._y3 = y;
break;
case 1:
this._point = 2;
this._context.moveTo(this._x4 = x, this._y4 = y);
break;
case 2:
this._point = 3;
this._x5 = x, this._y5 = y;
break;
default:
catmullRom_point(this, x, y);
break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
/* harmony default export */ var catmullRomClosed = ((function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
}
catmullRom.alpha = function (alpha) {
return custom(+alpha);
};
return catmullRom;
})(.5));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/catmullRomOpen.js
function CatmullRomOpen(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomOpen.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0;
},
lineEnd: function lineEnd() {
if (this._line || this._line !== 0 && this._point === 3) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0:
this._point = 1;
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3;
this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2);
break;
case 3:
this._point = 4;
// falls through
default:
catmullRom_point(this, x, y);
break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
/* harmony default export */ var catmullRomOpen = ((function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
}
catmullRom.alpha = function (alpha) {
return custom(+alpha);
};
return catmullRom;
})(.5));
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/monotone.js
function sign(x) {
return x < 0 ? -1 : 1;
}
// Calculate the slopes of the tangents (Hermite-type interpolation) based on
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
// NOV(II), P. 443, 1990.
function slope3(that, x2, y2) {
var h0 = that._x1 - that._x0,
h1 = x2 - that._x1,
s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0);
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), .5 * Math.abs((s0 * h1 + s1 * h0) / (h0 + h1))) || 0;
}
// Calculate a one-sided slope.
function slope2(that, t) {
var h = that._x1 - that._x0;
return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
}
// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
function monotone_point(that, t0, t1) {
var x0 = that._x0,
y0 = that._y0,
x1 = that._x1,
y1 = that._y1,
dx = (x1 - x0) / 3;
that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
}
function MonotoneX(context) {
this._context = context;
}
MonotoneX.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x0 = this._x1 = this._y0 = this._y1 = this._t0 = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
switch (this._point) {
case 2:
this._context.lineTo(this._x1, this._y1);
break;
case 3:
monotone_point(this, this._t0, slope2(this, this._t0));
break;
}
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
var t1 = NaN;
x = +x, y = +y;
if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3;
monotone_point(this, slope2(this, t1 = slope3(this, x, y)), t1);
break;
default:
monotone_point(this, this._t0, t1 = slope3(this, x, y));
break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
this._t0 = t1;
}
};
function MonotoneY(context) {
this._context = new ReflectContext(context);
}
(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function (x, y) {
MonotoneX.prototype.point.call(this, y, x);
};
function ReflectContext(context) {
this._context = context;
}
ReflectContext.prototype = {
moveTo: function moveTo(x, y) {
this._context.moveTo(y, x);
},
closePath: function closePath() {
this._context.closePath();
},
lineTo: function lineTo(x, y) {
this._context.lineTo(y, x);
},
bezierCurveTo: function bezierCurveTo(x1, y1, x2, y2, x, y) {
this._context.bezierCurveTo(y1, x1, y2, x2, y, x);
}
};
function monotoneX(context) {
return new MonotoneX(context);
}
function monotoneY(context) {
return new MonotoneY(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/natural.js
function Natural(context) {
this._context = context;
}
Natural.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x = [];
this._y = [];
},
lineEnd: function lineEnd() {
var x = this._x,
y = this._y,
n = x.length;
if (n) {
this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
if (n === 2) {
this._context.lineTo(x[1], y[1]);
} else {
for (var px = controlPoints(x), py = controlPoints(y), i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
}
}
}
if (this._line || this._line !== 0 && n === 1) this._context.closePath();
this._line = 1 - this._line;
this._x = this._y = null;
},
point: function point(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
function controlPoints(x) {
var i,
n = x.length - 1,
m,
a = Array(n),
b = Array(n),
r = Array(n);
a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
a[n - 1] = r[n - 1] / b[n - 1];
for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
b[n - 1] = (x[n] + a[n - 1]) / 2;
for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
return [a, b];
}
/* harmony default export */ function natural(context) {
return new Natural(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/linearClosed.js
function LinearClosed(context) {
this._context = context;
}
LinearClosed.prototype = {
areaStart: src_noop,
areaEnd: src_noop,
lineStart: function lineStart() {
this._point = 0;
},
lineEnd: function lineEnd() {
if (this._point) this._context.closePath();
},
point: function point(x, y) {
x = +x, y = +y;
if (this._point) this._context.lineTo(x, y);else this._point = 1, this._context.moveTo(x, y);
}
};
/* harmony default export */ function linearClosed(context) {
return new LinearClosed(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/linear.js
function Linear(context) {
this._context = context;
}
Linear.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._point = 0;
},
lineEnd: function lineEnd() {
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
break;
case 1:
this._point = 2;
// falls through
default:
this._context.lineTo(x, y);
break;
}
}
};
/* harmony default export */ function curve_linear(context) {
return new Linear(context);
}
;// CONCATENATED MODULE: ./node_modules/d3-shape/src/curve/step.js
function Step(context, t) {
this._context = context;
this._t = t;
}
Step.prototype = {
areaStart: function areaStart() {
this._line = 0;
},
areaEnd: function areaEnd() {
this._line = NaN;
},
lineStart: function lineStart() {
this._x = this._y = NaN;
this._point = 0;
},
lineEnd: function lineEnd() {
if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
},
point: function point(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0:
this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
break;
case 1:
this._point = 2;
// falls through
default:
{
if (this._t <= 0) {
this._context.lineTo(this._x, y);
this._context.lineTo(x, y);
} else {
var x1 = this._x * (1 - this._t) + x * this._t;
this._context.lineTo(x1, this._y);
this._context.lineTo(x1, y);
}
break;
}
}
this._x = x, this._y = y;
}
};
/* harmony default export */ function step(context) {
return new Step(context, .5);
}
function stepBefore(context) {
return new Step(context, 0);
}
function stepAfter(context) {
return new Step(context, 1);
}
;// CONCATENATED MODULE: ./src/ChartInternal/shape/shape.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get grouped data point function for y coordinate
* - Note: Grouped(stacking) works only for line and bar types
* @param {object} d data vlaue
* @returns {Function|undefined}
* @private
*/
function getGroupedDataPointsFn(d) {
const $$ = this;
let fn;
if ($$.isLineType(d)) {
fn = $$.generateGetLinePoints($$.getShapeIndices($$.isLineType));
} else if ($$.isBarType(d)) {
fn = $$.generateGetBarPoints($$.getShapeIndices($$.isBarType));
}
return fn;
}
/* harmony default export */ var shape = ({
/**
* Get the shape draw function
* @returns {object}
* @private
*/
getDrawShape: function getDrawShape() {
var _this = this;
const $$ = this,
isRotated = $$.config.axis_rotated,
_$$$state = $$.state,
hasRadar = _$$$state.hasRadar,
hasTreemap = _$$$state.hasTreemap,
shape = {
type: {},
indices: {},
pos: {}
};
hasTreemap || ["bar", "candlestick", "line", "area"].forEach(function (v) {
_newArrowCheck(this, _this);
const name = capitalize(/^(bubble|scatter)$/.test(v) ? "line" : v);
if ($$.hasType(v) || $$.hasTypeOf(name) || v === "line" && ($$.hasType("bubble") || $$.hasType("scatter"))) {
const indices = $$.getShapeIndices($$["is" + name + "Type"]),
drawFn = $$["generateDraw" + name];
shape.indices[v] = indices;
shape.type[v] = drawFn ? drawFn.bind($$)(indices, !1) : undefined;
}
}.bind(this));
if (!$$.hasArcType() || hasRadar || hasTreemap) {
let cx, cy;
// generate circle x/y functions depending on updated params
if (!hasTreemap) {
cx = hasRadar ? $$.radarCircleX : isRotated ? $$.circleY : $$.circleX;
cy = hasRadar ? $$.radarCircleY : isRotated ? $$.circleX : $$.circleY;
}
shape.pos = {
xForText: $$.generateXYForText(shape.indices, !0),
yForText: $$.generateXYForText(shape.indices, !1),
cx: (cx || function () {}).bind($$),
cy: (cy || function () {}).bind($$)
};
}
return shape;
},
/**
* Get shape's indices according it's position within each axis tick.
*
* From the below example, indices will be:
* ==> {data1: 0, data2: 0, data3: 1, data4: 1, __max__: 1}
*
* data1 data3 data1 data3
* data2 data4 data2 data4
* -------------------------
* 0 1
* @param {Function} typeFilter Chart type filter function
* @returns {object} Indices object with its position
*/
getShapeIndices: function getShapeIndices(typeFilter) {
var _this2 = this;
const $$ = this,
config = $$.config,
xs = config.data_xs,
hasXs = notEmpty(xs),
indices = {};
let i = hasXs ? {} : 0;
if (hasXs) {
getUnique(Object.keys(xs).map(function (v) {
_newArrowCheck(this, _this2);
return xs[v];
}.bind(this))).forEach(function (v) {
_newArrowCheck(this, _this2);
i[v] = 0;
indices[v] = {};
}.bind(this));
}
$$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
_newArrowCheck(this, _this2);
const xKey = d.id in xs ? xs[d.id] : "",
ind = xKey ? indices[xKey] : indices;
for (let j = 0, groups; groups = config.data_groups[j]; j++) {
if (groups.indexOf(d.id) < 0) {
continue;
}
for (let k = 0, key; key = groups[k]; k++) {
if (key in ind) {
ind[d.id] = ind[key];
break;
}
// for same grouped data, add other data to same indices
if (d.id !== key && xKey) {
var _ind$d$id;
ind[key] = (_ind$d$id = ind[d.id]) != null ? _ind$d$id : i[xKey];
}
}
}
if (isUndefined(ind[d.id])) {
ind[d.id] = xKey ? i[xKey]++ : i++;
ind.__max__ = (xKey ? i[xKey] : i) - 1;
}
}.bind(this));
return indices;
},
/**
* Get indices value based on data ID value
* @param {object} indices Indices object
* @param {object} d Data row
* @param {string} caller Caller function name (Used only for 'sparkline' plugin)
* @returns {object} Indices object
* @private
*/
getIndices: function getIndices(indices, d) {
var _this3 = this;
// eslint-disable-line
const $$ = this,
_$$$config = $$.config,
xs = _$$$config.data_xs,
removeNull = _$$$config.bar_indices_removeNull,
id = d.id,
index = d.index;
if ($$.isBarType(id) && removeNull) {
const ind = {};
// redefine bar indices order
$$.getAllValuesOnIndex(index, !0).forEach(function (v, i) {
_newArrowCheck(this, _this3);
ind[v.id] = i;
ind.__max__ = i;
}.bind(this));
return ind;
}
return notEmpty(xs) ? indices[xs[id]] : indices;
},
/**
* Get indices max number
* @param {object} indices Indices object
* @returns {number} Max number
* @private
*/
getIndicesMax: function getIndicesMax(indices) {
var _this4 = this;
return notEmpty(this.config.data_xs) ?
// if is multiple xs, return total sum of xs' __max__ value
Object.keys(indices).map(function (v) {
_newArrowCheck(this, _this4);
return indices[v].__max__ || 0;
}.bind(this)).reduce(function (acc, curr) {
_newArrowCheck(this, _this4);
return acc + curr;
}.bind(this)) : indices.__max__;
},
getShapeX: function getShapeX(offset, indices, isSub) {
var _this5 = this;
const $$ = this,
config = $$.config,
scale = $$.scale,
currScale = isSub ? scale.subX : scale.zoom || scale.x,
barOverlap = config.bar_overlap,
barPadding = config.bar_padding,
sum = function (p, c) {
_newArrowCheck(this, _this5);
return p + c;
}.bind(this),
halfWidth = isObjectType(offset) && (offset._$total.length ? offset._$total.reduce(sum) / 2 : 0);
// total shapes half width
return function (d) {
_newArrowCheck(this, _this5);
const ind = $$.getIndices(indices, d, "getShapeX"),
index = d.id in ind ? ind[d.id] : 0,
targetsNum = (ind.__max__ || 0) + 1;
let x = 0;
if (notEmpty(d.x)) {
const xPos = currScale(d.x, !0);
if (halfWidth) {
const offsetWidth = offset[d.id] || offset._$width;
x = barOverlap ? xPos - offsetWidth / 2 : xPos - offsetWidth + offset._$total.slice(0, index + 1).reduce(sum) - halfWidth;
} else {
x = xPos - (isNumber(offset) ? offset : offset._$width) * (targetsNum / 2 - (barOverlap ? 1 : index));
}
}
// adjust x position for bar.padding option
if (offset && x && targetsNum > 1 && barPadding) {
if (index) {
x += barPadding * index;
}
if (targetsNum > 2) {
x -= (targetsNum - 1) * barPadding / 2;
} else if (targetsNum === 2) {
x -= barPadding / 2;
}
}
return x;
}.bind(this);
},
getShapeY: function getShapeY(isSub) {
var _this6 = this;
const $$ = this,
isStackNormalized = $$.isStackNormalized();
return function (d) {
_newArrowCheck(this, _this6);
let value = d.value;
if (isNumber(d)) {
value = d;
} else if ($$.isAreaRangeType(d)) {
value = $$.getBaseValue(d, "mid");
} else if (isStackNormalized) {
value = $$.getRatio("index", d, !0);
} else if ($$.isBubbleZType(d)) {
value = $$.getBubbleZData(d.value, "y");
} else if ($$.isBarRangeType(d)) {
// TODO use range.getEnd() like method
value = value[1];
}
return $$.getYScaleById(d.id, isSub)(value);
}.bind(this);
},
/**
* Get shape based y Axis min value
* @param {string} id Data id
* @returns {number}
* @private
*/
getShapeYMin: function getShapeYMin(id) {
const $$ = this,
axisId = $$.axis.getId(id),
scale = $$.scale[axisId],
_scale$domain = scale.domain(),
yMin = _scale$domain[0],
inverted = $$.config["axis_" + axisId + "_inverted"];
return !$$.isGrouped(id) && !inverted && yMin > 0 ? yMin : 0;
},
/**
* Get Shape's offset data
* @param {Function} typeFilter Type filter function
* @returns {object}
* @private
*/
getShapeOffsetData: function getShapeOffsetData(typeFilter) {
var _this7 = this;
const $$ = this,
targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
isStackNormalized = $$.isStackNormalized(),
shapeOffsetTargets = targets.map(function (target) {
var _this8 = this;
_newArrowCheck(this, _this7);
let rowValues = target.values;
const values = {};
if ($$.isStepType(target)) {
rowValues = $$.convertValuesToStep(rowValues);
}
const rowValueMapByXValue = rowValues.reduce(function (out, d) {
_newArrowCheck(this, _this8);
const key = +d.x;
out[key] = d;
values[key] = isStackNormalized ? $$.getRatio("index", d, !0) : d.value;
return out;
}.bind(this), {});
return {
id: target.id,
rowValues: rowValues,
rowValueMapByXValue: rowValueMapByXValue,
values: values
};
}.bind(this)),
indexMapByTargetId = targets.reduce(function (out, _ref, index) {
let id = _ref.id;
_newArrowCheck(this, _this7);
out[id] = index;
return out;
}.bind(this), {});
return {
indexMapByTargetId: indexMapByTargetId,
shapeOffsetTargets: shapeOffsetTargets
};
},
getShapeOffset: function getShapeOffset(typeFilter, indices, isSub) {
var _this9 = this;
const $$ = this,
_$$$getShapeOffsetDat = $$.getShapeOffsetData(typeFilter),
shapeOffsetTargets = _$$$getShapeOffsetDat.shapeOffsetTargets,
indexMapByTargetId = _$$$getShapeOffsetDat.indexMapByTargetId,
groupsZeroAs = $$.config.data_groupsZeroAs;
return function (d, idx) {
var _this10 = this;
_newArrowCheck(this, _this9);
const id = d.id,
value = d.value,
x = d.x,
ind = $$.getIndices(indices, d),
scale = $$.getYScaleById(id, isSub);
if ($$.isBarRangeType(d)) {
// TODO use range.getStart()
return scale(value[0]);
}
const dataXAsNumber = +x,
y0 = scale(groupsZeroAs === "zero" ? 0 : $$.getShapeYMin(id));
let offset = y0;
shapeOffsetTargets.filter(function (t) {
_newArrowCheck(this, _this10);
return t.id !== id && ind[t.id] === ind[id];
}.bind(this)).forEach(function (t) {
_newArrowCheck(this, _this10);
const tid = t.id,
rowValueMapByXValue = t.rowValueMapByXValue,
rowValues = t.rowValues,
tvalues = t.values;
// for same stacked group (ind[tid] === ind[id])
if (indexMapByTargetId[tid] < indexMapByTargetId[id]) {
var _row;
const rValue = tvalues[dataXAsNumber];
let row = rowValues[idx];
// check if the x values line up
if (!row || +row.x !== dataXAsNumber) {
row = rowValueMapByXValue[dataXAsNumber];
}
if (((_row = row) == null ? void 0 : _row.value) * value >= 0 && isNumber(rValue)) {
const addOffset = value === 0 ? groupsZeroAs === "positive" && rValue > 0 || groupsZeroAs === "negative" && rValue < 0 : !0;
if (addOffset) {
offset += scale(rValue) - y0;
}
}
}
}.bind(this));
return offset;
}.bind(this);
},
/**
* Get data's y coordinate
* @param {object} d Target data
* @param {number} i Index number
* @returns {number} y coordinate
* @private
*/
circleY: function circleY(d, i) {
const $$ = this,
id = d.id;
let points;
if ($$.isGrouped(id)) {
points = getGroupedDataPointsFn.bind($$)(d);
}
return points ? points(d, i)[0][1] : $$.getYScaleById(id)($$.getBaseValue(d));
},
getBarW: function getBarW(type, axis, targetsNum) {
var _config$data_groups,
_$$$getZoomTransform,
_config$axis_x_min,
_config$axis_x_max,
_this11 = this;
const $$ = this,
config = $$.config,
org = $$.org,
scale = $$.scale,
maxDataCount = $$.getMaxDataCount(),
isGrouped = type === "bar" && ((_config$data_groups = config.data_groups) == null ? void 0 : _config$data_groups.length),
configName = type + "_width",
_ref2 = (_$$$getZoomTransform = $$.getZoomTransform == null ? void 0 : $$.getZoomTransform()) != null ? _$$$getZoomTransform : {
k: 1
},
k = _ref2.k,
xMinMax = [(_config$axis_x_min = config.axis_x_min) != null ? _config$axis_x_min : org.xDomain[0], (_config$axis_x_max = config.axis_x_max) != null ? _config$axis_x_max : org.xDomain[1]].map($$.axis.isTimeSeries() ? parseDate.bind($$) : Number);
let tickInterval = axis.tickInterval(maxDataCount);
if (scale.zoom && !$$.axis.isCategorized() && k > 1) {
const isSameMinMax = xMinMax.every(function (v, i) {
_newArrowCheck(this, _this11);
return v === org.xDomain[i];
}.bind(this));
tickInterval = org.xDomain.map(function (v, i) {
_newArrowCheck(this, _this11);
const value = isSameMinMax ? v : v - Math.abs(xMinMax[i]);
return scale.zoom(value);
}.bind(this)).reduce(function (a, c) {
_newArrowCheck(this, _this11);
return Math.abs(a) + c;
}.bind(this)) / maxDataCount;
}
const getWidth = function (id) {
_newArrowCheck(this, _this11);
const width = id ? config[configName][id] : config[configName],
ratio = id ? width.ratio : config[configName + "_ratio"],
max = id ? width.max : config[configName + "_max"],
w = isNumber(width) ? width : targetsNum ? tickInterval * ratio / targetsNum : 0;
return max && w > max ? max : w;
}.bind(this);
let result = getWidth();
if (!isGrouped && isObjectType(config[configName])) {
result = {
_$width: result,
_$total: []
};
$$.filterTargetsToShow($$.data.targets).forEach(function (v) {
_newArrowCheck(this, _this11);
if (config[configName][v.id]) {
result[v.id] = getWidth(v.id);
result._$total.push(result[v.id] || result._$width);
}
}.bind(this));
}
return result;
},
/**
* Get shape element
* @param {string} shapeName Shape string
* @param {number} i Index number
* @param {string} id Data series id
* @returns {d3Selection}
* @private
*/
getShapeByIndex: function getShapeByIndex(shapeName, i, id) {
var _this12 = this;
const $$ = this,
$el = $$.$el,
suffix = isValue(i) ? "-" + i : "";
let shape = $el[shapeName];
// filter from shape reference if has
if (shape && !shape.empty()) {
shape = shape.filter(function (d) {
_newArrowCheck(this, _this12);
return id ? d.id === id : !0;
}.bind(this)).filter(function (d) {
_newArrowCheck(this, _this12);
return isValue(i) ? d.index === i : !0;
}.bind(this));
} else {
shape = (id ? $el.main.selectAll("." + classes[shapeName + "s"] + $$.getTargetSelectorSuffix(id)) : $el.main).selectAll("." + classes[shapeName] + suffix);
}
return shape;
},
isWithinShape: function isWithinShape(that, d) {
const $$ = this,
shape = src_select(that);
let isWithin;
if (!$$.isTargetToShow(d.id)) {
isWithin = !1;
} else if ($$.hasValidPointType != null && $$.hasValidPointType(that.nodeName)) {
isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScaleById(d.id)(d.value)) : $$.isWithinCircle(that, $$.isBubbleType(d) ? $$.pointSelectR(d) * 1.5 : 0);
} else if (that.nodeName === "path") {
isWithin = shape.classed(classes.bar) ? $$.isWithinBar(that) : !0;
}
return isWithin;
},
getInterpolate: function getInterpolate(d) {
const $$ = this,
interpolation = $$.getInterpolateType(d);
return {
"basis": curve_basis,
"basis-closed": curve_basisClosed,
"basis-open": basisOpen,
"bundle": bundle,
"cardinal": cardinal,
"cardinal-closed": cardinalClosed,
"cardinal-open": cardinalOpen,
"catmull-rom": catmullRom,
"catmull-rom-closed": catmullRomClosed,
"catmull-rom-open": catmullRomOpen,
"monotone-x": monotoneX,
"monotone-y": monotoneY,
"natural": natural,
"linear-closed": linearClosed,
"linear": curve_linear,
"step": step,
"step-after": stepAfter,
"step-before": stepBefore
}[interpolation];
},
getInterpolateType: function getInterpolateType(d) {
const $$ = this,
config = $$.config,
type = config.spline_interpolation_type,
interpolation = $$.isInterpolationType(type) ? type : "cardinal";
return $$.isSplineType(d) ? interpolation : $$.isStepType(d) ? config.line_step_type : "linear";
},
isWithinBar: function isWithinBar(that) {
const mouse = getPointer(this.state.event, that),
list = getRectSegList(that),
_list = list,
seg0 = _list[0],
seg1 = _list[1],
x = Math.min(seg0.x, seg1.x),
y = Math.min(seg0.y, seg1.y),
offset = this.config.bar_sensitivity,
_that$getBBox = that.getBBox(),
width = _that$getBBox.width,
height = _that$getBBox.height,
isWithin = x - offset < mouse[0] && mouse[0] < x + width + offset && y - offset < mouse[1] && mouse[1] < y + height + offset;
return isWithin;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/size.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var internals_size = ({
/**
* Update container size
* @private
*/
setContainerSize: function setContainerSize() {
const $$ = this,
state = $$.state;
state.current.width = $$.getCurrentWidth();
state.current.height = $$.getCurrentHeight();
},
getCurrentWidth: function getCurrentWidth() {
const $$ = this;
return $$.config.size_width || $$.getParentWidth();
},
getCurrentHeight: function getCurrentHeight() {
const $$ = this,
config = $$.config,
h = config.size_height || $$.getParentHeight();
return h > 0 ? h : 320 / ($$.hasType("gauge") && !config.gauge_fullCircle ? 2 : 1);
},
/**
* Get the parent rect element's size
* @param {string} key property/attribute name
* @returns {number}
* @private
*/
getParentRectValue: function getParentRectValue(key) {
const offsetName = "offset" + capitalize(key);
let parent = this.$el.chart.node(),
v = 0;
while (v < 30 && parent && parent.tagName !== "BODY") {
try {
v = parent.getBoundingClientRect()[key];
} catch (e) {
if (offsetName in parent) {
// In IE in certain cases getBoundingClientRect
// will cause an "unspecified error"
v = parent[offsetName];
}
}
parent = parent.parentNode;
}
// Sometimes element's dimension value is incorrect(ex. flex container)
// In this case, use body's offset instead.
const bodySize = browser_doc.body[offsetName];
v > bodySize && (v = bodySize);
return v;
},
getParentWidth: function getParentWidth() {
return this.getParentRectValue("width");
},
getParentHeight: function getParentHeight() {
const h = this.$el.chart.style("height");
let height = 0;
if (h) {
height = /px$/.test(h) ? parseInt(h, 10) : this.getParentRectValue("height");
}
return height;
},
getSvgLeft: function getSvgLeft(withoutRecompute) {
const $$ = this,
config = $$.config,
hasAxis = $$.state.hasAxis,
$el = $$.$el,
isRotated = config.axis_rotated,
hasLeftAxisRect = isRotated || !isRotated && !config.axis_y_inner,
leftAxisClass = isRotated ? $AXIS.axisX : $AXIS.axisY,
leftAxis = $el.main.select("." + leftAxisClass).node(),
leftLabel = hasAxis && config["axis_" + (isRotated ? "x" : "y") + "_label"];
let labelWidth = 0;
// if axis label position set to inner, exclude from the value
if (hasAxis && (isString(leftLabel) || isString(leftLabel.text) || /^inner-/.test(leftLabel == null ? void 0 : leftLabel.position))) {
const label = $el.main.select("." + leftAxisClass + "-label");
if (!label.empty()) {
labelWidth = label.node().getBoundingClientRect().left;
}
}
const svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {
right: 0
},
chartRectLeft = $el.chart.node().getBoundingClientRect().left + labelWidth,
hasArc = $$.hasArcType(),
svgLeft = svgRect.right - chartRectLeft - (hasArc ? 0 : $$.getCurrentPaddingByDirection("left", withoutRecompute));
return svgLeft > 0 ? svgLeft : 0;
},
updateDimension: function updateDimension(withoutAxis) {
const $$ = this,
config = $$.config,
hasAxis = $$.state.hasAxis,
$el = $$.$el;
if (hasAxis && !withoutAxis && $$.axis.x && config.axis_rotated) {
var _$$$axis$subX;
(_$$$axis$subX = $$.axis.subX) == null || _$$$axis$subX.create($el.axis.subX);
}
// pass 'withoutAxis' param to not animate at the init rendering
$$.updateScales(withoutAxis);
$$.updateSvgSize();
$$.transformAll(!1);
},
updateSvgSize: function updateSvgSize() {
const $$ = this,
_$$$state = $$.state,
clip = _$$$state.clip,
current = _$$$state.current,
hasAxis = _$$$state.hasAxis,
width = _$$$state.width,
height = _$$$state.height,
svg = $$.$el.svg;
svg.attr("width", current.width).attr("height", current.height);
if (hasAxis) {
const brush = svg.select("." + $SUBCHART.brush + " .overlay"),
brushSize = {
width: 0,
height: 0
};
if (brush.size()) {
brushSize.width = +brush.attr("width");
brushSize.height = +brush.attr("height");
}
svg.selectAll(["#" + clip.id, "#" + clip.idGrid]).select("rect").attr("width", width).attr("height", height);
svg.select("#" + clip.idXAxis).select("rect").call($$.setXAxisClipPath.bind($$));
svg.select("#" + clip.idYAxis).select("rect").call($$.setYAxisClipPath.bind($$));
clip.idSubchart && svg.select("#" + clip.idSubchart).select("rect").attr("width", width).attr("height", brushSize.height);
}
},
/**
* Get padding by the direction.
* @param {string} type "top" | "bottom" | "left" | "right"
* @param {boolean} [withoutRecompute=false] If set true, do not recompute the padding value.
* @param {boolean} [withXAxisTickTextOverflow=false] If set true, calculate x axis tick text overflow.
* @returns {number} padding value
* @private
*/
getCurrentPaddingByDirection: function getCurrentPaddingByDirection(type, withoutRecompute, withXAxisTickTextOverflow) {
var _config$padding;
if (withoutRecompute === void 0) {
withoutRecompute = !1;
}
if (withXAxisTickTextOverflow === void 0) {
withXAxisTickTextOverflow = !1;
}
const $$ = this,
config = $$.config,
$el = $$.$el,
hasAxis = $$.state.hasAxis,
isRotated = config.axis_rotated,
isFitPadding = ((_config$padding = config.padding) == null ? void 0 : _config$padding.mode) === "fit",
paddingOption = isNumber(config["padding_" + type]) ? config["padding_" + type] : undefined,
axisId = hasAxis ? {
top: isRotated ? "y2" : null,
bottom: isRotated ? "y" : "x",
left: isRotated ? "x" : "y",
right: isRotated ? null : "y2"
}[type] : null,
isLeftRight = /^(left|right)$/.test(type),
isAxisInner = axisId && config["axis_" + axisId + "_inner"],
isAxisShow = axisId && config["axis_" + axisId + "_show"],
axesLen = axisId ? config["axis_" + axisId + "_axes"].length : 0;
let axisSize = axisId ? isLeftRight ? $$.getAxisWidthByAxisId(axisId, withoutRecompute) : $$.getHorizontalAxisHeight(axisId) : 0;
const defaultPadding = 20;
let gap = 0;
if (!isFitPadding && isLeftRight) {
axisSize = ceil10(axisSize);
}
let padding = hasAxis && isLeftRight && (isAxisInner || isUndefined(paddingOption) && !isAxisShow) ? 0 : isFitPadding ? (isAxisShow ? axisSize : 0) + (paddingOption != null ? paddingOption : 0) : isUndefined(paddingOption) ? axisSize : paddingOption;
if (isLeftRight && hasAxis) {
if (axisId && (isFitPadding || isAxisInner) && config["axis_" + axisId + "_label"].text) {
padding += $$.axis.getAxisLabelPosition(axisId).isOuter ? defaultPadding : 0;
}
if (type === "right") {
padding += isRotated ? !isFitPadding && isUndefined(paddingOption) ? 10 : 2 : !isAxisShow || isAxisInner ? isFitPadding ? 2 : 1 : 0;
padding += withXAxisTickTextOverflow ? $$.axis.getXAxisTickTextY2Overflow(defaultPadding) : 0;
} else if (type === "left" && isRotated && isUndefined(paddingOption)) {
padding = !config.axis_x_show ? 1 : isFitPadding ? axisSize : Math.max(axisSize, 40);
}
} else {
if (type === "top") {
if ($el.title && $el.title.node()) {
padding += $$.getTitlePadding();
}
gap = isRotated && !isAxisInner ? axesLen : 0;
} else if (type === "bottom" && hasAxis && isRotated && !isAxisShow) {
padding += 1;
}
}
return padding + axisSize * axesLen - gap;
},
getCurrentPadding: function getCurrentPadding(withXAxisTickTextOverflow) {
var _this = this;
if (withXAxisTickTextOverflow === void 0) {
withXAxisTickTextOverflow = !1;
}
const $$ = this,
_map = ["top", "bottom", "left", "right"].map(function (v) {
_newArrowCheck(this, _this);
return $$.getCurrentPaddingByDirection(v, null, withXAxisTickTextOverflow);
}.bind(this)),
top = _map[0],
bottom = _map[1],
left = _map[2],
right = _map[3];
return {
top: top,
bottom: bottom,
left: left,
right: right
};
},
/**
* Get resetted padding values when 'padding=false' option is set
* https://github.com/naver/billboard.js/issues/2367
* @param {number|object} v Padding values to be resetted
* @returns {number|object} Padding value
* @private
*/
getResettedPadding: function getResettedPadding(v) {
var _this2 = this;
const $$ = this,
config = $$.config,
isNum = isNumber(v);
let p = isNum ? 0 : {};
if (config.padding === !1) {
isNum || Object.keys(v).forEach(function (key) {
_newArrowCheck(this, _this2);
// when data.lables=true, do not reset top padding
p[key] = !isEmpty(config.data_labels) && config.data_labels !== !1 && key === "top" ? v[key] : 0;
}.bind(this));
} else {
p = v;
}
return p;
},
/**
* Update size values
* @param {boolean} isInit If is called at initialization
* @private
*/
updateSizes: function updateSizes(isInit) {
var _config$padding2;
const $$ = this,
config = $$.config,
state = $$.state,
legend = $$.$el.legend,
isRotated = config.axis_rotated,
isNonAxis = $$.hasArcType() || state.hasTreemap,
isFitPadding = ((_config$padding2 = config.padding) == null ? void 0 : _config$padding2.mode) === "fit";
isInit || $$.setContainerSize();
const currLegend = {
width: legend ? $$.getLegendWidth() : 0,
height: legend ? $$.getLegendHeight() : 0
};
if (!isNonAxis && config.axis_x_show && config.axis_x_tick_autorotate) {
$$.updateXAxisTickClip();
}
const legendSize = {
right: config.legend_show && state.isLegendRight ? $$.getLegendWidth() + (isFitPadding ? 0 : 20) : 0,
bottom: !config.legend_show || state.isLegendRight || state.isLegendInset ? 0 : currLegend.height
},
xAxisHeight = isRotated || isNonAxis ? 0 : $$.getHorizontalAxisHeight("x"),
subchartXAxisHeight = config.subchart_axis_x_show && config.subchart_axis_x_tick_text_show ? xAxisHeight : 30,
subchartHeight = config.subchart_show && !isNonAxis ? config.subchart_size_height + subchartXAxisHeight : 0,
gaugeHeight = $$.hasType("gauge") && config.arc_needle_show && !config.gauge_fullCircle && !config.gauge_label_show ? 10 : 0,
padding = $$.getCurrentPadding(!0); // when needle is shown with legend, it need some bottom space to not overlap with legend text
// for main
state.margin = !isNonAxis && isRotated ? {
top: padding.top,
right: isNonAxis ? 0 : padding.right + legendSize.right,
bottom: legendSize.bottom + padding.bottom,
left: subchartHeight + (isNonAxis ? 0 : padding.left)
} : {
top: (isFitPadding ? 0 : 4) + padding.top,
// for top tick text
right: isNonAxis ? 0 : padding.right + legendSize.right,
bottom: gaugeHeight + subchartHeight + legendSize.bottom + padding.bottom,
left: isNonAxis ? 0 : padding.left
};
state.margin = $$.getResettedPadding(state.margin);
// for subchart
state.margin2 = isRotated ? {
top: state.margin.top,
right: NaN,
bottom: 20 + legendSize.bottom,
left: $$.state.rotatedPadding.left
} : {
top: state.current.height - subchartHeight - legendSize.bottom,
right: NaN,
bottom: subchartXAxisHeight + legendSize.bottom,
left: state.margin.left
};
// for legend
state.margin3 = {
top: 0,
right: NaN,
bottom: 0,
left: 0
};
$$.updateSizeForLegend == null || $$.updateSizeForLegend(currLegend);
state.width = state.current.width - state.margin.left - state.margin.right;
state.height = state.current.height - state.margin.top - state.margin.bottom;
if (state.width < 0) {
state.width = 0;
}
if (state.height < 0) {
state.height = 0;
}
state.width2 = isRotated ? state.margin.left - state.rotatedPadding.left - state.rotatedPadding.right : state.width;
state.height2 = isRotated ? state.height : state.current.height - state.margin2.top - state.margin2.bottom;
if (state.width2 < 0) {
state.width2 = 0;
}
if (state.height2 < 0) {
state.height2 = 0;
}
// for arc
if ($$.hasArcType()) {
var _ref, _config$arc_rangeText;
const hasGauge = $$.hasType("gauge"),
isLegendRight = config.legend_show && state.isLegendRight,
textWidth = (_ref = state.hasRadar && $$.cache.get(KEY.radarTextWidth)) != null ? _ref : 0;
state.arcWidth = state.width - (isLegendRight ? currLegend.width + 10 : 0) - textWidth;
state.arcHeight = state.height - (isLegendRight && !hasGauge ? 0 : 10);
if ((_config$arc_rangeText = config.arc_rangeText_values) != null && _config$arc_rangeText.length) {
if (hasGauge) {
state.arcWidth -= 25;
state.arcHeight -= 10;
state.margin.left += 10;
} else {
state.arcHeight -= 20;
state.margin.top += 10;
}
}
if (hasGauge && !config.gauge_fullCircle) {
state.arcHeight += state.height - $$.getPaddingBottomForGauge();
}
$$.updateRadius == null || $$.updateRadius();
}
if (state.isLegendRight && isNonAxis) {
state.margin3.left = state.arcWidth / 2 + state.radiusExpanded * 1.1;
}
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/style.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var internals_style = ({
/**
* Add props color css rule to given selector
* @param {boolean} withShape Set shpes' prefix class
* @param {string} selector CSS selector
* @param {Array} props CSS props list
* @param {Function} propsFn Function to retrieve value or determine for props
* @returns {Function}
* @private
*/
setCssRule: function setCssRule(withShape, selector, props, propsFn) {
var _this = this;
const $$ = this,
config = $$.config,
_$$$state = $$.state,
cssRule = _$$$state.cssRule,
style = _$$$state.style;
return config.boost_useCssRule ? function (selection) {
var _this2 = this;
_newArrowCheck(this, _this);
selection.each(function (d) {
var _this3 = this;
_newArrowCheck(this, _this2);
const res = propsFn && (propsFn == null ? void 0 : propsFn.call($$, d)),
shapeSelector = "" + (withShape ? "." + ($SHAPE.shapes + $$.getTargetSelectorSuffix(d.id)) : "") + selector;
selector in cssRule && style.sheet.deleteRule(cssRule[shapeSelector]);
$$.state.cssRule[shapeSelector] = addCssRules(style, shapeSelector, props.filter(Boolean).map(function (v) {
_newArrowCheck(this, _this3);
return isString(res) && v.indexOf(":") === -1 ? v + ": " + res : v || "";
}.bind(this)));
}.bind(this));
}.bind(this) : function () {
_newArrowCheck(this, _this);
}.bind(this);
},
/**
* Get style prop value
* @param {Function|string} v Value
* @returns {string|null}
* @private
*/
getStylePropValue: function getStylePropValue(v) {
const useCssRule = this.config.boost_useCssRule;
return useCssRule ? null : isFunction(v) ? v.bind(this) : v;
}
});
;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selectAll.js
/* harmony default export */ function src_selectAll(selector) {
return typeof selector === "string" ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) : new Selection([array(selector)], root);
}
;// CONCATENATED MODULE: ./src/ChartInternal/internals/text.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get text-anchor according text.labels.rotate angle
* @param {number} angle Angle value
* @returns {string} Anchor string value
* @private
*/
function getRotateAnchor(angle) {
let anchor = "middle";
if (angle > 0 && angle <= 170) {
anchor = "end";
} else if (angle > 190 && angle <= 360) {
anchor = "start";
}
return anchor;
}
/**
* Set rotated position coordinate according text.labels.rotate angle
* @param {object} d Data object
* @param {object} pos Position object
* @param {object} pos.x x coordinate
* @param {object} pos.y y coordinate
* @param {string} anchor string value
* @param {boolean} isRotated If axis is rotated
* @param {boolean} isInverted If axis is inverted
* @returns {object} x, y coordinate
* @private
*/
function setRotatePos(d, pos, anchor, isRotated, isInverted) {
var _$$$getCandlestickDat;
const $$ = this,
value = d.value,
isCandlestickType = $$.isCandlestickType(d),
isNegative = isNumber(value) && value < 0 || isCandlestickType && !((_$$$getCandlestickDat = $$.getCandlestickData(d)) != null && _$$$getCandlestickDat._isUp);
let x = pos.x,
y = pos.y;
const gap = 4,
doubleGap = 8;
if (isRotated) {
if (anchor === "start") {
x += isNegative ? 0 : doubleGap;
y += gap;
} else if (anchor === "middle") {
x += doubleGap;
y -= doubleGap;
} else if (anchor === "end") {
isNegative && (x -= doubleGap);
y += gap;
}
} else {
if (anchor === "start") {
x += gap;
isNegative && (y += doubleGap * 2);
} else if (anchor === "middle") {
y -= doubleGap;
} else if (anchor === "end") {
x -= gap;
isNegative && (y += doubleGap * 2);
}
if (isInverted) {
y += isNegative ? -17 : isCandlestickType ? 13 : 7;
}
}
return {
x: x,
y: y
};
}
/**
* Get data.labels.position value
* @param {object} d Data object
* @param {string} type x | y
* @returns {number} Position value
* @private
*/
function getTextPos(d, type) {
var _ref;
const position = this.config.data_labels_position,
id = d.id,
index = d.index,
value = d.value;
return (_ref = isFunction(position) ? position.bind(this.api)(type, value, id, index, this.$el.text) : (id in position ? position[id] : position)[type]) != null ? _ref : 0;
}
/* harmony default export */ var internals_text = ({
opacityForText: function opacityForText(d) {
const $$ = this;
return $$.isBarType(d) && !$$.meetsLabelThreshold(Math.abs($$.getRatio("bar", d)), "bar") ? "0" : $$.hasDataLabel ? null : "0";
},
/**
* Initializes the text
* @private
*/
initText: function initText() {
const $el = this.$el;
$el.main.select("." + $COMMON.chart).append("g").attr("class", $TEXT.chartTexts).style("pointer-events", $el.treemap ? "none" : null);
},
/**
* Update chartText
* @param {object} targets $$.data.targets
* @private
*/
updateTargetsForText: function updateTargetsForText(targets) {
var _this = this;
const $$ = this,
classChartText = $$.getChartClass("Text"),
classTexts = $$.getClass("texts", "id"),
classFocus = $$.classFocus.bind($$),
mainTextUpdate = $$.$el.main.select("." + $TEXT.chartTexts).selectAll("." + $TEXT.chartText).data(targets).attr("class", function (d) {
_newArrowCheck(this, _this);
return ("" + classChartText(d) + classFocus(d)).trim();
}.bind(this)),
mainTextEnter = mainTextUpdate.enter().append("g").style("opacity", "0").attr("class", classChartText).call($$.setCssRule(!0, " ." + $TEXT.text, ["fill", "pointer-events:none"], $$.updateTextColor));
mainTextEnter.append("g").attr("class", classTexts);
},
/**
* Update text
* @private
*/
updateText: function updateText() {
var _this2 = this;
const $$ = this,
$el = $$.$el,
$T = $$.$T,
config = $$.config,
axis = $$.axis,
classText = $$.getClass("text", "index"),
labelsCentered = config.data_labels.centered,
text = $el.main.selectAll("." + $TEXT.texts).selectAll("." + $TEXT.text).data($$.labelishData.bind($$));
$T(text.exit()).style("fill-opacity", "0").remove();
$el.text = text.enter().append("text").merge(text).attr("class", classText).attr("text-anchor", function (d) {
_newArrowCheck(this, _this2);
const isInverted = config["axis_" + (axis == null ? void 0 : axis.getId(d.id)) + "_inverted"];
// when value is negative or
let isEndAnchor = isInverted ? d.value > 0 : d.value < 0;
if ($$.isCandlestickType(d)) {
const data = $$.getCandlestickData(d);
isEndAnchor = !(data != null && data._isUp);
} else if ($$.isTreemapType(d)) {
return labelsCentered ? "middle" : "start";
}
return config.axis_rotated ? isEndAnchor ? "end" : "start" : "middle";
}.bind(this)).style("fill", $$.getStylePropValue($$.updateTextColor)).style("fill-opacity", "0").each(function (d, i, texts) {
const node = src_select(this);
let value = d.value;
if ($$.isBubbleZType(d)) {
value = $$.getBubbleZData(value, "z");
} else if ($$.isCandlestickType(d)) {
const data = $$.getCandlestickData(d);
if (data) {
value = data.close;
}
}
value = $$.isTreemapType(d) ? $$.treemapDataLabelFormat(d)(node) : $$.dataLabelFormat(d.id)(value, d.id, d.index, texts);
if (isNumber(value)) {
this.textContent = value;
} else {
setTextValue(node, value);
}
});
},
updateTextColor: function updateTextColor(d) {
const $$ = this,
config = $$.config,
labelColors = config.data_labels_colors,
defaultColor = $$.isArcType(d) && !$$.isRadarType(d) || $$.isTreemapType(d) ? null : $$.color(d);
let color;
if (isString(labelColors)) {
color = labelColors;
} else if (isObject(labelColors)) {
const _ref2 = d.data || d,
id = _ref2.id;
color = labelColors[id];
} else if (isFunction(labelColors)) {
color = labelColors.bind($$.api)(defaultColor, d);
}
if ($$.isCandlestickType(d) && !isFunction(labelColors)) {
const value = $$.getCandlestickData(d);
if (!(value != null && value._isUp)) {
const downColor = config.candlestick_color_down;
color = isObject(downColor) ? downColor[d.id] : downColor;
}
}
return color || defaultColor;
},
/**
* Update data label text background color
* @param {object} d Data object
* @returns {string|null}
* @private
*/
updateTextBackgroundColor: function updateTextBackgroundColor(d) {
const $$ = this,
$el = $$.$el,
config = $$.config,
backgroundColor = config.data_labels_backgroundColors;
let color = "";
if (isString(backgroundColor) || isObject(backgroundColor)) {
const id = isString(backgroundColor) ? "" : $$.getTargetSelectorSuffix("id" in d ? d.id : d.data.id),
filter = $el.defs.select(["filter[id*='labels-bg", "']"].join(id));
if (filter.size()) {
color = "url(#" + filter.attr("id") + ")";
}
}
return color || null;
},
/**
* Redraw chartText
* @param {Function} getX Positioning function for x
* @param {Function} getY Positioning function for y
* @param {boolean} forFlow Weather is flow
* @param {boolean} withTransition transition is enabled
* @returns {Array}
* @private
*/
redrawText: function redrawText(getX, getY, forFlow, withTransition) {
const $$ = this,
$T = $$.$T,
axis = $$.axis,
config = $$.config,
hasTreemap = $$.state.hasTreemap,
t = getRandom(!0),
isRotated = config.axis_rotated,
angle = config.data_labels.rotate,
anchorString = getRotateAnchor(angle),
rotateString = angle ? "rotate(" + angle + ")" : "";
$$.$el.text.style("fill", $$.getStylePropValue($$.updateTextColor)).attr("filter", $$.updateTextBackgroundColor.bind($$)).style("fill-opacity", forFlow ? 0 : $$.opacityForText.bind($$)).each(function (d, i) {
// do not apply transition for newly added text elements
const node = $T(hasTreemap && this.childElementCount ? this.parentNode : this, !!(withTransition && this.getAttribute("x")), t),
isInverted = config["axis_" + (axis == null ? void 0 : axis.getId(d.id)) + "_inverted"];
let pos = {
x: getX.bind(this)(d, i),
y: getY.bind(this)(d, i)
};
if (angle) {
pos = setRotatePos.bind($$)(d, pos, anchorString, isRotated, isInverted);
node.attr("text-anchor", anchorString);
}
// when is multiline
if (this.childElementCount || angle) {
node.attr("transform", "translate(" + pos.x + " " + pos.y + ") " + rotateString);
} else {
node.attr("x", pos.x).attr("y", pos.y);
}
});
// need to return 'true' as of being pushed to the redraw list
// ref: getRedrawList()
return !0;
},
/**
* Gets the getBoundingClientRect value of the element
* @param {HTMLElement|d3.selection} element Target element
* @param {string} className Class name
* @returns {object} value of element.getBoundingClientRect()
* @private
*/
getTextRect: function getTextRect(element, className) {
var _this3 = this;
const $$ = this;
let base = element.node ? element.node() : element;
if (!/text/i.test(base.tagName)) {
base = base.querySelector("text");
}
const text = base.textContent,
cacheKey = KEY.textRect + "-" + text.replace(/\W/g, "_");
let rect = $$.cache.get(cacheKey);
if (!rect) {
$$.$el.svg.append("text").style("visibility", "hidden").style("font", src_select(base).style("font")).classed(className, !0).text(text).call(function (v) {
_newArrowCheck(this, _this3);
rect = getBoundingRect(v.node());
}.bind(this)).remove();
$$.cache.add(cacheKey, rect);
}
return rect;
},
/**
* Gets the x or y coordinate of the text
* @param {object} indices Indices values
* @param {boolean} forX whether or not to x
* @returns {number} coordinates
* @private
*/
generateXYForText: function generateXYForText(indices, forX) {
var _this4 = this;
const $$ = this,
_$$$state = $$.state,
hasRadar = _$$$state.hasRadar,
hasTreemap = _$$$state.hasTreemap,
types = Object.keys(indices),
points = {},
getter = forX ? $$.getXForText : $$.getYForText;
hasRadar && types.push("radar");
hasTreemap && types.push("treemap");
types.forEach(function (v) {
_newArrowCheck(this, _this4);
points[v] = $$["generateGet" + capitalize(v) + "Points"](indices[v], !1);
}.bind(this));
return function (d, i) {
const type = $$.isAreaType(d) && "area" || $$.isBarType(d) && "bar" || $$.isCandlestickType(d) && "candlestick" || $$.isRadarType(d) && "radar" || $$.isTreemapType(d) && "treemap" || "line";
return getter.call($$, points[type](d, i), d, this);
};
},
/**
* Get centerized text position for bar type data.label.text
* @param {object} d Data object
* @param {Array} points Data points position
* @param {HTMLElement} textElement Data label text element
* @param {string} type 'x' or 'y'
* @returns {number} Position value
* @private
*/
getCenteredTextPos: function getCenteredTextPos(d, points, textElement, type) {
const $$ = this,
config = $$.config,
isRotated = config.axis_rotated,
isBarType = $$.isBarType(d),
isTreemapType = $$.isTreemapType(d);
if (config.data_labels.centered && (isBarType || isTreemapType)) {
const rect = getBoundingRect(textElement);
if (isBarType) {
const isPositive = $$.getRangedData(d, null, "bar") >= 0;
if (isRotated) {
const w = (isPositive ? points[1][1] - points[0][1] : points[0][1] - points[1][1]) / 2 + rect.width / 2;
return isPositive ? -w - 3 : w + 2;
} else {
const h = (isPositive ? points[0][1] - points[1][1] : points[1][1] - points[0][1]) / 2 + rect.height / 2;
return isPositive ? h : -h - 2;
}
} else if (isTreemapType) {
return type === "x" ? (points[1][0] - points[0][0]) / 2 : (points[1][1] - points[0][1]) / 2 + rect.height / 2;
}
}
return 0;
},
/**
* Gets the x coordinate of the text
* @param {object} points Data points position
* @param {object} d Data object
* @param {HTMLElement} textElement Data label text element
* @returns {number} x coordinate
* @private
*/
getXForText: function getXForText(points, d, textElement) {
const $$ = this,
config = $$.config,
isRotated = config.axis_rotated,
isTreemapType = $$.isTreemapType(d);
let xPos = points[0][0];
if ($$.isCandlestickType(d)) {
if (isRotated) {
var _$$$getCandlestickDat2;
xPos = (_$$$getCandlestickDat2 = $$.getCandlestickData(d)) != null && _$$$getCandlestickDat2._isUp ? points[2][2] + 4 : points[2][1] - 4;
} else {
xPos += (points[1][0] - xPos) / 2;
}
} else if (isTreemapType) {
xPos += config.data_labels.centered ? 0 : 5;
} else {
if (isRotated) {
const isInverted = config["axis_" + $$.axis.getId(d.id) + "_inverted"],
padding = $$.isBarType(d) ? 4 : 6,
value = d.value;
xPos = points[2][1];
if (isInverted) {
xPos -= padding * (value > 0 ? 1 : -1);
} else {
xPos += padding * (value < 0 ? -1 : 1);
}
} else {
xPos = $$.hasType("bar") ? (points[2][0] + points[0][0]) / 2 : xPos;
}
}
if (isRotated || isTreemapType) {
xPos += $$.getCenteredTextPos(d, points, textElement, "x");
}
return xPos + getTextPos.call(this, d, "x");
},
/**
* Gets the y coordinate of the text
* @param {object} points Data points position
* @param {object} d Data object
* @param {HTMLElement} textElement Data label text element
* @returns {number} y coordinate
* @private
*/
getYForText: function getYForText(points, d, textElement) {
const $$ = this,
axis = $$.axis,
config = $$.config,
state = $$.state,
isRotated = config.axis_rotated,
isInverted = config["axis_" + (axis == null ? void 0 : axis.getId(d.id)) + "_inverted"],
isBarType = $$.isBarType(d),
isTreemapType = $$.isTreemapType(d),
r = config.point_r,
rect = getBoundingRect(textElement);
let value = d.value,
baseY = 3,
yPos;
if ($$.isCandlestickType(d)) {
value = $$.getCandlestickData(d);
if (isRotated) {
yPos = points[0][0];
yPos += (points[1][0] - yPos) / 2 + baseY;
} else {
yPos = value && value._isUp ? points[2][2] - baseY : points[2][1] + baseY * 4;
if (isInverted) {
yPos += 15 * (value._isUp ? 1 : -1);
}
}
} else if (isTreemapType) {
yPos = points[0][1] + (config.data_labels.centered ? 0 : rect.height + 5);
} else {
if (isRotated) {
yPos = (points[0][0] + points[2][0] + rect.height * .6) / 2;
} else {
yPos = points[2][1];
if (isNumber(r) && r > 5 && ($$.isLineType(d) || $$.isScatterType(d))) {
baseY += config.point_r / 2.3;
}
if (value < 0 || value === 0 && !state.hasPositiveValue && state.hasNegativeValue) {
yPos += isInverted ? isBarType ? -3 : -5 : rect.height + (isBarType ? -baseY : baseY);
} else {
let diff = -baseY * 2;
if (isBarType) {
diff = -baseY;
} else if ($$.isBubbleType(d)) {
diff = baseY;
}
if (isInverted) {
diff = isBarType ? 10 : 15;
}
yPos += diff;
}
}
}
if (!isRotated || isTreemapType) {
yPos += $$.getCenteredTextPos(d, points, textElement, "y");
}
return yPos + getTextPos.call(this, d, "y");
},
/**
* Calculate if two or more text nodes are overlapping
* Mark overlapping text nodes with "text-overlapping" class
* @param {string} id Axis id
* @param {ChartInternal} $$ ChartInternal context
* @param {string} selector Selector string
* @private
*/
markOverlapped: function markOverlapped(id, $$, selector) {
var _this5 = this;
const textNodes = $$.$el.arcs.selectAll(selector),
filteredTextNodes = textNodes.filter(function (node) {
_newArrowCheck(this, _this5);
return node.data.id !== id;
}.bind(this)),
textNode = textNodes.filter(function (node) {
_newArrowCheck(this, _this5);
return node.data.id === id;
}.bind(this)),
translate = getTranslation(textNode.node()),
calcHypo = function (x, y) {
_newArrowCheck(this, _this5);
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}.bind(this); // Calculates the length of the hypotenuse
textNode.node() && filteredTextNodes.each(function () {
const coordinate = getTranslation(this),
filteredTextNode = src_select(this),
nodeForWidth = calcHypo(translate.e, translate.f) > calcHypo(coordinate.e, coordinate.f) ? textNode : filteredTextNode,
overlapsX = Math.ceil(Math.abs(translate.e - coordinate.e)) < Math.ceil(nodeForWidth.node().getComputedTextLength()),
overlapsY = Math.ceil(Math.abs(translate.f - coordinate.f)) < parseInt(textNode.style("font-size"), 10);
filteredTextNode.classed($TEXT.TextOverlapping, overlapsX && overlapsY);
});
},
/**
* Calculate if two or more text nodes are overlapping
* Remove "text-overlapping" class on selected text nodes
* @param {ChartInternal} $$ ChartInternal context
* @param {string} selector Selector string
* @private
*/
undoMarkOverlapped: function undoMarkOverlapped($$, selector) {
$$.$el.arcs.selectAll(selector).each(function () {
src_selectAll([this, this.previousSibling]).classed($TEXT.TextOverlapping, !1);
});
},
/**
* Check if meets the ratio to show data label text
* @param {number} ratio ratio to meet
* @param {string} type chart type
* @returns {boolean}
* @private
*/
meetsLabelThreshold: function meetsLabelThreshold(ratio, type) {
if (ratio === void 0) {
ratio = 0;
}
const $$ = this,
config = $$.config,
threshold = config[type + "_label_threshold"] || 0;
return ratio >= threshold;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/title.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Get the text position
* @param {string} pos right, left or center
* @param {number} width chart width
* @returns {string|number} text-anchor value or position in pixel
* @private
*/
function getTextXPos(pos, width) {
if (pos === void 0) {
pos = "left";
}
const isNum = isNumber(width);
let position;
if (pos.indexOf("center") > -1) {
position = isNum ? width / 2 : "middle";
} else if (pos.indexOf("right") > -1) {
position = isNum ? width : "end";
} else {
position = isNum ? 0 : "start";
}
return position;
}
/* harmony default export */ var internals_title = ({
/**
* Initializes the title
* @private
*/
initTitle: function initTitle() {
const $$ = this,
config = $$.config,
$el = $$.$el;
if (config.title_text) {
$el.title = $el.svg.append("g");
const text = $el.title.append("text").style("text-anchor", getTextXPos(config.title_position)).attr("class", $TEXT.title);
setTextValue(text, config.title_text, [.3, 1.5]);
}
},
/**
* Redraw title
* @private
*/
redrawTitle: function redrawTitle() {
const $$ = this,
config = $$.config,
current = $$.state.current,
title = $$.$el.title;
if (title) {
const x = getTextXPos(config.title_position, current.width),
y = (config.title_padding.top || 0) + $$.getTextRect($$.$el.title, $TEXT.title).height;
title.attr("transform", "translate(" + x + ", " + y + ")");
}
},
/**
* Get title padding
* @returns {number} padding value
* @private
*/
getTitlePadding: function getTitlePadding() {
const $$ = this,
title = $$.$el.title,
config = $$.config;
return (config.title_padding.top || 0) + (title ? $$.getTextRect(title, $TEXT.title).height : 0) + (config.title_padding.bottom || 0);
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/tooltip.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var internals_tooltip = ({
/**
* Initializes the tooltip
* @private
*/
initTooltip: function initTooltip() {
const $$ = this,
config = $$.config,
$el = $$.$el;
$el.tooltip = src_select(config.tooltip_contents.bindto);
if ($el.tooltip.empty()) {
$el.tooltip = $el.chart.append("div").attr("class", $TOOLTIP.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none");
}
$$.bindTooltipResizePos();
},
/**
* Show tooltip at initialization.
* Is called only when tooltip.init.show=true option is set
* @private
*/
initShowTooltip: function initShowTooltip() {
const $$ = this,
config = $$.config,
$el = $$.$el,
_$$$state = $$.state,
hasAxis = _$$$state.hasAxis,
hasRadar = _$$$state.hasRadar;
// Show tooltip if needed
if (config.tooltip_init_show) {
var _$$$axis, _data;
if ((_$$$axis = $$.axis) != null && _$$$axis.isTimeSeries() && isString(config.tooltip_init_x)) {
config.tooltip_init_x = parseDate.call($$, config.tooltip_init_x);
}
$$.api.tooltip.show({
data: (_data = {}, _data[!(hasAxis || hasRadar) ? "index" : "x"] = config.tooltip_init_x, _data)
});
const position = config.tooltip_init_position;
if (!config.tooltip_contents.bindto && !isEmpty(position)) {
const _position$top = position.top,
top = _position$top === void 0 ? 0 : _position$top,
_position$left = position.left,
left = _position$left === void 0 ? 50 : _position$left;
$el.tooltip.style("top", isString(top) ? top : top + "px").style("left", isString(left) ? left : left + "px").style("display", null);
}
}
},
/**
* Get the tooltip HTML string
* @param {Array} args Arguments
* @returns {string} Formatted HTML string
* @private
*/
getTooltipHTML: function getTooltipHTML() {
const $$ = this,
api = $$.api,
config = $$.config;
return isFunction(config.tooltip_contents) ? config.tooltip_contents.bind(api).apply(void 0, arguments) : $$.getTooltipContent.apply($$, arguments);
},
/**
* Returns the tooltip content(HTML string)
* @param {object} d data
* @param {Function} defaultTitleFormat Default title format
* @param {Function} defaultValueFormat Default format for each data value in the tooltip.
* @param {Function} color Color function
* @returns {string} html
* @private
*/
getTooltipContent: function getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) {
var _this = this;
const $$ = this,
api = $$.api,
config = $$.config,
state = $$.state,
$el = $$.$el,
_map = ["title", "name", "value"].map(function (v) {
_newArrowCheck(this, _this);
const fn = config["tooltip_format_" + v];
return isFunction(fn) ? fn.bind(api) : fn;
}.bind(this)),
titleFn = _map[0],
nameFn = _map[1],
valueFn = _map[2],
titleFormat = function () {
_newArrowCheck(this, _this);
return sanitize((titleFn || defaultTitleFormat).apply(void 0, arguments));
}.bind(this),
nameFormat = function () {
var _this2 = this;
_newArrowCheck(this, _this);
return sanitize((nameFn || function (name) {
_newArrowCheck(this, _this2);
return name;
}.bind(this)).apply(void 0, arguments));
}.bind(this),
valueFormat = function () {
var _this3 = this;
_newArrowCheck(this, _this);
const fn = valueFn || (state.hasTreemap || $$.isStackNormalized() ? function (v, ratio) {
_newArrowCheck(this, _this3);
return (ratio * 100).toFixed(2) + "%";
}.bind(this) : defaultValueFormat);
return sanitize(fn.apply(void 0, arguments));
}.bind(this),
order = config.tooltip_order,
getRowValue = function (row) {
_newArrowCheck(this, _this);
return $$.axis && $$.isBubbleZType(row) ? $$.getBubbleZData(row.value, "z") : $$.getBaseValue(row);
}.bind(this),
getBgColor = $$.levelColor ? function (row) {
_newArrowCheck(this, _this);
return $$.levelColor(row.value);
}.bind(this) : function (row) {
_newArrowCheck(this, _this);
return color(row);
}.bind(this),
contents = config.tooltip_contents,
tplStr = contents.template,
targetIds = $$.mapToTargetIds();
// get formatter function
// determine fotmatter function with sanitization
if (order === null && config.data_groups.length) {
// for stacked data, order should aligned with the visually displayed data
const ids = $$.orderTargets($$.data.targets).map(function (i2) {
_newArrowCheck(this, _this);
return i2.id;
}.bind(this)).reverse();
d.sort(function (a, b) {
_newArrowCheck(this, _this);
let v1 = a ? a.value : null,
v2 = b ? b.value : null;
if (v1 > 0 && v2 > 0) {
v1 = a.id ? ids.indexOf(a.id) : null;
v2 = b.id ? ids.indexOf(b.id) : null;
}
return v1 - v2;
}.bind(this));
} else if (/^(asc|desc)$/.test(order)) {
d.sort(function (a, b) {
_newArrowCheck(this, _this);
const v1 = a ? getRowValue(a) : null,
v2 = b ? getRowValue(b) : null;
return order === "asc" ? v1 - v2 : v2 - v1;
}.bind(this));
} else if (isFunction(order)) {
d.sort(order.bind(api));
}
const tpl = $$.getTooltipContentTemplate(tplStr),
len = d.length;
let text, row, param, value, i;
for (i = 0; i < len; i++) {
row = d[i];
if (!row || !(getRowValue(row) || getRowValue(row) === 0)) {
continue;
}
if (isUndefined(text)) {
const title = (state.hasAxis || state.hasRadar) && titleFormat(row.x);
text = tplProcess(tpl[0], {
CLASS_TOOLTIP: $TOOLTIP.tooltip,
TITLE: isValue(title) ? tplStr ? title : "" + title + " |
" : ""
});
}
if (!row.ratio && $el.arcs) {
param = ["arc", $$.$el.arcs.select("path." + $ARC.arc + "-" + row.id).data()[0]];
row.ratio = $$.getRatio.apply($$, param);
}
// arrange param to be passed to formatter
param = [row.ratio, row.id, row.index];
if ($$.isAreaRangeType(row)) {
const _map2 = ["high", "low"].map(function (v) {
_newArrowCheck(this, _this);
return valueFormat.apply(void 0, [$$.getRangedData(row, v)].concat(param));
}.bind(this)),
high = _map2[0],
low = _map2[1],
mid = valueFormat.apply(void 0, [getRowValue(row)].concat(param));
value = "Mid: " + mid + " High: " + high + " Low: " + low;
} else if ($$.isCandlestickType(row)) {
const _map3 = ["open", "high", "low", "close", "volume"].map(function (v) {
_newArrowCheck(this, _this);
const value = $$.getRangedData(row, v, "candlestick");
return value ? valueFormat.apply(void 0, [$$.getRangedData(row, v, "candlestick")].concat(param)) : undefined;
}.bind(this)),
open = _map3[0],
high = _map3[1],
low = _map3[2],
close = _map3[3],
volume = _map3[4];
value = "Open: " + open + " High: " + high + " Low: " + low + " Close: " + close + (volume ? " Volume: " + volume : "");
} else if ($$.isBarRangeType(row)) {
const _row = row,
rangeValue = _row.value,
id = _row.id,
index = _row.index;
value = "" + valueFormat(rangeValue, undefined, id, index);
} else {
value = valueFormat.apply(void 0, [getRowValue(row)].concat(param));
}
if (value !== undefined) {
// Skip elements when their name is set to null
if (row.name === null) {
continue;
}
const name = nameFormat.apply(void 0, [row.name].concat(param)),
color = getBgColor(row),
contentValue = {
CLASS_TOOLTIP_NAME: $TOOLTIP.tooltipName + $$.getTargetSelectorSuffix(row.id),
COLOR: tplStr || !$$.patterns ? color : "",
NAME: name,
VALUE: value
};
if (tplStr && isObject(contents.text)) {
const index = targetIds.indexOf(row.id);
Object.keys(contents.text).forEach(function (key) {
_newArrowCheck(this, _this);
contentValue[key] = contents.text[key][index];
}.bind(this));
}
text += tplProcess(tpl[1], contentValue);
}
}
return text + "";
},
/**
* Get the content template string
* @param {string} tplStr Tempalte string
* @returns {Array} Template string
* @private
*/
getTooltipContentTemplate: function getTooltipContentTemplate(tplStr) {
return (tplStr || "").replace(/(\r?\n|\t)/g, "").split(/{{(.*)}}/);
},
/**
* Update tooltip position coordinate
* @param {object} dataToShow Data object
* @param {SVGElement} eventTarget Event element
* @private
*/
setTooltipPosition: function setTooltipPosition(dataToShow, eventTarget) {
var _this4 = this;
const $$ = this,
config = $$.config,
scale = $$.scale,
state = $$.state,
_$$$$el = $$.$el,
eventRect = _$$$$el.eventRect,
tooltip = _$$$$el.tooltip,
bindto = config.tooltip_contents.bindto,
isRotated = config.axis_rotated,
datum = tooltip == null ? void 0 : tooltip.datum();
if (!bindto && datum) {
var _config$tooltip_posit, _config$tooltip_posit2;
const data = dataToShow != null ? dataToShow : JSON.parse(datum.current),
_getPointer = getPointer(state.event, eventTarget != null ? eventTarget : eventRect == null ? void 0 : eventRect.node()),
x = _getPointer[0],
y = _getPointer[1],
currPos = {
x: x,
y: y
};
// get mouse event position
if (state.hasAxis && scale.x && datum && "x" in datum) {
const getYPos = function (value, id, axisId) {
var _$$$axis2;
if (value === void 0) {
value = 0;
}
if (axisId === void 0) {
axisId = "y";
}
_newArrowCheck(this, _this4);
const scaleFn = scale[id ? (_$$$axis2 = $$.axis) == null ? void 0 : _$$$axis2.getId(id) : axisId];
return scaleFn ? scaleFn(value) + (isRotated ? state.margin.left : state.margin.top) : 0;
}.bind(this);
currPos.xAxis = scale.x(datum.x) + (
// add margin only when user specified tooltip.position function
config.tooltip_position ? isRotated ? state.margin.top : state.margin.left : 0);
if (data.length === 1) {
currPos.yAxis = getYPos(data[0].value, data[0].id);
} else {
currPos.yAxis = getYPos;
}
}
const _datum$width = datum.width,
width = _datum$width === void 0 ? 0 : _datum$width,
_datum$height = datum.height,
height = _datum$height === void 0 ? 0 : _datum$height,
pos = (_config$tooltip_posit = (_config$tooltip_posit2 = config.tooltip_position) == null ? void 0 : _config$tooltip_posit2.bind($$.api)(data, width, height, eventRect == null ? void 0 : eventRect.node(), currPos)) != null ? _config$tooltip_posit : $$.getTooltipPosition.bind($$)(width, height, currPos); // Get tooltip position
["top", "left"].forEach(function (v) {
_newArrowCheck(this, _this4);
const value = pos[v];
tooltip.style(v, value + "px");
// Remember left pos in percentage to be used on resize call
if (v === "left" && !datum.xPosInPercent) {
datum.xPosInPercent = value / state.current.width * 100;
}
}.bind(this));
}
},
/**
* Returns the position of the tooltip
* @param {string} tWidth Width value of tooltip element
* @param {string} tHeight Height value of tooltip element
* @param {object} currPos Current mouse position
* @returns {object} top, left value
* @private
*/
getTooltipPosition: function getTooltipPosition(tWidth, tHeight, currPos) {
var _this5 = this;
const $$ = this,
config = $$.config,
scale = $$.scale,
state = $$.state,
_state = state,
width = _state.width,
height = _state.height,
current = _state.current,
hasRadar = _state.hasRadar,
hasTreemap = _state.hasTreemap,
isLegendRight = _state.isLegendRight,
inputType = _state.inputType,
hasGauge = $$.hasType("gauge") && !config.gauge_fullCircle,
isRotated = config.axis_rotated,
hasArcType = $$.hasArcType(),
svgLeft = $$.getSvgLeft(!0);
let chartRight = svgLeft + current.width - $$.getCurrentPaddingByDirection("right");
const size = 20;
let x = currPos.x,
y = currPos.y;
// Determine tooltip position
if (hasRadar) {
x += x >= width / 2 ? 15 : -(tWidth + 15);
y += 15;
} else if (hasArcType) {
if (inputType !== "touch") {
var _$$$getTitlePadding, _config$arc_rangeText;
let titlePadding = (_$$$getTitlePadding = $$.getTitlePadding == null ? void 0 : $$.getTitlePadding()) != null ? _$$$getTitlePadding : 0;
if (titlePadding && hasGauge && (_config$arc_rangeText = config.arc_rangeText_values) != null && _config$arc_rangeText.length) {
titlePadding += 10;
}
x += (width - (isLegendRight ? $$.getLegendWidth() : 0)) / 2;
y += (hasGauge ? height : height / 2 + tHeight) + titlePadding;
}
} else if (hasTreemap) {
y += tHeight;
} else {
const padding = {
top: $$.getCurrentPaddingByDirection("top", !0),
left: $$.getCurrentPaddingByDirection("left", !0)
};
if (isRotated) {
x += svgLeft + padding.left + size;
y = padding.top + currPos.xAxis + size;
chartRight -= svgLeft;
} else {
x = svgLeft + padding.left + size + (scale.zoom ? x : currPos.xAxis);
y += padding.top - 5;
}
}
// when tooltip left + tWidth > chart's width
if (x + tWidth + 15 > chartRight) {
x -= tWidth + (hasTreemap || hasArcType ? 0 : isRotated ? 40 : 38);
}
if (y + tHeight > current.height) {
const gap = hasTreemap ? tHeight + 10 : 30;
y -= hasGauge ? tHeight * 1.5 : tHeight + gap;
}
const pos = {
top: y,
left: x
};
// make sure to not be positioned out of viewport
Object.keys(pos).forEach(function (v) {
_newArrowCheck(this, _this5);
if (pos[v] < 0) {
pos[v] = 0;
}
}.bind(this));
return pos;
},
/**
* Show the tooltip
* @param {object} selectedData Data object
* @param {SVGElement} eventTarget Event element
* @private
*/
showTooltip: function showTooltip(selectedData, eventTarget) {
var _this6 = this;
const $$ = this,
config = $$.config,
tooltip = $$.$el.tooltip,
dataToShow = selectedData.filter(function (d) {
_newArrowCheck(this, _this6);
return d && isValue($$.getBaseValue(d));
}.bind(this));
if (!tooltip || dataToShow.length === 0 || !config.tooltip_show) {
return;
}
let datum = tooltip.datum();
const dataStr = JSON.stringify(selectedData);
if (!datum || datum.current !== dataStr) {
const _selectedData$concat$ = selectedData.concat().sort()[0],
index = _selectedData$concat$.index,
x = _selectedData$concat$.x;
callFn(config.tooltip_onshow, $$.api, selectedData);
// set tooltip content
tooltip.html($$.getTooltipHTML(selectedData,
// data
$$.axis ? $$.axis.getXAxisTickFormat() : $$.categoryName.bind($$),
// defaultTitleFormat
$$.getDefaultValueFormat(),
// defaultValueFormat
$$.color // color
)).style("display", null).style("visibility", null) // for IE9
.datum(datum = {
index: index,
x: x,
current: dataStr,
width: tooltip.property("offsetWidth"),
height: tooltip.property("offsetHeight")
});
callFn(config.tooltip_onshown, $$.api, selectedData);
$$._handleLinkedCharts(!0, index);
}
$$.setTooltipPosition(dataToShow, eventTarget);
},
/**
* Adjust tooltip position on resize event
* @private
*/
bindTooltipResizePos: function bindTooltipResizePos() {
var _this7 = this;
const $$ = this,
resizeFunction = $$.resizeFunction,
state = $$.state,
tooltip = $$.$el.tooltip;
resizeFunction.add(function () {
_newArrowCheck(this, _this7);
if (tooltip.style("display") === "block") {
const current = state.current,
_tooltip$datum = tooltip.datum(),
width = _tooltip$datum.width,
xPosInPercent = _tooltip$datum.xPosInPercent;
let value = current.width / 100 * xPosInPercent;
const diff = current.width - (value + width);
// if tooltip size overs current viewport size
if (diff < 0) {
value += diff;
}
tooltip.style("left", value + "px");
}
}.bind(this));
},
/**
* Hide the tooltip
* @param {boolean} force Force to hide
* @private
*/
hideTooltip: function hideTooltip(force) {
const $$ = this,
api = $$.api,
config = $$.config,
tooltip = $$.$el.tooltip;
if (tooltip && tooltip.style("display") !== "none" && (!config.tooltip_doNotHide || force)) {
var _tooltip$datum$curren;
const selectedData = JSON.parse((_tooltip$datum$curren = tooltip.datum().current) != null ? _tooltip$datum$curren : {});
callFn(config.tooltip_onhide, api, selectedData);
// hide tooltip
tooltip.style("display", "none").style("visibility", "hidden") // for IE9
.datum(null);
callFn(config.tooltip_onhidden, api, selectedData);
}
},
/**
* Toggle display for linked chart instances
* @param {boolean} show true: show, false: hide
* @param {number} index x Axis index
* @private
*/
_handleLinkedCharts: function _handleLinkedCharts(show, index) {
var _this8 = this;
const $$ = this,
charts = $$.charts,
config = $$.config,
event = $$.state.event;
// Prevent propagation among instances if isn't instantiated from the user's event
// https://github.com/naver/billboard.js/issues/1979
if (event != null && event.isTrusted && config.tooltip_linked && charts.length > 1) {
const linkedName = config.tooltip_linked_name;
charts.filter(function (c) {
_newArrowCheck(this, _this8);
return c !== $$.api;
}.bind(this)).forEach(function (c) {
_newArrowCheck(this, _this8);
const _c$internal = c.internal,
config = _c$internal.config,
$el = _c$internal.$el,
isLinked = config.tooltip_linked,
name = config.tooltip_linked_name,
isInDom = browser_doc.body.contains($el.chart.node());
if (isLinked && linkedName === name && isInDom) {
const data = $el.tooltip.data()[0],
isNotSameIndex = index !== (data == null ? void 0 : data.index);
try {
c.tooltip[show && isNotSameIndex ? "show" : "hide"]({
index: index
});
} catch (e) {}
}
}.bind(this));
}
},
/**
* Update tooltip content on redraw
* - In a situation where tooltip is displayed and data load happens, it should reflect loaded data to tooltip
* @param {d3Selection} context Event rect element
* @param {number} index Data index
* @private
*/
updateTooltipOnRedraw: function updateTooltipOnRedraw(context, index) {
var _this9 = this;
const $$ = this,
config = $$.config,
_$$$$el2 = $$.$el,
eventRect = _$$$$el2.eventRect,
svg = _$$$$el2.svg,
tooltip = _$$$$el2.tooltip,
_$$$state2 = $$.state,
event = _$$$state2.event,
hasAxis = _$$$state2.hasAxis,
hasRadar = _$$$state2.hasRadar,
hasTreemap = _$$$state2.hasTreemap;
// Update tooltip, when tooltip is in shown state
if ((tooltip == null ? void 0 : tooltip.style("display")) === "block" && event) {
var _ref;
const rect = context != null ? context : (_ref = hasRadar ? svg : eventRect) == null ? void 0 : _ref.node();
// for Axis based & Radar
if (hasAxis || hasRadar) {
if ($$.isMultipleX()) {
$$.selectRectForMultipleXs(rect, !1);
} else {
const idx = index != null ? index : $$.getDataIndexFromEvent(event);
if (index === -1) {
$$.api.tooltip.hide();
} else {
$$.selectRectForSingle(rect, idx);
$$.setExpand(idx, null, !0);
}
}
// for Arc & Treemap
} else {
const clientX = event.clientX,
clientY = event.clientY;
setTimeout(function () {
_newArrowCheck(this, _this9);
let target = browser_doc.elementFromPoint(clientX, clientY);
const data = src_select(target).datum();
if (data) {
const d = $$.hasArcType() ? $$.convertToArcData($$.updateAngle(data)) : data == null ? void 0 : data.data;
hasTreemap && (target = svg.node());
d && $$.showTooltip([d], target);
} else {
$$.api.tooltip.hide();
}
}.bind(this), config.transition_duration);
}
}
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/transform.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var transform = ({
getTranslate: function getTranslate(target, index) {
if (index === void 0) {
index = 0;
}
const $$ = this,
config = $$.config,
state = $$.state,
isRotated = config.axis_rotated;
let padding = 0,
x,
y;
if (index && /^(x|y2?)$/.test(target)) {
padding = $$.getAxisSize(target) * index;
}
if (target === "main") {
x = asHalfPixel(state.margin.left);
y = asHalfPixel(state.margin.top);
} else if (target === "context") {
x = asHalfPixel(state.margin2.left);
y = asHalfPixel(state.margin2.top);
} else if (target === "legend") {
x = state.margin3.left;
y = state.margin3.top;
} else if (target === "x") {
x = isRotated ? -padding : 0;
y = isRotated ? 0 : state.height + padding;
} else if (target === "y") {
x = isRotated ? 0 : -padding;
y = isRotated ? state.height + padding : 0;
} else if (target === "y2") {
x = isRotated ? 0 : state.width + padding;
y = isRotated ? -padding - 1 : 0;
} else if (target === "subX") {
x = 0;
y = isRotated ? 0 : state.height2;
} else if (target === "arc") {
var _config$arc_rangeText;
x = state.arcWidth / 2;
y = state.arcHeight / 2;
if ((_config$arc_rangeText = config.arc_rangeText_values) != null && _config$arc_rangeText.length) {
y += 5 + ($$.hasType("gauge") && config.title_text ? 10 : 0);
}
} else if (target === "polar") {
x = state.arcWidth / 2;
y = state.arcHeight / 2;
} else if (target === "radar") {
const _$$$getRadarSize = $$.getRadarSize(),
width = _$$$getRadarSize[0],
height = _$$$getRadarSize[1];
x = state.width / 2 - width;
y = state.height / 2 - height;
}
return "translate(" + x + ", " + y + ")";
},
transformMain: function transformMain(withTransition, transitions) {
const $$ = this,
main = $$.$el.main,
$T = $$.$T,
xAxis = transitions != null && transitions.axisX ? transitions.axisX : $T(main.select("." + $AXIS.axisX), withTransition),
yAxis = transitions != null && transitions.axisY ? transitions.axisY : $T(main.select("." + $AXIS.axisY), withTransition),
y2Axis = transitions != null && transitions.axisY2 ? transitions.axisY2 : $T(main.select("." + $AXIS.axisY2), withTransition);
$T(main, withTransition).attr("transform", $$.getTranslate("main"));
xAxis.attr("transform", $$.getTranslate("x"));
yAxis.attr("transform", $$.getTranslate("y"));
y2Axis.attr("transform", $$.getTranslate("y2"));
main.select("." + $ARC.chartArcs).attr("transform", $$.getTranslate("arc"));
},
transformAll: function transformAll(withTransition, transitions) {
const $$ = this,
config = $$.config,
_$$$state = $$.state,
hasAxis = _$$$state.hasAxis,
hasTreemap = _$$$state.hasTreemap,
$el = $$.$el;
hasTreemap || $$.transformMain(withTransition, transitions);
hasAxis && config.subchart_show && $$.transformContext(withTransition, transitions);
$el.legend && $$.transformLegend(withTransition);
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/internals/type.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var internals_type = ({
/**
* Check if the given chart type is valid
* @param {string} type Chart type string
* @returns {boolean}
* @private
*/
isValidChartType: function isValidChartType(type) {
return !!(type && Object.values(TYPE).indexOf(type) > -1);
},
setTargetType: function setTargetType(targetIds, type) {
var _this = this;
const $$ = this,
config = $$.config,
withoutFadeIn = $$.state.withoutFadeIn;
$$.mapToTargetIds(targetIds).forEach(function (id) {
_newArrowCheck(this, _this);
withoutFadeIn[id] = type === config.data_types[id];
config.data_types[id] = type;
}.bind(this));
if (!targetIds) {
config.data_type = type;
}
},
/**
* Updte current used chart types
* @private
*/
updateTypesElements: function updateTypesElements() {
var _this2 = this;
const $$ = this,
current = $$.state.current;
Object.keys(TYPE).forEach(function (v) {
_newArrowCheck(this, _this2);
const t = TYPE[v],
has = $$.hasType(t, null, !0),
idx = current.types.indexOf(t);
if (idx === -1 && has) {
current.types.push(t);
} else if (idx > -1 && !has) {
current.types.splice(idx, 1);
}
}.bind(this));
// Update current chart elements reference
$$.setChartElements();
},
/**
* Check if given chart types exists
* @param {string} type Chart type
* @param {Array} targetsValue Data array
* @param {boolean} checkFromData Force to check type cotains from data targets
* @returns {boolean}
* @private
*/
hasType: function hasType(type, targetsValue, checkFromData) {
var _current$types,
_this3 = this;
if (checkFromData === void 0) {
checkFromData = !1;
}
const $$ = this,
config = $$.config,
current = $$.state.current,
types = config.data_types,
targets = targetsValue || $$.data.targets;
let has = !1;
if (!checkFromData && ((_current$types = current.types) == null ? void 0 : _current$types.indexOf(type)) > -1) {
has = !0;
} else if (targets != null && targets.length) {
targets.forEach(function (target) {
_newArrowCheck(this, _this3);
const t = types[target.id];
if (t === type || !t && type === "line") {
has = !0;
}
}.bind(this));
} else if (Object.keys(types).length) {
Object.keys(types).forEach(function (id) {
_newArrowCheck(this, _this3);
if (types[id] === type) {
has = !0;
}
}.bind(this));
} else {
has = config.data_type === type;
}
return has;
},
/**
* Check if contains given chart types
* @param {string} type Type key
* @param {object} targets Target data
* @param {Array} exclude Excluded types
* @returns {boolean}
* @private
*/
hasTypeOf: function hasTypeOf(type, targets, exclude) {
var _this4 = this;
if (exclude === void 0) {
exclude = [];
}
if (type in TYPE_BY_CATEGORY) {
return !TYPE_BY_CATEGORY[type].filter(function (v) {
_newArrowCheck(this, _this4);
return exclude.indexOf(v) === -1;
}.bind(this)).every(function (v) {
_newArrowCheck(this, _this4);
return !this.hasType(v, targets);
}.bind(this));
}
return !1;
},
/**
* Check if given data is certain chart type
* @param {object} d Data object
* @param {string|Array} type chart type
* @returns {boolean}
* @private
*/
isTypeOf: function isTypeOf(d, type) {
var _this$config$data_typ;
const id = isString(d) ? d : d.id,
dataType = this.config && (((_this$config$data_typ = this.config.data_types) == null ? void 0 : _this$config$data_typ[id]) || this.config.data_type);
return isArray(type) ? type.indexOf(dataType) >= 0 : dataType === type;
},
hasPointType: function hasPointType() {
const $$ = this;
return $$.hasTypeOf("Line") || $$.hasType("bubble") || $$.hasType("scatter");
},
/**
* Check if contains arc types chart
* @param {object} targets Target data
* @param {Array} exclude Excluded types
* @returns {boolean}
* @private
*/
hasArcType: function hasArcType(targets, exclude) {
return this.hasTypeOf("Arc", targets, exclude);
},
hasMultiArcGauge: function hasMultiArcGauge() {
return this.hasType("gauge") && this.config.gauge_type === "multi";
},
isLineType: function isLineType(d) {
const id = isString(d) ? d : d.id;
return !this.config.data_types[id] || this.isTypeOf(id, TYPE_BY_CATEGORY.Line);
},
isStepType: function isStepType(d) {
return this.isTypeOf(d, TYPE_BY_CATEGORY.Step);
},
isSplineType: function isSplineType(d) {
return this.isTypeOf(d, TYPE_BY_CATEGORY.Spline);
},
isAreaType: function isAreaType(d) {
return this.isTypeOf(d, TYPE_BY_CATEGORY.Area);
},
isAreaRangeType: function isAreaRangeType(d) {
return this.isTypeOf(d, TYPE_BY_CATEGORY.AreaRange);
},
isBarType: function isBarType(d) {
return this.isTypeOf(d, "bar");
},
isBubbleType: function isBubbleType(d) {
return this.isTypeOf(d, "bubble");
},
isCandlestickType: function isCandlestickType(d) {
return this.isTypeOf(d, "candlestick");
},
isScatterType: function isScatterType(d) {
return this.isTypeOf(d, "scatter");
},
isTreemapType: function isTreemapType(d) {
return this.isTypeOf(d, "treemap");
},
isPieType: function isPieType(d) {
return this.isTypeOf(d, "pie");
},
isGaugeType: function isGaugeType(d) {
return this.isTypeOf(d, "gauge");
},
isDonutType: function isDonutType(d) {
return this.isTypeOf(d, "donut");
},
isPolarType: function isPolarType(d) {
return this.isTypeOf(d, "polar");
},
isRadarType: function isRadarType(d) {
return this.isTypeOf(d, "radar");
},
isArcType: function isArcType(d) {
return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d) || this.isPolarType(d) || this.isRadarType(d);
},
// determine if is 'circle' data point
isCirclePoint: function isCirclePoint(node) {
const config = this.config,
pattern = config.point_pattern;
let isCircle = !1;
if ((node == null ? void 0 : node.tagName) === "circle") {
isCircle = !0;
} else {
isCircle = config.point_type === "circle" && (!pattern || isArray(pattern) && pattern.length === 0);
}
return isCircle;
},
lineData: function lineData(d) {
return this.isLineType(d) ? [d] : [];
},
arcData: function arcData(d) {
return this.isArcType(d.data) ? [d] : [];
},
/**
* Get data adapt for data label showing
* @param {object} d Data object
* @returns {Array}
* @private
*/
labelishData: function labelishData(d) {
var _this5 = this;
return this.isBarType(d) || this.isLineType(d) || this.isScatterType(d) || this.isBubbleType(d) || this.isCandlestickType(d) || this.isRadarType(d) || this.isTreemapType(d) ? d.values.filter(function (v) {
_newArrowCheck(this, _this5);
return isNumber(v.value) || !!v.value;
}.bind(this)) : [];
},
barLineBubbleData: function barLineBubbleData(d) {
return this.isBarType(d) || this.isLineType(d) || this.isBubbleType(d) ? d.values : [];
},
// https://github.com/d3/d3-shape#curves
isInterpolationType: function isInterpolationType(type) {
return ["basis", "basis-closed", "basis-open", "bundle", "cardinal", "cardinal-closed", "cardinal-open", "catmull-rom", "catmull-rom-closed", "catmull-rom-open", "linear", "linear-closed", "monotone-x", "monotone-y", "natural"].indexOf(type) >= 0;
}
});
;// CONCATENATED MODULE: ./src/ChartInternal/ChartInternal.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
* @ignore
*/
// data
// interactions
// internals
// used to retrieve radar Axis name
/**
* Internal chart class.
* - Note: Instantiated internally, not exposed for public.
* @class ChartInternal
* @ignore
* @private
*/
let ChartInternal = /*#__PURE__*/function () {
function ChartInternal(api) {
this.api = void 0;
// API interface
this.config = void 0;
// config object
this.cache = void 0;
// cache instance
this.$el = void 0;
// elements
this.state = void 0;
// state variables
this.charts = void 0;
// all Chart instances array within page (equivalent of 'bb.instances')
// data object
this.data = {
xs: {},
targets: []
};
// Axis
this.axis = void 0;
// Axis
// scales
this.scale = {
x: null,
y: null,
y2: null,
subX: null,
subY: null,
subY2: null,
zoom: null
};
// original values
this.org = {
xScale: null,
xDomain: null
};
// formatter function
this.color = void 0;
this.patterns = void 0;
this.levelColor = void 0;
this.point = void 0;
this.brush = void 0;
// format function
this.format = {
extraLineClasses: null,
xAxisTick: null,
dataTime: null,
// dataTimeFormat
defaultAxisTime: null,
// defaultAxisTimeFormat
axisTime: null // axisTimeFormat
};
const $$ = this;
$$.api = api; // Chart class instance alias
$$.config = new Options();
$$.cache = new Cache();
const store = new Store();
$$.$el = store.getStore("element");
$$.state = store.getStore("state");
$$.$T = $$.$T.bind($$);
}
/**
* Get the selection based on transition config
* @param {SVGElement|d3Selection} selection Target selection
* @param {boolean} force Force transition
* @param {string} name Transition name
* @returns {d3Selection}
* @private
*/
var _proto = ChartInternal.prototype;
_proto.$T = function $T(selection, force, name) {
const config = this.config,
state = this.state,
duration = config.transition_duration,
subchart = config.subchart_show;
let t = selection;
if (t) {
// in case of non d3 selection, wrap with d3 selection
if ("tagName" in t) {
t = src_select(t);
}
// do not transit on:
// - wheel zoom (state.zooming = true)
// - when has no subchart
// - initialization
// - resizing
const transit = (force !== !1 && duration || force) && (!state.zooming || state.dragging) && !state.resizing && state.rendered && !subchart;
t = transit ? t.transition(name).duration(duration) : t;
}
return t;
};
_proto.beforeInit = function beforeInit() {
const $$ = this;
$$.callPluginHook("$beforeInit");
// can do something
callFn($$.config.onbeforeinit, $$.api);
};
_proto.afterInit = function afterInit() {
const $$ = this;
$$.callPluginHook("$afterInit");
// can do something
callFn($$.config.onafterinit, $$.api);
};
_proto.init = function init() {
const $$ = this,
config = $$.config,
state = $$.state,
$el = $$.$el,
useCssRule = config.boost_useCssRule;
checkModuleImport($$);
state.hasRadar = !state.hasAxis && $$.hasType("radar");
state.hasTreemap = !state.hasAxis && $$.hasType("treemap");
state.hasAxis = !$$.hasArcType() && !state.hasTreemap;
// datetime to be used for uniqueness
state.datetimeId = "bb-" + +new Date() * getRandom();
if (useCssRule) {
// append style element
const styleEl = browser_doc.createElement("style");
// styleEl.id = styleId;
styleEl.type = "text/css";
browser_doc.head.appendChild(styleEl);
state.style = {
rootSelctor: "." + state.datetimeId,
sheet: styleEl.sheet
};
// used on .destroy()
$el.style = styleEl;
}
const bindto = {
element: config.bindto,
classname: "bb"
};
if (isObject(config.bindto)) {
bindto.element = config.bindto.element || "#chart";
bindto.classname = config.bindto.classname || bindto.classname;
}
// select bind element
$el.chart = isFunction(bindto.element.node) ? config.bindto.element : src_select(bindto.element || []);
if ($el.chart.empty()) {
$el.chart = src_select(browser_doc.body.appendChild(browser_doc.createElement("div")));
}
$el.chart.html("").classed(bindto.classname, !0).classed(state.datetimeId, useCssRule).style("position", "relative");
$$.initParams();
$$.initToRender();
}
/**
* Initialize the rendering process
* @param {boolean} forced Force to render process
* @private
*/;
_proto.initToRender = function initToRender(forced) {
var _this = this;
const $$ = this,
config = $$.config,
state = $$.state,
chart = $$.$el.chart,
isHidden = function () {
_newArrowCheck(this, _this);
return chart.style("display") === "none" || chart.style("visibility") === "hidden";
}.bind(this),
isLazy = config.render.lazy || isHidden(),
MutationObserver = win.MutationObserver;
if (isLazy && MutationObserver && config.render.observe !== !1 && !forced) {
new MutationObserver(function (mutation, observer) {
_newArrowCheck(this, _this);
if (!isHidden()) {
observer.disconnect();
state.rendered || $$.initToRender(!0);
}
}.bind(this)).observe(chart.node(), {
attributes: !0,
attributeFilter: ["class", "style"]
});
}
if (!isLazy || forced) {
$$.convertData(config, function (res) {
_newArrowCheck(this, _this);
$$.initWithData(res);
$$.afterInit();
}.bind(this));
}
};
_proto.initParams = function initParams() {
var _this2 = this;
const $$ = this,
config = $$.config,
format = $$.format,
state = $$.state,
isRotated = config.axis_rotated;
// color settings
$$.color = $$.generateColor();
$$.levelColor = $$.generateLevelColor();
// when 'padding=false' is set, disable axes and subchart. Because they are useless.
if (config.padding === !1) {
config.axis_x_show = !1;
config.axis_y_show = !1;
config.axis_y2_show = !1;
config.subchart_show = !1;
}
if ($$.hasPointType() || $$.hasLegendDefsPoint != null && $$.hasLegendDefsPoint()) {
$$.point = $$.generatePoint();
}
if (state.hasAxis) {
$$.initClip();
format.extraLineClasses = $$.generateExtraLineClass();
format.dataTime = config.data_xLocaltime ? timeParse : utcParse;
format.axisTime = config.axis_x_localtime ? timeFormat : utcFormat;
const isDragZoom = $$.config.zoom_enabled && $$.config.zoom_type === "drag";
format.defaultAxisTime = function (d) {
_newArrowCheck(this, _this2);
const _$$$scale = $$.scale,
x = _$$$scale.x,
zoom = _$$$scale.zoom,
isZoomed = isDragZoom ? zoom : zoom && x.orgDomain().toString() !== zoom.domain().toString(),
specifier = d.getMilliseconds() && ".%L" || d.getSeconds() && ".:%S" || d.getMinutes() && "%I:%M" || d.getHours() && "%I %p" || d.getDate() !== 1 && "%b %d" || isZoomed && d.getDate() === 1 && "%b\'%y" || d.getMonth() && "%-m/%-d" || "%Y";
return format.axisTime(specifier)(d);
}.bind(this);
}
state.isLegendRight = config.legend_position === "right";
state.isLegendInset = config.legend_position === "inset";
state.isLegendTop = config.legend_inset_anchor === "top-left" || config.legend_inset_anchor === "top-right";
state.isLegendLeft = config.legend_inset_anchor === "top-left" || config.legend_inset_anchor === "bottom-left";
state.rotatedPadding.top = $$.getResettedPadding(state.rotatedPadding.top);
state.rotatedPadding.right = isRotated && !config.axis_x_show ? 0 : 30;
state.inputType = convertInputType(config.interaction_inputType_mouse, config.interaction_inputType_touch);
};
_proto.initWithData = function initWithData(data) {
var _this3 = this;
const $$ = this,
config = $$.config,
scale = $$.scale,
state = $$.state,
$el = $$.$el,
org = $$.org,
_state = state,
hasAxis = _state.hasAxis,
hasTreemap = _state.hasTreemap,
hasInteraction = config.interaction_enabled,
hasPolar = $$.hasType("polar");
// for arc type, set axes to not be shown
// $$.hasArcType() && ["x", "y", "y2"].forEach(id => (config[`axis_${id}_show`] = false));
if (hasAxis) {
$$.axis = $$.getAxisInstance();
config.zoom_enabled && $$.initZoom();
}
// Init data as targets
$$.data.xs = {};
$$.data.targets = $$.convertDataToTargets(data);
if (config.data_filter) {
$$.data.targets = $$.data.targets.filter(config.data_filter.bind($$.api));
}
// Set targets to hide if needed
if (config.data_hide) {
$$.addHiddenTargetIds(config.data_hide === !0 ? $$.mapToIds($$.data.targets) : config.data_hide);
}
if (config.legend_hide) {
$$.addHiddenLegendIds(config.legend_hide === !0 ? $$.mapToIds($$.data.targets) : config.legend_hide);
}
// Init sizes and scales
$$.updateSizes();
$$.updateScales(!0);
// retrieve scale after the 'updateScales()' is called
if (hasAxis) {
const x = scale.x,
y = scale.y,
y2 = scale.y2,
subX = scale.subX,
subY = scale.subY,
subY2 = scale.subY2;
// Set domains for each scale
if (x) {
x.domain(sortValue($$.getXDomain($$.data.targets), !config.axis_x_inverted));
subX.domain(x.domain());
// Save original x domain for zoom update
org.xDomain = x.domain();
}
if (y) {
y.domain($$.getYDomain($$.data.targets, "y"));
subY.domain(y.domain());
}
if (y2) {
y2.domain($$.getYDomain($$.data.targets, "y2"));
subY2 && subY2.domain(y2.domain());
}
}
// -- Basic Elements --
$el.svg = $el.chart.append("svg").style("overflow", "hidden").style("display", "block");
if (hasInteraction && state.inputType) {
const isTouch = state.inputType === "touch",
onclick = config.onclick,
onover = config.onover,
onout = config.onout;
$el.svg.on("click", (onclick == null ? void 0 : onclick.bind($$.api)) || null).on(isTouch ? "touchstart" : "mouseenter", (onover == null ? void 0 : onover.bind($$.api)) || null).on(isTouch ? "touchend" : "mouseleave", (onout == null ? void 0 : onout.bind($$.api)) || null);
}
config.svg_classname && $el.svg.attr("class", config.svg_classname);
// Define defs
const hasColorPatterns = isFunction(config.color_tiles) && $$.patterns;
if (hasAxis || hasColorPatterns || hasPolar || hasTreemap || config.data_labels_backgroundColors || $$.hasLegendDefsPoint != null && $$.hasLegendDefsPoint()) {
$el.defs = $el.svg.append("defs");
if (hasAxis) {
["id", "idXAxis", "idYAxis", "idGrid"].forEach(function (v) {
_newArrowCheck(this, _this3);
$$.appendClip($el.defs, state.clip[v]);
}.bind(this));
}
// Append data background color filter definition
$$.generateDataLabelBackgroundColorFilter();
// set color patterns
if (hasColorPatterns) {
$$.patterns.forEach(function (p) {
var _this4 = this;
_newArrowCheck(this, _this3);
return $el.defs.append(function () {
_newArrowCheck(this, _this4);
return p.node;
}.bind(this));
}.bind(this));
}
}
$$.updateSvgSize();
// Bind resize event
$$.bindResize();
// Define regions
const main = $el.svg.append("g").classed($COMMON.main, !0).attr("transform", hasTreemap ? null : $$.getTranslate("main"));
$el.main = main;
// initialize subchart when subchart show option is set
config.subchart_show && $$.initSubchart();
config.tooltip_show && $$.initTooltip();
config.title_text && $$.initTitle();
!hasTreemap && config.legend_show && $$.initLegend();
// -- Main Region --
// text when empty
if (config.data_empty_label_text) {
main.append("text").attr("class", $TEXT.text + " " + $COMMON.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 (hasAxis) {
// Regions
config.regions.length && $$.initRegion();
// Add Axis here, when clipPath is 'false'
config.clipPath || $$.axis.init();
}
// Define g for chart area
main.append("g").classed($COMMON.chart, !0).attr("clip-path", hasAxis ? state.clip.path : null);
$$.callPluginHook("$init");
$$.initChartElements();
if (hasAxis) {
var _$$$axis;
// Cover whole with rects for events
hasInteraction && ($$.initEventRect == null ? void 0 : $$.initEventRect());
// Grids
$$.initGrid();
// Add Axis here, when clipPath is 'true'
config.clipPath && ((_$$$axis = $$.axis) == null ? void 0 : _$$$axis.init());
}
// Set targets
$$.updateTargets($$.data.targets);
// Draw with targets
$$.updateDimension();
// oninit callback
callFn(config.oninit, $$.api);
// Set background
$$.setBackground();
$$.redraw({
withTransition: !1,
withTransform: !0,
withUpdateXDomain: !0,
withUpdateOrgXDomain: !0,
withTransitionForAxis: !1,
initializing: !0
});
// data.onmin/max callback
if (config.data_onmin || config.data_onmax) {
const minMax = $$.getMinMaxData();
callFn(config.data_onmin, $$.api, minMax.min);
callFn(config.data_onmax, $$.api, minMax.max);
}
config.tooltip_show && $$.initShowTooltip();
state.rendered = !0;
}
/**
* Initialize chart elements
* @private
*/;
_proto.initChartElements = function initChartElements() {
var _this5 = this;
const $$ = this,
_$$$state = $$.state,
hasAxis = _$$$state.hasAxis,
hasRadar = _$$$state.hasRadar,
hasTreemap = _$$$state.hasTreemap,
types = [];
if (hasAxis) {
const shapes = ["bar", "bubble", "candlestick", "line"];
if ($$.config.bar_front) {
shapes.push(shapes.shift());
}
shapes.forEach(function (v) {
_newArrowCheck(this, _this5);
const name = capitalize(v);
if (v === "line" && $$.hasTypeOf(name) || $$.hasType(v)) {
types.push(name);
}
}.bind(this));
} else if (hasTreemap) {
types.push("Treemap");
} else {
const hasPolar = $$.hasType("polar");
if (!hasRadar) {
types.push("Arc", "Pie");
}
if ($$.hasType("gauge")) {
types.push("Gauge");
} else if (hasRadar) {
types.push("Radar");
} else if (hasPolar) {
types.push("Polar");
}
}
types.forEach(function (v) {
_newArrowCheck(this, _this5);
$$["init" + v]();
}.bind(this));
notEmpty($$.config.data_labels) && !$$.hasArcType(null, ["radar"]) && $$.initText();
}
/**
* Set chart elements
* @private
*/;
_proto.setChartElements = function setChartElements() {
const $$ = this,
_$$$$el = $$.$el,
chart = _$$$$el.chart,
svg = _$$$$el.svg,
defs = _$$$$el.defs,
main = _$$$$el.main,
tooltip = _$$$$el.tooltip,
legend = _$$$$el.legend,
title = _$$$$el.title,
grid = _$$$$el.grid,
needle = _$$$$el.needle,
arc = _$$$$el.arcs,
circles = _$$$$el.circle,
bars = _$$$$el.bar,
candlestick = _$$$$el.candlestick,
lines = _$$$$el.line,
areas = _$$$$el.area,
texts = _$$$$el.text;
// public
$$.api.$ = {
chart: chart,
svg: svg,
defs: defs,
main: main,
tooltip: tooltip,
legend: legend,
title: title,
grid: grid,
arc: arc,
circles: circles,
bar: {
bars: bars
},
candlestick: candlestick,
line: {
lines: lines,
areas: areas
},
needle: needle,
text: {
texts: texts
}
};
}
/**
* Set background element/image
* @private
*/;
_proto.setBackground = function setBackground() {
const $$ = this,
bg = $$.config.background,
state = $$.state,
svg = $$.$el.svg;
if (notEmpty(bg)) {
const element = svg.select("g").insert(bg.imgUrl ? "image" : "rect", ":first-child");
if (bg.imgUrl) {
element.attr("href", bg.imgUrl);
} else if (bg.color) {
element.style("fill", bg.color).attr("clip-path", state.clip.path);
}
element.attr("class", bg.class || null).attr("width", "100%").attr("height", "100%");
}
}
/**
* Update targeted element with given data
* @param {object} targets Data object formatted as 'target'
* @private
*/;
_proto.updateTargets = function updateTargets(targets) {
var _this6 = this;
const $$ = this,
_$$$state2 = $$.state,
hasAxis = _$$$state2.hasAxis,
hasRadar = _$$$state2.hasRadar,
hasTreemap = _$$$state2.hasTreemap,
helper = function (type) {
_newArrowCheck(this, _this6);
return $$["updateTargetsFor" + type](targets.filter($$["is" + type + "Type"].bind($$)));
}.bind(this);
// Text
$$.updateTargetsForText(targets);
if (hasAxis) {
["bar", "candlestick", "line"].forEach(function (v) {
_newArrowCheck(this, _this6);
const name = capitalize(v);
if (v === "line" && $$.hasTypeOf(name) || $$.hasType(v)) {
helper(name);
}
}.bind(this));
// Sub Chart
$$.updateTargetsForSubchart && $$.updateTargetsForSubchart(targets);
// Arc, Polar, Radar
} else if ($$.hasArcType(targets)) {
let type = "Arc";
if (hasRadar) {
type = "Radar";
} else if ($$.hasType("polar")) {
type = "Polar";
}
helper(type);
// Arc, Polar, Radar
} else if (hasTreemap) {
helper("Treemap");
}
// Point types
const hasPointType = $$.hasType("bubble") || $$.hasType("scatter");
if (hasPointType) {
$$.updateTargetForCircle == null || $$.updateTargetForCircle();
}
// Fade-in each chart
$$.filterTargetsToShowAtInit(hasPointType);
}
/**
* Display targeted elements at initialization
* @param {boolean} hasPointType whether has point type(bubble, scatter) or not
* @private
*/;
_proto.filterTargetsToShowAtInit = function filterTargetsToShowAtInit(hasPointType) {
var _this7 = this;
if (hasPointType === void 0) {
hasPointType = !1;
}
const $$ = this,
svg = $$.$el.svg,
$T = $$.$T;
let selector = "." + $COMMON.target;
if (hasPointType) {
selector += ", ." + $CIRCLE.chartCircles + " > ." + $CIRCLE.circles;
}
$T(svg.selectAll(selector).filter(function (d) {
_newArrowCheck(this, _this7);
return $$.isTargetToShow(d.id);
}.bind(this))).style("opacity", null);
};
_proto.getWithOption = function getWithOption(options) {
var _this8 = this;
const withOptions = {
Dimension: !0,
EventRect: !0,
Legend: !1,
Subchart: !0,
Transform: !1,
Transition: !0,
TrimXDomain: !0,
UpdateXAxis: "UpdateXDomain",
UpdateXDomain: !1,
UpdateOrgXDomain: !1,
TransitionForExit: "Transition",
TransitionForAxis: "Transition",
Y: !0
};
Object.keys(withOptions).forEach(function (key) {
_newArrowCheck(this, _this8);
let defVal = withOptions[key];
if (isString(defVal)) {
defVal = withOptions[defVal];
}
withOptions[key] = getOption(options, "with" + key, defVal);
}.bind(this));
return withOptions;
};
_proto.initialOpacity = function initialOpacity(d) {
const $$ = this,
withoutFadeIn = $$.state.withoutFadeIn,
r = $$.getBaseValue(d) !== null && withoutFadeIn[d.id] ? null : "0";
return r;
};
_proto.bindResize = function bindResize() {
var _this9 = this;
const $$ = this,
config = $$.config,
state = $$.state,
resizeFunction = generateResize(config.resize_timer),
list = [];
list.push(function () {
_newArrowCheck(this, _this9);
return callFn(config.onresize, $$.api);
}.bind(this));
if (config.resize_auto) {
list.push(function () {
_newArrowCheck(this, _this9);
state.resizing = !0;
// https://github.com/naver/billboard.js/issues/2650
if (config.legend_show) {
$$.updateSizes();
$$.updateLegend();
}
$$.api.flush(!1);
}.bind(this));
}
list.push(function () {
_newArrowCheck(this, _this9);
callFn(config.onresized, $$.api);
state.resizing = !1;
}.bind(this));
// add resize functions
list.forEach(function (v) {
_newArrowCheck(this, _this9);
return resizeFunction.add(v);
}.bind(this));
$$.resizeFunction = resizeFunction;
// attach resize event
win.addEventListener("resize", $$.resizeFunction = resizeFunction);
}
/**
* Call plugin hook
* @param {string} phase The lifecycle phase
* @param {Array} args Arguments
* @private
*/;
_proto.callPluginHook = function callPluginHook(phase) {
for (var _this10 = this, _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
this.config.plugins.forEach(function (v) {
_newArrowCheck(this, _this10);
if (phase === "$beforeInit") {
v.$$ = this;
this.api.plugins.push(v);
}
v[phase].apply(v, args);
}.bind(this));
};
return ChartInternal;
}();
util_extend(ChartInternal.prototype, [
// common
convert, ChartInternal_data_data, load, category, internals_class, internals_color, domain, interactions_interaction, format, internals_legend, redraw, scale, shape, internals_size, internals_style, internals_text, internals_title, internals_tooltip, transform, internals_type]);
;// CONCATENATED MODULE: ./src/config/config.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Load configuration option
* @param {object} config User's generation config value
* @private
*/
function loadConfig(config) {
var _this = this;
const thisConfig = this.config;
let target, keys, read;
const _find = function find() {
_newArrowCheck(this, _this);
const key = keys.shift();
if (key && target && isObjectType(target) && key in target) {
target = target[key];
return _find();
} else if (!key) {
return target;
}
return undefined;
}.bind(this);
Object.keys(thisConfig).forEach(function (key) {
_newArrowCheck(this, _this);
target = config;
keys = key.split("_");
read = _find();
if (isDefined(read)) {
thisConfig[key] = read;
}
}.bind(this));
// only should run in the ChartInternal context
if (this.api) {
this.state.orgConfig = config;
}
}
;// CONCATENATED MODULE: ./src/Chart/api/chart.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* harmony default export */ var chart = ({
/**
* Resize the chart.
* @function resize
* @instance
* @memberof Chart
* @param {object} size This argument should include width and height in pixels.
* @param {number} [size.width] width value
* @param {number} [size.height] height value
* @example
* // Resize to 640x480
* chart.resize({
* width: 640,
* height: 480
* });
*/
resize: function resize(size) {
const $$ = this.internal,
config = $$.config,
state = $$.state;
if (state.rendered) {
config.size_width = size ? size.width : null;
config.size_height = size ? size.height : null;
state.resizing = !0;
this.flush(!1);
$$.resizeFunction();
}
},
/**
* Force to redraw.
* - **NOTE:** When zoom/subchart is used, the zoomed state will be resetted.
* @function flush
* @instance
* @memberof Chart
* @param {boolean} [soft] For soft redraw.
* @example
* chart.flush();
*
* // for soft redraw
* chart.flush(true);
*/
flush: function flush(soft) {
const $$ = this.internal,
state = $$.state,
zoomResetBtn = $$.$el.zoomResetBtn;
if (state.rendered) {
// reset possible zoom scale when is called from resize event
// eslint-disable-next-line prefer-rest-params
if (state.resizing) {
var _$$$brush;
// arguments[1] is given when is called from resize
(_$$$brush = $$.brush) == null || _$$$brush.updateResize();
} else {
var _$$$axis;
// re-update config info
(_$$$axis = $$.axis) == null || _$$$axis.setOrient();
}
// hide possible reset zoom button
// https://github.com/naver/billboard.js/issues/2201
zoomResetBtn == null || zoomResetBtn.style("display", "none");
$$.scale.zoom = null;
soft ? $$.redraw({
withTransform: !0,
withUpdateXDomain: !0,
withUpdateOrgXDomain: !0,
withLegend: !0
}) : $$.updateAndRedraw({
withLegend: !0,
withTransition: !1,
withTransitionForTransform: !1
});
// reset subchart selection & selection state
if (!state.resizing && $$.brush) {
$$.brush.getSelection().call($$.brush.move);
$$.unselectRect();
}
} else {
$$.initToRender(!0);
}
},
/**
* Reset the chart object and remove element and events completely.
* @function destroy
* @instance
* @memberof Chart
* @returns {null}
* @example
* chart.destroy();
*/
destroy: function destroy() {
var _this = this;
const $$ = this.internal,
_$$$$el = $$.$el,
chart = _$$$$el.chart,
style = _$$$$el.style,
svg = _$$$$el.svg;
if (notEmpty($$)) {
$$.callPluginHook("$willDestroy");
$$.charts.splice($$.charts.indexOf(this), 1);
// detach events
$$.unbindAllEvents();
// clear timers && pending transition
svg.select("*").interrupt();
$$.resizeFunction.clear();
win.removeEventListener("resize", $$.resizeFunction);
chart.classed("bb", !1).style("position", null).selectChildren().remove();
// remove