@devexpress/dx-chart-core
Advanced tools
Comparing version 1.9.0 to 1.9.1
/** | ||
* Bundle of @devexpress/dx-chart-core | ||
* Generated: 2018-11-07 | ||
* Version: 1.9.0 | ||
* Generated: 2018-12-07 | ||
* Version: 1.9.1 | ||
* License: https://js.devexpress.com/Licensing | ||
@@ -12,38 +12,3 @@ */ | ||
var HORIZONTAL = 'horizontal'; | ||
var VERTICAL = 'vertical'; | ||
var TOP = 'top'; | ||
var BOTTOM = 'bottom'; | ||
var LEFT = 'left'; | ||
var RIGHT = 'right'; | ||
var MIDDLE = 'middle'; | ||
var END = 'end'; | ||
var START = 'start'; | ||
var LINEAR = 'linear'; | ||
var BAND = 'band'; | ||
var ARGUMENT_DOMAIN = 'argument-domain'; | ||
var VALUE_DOMAIN = 'value-domain'; | ||
var HOVERED = 'hovered'; | ||
var SELECTED = 'selected'; | ||
var createScale = function createScale(_ref, width, height, constructor) { | ||
var domain = _ref.domain, | ||
orientation = _ref.orientation; | ||
var scale = constructor(); | ||
return scale.domain(domain).range(orientation === HORIZONTAL ? [0, width] : [height, 0]); | ||
}; | ||
var getWidth = function getWidth(scale) { | ||
return scale.bandwidth ? scale.bandwidth() : 0; | ||
}; | ||
var getValueDomainName = function getValueDomainName(name) { | ||
return name || VALUE_DOMAIN; | ||
}; | ||
var defineProperty = function (obj, key, value) { | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
@@ -61,89 +26,127 @@ Object.defineProperty(obj, key, { | ||
return obj; | ||
}; | ||
} | ||
var _extends = Object.assign || function (target) { | ||
function _objectSpread(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
var ownKeys = Object.keys(source); | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
if (typeof Object.getOwnPropertySymbols === 'function') { | ||
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(source, sym).enumerable; | ||
})); | ||
} | ||
ownKeys.forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} | ||
return target; | ||
}; | ||
} | ||
var objectWithoutProperties = function (obj, keys) { | ||
var target = {}; | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); | ||
} | ||
for (var i in obj) { | ||
if (keys.indexOf(i) >= 0) continue; | ||
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; | ||
target[i] = obj[i]; | ||
function _toConsumableArray(arr) { | ||
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); | ||
} | ||
function _arrayWithoutHoles(arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
} | ||
return target; | ||
}; | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
var slicedToArray = function () { | ||
function sliceIterator(arr, i) { | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
function _iterableToArray(iter) { | ||
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); | ||
} | ||
function _iterableToArrayLimit(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 { | ||
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; | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
try { | ||
if (!_n && _i["return"]) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
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"); | ||
} | ||
}; | ||
}(); | ||
return _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]; | ||
function _nonIterableSpread() { | ||
throw new TypeError("Invalid attempt to spread non-iterable instance"); | ||
} | ||
return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
} | ||
var HORIZONTAL = 'horizontal'; | ||
var VERTICAL = 'vertical'; | ||
var TOP = 'top'; | ||
var BOTTOM = 'bottom'; | ||
var LEFT = 'left'; | ||
var RIGHT = 'right'; | ||
var MIDDLE = 'middle'; | ||
var END = 'end'; | ||
var START = 'start'; | ||
var LINEAR = 'linear'; | ||
var BAND = 'band'; | ||
var ARGUMENT_DOMAIN = 'argument-domain'; | ||
var VALUE_DOMAIN = 'value-domain'; | ||
var HOVERED = 'hovered'; | ||
var SELECTED = 'selected'; | ||
var createScale = function createScale(_ref, width, height, constructor) { | ||
var domain = _ref.domain, | ||
orientation = _ref.orientation; | ||
var scale = constructor(); | ||
return scale.domain(domain).range(orientation === HORIZONTAL ? [0, width] : [height, 0]); | ||
}; | ||
var getWidth = function getWidth(scale) { | ||
return scale.bandwidth ? scale.bandwidth() : 0; | ||
}; | ||
var getValueDomainName = function getValueDomainName(name) { | ||
return name || VALUE_DOMAIN; | ||
}; | ||
var fixOffset = function fixOffset(scale) { | ||
var offset = getWidth(scale) / 2; | ||
return offset > 0 ? function (value) { | ||
return scale(value) + offset; | ||
} : scale; | ||
}; | ||
var isDefined = function isDefined(item) { | ||
return item !== undefined; | ||
}; | ||
}; // TODO: Property name should not contain "axis" part as it actually means domain. | ||
// TODO: Property name should not contain "axis" part as it actually means domain. | ||
var getSeriesValueDomainName = function getSeriesValueDomainName(series) { | ||
return getValueDomainName(series.axisName); | ||
return getValueDomainName(series.scaleName); | ||
}; | ||
var calculateDomainField = function calculateDomainField(items, domain, type) { | ||
return type === BAND ? [].concat(toConsumableArray(domain), toConsumableArray(items)) : extent([].concat(toConsumableArray(domain), toConsumableArray(extent(items)))); | ||
return type === BAND ? _toConsumableArray(domain).concat(_toConsumableArray(items)) : extent(_toConsumableArray(domain).concat(_toConsumableArray(extent(items)))); | ||
}; | ||
@@ -167,16 +170,12 @@ | ||
var points = seriesItem.points; | ||
var argumentDomain = domains[ARGUMENT_DOMAIN]; | ||
var valueDomain = domains[valueDomainName]; | ||
var valueType = getCorrectAxisType(valueDomain.type, points, getValue); | ||
var argumentType = getCorrectAxisType(argumentDomain.type, points, getArgument); | ||
// TODO: This is a temporary workaround for Stack plugin. | ||
var argumentType = getCorrectAxisType(argumentDomain.type, points, getArgument); // TODO: This is a temporary workaround for Stack plugin. | ||
// Once scales (or domains) are exposed for modification Stack will modify scale and | ||
// this code will be removed. | ||
var valueDomainItems = seriesItem.getValueDomain ? seriesItem.getValueDomain(points) : points.map(getValue); | ||
valueDomain.domain = calculateDomainField(valueDomainItems, valueDomain.domain, valueType); | ||
valueDomain.type = valueType; | ||
argumentDomain.domain = calculateDomainField(points.map(getArgument), argumentDomain.domain, argumentType); | ||
@@ -188,5 +187,11 @@ argumentDomain.type = argumentType; | ||
var computeExtension = function computeExtension(extension) { | ||
var defaultExtension = [{ type: LINEAR, constructor: scaleLinear }, { type: BAND, constructor: function constructor() { | ||
var defaultExtension = [{ | ||
type: LINEAR, | ||
constructor: scaleLinear | ||
}, { | ||
type: BAND, | ||
constructor: function constructor() { | ||
return scaleBand().paddingInner(0.3).paddingOuter(0.15); | ||
} }]; | ||
} | ||
}]; | ||
return extension.concat(defaultExtension); | ||
@@ -196,8 +201,16 @@ }; | ||
var collectDomains = function collectDomains(seriesList) { | ||
var domains = defineProperty({}, ARGUMENT_DOMAIN, { domain: [], orientation: HORIZONTAL }); | ||
var domains = _defineProperty({}, ARGUMENT_DOMAIN, { | ||
domain: [], | ||
orientation: HORIZONTAL | ||
}); | ||
seriesList.forEach(function (seriesItem) { | ||
var name = getSeriesValueDomainName(seriesItem); | ||
var domain = domains[name] || { domain: [], orientation: VERTICAL }; | ||
var domain = domains[name] || { | ||
domain: [], | ||
orientation: VERTICAL | ||
}; | ||
domains[name] = domain; | ||
if (seriesItem.isStartedFromZero && domain.domain.length === 0) { | ||
if (seriesItem.getPointTransformer.isStartedFromZero && domain.domain.length === 0) { | ||
domain.domain = [0]; | ||
@@ -211,6 +224,6 @@ } | ||
axes.forEach(function (_ref) { | ||
var name = _ref.name, | ||
var scaleName = _ref.scaleName, | ||
type = _ref.type; | ||
var domain = domains[scaleName]; | ||
var domain = domains[name]; | ||
if (domain) { | ||
@@ -224,12 +237,11 @@ domain.type = type; | ||
axes.forEach(function (_ref2) { | ||
var name = _ref2.name, | ||
tickFormat = _ref2.tickFormat, | ||
var scaleName = _ref2.scaleName, | ||
min = _ref2.min, | ||
max = _ref2.max; | ||
var domain = domains[scaleName]; | ||
var domain = domains[name]; | ||
if (!domain) { | ||
return; | ||
} | ||
domain.tickFormat = tickFormat; | ||
if (domain.type !== BAND) { | ||
@@ -242,5 +254,5 @@ domain.domain = [isDefined(min) ? min : domain.domain[0], isDefined(max) ? max : domain.domain[1]]; | ||
var computeDomains = function computeDomains(axes, series) { | ||
var result = collectDomains(series); | ||
// Axes options are taken in two steps because *type* is required for domains calculation | ||
var result = collectDomains(series); // Axes options are taken in two steps because *type* is required for domains calculation | ||
// and other options must be applied after domains are calculated. | ||
takeTypeFromAxesOptions(result, axes); | ||
@@ -251,10 +263,8 @@ calculateDomains(result, series); | ||
}; | ||
var buildScales = function buildScales(domains, scaleExtension, _ref3) { | ||
var width = _ref3.width, | ||
height = _ref3.height; | ||
var scales = {}; | ||
Object.entries(domains).forEach(function (_ref4) { | ||
var _ref5 = slicedToArray(_ref4, 2), | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
name = _ref5[0], | ||
@@ -284,22 +294,20 @@ domain = _ref5[1]; | ||
placeholder = _ref3.placeholder; | ||
if (isEqual(prevBBoxes[placeholder] || {}, bBox)) return prevBBoxes; | ||
return _extends({}, prevBBoxes, defineProperty({}, placeholder, bBox)); | ||
return _objectSpread({}, prevBBoxes, _defineProperty({}, placeholder, bBox)); | ||
}; | ||
var isHorizontal = function isHorizontal(name) { | ||
return name === ARGUMENT_DOMAIN; | ||
}; | ||
var getTicks = function getTicks(scale) { | ||
return scale.ticks ? scale.ticks() : scale.domain(); | ||
}; | ||
var getDominantBaseline = function getDominantBaseline(orientation, position) { | ||
if (orientation === HORIZONTAL) { | ||
return position === TOP ? 'baseline' : 'hanging'; | ||
} | ||
return MIDDLE; | ||
var createTicks = function createTicks(scale, callback) { | ||
var fixedScale = fixOffset(scale); | ||
return getTicks(scale).map(function (tick, index) { | ||
return callback(fixedScale(tick), String(index), tick); | ||
}); | ||
}; | ||
var getTextAnchor = function getTextAnchor(orientation, position) { | ||
if (orientation === HORIZONTAL) { | ||
return MIDDLE; | ||
} | ||
return position === LEFT ? END : START; | ||
}; | ||
@@ -310,2 +318,3 @@ var getFormat = function getFormat(scale, tickFormat) { | ||
} | ||
return function (tick) { | ||
@@ -316,50 +325,78 @@ return tick; | ||
// It is called for grid (which do not have labels) - how is it handled here? | ||
var calculateAxisCoordinates = function calculateAxisCoordinates(scale, orientation, position, tickSize, indentFromAxis, tickFormat) { | ||
var ticks = getTicks(scale); | ||
var offset = getWidth(scale) / 2; | ||
var dominantBaseline = getDominantBaseline(orientation, position); | ||
var textAnchor = getTextAnchor(orientation, position); | ||
var getTickCoordinates = function getTickCoordinates(tick, index) { | ||
var coordinates = scale(tick) + offset; | ||
if (orientation === HORIZONTAL) { | ||
return { | ||
dominantBaseline: dominantBaseline, | ||
textAnchor: textAnchor, | ||
x1: coordinates, | ||
x2: coordinates, | ||
y1: position === TOP ? -tickSize : 0, | ||
y2: position === TOP ? 0 : tickSize, | ||
text: getFormat(scale, tickFormat)(tick), | ||
xText: coordinates, | ||
yText: position === TOP ? -indentFromAxis : indentFromAxis, | ||
key: index | ||
}; | ||
} | ||
return { | ||
dominantBaseline: dominantBaseline, | ||
textAnchor: textAnchor, | ||
var createHorizontalOptions = function createHorizontalOptions(position, tickSize, indentFromAxis) { | ||
// Make *position* orientation agnostic - should be START or END. | ||
var isStart = position === BOTTOM; | ||
return { | ||
y1: 0, | ||
y2: isStart ? +tickSize : -tickSize, | ||
yText: isStart ? +indentFromAxis : -indentFromAxis, | ||
dominantBaseline: isStart ? 'hanging' : 'baseline', | ||
textAnchor: MIDDLE | ||
}; | ||
}; | ||
var createVerticalOptions = function createVerticalOptions(position, tickSize, indentFromAxis) { | ||
// Make *position* orientation agnostic - should be START or END. | ||
var isStart = position === LEFT; | ||
return { | ||
x1: 0, | ||
x2: isStart ? -tickSize : +tickSize, | ||
xText: isStart ? -indentFromAxis : +indentFromAxis, | ||
dominantBaseline: MIDDLE, | ||
textAnchor: isStart ? END : START | ||
}; | ||
}; | ||
var axisCoordinates = function axisCoordinates(_ref) { | ||
var scaleName = _ref.scaleName, | ||
scale = _ref.scale, | ||
position = _ref.position, | ||
tickSize = _ref.tickSize, | ||
tickFormat = _ref.tickFormat, | ||
indentFromAxis = _ref.indentFromAxis; | ||
var isHor = isHorizontal(scaleName); | ||
var options = (isHor ? createHorizontalOptions : createVerticalOptions)(position, tickSize, indentFromAxis); | ||
var formatTick = getFormat(scale, tickFormat); | ||
var ticks = createTicks(scale, function (coordinates, key, tick) { | ||
return _objectSpread({ | ||
key: key, | ||
x1: coordinates, | ||
x2: coordinates, | ||
y1: coordinates, | ||
y2: coordinates, | ||
x1: position === LEFT ? -tickSize : 0, | ||
x2: position === LEFT ? 0 : tickSize, | ||
text: getFormat(scale, tickFormat)(tick), | ||
xText: position === LEFT ? -indentFromAxis : indentFromAxis, | ||
xText: coordinates, | ||
yText: coordinates, | ||
key: index | ||
}; | ||
}; | ||
text: formatTick(tick) | ||
}, options); | ||
}); | ||
return { | ||
ticks: ticks.map(getTickCoordinates) | ||
sides: [Number(isHor), Number(!isHor)], | ||
ticks: ticks | ||
}; | ||
}; | ||
var axisCoordinates = function axisCoordinates(domain, scale, position, tickSize, indentFromAxis) { | ||
return calculateAxisCoordinates(scale, domain.orientation, position, tickSize, indentFromAxis, | ||
// TODO: *tickFormat* belongs to axis rather then domain - take it from axis. | ||
domain.tickFormat); | ||
var horizontalGridOptions = { | ||
y: 0, | ||
dy: 1 | ||
}; | ||
var verticalGridOptions = { | ||
x: 0, | ||
dx: 1 | ||
}; | ||
var getGridCoordinates = function getGridCoordinates(_ref2) { | ||
var scaleName = _ref2.scaleName, | ||
scale = _ref2.scale; | ||
var isHor = isHorizontal(scaleName); | ||
var options = isHor ? horizontalGridOptions : verticalGridOptions; | ||
return createTicks(scale, function (coordinates, key) { | ||
return _objectSpread({ | ||
key: key, | ||
x: coordinates, | ||
y: coordinates, | ||
dx: 0, | ||
dy: 0 | ||
}, options); | ||
}); | ||
}; | ||
var axesData = function axesData(axes, axisProps) { | ||
return [].concat(toConsumableArray(axes), [axisProps]); | ||
return _toConsumableArray(axes).concat([axisProps]); | ||
}; | ||
@@ -371,2 +408,3 @@ | ||
}; | ||
var getY = function getY(_ref2) { | ||
@@ -376,2 +414,3 @@ var y = _ref2.y; | ||
}; | ||
var getY1 = function getY1(_ref3) { | ||
@@ -383,21 +422,14 @@ var y1 = _ref3.y1; | ||
var DEFAULT_POINT_SIZE = 7; | ||
var dArea = area().x(getX).y1(getY).y0(getY1); | ||
var dLine = line().x(getX).y(getY); | ||
var dSpline = line().x(getX).y(getY).curve(curveMonotoneX); | ||
var getPiePointTransformer = function getPiePointTransformer(_ref4) { | ||
var _ref4$innerRadius = _ref4.innerRadius, | ||
innerRadius = _ref4$innerRadius === undefined ? 0 : _ref4$innerRadius, | ||
_ref4$outerRadius = _ref4.outerRadius, | ||
outerRadius = _ref4$outerRadius === undefined ? 1 : _ref4$outerRadius, | ||
argumentScale = _ref4.argumentScale, | ||
var argumentScale = _ref4.argumentScale, | ||
valueScale = _ref4.valueScale, | ||
palette = _ref4.palette, | ||
points = _ref4.points; | ||
var x = Math.max.apply(Math, toConsumableArray(argumentScale.range())) / 2; | ||
var y = Math.max.apply(Math, toConsumableArray(valueScale.range())) / 2; | ||
points = _ref4.points, | ||
innerRadius = _ref4.innerRadius, | ||
outerRadius = _ref4.outerRadius, | ||
palette = _ref4.palette; | ||
var x = Math.max.apply(Math, _toConsumableArray(argumentScale.range())) / 2; | ||
var y = Math.max.apply(Math, _toConsumableArray(valueScale.range())) / 2; | ||
var radius = Math.min(x, y); | ||
@@ -415,4 +447,3 @@ var pieData = pie().sort(null).value(function (d) { | ||
endAngle = _pieData$point$index.endAngle; | ||
return _extends({}, point, { | ||
return _objectSpread({}, point, { | ||
// TODO: It should be calculated in *pointComponent*. | ||
@@ -430,18 +461,24 @@ d: gen.startAngle(startAngle).endAngle(endAngle)(), | ||
}; | ||
var getAreaPointTransformer = function getAreaPointTransformer(_ref5) { | ||
var getLinePointTransformer = function getLinePointTransformer(_ref5) { | ||
var argumentScale = _ref5.argumentScale, | ||
valueScale = _ref5.valueScale; | ||
var y1 = valueScale(0); | ||
var offset = getWidth(argumentScale) / 2; | ||
var fixedArgumentScale = fixOffset(argumentScale); | ||
return function (point) { | ||
return _extends({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
y: valueScale(point.value), | ||
y1: y1 | ||
return _objectSpread({}, point, { | ||
x: fixedArgumentScale(point.argument), | ||
y: valueScale(point.value) | ||
}); | ||
}; | ||
}; | ||
var getAreaPointTransformer = function getAreaPointTransformer(series) { | ||
var transform = getLinePointTransformer(series); | ||
var y1 = series.valueScale(0); | ||
return function (point) { | ||
var ret = transform(point); | ||
ret.y1 = y1; | ||
return ret; | ||
}; | ||
}; // Used for domain calculation and stacking. | ||
getAreaPointTransformer.isStartedFromZero = true; | ||
var getBarPointTransformer = function getBarPointTransformer(_ref6) { | ||
@@ -451,3 +488,2 @@ var argumentScale = _ref6.argumentScale, | ||
barWidth = _ref6.barWidth; | ||
var y1 = valueScale(0); | ||
@@ -458,3 +494,3 @@ var categoryWidth = getWidth(argumentScale); | ||
return function (point) { | ||
return _extends({}, point, { | ||
return _objectSpread({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
@@ -466,6 +502,7 @@ y: valueScale(point.value), | ||
}; | ||
}; | ||
// Used for Bar grouping. | ||
}; // Used for domain calculation and stacking. | ||
getBarPointTransformer.isStartedFromZero = true; // Used for Bar grouping. | ||
getBarPointTransformer.isBroad = true; | ||
var findSeriesByName = function findSeriesByName(name, series) { | ||
@@ -476,3 +513,2 @@ return series.find(function (seriesItem) { | ||
}; | ||
var dBar = function dBar(_ref7) { | ||
@@ -484,10 +520,11 @@ var x = _ref7.x, | ||
return { | ||
x: x, y: Math.min(y, y1), width: width || 2, height: Math.abs(y1 - y) | ||
x: x, | ||
y: Math.min(y, y1), | ||
width: width || 2, | ||
height: Math.abs(y1 - y) | ||
}; | ||
}; | ||
var pointAttributes = function pointAttributes(_ref8) { | ||
var _ref8$size = _ref8.size, | ||
size = _ref8$size === undefined ? DEFAULT_POINT_SIZE : _ref8$size; | ||
size = _ref8$size === void 0 ? DEFAULT_POINT_SIZE : _ref8$size; | ||
var dPoint = symbol().size([Math.pow(size, 2)]).type(symbolCircle)(); | ||
@@ -504,2 +541,44 @@ return function (item) { | ||
getBarPointTransformer.getTargetElement = function (_ref9) { | ||
var x = _ref9.x, | ||
y = _ref9.y, | ||
y1 = _ref9.y1, | ||
width = _ref9.width; | ||
var height = Math.abs(y1 - y); | ||
return { | ||
x: x, | ||
y: y, | ||
d: "M0,0 ".concat(width, ",0 ").concat(width, ",").concat(height, " 0,").concat(height) | ||
}; | ||
}; | ||
getPiePointTransformer.getTargetElement = function (_ref10) { | ||
var x = _ref10.x, | ||
y = _ref10.y, | ||
innerRadius = _ref10.innerRadius, | ||
outerRadius = _ref10.outerRadius, | ||
startAngle = _ref10.startAngle, | ||
endAngle = _ref10.endAngle; | ||
var center = arc().innerRadius(innerRadius).outerRadius(outerRadius).startAngle(startAngle).endAngle(endAngle).centroid(); | ||
return { | ||
x: center[0] + x, | ||
y: center[1] + y, | ||
d: symbol().size([Math.pow(1, 2)]).type(symbolCircle)() | ||
}; | ||
}; | ||
getAreaPointTransformer.getTargetElement = function (_ref11) { | ||
var x = _ref11.x, | ||
y = _ref11.y; | ||
var size = DEFAULT_POINT_SIZE; // TODO get user size | ||
return { | ||
x: x, | ||
y: y, | ||
d: symbol().size([Math.pow(size, 2)]).type(symbolCircle)() | ||
}; | ||
}; | ||
getLinePointTransformer.getTargetElement = getAreaPointTransformer.getTargetElement; | ||
var createNewUniqueName = function createNewUniqueName(name) { | ||
@@ -514,9 +593,9 @@ return name.replace(/\d*$/, function (str) { | ||
return obj.uniqueName === item.uniqueName; | ||
}) ? addItem(list, _extends({}, item, { | ||
}) ? addItem(list, _objectSpread({}, item, { | ||
uniqueName: createNewUniqueName(item.uniqueName) | ||
})) : list.concat(item); | ||
}; | ||
}; // TODO: Memoization is much needed here. | ||
// Though "series" list never persists, single "series" item most often does. | ||
// TODO: Memoization is much needed here. | ||
// Though "series" list never persists, single "series" item most often does. | ||
var createPoints = function createPoints(argumentField, valueField, data) { | ||
@@ -527,4 +606,9 @@ var points = []; | ||
var value = dataItem[valueField]; | ||
if (argument !== undefined && value !== undefined) { | ||
points.push({ argument: argument, value: value, index: index }); | ||
points.push({ | ||
argument: argument, | ||
value: value, | ||
index: index | ||
}); | ||
} | ||
@@ -536,27 +620,24 @@ }); | ||
var addSeries = function addSeries(series, data, palette, props) { | ||
var points = createPoints(props.argumentField, props.valueField, data); | ||
// It is used to generate unique series dependent attribute names for patterns. | ||
var points = createPoints(props.argumentField, props.valueField, data); // It is used to generate unique series dependent attribute names for patterns. | ||
// *symbolName* cannot be used as it cannot be part of DOM attribute name. | ||
// TODO: Consider making *name* unique and then use it instead of *index*. | ||
var index = series.length; | ||
return addItem(series, _extends({}, props, { | ||
return addItem(series, _objectSpread({}, props, { | ||
index: index, | ||
points: points, | ||
uniqueName: props.name, | ||
palette: palette, // TODO: For Pie only. Find a better place for it. | ||
palette: palette, | ||
// TODO: For Pie only. Find a better place for it. | ||
color: props.color || palette[index % palette.length] | ||
})); | ||
}; | ||
}; // TODO: Memoization is much needed here by the same reason as in "createPoints". | ||
// Make "scales" persistent first. | ||
// TODO: Memoization is much needed here by the same reason as in "createPoints". | ||
// Make "scales" persistent first. | ||
var scalePoints = function scalePoints(series, scales) { | ||
var getPointTransformer = series.getPointTransformer, | ||
rest = objectWithoutProperties(series, ['getPointTransformer']); | ||
var transform = getPointTransformer(_extends({}, series, { | ||
var transform = series.getPointTransformer(_objectSpread({}, series, { | ||
argumentScale: scales[ARGUMENT_DOMAIN], | ||
valueScale: scales[getValueDomainName(series.axisName)] | ||
valueScale: scales[getValueDomainName(series.scaleName)] | ||
})); | ||
return _extends({}, rest, { | ||
return _objectSpread({}, series, { | ||
points: series.points.map(transform) | ||
@@ -572,3 +653,2 @@ }); | ||
// "Stack" plugin relies on "data" and "series" getters and | ||
// knowledge about "getPointTransformer" and "path" functions behavior. | ||
@@ -580,3 +660,2 @@ | ||
var series = _ref.series; | ||
series.forEach(function (name) { | ||
@@ -593,3 +672,2 @@ result[name] = i; | ||
var valueScale = series.valueScale; | ||
return function (point) { | ||
@@ -600,9 +678,10 @@ var ret = transform(point); | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
}; // Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
return wrapper; | ||
}; | ||
}; // TODO: Temporary - see corresponding note in *computeDomains*. | ||
// TODO: Temporary - see corresponding note in *computeDomains*. | ||
var getValueDomain = function getValueDomain(points) { | ||
@@ -622,4 +701,4 @@ var items = []; | ||
valueField = _ref2.valueField; | ||
var stackId = seriesToStackMap[name]; | ||
var stackId = seriesToStackMap[name]; | ||
if (stackId === undefined) { | ||
@@ -632,6 +711,7 @@ return; | ||
} | ||
seriesPositions[name] = stacksKeys[stackId].length; | ||
stacksKeys[stackId].push(valueField); | ||
}); | ||
// Stack cannot consist of single series. | ||
}); // Stack cannot consist of single series. | ||
Object.keys(stacksKeys).forEach(function (stackId) { | ||
@@ -655,15 +735,21 @@ if (stacksKeys[stackId].length === 1) { | ||
var points = series.points.map(function (point) { | ||
var _dataItems$point$inde = slicedToArray(dataItems[point.index], 2), | ||
var _dataItems$point$inde = _slicedToArray(dataItems[point.index], 2), | ||
value0 = _dataItems$point$inde[0], | ||
value = _dataItems$point$inde[1]; | ||
return _extends({}, point, { value: value, value0: value0 }); | ||
return _objectSpread({}, point, { | ||
value: value, | ||
value0: value0 | ||
}); | ||
}); | ||
var stackedSeries = _extends({}, series, { | ||
var stackedSeries = _objectSpread({}, series, { | ||
points: points | ||
}); | ||
if (series.isStartedFromZero) { | ||
if (series.getPointTransformer.isStartedFromZero) { | ||
stackedSeries.getPointTransformer = getStackedPointTransformer(series.getPointTransformer); | ||
stackedSeries.getValueDomain = getValueDomain; | ||
} | ||
return stackedSeries; | ||
@@ -674,3 +760,3 @@ }; | ||
var _collectStacks = collectStacks(seriesList, seriesToStackMap), | ||
_collectStacks2 = slicedToArray(_collectStacks, 2), | ||
_collectStacks2 = _slicedToArray(_collectStacks, 2), | ||
stacksKeys = _collectStacks2[0], | ||
@@ -682,2 +768,3 @@ seriesPositions = _collectStacks2[1]; | ||
} | ||
var stackedData = getStackedData(stacksKeys, dataItems, offset, order); | ||
@@ -687,5 +774,7 @@ return seriesList.map(function (seriesItem) { | ||
var stackData = stackedData[stackId]; | ||
if (!stackData) { | ||
return seriesItem; | ||
} | ||
var position = seriesPositions[seriesItem.name]; | ||
@@ -698,3 +787,3 @@ return buildStackedSeries(seriesItem, stackData[position]); | ||
var stackId = seriesToStackMap[series.name]; | ||
return stackId >= 0 ? String(stackId) : 'group-' + i; | ||
return stackId >= 0 ? String(stackId) : "group-".concat(i); | ||
}; | ||
@@ -706,3 +795,2 @@ | ||
var barWidth = series.barWidth; | ||
var widthCoeff = 1 / groupCount; | ||
@@ -716,4 +804,5 @@ var offsetCoeff = -(1 - barWidth) / 2 + groupOffset + widthCoeff * (1 - barWidth) / 2; | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
}; // Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
@@ -729,7 +818,8 @@ return wrapper; | ||
} | ||
}); | ||
// There cannot be single group. | ||
}); // There cannot be single group. | ||
if (groups.size < 2) { | ||
return seriesList; | ||
} | ||
var scale = scaleBand().domain(Array.from(groups)).range([0, 1]); | ||
@@ -740,4 +830,5 @@ return seriesList.map(function (seriesItem, i) { | ||
} | ||
var getPointTransformer = getGroupedPointTransformer(seriesItem.getPointTransformer, groups.size, scale(getGroupName(seriesItem, i, seriesToStackMap))); | ||
return _extends({}, seriesItem, { | ||
return _objectSpread({}, seriesItem, { | ||
getPointTransformer: getPointTransformer | ||
@@ -752,3 +843,2 @@ }); | ||
order = _ref3.order; | ||
var map = buildSeriesToStackMap(stacks); | ||
@@ -766,8 +856,12 @@ var stackedSeriesList = applyStacking(seriesList, dataItems, map, offset, order); | ||
} | ||
var head = document.getElementsByTagName('head')[0]; // eslint-disable-line no-undef | ||
var style = Array.from(head.getElementsByTagName('style')).find(function (node) { | ||
return node.dataset[ANIMATIONS]; | ||
}); | ||
if (!style) { | ||
style = document.createElement('style'); // eslint-disable-line no-undef | ||
style.type = 'text/css'; | ||
@@ -777,5 +871,7 @@ style.dataset[ANIMATIONS] = true; | ||
} | ||
var content = style.textContent; | ||
if (!content.includes(name)) { | ||
style.textContent += '\n@keyframes ' + name + ' ' + def + '\n'; | ||
style.textContent += "\n@keyframes ".concat(name, " ").concat(def, "\n"); | ||
} | ||
@@ -808,3 +904,3 @@ }; | ||
var index = _ref.index; | ||
return 0.7 + index * 0.1 + 's'; | ||
return "".concat(0.7 + index * 0.1, "s"); | ||
}; | ||
@@ -814,67 +910,180 @@ | ||
var animationStyle = { | ||
transformOrigin: '0px ' + scales.yScale.copy().clamp(true)(0) + 'px' | ||
transformOrigin: "0px ".concat(scales.yScale.copy().clamp(true)(0), "px") | ||
}; | ||
var options = getDefaultAreaAnimationOptions(); | ||
return _extends({ | ||
animation: getAreaAnimationName() + ' ' + options | ||
return _objectSpread({ | ||
animation: "".concat(getAreaAnimationName(), " ").concat(options) | ||
}, animationStyle); | ||
}; | ||
var getPieAnimationStyle = function getPieAnimationStyle(scales, point) { | ||
var options = getDefaultPieAnimationOptions(point); | ||
return { | ||
animation: getPieAnimationName() + ' ' + options | ||
animation: "".concat(getPieAnimationName(), " ").concat(options) | ||
}; | ||
}; | ||
var getScatterAnimationStyle = function getScatterAnimationStyle() { | ||
var options = getDefaultAreaAnimationOptions(); | ||
return { | ||
animation: getScatterAnimationName() + ' ' + options | ||
animation: "".concat(getScatterAnimationName(), " ").concat(options) | ||
}; | ||
}; | ||
var buildAnimatedStyleGetter = function buildAnimatedStyleGetter(style, getAnimationStyle, scales, point) { | ||
var animationStyle = getAnimationStyle(scales, point); | ||
return _extends({}, animationStyle, style); | ||
return _objectSpread({}, animationStyle, style); | ||
}; | ||
var isPointInRect = function isPointInRect(x, y, x1, x2, y1, y2) { | ||
return x1 <= x && x <= x2 && y1 <= y && y <= y2; | ||
// Comparing by reference is not an option as Tracker always sends new objects. | ||
// On the other side Tracker cannot persist references as it actually operates with simple scalars | ||
// and constructs objects to provide info in a slightly more suitable way. | ||
var compareTargets = function compareTargets(target1, target2) { | ||
return target1.series === target2.series && target1.point === target2.point; | ||
}; // Current value is chosen roughly and expected to be adjusted. | ||
var DISTANCE_PRIORITY_RATIO = 4; // If *currentTarget* is among *targets* then it has priority but only while its distance | ||
// is not significantly greater (DISTANCE_PRIORITY_RATIO) than that of the best candidate. | ||
var selectTarget = function selectTarget(targets, currentTarget) { | ||
if (!currentTarget) { | ||
return targets.length ? targets[0] : undefined; | ||
} | ||
if (!targets.length) { | ||
return null; | ||
} | ||
var candidate = targets[0]; // Skip complex checks if *currentTarget* has minimal distance. | ||
if (compareTargets(candidate, currentTarget)) { | ||
return undefined; | ||
} // Skip complex check if there is single candidate. | ||
if (targets.length === 1) { | ||
return candidate; | ||
} | ||
var current = targets.find(function (target) { | ||
return compareTargets(target, currentTarget); | ||
}); | ||
if (current) { | ||
// Here *current.distance* is exactly greater than *candidate.distance*. | ||
// The question is - how much greater? | ||
var ratio = current.distance / candidate.distance; | ||
return ratio > DISTANCE_PRIORITY_RATIO ? candidate : undefined; | ||
} | ||
return candidate; | ||
}; | ||
var processPointerMove = function processPointerMove(targets, currentTarget, notify) { | ||
var nextTarget = selectTarget(targets, currentTarget); | ||
if (nextTarget === undefined) { | ||
return undefined; | ||
} | ||
if (notify) { | ||
notify(nextTarget); | ||
} | ||
return nextTarget; | ||
}; // It handles the case when point is hovered and series does not contain visual points. | ||
// Series then knows that it is also hovered and can represent the changed state. | ||
var getHoverTargets = function getHoverTargets(hover) { | ||
if (!hover) { | ||
return []; | ||
} | ||
return hover.point >= 0 ? [{ | ||
series: hover.series | ||
}, hover] : [hover]; | ||
}; | ||
var getParameters = function getParameters(series, target) { | ||
var currentSeries = series.find(function (_ref) { | ||
var name = _ref.name; | ||
return target.series === name; | ||
}); | ||
var item = currentSeries.points.find(function (point) { | ||
return point.index === target.point; | ||
}); | ||
return { | ||
element: currentSeries.getPointTransformer.getTargetElement(item), | ||
text: "".concat(item.value) | ||
}; | ||
}; | ||
var processHandleTooltip = function processHandleTooltip(targets, currentTarget, onTargetItemChange) { | ||
var filterTargets = targets.filter(function (target) { | ||
return target.point !== undefined; | ||
}); | ||
return processPointerMove(filterTargets, currentTarget, onTargetItemChange); | ||
}; | ||
var getUniformDistance = function getUniformDistance(dx, dy, rx, ry) { | ||
return Math.max(Math.abs(dx) / rx, Math.abs(dy) / ry); | ||
}; // Based on https://en.wikipedia.org/wiki/Norm_(mathematics)#Euclidean_norm | ||
var getEuclideanDistance = function getEuclideanDistance(dx, dy, rx, ry) { | ||
return Math.sqrt(dx * dx / (rx * rx) + dy * dy / (ry * ry)); | ||
}; | ||
var createPointsEnumeratingHitTesterCreator = function createPointsEnumeratingHitTesterCreator(hitTestPoint) { | ||
return function (points) { | ||
return function (target) { | ||
var list = []; | ||
points.forEach(function (point) { | ||
// *distance* is a normalized distance to point. | ||
// It belongs to [0, Infinity): | ||
// = 0 - at point center | ||
// = 1 - at point border | ||
// > 1 - outside point | ||
var distance = hitTestPoint(target, point); | ||
if (distance <= 1) { | ||
list.push({ | ||
index: point.index, | ||
distance: distance | ||
}); | ||
} | ||
}); | ||
return list.length ? { | ||
points: list | ||
} : null; | ||
}; | ||
}; | ||
}; | ||
var LINE_TOLERANCE = 10; | ||
var createContinuousSeriesPointsHitTester = createPointsEnumeratingHitTesterCreator(function (_ref, _ref2) { | ||
var _ref3 = _slicedToArray(_ref, 2), | ||
px = _ref3[0], | ||
py = _ref3[1]; | ||
// This function is called from event handlers (when DOM is available) - | ||
var x = _ref2.x, | ||
y = _ref2.y; | ||
return getEuclideanDistance(px - x, py - y, LINE_TOLERANCE, LINE_TOLERANCE); | ||
}); // This function is called from event handlers (when DOM is available) - | ||
// *window.document* can be accessed safely. | ||
var createContext = function createContext() { | ||
return document.createElement('canvas').getContext('2d'); | ||
}; // eslint-disable-line no-undef | ||
// For a start using browser canvas will suffice. | ||
// However a better and more clean solution should be found. | ||
// Can't d3 perform hit testing? | ||
var createCanvasAbusingHitTesterCreator = function createCanvasAbusingHitTesterCreator(makePath) { | ||
return function (coordinates) { | ||
return function (points) { | ||
var ctx = createContext(); | ||
var path = makePath(); | ||
path.context(ctx); | ||
path(coordinates); | ||
return function (_ref) { | ||
var _ref2 = slicedToArray(_ref, 2), | ||
px = _ref2[0], | ||
py = _ref2[1]; | ||
var hit = ctx.isPointInPath(px, py) ? {} : null; | ||
if (hit) { | ||
var point = coordinates.find(function (_ref3) { | ||
var x = _ref3.x, | ||
y = _ref3.y; | ||
return isPointInRect(px, py, x - LINE_TOLERANCE, x + LINE_TOLERANCE, y - LINE_TOLERANCE, y + LINE_TOLERANCE); | ||
}); | ||
if (point) { | ||
hit.point = point.index; | ||
} | ||
} | ||
return hit; | ||
path(points); | ||
var hitTestPoints = createContinuousSeriesPointsHitTester(points); | ||
return function (point) { | ||
return ctx.isPointInPath(point[0], point[1]) ? hitTestPoints(point) || {} : null; | ||
}; | ||
@@ -891,3 +1100,2 @@ }; | ||
}); | ||
var createLineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
@@ -905,3 +1113,2 @@ var path = area(); | ||
}); | ||
var createSplineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
@@ -919,36 +1126,25 @@ var path = area(); | ||
return path; | ||
}); | ||
}); // Some kind of binary search can be used here as bars can be ordered along argument axis. | ||
var createBarHitTester = function createBarHitTester(coordinates) { | ||
return function (_ref4) { | ||
var _ref5 = slicedToArray(_ref4, 2), | ||
px = _ref5[0], | ||
py = _ref5[1]; | ||
var createBarHitTester = createPointsEnumeratingHitTesterCreator(function (_ref4, point) { | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
px = _ref5[0], | ||
py = _ref5[1]; | ||
var point = coordinates.find(function (_ref6) { | ||
var x = _ref6.x, | ||
width = _ref6.width, | ||
y = _ref6.y, | ||
y1 = _ref6.y1; | ||
return isPointInRect(px, py, x, x + width, Math.min(y, y1), Math.max(y, y1)); | ||
}); | ||
return point ? { point: point.index } : null; | ||
}; | ||
}; | ||
var xCenter = point.x + point.width / 2; | ||
var yCenter = (point.y + point.y1) / 2; | ||
var halfWidth = point.width / 2; | ||
var halfHeight = Math.abs(point.y - point.y1) / 2; | ||
return getUniformDistance(px - xCenter, py - yCenter, halfWidth, halfHeight); | ||
}); // TODO: Use actual point size here! | ||
// TODO: Use actual point size here! | ||
var createScatterHitTester = function createScatterHitTester(coordinates) { | ||
return function (_ref7) { | ||
var _ref8 = slicedToArray(_ref7, 2), | ||
px = _ref8[0], | ||
py = _ref8[1]; | ||
var createScatterHitTester = createPointsEnumeratingHitTesterCreator(function (_ref6, _ref7) { | ||
var _ref8 = _slicedToArray(_ref6, 2), | ||
px = _ref8[0], | ||
py = _ref8[1]; | ||
var point = coordinates.find(function (_ref9) { | ||
var x = _ref9.x, | ||
y = _ref9.y; | ||
return isPointInRect(px, py, x - 10, x + 10, y - 10, y + 10); | ||
}); | ||
return point ? { point: point.index } : null; | ||
}; | ||
}; | ||
var x = _ref7.x, | ||
y = _ref7.y; | ||
return getEuclideanDistance(px - x, py - y, 10, 10); | ||
}); | ||
@@ -958,38 +1154,36 @@ var mapAngleTod3 = function mapAngleTod3(angle) { | ||
return ret >= 0 ? ret : ret + Math.PI * 2; | ||
}; | ||
}; // Some kind of binary search can be used here as pies can be ordered along angle axis. | ||
var createPieHitTester = function createPieHitTester(coordinates) { | ||
return function (_ref10) { | ||
var _ref11 = slicedToArray(_ref10, 2), | ||
px = _ref11[0], | ||
py = _ref11[1]; | ||
var point = coordinates.find(function (_ref12) { | ||
var x = _ref12.x, | ||
y = _ref12.y, | ||
innerRadius = _ref12.innerRadius, | ||
outerRadius = _ref12.outerRadius, | ||
startAngle = _ref12.startAngle, | ||
endAngle = _ref12.endAngle; | ||
var createPieHitTester = createPointsEnumeratingHitTesterCreator(function (_ref9, _ref10) { | ||
var _ref11 = _slicedToArray(_ref9, 2), | ||
px = _ref11[0], | ||
py = _ref11[1]; | ||
var dx = px - x; | ||
var dy = py - y; | ||
var r = Math.sqrt(dx * dx + dy * dy); | ||
if (r < innerRadius || r > outerRadius) { | ||
return null; | ||
} | ||
var angle = mapAngleTod3(Math.atan2(dy, dx)); | ||
return startAngle <= angle && angle <= endAngle; | ||
}); | ||
return point ? { point: point.index } : null; | ||
}; | ||
}; | ||
var x = _ref10.x, | ||
y = _ref10.y, | ||
innerRadius = _ref10.innerRadius, | ||
outerRadius = _ref10.outerRadius, | ||
startAngle = _ref10.startAngle, | ||
endAngle = _ref10.endAngle; | ||
var rCenter = (innerRadius + outerRadius) / 2; | ||
var angleCenter = (startAngle + endAngle) / 2; | ||
var halfRadius = (outerRadius - innerRadius) / 2; | ||
var halfAngle = Math.abs(startAngle - endAngle) / 2; | ||
var dx = px - x; | ||
var dy = py - y; | ||
var r = Math.sqrt(dx * dx + dy * dy); | ||
var angle = mapAngleTod3(Math.atan2(dy, dx)); | ||
return getUniformDistance(r - rCenter, angle - angleCenter, halfRadius, halfAngle); | ||
}); | ||
var buildFilter = function buildFilter(targets) { | ||
var result = {}; | ||
targets.forEach(function (_ref13) { | ||
var series = _ref13.series, | ||
point = _ref13.point; | ||
targets.forEach(function (_ref12) { | ||
var series = _ref12.series, | ||
point = _ref12.point; | ||
result[series] = result[series] || { | ||
points: {} | ||
}; | ||
result[series] = result[series] || { points: {} }; | ||
if (point >= 0) { | ||
@@ -1008,2 +1202,3 @@ result[series].points[point] = true; | ||
} | ||
var filter = buildFilter(targets); | ||
@@ -1013,18 +1208,25 @@ var matches = 0; | ||
var obj = filter[seriesItem.name]; | ||
if (!obj) { | ||
return seriesItem; | ||
} | ||
matches += 1; | ||
var props = {}; | ||
if (obj.self) { | ||
props.state = state; | ||
} | ||
if (Object.keys(obj.points).length) { | ||
props.points = seriesItem.points.map(function (point) { | ||
return obj.points[point.index] ? _extends({}, point, { state: state }) : point; | ||
return obj.points[point.index] ? _objectSpread({}, point, { | ||
state: state | ||
}) : point; | ||
}); | ||
} | ||
return _extends({}, seriesItem, props); | ||
}); | ||
// This is to prevent false rerenders. | ||
return _objectSpread({}, seriesItem, props); | ||
}); // This is to prevent false rerenders. | ||
return matches > 0 ? result : seriesList; | ||
@@ -1037,3 +1239,6 @@ }; | ||
color = _ref.color; | ||
return { text: text, color: color }; | ||
return { | ||
text: text, | ||
color: color | ||
}; | ||
}); | ||
@@ -1046,9 +1251,12 @@ }; | ||
color = _ref2.color; | ||
return { text: text, color: color }; | ||
return { | ||
text: text, | ||
color: color | ||
}; | ||
}); | ||
}; | ||
// The function supports special case when there is single Pie series. | ||
}; // The function supports special case when there is single Pie series. | ||
// There is no commom way to tell if series is of Pie type - | ||
// checking `seriesComponent` function name will suffice for now. | ||
var isSinglePieSeriesCase = function isSinglePieSeriesCase(series) { | ||
@@ -1076,2 +1284,6 @@ return series.length === 1 && series[0].seriesComponent.name === 'SliceCollection'; | ||
var compare = function compare(t1, t2) { | ||
return t1.distance - t2.distance; | ||
}; | ||
var buildEventHandler = function buildEventHandler(seriesList, handlers) { | ||
@@ -1092,9 +1304,29 @@ var hitTesters = null; | ||
var targets = []; | ||
seriesList.forEach(function (seriesItem) { | ||
var status = hitTesters[seriesItem.symbolName](location); | ||
seriesList.forEach(function (_ref) { | ||
var series = _ref.name, | ||
symbolName = _ref.symbolName; | ||
var status = hitTesters[symbolName](location); | ||
if (status) { | ||
targets.push(_extends({ series: seriesItem.name }, status)); | ||
if (status.points) { | ||
targets.push.apply(targets, _toConsumableArray(status.points.map(function (point) { | ||
return { | ||
series: series, | ||
point: point.index, | ||
distance: point.distance | ||
}; | ||
}))); | ||
} else { | ||
targets.push({ | ||
series: series, | ||
distance: 1 | ||
}); | ||
} | ||
} | ||
}); | ||
var arg = { location: location, targets: targets }; | ||
targets.sort(compare); | ||
var arg = { | ||
location: location, | ||
targets: targets | ||
}; | ||
handlers.forEach(function (handler) { | ||
@@ -1109,3 +1341,6 @@ return handler(arg); | ||
var location = getEventCoords(e); | ||
var arg = { location: location, targets: [] }; | ||
var arg = { | ||
location: location, | ||
targets: [] | ||
}; | ||
handlers.forEach(function (handler) { | ||
@@ -1117,10 +1352,11 @@ return handler(arg); | ||
var buildEventHandlers = function buildEventHandlers(seriesList, _ref) { | ||
var clickHandlers = _ref.clickHandlers, | ||
pointerMoveHandlers = _ref.pointerMoveHandlers; | ||
var buildEventHandlers = function buildEventHandlers(seriesList, _ref2) { | ||
var clickHandlers = _ref2.clickHandlers, | ||
pointerMoveHandlers = _ref2.pointerMoveHandlers; | ||
var handlers = {}; | ||
var handlers = {}; | ||
if (clickHandlers.length) { | ||
handlers.click = buildEventHandler(seriesList, clickHandlers); | ||
} | ||
if (pointerMoveHandlers.length) { | ||
@@ -1130,37 +1366,7 @@ handlers.pointermove = buildEventHandler(seriesList, pointerMoveHandlers); | ||
} | ||
return handlers; | ||
}; | ||
var selectTarget = function selectTarget(targets) { | ||
return targets.length > 0 ? targets[targets.length - 1] : null; | ||
}; | ||
// Comparing by reference is not an option as Tracker always sends new objects. | ||
// On the other side Tracker cannot persist references as it actually operates with simple scalars | ||
// and constructs objects to provide info in a slightly more suitable way. | ||
var compareTargets = function compareTargets(target1, target2) { | ||
return target1 && target2 && target1.series === target2.series && target1.point === target2.point || !target1 && !target2; | ||
}; | ||
var processPointerMove = function processPointerMove(targets, currentTarget, notify) { | ||
var nextTarget = selectTarget(targets); | ||
if (compareTargets(currentTarget, nextTarget)) { | ||
return undefined; | ||
} | ||
if (notify) { | ||
notify(nextTarget); | ||
} | ||
return nextTarget; | ||
}; | ||
// It handles the case when point is hovered and series does not contain visual points. | ||
// Series then knows that it is also hovered and can represent the changed state. | ||
var getHoverTargets = function getHoverTargets(hover) { | ||
if (!hover) { | ||
return []; | ||
} | ||
return hover.point >= 0 ? [{ series: hover.series }, hover] : [hover]; | ||
}; | ||
export { computeExtension, computeDomains, buildScales, bBoxes, axisCoordinates, axesData, dArea, dLine, dSpline, getPiePointTransformer, getAreaPointTransformer, getBarPointTransformer, findSeriesByName, dBar, pointAttributes, addSeries, scaleSeriesPoints, getStackedSeries, getAreaAnimationStyle, getPieAnimationStyle, getScatterAnimationStyle, buildAnimatedStyleGetter, createAreaHitTester, createLineHitTester, createSplineHitTester, createBarHitTester, createScatterHitTester, createPieHitTester, changeSeriesState, createScale, getWidth, getValueDomainName, getLegendItems, buildEventHandlers, processPointerMove, getHoverTargets, HORIZONTAL, VERTICAL, TOP, BOTTOM, LEFT, RIGHT, MIDDLE, END, START, LINEAR, BAND, ARGUMENT_DOMAIN, VALUE_DOMAIN, HOVERED, SELECTED }; | ||
export { computeExtension, computeDomains, buildScales, bBoxes, axisCoordinates, getGridCoordinates, axesData, dArea, dLine, dSpline, getPiePointTransformer, getLinePointTransformer, getAreaPointTransformer, getBarPointTransformer, findSeriesByName, dBar, pointAttributes, addSeries, scaleSeriesPoints, getStackedSeries, getAreaAnimationStyle, getPieAnimationStyle, getScatterAnimationStyle, buildAnimatedStyleGetter, getParameters, processHandleTooltip, createAreaHitTester, createLineHitTester, createSplineHitTester, createBarHitTester, createScatterHitTester, createPieHitTester, changeSeriesState, createScale, getWidth, getValueDomainName, fixOffset, getLegendItems, buildEventHandlers, processPointerMove, getHoverTargets, HORIZONTAL, VERTICAL, TOP, BOTTOM, LEFT, RIGHT, MIDDLE, END, START, LINEAR, BAND, ARGUMENT_DOMAIN, VALUE_DOMAIN, HOVERED, SELECTED }; | ||
//# sourceMappingURL=dx-chart-core.es.js.map |
/** | ||
* Bundle of @devexpress/dx-chart-core | ||
* Generated: 2018-11-07 | ||
* Version: 1.9.0 | ||
* Generated: 2018-12-07 | ||
* Version: 1.9.1 | ||
* License: https://js.devexpress.com/Licensing | ||
@@ -14,38 +14,3 @@ */ | ||
var HORIZONTAL = 'horizontal'; | ||
var VERTICAL = 'vertical'; | ||
var TOP = 'top'; | ||
var BOTTOM = 'bottom'; | ||
var LEFT = 'left'; | ||
var RIGHT = 'right'; | ||
var MIDDLE = 'middle'; | ||
var END = 'end'; | ||
var START = 'start'; | ||
var LINEAR = 'linear'; | ||
var BAND = 'band'; | ||
var ARGUMENT_DOMAIN = 'argument-domain'; | ||
var VALUE_DOMAIN = 'value-domain'; | ||
var HOVERED = 'hovered'; | ||
var SELECTED = 'selected'; | ||
var createScale = function createScale(_ref, width, height, constructor) { | ||
var domain = _ref.domain, | ||
orientation = _ref.orientation; | ||
var scale = constructor(); | ||
return scale.domain(domain).range(orientation === HORIZONTAL ? [0, width] : [height, 0]); | ||
}; | ||
var getWidth = function getWidth(scale) { | ||
return scale.bandwidth ? scale.bandwidth() : 0; | ||
}; | ||
var getValueDomainName = function getValueDomainName(name) { | ||
return name || VALUE_DOMAIN; | ||
}; | ||
var defineProperty = function (obj, key, value) { | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
@@ -63,89 +28,127 @@ Object.defineProperty(obj, key, { | ||
return obj; | ||
}; | ||
} | ||
var _extends = Object.assign || function (target) { | ||
function _objectSpread(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
var ownKeys = Object.keys(source); | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
if (typeof Object.getOwnPropertySymbols === 'function') { | ||
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(source, sym).enumerable; | ||
})); | ||
} | ||
ownKeys.forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} | ||
return target; | ||
}; | ||
} | ||
var objectWithoutProperties = function (obj, keys) { | ||
var target = {}; | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); | ||
} | ||
for (var i in obj) { | ||
if (keys.indexOf(i) >= 0) continue; | ||
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; | ||
target[i] = obj[i]; | ||
function _toConsumableArray(arr) { | ||
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); | ||
} | ||
function _arrayWithoutHoles(arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
} | ||
return target; | ||
}; | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
var slicedToArray = function () { | ||
function sliceIterator(arr, i) { | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
function _iterableToArray(iter) { | ||
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); | ||
} | ||
function _iterableToArrayLimit(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 { | ||
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; | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
try { | ||
if (!_n && _i["return"]) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
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"); | ||
} | ||
}; | ||
}(); | ||
return _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]; | ||
function _nonIterableSpread() { | ||
throw new TypeError("Invalid attempt to spread non-iterable instance"); | ||
} | ||
return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
} | ||
var HORIZONTAL = 'horizontal'; | ||
var VERTICAL = 'vertical'; | ||
var TOP = 'top'; | ||
var BOTTOM = 'bottom'; | ||
var LEFT = 'left'; | ||
var RIGHT = 'right'; | ||
var MIDDLE = 'middle'; | ||
var END = 'end'; | ||
var START = 'start'; | ||
var LINEAR = 'linear'; | ||
var BAND = 'band'; | ||
var ARGUMENT_DOMAIN = 'argument-domain'; | ||
var VALUE_DOMAIN = 'value-domain'; | ||
var HOVERED = 'hovered'; | ||
var SELECTED = 'selected'; | ||
var createScale = function createScale(_ref, width, height, constructor) { | ||
var domain = _ref.domain, | ||
orientation = _ref.orientation; | ||
var scale = constructor(); | ||
return scale.domain(domain).range(orientation === HORIZONTAL ? [0, width] : [height, 0]); | ||
}; | ||
var getWidth = function getWidth(scale) { | ||
return scale.bandwidth ? scale.bandwidth() : 0; | ||
}; | ||
var getValueDomainName = function getValueDomainName(name) { | ||
return name || VALUE_DOMAIN; | ||
}; | ||
var fixOffset = function fixOffset(scale) { | ||
var offset = getWidth(scale) / 2; | ||
return offset > 0 ? function (value) { | ||
return scale(value) + offset; | ||
} : scale; | ||
}; | ||
var isDefined = function isDefined(item) { | ||
return item !== undefined; | ||
}; | ||
}; // TODO: Property name should not contain "axis" part as it actually means domain. | ||
// TODO: Property name should not contain "axis" part as it actually means domain. | ||
var getSeriesValueDomainName = function getSeriesValueDomainName(series) { | ||
return getValueDomainName(series.axisName); | ||
return getValueDomainName(series.scaleName); | ||
}; | ||
var calculateDomainField = function calculateDomainField(items, domain, type) { | ||
return type === BAND ? [].concat(toConsumableArray(domain), toConsumableArray(items)) : d3Array.extent([].concat(toConsumableArray(domain), toConsumableArray(d3Array.extent(items)))); | ||
return type === BAND ? _toConsumableArray(domain).concat(_toConsumableArray(items)) : d3Array.extent(_toConsumableArray(domain).concat(_toConsumableArray(d3Array.extent(items)))); | ||
}; | ||
@@ -169,16 +172,12 @@ | ||
var points = seriesItem.points; | ||
var argumentDomain = domains[ARGUMENT_DOMAIN]; | ||
var valueDomain = domains[valueDomainName]; | ||
var valueType = getCorrectAxisType(valueDomain.type, points, getValue); | ||
var argumentType = getCorrectAxisType(argumentDomain.type, points, getArgument); | ||
// TODO: This is a temporary workaround for Stack plugin. | ||
var argumentType = getCorrectAxisType(argumentDomain.type, points, getArgument); // TODO: This is a temporary workaround for Stack plugin. | ||
// Once scales (or domains) are exposed for modification Stack will modify scale and | ||
// this code will be removed. | ||
var valueDomainItems = seriesItem.getValueDomain ? seriesItem.getValueDomain(points) : points.map(getValue); | ||
valueDomain.domain = calculateDomainField(valueDomainItems, valueDomain.domain, valueType); | ||
valueDomain.type = valueType; | ||
argumentDomain.domain = calculateDomainField(points.map(getArgument), argumentDomain.domain, argumentType); | ||
@@ -190,5 +189,11 @@ argumentDomain.type = argumentType; | ||
var computeExtension = function computeExtension(extension) { | ||
var defaultExtension = [{ type: LINEAR, constructor: d3Scale.scaleLinear }, { type: BAND, constructor: function constructor() { | ||
var defaultExtension = [{ | ||
type: LINEAR, | ||
constructor: d3Scale.scaleLinear | ||
}, { | ||
type: BAND, | ||
constructor: function constructor() { | ||
return d3Scale.scaleBand().paddingInner(0.3).paddingOuter(0.15); | ||
} }]; | ||
} | ||
}]; | ||
return extension.concat(defaultExtension); | ||
@@ -198,8 +203,16 @@ }; | ||
var collectDomains = function collectDomains(seriesList) { | ||
var domains = defineProperty({}, ARGUMENT_DOMAIN, { domain: [], orientation: HORIZONTAL }); | ||
var domains = _defineProperty({}, ARGUMENT_DOMAIN, { | ||
domain: [], | ||
orientation: HORIZONTAL | ||
}); | ||
seriesList.forEach(function (seriesItem) { | ||
var name = getSeriesValueDomainName(seriesItem); | ||
var domain = domains[name] || { domain: [], orientation: VERTICAL }; | ||
var domain = domains[name] || { | ||
domain: [], | ||
orientation: VERTICAL | ||
}; | ||
domains[name] = domain; | ||
if (seriesItem.isStartedFromZero && domain.domain.length === 0) { | ||
if (seriesItem.getPointTransformer.isStartedFromZero && domain.domain.length === 0) { | ||
domain.domain = [0]; | ||
@@ -213,6 +226,6 @@ } | ||
axes.forEach(function (_ref) { | ||
var name = _ref.name, | ||
var scaleName = _ref.scaleName, | ||
type = _ref.type; | ||
var domain = domains[scaleName]; | ||
var domain = domains[name]; | ||
if (domain) { | ||
@@ -226,12 +239,11 @@ domain.type = type; | ||
axes.forEach(function (_ref2) { | ||
var name = _ref2.name, | ||
tickFormat = _ref2.tickFormat, | ||
var scaleName = _ref2.scaleName, | ||
min = _ref2.min, | ||
max = _ref2.max; | ||
var domain = domains[scaleName]; | ||
var domain = domains[name]; | ||
if (!domain) { | ||
return; | ||
} | ||
domain.tickFormat = tickFormat; | ||
if (domain.type !== BAND) { | ||
@@ -244,5 +256,5 @@ domain.domain = [isDefined(min) ? min : domain.domain[0], isDefined(max) ? max : domain.domain[1]]; | ||
var computeDomains = function computeDomains(axes, series) { | ||
var result = collectDomains(series); | ||
// Axes options are taken in two steps because *type* is required for domains calculation | ||
var result = collectDomains(series); // Axes options are taken in two steps because *type* is required for domains calculation | ||
// and other options must be applied after domains are calculated. | ||
takeTypeFromAxesOptions(result, axes); | ||
@@ -253,10 +265,8 @@ calculateDomains(result, series); | ||
}; | ||
var buildScales = function buildScales(domains, scaleExtension, _ref3) { | ||
var width = _ref3.width, | ||
height = _ref3.height; | ||
var scales = {}; | ||
Object.entries(domains).forEach(function (_ref4) { | ||
var _ref5 = slicedToArray(_ref4, 2), | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
name = _ref5[0], | ||
@@ -286,22 +296,20 @@ domain = _ref5[1]; | ||
placeholder = _ref3.placeholder; | ||
if (isEqual(prevBBoxes[placeholder] || {}, bBox)) return prevBBoxes; | ||
return _extends({}, prevBBoxes, defineProperty({}, placeholder, bBox)); | ||
return _objectSpread({}, prevBBoxes, _defineProperty({}, placeholder, bBox)); | ||
}; | ||
var isHorizontal = function isHorizontal(name) { | ||
return name === ARGUMENT_DOMAIN; | ||
}; | ||
var getTicks = function getTicks(scale) { | ||
return scale.ticks ? scale.ticks() : scale.domain(); | ||
}; | ||
var getDominantBaseline = function getDominantBaseline(orientation, position) { | ||
if (orientation === HORIZONTAL) { | ||
return position === TOP ? 'baseline' : 'hanging'; | ||
} | ||
return MIDDLE; | ||
var createTicks = function createTicks(scale, callback) { | ||
var fixedScale = fixOffset(scale); | ||
return getTicks(scale).map(function (tick, index) { | ||
return callback(fixedScale(tick), String(index), tick); | ||
}); | ||
}; | ||
var getTextAnchor = function getTextAnchor(orientation, position) { | ||
if (orientation === HORIZONTAL) { | ||
return MIDDLE; | ||
} | ||
return position === LEFT ? END : START; | ||
}; | ||
@@ -312,2 +320,3 @@ var getFormat = function getFormat(scale, tickFormat) { | ||
} | ||
return function (tick) { | ||
@@ -318,50 +327,78 @@ return tick; | ||
// It is called for grid (which do not have labels) - how is it handled here? | ||
var calculateAxisCoordinates = function calculateAxisCoordinates(scale, orientation, position, tickSize, indentFromAxis, tickFormat) { | ||
var ticks = getTicks(scale); | ||
var offset = getWidth(scale) / 2; | ||
var dominantBaseline = getDominantBaseline(orientation, position); | ||
var textAnchor = getTextAnchor(orientation, position); | ||
var getTickCoordinates = function getTickCoordinates(tick, index) { | ||
var coordinates = scale(tick) + offset; | ||
if (orientation === HORIZONTAL) { | ||
return { | ||
dominantBaseline: dominantBaseline, | ||
textAnchor: textAnchor, | ||
x1: coordinates, | ||
x2: coordinates, | ||
y1: position === TOP ? -tickSize : 0, | ||
y2: position === TOP ? 0 : tickSize, | ||
text: getFormat(scale, tickFormat)(tick), | ||
xText: coordinates, | ||
yText: position === TOP ? -indentFromAxis : indentFromAxis, | ||
key: index | ||
}; | ||
} | ||
return { | ||
dominantBaseline: dominantBaseline, | ||
textAnchor: textAnchor, | ||
var createHorizontalOptions = function createHorizontalOptions(position, tickSize, indentFromAxis) { | ||
// Make *position* orientation agnostic - should be START or END. | ||
var isStart = position === BOTTOM; | ||
return { | ||
y1: 0, | ||
y2: isStart ? +tickSize : -tickSize, | ||
yText: isStart ? +indentFromAxis : -indentFromAxis, | ||
dominantBaseline: isStart ? 'hanging' : 'baseline', | ||
textAnchor: MIDDLE | ||
}; | ||
}; | ||
var createVerticalOptions = function createVerticalOptions(position, tickSize, indentFromAxis) { | ||
// Make *position* orientation agnostic - should be START or END. | ||
var isStart = position === LEFT; | ||
return { | ||
x1: 0, | ||
x2: isStart ? -tickSize : +tickSize, | ||
xText: isStart ? -indentFromAxis : +indentFromAxis, | ||
dominantBaseline: MIDDLE, | ||
textAnchor: isStart ? END : START | ||
}; | ||
}; | ||
var axisCoordinates = function axisCoordinates(_ref) { | ||
var scaleName = _ref.scaleName, | ||
scale = _ref.scale, | ||
position = _ref.position, | ||
tickSize = _ref.tickSize, | ||
tickFormat = _ref.tickFormat, | ||
indentFromAxis = _ref.indentFromAxis; | ||
var isHor = isHorizontal(scaleName); | ||
var options = (isHor ? createHorizontalOptions : createVerticalOptions)(position, tickSize, indentFromAxis); | ||
var formatTick = getFormat(scale, tickFormat); | ||
var ticks = createTicks(scale, function (coordinates, key, tick) { | ||
return _objectSpread({ | ||
key: key, | ||
x1: coordinates, | ||
x2: coordinates, | ||
y1: coordinates, | ||
y2: coordinates, | ||
x1: position === LEFT ? -tickSize : 0, | ||
x2: position === LEFT ? 0 : tickSize, | ||
text: getFormat(scale, tickFormat)(tick), | ||
xText: position === LEFT ? -indentFromAxis : indentFromAxis, | ||
xText: coordinates, | ||
yText: coordinates, | ||
key: index | ||
}; | ||
}; | ||
text: formatTick(tick) | ||
}, options); | ||
}); | ||
return { | ||
ticks: ticks.map(getTickCoordinates) | ||
sides: [Number(isHor), Number(!isHor)], | ||
ticks: ticks | ||
}; | ||
}; | ||
var axisCoordinates = function axisCoordinates(domain, scale, position, tickSize, indentFromAxis) { | ||
return calculateAxisCoordinates(scale, domain.orientation, position, tickSize, indentFromAxis, | ||
// TODO: *tickFormat* belongs to axis rather then domain - take it from axis. | ||
domain.tickFormat); | ||
var horizontalGridOptions = { | ||
y: 0, | ||
dy: 1 | ||
}; | ||
var verticalGridOptions = { | ||
x: 0, | ||
dx: 1 | ||
}; | ||
var getGridCoordinates = function getGridCoordinates(_ref2) { | ||
var scaleName = _ref2.scaleName, | ||
scale = _ref2.scale; | ||
var isHor = isHorizontal(scaleName); | ||
var options = isHor ? horizontalGridOptions : verticalGridOptions; | ||
return createTicks(scale, function (coordinates, key) { | ||
return _objectSpread({ | ||
key: key, | ||
x: coordinates, | ||
y: coordinates, | ||
dx: 0, | ||
dy: 0 | ||
}, options); | ||
}); | ||
}; | ||
var axesData = function axesData(axes, axisProps) { | ||
return [].concat(toConsumableArray(axes), [axisProps]); | ||
return _toConsumableArray(axes).concat([axisProps]); | ||
}; | ||
@@ -373,2 +410,3 @@ | ||
}; | ||
var getY = function getY(_ref2) { | ||
@@ -378,2 +416,3 @@ var y = _ref2.y; | ||
}; | ||
var getY1 = function getY1(_ref3) { | ||
@@ -385,21 +424,14 @@ var y1 = _ref3.y1; | ||
var DEFAULT_POINT_SIZE = 7; | ||
var dArea = d3Shape.area().x(getX).y1(getY).y0(getY1); | ||
var dLine = d3Shape.line().x(getX).y(getY); | ||
var dSpline = d3Shape.line().x(getX).y(getY).curve(d3Shape.curveMonotoneX); | ||
var getPiePointTransformer = function getPiePointTransformer(_ref4) { | ||
var _ref4$innerRadius = _ref4.innerRadius, | ||
innerRadius = _ref4$innerRadius === undefined ? 0 : _ref4$innerRadius, | ||
_ref4$outerRadius = _ref4.outerRadius, | ||
outerRadius = _ref4$outerRadius === undefined ? 1 : _ref4$outerRadius, | ||
argumentScale = _ref4.argumentScale, | ||
var argumentScale = _ref4.argumentScale, | ||
valueScale = _ref4.valueScale, | ||
palette = _ref4.palette, | ||
points = _ref4.points; | ||
var x = Math.max.apply(Math, toConsumableArray(argumentScale.range())) / 2; | ||
var y = Math.max.apply(Math, toConsumableArray(valueScale.range())) / 2; | ||
points = _ref4.points, | ||
innerRadius = _ref4.innerRadius, | ||
outerRadius = _ref4.outerRadius, | ||
palette = _ref4.palette; | ||
var x = Math.max.apply(Math, _toConsumableArray(argumentScale.range())) / 2; | ||
var y = Math.max.apply(Math, _toConsumableArray(valueScale.range())) / 2; | ||
var radius = Math.min(x, y); | ||
@@ -417,4 +449,3 @@ var pieData = d3Shape.pie().sort(null).value(function (d) { | ||
endAngle = _pieData$point$index.endAngle; | ||
return _extends({}, point, { | ||
return _objectSpread({}, point, { | ||
// TODO: It should be calculated in *pointComponent*. | ||
@@ -432,18 +463,24 @@ d: gen.startAngle(startAngle).endAngle(endAngle)(), | ||
}; | ||
var getAreaPointTransformer = function getAreaPointTransformer(_ref5) { | ||
var getLinePointTransformer = function getLinePointTransformer(_ref5) { | ||
var argumentScale = _ref5.argumentScale, | ||
valueScale = _ref5.valueScale; | ||
var y1 = valueScale(0); | ||
var offset = getWidth(argumentScale) / 2; | ||
var fixedArgumentScale = fixOffset(argumentScale); | ||
return function (point) { | ||
return _extends({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
y: valueScale(point.value), | ||
y1: y1 | ||
return _objectSpread({}, point, { | ||
x: fixedArgumentScale(point.argument), | ||
y: valueScale(point.value) | ||
}); | ||
}; | ||
}; | ||
var getAreaPointTransformer = function getAreaPointTransformer(series) { | ||
var transform = getLinePointTransformer(series); | ||
var y1 = series.valueScale(0); | ||
return function (point) { | ||
var ret = transform(point); | ||
ret.y1 = y1; | ||
return ret; | ||
}; | ||
}; // Used for domain calculation and stacking. | ||
getAreaPointTransformer.isStartedFromZero = true; | ||
var getBarPointTransformer = function getBarPointTransformer(_ref6) { | ||
@@ -453,3 +490,2 @@ var argumentScale = _ref6.argumentScale, | ||
barWidth = _ref6.barWidth; | ||
var y1 = valueScale(0); | ||
@@ -460,3 +496,3 @@ var categoryWidth = getWidth(argumentScale); | ||
return function (point) { | ||
return _extends({}, point, { | ||
return _objectSpread({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
@@ -468,6 +504,7 @@ y: valueScale(point.value), | ||
}; | ||
}; | ||
// Used for Bar grouping. | ||
}; // Used for domain calculation and stacking. | ||
getBarPointTransformer.isStartedFromZero = true; // Used for Bar grouping. | ||
getBarPointTransformer.isBroad = true; | ||
var findSeriesByName = function findSeriesByName(name, series) { | ||
@@ -478,3 +515,2 @@ return series.find(function (seriesItem) { | ||
}; | ||
var dBar = function dBar(_ref7) { | ||
@@ -486,10 +522,11 @@ var x = _ref7.x, | ||
return { | ||
x: x, y: Math.min(y, y1), width: width || 2, height: Math.abs(y1 - y) | ||
x: x, | ||
y: Math.min(y, y1), | ||
width: width || 2, | ||
height: Math.abs(y1 - y) | ||
}; | ||
}; | ||
var pointAttributes = function pointAttributes(_ref8) { | ||
var _ref8$size = _ref8.size, | ||
size = _ref8$size === undefined ? DEFAULT_POINT_SIZE : _ref8$size; | ||
size = _ref8$size === void 0 ? DEFAULT_POINT_SIZE : _ref8$size; | ||
var dPoint = d3Shape.symbol().size([Math.pow(size, 2)]).type(d3Shape.symbolCircle)(); | ||
@@ -506,2 +543,44 @@ return function (item) { | ||
getBarPointTransformer.getTargetElement = function (_ref9) { | ||
var x = _ref9.x, | ||
y = _ref9.y, | ||
y1 = _ref9.y1, | ||
width = _ref9.width; | ||
var height = Math.abs(y1 - y); | ||
return { | ||
x: x, | ||
y: y, | ||
d: "M0,0 ".concat(width, ",0 ").concat(width, ",").concat(height, " 0,").concat(height) | ||
}; | ||
}; | ||
getPiePointTransformer.getTargetElement = function (_ref10) { | ||
var x = _ref10.x, | ||
y = _ref10.y, | ||
innerRadius = _ref10.innerRadius, | ||
outerRadius = _ref10.outerRadius, | ||
startAngle = _ref10.startAngle, | ||
endAngle = _ref10.endAngle; | ||
var center = d3Shape.arc().innerRadius(innerRadius).outerRadius(outerRadius).startAngle(startAngle).endAngle(endAngle).centroid(); | ||
return { | ||
x: center[0] + x, | ||
y: center[1] + y, | ||
d: d3Shape.symbol().size([Math.pow(1, 2)]).type(d3Shape.symbolCircle)() | ||
}; | ||
}; | ||
getAreaPointTransformer.getTargetElement = function (_ref11) { | ||
var x = _ref11.x, | ||
y = _ref11.y; | ||
var size = DEFAULT_POINT_SIZE; // TODO get user size | ||
return { | ||
x: x, | ||
y: y, | ||
d: d3Shape.symbol().size([Math.pow(size, 2)]).type(d3Shape.symbolCircle)() | ||
}; | ||
}; | ||
getLinePointTransformer.getTargetElement = getAreaPointTransformer.getTargetElement; | ||
var createNewUniqueName = function createNewUniqueName(name) { | ||
@@ -516,9 +595,9 @@ return name.replace(/\d*$/, function (str) { | ||
return obj.uniqueName === item.uniqueName; | ||
}) ? addItem(list, _extends({}, item, { | ||
}) ? addItem(list, _objectSpread({}, item, { | ||
uniqueName: createNewUniqueName(item.uniqueName) | ||
})) : list.concat(item); | ||
}; | ||
}; // TODO: Memoization is much needed here. | ||
// Though "series" list never persists, single "series" item most often does. | ||
// TODO: Memoization is much needed here. | ||
// Though "series" list never persists, single "series" item most often does. | ||
var createPoints = function createPoints(argumentField, valueField, data) { | ||
@@ -529,4 +608,9 @@ var points = []; | ||
var value = dataItem[valueField]; | ||
if (argument !== undefined && value !== undefined) { | ||
points.push({ argument: argument, value: value, index: index }); | ||
points.push({ | ||
argument: argument, | ||
value: value, | ||
index: index | ||
}); | ||
} | ||
@@ -538,27 +622,24 @@ }); | ||
var addSeries = function addSeries(series, data, palette, props) { | ||
var points = createPoints(props.argumentField, props.valueField, data); | ||
// It is used to generate unique series dependent attribute names for patterns. | ||
var points = createPoints(props.argumentField, props.valueField, data); // It is used to generate unique series dependent attribute names for patterns. | ||
// *symbolName* cannot be used as it cannot be part of DOM attribute name. | ||
// TODO: Consider making *name* unique and then use it instead of *index*. | ||
var index = series.length; | ||
return addItem(series, _extends({}, props, { | ||
return addItem(series, _objectSpread({}, props, { | ||
index: index, | ||
points: points, | ||
uniqueName: props.name, | ||
palette: palette, // TODO: For Pie only. Find a better place for it. | ||
palette: palette, | ||
// TODO: For Pie only. Find a better place for it. | ||
color: props.color || palette[index % palette.length] | ||
})); | ||
}; | ||
}; // TODO: Memoization is much needed here by the same reason as in "createPoints". | ||
// Make "scales" persistent first. | ||
// TODO: Memoization is much needed here by the same reason as in "createPoints". | ||
// Make "scales" persistent first. | ||
var scalePoints = function scalePoints(series, scales) { | ||
var getPointTransformer = series.getPointTransformer, | ||
rest = objectWithoutProperties(series, ['getPointTransformer']); | ||
var transform = getPointTransformer(_extends({}, series, { | ||
var transform = series.getPointTransformer(_objectSpread({}, series, { | ||
argumentScale: scales[ARGUMENT_DOMAIN], | ||
valueScale: scales[getValueDomainName(series.axisName)] | ||
valueScale: scales[getValueDomainName(series.scaleName)] | ||
})); | ||
return _extends({}, rest, { | ||
return _objectSpread({}, series, { | ||
points: series.points.map(transform) | ||
@@ -574,3 +655,2 @@ }); | ||
// "Stack" plugin relies on "data" and "series" getters and | ||
// knowledge about "getPointTransformer" and "path" functions behavior. | ||
@@ -582,3 +662,2 @@ | ||
var series = _ref.series; | ||
series.forEach(function (name) { | ||
@@ -595,3 +674,2 @@ result[name] = i; | ||
var valueScale = series.valueScale; | ||
return function (point) { | ||
@@ -602,9 +680,10 @@ var ret = transform(point); | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
}; // Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
return wrapper; | ||
}; | ||
}; // TODO: Temporary - see corresponding note in *computeDomains*. | ||
// TODO: Temporary - see corresponding note in *computeDomains*. | ||
var getValueDomain = function getValueDomain(points) { | ||
@@ -624,4 +703,4 @@ var items = []; | ||
valueField = _ref2.valueField; | ||
var stackId = seriesToStackMap[name]; | ||
var stackId = seriesToStackMap[name]; | ||
if (stackId === undefined) { | ||
@@ -634,6 +713,7 @@ return; | ||
} | ||
seriesPositions[name] = stacksKeys[stackId].length; | ||
stacksKeys[stackId].push(valueField); | ||
}); | ||
// Stack cannot consist of single series. | ||
}); // Stack cannot consist of single series. | ||
Object.keys(stacksKeys).forEach(function (stackId) { | ||
@@ -657,15 +737,21 @@ if (stacksKeys[stackId].length === 1) { | ||
var points = series.points.map(function (point) { | ||
var _dataItems$point$inde = slicedToArray(dataItems[point.index], 2), | ||
var _dataItems$point$inde = _slicedToArray(dataItems[point.index], 2), | ||
value0 = _dataItems$point$inde[0], | ||
value = _dataItems$point$inde[1]; | ||
return _extends({}, point, { value: value, value0: value0 }); | ||
return _objectSpread({}, point, { | ||
value: value, | ||
value0: value0 | ||
}); | ||
}); | ||
var stackedSeries = _extends({}, series, { | ||
var stackedSeries = _objectSpread({}, series, { | ||
points: points | ||
}); | ||
if (series.isStartedFromZero) { | ||
if (series.getPointTransformer.isStartedFromZero) { | ||
stackedSeries.getPointTransformer = getStackedPointTransformer(series.getPointTransformer); | ||
stackedSeries.getValueDomain = getValueDomain; | ||
} | ||
return stackedSeries; | ||
@@ -676,3 +762,3 @@ }; | ||
var _collectStacks = collectStacks(seriesList, seriesToStackMap), | ||
_collectStacks2 = slicedToArray(_collectStacks, 2), | ||
_collectStacks2 = _slicedToArray(_collectStacks, 2), | ||
stacksKeys = _collectStacks2[0], | ||
@@ -684,2 +770,3 @@ seriesPositions = _collectStacks2[1]; | ||
} | ||
var stackedData = getStackedData(stacksKeys, dataItems, offset, order); | ||
@@ -689,5 +776,7 @@ return seriesList.map(function (seriesItem) { | ||
var stackData = stackedData[stackId]; | ||
if (!stackData) { | ||
return seriesItem; | ||
} | ||
var position = seriesPositions[seriesItem.name]; | ||
@@ -700,3 +789,3 @@ return buildStackedSeries(seriesItem, stackData[position]); | ||
var stackId = seriesToStackMap[series.name]; | ||
return stackId >= 0 ? String(stackId) : 'group-' + i; | ||
return stackId >= 0 ? String(stackId) : "group-".concat(i); | ||
}; | ||
@@ -708,3 +797,2 @@ | ||
var barWidth = series.barWidth; | ||
var widthCoeff = 1 / groupCount; | ||
@@ -718,4 +806,5 @@ var offsetCoeff = -(1 - barWidth) / 2 + groupOffset + widthCoeff * (1 - barWidth) / 2; | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
}; // Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
@@ -731,7 +820,8 @@ return wrapper; | ||
} | ||
}); | ||
// There cannot be single group. | ||
}); // There cannot be single group. | ||
if (groups.size < 2) { | ||
return seriesList; | ||
} | ||
var scale = d3Scale.scaleBand().domain(Array.from(groups)).range([0, 1]); | ||
@@ -742,4 +832,5 @@ return seriesList.map(function (seriesItem, i) { | ||
} | ||
var getPointTransformer = getGroupedPointTransformer(seriesItem.getPointTransformer, groups.size, scale(getGroupName(seriesItem, i, seriesToStackMap))); | ||
return _extends({}, seriesItem, { | ||
return _objectSpread({}, seriesItem, { | ||
getPointTransformer: getPointTransformer | ||
@@ -754,3 +845,2 @@ }); | ||
order = _ref3.order; | ||
var map = buildSeriesToStackMap(stacks); | ||
@@ -768,8 +858,12 @@ var stackedSeriesList = applyStacking(seriesList, dataItems, map, offset, order); | ||
} | ||
var head = document.getElementsByTagName('head')[0]; // eslint-disable-line no-undef | ||
var style = Array.from(head.getElementsByTagName('style')).find(function (node) { | ||
return node.dataset[ANIMATIONS]; | ||
}); | ||
if (!style) { | ||
style = document.createElement('style'); // eslint-disable-line no-undef | ||
style.type = 'text/css'; | ||
@@ -779,5 +873,7 @@ style.dataset[ANIMATIONS] = true; | ||
} | ||
var content = style.textContent; | ||
if (!content.includes(name)) { | ||
style.textContent += '\n@keyframes ' + name + ' ' + def + '\n'; | ||
style.textContent += "\n@keyframes ".concat(name, " ").concat(def, "\n"); | ||
} | ||
@@ -810,3 +906,3 @@ }; | ||
var index = _ref.index; | ||
return 0.7 + index * 0.1 + 's'; | ||
return "".concat(0.7 + index * 0.1, "s"); | ||
}; | ||
@@ -816,67 +912,180 @@ | ||
var animationStyle = { | ||
transformOrigin: '0px ' + scales.yScale.copy().clamp(true)(0) + 'px' | ||
transformOrigin: "0px ".concat(scales.yScale.copy().clamp(true)(0), "px") | ||
}; | ||
var options = getDefaultAreaAnimationOptions(); | ||
return _extends({ | ||
animation: getAreaAnimationName() + ' ' + options | ||
return _objectSpread({ | ||
animation: "".concat(getAreaAnimationName(), " ").concat(options) | ||
}, animationStyle); | ||
}; | ||
var getPieAnimationStyle = function getPieAnimationStyle(scales, point) { | ||
var options = getDefaultPieAnimationOptions(point); | ||
return { | ||
animation: getPieAnimationName() + ' ' + options | ||
animation: "".concat(getPieAnimationName(), " ").concat(options) | ||
}; | ||
}; | ||
var getScatterAnimationStyle = function getScatterAnimationStyle() { | ||
var options = getDefaultAreaAnimationOptions(); | ||
return { | ||
animation: getScatterAnimationName() + ' ' + options | ||
animation: "".concat(getScatterAnimationName(), " ").concat(options) | ||
}; | ||
}; | ||
var buildAnimatedStyleGetter = function buildAnimatedStyleGetter(style, getAnimationStyle, scales, point) { | ||
var animationStyle = getAnimationStyle(scales, point); | ||
return _extends({}, animationStyle, style); | ||
return _objectSpread({}, animationStyle, style); | ||
}; | ||
var isPointInRect = function isPointInRect(x, y, x1, x2, y1, y2) { | ||
return x1 <= x && x <= x2 && y1 <= y && y <= y2; | ||
// Comparing by reference is not an option as Tracker always sends new objects. | ||
// On the other side Tracker cannot persist references as it actually operates with simple scalars | ||
// and constructs objects to provide info in a slightly more suitable way. | ||
var compareTargets = function compareTargets(target1, target2) { | ||
return target1.series === target2.series && target1.point === target2.point; | ||
}; // Current value is chosen roughly and expected to be adjusted. | ||
var DISTANCE_PRIORITY_RATIO = 4; // If *currentTarget* is among *targets* then it has priority but only while its distance | ||
// is not significantly greater (DISTANCE_PRIORITY_RATIO) than that of the best candidate. | ||
var selectTarget = function selectTarget(targets, currentTarget) { | ||
if (!currentTarget) { | ||
return targets.length ? targets[0] : undefined; | ||
} | ||
if (!targets.length) { | ||
return null; | ||
} | ||
var candidate = targets[0]; // Skip complex checks if *currentTarget* has minimal distance. | ||
if (compareTargets(candidate, currentTarget)) { | ||
return undefined; | ||
} // Skip complex check if there is single candidate. | ||
if (targets.length === 1) { | ||
return candidate; | ||
} | ||
var current = targets.find(function (target) { | ||
return compareTargets(target, currentTarget); | ||
}); | ||
if (current) { | ||
// Here *current.distance* is exactly greater than *candidate.distance*. | ||
// The question is - how much greater? | ||
var ratio = current.distance / candidate.distance; | ||
return ratio > DISTANCE_PRIORITY_RATIO ? candidate : undefined; | ||
} | ||
return candidate; | ||
}; | ||
var processPointerMove = function processPointerMove(targets, currentTarget, notify) { | ||
var nextTarget = selectTarget(targets, currentTarget); | ||
if (nextTarget === undefined) { | ||
return undefined; | ||
} | ||
if (notify) { | ||
notify(nextTarget); | ||
} | ||
return nextTarget; | ||
}; // It handles the case when point is hovered and series does not contain visual points. | ||
// Series then knows that it is also hovered and can represent the changed state. | ||
var getHoverTargets = function getHoverTargets(hover) { | ||
if (!hover) { | ||
return []; | ||
} | ||
return hover.point >= 0 ? [{ | ||
series: hover.series | ||
}, hover] : [hover]; | ||
}; | ||
var getParameters = function getParameters(series, target) { | ||
var currentSeries = series.find(function (_ref) { | ||
var name = _ref.name; | ||
return target.series === name; | ||
}); | ||
var item = currentSeries.points.find(function (point) { | ||
return point.index === target.point; | ||
}); | ||
return { | ||
element: currentSeries.getPointTransformer.getTargetElement(item), | ||
text: "".concat(item.value) | ||
}; | ||
}; | ||
var processHandleTooltip = function processHandleTooltip(targets, currentTarget, onTargetItemChange) { | ||
var filterTargets = targets.filter(function (target) { | ||
return target.point !== undefined; | ||
}); | ||
return processPointerMove(filterTargets, currentTarget, onTargetItemChange); | ||
}; | ||
var getUniformDistance = function getUniformDistance(dx, dy, rx, ry) { | ||
return Math.max(Math.abs(dx) / rx, Math.abs(dy) / ry); | ||
}; // Based on https://en.wikipedia.org/wiki/Norm_(mathematics)#Euclidean_norm | ||
var getEuclideanDistance = function getEuclideanDistance(dx, dy, rx, ry) { | ||
return Math.sqrt(dx * dx / (rx * rx) + dy * dy / (ry * ry)); | ||
}; | ||
var createPointsEnumeratingHitTesterCreator = function createPointsEnumeratingHitTesterCreator(hitTestPoint) { | ||
return function (points) { | ||
return function (target) { | ||
var list = []; | ||
points.forEach(function (point) { | ||
// *distance* is a normalized distance to point. | ||
// It belongs to [0, Infinity): | ||
// = 0 - at point center | ||
// = 1 - at point border | ||
// > 1 - outside point | ||
var distance = hitTestPoint(target, point); | ||
if (distance <= 1) { | ||
list.push({ | ||
index: point.index, | ||
distance: distance | ||
}); | ||
} | ||
}); | ||
return list.length ? { | ||
points: list | ||
} : null; | ||
}; | ||
}; | ||
}; | ||
var LINE_TOLERANCE = 10; | ||
var createContinuousSeriesPointsHitTester = createPointsEnumeratingHitTesterCreator(function (_ref, _ref2) { | ||
var _ref3 = _slicedToArray(_ref, 2), | ||
px = _ref3[0], | ||
py = _ref3[1]; | ||
// This function is called from event handlers (when DOM is available) - | ||
var x = _ref2.x, | ||
y = _ref2.y; | ||
return getEuclideanDistance(px - x, py - y, LINE_TOLERANCE, LINE_TOLERANCE); | ||
}); // This function is called from event handlers (when DOM is available) - | ||
// *window.document* can be accessed safely. | ||
var createContext = function createContext() { | ||
return document.createElement('canvas').getContext('2d'); | ||
}; // eslint-disable-line no-undef | ||
// For a start using browser canvas will suffice. | ||
// However a better and more clean solution should be found. | ||
// Can't d3 perform hit testing? | ||
var createCanvasAbusingHitTesterCreator = function createCanvasAbusingHitTesterCreator(makePath) { | ||
return function (coordinates) { | ||
return function (points) { | ||
var ctx = createContext(); | ||
var path = makePath(); | ||
path.context(ctx); | ||
path(coordinates); | ||
return function (_ref) { | ||
var _ref2 = slicedToArray(_ref, 2), | ||
px = _ref2[0], | ||
py = _ref2[1]; | ||
var hit = ctx.isPointInPath(px, py) ? {} : null; | ||
if (hit) { | ||
var point = coordinates.find(function (_ref3) { | ||
var x = _ref3.x, | ||
y = _ref3.y; | ||
return isPointInRect(px, py, x - LINE_TOLERANCE, x + LINE_TOLERANCE, y - LINE_TOLERANCE, y + LINE_TOLERANCE); | ||
}); | ||
if (point) { | ||
hit.point = point.index; | ||
} | ||
} | ||
return hit; | ||
path(points); | ||
var hitTestPoints = createContinuousSeriesPointsHitTester(points); | ||
return function (point) { | ||
return ctx.isPointInPath(point[0], point[1]) ? hitTestPoints(point) || {} : null; | ||
}; | ||
@@ -893,3 +1102,2 @@ }; | ||
}); | ||
var createLineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
@@ -907,3 +1115,2 @@ var path = d3Shape.area(); | ||
}); | ||
var createSplineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
@@ -921,36 +1128,25 @@ var path = d3Shape.area(); | ||
return path; | ||
}); | ||
}); // Some kind of binary search can be used here as bars can be ordered along argument axis. | ||
var createBarHitTester = function createBarHitTester(coordinates) { | ||
return function (_ref4) { | ||
var _ref5 = slicedToArray(_ref4, 2), | ||
px = _ref5[0], | ||
py = _ref5[1]; | ||
var createBarHitTester = createPointsEnumeratingHitTesterCreator(function (_ref4, point) { | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
px = _ref5[0], | ||
py = _ref5[1]; | ||
var point = coordinates.find(function (_ref6) { | ||
var x = _ref6.x, | ||
width = _ref6.width, | ||
y = _ref6.y, | ||
y1 = _ref6.y1; | ||
return isPointInRect(px, py, x, x + width, Math.min(y, y1), Math.max(y, y1)); | ||
}); | ||
return point ? { point: point.index } : null; | ||
}; | ||
}; | ||
var xCenter = point.x + point.width / 2; | ||
var yCenter = (point.y + point.y1) / 2; | ||
var halfWidth = point.width / 2; | ||
var halfHeight = Math.abs(point.y - point.y1) / 2; | ||
return getUniformDistance(px - xCenter, py - yCenter, halfWidth, halfHeight); | ||
}); // TODO: Use actual point size here! | ||
// TODO: Use actual point size here! | ||
var createScatterHitTester = function createScatterHitTester(coordinates) { | ||
return function (_ref7) { | ||
var _ref8 = slicedToArray(_ref7, 2), | ||
px = _ref8[0], | ||
py = _ref8[1]; | ||
var createScatterHitTester = createPointsEnumeratingHitTesterCreator(function (_ref6, _ref7) { | ||
var _ref8 = _slicedToArray(_ref6, 2), | ||
px = _ref8[0], | ||
py = _ref8[1]; | ||
var point = coordinates.find(function (_ref9) { | ||
var x = _ref9.x, | ||
y = _ref9.y; | ||
return isPointInRect(px, py, x - 10, x + 10, y - 10, y + 10); | ||
}); | ||
return point ? { point: point.index } : null; | ||
}; | ||
}; | ||
var x = _ref7.x, | ||
y = _ref7.y; | ||
return getEuclideanDistance(px - x, py - y, 10, 10); | ||
}); | ||
@@ -960,38 +1156,36 @@ var mapAngleTod3 = function mapAngleTod3(angle) { | ||
return ret >= 0 ? ret : ret + Math.PI * 2; | ||
}; | ||
}; // Some kind of binary search can be used here as pies can be ordered along angle axis. | ||
var createPieHitTester = function createPieHitTester(coordinates) { | ||
return function (_ref10) { | ||
var _ref11 = slicedToArray(_ref10, 2), | ||
px = _ref11[0], | ||
py = _ref11[1]; | ||
var point = coordinates.find(function (_ref12) { | ||
var x = _ref12.x, | ||
y = _ref12.y, | ||
innerRadius = _ref12.innerRadius, | ||
outerRadius = _ref12.outerRadius, | ||
startAngle = _ref12.startAngle, | ||
endAngle = _ref12.endAngle; | ||
var createPieHitTester = createPointsEnumeratingHitTesterCreator(function (_ref9, _ref10) { | ||
var _ref11 = _slicedToArray(_ref9, 2), | ||
px = _ref11[0], | ||
py = _ref11[1]; | ||
var dx = px - x; | ||
var dy = py - y; | ||
var r = Math.sqrt(dx * dx + dy * dy); | ||
if (r < innerRadius || r > outerRadius) { | ||
return null; | ||
} | ||
var angle = mapAngleTod3(Math.atan2(dy, dx)); | ||
return startAngle <= angle && angle <= endAngle; | ||
}); | ||
return point ? { point: point.index } : null; | ||
}; | ||
}; | ||
var x = _ref10.x, | ||
y = _ref10.y, | ||
innerRadius = _ref10.innerRadius, | ||
outerRadius = _ref10.outerRadius, | ||
startAngle = _ref10.startAngle, | ||
endAngle = _ref10.endAngle; | ||
var rCenter = (innerRadius + outerRadius) / 2; | ||
var angleCenter = (startAngle + endAngle) / 2; | ||
var halfRadius = (outerRadius - innerRadius) / 2; | ||
var halfAngle = Math.abs(startAngle - endAngle) / 2; | ||
var dx = px - x; | ||
var dy = py - y; | ||
var r = Math.sqrt(dx * dx + dy * dy); | ||
var angle = mapAngleTod3(Math.atan2(dy, dx)); | ||
return getUniformDistance(r - rCenter, angle - angleCenter, halfRadius, halfAngle); | ||
}); | ||
var buildFilter = function buildFilter(targets) { | ||
var result = {}; | ||
targets.forEach(function (_ref13) { | ||
var series = _ref13.series, | ||
point = _ref13.point; | ||
targets.forEach(function (_ref12) { | ||
var series = _ref12.series, | ||
point = _ref12.point; | ||
result[series] = result[series] || { | ||
points: {} | ||
}; | ||
result[series] = result[series] || { points: {} }; | ||
if (point >= 0) { | ||
@@ -1010,2 +1204,3 @@ result[series].points[point] = true; | ||
} | ||
var filter = buildFilter(targets); | ||
@@ -1015,18 +1210,25 @@ var matches = 0; | ||
var obj = filter[seriesItem.name]; | ||
if (!obj) { | ||
return seriesItem; | ||
} | ||
matches += 1; | ||
var props = {}; | ||
if (obj.self) { | ||
props.state = state; | ||
} | ||
if (Object.keys(obj.points).length) { | ||
props.points = seriesItem.points.map(function (point) { | ||
return obj.points[point.index] ? _extends({}, point, { state: state }) : point; | ||
return obj.points[point.index] ? _objectSpread({}, point, { | ||
state: state | ||
}) : point; | ||
}); | ||
} | ||
return _extends({}, seriesItem, props); | ||
}); | ||
// This is to prevent false rerenders. | ||
return _objectSpread({}, seriesItem, props); | ||
}); // This is to prevent false rerenders. | ||
return matches > 0 ? result : seriesList; | ||
@@ -1039,3 +1241,6 @@ }; | ||
color = _ref.color; | ||
return { text: text, color: color }; | ||
return { | ||
text: text, | ||
color: color | ||
}; | ||
}); | ||
@@ -1048,9 +1253,12 @@ }; | ||
color = _ref2.color; | ||
return { text: text, color: color }; | ||
return { | ||
text: text, | ||
color: color | ||
}; | ||
}); | ||
}; | ||
// The function supports special case when there is single Pie series. | ||
}; // The function supports special case when there is single Pie series. | ||
// There is no commom way to tell if series is of Pie type - | ||
// checking `seriesComponent` function name will suffice for now. | ||
var isSinglePieSeriesCase = function isSinglePieSeriesCase(series) { | ||
@@ -1078,2 +1286,6 @@ return series.length === 1 && series[0].seriesComponent.name === 'SliceCollection'; | ||
var compare = function compare(t1, t2) { | ||
return t1.distance - t2.distance; | ||
}; | ||
var buildEventHandler = function buildEventHandler(seriesList, handlers) { | ||
@@ -1094,9 +1306,29 @@ var hitTesters = null; | ||
var targets = []; | ||
seriesList.forEach(function (seriesItem) { | ||
var status = hitTesters[seriesItem.symbolName](location); | ||
seriesList.forEach(function (_ref) { | ||
var series = _ref.name, | ||
symbolName = _ref.symbolName; | ||
var status = hitTesters[symbolName](location); | ||
if (status) { | ||
targets.push(_extends({ series: seriesItem.name }, status)); | ||
if (status.points) { | ||
targets.push.apply(targets, _toConsumableArray(status.points.map(function (point) { | ||
return { | ||
series: series, | ||
point: point.index, | ||
distance: point.distance | ||
}; | ||
}))); | ||
} else { | ||
targets.push({ | ||
series: series, | ||
distance: 1 | ||
}); | ||
} | ||
} | ||
}); | ||
var arg = { location: location, targets: targets }; | ||
targets.sort(compare); | ||
var arg = { | ||
location: location, | ||
targets: targets | ||
}; | ||
handlers.forEach(function (handler) { | ||
@@ -1111,3 +1343,6 @@ return handler(arg); | ||
var location = getEventCoords(e); | ||
var arg = { location: location, targets: [] }; | ||
var arg = { | ||
location: location, | ||
targets: [] | ||
}; | ||
handlers.forEach(function (handler) { | ||
@@ -1119,10 +1354,11 @@ return handler(arg); | ||
var buildEventHandlers = function buildEventHandlers(seriesList, _ref) { | ||
var clickHandlers = _ref.clickHandlers, | ||
pointerMoveHandlers = _ref.pointerMoveHandlers; | ||
var buildEventHandlers = function buildEventHandlers(seriesList, _ref2) { | ||
var clickHandlers = _ref2.clickHandlers, | ||
pointerMoveHandlers = _ref2.pointerMoveHandlers; | ||
var handlers = {}; | ||
var handlers = {}; | ||
if (clickHandlers.length) { | ||
handlers.click = buildEventHandler(seriesList, clickHandlers); | ||
} | ||
if (pointerMoveHandlers.length) { | ||
@@ -1132,36 +1368,6 @@ handlers.pointermove = buildEventHandler(seriesList, pointerMoveHandlers); | ||
} | ||
return handlers; | ||
}; | ||
var selectTarget = function selectTarget(targets) { | ||
return targets.length > 0 ? targets[targets.length - 1] : null; | ||
}; | ||
// Comparing by reference is not an option as Tracker always sends new objects. | ||
// On the other side Tracker cannot persist references as it actually operates with simple scalars | ||
// and constructs objects to provide info in a slightly more suitable way. | ||
var compareTargets = function compareTargets(target1, target2) { | ||
return target1 && target2 && target1.series === target2.series && target1.point === target2.point || !target1 && !target2; | ||
}; | ||
var processPointerMove = function processPointerMove(targets, currentTarget, notify) { | ||
var nextTarget = selectTarget(targets); | ||
if (compareTargets(currentTarget, nextTarget)) { | ||
return undefined; | ||
} | ||
if (notify) { | ||
notify(nextTarget); | ||
} | ||
return nextTarget; | ||
}; | ||
// It handles the case when point is hovered and series does not contain visual points. | ||
// Series then knows that it is also hovered and can represent the changed state. | ||
var getHoverTargets = function getHoverTargets(hover) { | ||
if (!hover) { | ||
return []; | ||
} | ||
return hover.point >= 0 ? [{ series: hover.series }, hover] : [hover]; | ||
}; | ||
exports.computeExtension = computeExtension; | ||
@@ -1172,2 +1378,3 @@ exports.computeDomains = computeDomains; | ||
exports.axisCoordinates = axisCoordinates; | ||
exports.getGridCoordinates = getGridCoordinates; | ||
exports.axesData = axesData; | ||
@@ -1178,2 +1385,3 @@ exports.dArea = dArea; | ||
exports.getPiePointTransformer = getPiePointTransformer; | ||
exports.getLinePointTransformer = getLinePointTransformer; | ||
exports.getAreaPointTransformer = getAreaPointTransformer; | ||
@@ -1191,2 +1399,4 @@ exports.getBarPointTransformer = getBarPointTransformer; | ||
exports.buildAnimatedStyleGetter = buildAnimatedStyleGetter; | ||
exports.getParameters = getParameters; | ||
exports.processHandleTooltip = processHandleTooltip; | ||
exports.createAreaHitTester = createAreaHitTester; | ||
@@ -1202,2 +1412,3 @@ exports.createLineHitTester = createLineHitTester; | ||
exports.getValueDomainName = getValueDomainName; | ||
exports.fixOffset = fixOffset; | ||
exports.getLegendItems = getLegendItems; | ||
@@ -1204,0 +1415,0 @@ exports.buildEventHandlers = buildEventHandlers; |
{ | ||
"name": "@devexpress/dx-chart-core", | ||
"version": "1.9.0", | ||
"version": "1.9.1", | ||
"description": "Core library for the DevExtreme Reactive Chart component", | ||
@@ -42,17 +42,16 @@ "author": { | ||
"devDependencies": { | ||
"babel-core": "^6.26.3", | ||
"@babel/core": "^7.1.6", | ||
"@babel/plugin-transform-runtime": "^7.1.0", | ||
"@babel/preset-env": "^7.1.6", | ||
"babel-core": "^7.0.0-bridge.0", | ||
"babel-jest": "^23.6.0", | ||
"babel-plugin-external-helpers": "^6.22.0", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"babel-plugin-transform-runtime": "^6.23.0", | ||
"babel-preset-env": "^1.7.0", | ||
"core-js": "^2.5.7", | ||
"eslint": "^5.8.0", | ||
"eslint": "^5.9.0", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-plugin-filenames": "^1.3.2", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-jest": "^21.26.2", | ||
"eslint-plugin-jest": "^22.0.0", | ||
"jest": "^23.6.0", | ||
"rollup": "^0.66.6", | ||
"rollup-plugin-babel": "^3.0.4", | ||
"rollup": "^0.67.3", | ||
"rollup-plugin-babel": "^4.0.3", | ||
"rollup-plugin-license": "^0.7.0" | ||
@@ -65,3 +64,3 @@ }, | ||
}, | ||
"gitHead": "227293d65d3fc8972ff36981be7ec6789876dbe7" | ||
"gitHead": "29cb22ed32aac31a3fa3d985b9160300af79b12f" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
242094
15
2314