(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-scale'), require('d3-time'), require('d3-random'), require('d3-fetch'), require('d3-path'), require('d3-selection'), require('d3-shape'), require('d3-dispatch'), require('d3-brush')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-scale', 'd3-time', 'd3-random', 'd3-fetch', 'd3-path', 'd3-selection', 'd3-shape', 'd3-dispatch', 'd3-brush'], factory) :
(factory((global.fc = global.fc || {}),global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3));
}(this, (function (exports,d3Array,d3Scale,d3Time,d3Random,d3Fetch,d3Path,d3Selection,d3Shape,d3Dispatch,d3Brush) { 'use strict';
var createReboundMethod = (function (target, source, name) {
var method = source[name];
if (typeof method !== 'function') {
throw new Error('Attempt to rebind ' + name + ' which isn\'t a function on the source object');
}
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var value = method.apply(source, args);
return value === source ? target : value;
};
});
var rebind = (function (target, source) {
for (var _len = arguments.length, names = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
names[_key - 2] = arguments[_key];
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = names[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var name = _step.value;
target[name] = createReboundMethod(target, source, name);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return target;
});
var createTransform = function createTransform(transforms) {
return function (name) {
return transforms.reduce(function (name, fn) {
return name && fn(name);
}, name);
};
};
var rebindAll = (function (target, source) {
for (var _len = arguments.length, transforms = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
transforms[_key - 2] = arguments[_key];
}
var transform = createTransform(transforms);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = Object.keys(source)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var name = _step.value;
var result = transform(name);
if (result) {
target[result] = createReboundMethod(target, source, name);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return target;
});
var regexify = (function (strsOrRegexes) {
return strsOrRegexes.map(function (strOrRegex) {
return typeof strOrRegex === 'string' ? new RegExp('^' + strOrRegex + '$') : strOrRegex;
});
});
var exclude = (function () {
for (var _len = arguments.length, exclusions = Array(_len), _key = 0; _key < _len; _key++) {
exclusions[_key] = arguments[_key];
}
exclusions = regexify(exclusions);
return function (name) {
return exclusions.every(function (exclusion) {
return !exclusion.test(name);
}) && name;
};
});
var include = (function () {
for (var _len = arguments.length, inclusions = Array(_len), _key = 0; _key < _len; _key++) {
inclusions[_key] = arguments[_key];
}
inclusions = regexify(inclusions);
return function (name) {
return inclusions.some(function (inclusion) {
return inclusion.test(name);
}) && name;
};
});
var includeMap = (function (mappings) {
return function (name) {
return mappings[name];
};
});
var capitalizeFirstLetter = function capitalizeFirstLetter(str) {
return str[0].toUpperCase() + str.slice(1);
};
var prefix = (function (prefix) {
return function (name) {
return prefix + capitalizeFirstLetter(name);
};
});
function identity(d) {
return d;
}
function noop(d) {}
function functor(v) {
return typeof v === 'function' ? v : function () {
return v;
};
}
function convertNaN(value) {
return typeof value === 'number' && isNaN(value) ? undefined : value;
}
var _slidingWindow = function () {
var period = function period() {
return 10;
};
var accumulator = noop;
var value = identity;
var defined = function defined(d) {
return d != null;
};
var slidingWindow = function slidingWindow(data) {
var size = period.apply(this, arguments);
var windowData = data.slice(0, size).map(value);
return data.map(function (d, i) {
if (i >= size) {
// Treat windowData as FIFO rolling buffer
windowData.shift();
windowData.push(value(d, i));
}
if (i < size - 1 || windowData.some(function (d) {
return !defined(d);
})) {
return accumulator(undefined, i);
}
return accumulator(windowData, i);
});
};
slidingWindow.period = function () {
if (!arguments.length) {
return period;
}
period = functor(arguments.length <= 0 ? undefined : arguments[0]);
return slidingWindow;
};
slidingWindow.accumulator = function () {
if (!arguments.length) {
return accumulator;
}
accumulator = arguments.length <= 0 ? undefined : arguments[0];
return slidingWindow;
};
slidingWindow.defined = function () {
if (!arguments.length) {
return defined;
}
defined = arguments.length <= 0 ? undefined : arguments[0];
return slidingWindow;
};
slidingWindow.value = function () {
if (!arguments.length) {
return value;
}
value = arguments.length <= 0 ? undefined : arguments[0];
return slidingWindow;
};
return slidingWindow;
};
var bollingerBands = function () {
var multiplier = 2;
var slidingWindow = _slidingWindow().accumulator(function (values) {
var stdDev = values && d3Array.deviation(values);
var average = values && d3Array.mean(values);
return {
average: average,
upper: convertNaN(average + multiplier * stdDev),
lower: convertNaN(average - multiplier * stdDev)
};
});
var bollingerBands = function bollingerBands(data) {
return slidingWindow(data);
};
bollingerBands.multiplier = function () {
if (!arguments.length) {
return multiplier;
}
multiplier = arguments.length <= 0 ? undefined : arguments[0];
return bollingerBands;
};
rebind(bollingerBands, slidingWindow, 'period', 'value');
return bollingerBands;
};
var exponentialMovingAverage = function () {
var value = identity;
var period = function period() {
return 9;
};
var initialMovingAverageAccumulator = function initialMovingAverageAccumulator(period) {
var values = [];
return function (value) {
var movingAverage = void 0;
if (values.length < period) {
if (value != null) {
values.push(value);
} else {
values = [];
}
}
if (values.length >= period) {
movingAverage = d3Array.mean(values);
}
return movingAverage;
};
};
var exponentialMovingAverage = function exponentialMovingAverage(data) {
var size = period.apply(this, arguments);
var alpha = 2 / (size + 1);
var initialAccumulator = initialMovingAverageAccumulator(size);
var ema = void 0;
return data.map(function (d, i) {
var v = value(d, i);
if (ema === undefined) {
ema = initialAccumulator(v);
} else {
ema = v * alpha + (1 - alpha) * ema;
}
return convertNaN(ema);
});
};
exponentialMovingAverage.period = function () {
if (!arguments.length) {
return period;
}
period = functor(arguments.length <= 0 ? undefined : arguments[0]);
return exponentialMovingAverage;
};
exponentialMovingAverage.value = function () {
if (!arguments.length) {
return value;
}
value = arguments.length <= 0 ? undefined : arguments[0];
return exponentialMovingAverage;
};
return exponentialMovingAverage;
};
var macd = function () {
var value = identity;
var fastEMA = exponentialMovingAverage().period(12);
var slowEMA = exponentialMovingAverage().period(26);
var signalEMA = exponentialMovingAverage().period(9);
var macd = function macd(data) {
fastEMA.value(value);
slowEMA.value(value);
var diff = d3Array.zip(fastEMA(data), slowEMA(data)).map(function (d) {
return d[0] !== undefined && d[1] !== undefined ? d[0] - d[1] : undefined;
});
var averageDiff = signalEMA(diff);
return d3Array.zip(diff, averageDiff).map(function (d) {
return {
macd: d[0],
signal: d[1],
divergence: d[0] !== undefined && d[1] !== undefined ? d[0] - d[1] : undefined
};
});
};
macd.value = function () {
if (!arguments.length) {
return value;
}
value = arguments.length <= 0 ? undefined : arguments[0];
return macd;
};
rebindAll(macd, fastEMA, includeMap({ 'period': 'fastPeriod' }));
rebindAll(macd, slowEMA, includeMap({ 'period': 'slowPeriod' }));
rebindAll(macd, signalEMA, includeMap({ 'period': 'signalPeriod' }));
return macd;
};
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var toArray = function (arr) {
return Array.isArray(arr) ? arr : Array.from(arr);
};
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
var relativeStrengthIndex = function () {
var slidingWindow = _slidingWindow().period(14);
var wildersSmoothing = function wildersSmoothing(values, prevAvg) {
return prevAvg + (values[values.length - 1] - prevAvg) / values.length;
};
var downChange = function downChange(_ref) {
var _ref2 = slicedToArray(_ref, 2),
prevClose = _ref2[0],
close = _ref2[1];
return prevClose < close ? 0 : prevClose - close;
};
var upChange = function upChange(_ref3) {
var _ref4 = slicedToArray(_ref3, 2),
prevClose = _ref4[0],
close = _ref4[1];
return prevClose > close ? 0 : close - prevClose;
};
var updateAverage = function updateAverage(changes, prevAverage) {
return prevAverage !== undefined ? wildersSmoothing(changes, prevAverage) : d3Array.mean(changes);
};
var makeAccumulator = function makeAccumulator() {
var prevClose = void 0;
var downChangesAvg = void 0;
var upChangesAvg = void 0;
return function (closes) {
if (!closes) {
if (prevClose !== undefined) {
prevClose = NaN;
}
return undefined;
}
if (prevClose === undefined) {
prevClose = closes[0];
return undefined;
}
var closePairs = d3Array.pairs([prevClose].concat(toConsumableArray(closes)));
downChangesAvg = updateAverage(closePairs.map(downChange), downChangesAvg);
upChangesAvg = updateAverage(closePairs.map(upChange), upChangesAvg);
var rs = !isNaN(prevClose) ? upChangesAvg / downChangesAvg : NaN;
return convertNaN(100 - 100 / (1 + rs));
};
};
var rsi = function rsi(data) {
var rsiAccumulator = makeAccumulator();
slidingWindow.accumulator(rsiAccumulator);
return slidingWindow(data);
};
rebind(rsi, slidingWindow, 'period', 'value');
return rsi;
};
var movingAverage = function () {
var slidingWindow = _slidingWindow().accumulator(function (values) {
return values && d3Array.mean(values);
});
var movingAverage = function movingAverage(data) {
return slidingWindow(data);
};
rebind(movingAverage, slidingWindow, 'period', 'value');
return movingAverage;
};
var stochasticOscillator = function () {
var closeValue = function closeValue(d, i) {
return d.close;
};
var highValue = function highValue(d, i) {
return d.high;
};
var lowValue = function lowValue(d, i) {
return d.low;
};
var kWindow = _slidingWindow().period(5).defined(function (d) {
return closeValue(d) != null && highValue(d) != null && lowValue(d) != null;
}).accumulator(function (values) {
var maxHigh = values && d3Array.max(values, highValue);
var minLow = values && d3Array.min(values, lowValue);
var kValue = values && 100 * (closeValue(values[values.length - 1]) - minLow) / (maxHigh - minLow);
return convertNaN(kValue);
});
var dWindow = movingAverage().period(3);
var stochastic = function stochastic(data) {
var kValues = kWindow(data);
var dValues = dWindow(kValues);
return kValues.map(function (k, i) {
return { k: k, d: dValues[i] };
});
};
stochastic.closeValue = function () {
if (!arguments.length) {
return closeValue;
}
closeValue = arguments.length <= 0 ? undefined : arguments[0];
return stochastic;
};
stochastic.highValue = function () {
if (!arguments.length) {
return highValue;
}
highValue = arguments.length <= 0 ? undefined : arguments[0];
return stochastic;
};
stochastic.lowValue = function () {
if (!arguments.length) {
return lowValue;
}
lowValue = arguments.length <= 0 ? undefined : arguments[0];
return stochastic;
};
rebindAll(stochastic, kWindow, includeMap({ 'period': 'kPeriod' }));
rebindAll(stochastic, dWindow, includeMap({ 'period': 'dPeriod' }));
return stochastic;
};
var forceIndex = function () {
var volumeValue = function volumeValue(d, i) {
return d.volume;
};
var closeValue = function closeValue(d, i) {
return d.close;
};
var emaComputer = exponentialMovingAverage().period(13);
var slidingWindow = _slidingWindow().period(2).defined(function (d) {
return closeValue(d) != null && volumeValue(d) != null;
}).accumulator(function (values) {
return values && convertNaN((closeValue(values[1]) - closeValue(values[0])) * volumeValue(values[1]));
});
var force = function force(data) {
var forceIndex = slidingWindow(data);
return emaComputer(forceIndex);
};
force.volumeValue = function () {
if (!arguments.length) {
return volumeValue;
}
volumeValue = arguments.length <= 0 ? undefined : arguments[0];
return force;
};
force.closeValue = function () {
if (!arguments.length) {
return closeValue;
}
closeValue = arguments.length <= 0 ? undefined : arguments[0];
return force;
};
rebind(force, emaComputer, 'period');
return force;
};
var envelope = function () {
var factor = 0.1;
var value = identity;
var envelope = function envelope(data) {
return data.map(function (d) {
var lower = convertNaN(value(d) * (1.0 - factor));
var upper = convertNaN(value(d) * (1.0 + factor));
return { lower: lower, upper: upper };
});
};
envelope.factor = function () {
if (!arguments.length) {
return factor;
}
factor = arguments.length <= 0 ? undefined : arguments[0];
return envelope;
};
envelope.value = function () {
if (!arguments.length) {
return value;
}
value = arguments.length <= 0 ? undefined : arguments[0];
return envelope;
};
return envelope;
};
var elderRay = function () {
var closeValue = function closeValue(d, i) {
return d.close;
};
var highValue = function highValue(d, i) {
return d.high;
};
var lowValue = function lowValue(d, i) {
return d.low;
};
var emaComputer = exponentialMovingAverage().period(13);
var elderRay = function elderRay(data) {
emaComputer.value(closeValue);
return d3Array.zip(data, emaComputer(data)).map(function (d) {
var bullPower = convertNaN(highValue(d[0]) - d[1]);
var bearPower = convertNaN(lowValue(d[0]) - d[1]);
return { bullPower: bullPower, bearPower: bearPower };
});
};
elderRay.closeValue = function () {
if (!arguments.length) {
return closeValue;
}
closeValue = arguments.length <= 0 ? undefined : arguments[0];
return elderRay;
};
elderRay.highValue = function () {
if (!arguments.length) {
return highValue;
}
highValue = arguments.length <= 0 ? undefined : arguments[0];
return elderRay;
};
elderRay.lowValue = function () {
if (!arguments.length) {
return lowValue;
}
lowValue = arguments.length <= 0 ? undefined : arguments[0];
return elderRay;
};
rebind(elderRay, emaComputer, 'period');
return elderRay;
};
var identity$1 = function () {
var identity = {};
identity.distance = function (start, end) {
return end - start;
};
identity.offset = function (start, offset) {
return start instanceof Date ? new Date(start.getTime() + offset) : start + offset;
};
identity.clampUp = function (d) {
return d;
};
identity.clampDown = function (d) {
return d;
};
identity.copy = function () {
return identity;
};
return identity;
};
function tickFilter(ticks, discontinuityProvider) {
var discontinuousTicks = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = ticks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var tick = _step.value;
var up = discontinuityProvider.clampUp(tick);
var down = discontinuityProvider.clampDown(tick);
if (up === down) {
discontinuousTicks.push(up);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return discontinuousTicks;
}
function discontinuous(adaptedScale) {
var _this = this;
if (!arguments.length) {
adaptedScale = d3Scale.scaleIdentity();
}
var discontinuityProvider = identity$1();
var scale = function scale(value) {
var domain = adaptedScale.domain();
var range$$1 = adaptedScale.range();
// The discontinuityProvider is responsible for determine the distance between two points
// along a scale that has discontinuities (i.e. sections that have been removed).
// the scale for the given point 'x' is calculated as the ratio of the discontinuous distance
// over the domain of this axis, versus the discontinuous distance to 'x'
var totalDomainDistance = discontinuityProvider.distance(domain[0], domain[1]);
var distanceToX = discontinuityProvider.distance(domain[0], value);
var ratioToX = distanceToX / totalDomainDistance;
var scaledByRange = ratioToX * (range$$1[1] - range$$1[0]) + range$$1[0];
return scaledByRange;
};
scale.invert = function (x) {
var domain = adaptedScale.domain();
var range$$1 = adaptedScale.range();
var ratioToX = (x - range$$1[0]) / (range$$1[1] - range$$1[0]);
var totalDomainDistance = discontinuityProvider.distance(domain[0], domain[1]);
var distanceToX = ratioToX * totalDomainDistance;
return discontinuityProvider.offset(domain[0], distanceToX);
};
scale.domain = function () {
if (!arguments.length) {
return adaptedScale.domain();
}
var newDomain = arguments.length <= 0 ? undefined : arguments[0];
// clamp the upper and lower domain values to ensure they
// do not fall within a discontinuity
var domainLower = discontinuityProvider.clampUp(newDomain[0]);
var domainUpper = discontinuityProvider.clampDown(newDomain[1]);
adaptedScale.domain([domainLower, domainUpper]);
return scale;
};
scale.nice = function () {
adaptedScale.nice();
var domain = adaptedScale.domain();
var domainLower = discontinuityProvider.clampUp(domain[0]);
var domainUpper = discontinuityProvider.clampDown(domain[1]);
adaptedScale.domain([domainLower, domainUpper]);
return scale;
};
scale.ticks = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var ticks = adaptedScale.ticks.apply(_this, args);
return tickFilter(ticks, discontinuityProvider);
};
scale.copy = function () {
return discontinuous(adaptedScale.copy()).discontinuityProvider(discontinuityProvider.copy());
};
scale.discontinuityProvider = function () {
if (!arguments.length) {
return discontinuityProvider;
}
discontinuityProvider = arguments.length <= 0 ? undefined : arguments[0];
return scale;
};
rebindAll(scale, adaptedScale, include('range', 'rangeRound', 'interpolate', 'clamp', 'tickFormat'));
return scale;
}
var skipWeekends = function () {
// the indices returned by date.getDay()
var day = {
sunday: 0,
monday: 1,
saturday: 6
};
var millisPerDay = 24 * 3600 * 1000;
var millisPerWorkWeek = millisPerDay * 5;
var millisPerWeek = millisPerDay * 7;
var skipWeekends = {};
var isWeekend = function isWeekend(date) {
return date.getDay() === 0 || date.getDay() === 6;
};
skipWeekends.clampDown = function (date) {
if (date && isWeekend(date)) {
// round the date up to midnight
var newDate = d3Time.timeDay.ceil(date);
// then subtract the required number of days
if (newDate.getDay() === day.sunday) {
return d3Time.timeDay.offset(newDate, -1);
} else if (newDate.getDay() === day.monday) {
return d3Time.timeDay.offset(newDate, -2);
} else {
return newDate;
}
} else {
return date;
}
};
skipWeekends.clampUp = function (date) {
if (date && isWeekend(date)) {
// round the date down to midnight
var newDate = d3Time.timeDay.floor(date);
// then add the required number of days
if (newDate.getDay() === day.saturday) {
return d3Time.timeDay.offset(newDate, 2);
} else if (newDate.getDay() === day.sunday) {
return d3Time.timeDay.offset(newDate, 1);
} else {
return newDate;
}
} else {
return date;
}
};
// returns the number of included milliseconds (i.e. those which do not fall)
// within discontinuities, along this scale
skipWeekends.distance = function (startDate, endDate) {
startDate = skipWeekends.clampUp(startDate);
endDate = skipWeekends.clampDown(endDate);
// move the start date to the end of week boundary
var offsetStart = d3Time.timeSaturday.ceil(startDate);
if (endDate < offsetStart) {
return endDate.getTime() - startDate.getTime();
}
var msAdded = offsetStart.getTime() - startDate.getTime();
// move the end date to the end of week boundary
var offsetEnd = d3Time.timeSaturday.ceil(endDate);
var msRemoved = offsetEnd.getTime() - endDate.getTime();
// determine how many weeks there are between these two dates
// round to account for DST transitions
var weeks = Math.round((offsetEnd.getTime() - offsetStart.getTime()) / millisPerWeek);
return weeks * millisPerWorkWeek + msAdded - msRemoved;
};
skipWeekends.offset = function (startDate, ms) {
var date = isWeekend(startDate) ? skipWeekends.clampUp(startDate) : startDate;
if (ms === 0) {
return date;
}
var isNegativeOffset = ms < 0;
var isPositiveOffset = ms > 0;
var remainingms = ms;
// move to the end of week boundary for a postive offset or to the start of a week for a negative offset
var weekBoundary = isNegativeOffset ? d3Time.timeMonday.floor(date) : d3Time.timeSaturday.ceil(date);
remainingms -= weekBoundary.getTime() - date.getTime();
// if the distance to the boundary is greater than the number of ms
// simply add the ms to the current date
if (isNegativeOffset && remainingms > 0 || isPositiveOffset && remainingms < 0) {
return new Date(date.getTime() + ms);
}
// skip the weekend for a positive offset
date = isNegativeOffset ? weekBoundary : d3Time.timeDay.offset(weekBoundary, 2);
// add all of the complete weeks to the date
var completeWeeks = Math.floor(remainingms / millisPerWorkWeek);
date = d3Time.timeDay.offset(date, completeWeeks * 7);
remainingms -= completeWeeks * millisPerWorkWeek;
// add the remaining time
date = new Date(date.getTime() + remainingms);
return date;
};
skipWeekends.copy = function () {
return skipWeekends;
};
return skipWeekends;
};
var provider = function provider() {
for (var _len = arguments.length, ranges = Array(_len), _key = 0; _key < _len; _key++) {
ranges[_key] = arguments[_key];
}
var inRange = function inRange(number, range$$1) {
return number > range$$1[0] && number < range$$1[1];
};
var surroundsRange = function surroundsRange(inner, outer) {
return inner[0] >= outer[0] && inner[1] <= outer[1];
};
var identity = {};
identity.distance = function (start, end) {
start = identity.clampUp(start);
end = identity.clampDown(end);
var surroundedRanges = ranges.filter(function (r) {
return surroundsRange(r, [start, end]);
});
var rangeSizes = surroundedRanges.map(function (r) {
return r[1] - r[0];
});
return end - start - rangeSizes.reduce(function (total, current) {
return total + current;
}, 0);
};
var add = function add(value, offset) {
return value instanceof Date ? new Date(value.getTime() + offset) : value + offset;
};
identity.offset = function (location, offset) {
if (offset > 0) {
var _ret = function () {
var currentLocation = identity.clampUp(location);
var offsetRemaining = offset;
while (offsetRemaining > 0) {
var futureRanges = ranges.filter(function (r) {
return r[0] > currentLocation;
}).sort(function (a, b) {
return a[0] - b[0];
});
if (futureRanges.length) {
var nextRange = futureRanges[0];
var delta = nextRange[0] - currentLocation;
if (delta > offsetRemaining) {
currentLocation = add(currentLocation, offsetRemaining);
offsetRemaining = 0;
} else {
currentLocation = nextRange[1];
offsetRemaining -= delta;
}
} else {
currentLocation = add(currentLocation, offsetRemaining);
offsetRemaining = 0;
}
}
return {
v: currentLocation
};
}();
if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v;
} else {
var _ret2 = function () {
var currentLocation = identity.clampDown(location);
var offsetRemaining = offset;
while (offsetRemaining < 0) {
var futureRanges = ranges.filter(function (r) {
return r[1] < currentLocation;
}).sort(function (a, b) {
return b[0] - a[0];
});
if (futureRanges.length) {
var nextRange = futureRanges[0];
var delta = nextRange[1] - currentLocation;
if (delta < offsetRemaining) {
currentLocation = add(currentLocation, offsetRemaining);
offsetRemaining = 0;
} else {
currentLocation = nextRange[0];
offsetRemaining -= delta;
}
} else {
currentLocation = add(currentLocation, offsetRemaining);
offsetRemaining = 0;
}
}
return {
v: currentLocation
};
}();
if ((typeof _ret2 === "undefined" ? "undefined" : _typeof(_ret2)) === "object") return _ret2.v;
}
};
identity.clampUp = function (d) {
return ranges.reduce(function (value, range$$1) {
return inRange(value, range$$1) ? range$$1[1] : value;
}, d);
};
identity.clampDown = function (d) {
return ranges.reduce(function (value, range$$1) {
return inRange(value, range$$1) ? range$$1[0] : value;
}, d);
};
identity.copy = function () {
return identity;
};
return identity;
};
var linearExtent = function () {
var accessors = [function (d) {
return d;
}];
var pad = [0, 0];
var padUnit = 'percent';
var symmetricalAbout = null;
var include = [];
var instance = function instance(data) {
var values = new Array(data.length);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = accessors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var accessor = _step.value;
for (var i = 0; i < data.length; i++) {
var value = accessor(data[i], i);
if (Array.isArray(value)) {
values.push.apply(values, toConsumableArray(value));
} else {
values.push(value);
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var extent$$1 = [d3Array.min(values), d3Array.max(values)];
extent$$1[0] = extent$$1[0] == null ? d3Array.min(include) : d3Array.min([extent$$1[0]].concat(toConsumableArray(include)));
extent$$1[1] = extent$$1[1] == null ? d3Array.max(include) : d3Array.max([extent$$1[1]].concat(toConsumableArray(include)));
if (symmetricalAbout != null) {
var halfRange = Math.max(Math.abs(extent$$1[1] - symmetricalAbout), Math.abs(extent$$1[0] - symmetricalAbout));
extent$$1[0] = symmetricalAbout - halfRange;
extent$$1[1] = symmetricalAbout + halfRange;
}
switch (padUnit) {
case 'domain':
{
extent$$1[0] -= pad[0];
extent$$1[1] += pad[1];
break;
}
case 'percent':
{
var delta = extent$$1[1] - extent$$1[0];
extent$$1[0] -= pad[0] * delta;
extent$$1[1] += pad[1] * delta;
break;
}
default:
throw new Error('Unknown padUnit: ' + padUnit);
}
return extent$$1;
};
instance.accessors = function () {
if (!arguments.length) {
return accessors;
}
accessors = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.pad = function () {
if (!arguments.length) {
return pad;
}
pad = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.padUnit = function () {
if (!arguments.length) {
return padUnit;
}
padUnit = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.include = function () {
if (!arguments.length) {
return include;
}
include = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.symmetricalAbout = function () {
if (!arguments.length) {
return symmetricalAbout;
}
symmetricalAbout = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
return instance;
};
var time = function () {
var accessors = [];
var pad = [0, 0];
var padUnit = 'percent';
var symmetricalAbout = null;
var include = [];
var extent$$1 = linearExtent();
var valueOf = function valueOf(date) {
return date != null ? date.valueOf() : null;
};
var instance = function instance(data) {
var adaptedAccessors = accessors.map(function (accessor) {
return function () {
var value = accessor.apply(undefined, arguments);
return Array.isArray(value) ? value.map(valueOf) : valueOf(value);
};
});
extent$$1.accessors(adaptedAccessors).pad(pad).padUnit(padUnit).symmetricalAbout(symmetricalAbout != null ? symmetricalAbout.valueOf() : null).include(include.map(function (date) {
return date.valueOf();
}));
return extent$$1(data).map(function (value) {
return new Date(value);
});
};
instance.accessors = function () {
if (!arguments.length) {
return accessors;
}
accessors = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.pad = function () {
if (!arguments.length) {
return pad;
}
pad = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.padUnit = function () {
if (!arguments.length) {
return padUnit;
}
padUnit = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.include = function () {
if (!arguments.length) {
return include;
}
include = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.symmetricalAbout = function () {
if (!arguments.length) {
return symmetricalAbout;
}
symmetricalAbout = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
return instance;
};
var geometricBrownianMotion = function () {
var period = 1;
var steps = 20;
var mu = 0.1;
var sigma = 0.1;
var random = d3Random.randomNormal();
var geometricBrownianMotion = function geometricBrownianMotion() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var timeStep = period / steps;
var pathData = [];
for (var i = 0; i < steps + 1; i++) {
pathData.push(value);
var increment = random() * Math.sqrt(timeStep) * sigma + (mu - sigma * sigma / 2) * timeStep;
value = value * Math.exp(increment);
}
return pathData;
};
geometricBrownianMotion.period = function () {
if (!arguments.length) {
return period;
}
period = arguments.length <= 0 ? undefined : arguments[0];
return geometricBrownianMotion;
};
geometricBrownianMotion.steps = function () {
if (!arguments.length) {
return steps;
}
steps = arguments.length <= 0 ? undefined : arguments[0];
return geometricBrownianMotion;
};
geometricBrownianMotion.mu = function () {
if (!arguments.length) {
return mu;
}
mu = arguments.length <= 0 ? undefined : arguments[0];
return geometricBrownianMotion;
};
geometricBrownianMotion.sigma = function () {
if (!arguments.length) {
return sigma;
}
sigma = arguments.length <= 0 ? undefined : arguments[0];
return geometricBrownianMotion;
};
geometricBrownianMotion.random = function () {
if (!arguments.length) {
return random;
}
random = arguments.length <= 0 ? undefined : arguments[0];
return geometricBrownianMotion;
};
return geometricBrownianMotion;
};
function functor$1(v) {
return typeof v === 'function' ? v : function () {
return v;
};
}
var financial = function () {
var startDate = new Date();
var startPrice = 100;
var interval = d3Time.timeDay;
var intervalStep = 1;
var unitInterval = d3Time.timeYear;
var unitIntervalStep = 1;
var filter = null;
var volume = function volume() {
var normal = d3Random.randomNormal(1, 0.1);
return Math.ceil(normal() * 1000);
};
var gbm = geometricBrownianMotion();
var getOffsetPeriod = function getOffsetPeriod(date) {
var unitMilliseconds = unitInterval.offset(date, unitIntervalStep) - date;
return (interval.offset(date, intervalStep) - date) / unitMilliseconds;
};
var calculateOHLC = function calculateOHLC(start, price) {
var period = getOffsetPeriod(start);
var prices = gbm.period(period)(price);
var ohlc = {
date: start,
open: prices[0],
high: Math.max.apply(Math, prices),
low: Math.min.apply(Math, prices),
close: prices[gbm.steps()]
};
ohlc.volume = volume(ohlc);
return ohlc;
};
var getNextDatum = function getNextDatum(ohlc) {
var date = void 0,
price = void 0,
filtered = void 0;
do {
date = ohlc ? interval.offset(ohlc.date, intervalStep) : new Date(startDate.getTime());
price = ohlc ? ohlc.close : startPrice;
ohlc = calculateOHLC(date, price);
filtered = filter && !filter(ohlc);
} while (filtered);
return ohlc;
};
var makeStream = function makeStream() {
var latest = void 0;
var stream = {};
stream.next = function () {
var ohlc = getNextDatum(latest);
latest = ohlc;
return ohlc;
};
stream.take = function (numPoints) {
return stream.until(function (d, i) {
return !numPoints || numPoints < 0 || i === numPoints;
});
};
stream.until = function (comparison) {
var data = [];
var index = 0;
var ohlc = getNextDatum(latest);
var compared = comparison && !comparison(ohlc, index);
while (compared) {
data.push(ohlc);
latest = ohlc;
ohlc = getNextDatum(latest);
index += 1;
compared = comparison && !comparison(ohlc, index);
}
return data;
};
return stream;
};
var financial = function financial(numPoints) {
return makeStream().take(numPoints);
};
financial.stream = makeStream;
if (typeof Symbol !== 'function' || _typeof(Symbol.iterator) !== 'symbol') {
throw new Error('d3fc-random-data depends on Symbol. Make sure that you load a polyfill in older browsers. See README.');
}
financial[Symbol.iterator] = function () {
var stream = makeStream();
return {
next: function next() {
return {
value: stream.next(),
done: false
};
}
};
};
financial.startDate = function () {
if (!arguments.length) {
return startDate;
}
startDate = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.startPrice = function () {
if (!arguments.length) {
return startPrice;
}
startPrice = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.interval = function () {
if (!arguments.length) {
return interval;
}
interval = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.intervalStep = function () {
if (!arguments.length) {
return intervalStep;
}
intervalStep = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.unitInterval = function () {
if (!arguments.length) {
return unitInterval;
}
unitInterval = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.unitIntervalStep = function () {
if (!arguments.length) {
return unitIntervalStep;
}
unitIntervalStep = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.filter = function () {
if (!arguments.length) {
return filter;
}
filter = arguments.length <= 0 ? undefined : arguments[0];
return financial;
};
financial.volume = function () {
if (!arguments.length) {
return volume;
}
volume = functor$1(arguments.length <= 0 ? undefined : arguments[0]);
return financial;
};
rebindAll(financial, gbm);
return financial;
};
var skipWeekends$1 = function (datum) {
var day = datum.date.getDay();
return !(day === 0 || day === 6);
};
// https://docs.gdax.com/#market-data
var gdax = function () {
var product = 'BTC-USD';
var start = null;
var end = null;
var granularity = null;
var gdax = function gdax() {
var params = [];
if (start != null) {
params.push('start=' + start.toISOString());
}
if (end != null) {
params.push('end=' + end.toISOString());
}
if (granularity != null) {
params.push('granularity=' + granularity);
}
var url = 'https://api.gdax.com/products/' + product + '/candles?' + params.join('&');
return d3Fetch.json(url).then(function (data) {
return data.map(function (d) {
return {
date: new Date(d[0] * 1000),
open: d[3],
high: d[2],
low: d[1],
close: d[4],
volume: d[5]
};
});
});
};
gdax.product = function (x) {
if (!arguments.length) {
return product;
}
product = x;
return gdax;
};
gdax.start = function (x) {
if (!arguments.length) {
return start;
}
start = x;
return gdax;
};
gdax.end = function (x) {
if (!arguments.length) {
return end;
}
end = x;
return gdax;
};
gdax.granularity = function (x) {
if (!arguments.length) {
return granularity;
}
granularity = x;
return gdax;
};
return gdax;
};
var bucket = function () {
var bucketSize = 10;
var bucket = function bucket(data) {
return bucketSize <= 1 ? data.map(function (d) {
return [d];
}) : d3Array.range(0, Math.ceil(data.length / bucketSize)).map(function (i) {
return data.slice(i * bucketSize, (i + 1) * bucketSize);
});
};
bucket.bucketSize = function (x) {
if (!arguments.length) {
return bucketSize;
}
bucketSize = x;
return bucket;
};
return bucket;
};
var largestTriangleOneBucket = function () {
var dataBucketer = bucket();
var x = function x(d) {
return d;
};
var y = function y(d) {
return d;
};
var largestTriangleOneBucket = function largestTriangleOneBucket(data) {
if (dataBucketer.bucketSize() >= data.length) {
return data;
}
var pointAreas = calculateAreaOfPoints(data);
var pointAreaBuckets = dataBucketer(pointAreas);
var buckets = dataBucketer(data.slice(1, data.length - 1));
var subsampledData = buckets.map(function (thisBucket, i) {
var pointAreaBucket = pointAreaBuckets[i];
var maxArea = d3Array.max(pointAreaBucket);
var currentMaxIndex = pointAreaBucket.indexOf(maxArea);
return thisBucket[currentMaxIndex];
});
// First and last data points are their own buckets.
return [].concat([data[0]], subsampledData, [data[data.length - 1]]);
};
function calculateAreaOfPoints(data) {
var xyData = data.map(function (point) {
return [x(point), y(point)];
});
var pointAreas = d3Array.range(1, xyData.length - 1).map(function (i) {
var lastPoint = xyData[i - 1];
var thisPoint = xyData[i];
var nextPoint = xyData[i + 1];
return 0.5 * Math.abs((lastPoint[0] - nextPoint[0]) * (thisPoint[1] - lastPoint[1]) - (lastPoint[0] - thisPoint[0]) * (nextPoint[1] - lastPoint[1]));
});
return pointAreas;
}
rebind(largestTriangleOneBucket, dataBucketer, 'bucketSize');
largestTriangleOneBucket.x = function (d) {
if (!arguments.length) {
return x;
}
x = d;
return largestTriangleOneBucket;
};
largestTriangleOneBucket.y = function (d) {
if (!arguments.length) {
return y;
}
y = d;
return largestTriangleOneBucket;
};
return largestTriangleOneBucket;
};
var largestTriangleThreeBucket = function () {
var x = function x(d) {
return d;
};
var y = function y(d) {
return d;
};
var dataBucketer = bucket();
var largestTriangleThreeBucket = function largestTriangleThreeBucket(data) {
if (dataBucketer.bucketSize() >= data.length) {
return data;
}
var buckets = dataBucketer(data.slice(1, data.length - 1));
var firstBucket = data[0];
var lastBucket = data[data.length - 1];
// Keep track of the last selected bucket info and all buckets
// (for the next bucket average)
var allBuckets = [].concat([firstBucket], buckets, [lastBucket]);
var lastSelectedX = x(firstBucket);
var lastSelectedY = y(firstBucket);
var subsampledData = buckets.map(function (thisBucket, i) {
var nextAvgX = d3Array.mean(allBuckets[i + 1], x);
var nextAvgY = d3Array.mean(allBuckets[i + 1], y);
var xyData = thisBucket.map(function (item) {
return [x(item), y(item)];
});
var areas = xyData.map(function (item) {
return 0.5 * Math.abs((lastSelectedX - nextAvgX) * (item[1] - lastSelectedY) - (lastSelectedX - item[0]) * (nextAvgY - lastSelectedY));
});
var highestIndex = areas.indexOf(d3Array.max(areas));
var highestXY = xyData[highestIndex];
lastSelectedX = highestXY[0];
lastSelectedY = highestXY[1];
return thisBucket[highestIndex];
});
// First and last data points are their own buckets.
return [].concat([data[0]], subsampledData, [data[data.length - 1]]);
};
rebind(largestTriangleThreeBucket, dataBucketer, 'bucketSize');
largestTriangleThreeBucket.x = function (d) {
if (!arguments.length) {
return x;
}
x = d;
return largestTriangleThreeBucket;
};
largestTriangleThreeBucket.y = function (d) {
if (!arguments.length) {
return y;
}
y = d;
return largestTriangleThreeBucket;
};
return largestTriangleThreeBucket;
};
var modeMedian = function () {
var dataBucketer = bucket();
var value = function value(d) {
return d;
};
var modeMedian = function modeMedian(data) {
if (dataBucketer.bucketSize() > data.length) {
return data;
}
var minMax = d3Array.extent(data, value);
var buckets = dataBucketer(data.slice(1, data.length - 1));
var subsampledData = buckets.map(function (thisBucket, i) {
var frequencies = {};
var mostFrequent;
var mostFrequentIndex;
var singleMostFrequent = true;
var values = thisBucket.map(value);
var globalMinMax = values.filter(function (value) {
return value === minMax[0] || value === minMax[1];
}).map(function (value) {
return values.indexOf(value);
})[0];
if (globalMinMax !== undefined) {
return thisBucket[globalMinMax];
}
values.forEach(function (item, i) {
if (frequencies[item] === undefined) {
frequencies[item] = 0;
}
frequencies[item]++;
if (frequencies[item] > frequencies[mostFrequent] || mostFrequent === undefined) {
mostFrequent = item;
mostFrequentIndex = i;
singleMostFrequent = true;
} else if (frequencies[item] === frequencies[mostFrequent]) {
singleMostFrequent = false;
}
});
if (singleMostFrequent) {
return thisBucket[mostFrequentIndex];
} else {
return thisBucket[Math.floor(thisBucket.length / 2)];
}
});
// First and last data points are their own buckets.
return [].concat([data[0]], subsampledData, [data[data.length - 1]]);
};
rebind(modeMedian, dataBucketer, 'bucketSize');
modeMedian.value = function (x) {
if (!arguments.length) {
return value;
}
value = x;
return modeMedian;
};
return modeMedian;
};
var functor$2 = (function (v) {
return typeof v === 'function' ? v : function () {
return v;
};
});
// Renders an OHLC as an SVG path based on the given array of datapoints. Each
// OHLC has a fixed width, whilst the x, open, high, low and close positions are
// obtained from each point via the supplied accessor functions.
var shapeOhlc = (function () {
var context = null;
var x = function x(d) {
return d.date;
};
var open = function open(d) {
return d.open;
};
var high = function high(d) {
return d.high;
};
var low = function low(d) {
return d.low;
};
var close = function close(d) {
return d.close;
};
var orient = 'vertical';
var width = functor$2(3);
var ohlc = function ohlc(data) {
var drawingContext = context || d3Path.path();
data.forEach(function (d, i) {
var xValue = x(d, i);
var yOpen = open(d, i);
var yHigh = high(d, i);
var yLow = low(d, i);
var yClose = close(d, i);
var halfWidth = width(d, i) / 2;
if (orient === 'vertical') {
drawingContext.moveTo(xValue, yLow);
drawingContext.lineTo(xValue, yHigh);
drawingContext.moveTo(xValue, yOpen);
drawingContext.lineTo(xValue - halfWidth, yOpen);
drawingContext.moveTo(xValue, yClose);
drawingContext.lineTo(xValue + halfWidth, yClose);
} else {
drawingContext.moveTo(yLow, xValue);
drawingContext.lineTo(yHigh, xValue);
drawingContext.moveTo(yOpen, xValue);
drawingContext.lineTo(yOpen, xValue + halfWidth);
drawingContext.moveTo(yClose, xValue);
drawingContext.lineTo(yClose, xValue - halfWidth);
}
});
return context ? null : drawingContext.toString();
};
ohlc.context = function () {
if (!arguments.length) {
return context;
}
context = arguments.length <= 0 ? undefined : arguments[0];
return ohlc;
};
ohlc.x = function () {
if (!arguments.length) {
return x;
}
x = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return ohlc;
};
ohlc.open = function () {
if (!arguments.length) {
return open;
}
open = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return ohlc;
};
ohlc.high = function () {
if (!arguments.length) {
return high;
}
high = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return ohlc;
};
ohlc.low = function () {
if (!arguments.length) {
return low;
}
low = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return ohlc;
};
ohlc.close = function () {
if (!arguments.length) {
return close;
}
close = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return ohlc;
};
ohlc.width = function () {
if (!arguments.length) {
return width;
}
width = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return ohlc;
};
ohlc.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return ohlc;
};
return ohlc;
});
// Renders a bar series as an SVG path based on the given array of datapoints. Each
// bar has a fixed width, whilst the x, y and height are obtained from each data
// point via the supplied accessor functions.
var shapeBar = (function () {
var context = null;
var x = function x(d) {
return d.x;
};
var y = function y(d) {
return d.y;
};
var horizontalAlign = 'center';
var verticalAlign = 'center';
var height = function height(d) {
return d.height;
};
var width = functor$2(3);
var bar = function bar(data, index) {
var drawingContext = context || d3Path.path();
data.forEach(function (d, i) {
var xValue = x.call(this, d, index || i);
var yValue = y.call(this, d, index || i);
var barHeight = height.call(this, d, index || i);
var barWidth = width.call(this, d, index || i);
var horizontalOffset = void 0;
switch (horizontalAlign) {
case 'left':
horizontalOffset = barWidth;
break;
case 'right':
horizontalOffset = 0;
break;
case 'center':
horizontalOffset = barWidth / 2;
break;
default:
throw new Error('Invalid horizontal alignment ' + horizontalAlign);
}
var verticalOffset = void 0;
switch (verticalAlign) {
case 'bottom':
verticalOffset = -barHeight;
break;
case 'top':
verticalOffset = 0;
break;
case 'center':
verticalOffset = barHeight / 2;
break;
default:
throw new Error('Invalid vertical alignment ' + verticalAlign);
}
drawingContext.rect(xValue - horizontalOffset, yValue - verticalOffset, barWidth, barHeight);
}, this);
return context ? null : drawingContext.toString();
};
bar.context = function () {
if (!arguments.length) {
return context;
}
context = arguments.length <= 0 ? undefined : arguments[0];
return bar;
};
bar.x = function () {
if (!arguments.length) {
return x;
}
x = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return bar;
};
bar.y = function () {
if (!arguments.length) {
return y;
}
y = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return bar;
};
bar.width = function () {
if (!arguments.length) {
return width;
}
width = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return bar;
};
bar.horizontalAlign = function () {
if (!arguments.length) {
return horizontalAlign;
}
horizontalAlign = arguments.length <= 0 ? undefined : arguments[0];
return bar;
};
bar.height = function () {
if (!arguments.length) {
return height;
}
height = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return bar;
};
bar.verticalAlign = function () {
if (!arguments.length) {
return verticalAlign;
}
verticalAlign = arguments.length <= 0 ? undefined : arguments[0];
return bar;
};
return bar;
});
// Renders a candlestick as an SVG path based on the given array of datapoints. Each
// candlestick has a fixed width, whilst the x, open, high, low and close positions are
// obtained from each point via the supplied accessor functions.
var shapeCandlestick = (function () {
var context = null;
var x = function x(d) {
return d.date;
};
var open = function open(d) {
return d.open;
};
var high = function high(d) {
return d.high;
};
var low = function low(d) {
return d.low;
};
var close = function close(d) {
return d.close;
};
var width = functor$2(3);
var candlestick = function candlestick(data) {
var drawingContext = context || d3Path.path();
data.forEach(function (d, i) {
var xValue = x(d, i);
var yOpen = open(d, i);
var yHigh = high(d, i);
var yLow = low(d, i);
var yClose = close(d, i);
var barWidth = width(d, i);
var halfBarWidth = barWidth / 2;
// Body
drawingContext.rect(xValue - halfBarWidth, yOpen, barWidth, yClose - yOpen);
// High wick
// // Move to the max price of close or open; draw the high wick
// N.B. Math.min() is used as we're dealing with pixel values,
// the lower the pixel value, the higher the price!
drawingContext.moveTo(xValue, Math.min(yClose, yOpen));
drawingContext.lineTo(xValue, yHigh);
// Low wick
// // Move to the min price of close or open; draw the low wick
// N.B. Math.max() is used as we're dealing with pixel values,
// the higher the pixel value, the lower the price!
drawingContext.moveTo(xValue, Math.max(yClose, yOpen));
drawingContext.lineTo(xValue, yLow);
});
return context ? null : drawingContext.toString();
};
candlestick.context = function () {
if (!arguments.length) {
return context;
}
context = arguments.length <= 0 ? undefined : arguments[0];
return candlestick;
};
candlestick.x = function () {
if (!arguments.length) {
return x;
}
x = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return candlestick;
};
candlestick.open = function () {
if (!arguments.length) {
return open;
}
open = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return candlestick;
};
candlestick.high = function () {
if (!arguments.length) {
return high;
}
high = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return candlestick;
};
candlestick.low = function () {
if (!arguments.length) {
return low;
}
low = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return candlestick;
};
candlestick.close = function () {
if (!arguments.length) {
return close;
}
close = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return candlestick;
};
candlestick.width = function () {
if (!arguments.length) {
return width;
}
width = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return candlestick;
};
return candlestick;
});
// Renders a box plot series as an SVG path based on the given array of datapoints.
var shapeBoxPlot = (function () {
var context = null;
var value = function value(d) {
return d.value;
};
var median = function median(d) {
return d.median;
};
var upperQuartile = function upperQuartile(d) {
return d.upperQuartile;
};
var lowerQuartile = function lowerQuartile(d) {
return d.lowerQuartile;
};
var high = function high(d) {
return d.high;
};
var low = function low(d) {
return d.low;
};
var orient = 'vertical';
var width = functor$2(5);
var cap = functor$2(0.5);
var boxPlot = function boxPlot(data) {
var drawingContext = context || d3Path.path();
data.forEach(function (d, i) {
// naming convention is for vertical orientation
var _value = value(d, i);
var _width = width(d, i);
var halfWidth = _width / 2;
var capWidth = _width * cap(d, i);
var halfCapWidth = capWidth / 2;
var _high = high(d, i);
var _upperQuartile = upperQuartile(d, i);
var _median = median(d, i);
var _lowerQuartile = lowerQuartile(d, i);
var _low = low(d, i);
var upperQuartileToLowerQuartile = _lowerQuartile - _upperQuartile;
if (orient === 'vertical') {
// Upper whisker
drawingContext.moveTo(_value - halfCapWidth, _high);
drawingContext.lineTo(_value + halfCapWidth, _high);
drawingContext.moveTo(_value, _high);
drawingContext.lineTo(_value, _upperQuartile);
// Box
drawingContext.rect(_value - halfWidth, _upperQuartile, _width, upperQuartileToLowerQuartile);
drawingContext.moveTo(_value - halfWidth, _median);
// Median line
drawingContext.lineTo(_value + halfWidth, _median);
// Lower whisker
drawingContext.moveTo(_value, _lowerQuartile);
drawingContext.lineTo(_value, _low);
drawingContext.moveTo(_value - halfCapWidth, _low);
drawingContext.lineTo(_value + halfCapWidth, _low);
} else {
// Lower whisker
drawingContext.moveTo(_low, _value - halfCapWidth);
drawingContext.lineTo(_low, _value + halfCapWidth);
drawingContext.moveTo(_low, _value);
drawingContext.lineTo(_lowerQuartile, _value);
// Box
drawingContext.rect(_lowerQuartile, _value - halfWidth, -upperQuartileToLowerQuartile, _width);
drawingContext.moveTo(_median, _value - halfWidth);
drawingContext.lineTo(_median, _value + halfWidth);
// Upper whisker
drawingContext.moveTo(_upperQuartile, _value);
drawingContext.lineTo(_high, _value);
drawingContext.moveTo(_high, _value - halfCapWidth);
drawingContext.lineTo(_high, _value + halfCapWidth);
}
});
return context ? null : drawingContext.toString();
};
boxPlot.context = function () {
if (!arguments.length) {
return context;
}
context = arguments.length <= 0 ? undefined : arguments[0];
return boxPlot;
};
boxPlot.value = function () {
if (!arguments.length) {
return value;
}
value = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.median = function () {
if (!arguments.length) {
return median;
}
median = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.upperQuartile = function () {
if (!arguments.length) {
return upperQuartile;
}
upperQuartile = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.lowerQuartile = function () {
if (!arguments.length) {
return lowerQuartile;
}
lowerQuartile = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.high = function () {
if (!arguments.length) {
return high;
}
high = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.low = function () {
if (!arguments.length) {
return low;
}
low = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.width = function () {
if (!arguments.length) {
return width;
}
width = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
boxPlot.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return boxPlot;
};
boxPlot.cap = function () {
if (!arguments.length) {
return cap;
}
cap = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return boxPlot;
};
return boxPlot;
});
// Renders an error bar series as an SVG path based on the given array of datapoints.
var shapeErrorBar = (function () {
var context = null;
var value = function value(d) {
return d.x;
};
var high = function high(d) {
return d.high;
};
var low = function low(d) {
return d.low;
};
var orient = 'vertical';
var width = functor$2(5);
var errorBar = function errorBar(data) {
var drawingContext = context || d3Path.path();
data.forEach(function (d, i) {
// naming convention is for vertical orientation
var _value = value(d, i);
var _width = width(d, i);
var halfWidth = _width / 2;
var _high = high(d, i);
var _low = low(d, i);
if (orient === 'vertical') {
drawingContext.moveTo(_value - halfWidth, _high);
drawingContext.lineTo(_value + halfWidth, _high);
drawingContext.moveTo(_value, _high);
drawingContext.lineTo(_value, _low);
drawingContext.moveTo(_value - halfWidth, _low);
drawingContext.lineTo(_value + halfWidth, _low);
} else {
drawingContext.moveTo(_low, _value - halfWidth);
drawingContext.lineTo(_low, _value + halfWidth);
drawingContext.moveTo(_low, _value);
drawingContext.lineTo(_high, _value);
drawingContext.moveTo(_high, _value - halfWidth);
drawingContext.lineTo(_high, _value + halfWidth);
}
});
return context ? null : drawingContext.toString();
};
errorBar.context = function () {
if (!arguments.length) {
return context;
}
context = arguments.length <= 0 ? undefined : arguments[0];
return errorBar;
};
errorBar.value = function () {
if (!arguments.length) {
return value;
}
value = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return errorBar;
};
errorBar.high = function () {
if (!arguments.length) {
return high;
}
high = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return errorBar;
};
errorBar.low = function () {
if (!arguments.length) {
return low;
}
low = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return errorBar;
};
errorBar.width = function () {
if (!arguments.length) {
return width;
}
width = functor$2(arguments.length <= 0 ? undefined : arguments[0]);
return errorBar;
};
errorBar.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return errorBar;
};
return errorBar;
});
var functor$3 = (function (d) {
return typeof d === 'function' ? d : function () {
return d;
};
});
// "Caution: avoid interpolating to or from the number zero when the interpolator is used to generate
// a string (such as with attr).
// Very small values, when stringified, may be converted to scientific notation and
// cause a temporarily invalid attribute or style property value.
// For example, the number 0.0000001 is converted to the string "1e-7".
// This is particularly noticeable when interpolating opacity values.
// To avoid scientific notation, start or end the transition at 1e-6,
// which is the smallest value that is not stringified in exponential notation."
// - https://github.com/mbostock/d3/wiki/Transitions#d3_interpolateNumber
var effectivelyZero = 1e-6;
// Wrapper around d3's selectAll/data data-join, which allows decoration of the result.
// This is achieved by appending the element to the enter selection before exposing it.
// A default transition of fade in/out is also implicitly added but can be modified.
var dataJoin = (function (element, className) {
element = element || 'g';
var key = function key(_, i) {
return i;
};
var explicitTransition = null;
var dataJoin = function dataJoin(container, data) {
data = data || function (d) {
return d;
};
var implicitTransition = container.selection ? container : null;
if (implicitTransition) {
container = container.selection();
}
var selected = container.selectAll(function (d, i, nodes) {
return Array.from(nodes[i].childNodes).filter(function (node) {
return node.nodeType === 1;
});
}).filter(className == null ? element : element + '.' + className);
var update = selected.data(data, key);
var enter = update.enter().append(element).attr('class', className);
var exit = update.exit();
// automatically merge in the enter selection
update = update.merge(enter);
// if transitions are enabled apply a default fade in/out transition
var transition = implicitTransition || explicitTransition;
if (transition) {
update = update.transition(transition).style('opacity', 1);
enter.style('opacity', effectivelyZero);
exit = exit.transition(transition).style('opacity', effectivelyZero);
}
exit.remove();
update.enter = function () {
return enter;
};
update.exit = function () {
return exit;
};
return update;
};
dataJoin.element = function () {
if (!arguments.length) {
return element;
}
element = arguments.length <= 0 ? undefined : arguments[0];
return dataJoin;
};
dataJoin.className = function () {
if (!arguments.length) {
return className;
}
className = arguments.length <= 0 ? undefined : arguments[0];
return dataJoin;
};
dataJoin.key = function () {
if (!arguments.length) {
return key;
}
key = arguments.length <= 0 ? undefined : arguments[0];
return dataJoin;
};
dataJoin.transition = function () {
if (!arguments.length) {
return explicitTransition;
}
explicitTransition = arguments.length <= 0 ? undefined : arguments[0];
return dataJoin;
};
return dataJoin;
});
var label = (function (layoutStrategy) {
var decorate = function decorate() {};
var size = function size() {
return [0, 0];
};
var position = function position(d, i) {
return [d.x, d.y];
};
var strategy = layoutStrategy || function (x) {
return x;
};
var component = function component() {};
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var dataJoin$$1 = dataJoin('g', 'label');
var label = function label(selection$$1) {
selection$$1.each(function (data, index, group) {
var g = dataJoin$$1(d3Selection.select(group[index]), data).call(component);
// obtain the rectangular bounding boxes for each child
var nodes = g.nodes();
var childRects = nodes.map(function (node, i) {
var d = d3Selection.select(node).datum();
var pos = position(d, i, nodes);
var childPos = [xScale(pos[0]), yScale(pos[1])];
var childSize = size(d, i, nodes);
return {
hidden: false,
x: childPos[0],
y: childPos[1],
width: childSize[0],
height: childSize[1]
};
});
// apply the strategy to derive the layout. The strategy does not change the order
// or number of label.
var layout = strategy(childRects);
g.attr('style', function (_, i) {
return 'display:' + (layout[i].hidden ? 'none' : 'inherit');
}).attr('transform', function (_, i) {
return 'translate(' + layout[i].x + ', ' + layout[i].y + ')';
})
// set the layout width / height so that children can use SVG layout if required
.attr('layout-width', function (_, i) {
return layout[i].width;
}).attr('layout-height', function (_, i) {
return layout[i].height;
}).attr('anchor-x', function (d, i, g) {
return childRects[i].x - layout[i].x;
}).attr('anchor-y', function (d, i, g) {
return childRects[i].y - layout[i].y;
});
g.call(component);
decorate(g, data, index);
});
};
rebindAll(label, dataJoin$$1, include('key'));
rebindAll(label, strategy);
label.size = function () {
if (!arguments.length) {
return size;
}
size = functor$3(arguments.length <= 0 ? undefined : arguments[0]);
return label;
};
label.position = function () {
if (!arguments.length) {
return position;
}
position = functor$3(arguments.length <= 0 ? undefined : arguments[0]);
return label;
};
label.component = function () {
if (!arguments.length) {
return component;
}
component = arguments.length <= 0 ? undefined : arguments[0];
return label;
};
label.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return label;
};
label.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return label;
};
label.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return label;
};
return label;
});
var textLabel = (function (layoutStrategy) {
var padding = 2;
var value = function value(x) {
return x;
};
var textJoin = dataJoin('text');
var rectJoin = dataJoin('rect');
var pointJoin = dataJoin('circle');
var textLabel = function textLabel(selection$$1) {
selection$$1.each(function (data, index, group) {
var node = group[index];
var nodeSelection = d3Selection.select(node);
var width = Number(node.getAttribute('layout-width'));
var height = Number(node.getAttribute('layout-height'));
var rect = rectJoin(nodeSelection, [data]);
rect.attr('width', width).attr('height', height);
var anchorX = Number(node.getAttribute('anchor-x'));
var anchorY = Number(node.getAttribute('anchor-y'));
var circle = pointJoin(nodeSelection, [data]);
circle.attr('r', 2).attr('cx', anchorX).attr('cy', anchorY);
var text = textJoin(nodeSelection, [data]);
text.enter().attr('dy', '0.9em').attr('transform', 'translate(' + padding + ', ' + padding + ')');
text.text(value);
});
};
textLabel.padding = function () {
if (!arguments.length) {
return padding;
}
padding = arguments.length <= 0 ? undefined : arguments[0];
return textLabel;
};
textLabel.value = function () {
if (!arguments.length) {
return value;
}
value = functor$3(arguments.length <= 0 ? undefined : arguments[0]);
return textLabel;
};
return textLabel;
});
var isIntersecting = function isIntersecting(a, b) {
return !(a.x >= b.x + b.width || a.x + a.width <= b.x || a.y >= b.y + b.height || a.y + a.height <= b.y);
};
var intersect = (function (a, b) {
if (isIntersecting(a, b)) {
var left = Math.max(a.x, b.x);
var right = Math.min(a.x + a.width, b.x + b.width);
var top = Math.max(a.y, b.y);
var bottom = Math.min(a.y + a.height, b.y + b.height);
return (right - left) * (bottom - top);
} else {
return 0;
}
});
// computes the area of overlap between the rectangle with the given index with the
// rectangles in the array
var collisionArea = function collisionArea(rectangles, index) {
return d3Array.sum(rectangles.map(function (d, i) {
return index === i ? 0 : intersect(rectangles[index], d);
}));
};
// computes the total overlapping area of all of the rectangles in the given array
var getPlacement = function getPlacement(x, y, width, height, location) {
return {
x: x,
y: y,
width: width,
height: height,
location: location
};
};
// returns all the potential placements of the given label
var placements = (function (label) {
var x = label.x;
var y = label.y;
var width = label.width;
var height = label.height;
return [getPlacement(x, y, width, height, 'bottom-right'), getPlacement(x - width, y, width, height, 'bottom-left'), getPlacement(x - width, y - height, width, height, 'top-left'), getPlacement(x, y - height, width, height, 'top-right'), getPlacement(x, y - height / 2, width, height, 'middle-right'), getPlacement(x - width / 2, y, width, height, 'bottom-center'), getPlacement(x - width, y - height / 2, width, height, 'middle-left'), getPlacement(x - width / 2, y - height, width, height, 'top-center')];
});
var substitute = function substitute(array, index, substitution) {
return [].concat(toConsumableArray(array.slice(0, index)), [substitution], toConsumableArray(array.slice(index + 1)));
};
var lessThan = function lessThan(a, b) {
return a < b;
};
// a layout takes an array of rectangles and allows their locations to be optimised.
// it is constructed using two functions, locationScore, which score the placement of and
// individual rectangle, and winningScore which takes the scores for a rectangle
// at two different locations and assigns a winningScore.
var layoutComponent = function layoutComponent() {
var score = null;
var winningScore = lessThan;
var locationScore = function locationScore() {
return 0;
};
var rectangles = void 0;
var evaluatePlacement = function evaluatePlacement(placement, index) {
return score - locationScore(rectangles[index], index, rectangles) + locationScore(placement, index, substitute(rectangles, index, placement));
};
var layout = function layout(placement, index) {
if (!score) {
score = d3Array.sum(rectangles.map(function (r, i) {
return locationScore(r, i, rectangles);
}));
}
var newScore = evaluatePlacement(placement, index);
if (winningScore(newScore, score)) {
return layoutComponent().locationScore(locationScore).winningScore(winningScore).score(newScore).rectangles(substitute(rectangles, index, placement));
} else {
return layout;
}
};
layout.rectangles = function () {
if (!arguments.length) {
return rectangles;
}
rectangles = arguments.length <= 0 ? undefined : arguments[0];
return layout;
};
layout.score = function () {
if (!arguments.length) {
return score;
}
score = arguments.length <= 0 ? undefined : arguments[0];
return layout;
};
layout.winningScore = function () {
if (!arguments.length) {
return winningScore;
}
winningScore = arguments.length <= 0 ? undefined : arguments[0];
return layout;
};
layout.locationScore = function () {
if (!arguments.length) {
return locationScore;
}
locationScore = arguments.length <= 0 ? undefined : arguments[0];
return layout;
};
return layout;
};
var greedy = (function () {
var bounds = void 0;
var containerPenalty = function containerPenalty(rectangle) {
return bounds ? rectangle.width * rectangle.height - intersect(rectangle, bounds) : 0;
};
var penaltyForRectangle = function penaltyForRectangle(rectangle, index, rectangles) {
return collisionArea(rectangles, index) + containerPenalty(rectangle);
};
var strategy = function strategy(data) {
var rectangles = layoutComponent().locationScore(penaltyForRectangle).rectangles(data);
data.forEach(function (rectangle, index) {
placements(rectangle).forEach(function (placement, placementIndex) {
rectangles = rectangles(placement, index);
});
});
return rectangles.rectangles();
};
strategy.bounds = function () {
if (!arguments.length) {
return bounds;
}
bounds = arguments.length <= 0 ? undefined : arguments[0];
return strategy;
};
return strategy;
});
var randomItem = function randomItem(array) {
return array[randomIndex(array)];
};
var randomIndex = function randomIndex(array) {
return Math.floor(Math.random() * array.length);
};
var annealing = (function () {
var temperature = 1000;
var cooling = 1;
var bounds = void 0;
var orientationPenalty = function orientationPenalty(rectangle) {
switch (rectangle.location) {
case 'bottom-right':
return 0;
case 'middle-right':
case 'bottom-center':
return rectangle.width * rectangle.height / 8;
}
return rectangle.width * rectangle.height / 4;
};
var containerPenalty = function containerPenalty(rectangle) {
return bounds ? rectangle.width * rectangle.height - intersect(rectangle, bounds) : 0;
};
var penaltyForRectangle = function penaltyForRectangle(rectangle, index, rectangles) {
return collisionArea(rectangles, index) + containerPenalty(rectangle) + orientationPenalty(rectangle);
};
var strategy = function strategy(data) {
var currentTemperature = temperature;
// use annealing to allow a new score to be picked even if it is worse than the old
var winningScore = function winningScore(newScore, oldScore) {
return Math.exp((oldScore - newScore) / currentTemperature) > Math.random();
};
var rectangles = layoutComponent().locationScore(penaltyForRectangle).winningScore(winningScore).rectangles(data);
while (currentTemperature > 0) {
var index = randomIndex(data);
var randomNewPlacement = randomItem(placements(data[index]));
rectangles = rectangles(randomNewPlacement, index);
currentTemperature -= cooling;
}
return rectangles.rectangles();
};
strategy.temperature = function () {
if (!arguments.length) {
return temperature;
}
temperature = arguments.length <= 0 ? undefined : arguments[0];
return strategy;
};
strategy.cooling = function () {
if (!arguments.length) {
return cooling;
}
cooling = arguments.length <= 0 ? undefined : arguments[0];
return strategy;
};
strategy.bounds = function () {
if (!arguments.length) {
return bounds;
}
bounds = arguments.length <= 0 ? undefined : arguments[0];
return strategy;
};
return strategy;
});
var scanForObject = function scanForObject(array, comparator) {
return array[d3Array.scan(array, comparator)];
};
var removeOverlaps = (function (adaptedStrategy) {
adaptedStrategy = adaptedStrategy || function (x) {
return x;
};
var removeOverlaps = function removeOverlaps(layout) {
layout = adaptedStrategy(layout);
var _loop = function _loop() {
// find the collision area for all overlapping rectangles, hiding the one
// with the greatest overlap
var visible = layout.filter(function (d) {
return !d.hidden;
});
var collisions = visible.map(function (d, i) {
return [d, collisionArea(visible, i)];
});
var maximumCollision = scanForObject(collisions, function (a, b) {
return b[1] - a[1];
});
if (maximumCollision[1] > 0) {
maximumCollision[0].hidden = true;
} else {
return 'break';
}
};
while (true) {
var _ret = _loop();
if (_ret === 'break') break;
}
return layout;
};
rebindAll(removeOverlaps, adaptedStrategy);
return removeOverlaps;
});
var boundingBox = (function () {
var bounds = [0, 0];
var strategy = function strategy(data) {
return data.map(function (d, i) {
var tx = d.x;
var ty = d.y;
if (tx + d.width > bounds[0]) {
tx -= d.width;
}
if (ty + d.height > bounds[1]) {
ty -= d.height;
}
return { height: d.height, width: d.width, x: tx, y: ty };
});
};
strategy.bounds = function () {
if (!arguments.length) {
return bounds;
}
bounds = arguments.length <= 0 ? undefined : arguments[0];
return strategy;
};
return strategy;
});
var functor$4 = (function (d) {
return typeof d === 'function' ? d : function () {
return d;
};
});
// Checks that passes properties are 'defined', meaning that calling them with (d, i) returns non null values
function defined$1() {
var outerArguments = arguments;
return function (d, i) {
for (var c = 0, j = outerArguments.length; c < j; c++) {
if (outerArguments[c](d, i) == null) {
return false;
}
}
return true;
};
}
// determines the offset required along the cross scale based
// on the series alignment
var alignOffset = (function (align, width) {
switch (align) {
case 'left':
return width / 2;
case 'right':
return -width / 2;
default:
return 0;
}
});
var createBase = (function (initialValues) {
var env = Object.assign({}, initialValues);
var base = function base() {};
Object.keys(env).forEach(function (key) {
base[key] = function () {
if (!arguments.length) {
return env[key];
}
env[key] = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
});
return base;
});
var xyBase = (function () {
var baseValue = function baseValue() {
return 0;
};
var crossValue = function crossValue(d) {
return d.x;
};
var mainValue = function mainValue(d) {
return d.y;
};
var align = 'center';
var bandwidth = function bandwidth() {
return 5;
};
var orient = 'vertical';
var base = createBase({
decorate: function decorate() {},
defined: function defined(d, i) {
return defined$1(baseValue, crossValue, mainValue)(d, i);
},
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity()
});
base.values = function (d, i) {
var width = bandwidth(d, i);
var offset = alignOffset(align, width);
var xScale = base.xScale();
var yScale = base.yScale();
if (orient === 'vertical') {
var y = yScale(mainValue(d, i), i);
var y0 = yScale(baseValue(d, i), i);
var x = xScale(crossValue(d, i), i) + offset;
return {
d: d,
x: x,
y: y,
y0: y0,
width: width,
height: y - y0,
origin: [x, y],
baseOrigin: [x, y0],
transposedX: x,
transposedY: y
};
} else {
var _y = xScale(mainValue(d, i), i);
var _y2 = xScale(baseValue(d, i), i);
var _x = yScale(crossValue(d, i), i) + offset;
return {
d: d,
x: _x,
y: _y,
y0: _y2,
width: width,
height: _y - _y2,
origin: [_y, _x],
baseOrigin: [_y2, _x],
transposedX: _y,
transposedY: _x
};
}
};
base.baseValue = function () {
if (!arguments.length) {
return baseValue;
}
baseValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.crossValue = function () {
if (!arguments.length) {
return crossValue;
}
crossValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.mainValue = function () {
if (!arguments.length) {
return mainValue;
}
mainValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.bandwidth = function () {
if (!arguments.length) {
return bandwidth;
}
bandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.align = function () {
if (!arguments.length) {
return align;
}
align = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
return base;
});
var red = '#c60';
var green = '#6c0';
var black = '#000';
var gray = '#ddd';
var darkGray = '#999';
var colors = {
red: red,
green: green,
black: black,
gray: gray,
darkGray: darkGray
};
var seriesSvgLine = (function () {
var base = xyBase();
var lineData = d3Shape.line().x(function (d, i) {
return base.values(d, i).transposedX;
}).y(function (d, i) {
return base.values(d, i).transposedY;
});
var join = dataJoin('path', 'line');
var line$$1 = function line$$1(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
lineData.defined(base.defined());
selection$$1.each(function (data, index, group) {
var path$$1 = join(d3Selection.select(group[index]), [data]);
path$$1.enter().attr('fill', 'none').attr('stroke', colors.black);
path$$1.attr('d', lineData);
base.decorate()(path$$1, data, index);
});
};
rebindAll(line$$1, base, exclude('baseValue', 'bandwidth', 'align'));
rebind(line$$1, join, 'key');
rebind(line$$1, lineData, 'curve');
return line$$1;
});
var seriesCanvasLine = (function () {
var base = xyBase();
var lineData = d3Shape.line().x(function (d, i) {
return base.values(d, i).transposedX;
}).y(function (d, i) {
return base.values(d, i).transposedY;
});
var line$$1 = function line$$1(data) {
var context = lineData.context();
context.beginPath();
lineData.defined(base.defined())(data);
context.strokeStyle = colors.black;
context.fillStyle = 'transparent';
base.decorate()(context, data);
context.fill();
context.stroke();
context.closePath();
};
rebindAll(line$$1, base, exclude('baseValue', 'bandwidth', 'align'));
rebind(line$$1, lineData, 'curve', 'context');
return line$$1;
});
var seriesSvgPoint = (function () {
var symbol$$1 = d3Shape.symbol();
var base = xyBase();
var join = dataJoin('g', 'point');
var containerTransform = function containerTransform(origin) {
return 'translate(' + origin[0] + ', ' + origin[1] + ')';
};
var point = function point(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
selection$$1.each(function (data, index, group) {
var filteredData = data.filter(base.defined());
var g = join(d3Selection.select(group[index]), filteredData);
g.enter().attr('transform', function (d, i) {
return containerTransform(base.values(d, i).origin);
}).attr('fill', colors.gray).attr('stroke', colors.black).append('path');
g.attr('transform', function (d, i) {
return containerTransform(base.values(d, i).origin);
}).select('path').attr('d', symbol$$1);
base.decorate()(g, data, index);
});
};
rebindAll(point, base, exclude('baseValue', 'bandwidth', 'align'));
rebind(point, join, 'key');
rebind(point, symbol$$1, 'type', 'size');
return point;
});
var seriesCanvasPoint = (function () {
var symbol$$1 = d3Shape.symbol();
var base = xyBase();
var point = function point(data) {
var filteredData = data.filter(base.defined());
var context = symbol$$1.context();
filteredData.forEach(function (d, i) {
context.save();
var values = base.values(d, i);
context.translate(values.origin[0], values.origin[1]);
context.beginPath();
symbol$$1(d, i);
context.strokeStyle = colors.black;
context.fillStyle = colors.gray;
base.decorate()(context, d, i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
rebindAll(point, base, exclude('baseValue', 'bandwidth', 'align'));
rebind(point, symbol$$1, 'size', 'type', 'context');
return point;
});
var bar = (function () {
var pathGenerator = shapeBar().x(0).y(0);
var base = xyBase();
var join = dataJoin('g', 'bar');
var valueAxisDimension = function valueAxisDimension(generator) {
return base.orient() === 'vertical' ? generator.height : generator.width;
};
var crossAxisDimension = function crossAxisDimension(generator) {
return base.orient() === 'vertical' ? generator.width : generator.height;
};
var translation = function translation(origin) {
return 'translate(' + origin[0] + ', ' + origin[1] + ')';
};
var bar = function bar(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
selection$$1.each(function (data, index, group) {
var orient = base.orient();
if (orient !== 'vertical' && orient !== 'horizontal') {
throw new Error('The bar series does not support an orientation of ' + orient);
}
var filteredData = data.filter(base.defined());
var projectedData = filteredData.map(base.values);
pathGenerator.width(0).height(0);
if (base.orient() === 'vertical') {
pathGenerator.verticalAlign('top');
pathGenerator.horizontalAlign('center');
} else {
pathGenerator.horizontalAlign('right');
pathGenerator.verticalAlign('center');
}
var g = join(d3Selection.select(group[index]), filteredData);
// within the enter selection the pathGenerator creates a zero
// height bar on the baseline. As a result, when used with a transition the bar grows
// from y0 to y1 (y)
g.enter().attr('transform', function (_, i) {
return translation(projectedData[i].baseOrigin);
}).attr('class', 'bar ' + base.orient()).attr('fill', colors.darkGray).append('path').attr('d', function (d, i) {
crossAxisDimension(pathGenerator)(projectedData[i].width);
return pathGenerator([d]);
});
// the container translation sets the origin to the 'tip'
// of each bar as per the decorate pattern
g.attr('transform', function (_, i) {
return translation(projectedData[i].origin);
}).select('path').attr('d', function (d, i) {
crossAxisDimension(pathGenerator)(projectedData[i].width);
valueAxisDimension(pathGenerator)(-projectedData[i].height);
return pathGenerator([d]);
});
base.decorate()(g, filteredData, index);
});
};
rebindAll(bar, base);
rebind(bar, join, 'key');
return bar;
});
var bar$1 = (function () {
var base = xyBase();
var pathGenerator = shapeBar().x(0).y(0);
var valueAxisDimension = function valueAxisDimension(generator) {
return base.orient() === 'vertical' ? generator.height : generator.width;
};
var crossAxisDimension = function crossAxisDimension(generator) {
return base.orient() === 'vertical' ? generator.width : generator.height;
};
var bar = function bar(data) {
var context = pathGenerator.context();
var filteredData = data.filter(base.defined());
var projectedData = filteredData.map(base.values);
if (base.orient() === 'vertical') {
pathGenerator.verticalAlign('top');
pathGenerator.horizontalAlign('center');
} else {
pathGenerator.horizontalAlign('right');
pathGenerator.verticalAlign('center');
}
projectedData.forEach(function (datum, i) {
context.save();
context.beginPath();
context.translate(datum.origin[0], datum.origin[1]);
valueAxisDimension(pathGenerator)(-datum.height);
crossAxisDimension(pathGenerator)(datum.width);
pathGenerator([datum]);
context.fillStyle = colors.darkGray;
context.strokeStyle = 'transparent';
base.decorate()(context, datum.d, i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
rebindAll(bar, base);
rebind(bar, pathGenerator, 'context');
return bar;
});
var errorBarBase = (function () {
var highValue = function highValue(d) {
return d.high;
};
var lowValue = function lowValue(d) {
return d.low;
};
var crossValue = function crossValue(d) {
return d.cross;
};
var orient = 'vertical';
var align = 'center';
var bandwidth = function bandwidth() {
return 5;
};
var base = createBase({
decorate: function decorate() {},
defined: function defined(d, i) {
return defined$1(lowValue, highValue, crossValue)(d, i);
},
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity()
});
base.values = function (d, i) {
var width = bandwidth(d, i);
var offset = alignOffset(align, width);
var xScale = base.xScale();
var yScale = base.yScale();
if (orient === 'vertical') {
var y = yScale(highValue(d, i));
return {
origin: [xScale(crossValue(d, i)) + offset, y],
high: 0,
low: yScale(lowValue(d, i)) - y,
width: width
};
} else {
var x = xScale(lowValue(d, i));
return {
origin: [x, yScale(crossValue(d, i)) + offset],
high: xScale(highValue(d, i)) - x,
low: 0,
width: width
};
}
};
base.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.lowValue = function () {
if (!arguments.length) {
return lowValue;
}
lowValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.highValue = function () {
if (!arguments.length) {
return highValue;
}
highValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.crossValue = function () {
if (!arguments.length) {
return crossValue;
}
crossValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.bandwidth = function () {
if (!arguments.length) {
return bandwidth;
}
bandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.align = function () {
if (!arguments.length) {
return align;
}
align = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
return base;
});
var errorBar = (function () {
var base = errorBarBase();
var join = dataJoin('g', 'error-bar');
var pathGenerator = shapeErrorBar().value(0);
var propagateTransition = function propagateTransition(maybeTransition) {
return function (selection$$1) {
return maybeTransition.selection ? selection$$1.transition(maybeTransition) : selection$$1;
};
};
var containerTranslation = function containerTranslation(values) {
return 'translate(' + values.origin[0] + ', ' + values.origin[1] + ')';
};
var errorBar = function errorBar(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
var transitionPropagator = propagateTransition(selection$$1);
selection$$1.each(function (data, index, group) {
var filteredData = data.filter(base.defined());
var projectedData = filteredData.map(base.values);
var g = join(d3Selection.select(group[index]), filteredData);
g.enter().attr('stroke', colors.black).attr('fill', colors.gray).attr('transform', function (d, i) {
return containerTranslation(base.values(d, i)) + ' scale(1e-6, 1)';
}).append('path');
pathGenerator.orient(base.orient());
g.each(function (d, i, g) {
var values = projectedData[i];
pathGenerator.high(values.high).low(values.low).width(values.width);
transitionPropagator(d3Selection.select(g[i])).attr('transform', containerTranslation(values) + ' scale(1)').select('path').attr('d', pathGenerator([d]));
});
base.decorate()(g, data, index);
});
};
rebindAll(errorBar, base);
rebind(errorBar, join, 'key');
return errorBar;
});
var errorBar$1 = (function () {
var base = errorBarBase();
var pathGenerator = shapeErrorBar().value(0);
var errorBar = function errorBar(data) {
var filteredData = data.filter(base.defined());
var context = pathGenerator.context();
pathGenerator.orient(base.orient());
filteredData.forEach(function (d, i) {
context.save();
var values = base.values(d, i);
context.translate(values.origin[0], values.origin[1]);
context.beginPath();
pathGenerator.high(values.high).width(values.width).low(values.low)([d]);
context.strokeStyle = colors.black;
context.fillStyle = colors.gray;
base.decorate()(context, d, i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
rebindAll(errorBar, base);
rebind(errorBar, pathGenerator, 'context');
return errorBar;
});
var area$1 = (function () {
var base = xyBase();
var areaData = d3Shape.area();
var join = dataJoin('path', 'area');
var area$$1 = function area$$1(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
areaData.defined(base.defined());
selection$$1.each(function (data, index, group) {
var projectedData = data.map(base.values);
areaData.x(function (_, i) {
return projectedData[i].transposedX;
}).y(function (_, i) {
return projectedData[i].transposedY;
});
var valueComponent = base.orient() === 'vertical' ? 'y' : 'x';
areaData[valueComponent + '0'](function (_, i) {
return projectedData[i].y0;
});
areaData[valueComponent + '1'](function (_, i) {
return projectedData[i].y;
});
var path$$1 = join(d3Selection.select(group[index]), [data]);
path$$1.enter().attr('fill', colors.gray);
path$$1.attr('d', areaData);
base.decorate()(path$$1, data, index);
});
};
rebindAll(area$$1, base, exclude('bandwidth', 'align'));
rebind(area$$1, join, 'key');
rebind(area$$1, areaData, 'curve');
return area$$1;
});
var area$2 = (function () {
var base = xyBase();
var areaData = d3Shape.area();
var area$$1 = function area$$1(data) {
var context = areaData.context();
areaData.defined(base.defined());
var projectedData = data.map(base.values);
areaData.x(function (_, i) {
return projectedData[i].transposedX;
}).y(function (_, i) {
return projectedData[i].transposedY;
});
var valueComponent = base.orient() === 'vertical' ? 'y' : 'x';
areaData[valueComponent + '0'](function (_, i) {
return projectedData[i].y0;
});
areaData[valueComponent + '1'](function (_, i) {
return projectedData[i].y;
});
context.beginPath();
areaData(data);
context.fillStyle = colors.gray;
context.strokeStyle = 'transparent';
base.decorate()(context, data);
context.fill();
context.stroke();
context.closePath();
};
rebindAll(area$$1, base, exclude('bandwidth', 'align'));
rebind(area$$1, areaData, 'curve', 'context');
return area$$1;
});
var ohlcBase$1 = (function () {
var base = void 0;
var crossValue = function crossValue(d) {
return d.date;
};
var openValue = function openValue(d) {
return d.open;
};
var highValue = function highValue(d) {
return d.high;
};
var lowValue = function lowValue(d) {
return d.low;
};
var closeValue = function closeValue(d) {
return d.close;
};
var bandwidth = function bandwidth() {
return 5;
};
var align = 'center';
var crossValueScaled = function crossValueScaled(d, i) {
return base.xScale()(crossValue(d, i));
};
base = createBase({
decorate: function decorate() {},
defined: function defined(d, i) {
return defined$1(crossValue, openValue, lowValue, highValue, closeValue)(d, i);
},
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity()
});
base.values = function (d, i) {
var closeRaw = closeValue(d, i);
var openRaw = openValue(d, i);
var width = bandwidth(d, i);
var offset = alignOffset(align, width);
var direction = '';
if (closeRaw > openRaw) {
direction = 'up';
} else if (closeRaw < openRaw) {
direction = 'down';
}
return {
cross: crossValueScaled(d, i) + offset,
open: base.yScale()(openRaw),
high: base.yScale()(highValue(d, i)),
low: base.yScale()(lowValue(d, i)),
close: base.yScale()(closeRaw),
width: width,
direction: direction
};
};
base.crossValue = function () {
if (!arguments.length) {
return crossValue;
}
crossValue = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.openValue = function () {
if (!arguments.length) {
return openValue;
}
openValue = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.highValue = function () {
if (!arguments.length) {
return highValue;
}
highValue = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.lowValue = function () {
if (!arguments.length) {
return lowValue;
}
lowValue = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.yValue = base.closeValue = function () {
if (!arguments.length) {
return closeValue;
}
closeValue = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.bandwidth = function () {
if (!arguments.length) {
return bandwidth;
}
bandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.align = function () {
if (!arguments.length) {
return align;
}
align = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
return base;
});
var ohlcBase = (function (pathGenerator, seriesName) {
var base = ohlcBase$1();
var join = dataJoin('g', seriesName);
var containerTranslation = function containerTranslation(values) {
return 'translate(' + values.cross + ', ' + values.high + ')';
};
var propagateTransition = function propagateTransition(maybeTransition) {
return function (selection$$1) {
return maybeTransition.selection ? selection$$1.transition(maybeTransition) : selection$$1;
};
};
var candlestick = function candlestick(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
var transitionPropagator = propagateTransition(selection$$1);
selection$$1.each(function (data, index, group) {
var filteredData = data.filter(base.defined());
var g = join(d3Selection.select(group[index]), filteredData);
g.enter().attr('transform', function (d, i) {
return containerTranslation(base.values(d, i)) + ' scale(1e-6, 1)';
}).append('path');
g.each(function (d, i, g) {
var values = base.values(d, i);
var color = values.direction === 'up' ? colors.green : colors.red;
var singleCandlestick = transitionPropagator(d3Selection.select(g[i])).attr('class', seriesName + ' ' + values.direction).attr('stroke', color).attr('fill', color).attr('transform', function () {
return containerTranslation(values) + ' scale(1)';
});
pathGenerator.x(0).width(values.width).open(function () {
return values.open - values.high;
}).high(0).low(function () {
return values.low - values.high;
}).close(function () {
return values.close - values.high;
});
singleCandlestick.select('path').attr('d', pathGenerator([d]));
});
base.decorate()(g, data, index);
});
};
rebind(candlestick, join, 'key');
rebindAll(candlestick, base);
return candlestick;
});
var candlestick = (function () {
return ohlcBase(shapeCandlestick(), 'candlestick');
});
var ohlcBase$2 = (function (pathGenerator) {
var base = ohlcBase$1();
var candlestick = function candlestick(data) {
var filteredData = data.filter(base.defined());
var context = pathGenerator.context();
filteredData.forEach(function (d, i) {
context.save();
var values = base.values(d, i);
context.translate(values.cross, values.high);
context.beginPath();
pathGenerator.x(0).open(function () {
return values.open - values.high;
}).width(values.width).high(0).low(function () {
return values.low - values.high;
}).close(function () {
return values.close - values.high;
})([d]);
var color = values.direction === 'up' ? colors.green : colors.red;
context.strokeStyle = color;
context.fillStyle = color;
base.decorate()(context, d, i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
rebind(candlestick, pathGenerator, 'context');
rebindAll(candlestick, base);
return candlestick;
});
var candlestick$1 = (function () {
return ohlcBase$2(shapeCandlestick());
});
var boxPlotBase = (function () {
var upperQuartileValue = function upperQuartileValue(d) {
return d.upperQuartile;
};
var lowerQuartileValue = function lowerQuartileValue(d) {
return d.lowerQuartile;
};
var highValue = function highValue(d) {
return d.high;
};
var lowValue = function lowValue(d) {
return d.low;
};
var crossValue = function crossValue(d) {
return d.value;
};
var medianValue = function medianValue(d) {
return d.median;
};
var orient = 'vertical';
var align = 'center';
var bandwidth = function bandwidth() {
return 5;
};
var base = createBase({
decorate: function decorate() {},
defined: function defined(d, i) {
return defined$1(lowValue, highValue, lowerQuartileValue, upperQuartileValue, crossValue, medianValue)(d, i);
},
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity()
});
base.values = function (d, i) {
var width = bandwidth(d, i);
var offset = alignOffset(align, width);
var xScale = base.xScale();
var yScale = base.yScale();
if (orient === 'vertical') {
var y = yScale(highValue(d, i));
return {
origin: [xScale(crossValue(d, i)) + offset, y],
high: 0,
upperQuartile: yScale(upperQuartileValue(d, i)) - y,
median: yScale(medianValue(d, i)) - y,
lowerQuartile: yScale(lowerQuartileValue(d, i)) - y,
low: yScale(lowValue(d, i)) - y,
width: width
};
} else {
var x = xScale(lowValue(d, i));
return {
origin: [x, yScale(crossValue(d, i)) + offset],
high: xScale(highValue(d, i)) - x,
upperQuartile: xScale(upperQuartileValue(d, i)) - x,
median: xScale(medianValue(d, i)) - x,
lowerQuartile: xScale(lowerQuartileValue(d, i)) - x,
low: 0,
width: width
};
}
};
base.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.lowerQuartileValue = function () {
if (!arguments.length) {
return lowerQuartileValue;
}
lowerQuartileValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.upperQuartileValue = function () {
if (!arguments.length) {
return upperQuartileValue;
}
upperQuartileValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.lowValue = function () {
if (!arguments.length) {
return lowValue;
}
lowValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.highValue = function () {
if (!arguments.length) {
return highValue;
}
highValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.crossValue = function () {
if (!arguments.length) {
return crossValue;
}
crossValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.medianValue = function () {
if (!arguments.length) {
return medianValue;
}
medianValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.bandwidth = function () {
if (!arguments.length) {
return bandwidth;
}
bandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return base;
};
base.align = function () {
if (!arguments.length) {
return align;
}
align = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
return base;
});
var boxPlot = (function () {
var base = boxPlotBase();
var join = dataJoin('g', 'box-plot');
var pathGenerator = shapeBoxPlot().value(0);
var propagateTransition = function propagateTransition(maybeTransition) {
return function (selection$$1) {
return maybeTransition.selection ? selection$$1.transition(maybeTransition) : selection$$1;
};
};
var containerTranslation = function containerTranslation(values) {
return 'translate(' + values.origin[0] + ', ' + values.origin[1] + ')';
};
var boxPlot = function boxPlot(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
var transitionPropagator = propagateTransition(selection$$1);
selection$$1.each(function (data, index, group) {
var filteredData = data.filter(base.defined());
var g = join(d3Selection.select(group[index]), filteredData);
g.enter().attr('stroke', colors.black).attr('fill', colors.gray).attr('transform', function (d, i) {
return containerTranslation(base.values(d, i)) + ' scale(1e-6, 1)';
}).append('path');
pathGenerator.orient(base.orient());
g.each(function (d, i, g) {
var values = base.values(d, i);
pathGenerator.median(values.median).upperQuartile(values.upperQuartile).lowerQuartile(values.lowerQuartile).width(values.width).high(values.high).low(values.low);
transitionPropagator(d3Selection.select(g[i])).attr('transform', containerTranslation(values)).select('path').attr('d', pathGenerator([d]));
});
base.decorate()(g, data, index);
});
};
rebindAll(boxPlot, base);
rebind(boxPlot, join, 'key');
rebind(boxPlot, pathGenerator, 'cap');
return boxPlot;
});
var boxPlot$1 = (function () {
var base = boxPlotBase();
var pathGenerator = shapeBoxPlot().value(0);
var boxPlot = function boxPlot(data) {
var filteredData = data.filter(base.defined());
var context = pathGenerator.context();
pathGenerator.orient(base.orient());
filteredData.forEach(function (d, i) {
context.save();
var values = base.values(d, i);
context.translate(values.origin[0], values.origin[1]);
context.beginPath();
pathGenerator.median(values.median).upperQuartile(values.upperQuartile).lowerQuartile(values.lowerQuartile).high(values.high).width(values.width).low(values.low)([d]);
context.fillStyle = colors.gray;
context.strokeStyle = colors.black;
base.decorate()(context, d, i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
rebindAll(boxPlot, base);
rebind(boxPlot, pathGenerator, 'cap', 'context');
return boxPlot;
});
var ohlc = (function () {
return ohlcBase(shapeOhlc(), 'ohlc');
});
var ohlc$1 = (function () {
return ohlcBase$2(shapeOhlc());
});
var multiBase = (function () {
var series = [];
var mapping = function mapping(d) {
return d;
};
var key = function key(_, i) {
return i;
};
var multi = createBase({
decorate: function decorate() {},
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity()
});
multi.mapping = function () {
if (!arguments.length) {
return mapping;
}
mapping = arguments.length <= 0 ? undefined : arguments[0];
return multi;
};
multi.key = function () {
if (!arguments.length) {
return key;
}
key = arguments.length <= 0 ? undefined : arguments[0];
return multi;
};
multi.series = function () {
if (!arguments.length) {
return series;
}
series = arguments.length <= 0 ? undefined : arguments[0];
return multi;
};
return multi;
});
var seriesSvgMulti = (function () {
var base = multiBase();
var innerJoin = dataJoin('g');
var join = dataJoin('g', 'multi');
var multi = function multi(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
innerJoin.transition(selection$$1);
}
var mapping = base.mapping();
var series = base.series();
var xScale = base.xScale();
var yScale = base.yScale();
selection$$1.each(function (data, index, group) {
var container = join(d3Selection.select(group[index]), series);
// iterate over the containers, 'call'-ing the series for each
container.each(function (dataSeries, seriesIndex, seriesGroup) {
dataSeries.xScale(xScale).yScale(yScale);
var seriesData = mapping(data, seriesIndex, series);
var innerContainer = innerJoin(d3Selection.select(seriesGroup[seriesIndex]), [seriesData]);
innerContainer.call(dataSeries);
});
var unwrappedSelection = container.selection ? container.selection() : container;
unwrappedSelection.order();
base.decorate()(container, data, index);
});
};
rebindAll(multi, base);
rebind(multi, join, 'key');
return multi;
});
var seriesCanvasMulti = (function () {
var context = null;
var base = multiBase();
var multi = function multi(data) {
var mapping = base.mapping();
var series = base.series();
var xScale = base.xScale();
var yScale = base.yScale();
series.forEach(function (dataSeries, index) {
var seriesData = mapping(data, index, series);
dataSeries.context(context).xScale(xScale).yScale(yScale);
var adaptedDecorate = void 0;
if (dataSeries.decorate) {
adaptedDecorate = dataSeries.decorate();
dataSeries.decorate(function (c, d, i) {
base.decorate()(c, data, index);
adaptedDecorate(c, d, i);
});
} else {
base.decorate()(context, data, index);
}
dataSeries(seriesData);
if (adaptedDecorate) {
dataSeries.decorate(adaptedDecorate);
}
});
};
multi.context = function () {
if (!arguments.length) {
return context;
}
context = arguments.length <= 0 ? undefined : arguments[0];
return multi;
};
rebindAll(multi, base);
return multi;
});
var groupedBase = (function (series) {
var bandwidth = function bandwidth() {
return 50;
};
var align = 'center';
// the offset scale is used to offset each of the series within a group
var offsetScale = d3Scale.scaleBand();
var grouped = createBase({
decorate: function decorate() {},
xScale: d3Scale.scaleLinear(),
yScale: d3Scale.scaleLinear()
});
// the bandwidth for the grouped series can be a function of datum / index. As a result
// the offset scale required to cluster the 'sub' series is also dependent on datum / index.
// This function computes the offset scale for a specific datum / index of the grouped series
grouped.offsetScaleForDatum = function (data, d, i) {
var width = bandwidth(d, i);
var offset = alignOffset(align, width);
var halfWidth = width / 2;
return offsetScale.domain(d3Array.range(0, data.length)).range([-halfWidth + offset, halfWidth + offset]);
};
grouped.bandwidth = function () {
if (!arguments.length) {
return bandwidth;
}
bandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return grouped;
};
grouped.align = function () {
if (!arguments.length) {
return align;
}
align = arguments.length <= 0 ? undefined : arguments[0];
return grouped;
};
rebindAll(grouped, offsetScale, includeMap({ 'paddingInner': 'paddingOuter' }));
return grouped;
});
var grouped = (function (series) {
var base = groupedBase(series);
var join = dataJoin('g', 'grouped');
var grouped = function grouped(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
selection$$1.each(function (data, index, group) {
var g = join(d3Selection.select(group[index]), data);
g.enter().append('g');
g.select('g').each(function (_, index, group) {
var container = d3Selection.select(group[index]);
// create a composite scale that applies the required offset
var isVertical = series.orient() !== 'horizontal';
var compositeScale = function compositeScale(d, i) {
var offset = base.offsetScaleForDatum(data, d, i);
var baseScale = isVertical ? base.xScale() : base.yScale();
return baseScale(d) + offset(index) + offset.bandwidth() / 2;
};
if (isVertical) {
series.xScale(compositeScale);
series.yScale(base.yScale());
} else {
series.yScale(compositeScale);
series.xScale(base.xScale());
}
// if the sub-series has a bandwidth, set this from the offset scale
if (series.bandwidth) {
series.bandwidth(function (d, i) {
return base.offsetScaleForDatum(data, d, i).bandwidth();
});
}
// adapt the decorate function to give each series the correct index
series.decorate(function (s, d) {
return base.decorate()(s, d, index);
});
container.call(series);
});
});
};
rebindAll(grouped, series, exclude('decorate', 'xScale', 'yScale'));
rebindAll(grouped, base, exclude('offsetScaleForDatum'));
return grouped;
});
var grouped$1 = function (series) {
var base = groupedBase(series);
var grouped = function grouped(data) {
data.forEach(function (seriesData, index) {
// create a composite scale that applies the required offset
var isVertical = series.orient() !== 'horizontal';
var compositeScale = function compositeScale(d, i) {
var offset = base.offsetScaleForDatum(data, d, i);
var baseScale = isVertical ? base.xScale() : base.yScale();
return baseScale(d) + offset(index) + offset.bandwidth() / 2;
};
if (isVertical) {
series.xScale(compositeScale);
series.yScale(base.yScale());
} else {
series.yScale(compositeScale);
series.xScale(base.xScale());
}
// if the sub-series has a bandwidth, set this from the offset scale
if (series.bandwidth) {
series.bandwidth(function (d, i) {
return base.offsetScaleForDatum(data, d, i).bandwidth();
});
}
// adapt the decorate function to give each series the correct index
series.decorate(function (c, d) {
return base.decorate()(c, d, index);
});
series(seriesData);
});
};
rebindAll(grouped, series, exclude('decorate', 'xScale', 'yScale'));
rebindAll(grouped, base, exclude('offsetScaleForDatum'));
return grouped;
};
var repeat = (function () {
var orient = 'vertical';
var series = seriesSvgLine();
var multi = seriesSvgMulti();
var repeat = function repeat(selection$$1) {
return selection$$1.each(function (data, index, group) {
if (orient === 'vertical') {
multi.series(data[0].map(function (_) {
return series;
})).mapping(function (data, index) {
return data.map(function (d) {
return d[index];
});
});
} else {
multi.series(data.map(function (_) {
return series;
})).mapping(function (data, index) {
return data[index];
});
}
d3Selection.select(group[index]).call(multi);
});
};
repeat.series = function () {
if (!arguments.length) {
return series;
}
series = arguments.length <= 0 ? undefined : arguments[0];
return repeat;
};
repeat.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return repeat;
};
rebindAll(repeat, multi, exclude('series', 'mapping'));
return repeat;
});
var repeat$1 = (function () {
var orient = 'vertical';
var series = seriesCanvasLine();
var multi = seriesCanvasMulti();
var repeat = function repeat(data) {
if (orient === 'vertical') {
multi.series(data[0].map(function (_) {
return series;
})).mapping(function (data, index) {
return data.map(function (d) {
return d[index];
});
});
} else {
multi.series(data.map(function (_) {
return series;
})).mapping(function (data, index) {
return data[index];
});
}
multi(data);
};
repeat.series = function () {
if (!arguments.length) {
return series;
}
series = arguments.length <= 0 ? undefined : arguments[0];
return repeat;
};
repeat.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return repeat;
};
rebindAll(repeat, multi, exclude('series', 'mapping'));
return repeat;
});
var sortUnique = function sortUnique(arr) {
return arr.sort(d3Array.ascending).filter(function (value, index, self) {
return self.indexOf(value, index + 1) === -1;
});
};
var autoBandwidth = (function (adaptee) {
var widthFraction = 0.75;
// computes the bandwidth as a fraction of the smallest distance between the datapoints
var computeBandwidth = function computeBandwidth(screenValues) {
// return some default value if there are not enough datapoints to compute the width
if (screenValues.length <= 1) {
return 10;
}
screenValues = sortUnique(screenValues);
// compute the distance between neighbouring items
var neighbourDistances = d3Array.pairs(screenValues).map(function (tuple) {
return Math.abs(tuple[0] - tuple[1]);
});
var minDistance = d3Array.min(neighbourDistances);
return widthFraction * minDistance;
};
var determineBandwith = function determineBandwith(crossScale, data, accessor) {
// if the cross-scale has a bandwidth function, i.e. it is a scaleBand, use
// this to determine the width
if (crossScale.bandwidth) {
return crossScale.bandwidth();
} else {
var _ref;
// grouped series expect a nested array, which is flattened out
var flattenedData = Array.isArray(data) ? (_ref = []).concat.apply(_ref, toConsumableArray(data)) : data;
// obtain an array of points along the crossValue axis, mapped to screen coordinates.
var crossValuePoints = flattenedData.filter(adaptee.defined()).map(accessor()).map(crossScale);
var width = computeBandwidth(crossValuePoints);
return width;
}
};
var autoBandwidth = function autoBandwidth(arg) {
var computeWidth = function computeWidth(data) {
if (adaptee.xBandwidth && adaptee.yBandwidth) {
adaptee.xBandwidth(determineBandwith(adaptee.xScale(), data, adaptee.xValue));
adaptee.yBandwidth(determineBandwith(adaptee.yScale(), data, adaptee.yValue));
} else {
// if the series has an orient property, use this to determine the cross-scale, otherwise
// assume it is the x-scale
var crossScale = adaptee.orient && adaptee.orient() === 'horizontal' ? adaptee.yScale() : adaptee.xScale();
adaptee.bandwidth(determineBandwith(crossScale, data, adaptee.crossValue));
}
};
if (arg instanceof d3Selection.selection) {
arg.each(function (data, index, group) {
computeWidth(data);
adaptee(d3Selection.select(group[index]));
});
} else {
computeWidth(arg);
adaptee(arg);
}
};
rebindAll(autoBandwidth, adaptee);
autoBandwidth.widthFraction = function () {
if (!arguments.length) {
return widthFraction;
}
widthFraction = arguments.length <= 0 ? undefined : arguments[0];
return autoBandwidth;
};
return autoBandwidth;
});
var heatmapBase = (function () {
var xValue = function xValue(d) {
return d.x;
};
var yValue = function yValue(d) {
return d.y;
};
var colorValue = function colorValue(d) {
return d.color;
};
var yBandwidth = function yBandwidth() {
return 5;
};
var xBandwidth = function xBandwidth() {
return 5;
};
var colorInterpolate = d3Scale.interpolateViridis;
var heatmap = createBase({
decorate: function decorate() {},
defined: function defined(d, i) {
return defined$1(xValue, yValue, colorValue)(d, i);
},
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity()
});
heatmap.pathGenerator = shapeBar().x(0).y(0);
heatmap.colorScale = function (data) {
var colorValues = data.map(colorValue);
// a scale that maps the color values onto a unit range, [0, 1]
return d3Scale.scaleLinear().domain([d3Array.min(colorValues), d3Array.max(colorValues)]);
};
heatmap.values = function (d, i) {
return {
x: heatmap.xScale()(xValue(d, i)),
y: heatmap.yScale()(yValue(d, i)),
colorValue: colorValue(d, i),
width: xBandwidth(d, i),
height: yBandwidth(d, i)
};
};
heatmap.xValue = function () {
if (!arguments.length) {
return xValue;
}
xValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return heatmap;
};
heatmap.yValue = function () {
if (!arguments.length) {
return yValue;
}
yValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return heatmap;
};
heatmap.colorValue = function () {
if (!arguments.length) {
return colorValue;
}
colorValue = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return heatmap;
};
heatmap.colorInterpolate = function () {
if (!arguments.length) {
return colorInterpolate;
}
colorInterpolate = arguments.length <= 0 ? undefined : arguments[0];
return heatmap;
};
heatmap.xBandwidth = function () {
if (!arguments.length) {
return xBandwidth;
}
xBandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return heatmap;
};
heatmap.yBandwidth = function () {
if (!arguments.length) {
return yBandwidth;
}
yBandwidth = functor$4(arguments.length <= 0 ? undefined : arguments[0]);
return heatmap;
};
rebindAll(heatmap, heatmap.pathGenerator, includeMap({
'horizontalAlign': 'xAlign',
'verticalAlign': 'yAlign'
}));
return heatmap;
});
var heatmap = (function () {
var base = heatmapBase();
var join = dataJoin('g', 'box');
var containerTransform = function containerTransform(values) {
return 'translate(' + values.x + ', ' + values.y + ')';
};
var heatmap = function heatmap(selection$$1) {
selection$$1.each(function (data, index, group) {
var filteredData = data.filter(base.defined());
var colorValue = base.colorValue();
var colorInterpolate = base.colorInterpolate();
var colorScale = base.colorScale(filteredData);
var g = join(d3Selection.select(group[index]), filteredData);
g.enter().append('path').attr('stroke', 'transparent');
g.attr('transform', function (d, i) {
return containerTransform(base.values(d, i));
}).select('path').attr('d', function (d, i) {
return base.pathGenerator.width(base.values(d, i).width).height(base.values(d, i).height)([d]);
}).attr('fill', function (d, i) {
return colorInterpolate(colorScale(colorValue(d, i)));
});
base.decorate()(g, data, index);
});
};
rebindAll(heatmap, base);
return heatmap;
});
var heatmap$1 = (function () {
var context = null;
var base = heatmapBase();
var heatmap = function heatmap(data) {
var filteredData = data.filter(base.defined());
var colorValue = base.colorValue();
var colorInterpolate = base.colorInterpolate();
var colorScale = base.colorScale(filteredData);
var context = base.pathGenerator.context();
filteredData.forEach(function (d, i) {
context.save();
context.beginPath();
var values = base.values(d, i);
context.translate(values.x, values.y);
context.fillStyle = colorInterpolate(colorScale(values.colorValue));
context.strokeStyle = 'transparent';
base.pathGenerator.height(values.height).width(values.width)([d]);
base.decorate()(context, d, i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
rebind(heatmap, base.pathGenerator, 'context');
rebindAll(heatmap, base);
return heatmap;
});
var constant = (function (value) {
return typeof value === 'function' ? value : function () {
return value;
};
});
var band = (function () {
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var orient = 'horizontal';
var fromValue = function fromValue(d) {
return d.from;
};
var toValue = function toValue(d) {
return d.to;
};
var decorate = function decorate() {};
var join = dataJoin('g', 'annotation-band');
var pathGenerator = shapeBar().horizontalAlign('center').verticalAlign('center').x(0).y(0);
var instance = function instance(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
if (orient !== 'horizontal' && orient !== 'vertical') {
throw new Error('Invalid orientation');
}
var horizontal = orient === 'horizontal';
var translation = horizontal ? function (a, b) {
return 'translate(' + a + ', ' + b + ')';
} : function (a, b) {
return 'translate(' + b + ', ' + a + ')';
};
// the value scale which the annotation 'value' relates to, the crossScale
// is the other. Which is which depends on the orienation!
var crossScale = horizontal ? xScale : yScale;
var valueScale = horizontal ? yScale : xScale;
var crossScaleRange = crossScale.range();
var crossScaleSize = crossScaleRange[1] - crossScaleRange[0];
var valueAxisDimension = horizontal ? 'height' : 'width';
var crossAxisDimension = horizontal ? 'width' : 'height';
var containerTransform = function containerTransform() {
return translation((crossScaleRange[1] + crossScaleRange[0]) / 2, (valueScale(toValue.apply(undefined, arguments)) + valueScale(fromValue.apply(undefined, arguments))) / 2);
};
pathGenerator[crossAxisDimension](crossScaleSize);
pathGenerator[valueAxisDimension](function () {
return valueScale(toValue.apply(undefined, arguments)) - valueScale(fromValue.apply(undefined, arguments));
});
selection$$1.each(function (data, index, nodes) {
var g = join(d3Selection.select(nodes[index]), data);
g.enter().attr('transform', containerTransform).append('path').classed('band', true);
g.attr('class', 'annotation-band ' + orient).attr('transform', containerTransform).select('path')
// the path generator is being used to render a single path, hence
// an explicit index is provided
.attr('d', function (d, i) {
return pathGenerator([d], i);
});
decorate(g, data, index);
});
};
instance.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.fromValue = function () {
if (!arguments.length) {
return fromValue;
}
fromValue = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
instance.toValue = function () {
if (!arguments.length) {
return toValue;
}
toValue = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
return instance;
});
var band$1 = (function () {
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var orient = 'horizontal';
var fromValue = function fromValue(d) {
return d.from;
};
var toValue = function toValue(d) {
return d.to;
};
var decorate = function decorate() {};
var pathGenerator = shapeBar().horizontalAlign('right').verticalAlign('top');
var instance = function instance(data) {
if (orient !== 'horizontal' && orient !== 'vertical') {
throw new Error('Invalid orientation');
}
var context = pathGenerator.context();
var horizontal = orient === 'horizontal';
// the value scale which the annotation 'value' relates to, the crossScale
// is the other. Which is which depends on the orienation!
var crossScale = horizontal ? xScale : yScale;
var valueScale = horizontal ? yScale : xScale;
var crossScaleRange = crossScale.range();
var crossScaleSize = crossScaleRange[1] - crossScaleRange[0];
var valueAxisStart = horizontal ? 'x' : 'y';
var crossAxisStart = horizontal ? 'y' : 'x';
var valueAxisDimension = horizontal ? 'height' : 'width';
var crossAxisDimension = horizontal ? 'width' : 'height';
data.forEach(function (d, i) {
context.save();
context.beginPath();
context.strokeStyle = 'transparent';
pathGenerator[crossAxisStart](valueScale(fromValue(d)));
pathGenerator[valueAxisStart](crossScaleRange[0]);
pathGenerator[crossAxisDimension](crossScaleSize);
pathGenerator[valueAxisDimension](valueScale(toValue(d)) - valueScale(fromValue(d)));
decorate(context, d, i);
pathGenerator.context(context)([d], i);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
instance.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.fromValue = function () {
if (!arguments.length) {
return fromValue;
}
fromValue = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
instance.toValue = function () {
if (!arguments.length) {
return toValue;
}
toValue = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
rebind(instance, pathGenerator, 'context');
return instance;
});
var annotationLine = (function () {
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var value = function value(d) {
return d;
};
var label = value;
var decorate = function decorate() {};
var orient = 'horizontal';
var join = dataJoin('g', 'annotation-line');
var instance = function instance(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
if (orient !== 'horizontal' && orient !== 'vertical') {
throw new Error('Invalid orientation');
}
var horizontal = orient === 'horizontal';
var translation = horizontal ? function (a, b) {
return 'translate(' + a + ', ' + b + ')';
} : function (a, b) {
return 'translate(' + b + ', ' + a + ')';
};
var lineProperty = horizontal ? 'x2' : 'y2';
// the value scale which the annotation 'value' relates to, the crossScale
// is the other. Which is which depends on the orienation!
var crossScale = horizontal ? xScale : yScale;
var valueScale = horizontal ? yScale : xScale;
var handleOne = horizontal ? 'left-handle' : 'bottom-handle';
var handleTwo = horizontal ? 'right-handle' : 'top-handle';
var textOffsetX = horizontal ? '9' : '0';
var textOffsetY = horizontal ? '0' : '9';
var textOffsetDeltaY = horizontal ? '0.32em' : '0.71em';
var textAnchor = horizontal ? 'start' : 'middle';
var scaleRange = crossScale.range();
// the transform that sets the 'origin' of the annotation
var containerTransform = function containerTransform() {
return translation(scaleRange[0], valueScale(value.apply(undefined, arguments)));
};
var scaleWidth = scaleRange[1] - scaleRange[0];
selection$$1.each(function (data, selectionIndex, nodes) {
var g = join(d3Selection.select(nodes[selectionIndex]), data);
// create the outer container and line
var enter = g.enter().attr('transform', containerTransform).style('stroke', '#bbb');
enter.append('line').attr(lineProperty, scaleWidth);
// create containers at each end of the annotation
enter.append('g').classed(handleOne, true).style('stroke', 'none');
enter.append('g').classed(handleTwo, true).style('stroke', 'none').attr('transform', translation(scaleWidth, 0)).append('text').attr('text-anchor', textAnchor).attr('x', textOffsetX).attr('y', textOffsetY).attr('dy', textOffsetDeltaY);
// Update
g.attr('class', 'annotation-line ' + orient);
// translate the parent container to the left hand edge of the annotation
g.attr('transform', containerTransform);
// update the elements that depend on scale width
g.select('line').attr(lineProperty, scaleWidth);
g.select('g.' + handleTwo).attr('transform', translation(scaleWidth, 0));
// Update the text label
g.select('text').text(label);
decorate(g, data, selectionIndex);
});
};
instance.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.value = function () {
if (!arguments.length) {
return value;
}
value = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
instance.label = function () {
if (!arguments.length) {
return label;
}
label = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
instance.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
return instance;
});
var crosshair = function () {
var x = function x(d) {
return d.x;
};
var y = function y(d) {
return d.y;
};
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var decorate = function decorate() {};
var join = dataJoin('g', 'annotation-crosshair');
var point = seriesSvgPoint();
var horizontalLine = annotationLine();
var verticalLine = annotationLine().orient('vertical');
// The line annotations and point series used to render the crosshair are positioned using
// screen coordinates. This function constructs an identity scale for these components.
var xIdentity = d3Scale.scaleIdentity();
var yIdentity = d3Scale.scaleIdentity();
var multi = seriesSvgMulti().series([horizontalLine, verticalLine, point]).xScale(xIdentity).yScale(yIdentity).mapping(function (data) {
return [data];
});
var instance = function instance(selection$$1) {
if (selection$$1.selection) {
join.transition(selection$$1);
}
selection$$1.each(function (data, index, nodes) {
var g = join(d3Selection.select(nodes[index]), data);
// Prevent the crosshair triggering pointer events on itself
g.enter().style('pointer-events', 'none');
// Assign the identity scales an accurate range to allow the line annotations to cover
// the full width/height of the chart.
xIdentity.range(xScale.range());
yIdentity.range(yScale.range());
point.crossValue(x).mainValue(y);
horizontalLine.value(y);
verticalLine.value(x);
g.call(multi);
decorate(g, data, index);
});
};
// Don't use the xValue/yValue convention to indicate that these values are in screen
// not domain co-ordinates and are therefore not scaled.
instance.x = function () {
if (!arguments.length) {
return x;
}
x = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.y = function () {
if (!arguments.length) {
return y;
}
y = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
var lineIncludes = include('label');
rebindAll(instance, horizontalLine, lineIncludes, prefix('y'));
rebindAll(instance, verticalLine, lineIncludes, prefix('x'));
return instance;
};
var annotationLine$1 = (function () {
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var value = function value(d) {
return d;
};
var label = value;
var decorate = function decorate() {};
var orient = 'horizontal';
var lineData = d3Shape.line();
var instance = function instance(data) {
if (orient !== 'horizontal' && orient !== 'vertical') {
throw new Error('Invalid orientation');
}
var horizontal = orient === 'horizontal';
var context = lineData.context();
// the value scale which the annotation 'value' relates to, the crossScale
// is the other. Which is which depends on the orienation!
var crossScale = horizontal ? xScale : yScale;
var valueScale = horizontal ? yScale : xScale;
var crossDomain = crossScale.domain();
var textOffsetX = horizontal ? 9 : 0;
var textOffsetY = horizontal ? 0 : 9;
var textAlign = horizontal ? 'left' : 'center';
var textBaseline = horizontal ? 'middle' : 'hanging';
data.forEach(function (d, i) {
context.save();
context.beginPath();
context.strokeStyle = '#bbb';
context.fillStyle = '#000';
context.textAlign = textAlign;
context.textBaseline = textBaseline;
decorate(context, d, i);
// Draw line
lineData.context(context)(crossDomain.map(function (extent$$1) {
var point = [crossScale(extent$$1), valueScale(value(d))];
return horizontal ? point : point.reverse();
}));
// Draw label
var x = horizontal ? crossScale(crossDomain[1]) : valueScale(value(d));
var y = horizontal ? valueScale(value(d)) : crossScale(crossDomain[1]);
context.fillText(label(d), x + textOffsetX, y + textOffsetY);
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
instance.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.value = function () {
if (!arguments.length) {
return value;
}
value = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
instance.label = function () {
if (!arguments.length) {
return label;
}
label = constant(arguments.length <= 0 ? undefined : arguments[0]);
return instance;
};
instance.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
rebind(instance, lineData, 'context');
return instance;
});
var crosshair$1 = (function () {
var x = function x(d) {
return d.x;
};
var y = function y(d) {
return d.y;
};
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var point = seriesCanvasPoint();
var horizontalLine = annotationLine$1();
var verticalLine = annotationLine$1().orient('vertical');
// The line annotations and point series used to render the crosshair are positioned using
// screen coordinates. This function constructs an identity scale for these components.
var xIdentity = d3Scale.scaleIdentity();
var yIdentity = d3Scale.scaleIdentity();
var multi = seriesCanvasMulti().series([horizontalLine, verticalLine, point]).xScale(xIdentity).yScale(yIdentity).mapping(function (data) {
return [data];
});
var instance = function instance(data) {
data.forEach(function (d) {
// Assign the identity scales an accurate range to allow the line annotations to cover
// the full width/height of the chart.
xIdentity.range(xScale.range());
yIdentity.range(yScale.range());
point.crossValue(x).mainValue(y);
horizontalLine.value(y);
verticalLine.value(x);
multi(d);
});
};
// Don't use the xValue/yValue convention to indicate that these values are in screen
// not domain co-ordinates and are therefore not scaled.
instance.x = function () {
if (!arguments.length) {
return x;
}
x = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.y = function () {
if (!arguments.length) {
return y;
}
y = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
var lineIncludes = include('label', 'decorate');
rebindAll(instance, horizontalLine, lineIncludes, prefix('y'));
rebindAll(instance, verticalLine, lineIncludes, prefix('x'));
rebind(instance, point, 'decorate');
rebind(instance, multi, 'context');
return instance;
});
var ticks = (function () {
var scale = d3Scale.scaleIdentity();
var tickArguments = [10];
var tickValues = null;
var ticks = function ticks() {
var _scale;
return tickValues != null ? tickValues : scale.ticks ? (_scale = scale).ticks.apply(_scale, toConsumableArray(tickArguments)) : scale.domain();
};
ticks.scale = function () {
if (!arguments.length) {
return scale;
}
scale = arguments.length <= 0 ? undefined : arguments[0];
return ticks;
};
ticks.ticks = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
tickArguments = args;
return ticks;
};
ticks.tickArguments = function () {
if (!arguments.length) {
return tickArguments;
}
tickArguments = arguments.length <= 0 ? undefined : arguments[0];
return ticks;
};
ticks.tickValues = function () {
if (!arguments.length) {
return tickValues;
}
tickValues = arguments.length <= 0 ? undefined : arguments[0];
return ticks;
};
return ticks;
});
var identity$2 = function identity$2(d) {
return d;
};
var gridline = (function () {
var xDecorate = function xDecorate() {};
var yDecorate = function yDecorate() {};
var xTicks = ticks();
var yTicks = ticks();
var xJoin = dataJoin('line', 'gridline-y').key(identity$2);
var yJoin = dataJoin('line', 'gridline-x').key(identity$2);
var instance = function instance(selection$$1) {
if (selection$$1.selection) {
xJoin.transition(selection$$1);
yJoin.transition(selection$$1);
}
selection$$1.each(function (data, index, nodes) {
var element = nodes[index];
var container = d3Selection.select(nodes[index]);
var xScale = xTicks.scale();
var yScale = yTicks.scale();
// Stash a snapshot of the scale, and retrieve the old snapshot.
var xScaleOld = element.__x_scale__ || xScale;
element.__x_scale__ = xScale.copy();
var xData = xTicks();
var xLines = xJoin(container, xData);
xLines.enter().attr('x1', xScaleOld).attr('x2', xScaleOld).attr('y1', yScale.range()[0]).attr('y2', yScale.range()[1]);
xLines.attr('x1', xScale).attr('x2', xScale).attr('y1', yScale.range()[0]).attr('y2', yScale.range()[1]).attr('stroke', '#bbb');
xLines.exit().attr('x1', xScale).attr('x2', xScale);
xDecorate(xLines, xData, index);
// Stash a snapshot of the scale, and retrieve the old snapshot.
var yScaleOld = element.__y_scale__ || yScale;
element.__y_scale__ = yScale.copy();
var yData = yTicks();
var yLines = yJoin(container, yData);
yLines.enter().attr('y1', yScaleOld).attr('y2', yScaleOld).attr('x1', xScale.range()[0]).attr('x2', xScale.range()[1]);
yLines.attr('y1', yScale).attr('y2', yScale).attr('x1', xScale.range()[0]).attr('x2', xScale.range()[1]).attr('stroke', '#bbb');
yLines.exit().attr('y1', yScale).attr('y2', yScale);
yDecorate(yLines, yData, index);
});
};
instance.yDecorate = function () {
if (!arguments.length) {
return yDecorate;
}
yDecorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.xDecorate = function () {
if (!arguments.length) {
return xDecorate;
}
xDecorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
rebindAll(instance, xJoin, includeMap({ 'key': 'xKey' }));
rebindAll(instance, yJoin, includeMap({ 'key': 'yKey' }));
rebindAll(instance, xTicks, prefix('x'));
rebindAll(instance, yTicks, prefix('y'));
return instance;
});
var gridline$1 = (function () {
var xDecorate = function xDecorate() {};
var yDecorate = function yDecorate() {};
var xTicks = ticks();
var yTicks = ticks();
var lineData = d3Shape.line();
var instance = function instance() {
var context = lineData.context();
var xScale = xTicks.scale();
var yScale = yTicks.scale();
xTicks().forEach(function (xTick, i) {
context.save();
context.beginPath();
context.strokeStyle = '#bbb';
context.fillStyle = 'transparent';
xDecorate(context, xTick, i);
lineData.context(context)(yScale.domain().map(function (d) {
return [xScale(xTick), yScale(d)];
}));
context.fill();
context.stroke();
context.closePath();
context.restore();
});
yTicks().forEach(function (yTick, i) {
context.save();
context.beginPath();
context.strokeStyle = '#bbb';
context.fillStyle = 'transparent';
yDecorate(context, yTick, i);
lineData.context(context)(xScale.domain().map(function (d) {
return [xScale(d), yScale(yTick)];
}));
context.fill();
context.stroke();
context.closePath();
context.restore();
});
};
instance.yDecorate = function () {
if (!arguments.length) {
return yDecorate;
}
yDecorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
instance.xDecorate = function () {
if (!arguments.length) {
return xDecorate;
}
xDecorate = arguments.length <= 0 ? undefined : arguments[0];
return instance;
};
rebindAll(instance, xTicks, prefix('x'));
rebindAll(instance, yTicks, prefix('y'));
rebind(instance, lineData, 'context');
return instance;
});
var identity$3 = function identity$3(d) {
return d;
};
var axisBase = function axisBase(orient, scale) {
var custom = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var tickArguments = [10];
var tickValues = null;
var decorate = function decorate() {};
var tickFormat = null;
var tickSizeOuter = 6;
var tickSizeInner = 6;
var tickPadding = 3;
var svgDomainLine = d3Shape.line();
var dataJoin$$1 = dataJoin('g', 'tick').key(identity$3);
var domainPathDataJoin = dataJoin('path', 'domain');
var defaultLabelOffset = function defaultLabelOffset() {
return { offset: [0, tickSizeInner + tickPadding] };
};
var defaultTickPath = function defaultTickPath() {
return { path: [[0, 0], [0, tickSizeInner]] };
};
var labelOffset = custom.labelOffset || defaultLabelOffset;
var tickPath = custom.tickPath || defaultTickPath;
// returns a function that creates a translation based on
// the bound data
var containerTranslate = function containerTranslate(scale, trans) {
var offset = 0;
if (scale.bandwidth) {
offset = scale.bandwidth() / 2;
if (scale.round()) {
offset = Math.round(offset);
}
}
return function (d) {
return trans(scale(d) + offset, 0);
};
};
var translate = function translate(x, y) {
return isVertical() ? 'translate(' + y + ', ' + x + ')' : 'translate(' + x + ', ' + y + ')';
};
var pathTranspose = function pathTranspose(arr) {
return isVertical() ? arr.map(function (d) {
return [d[1], d[0]];
}) : arr;
};
var isVertical = function isVertical() {
return orient === 'left' || orient === 'right';
};
var tryApply = function tryApply(fn, args, defaultVal) {
return scale[fn] ? scale[fn].apply(scale, args) : defaultVal;
};
var axis = function axis(selection$$1) {
if (selection$$1.selection) {
dataJoin$$1.transition(selection$$1);
domainPathDataJoin.transition(selection$$1);
}
selection$$1.each(function (data, index, group) {
var element = group[index];
var container = d3Selection.select(element);
if (!element.__scale__) {
container.attr('fill', 'none').attr('font-size', 10).attr('font-family', 'sans-serif').attr('text-anchor', orient === 'right' ? 'start' : orient === 'left' ? 'end' : 'middle');
}
// Stash a snapshot of the new scale, and retrieve the old snapshot.
var scaleOld = element.__scale__ || scale;
element.__scale__ = scale.copy();
var ticksArray = tickValues == null ? tryApply('ticks', tickArguments, scale.domain()) : tickValues;
var tickFormatter = tickFormat == null ? tryApply('tickFormat', tickArguments, identity$3) : tickFormat;
var sign = orient === 'bottom' || orient === 'right' ? 1 : -1;
var withSign = function withSign(_ref) {
var _ref2 = slicedToArray(_ref, 2),
x = _ref2[0],
y = _ref2[1];
return [x, sign * y];
};
// add the domain line
var range$$1 = scale.range();
var domainPathData = pathTranspose([[range$$1[0], sign * tickSizeOuter], [range$$1[0], 0], [range$$1[1], 0], [range$$1[1], sign * tickSizeOuter]]);
var domainLine = domainPathDataJoin(container, [data]);
domainLine.attr('d', svgDomainLine(domainPathData)).attr('stroke', '#000');
var g = dataJoin$$1(container, ticksArray);
var labelOffsets = ticksArray.map(function (d, i) {
return labelOffset(d, i, ticksArray);
});
var tickPaths = ticksArray.map(function (d, i) {
return tickPath(d, i, ticksArray);
});
// enter
g.enter().attr('transform', containerTranslate(scaleOld, translate)).append('path').attr('stroke', '#000');
g.enter().append('text').attr('transform', function (d, i) {
return translate.apply(undefined, toConsumableArray(withSign(labelOffsets[i].offset)));
}).attr('fill', '#000');
// exit
g.exit().attr('transform', containerTranslate(scale, translate));
// update
g.select('path').attr('visibility', function (d, i) {
return tickPaths[i].hidden && 'hidden';
}).attr('d', function (d, i) {
return svgDomainLine(pathTranspose(tickPaths[i].path.map(withSign)));
});
g.select('text').attr('visibility', function (d, i) {
return labelOffsets[i].hidden && 'hidden';
}).attr('transform', function (d, i) {
return translate.apply(undefined, toConsumableArray(withSign(labelOffsets[i].offset)));
}).attr('dy', function () {
var offset = '0em';
if (isVertical()) {
offset = '0.32em';
} else if (orient === 'bottom') {
offset = '0.71em';
}
return offset;
}).text(tickFormatter);
g.attr('transform', containerTranslate(scale, translate));
decorate(g, data, index);
});
};
axis.tickFormat = function () {
if (!arguments.length) {
return tickFormat;
}
tickFormat = arguments.length <= 0 ? undefined : arguments[0];
return axis;
};
axis.tickSize = function () {
if (!arguments.length) {
return tickSizeInner;
}
tickSizeInner = tickSizeOuter = Number(arguments.length <= 0 ? undefined : arguments[0]);
return axis;
};
axis.tickSizeInner = function () {
if (!arguments.length) {
return tickSizeInner;
}
tickSizeInner = Number(arguments.length <= 0 ? undefined : arguments[0]);
return axis;
};
axis.tickSizeOuter = function () {
if (!arguments.length) {
return tickSizeOuter;
}
tickSizeOuter = Number(arguments.length <= 0 ? undefined : arguments[0]);
return axis;
};
axis.tickPadding = function () {
if (!arguments.length) {
return tickPadding;
}
tickPadding = arguments.length <= 0 ? undefined : arguments[0];
return axis;
};
axis.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return axis;
};
axis.scale = function () {
if (!arguments.length) {
return scale;
}
scale = arguments.length <= 0 ? undefined : arguments[0];
return axis;
};
axis.ticks = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
tickArguments = [].concat(args);
return axis;
};
axis.tickArguments = function () {
if (!arguments.length) {
return tickArguments.slice();
}
tickArguments = (arguments.length <= 0 ? undefined : arguments[0]) == null ? [] : [].concat(toConsumableArray(arguments.length <= 0 ? undefined : arguments[0]));
return axis;
};
axis.tickValues = function () {
if (!arguments.length) {
return tickValues.slice();
}
tickValues = (arguments.length <= 0 ? undefined : arguments[0]) == null ? [] : [].concat(toConsumableArray(arguments.length <= 0 ? undefined : arguments[0]));
return axis;
};
axis.orient = function () {
return orient;
};
return axis;
};
var axis = function axis(orient, scale) {
var tickCenterLabel = false;
var labelOffset = function labelOffset(tick, index, ticksArray) {
var x = 0;
var y = base.tickSizeInner() + base.tickPadding();
var hidden = false;
if (tickCenterLabel) {
var thisPosition = scale(tick);
var nextPosition = index < ticksArray.length - 1 ? scale(ticksArray[index + 1]) : scale.range()[1];
x = (nextPosition - thisPosition) / 2;
y = base.tickPadding();
hidden = index === ticksArray.length - 1 && thisPosition === nextPosition;
}
return { offset: [x, y], hidden: hidden };
};
var base = axisBase(orient, scale, { labelOffset: labelOffset });
var axis = function axis(selection$$1) {
return base(selection$$1);
};
axis.tickCenterLabel = function () {
if (!arguments.length) {
return tickCenterLabel;
}
tickCenterLabel = arguments.length <= 0 ? undefined : arguments[0];
return axis;
};
rebindAll(axis, base);
return axis;
};
var axisTop = function axisTop(scale) {
return axis('top', scale);
};
var axisBottom = function axisBottom(scale) {
return axis('bottom', scale);
};
var axisLeft = function axisLeft(scale) {
return axis('left', scale);
};
var axisRight = function axisRight(scale) {
return axis('right', scale);
};
var axisOrdinal = function axisOrdinal(orient, scale) {
var tickOffset = null;
var step = function step(tick, index, ticksArray) {
if (scale.step) {
// Use the scale step size
return scale.step();
}
var thisPosition = scale(tick);
if (index < ticksArray.length - 1) {
// Distance between ticks
return scale(ticksArray[index + 1]) / thisPosition;
} else {
// 2* distance to end
return (scale.range()[1] - thisPosition) * 2;
}
};
var tickPath = function tickPath(tick, index, ticksArray) {
var x = 0;
if (tickOffset) {
x = tickOffset(tick, index);
} else {
x = step(tick, index, ticksArray) / 2;
}
return {
path: [[x, 0], [x, base.tickSizeInner()]],
hidden: index === ticksArray.length - 1
};
};
var labelOffset = function labelOffset() {
// Don't include the tickSizeInner in the label positioning
return { offset: [0, base.tickPadding()] };
};
var base = axisBase(orient, scale, { labelOffset: labelOffset, tickPath: tickPath });
var axis = function axis(selection$$1) {
base(selection$$1);
};
axis.tickOffset = function () {
if (!arguments.length) {
return tickOffset;
}
tickOffset = arguments.length <= 0 ? undefined : arguments[0];
return axis;
};
rebindAll(axis, base);
return axis;
};
var axisOrdinalTop = function axisOrdinalTop(scale) {
return axisOrdinal('top', scale);
};
var axisOrdinalBottom = function axisOrdinalBottom(scale) {
return axisOrdinal('bottom', scale);
};
var axisOrdinalLeft = function axisOrdinalLeft(scale) {
return axisOrdinal('left', scale);
};
var axisOrdinalRight = function axisOrdinalRight(scale) {
return axisOrdinal('right', scale);
};
var measureLabels = (function (scale) {
var measure = function measure(selection$$1) {
var labels = scale['ticks'] ? scale.ticks() : scale.domain();
var tester = selection$$1.append('text');
var boundingBoxes = labels.map(function (l) {
return tester.text(l).node().getBBox();
});
var maxHeight = Math.max.apply(Math, toConsumableArray(boundingBoxes.map(function (b) {
return b.height;
})));
var maxWidth = Math.max.apply(Math, toConsumableArray(boundingBoxes.map(function (b) {
return b.width;
})));
tester.remove();
return {
maxHeight: maxHeight,
maxWidth: maxWidth,
labelCount: labels.length
};
};
return measure;
});
var axisLabelRotate = (function (adaptee) {
var labelRotate = 'auto';
var decorate = function decorate() {};
var isVertical = function isVertical() {
return adaptee.orient() === 'left' || adaptee.orient() === 'right';
};
var sign = function sign() {
return adaptee.orient() === 'top' || adaptee.orient() === 'left' ? -1 : 1;
};
var labelAnchor = function labelAnchor() {
switch (adaptee.orient()) {
case 'top':
case 'right':
return 'start';
default:
return 'end';
}
};
var calculateRotation = function calculateRotation(s) {
var _measureLabels = measureLabels(adaptee.scale())(s),
maxHeight = _measureLabels.maxHeight,
maxWidth = _measureLabels.maxWidth,
labelCount = _measureLabels.labelCount;
var measuredSize = labelCount * maxWidth;
// The more the overlap, the more we rotate
var rotate = void 0;
if (labelRotate === 'auto') {
var range$$1 = adaptee.scale().range()[1];
rotate = range$$1 < measuredSize ? 90 * Math.min(1, (measuredSize / range$$1 - 0.8) / 2) : 0;
} else {
rotate = labelRotate;
}
return {
rotate: isVertical() ? Math.floor(sign() * (90 - rotate)) : Math.floor(-rotate),
maxHeight: maxHeight,
maxWidth: maxWidth,
anchor: rotate ? labelAnchor() : 'middle'
};
};
var decorateRotation = function decorateRotation(sel) {
var _calculateRotation = calculateRotation(sel),
rotate = _calculateRotation.rotate,
maxHeight = _calculateRotation.maxHeight,
anchor = _calculateRotation.anchor;
var text = sel.select('text');
var existingTransform = text.attr('transform');
var offset = sign() * Math.floor(maxHeight / 2);
var offsetTransform = isVertical() ? 'translate(' + offset + ', 0)' : 'translate(0, ' + offset + ')';
text.style('text-anchor', anchor).attr('transform', existingTransform + ' ' + offsetTransform + ' rotate(' + rotate + ' 0 0)');
};
var axisLabelRotate = function axisLabelRotate(arg) {
adaptee(arg);
};
adaptee.decorate(function (s) {
decorateRotation(s);
decorate(s);
});
axisLabelRotate.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return axisLabelRotate;
};
axisLabelRotate.labelRotate = function () {
if (!arguments.length) {
return labelRotate;
}
labelRotate = arguments.length <= 0 ? undefined : arguments[0];
return axisLabelRotate;
};
rebindAll(axisLabelRotate, adaptee, exclude('decorate'));
return axisLabelRotate;
});
var axisLabelOffset = (function (adaptee) {
var labelOffsetDepth = 'auto';
var decorate = function decorate() {};
var isVertical = function isVertical() {
return adaptee.orient() === 'left' || adaptee.orient() === 'right';
};
var sign = function sign() {
return adaptee.orient() === 'top' || adaptee.orient() === 'left' ? -1 : 1;
};
var decorateOffset = function decorateOffset(sel) {
var _measureLabels = measureLabels(adaptee.scale())(sel),
maxHeight = _measureLabels.maxHeight,
maxWidth = _measureLabels.maxWidth,
labelCount = _measureLabels.labelCount;
var range$$1 = adaptee.scale().range()[1];
var offsetLevels = labelOffsetDepth === 'auto' ? Math.floor((isVertical() ? maxHeight : maxWidth) * labelCount / range$$1) + 1 : labelOffsetDepth;
var text = sel.select('text');
var existingTransform = text.attr('transform');
var transform = function transform(i) {
return isVertical() ? 'translate(' + i % offsetLevels * maxWidth * sign() + ', 0)' : 'translate(0, ' + i % offsetLevels * maxHeight * sign() + ')';
};
text.attr('transform', function (_, i) {
return existingTransform + ' ' + transform(i);
});
};
var axisLabelOffset = function axisLabelOffset(arg) {
return adaptee(arg);
};
adaptee.decorate(function (s) {
decorateOffset(s);
decorate(s);
});
axisLabelOffset.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return axisLabelOffset;
};
axisLabelOffset.labelOffsetDepth = function () {
if (!arguments.length) {
return labelOffsetDepth;
}
labelOffsetDepth = arguments.length <= 0 ? undefined : arguments[0];
return axisLabelOffset;
};
rebindAll(axisLabelOffset, adaptee, exclude('decorate'));
return axisLabelOffset;
});
var key = '__d3fc-elements__';
var get$2 = function get$2(element) {
return element[key] || {};
};
var set$2 = function set$2(element, data) {
return void (element[key] = data);
};
var clear = function clear(element) {
return delete element[key];
};
/* eslint-env browser */
var find = function find(element) {
return element.tagName === 'D3FC-GROUP' ? [element].concat(toConsumableArray(element.querySelectorAll('d3fc-canvas, d3fc-group, d3fc-svg'))) : [element];
};
var measure = function measure(element) {
var _data$get = get$2(element),
previousWidth = _data$get.width,
previousHeight = _data$get.height;
var pixelRatio = element.useDevicePixelRatio && global.devicePixelRatio != null ? global.devicePixelRatio : 1;
var width = element.clientWidth * pixelRatio;
var height = element.clientHeight * pixelRatio;
var resized = width !== previousWidth || height !== previousHeight;
set$2(element, { pixelRatio: pixelRatio, width: width, height: height, resized: resized });
};
if (typeof CustomEvent !== 'function') {
throw new Error('d3fc-element depends on CustomEvent. Make sure that you load a polyfill in older browsers. See README.');
}
var resize = function resize(element) {
var detail = get$2(element);
var event$$1 = new CustomEvent('measure', { detail: detail });
element.dispatchEvent(event$$1);
};
var draw = function draw(element) {
var detail = get$2(element);
var event$$1 = new CustomEvent('draw', { detail: detail });
element.dispatchEvent(event$$1);
};
var redraw = (function (elements) {
var allElements = elements.map(find).reduce(function (a, b) {
return a.concat(b);
});
allElements.forEach(measure);
allElements.forEach(resize);
allElements.forEach(draw);
});
/* eslint-env browser */
var getQueue = function getQueue(element) {
return get$2(element.ownerDocument).queue || [];
};
var setQueue = function setQueue(element, queue) {
var _data$get = get$2(element.ownerDocument),
requestId = _data$get.requestId;
if (requestId == null) {
requestId = requestAnimationFrame(function () {
// This seems like a weak way of retrieving the queue
// but I can't see an edge case at the minute...
var queue = getQueue(element);
redraw(queue);
clearQueue(element);
});
}
set$2(element.ownerDocument, { queue: queue, requestId: requestId });
};
var clearQueue = function clearQueue(element) {
return clear(element.ownerDocument);
};
var isDescendentOf = function isDescendentOf(element, ancestor) {
var node = element;
do {
if (node.parentNode === ancestor) {
return true;
}
// eslint-disable-next-line no-cond-assign
} while (node = node.parentNode);
return false;
};
var _requestRedraw = (function (element) {
var queue = getQueue(element);
var queueContainsElement = queue.indexOf(element) > -1;
if (queueContainsElement) {
return;
}
var queueContainsAncestor = queue.some(function (queuedElement) {
return isDescendentOf(element, queuedElement);
});
if (queueContainsAncestor) {
return;
}
var queueExcludingDescendents = queue.filter(function (queuedElement) {
return !isDescendentOf(queuedElement, element);
});
queueExcludingDescendents.push(element);
setQueue(element, queueExcludingDescendents);
});
function _CustomElement() {
return Reflect.construct(HTMLElement, [], this.__proto__.constructor);
}
Object.setPrototypeOf(_CustomElement.prototype, HTMLElement.prototype);
Object.setPrototypeOf(_CustomElement, HTMLElement);
/* eslint-env browser */
if (typeof HTMLElement !== 'function') {
throw new Error('d3fc-element depends on Custom Elements (v1). Make sure that you load a polyfill in older browsers. See README.');
}
var addMeasureListener = function addMeasureListener(element) {
if (element.__measureListener__ != null) {
return;
}
element.__measureListener__ = function (event$$1) {
return element.setMeasurements(event$$1.detail);
};
element.addEventListener('measure', element.__measureListener__);
};
var removeMeasureListener = function removeMeasureListener(element) {
if (element.__measureListener__ == null) {
return;
}
element.removeEventListener('measure', element.__measureListener__);
element.__measureListener__ = null;
};
var element = (function (createNode, applyMeasurements) {
return function (_CustomElement2) {
inherits(_class, _CustomElement2);
function _class() {
classCallCheck(this, _class);
return possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments));
}
createClass(_class, [{
key: 'attributeChangedCallback',
value: function attributeChangedCallback(name) {
switch (name) {
case 'use-device-pixel-ratio':
this.requestRedraw();
break;
}
}
}, {
key: 'connectedCallback',
value: function connectedCallback() {
if (this.childNodes.length === 0) {
this.appendChild(createNode());
}
addMeasureListener(this);
}
}, {
key: 'disconnectedCallback',
value: function disconnectedCallback() {
removeMeasureListener(this);
}
}, {
key: 'setMeasurements',
value: function setMeasurements(_ref) {
var width = _ref.width,
height = _ref.height;
var _childNodes = toArray(this.childNodes),
node = _childNodes[0],
other = _childNodes.slice(1);
if (other.length > 0) {
throw new Error('A d3fc-svg/canvas element must only contain a single svg/canvas element.');
}
applyMeasurements(node, { width: width, height: height });
}
}, {
key: 'requestRedraw',
value: function requestRedraw() {
_requestRedraw(this);
}
}, {
key: 'useDevicePixelRatio',
get: function get() {
return this.hasAttribute('use-device-pixel-ratio') && this.getAttribute('use-device-pixel-ratio') !== 'false';
},
set: function set(useDevicePixelRatio) {
if (useDevicePixelRatio && !this.useDevicePixelRatio) {
this.setAttribute('use-device-pixel-ratio', '');
} else if (!useDevicePixelRatio && this.useDevicePixelRatio) {
this.removeAttribute('use-device-pixel-ratio');
}
this.requestRedraw();
}
}], [{
key: 'observedAttributes',
get: function get() {
return ['use-device-pixel-ratio'];
}
}]);
return _class;
}(_CustomElement);
});
var Canvas = element(function () {
return document.createElement('canvas');
}, function (node, _ref) {
var width = _ref.width,
height = _ref.height;
node.setAttribute('width', width);
node.setAttribute('height', height);
});
function _CustomElement$1() {
return Reflect.construct(HTMLElement, [], this.__proto__.constructor);
}
Object.setPrototypeOf(_CustomElement$1.prototype, HTMLElement.prototype);
Object.setPrototypeOf(_CustomElement$1, HTMLElement);
/* eslint-env browser */
var updateAutoResize = function updateAutoResize(element) {
if (element.autoResize) {
addAutoResizeListener(element);
} else {
removeAutoResizeListener(element);
}
};
var addAutoResizeListener = function addAutoResizeListener(element) {
if (element.__autoResizeListener__ != null) {
return;
}
element.__autoResizeListener__ = function () {
return _requestRedraw(element);
};
addEventListener('resize', element.__autoResizeListener__);
};
var removeAutoResizeListener = function removeAutoResizeListener(element) {
if (element.__autoResizeListener__ == null) {
return;
}
removeEventListener('resize', element.__autoResizeListener__);
element.__autoResizeListener__ = null;
};
var _class = function (_CustomElement2) {
inherits(_class, _CustomElement2);
function _class() {
classCallCheck(this, _class);
return possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments));
}
createClass(_class, [{
key: 'connectedCallback',
value: function connectedCallback() {
updateAutoResize(this);
}
}, {
key: 'disconnectedCallback',
value: function disconnectedCallback() {
removeAutoResizeListener(this);
}
}, {
key: 'requestRedraw',
value: function requestRedraw() {
_requestRedraw(this);
}
}, {
key: 'attributeChangedCallback',
value: function attributeChangedCallback(name) {
switch (name) {
case 'auto-resize':
updateAutoResize(this);
break;
}
}
}, {
key: 'autoResize',
get: function get() {
return this.hasAttribute('auto-resize') && this.getAttribute('auto-resize') !== 'false';
},
set: function set(autoResize) {
if (autoResize && !this.autoResize) {
this.setAttribute('auto-resize', '');
} else if (!autoResize && this.autoResize) {
this.removeAttribute('auto-resize');
}
updateAutoResize(this);
}
}], [{
key: 'observedAttributes',
get: function get() {
return ['auto-resize'];
}
}]);
return _class;
}(_CustomElement$1);
var Svg = element(function () {
return document.createElementNS('http://www.w3.org/2000/svg', 'svg');
}, function (node, _ref) {
var width = _ref.width,
height = _ref.height;
node.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
});
// Adapted from https://github.com/substack/insert-css
var css = 'd3fc-canvas,d3fc-svg{position:relative;display:block}d3fc-canvas>canvas,d3fc-svg>svg{position:absolute;height:100%;width:100%}d3fc-svg>svg{overflow:visible}';
var styleElement = document.createElement('style');
styleElement.setAttribute('type', 'text/css');
document.querySelector('head').appendChild(styleElement);
if (styleElement.styleSheet) {
styleElement.styleSheet.cssText += css;
} else {
styleElement.textContent += css;
}
/* globals customElements */
if ((typeof customElements === 'undefined' ? 'undefined' : _typeof(customElements)) !== 'object' || typeof customElements.define !== 'function') {
throw new Error('d3fc-element depends on Custom Elements (v1). Make sure that you load a polyfill in older browsers. See README.');
}
customElements.define('d3fc-canvas', Canvas);
customElements.define('d3fc-group', _class);
customElements.define('d3fc-svg', Svg);
var pointer = (function () {
var event$$1 = d3Dispatch.dispatch('point');
function mousemove() {
var point = d3Selection.mouse(this);
event$$1.call('point', this, [{ x: point[0], y: point[1] }]);
}
function mouseleave() {
void event$$1.call('point', this, []);
}
var instance = function instance(selection$$1) {
selection$$1.on('mouseenter.pointer', mousemove).on('mousemove.pointer', mousemove).on('mouseleave.pointer', mouseleave);
};
rebind(instance, event$$1, 'on');
return instance;
});
var group = (function () {
var key = '';
var orient = 'vertical';
// D3 CSV returns all values as strings, this converts them to numbers
// by default.
var value = function value(row, column) {
return Number(row[column]);
};
var verticalgroup = function verticalgroup(data) {
return Object.keys(data[0]).filter(function (k) {
return k !== key;
}).map(function (k) {
var values = data.filter(function (row) {
return row[k];
}).map(function (row) {
var cell = [row[key], value(row, k)];
cell.data = row;
return cell;
});
values.key = k;
return values;
});
};
var horizontalgroup = function horizontalgroup(data) {
return data.map(function (row) {
var values = Object.keys(row).filter(function (d) {
return d !== key;
}).map(function (k) {
var cell = [k, value(row, k)];
cell.data = row;
return cell;
});
values.key = row[key];
return values;
});
};
var group = function group(data) {
return orient === 'vertical' ? verticalgroup(data) : horizontalgroup(data);
};
group.key = function () {
if (!arguments.length) {
return key;
}
key = arguments.length <= 0 ? undefined : arguments[0];
return group;
};
group.value = function () {
if (!arguments.length) {
return value;
}
value = arguments.length <= 0 ? undefined : arguments[0];
return group;
};
group.orient = function () {
if (!arguments.length) {
return orient;
}
orient = arguments.length <= 0 ? undefined : arguments[0];
return group;
};
return group;
});
var store = (function () {
for (var _len = arguments.length, names = Array(_len), _key = 0; _key < _len; _key++) {
names[_key] = arguments[_key];
}
var data = {};
var store = function store(target) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = Object.keys(data)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
target[key](data[key]);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return target;
};
var _loop = function _loop(name) {
store[name] = function () {
if (!arguments.length) {
return data[name];
}
data[name] = arguments.length <= 0 ? undefined : arguments[0];
return store;
};
};
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = names[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var name = _step2.value;
_loop(name);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return store;
});
// Adapted from https://github.com/substack/insert-css
var css$1 = 'd3fc-group.cartesian-chart{width:100%;height:100%;overflow:hidden;display:grid;display:-ms-grid;grid-template-columns:minmax(1em,max-content) auto 1fr auto minmax(1em,max-content);-ms-grid-columns:minmax(1em,max-content) auto 1fr auto minmax(1em,max-content);grid-template-rows:minmax(1em,max-content) auto 1fr auto minmax(1em,max-content);-ms-grid-rows:minmax(1em,max-content) auto 1fr auto minmax(1em,max-content);}\nd3fc-group.cartesian-chart>.top-label{align-self:center;-ms-grid-column-align:center;justify-self:center;-ms-grid-row-align:center;grid-column:3;-ms-grid-column:3;-ms-grid-row:1;-ms-grid-row:1;}\nd3fc-group.cartesian-chart>.top-axis{height:2em;grid-column:3;-ms-grid-column:3;grid-row:2;-ms-grid-row:2;}\nd3fc-group.cartesian-chart>.left-label{align-self:center;-ms-grid-column-align:center;justify-self:center;-ms-grid-row-align:center;grid-column:1;-ms-grid-column:1;grid-row:3;-ms-grid-row:3;}\nd3fc-group.cartesian-chart>.left-axis{width:3em;grid-column:2;-ms-grid-column:2;grid-row:3;-ms-grid-row:3;}\nd3fc-group.cartesian-chart>.plot-area{overflow:hidden;grid-column:3;-ms-grid-column:3;grid-row:3;-ms-grid-row:3;}\nd3fc-group.cartesian-chart>.right-axis{width:3em;grid-column:4;-ms-grid-column:4;grid-row:3;-ms-grid-row:3;}\nd3fc-group.cartesian-chart>.right-label{align-self:center;-ms-grid-column-align:center;justify-self:center;-ms-grid-row-align:center;grid-column:5;-ms-grid-column:5;grid-row:3;-ms-grid-row:3;}\nd3fc-group.cartesian-chart>.bottom-axis{height:2em;grid-column:3;-ms-grid-column:3;grid-row:4;-ms-grid-row:4;}\nd3fc-group.cartesian-chart>.bottom-label{align-self:center;-ms-grid-column-align:center;justify-self:center;-ms-grid-row-align:center;grid-column:3;-ms-grid-column:3;grid-row:5;-ms-grid-row:5;}';
var styleElement$1 = document.createElement('style');
styleElement$1.setAttribute('type', 'text/css');
document.querySelector('head').appendChild(styleElement$1);
if (styleElement$1.styleSheet) {
styleElement$1.styleSheet.cssText += css$1;
} else {
styleElement$1.textContent += css$1;
}
var functor$6 = function functor$6(v) {
return typeof v === 'function' ? v : function () {
return v;
};
};
var cartesianChart = (function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var _getArguments = getArguments.apply(undefined, args),
xScale = _getArguments.xScale,
yScale = _getArguments.yScale,
xAxis = _getArguments.xAxis,
yAxis = _getArguments.yAxis;
var xLabel = functor$6('');
var yLabel = functor$6('');
var xAxisHeight = functor$6(null);
var yAxisWidth = functor$6(null);
var yOrient = functor$6('right');
var xOrient = functor$6('bottom');
var canvasPlotArea = seriesCanvasMulti();
var svgPlotArea = seriesSvgMulti();
var xAxisStore = store('tickFormat', 'ticks', 'tickArguments', 'tickSize', 'tickSizeInner', 'tickSizeOuter', 'tickValues', 'tickPadding', 'tickCenterLabel');
var xDecorate = function xDecorate() {};
var yAxisStore = store('tickFormat', 'ticks', 'tickArguments', 'tickSize', 'tickSizeInner', 'tickSizeOuter', 'tickValues', 'tickPadding', 'tickCenterLabel');
var yDecorate = function yDecorate() {};
var decorate = function decorate() {};
var containerDataJoin = dataJoin('d3fc-group', 'cartesian-chart');
var xAxisDataJoin = dataJoin('d3fc-svg', 'x-axis').key(function (d) {
return d;
});
var yAxisDataJoin = dataJoin('d3fc-svg', 'y-axis').key(function (d) {
return d;
});
var xLabelDataJoin = dataJoin('div', 'x-label').key(function (d) {
return d;
});
var yLabelDataJoin = dataJoin('div', 'y-label').key(function (d) {
return d;
});
var propagateTransition = function propagateTransition(maybeTransition) {
return function (selection$$1) {
return maybeTransition.selection ? selection$$1.transition(maybeTransition) : selection$$1;
};
};
var cartesian = function cartesian(selection$$1) {
var transitionPropagator = propagateTransition(selection$$1);
selection$$1.each(function (data, index, group) {
var container = containerDataJoin(d3Selection.select(group[index]), [data]);
container.enter().attr('auto-resize', '').html('' + '');
xLabelDataJoin(container, [xOrient(data)]).attr('class', function (d) {
return 'x-label ' + d + '-label';
}).text(xLabel(data));
yLabelDataJoin(container, [yOrient(data)]).attr('class', function (d) {
return 'y-label ' + d + '-label';
}).text(yLabel(data));
xAxisDataJoin(container, [xOrient(data)]).attr('class', function (d) {
return 'x-axis ' + d + '-axis';
}).style('height', xAxisHeight(data)).on('measure', function (d, i, nodes) {
var _event$detail = d3Selection.event.detail,
width = _event$detail.width,
height = _event$detail.height;
if (d === 'top') {
d3Selection.select(nodes[i]).select('svg').attr('viewBox', '0 ' + -height + ' ' + width + ' ' + height);
}
xScale.range([0, width]);
}).on('draw', function (d, i, nodes) {
var xAxisComponent = d === 'top' ? xAxis.top(xScale) : xAxis.bottom(xScale);
xAxisComponent.decorate(xDecorate);
transitionPropagator(d3Selection.select(nodes[i])).select('svg').call(xAxisStore(xAxisComponent));
});
yAxisDataJoin(container, [yOrient(data)]).attr('class', function (d) {
return 'y-axis ' + d + '-axis';
}).style('width', yAxisWidth(data)).on('measure', function (d, i, nodes) {
var _event$detail2 = d3Selection.event.detail,
width = _event$detail2.width,
height = _event$detail2.height;
if (d === 'left') {
d3Selection.select(nodes[i]).select('svg').attr('viewBox', -width + ' 0 ' + width + ' ' + height);
}
yScale.range([height, 0]);
}).on('draw', function (d, i, nodes) {
var yAxisComponent = d === 'left' ? yAxis.left(yScale) : yAxis.right(yScale);
yAxisComponent.decorate(yDecorate);
transitionPropagator(d3Selection.select(nodes[i])).select('svg').call(yAxisStore(yAxisComponent));
});
container.select('d3fc-canvas.plot-area').on('draw', function (d, i, nodes) {
var canvas = d3Selection.select(nodes[i]).select('canvas').node();
canvasPlotArea.context(canvas.getContext('2d')).xScale(xScale).yScale(yScale);
canvasPlotArea(d);
});
container.select('d3fc-svg.plot-area').on('draw', function (d, i, nodes) {
svgPlotArea.xScale(xScale).yScale(yScale);
transitionPropagator(d3Selection.select(nodes[i])).select('svg').call(svgPlotArea);
});
container.each(function (d, i, nodes) {
return nodes[i].requestRedraw();
});
decorate(container, data, index);
});
};
var scaleExclusions = exclude(/range\w*/, // the scale range is set via the component layout
/tickFormat/ // use axis.tickFormat instead (only present on linear scales)
);
rebindAll(cartesian, xScale, scaleExclusions, prefix('x'));
rebindAll(cartesian, yScale, scaleExclusions, prefix('y'));
rebindAll(cartesian, xAxisStore, prefix('x'));
rebindAll(cartesian, yAxisStore, prefix('y'));
cartesian.xOrient = function () {
if (!arguments.length) {
return xOrient;
}
xOrient = functor$6(arguments.length <= 0 ? undefined : arguments[0]);
return cartesian;
};
cartesian.yOrient = function () {
if (!arguments.length) {
return yOrient;
}
yOrient = functor$6(arguments.length <= 0 ? undefined : arguments[0]);
return cartesian;
};
cartesian.xDecorate = function () {
if (!arguments.length) {
return xDecorate;
}
xDecorate = arguments.length <= 0 ? undefined : arguments[0];
return cartesian;
};
cartesian.yDecorate = function () {
if (!arguments.length) {
return yDecorate;
}
yDecorate = arguments.length <= 0 ? undefined : arguments[0];
return cartesian;
};
cartesian.xLabel = function () {
if (!arguments.length) {
return xLabel;
}
xLabel = functor$6(arguments.length <= 0 ? undefined : arguments[0]);
return cartesian;
};
cartesian.yLabel = function () {
if (!arguments.length) {
return yLabel;
}
yLabel = functor$6(arguments.length <= 0 ? undefined : arguments[0]);
return cartesian;
};
cartesian.xAxisHeight = function () {
if (!arguments.length) {
return xAxisHeight;
}
xAxisHeight = functor$6(arguments.length <= 0 ? undefined : arguments[0]);
return cartesian;
};
cartesian.yAxisWidth = function () {
if (!arguments.length) {
return yAxisWidth;
}
yAxisWidth = functor$6(arguments.length <= 0 ? undefined : arguments[0]);
return cartesian;
};
cartesian.canvasPlotArea = function () {
if (!arguments.length) {
return canvasPlotArea;
}
canvasPlotArea = arguments.length <= 0 ? undefined : arguments[0];
return cartesian;
};
cartesian.svgPlotArea = function () {
if (!arguments.length) {
return svgPlotArea;
}
svgPlotArea = arguments.length <= 0 ? undefined : arguments[0];
return cartesian;
};
cartesian.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return cartesian;
};
return cartesian;
});
var getArguments = function getArguments() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var defaultSettings = {
xScale: d3Scale.scaleIdentity(),
yScale: d3Scale.scaleIdentity(),
xAxis: { bottom: axisBottom, top: axisTop },
yAxis: { right: axisRight, left: axisLeft }
};
if (args.length === 1 && !args[0].domain && !args[0].range) {
// Settings object
return Object.assign(defaultSettings, args[0]);
}
// xScale/yScale parameters
return Object.assign(defaultSettings, {
xScale: args[0] || defaultSettings.xScale,
yScale: args[1] || defaultSettings.yScale
});
};
var functor$5 = function functor$5(v) {
return typeof v === 'function' ? v : function () {
return v;
};
};
var cartesianBase = (function (setPlotArea, defaultPlotArea) {
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var chartLabel = functor$5('');
var yLabel = functor$5('');
var plotArea = defaultPlotArea;
var decorate = function decorate() {};
var cartesian = cartesianChart.apply(undefined, args);
var cartesianBase = function cartesianBase(selection$$1) {
setPlotArea(cartesian, plotArea);
cartesian.decorate(function (container, data, index) {
container.enter().select('.x-label').style('height', '1em').style('line-height', '1em');
var yOrientValue = cartesian.yOrient()(data);
container.enter().append('div').attr('class', 'y-label-container').style('grid-column', yOrientValue === 'left' ? 1 : 5).style('-ms-grid-column', yOrientValue === 'left' ? 1 : 5).style('grid-row', 3).style('-ms-grid-row', 3).style('width', '1em').style('display', 'flex').style('align-items', 'center').style('justify-content', 'center').append('div').attr('class', 'y-label').style('transform', 'rotate(-90deg)');
container.select('.y-label-container>.y-label').text(yLabel);
container.select('.top-label').style('margin-top', '2em');
container.enter().append('div').attr('class', 'chart-label').style('grid-column', 3).style('-ms-grid-column', 3).style('grid-row', 1).style('-ms-grid-row', 1).style('height', '2em').style('line-height', '2em').style('text-align', 'center');
container.select('.chart-label').text(chartLabel(data));
decorate(container, data, index);
});
selection$$1.call(cartesian);
};
rebindAll(cartesianBase, cartesian, include(/^x/, /^y/));
cartesianBase.chartLabel = function () {
if (!arguments.length) {
return chartLabel;
}
chartLabel = functor$5(arguments.length <= 0 ? undefined : arguments[0]);
return cartesianBase;
};
cartesianBase.yLabel = function () {
if (!arguments.length) {
return yLabel;
}
yLabel = functor$5(arguments.length <= 0 ? undefined : arguments[0]);
return cartesianBase;
};
cartesianBase.plotArea = function () {
if (!arguments.length) {
return plotArea;
}
plotArea = arguments.length <= 0 ? undefined : arguments[0];
return cartesianBase;
};
cartesianBase.decorate = function () {
if (!arguments.length) {
return decorate;
}
decorate = arguments.length <= 0 ? undefined : arguments[0];
return cartesianBase;
};
return cartesianBase;
};
});
var cartesian = cartesianBase(function (cartesian, plotArea) {
return cartesian.svgPlotArea(plotArea);
}, seriesSvgLine);
var cartesian$1 = cartesianBase(function (cartesian, plotArea) {
return cartesian.canvasPlotArea(plotArea);
}, seriesCanvasLine);
var brushForOrient = function brushForOrient(orient) {
switch (orient) {
case 'x':
return d3Brush.brushX();
case 'y':
return d3Brush.brushY();
case 'xy':
return d3Brush.brush();
}
};
var invertRange = function invertRange(range$$1) {
return [range$$1[1], range$$1[0]];
};
var brushBase = function brushBase(orient) {
var brush$$1 = brushForOrient(orient);
var eventDispatch = d3Dispatch.dispatch('brush', 'start', 'end');
var xScale = d3Scale.scaleIdentity();
var yScale = d3Scale.scaleIdentity();
var innerJoin = dataJoin('g', 'brush');
var mapSelection = function mapSelection(selection$$1, xMapping, yMapping) {
switch (orient) {
case 'x':
return selection$$1.map(xMapping);
case 'y':
return selection$$1.map(yMapping);
case 'xy':
return [[xMapping(selection$$1[0][0]), yMapping(selection$$1[0][1])], [xMapping(selection$$1[1][0]), yMapping(selection$$1[1][1])]];
}
};
var percentToSelection = function percentToSelection(percent) {
return mapSelection(percent, d3Scale.scaleLinear().domain(xScale.range()).invert, d3Scale.scaleLinear().domain(invertRange(yScale.range())).invert);
};
var selectionToPercent = function selectionToPercent(selection$$1) {
return mapSelection(selection$$1, d3Scale.scaleLinear().domain(xScale.range()), d3Scale.scaleLinear().domain(invertRange(yScale.range())));
};
var updateXDomain = function updateXDomain(selection$$1) {
var f = d3Scale.scaleLinear().domain(xScale.domain());
if (orient === 'x') {
return selection$$1.map(f.invert);
} else if (orient === 'xy') {
return [f.invert(selection$$1[0][0]), f.invert(selection$$1[1][0])];
}
};
var updateYDomain = function updateYDomain(selection$$1) {
var g = d3Scale.scaleLinear().domain(invertRange(yScale.domain()));
if (orient === 'y') {
return [selection$$1[1], selection$$1[0]].map(g.invert);
} else if (orient === 'xy') {
return [g.invert(selection$$1[1][1]), g.invert(selection$$1[0][1])];
}
};
var transformEvent = function transformEvent(event$$1) {
// The render function calls brush.move, which triggers, start, brush and end events. We don't
// really want those events so suppress them.
if (event$$1.sourceEvent && event$$1.sourceEvent.type === 'draw') return;
if (event$$1.selection) {
var mappedSelection = selectionToPercent(event$$1.selection);
eventDispatch.call(event$$1.type, {}, {
selection: mappedSelection,
xDomain: updateXDomain(mappedSelection),
yDomain: updateYDomain(mappedSelection)
});
} else {
eventDispatch.call(event$$1.type, {}, {});
}
};
var base = function base(selection$$1) {
selection$$1.each(function (data, index, group) {
// set the extent
brush$$1.extent([[xScale.range()[0], yScale.range()[1]], [xScale.range()[1], yScale.range()[0]]]);
// forwards events
brush$$1.on('end', function () {
return transformEvent(d3Selection.event);
}).on('brush', function () {
return transformEvent(d3Selection.event);
}).on('start', function () {
return transformEvent(d3Selection.event);
});
// render
var container = innerJoin(d3Selection.select(group[index]), [data]);
container.call(brush$$1).call(brush$$1.move, data ? percentToSelection(data) : null);
});
};
base.xScale = function () {
if (!arguments.length) {
return xScale;
}
xScale = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
base.yScale = function () {
if (!arguments.length) {
return yScale;
}
yScale = arguments.length <= 0 ? undefined : arguments[0];
return base;
};
rebind(base, eventDispatch, 'on');
rebind(base, brush$$1, 'filter', 'handleSize');
return base;
};
var brushX$1 = function brushX$1() {
return brushBase('x');
};
var brushY$1 = function brushY$1() {
return brushBase('y');
};
var brush$1 = function brush$1() {
return brushBase('xy');
};
exports.indicatorBollingerBands = bollingerBands;
exports.indicatorExponentialMovingAverage = exponentialMovingAverage;
exports.indicatorMacd = macd;
exports.indicatorRelativeStrengthIndex = relativeStrengthIndex;
exports.indicatorStochasticOscillator = stochasticOscillator;
exports.indicatorForceIndex = forceIndex;
exports.indicatorEnvelope = envelope;
exports.indicatorElderRay = elderRay;
exports.indicatorMovingAverage = movingAverage;
exports.scaleDiscontinuous = discontinuous;
exports.discontinuitySkipWeekends = skipWeekends;
exports.discontinuityIdentity = identity$1;
exports.discontinuityRange = provider;
exports.extentLinear = linearExtent;
exports.extentTime = time;
exports.extentDate = time;
exports.randomFinancial = financial;
exports.randomGeometricBrownianMotion = geometricBrownianMotion;
exports.randomSkipWeekends = skipWeekends$1;
exports.feedGdax = gdax;
exports.bucket = bucket;
exports.largestTriangleOneBucket = largestTriangleOneBucket;
exports.largestTriangleThreeBucket = largestTriangleThreeBucket;
exports.modeMedian = modeMedian;
exports.rebind = rebind;
exports.rebindAll = rebindAll;
exports.exclude = exclude;
exports.include = include;
exports.includeMap = includeMap;
exports.prefix = prefix;
exports.shapeOhlc = shapeOhlc;
exports.shapeBar = shapeBar;
exports.shapeCandlestick = shapeCandlestick;
exports.shapeBoxPlot = shapeBoxPlot;
exports.shapeErrorBar = shapeErrorBar;
exports.layoutLabel = label;
exports.layoutTextLabel = textLabel;
exports.layoutGreedy = greedy;
exports.layoutAnnealing = annealing;
exports.layoutRemoveOverlaps = removeOverlaps;
exports.layoutBoundingBox = boundingBox;
exports.dataJoin = dataJoin;
exports.effectivelyZero = effectivelyZero;
exports.seriesSvgLine = seriesSvgLine;
exports.seriesCanvasLine = seriesCanvasLine;
exports.seriesSvgPoint = seriesSvgPoint;
exports.seriesCanvasPoint = seriesCanvasPoint;
exports.seriesSvgBar = bar;
exports.seriesCanvasBar = bar$1;
exports.seriesSvgErrorBar = errorBar;
exports.seriesCanvasErrorBar = errorBar$1;
exports.seriesSvgArea = area$1;
exports.seriesCanvasArea = area$2;
exports.seriesSvgCandlestick = candlestick;
exports.seriesCanvasCandlestick = candlestick$1;
exports.seriesSvgBoxPlot = boxPlot;
exports.seriesCanvasBoxPlot = boxPlot$1;
exports.seriesSvgOhlc = ohlc;
exports.seriesCanvasOhlc = ohlc$1;
exports.seriesSvgMulti = seriesSvgMulti;
exports.seriesCanvasMulti = seriesCanvasMulti;
exports.seriesSvgGrouped = grouped;
exports.seriesCanvasGrouped = grouped$1;
exports.seriesSvgRepeat = repeat;
exports.seriesCanvasRepeat = repeat$1;
exports.autoBandwidth = autoBandwidth;
exports.seriesSvgHeatmap = heatmap;
exports.seriesCanvasHeatmap = heatmap$1;
exports.annotationSvgBand = band;
exports.annotationCanvasBand = band$1;
exports.annotationSvgCrosshair = crosshair;
exports.annotationCanvasCrosshair = crosshair$1;
exports.annotationSvgLine = annotationLine;
exports.annotationCanvasLine = annotationLine$1;
exports.annotationSvgGridline = gridline;
exports.annotationCanvasGridline = gridline$1;
exports.axisLabelRotate = axisLabelRotate;
exports.axisLabelOffset = axisLabelOffset;
exports.axisTop = axisTop;
exports.axisBottom = axisBottom;
exports.axisLeft = axisLeft;
exports.axisRight = axisRight;
exports.axisOrdinalTop = axisOrdinalTop;
exports.axisOrdinalBottom = axisOrdinalBottom;
exports.axisOrdinalLeft = axisOrdinalLeft;
exports.axisOrdinalRight = axisOrdinalRight;
exports.pointer = pointer;
exports.group = group;
exports.chartSvgCartesian = cartesian;
exports.chartCanvasCartesian = cartesian$1;
exports.chartCartesian = cartesianChart;
exports.brushX = brushX$1;
exports.brushY = brushY$1;
exports.brush = brush$1;
Object.defineProperty(exports, '__esModule', { value: true });
})));