@devexpress/dx-chart-core
Advanced tools
Comparing version 1.8.0 to 1.9.0
/** | ||
* Bundle of @devexpress/dx-chart-core | ||
* Generated: 2018-10-04 | ||
* Version: 1.8.0 | ||
* Generated: 2018-11-07 | ||
* Version: 1.9.0 | ||
* License: https://js.devexpress.com/Licensing | ||
@@ -28,2 +28,21 @@ */ | ||
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) { | ||
@@ -58,2 +77,52 @@ if (key in obj) { | ||
var objectWithoutProperties = function (obj, keys) { | ||
var target = {}; | ||
for (var i in obj) { | ||
if (keys.indexOf(i) >= 0) continue; | ||
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; | ||
target[i] = obj[i]; | ||
} | ||
return target; | ||
}; | ||
var slicedToArray = function () { | ||
function sliceIterator(arr, i) { | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"]) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
return function (arr, i) { | ||
if (Array.isArray(arr)) { | ||
return arr; | ||
} else if (Symbol.iterator in Object(arr)) { | ||
return sliceIterator(arr, i); | ||
} else { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
} | ||
}; | ||
}(); | ||
var toConsumableArray = function (arr) { | ||
@@ -73,6 +142,2 @@ if (Array.isArray(arr)) { | ||
var getValueDomainName = function getValueDomainName(name) { | ||
return name || VALUE_DOMAIN; | ||
}; | ||
// TODO: Property name should not contain "axis" part as it actually means domain. | ||
@@ -83,35 +148,22 @@ var getSeriesValueDomainName = function getSeriesValueDomainName(series) { | ||
var calculateDomainField = function calculateDomainField(getFieldItemFirst, getFieldItemSecond, data, domain, type) { | ||
var getCategories = function getCategories(prev, cur) { | ||
var categories = getFieldItemFirst(cur); | ||
if (isDefined(categories)) { | ||
return [].concat(toConsumableArray(prev), [categories]); | ||
} | ||
return prev; | ||
}; | ||
if (type === BAND) { | ||
return [].concat(toConsumableArray(domain), toConsumableArray(data.reduce(getCategories, []))); | ||
} | ||
return extent([].concat(toConsumableArray(domain), toConsumableArray(extent(data, getFieldItemFirst)), toConsumableArray(extent(data, getFieldItemSecond)))); | ||
var calculateDomainField = function calculateDomainField(items, domain, type) { | ||
return type === BAND ? [].concat(toConsumableArray(domain), toConsumableArray(items)) : extent([].concat(toConsumableArray(domain), toConsumableArray(extent(items)))); | ||
}; | ||
var getCorrectAxisType = function getCorrectAxisType(type, data, field) { | ||
if (!type && typeof data.find(function (item) { | ||
return isDefined(item[field]); | ||
})[field] === 'string') { | ||
return BAND; | ||
} | ||
return type || LINEAR; | ||
var getArgument = function getArgument(point) { | ||
return point.argument; | ||
}; | ||
var getFieldStack = function getFieldStack(index, object) { | ||
return object && isDefined(object[index]) ? object[index] : undefined; | ||
var getValue = function getValue(point) { | ||
return point.value; | ||
}; | ||
var calculateDomains = function calculateDomains(domains, seriesList, data) { | ||
var getCorrectAxisType = function getCorrectAxisType(type, points, getItem) { | ||
return type || points.length && typeof getItem(points[0]) === 'string' && BAND || LINEAR; | ||
}; | ||
var calculateDomains = function calculateDomains(domains, seriesList) { | ||
seriesList.forEach(function (seriesItem) { | ||
var valueDomainName = getSeriesValueDomainName(seriesItem); | ||
var argumentField = seriesItem.argumentField, | ||
valueField = seriesItem.valueField, | ||
name = seriesItem.name; | ||
var points = seriesItem.points; | ||
@@ -121,15 +173,13 @@ var argumentDomain = domains[ARGUMENT_DOMAIN]; | ||
var valueType = getCorrectAxisType(valueDomain.type, data, valueField); | ||
var argumentType = getCorrectAxisType(argumentDomain.type, data, argumentField); | ||
var valueType = getCorrectAxisType(valueDomain.type, points, getValue); | ||
var argumentType = getCorrectAxisType(argumentDomain.type, points, getArgument); | ||
valueDomain.domain = calculateDomainField(function (object) { | ||
return getFieldStack(1, object[valueField + '-' + name + '-stack']); | ||
}, valueDomain.isStartedFromZero ? function (object) { | ||
return getFieldStack(0, object[valueField + '-' + name + '-stack']); | ||
} : undefined, data, valueDomain.domain, valueType); | ||
// 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(function (object) { | ||
return object[argumentField]; | ||
}, null, data, argumentDomain.domain, argumentType); | ||
argumentDomain.domain = calculateDomainField(points.map(getArgument), argumentDomain.domain, argumentType); | ||
argumentDomain.type = argumentType; | ||
@@ -140,3 +190,5 @@ }); | ||
var computeExtension = function computeExtension(extension) { | ||
var defaultExtension = [{ type: LINEAR, constructor: scaleLinear }, { type: BAND, constructor: scaleBand }]; | ||
var defaultExtension = [{ type: LINEAR, constructor: scaleLinear }, { type: BAND, constructor: function constructor() { | ||
return scaleBand().paddingInner(0.3).paddingOuter(0.15); | ||
} }]; | ||
return extension.concat(defaultExtension); | ||
@@ -151,3 +203,5 @@ }; | ||
domains[name] = domain; | ||
domain.isStartedFromZero = domain.isStartedFromZero || seriesItem.isStartedFromZero; | ||
if (seriesItem.isStartedFromZero && domain.domain.length === 0) { | ||
domain.domain = [0]; | ||
} | ||
}); | ||
@@ -187,3 +241,3 @@ return domains; | ||
var computeDomains = function computeDomains(axes, series, data) { | ||
var computeDomains = function computeDomains(axes, series) { | ||
var result = collectDomains(series); | ||
@@ -193,3 +247,3 @@ // Axes options are taken in two steps because *type* is required for domains calculation | ||
takeTypeFromAxesOptions(result, axes); | ||
calculateDomains(result, series, data); | ||
calculateDomains(result, series); | ||
takeRestAxesOptions(result, axes); | ||
@@ -199,2 +253,22 @@ return result; | ||
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), | ||
name = _ref5[0], | ||
domain = _ref5[1]; | ||
var _scaleExtension$find = scaleExtension.find(function (item) { | ||
return item.type === domain.type; | ||
}), | ||
constructor = _scaleExtension$find.constructor; | ||
scales[name] = createScale(domain, width, height, constructor); | ||
}); | ||
return scales; | ||
}; | ||
var isEqual = function isEqual(_ref, _ref2) { | ||
@@ -216,18 +290,2 @@ var firstWidth = _ref.width, | ||
var createScale = function createScale(_ref, width, height, constructor) { | ||
var domain = _ref.domain, | ||
orientation = _ref.orientation; | ||
var padding = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; | ||
var scale = constructor(); | ||
if (scale.paddingInner) { | ||
scale.paddingInner(padding).paddingOuter(padding / 2); | ||
} | ||
return scale.domain(domain).range(orientation === HORIZONTAL ? [0, width] : [height, 0]); | ||
}; | ||
var getWidth = function getWidth(scale) { | ||
return scale.bandwidth ? scale.bandwidth() : 0; | ||
}; | ||
var getTicks = function getTicks(scale) { | ||
@@ -258,2 +316,3 @@ return scale.ticks ? scale.ticks() : scale.domain(); | ||
// 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) { | ||
@@ -276,3 +335,3 @@ var ticks = getTicks(scale); | ||
xText: coordinates, | ||
yText: position === TOP ? -tickSize - indentFromAxis : tickSize + indentFromAxis, | ||
yText: position === TOP ? -indentFromAxis : indentFromAxis, | ||
key: index | ||
@@ -289,3 +348,3 @@ }; | ||
text: getFormat(scale, tickFormat)(tick), | ||
xText: position === LEFT ? -tickSize - indentFromAxis : tickSize + indentFromAxis, | ||
xText: position === LEFT ? -indentFromAxis : indentFromAxis, | ||
yText: coordinates, | ||
@@ -300,6 +359,6 @@ key: index | ||
var axisCoordinates = function axisCoordinates(domainOptions, position, width, height, tickSize, indentFromAxis, constructor) { | ||
var scale = createScale(domainOptions, width, height, constructor); | ||
return calculateAxisCoordinates(scale, domainOptions.orientation, position, tickSize, indentFromAxis, domainOptions.tickFormat); | ||
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); | ||
}; | ||
@@ -332,89 +391,76 @@ | ||
var getConstructor = function getConstructor(scaleExtension, type) { | ||
return scaleExtension.find(function (item) { | ||
return item.type === type; | ||
}).constructor; | ||
}; | ||
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, | ||
valueScale = _ref4.valueScale, | ||
palette = _ref4.palette, | ||
points = _ref4.points; | ||
var xyScales = function xyScales(argumentDomainOptions, valueDomainOptions, _ref4, groupWidth, scaleExtension) { | ||
var width = _ref4.width, | ||
height = _ref4.height; | ||
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); | ||
var pieData = pie().sort(null).value(function (d) { | ||
return d.value; | ||
})(points); | ||
var inner = innerRadius * radius; | ||
var outer = outerRadius * radius; | ||
var gen = arc().innerRadius(inner).outerRadius(outer); | ||
var colorScale = scaleOrdinal().range(palette); | ||
return function (point) { | ||
var _pieData$point$index = pieData[point.index], | ||
startAngle = _pieData$point$index.startAngle, | ||
endAngle = _pieData$point$index.endAngle; | ||
var xConstructor = getConstructor(scaleExtension, argumentDomainOptions.type); | ||
var yConstructor = getConstructor(scaleExtension, valueDomainOptions.type); | ||
return { | ||
xScale: createScale(argumentDomainOptions, width, height, xConstructor, 1 - groupWidth), | ||
yScale: createScale(valueDomainOptions, width, height, yConstructor) | ||
return _extends({}, point, { | ||
// TODO: It should be calculated in *pointComponent*. | ||
d: gen.startAngle(startAngle).endAngle(endAngle)(), | ||
color: point.color || colorScale(point.index), | ||
x: x, | ||
y: y, | ||
innerRadius: inner, | ||
outerRadius: outer, | ||
startAngle: startAngle, | ||
endAngle: endAngle | ||
}); | ||
}; | ||
}; | ||
var pieAttributes = function pieAttributes(data, _ref5, argumentField, valueField, name, stack$$1, stacks, _ref6) { | ||
var xScale = _ref5.xScale, | ||
yScale = _ref5.yScale; | ||
var _ref6$innerRadius = _ref6.innerRadius, | ||
innerRadius = _ref6$innerRadius === undefined ? 0 : _ref6$innerRadius, | ||
_ref6$outerRadius = _ref6.outerRadius, | ||
outerRadius = _ref6$outerRadius === undefined ? 1 : _ref6$outerRadius; | ||
var getAreaPointTransformer = function getAreaPointTransformer(_ref5) { | ||
var argumentScale = _ref5.argumentScale, | ||
valueScale = _ref5.valueScale; | ||
var width = Math.max.apply(null, xScale.range()); | ||
var height = Math.max.apply(null, yScale.range()); | ||
var radius = Math.min(width, height) / 2; | ||
var pieData = pie().sort(null).value(function (d) { | ||
return d[valueField]; | ||
})(data); | ||
return pieData.map(function (_ref7) { | ||
var startAngle = _ref7.startAngle, | ||
endAngle = _ref7.endAngle, | ||
value = _ref7.value, | ||
itemData = _ref7.data; | ||
return { | ||
d: arc().innerRadius(innerRadius * radius).outerRadius(outerRadius * radius).startAngle(startAngle).endAngle(endAngle)(), | ||
value: value, | ||
data: itemData, | ||
id: itemData[argumentField], | ||
x: width / 2, | ||
y: height / 2 | ||
}; | ||
}); | ||
var y1 = valueScale(0); | ||
var offset = getWidth(argumentScale) / 2; | ||
return function (point) { | ||
return _extends({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
y: valueScale(point.value), | ||
y1: y1 | ||
}); | ||
}; | ||
}; | ||
var coordinates = function coordinates(data, _ref8, argumentField, valueField, name) { | ||
var xScale = _ref8.xScale, | ||
yScale = _ref8.yScale; | ||
return data.reduce(function (result, dataItem, index) { | ||
if (dataItem[argumentField] !== undefined && dataItem[valueField] !== undefined) { | ||
return [].concat(toConsumableArray(result), [{ | ||
x: xScale(dataItem[argumentField]) + getWidth(xScale) / 2, | ||
y: yScale(dataItem[valueField + '-' + name + '-stack'][1]), | ||
y1: yScale(dataItem[valueField + '-' + name + '-stack'][0]), | ||
id: index, | ||
value: dataItem[valueField] | ||
}]); | ||
} | ||
return result; | ||
}, []); | ||
}; | ||
var getBarPointTransformer = function getBarPointTransformer(_ref6) { | ||
var argumentScale = _ref6.argumentScale, | ||
valueScale = _ref6.valueScale, | ||
barWidth = _ref6.barWidth; | ||
var barCoordinates = function barCoordinates(data, _ref9, argumentField, valueField, name, stack$$1) { | ||
var xScale = _ref9.xScale, | ||
yScale = _ref9.yScale; | ||
var stacks = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : [undefined]; | ||
var _ref10 = arguments[7]; | ||
var _ref10$barWidth = _ref10.barWidth, | ||
barWidth = _ref10$barWidth === undefined ? 0.9 : _ref10$barWidth; | ||
var scaleExtension = arguments[8]; | ||
var rawCoordinates = coordinates(data, { xScale: xScale, yScale: yScale }, argumentField, valueField, name); | ||
var width = getWidth(xScale); | ||
var x0Scale = createScale({ | ||
domain: stacks | ||
}, width, width, getConstructor(scaleExtension, 'band'), 1 - barWidth); | ||
return rawCoordinates.map(function (item) { | ||
return _extends({}, item, { | ||
width: getWidth(x0Scale), | ||
x: item.x - width / 2 + x0Scale(stack$$1) | ||
var y1 = valueScale(0); | ||
var categoryWidth = getWidth(argumentScale); | ||
var offset = categoryWidth * (1 - barWidth) / 2; | ||
var width = categoryWidth * barWidth; | ||
return function (point) { | ||
return _extends({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
y: valueScale(point.value), | ||
y1: y1, | ||
width: width | ||
}); | ||
}); | ||
}; | ||
}; | ||
// Used for Bar grouping. | ||
getBarPointTransformer.isBroad = true; | ||
@@ -427,7 +473,7 @@ var findSeriesByName = function findSeriesByName(name, series) { | ||
var dBar = function dBar(_ref11) { | ||
var x = _ref11.x, | ||
y = _ref11.y, | ||
y1 = _ref11.y1, | ||
width = _ref11.width; | ||
var dBar = function dBar(_ref7) { | ||
var x = _ref7.x, | ||
y = _ref7.y, | ||
y1 = _ref7.y1, | ||
width = _ref7.width; | ||
return { | ||
@@ -438,5 +484,5 @@ x: x, y: Math.min(y, y1), width: width || 2, height: Math.abs(y1 - y) | ||
var pointAttributes = function pointAttributes(_ref12) { | ||
var _ref12$size = _ref12.size, | ||
size = _ref12$size === undefined ? DEFAULT_POINT_SIZE : _ref12$size; | ||
var pointAttributes = function pointAttributes(_ref8) { | ||
var _ref8$size = _ref8.size, | ||
size = _ref8$size === undefined ? DEFAULT_POINT_SIZE : _ref8$size; | ||
@@ -446,2 +492,3 @@ var dPoint = symbol().size([Math.pow(size, 2)]).type(symbolCircle)(); | ||
return { | ||
// TODO: It should be calculated in *pointComponent*. | ||
d: dPoint, | ||
@@ -460,109 +507,621 @@ x: item.x, | ||
var seriesData = function seriesData() { | ||
var series = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | ||
var seriesProps = arguments[1]; | ||
var addItem = function addItem(list, item) { | ||
return list.find(function (obj) { | ||
return obj.uniqueName === item.uniqueName; | ||
}) ? addItem(list, _extends({}, item, { | ||
uniqueName: createNewUniqueName(item.uniqueName) | ||
})) : list.concat(item); | ||
}; | ||
if (series.find(function (_ref13) { | ||
var uniqueName = _ref13.uniqueName; | ||
return uniqueName === seriesProps.uniqueName; | ||
})) { | ||
return seriesData(series, _extends({}, seriesProps, { uniqueName: createNewUniqueName(seriesProps.uniqueName) })); | ||
// TODO: Memoization is much needed here. | ||
// Though "series" list never persists, single "series" item most often does. | ||
var createPoints = function createPoints(argumentField, valueField, data) { | ||
var points = []; | ||
data.forEach(function (dataItem, index) { | ||
var argument = dataItem[argumentField]; | ||
var value = dataItem[valueField]; | ||
if (argument !== undefined && value !== undefined) { | ||
points.push({ argument: argument, value: value, index: index }); | ||
} | ||
}); | ||
return points; | ||
}; | ||
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. | ||
// *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, { | ||
index: index, | ||
points: points, | ||
uniqueName: props.name, | ||
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. | ||
var scalePoints = function scalePoints(series, scales) { | ||
var getPointTransformer = series.getPointTransformer, | ||
rest = objectWithoutProperties(series, ['getPointTransformer']); | ||
var transform = getPointTransformer(_extends({}, series, { | ||
argumentScale: scales[ARGUMENT_DOMAIN], | ||
valueScale: scales[getValueDomainName(series.axisName)] | ||
})); | ||
return _extends({}, rest, { | ||
points: series.points.map(transform) | ||
}); | ||
}; | ||
var scaleSeriesPoints = function scaleSeriesPoints(series, scales) { | ||
return series.map(function (seriesItem) { | ||
return scalePoints(seriesItem, scales); | ||
}); | ||
}; | ||
// "Stack" plugin relies on "data" and "series" getters and | ||
// knowledge about "getPointTransformer" and "path" functions behavior. | ||
var buildSeriesToStackMap = function buildSeriesToStackMap(stacks) { | ||
var result = {}; | ||
stacks.forEach(function (_ref, i) { | ||
var series = _ref.series; | ||
series.forEach(function (name) { | ||
result[name] = i; | ||
}); | ||
}); | ||
return result; | ||
}; | ||
var getStackedPointTransformer = function getStackedPointTransformer(getPointTransformer) { | ||
var wrapper = function wrapper(series) { | ||
var transform = getPointTransformer(series); | ||
var valueScale = series.valueScale; | ||
return function (point) { | ||
var ret = transform(point); | ||
ret.y1 = valueScale(point.value0); | ||
return ret; | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
return wrapper; | ||
}; | ||
// TODO: Temporary - see corresponding note in *computeDomains*. | ||
var getValueDomain = function getValueDomain(points) { | ||
var items = []; | ||
points.forEach(function (point) { | ||
items.push(point.value, point.value0); | ||
}); | ||
return items; | ||
}; | ||
var collectStacks = function collectStacks(seriesList, seriesToStackMap) { | ||
var stacksKeys = {}; | ||
var seriesPositions = {}; | ||
seriesList.forEach(function (_ref2) { | ||
var name = _ref2.name, | ||
valueField = _ref2.valueField; | ||
var stackId = seriesToStackMap[name]; | ||
if (stackId === undefined) { | ||
return; | ||
} | ||
if (!stacksKeys[stackId]) { | ||
stacksKeys[stackId] = []; | ||
} | ||
seriesPositions[name] = stacksKeys[stackId].length; | ||
stacksKeys[stackId].push(valueField); | ||
}); | ||
// Stack cannot consist of single series. | ||
Object.keys(stacksKeys).forEach(function (stackId) { | ||
if (stacksKeys[stackId].length === 1) { | ||
delete stacksKeys[stackId]; | ||
} | ||
}); | ||
return [stacksKeys, seriesPositions]; | ||
}; | ||
var getStackedData = function getStackedData(stacksKeys, dataItems, offset, order) { | ||
var result = {}; | ||
Object.keys(stacksKeys).forEach(function (stackId) { | ||
result[stackId] = stack().keys(stacksKeys[stackId]).order(order).offset(offset)(dataItems); | ||
}); | ||
return result; | ||
}; | ||
var buildStackedSeries = function buildStackedSeries(series, dataItems) { | ||
var points = series.points.map(function (point) { | ||
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 }); | ||
}); | ||
var stackedSeries = _extends({}, series, { | ||
points: points | ||
}); | ||
if (series.isStartedFromZero) { | ||
stackedSeries.getPointTransformer = getStackedPointTransformer(series.getPointTransformer); | ||
stackedSeries.getValueDomain = getValueDomain; | ||
} | ||
return [].concat(toConsumableArray(series), [seriesProps]); | ||
return stackedSeries; | ||
}; | ||
var getPieItems = function getPieItems(series, domain) { | ||
return domain.map(function (uniqueName) { | ||
return { uniqueName: uniqueName }; | ||
var applyStacking = function applyStacking(seriesList, dataItems, seriesToStackMap, offset, order) { | ||
var _collectStacks = collectStacks(seriesList, seriesToStackMap), | ||
_collectStacks2 = slicedToArray(_collectStacks, 2), | ||
stacksKeys = _collectStacks2[0], | ||
seriesPositions = _collectStacks2[1]; | ||
if (Object.keys(stacksKeys).length === 0) { | ||
return seriesList; | ||
} | ||
var stackedData = getStackedData(stacksKeys, dataItems, offset, order); | ||
return seriesList.map(function (seriesItem) { | ||
var stackId = seriesToStackMap[seriesItem.name]; | ||
var stackData = stackedData[stackId]; | ||
if (!stackData) { | ||
return seriesItem; | ||
} | ||
var position = seriesPositions[seriesItem.name]; | ||
return buildStackedSeries(seriesItem, stackData[position]); | ||
}); | ||
}; | ||
var getStacks = function getStacks(series) { | ||
return series.reduce(function (prevValue, _ref, index) { | ||
var valueField = _ref.valueField, | ||
seriesStack = _ref.stack; | ||
var getGroupName = function getGroupName(series, i, seriesToStackMap) { | ||
var stackId = seriesToStackMap[series.name]; | ||
return stackId >= 0 ? String(stackId) : 'group-' + i; | ||
}; | ||
if (!prevValue[seriesStack]) { | ||
return _extends({}, prevValue, defineProperty({}, seriesStack, { | ||
keys: [valueField], | ||
series: [index] | ||
})); | ||
var getGroupedPointTransformer = function getGroupedPointTransformer(getPointTransformer, groupCount, groupOffset) { | ||
var wrapper = function wrapper(series) { | ||
var transform = getPointTransformer(series); | ||
var barWidth = series.barWidth; | ||
var widthCoeff = 1 / groupCount; | ||
var offsetCoeff = -(1 - barWidth) / 2 + groupOffset + widthCoeff * (1 - barWidth) / 2; | ||
return function (point) { | ||
var ret = transform(point); | ||
ret.x += ret.width / barWidth * offsetCoeff; | ||
ret.width *= widthCoeff; | ||
return ret; | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
return wrapper; | ||
}; | ||
var applyGrouping = function applyGrouping(seriesList, seriesToStackMap) { | ||
var groups = new Set(); | ||
seriesList.forEach(function (seriesItem, i) { | ||
if (seriesItem.getPointTransformer.isBroad) { | ||
groups.add(getGroupName(seriesItem, i, seriesToStackMap)); | ||
} | ||
return _extends({}, prevValue, defineProperty({}, seriesStack, { | ||
keys: [].concat(toConsumableArray(prevValue[seriesStack].keys), [valueField]), | ||
series: [].concat(toConsumableArray(prevValue[seriesStack].series), [index]) | ||
})); | ||
}, {}); | ||
}); | ||
// There cannot be single group. | ||
if (groups.size < 2) { | ||
return seriesList; | ||
} | ||
var scale = scaleBand().domain(Array.from(groups)).range([0, 1]); | ||
return seriesList.map(function (seriesItem, i) { | ||
if (!seriesItem.getPointTransformer.isBroad) { | ||
return seriesItem; | ||
} | ||
var getPointTransformer = getGroupedPointTransformer(seriesItem.getPointTransformer, groups.size, scale(getGroupName(seriesItem, i, seriesToStackMap))); | ||
return _extends({}, seriesItem, { | ||
getPointTransformer: getPointTransformer | ||
}); | ||
}); | ||
}; | ||
var filtering = function filtering(_ref2) { | ||
var seriesStack = _ref2.stack; | ||
return seriesStack; | ||
var getStackedSeries = function getStackedSeries(seriesList, dataItems, _ref3) { | ||
var stacks = _ref3.stacks, | ||
offset = _ref3.offset, | ||
order = _ref3.order; | ||
var map = buildSeriesToStackMap(stacks); | ||
var stackedSeriesList = applyStacking(seriesList, dataItems, map, offset, order); | ||
var groupedSeriesList = applyGrouping(stackedSeriesList, map); | ||
return groupedSeriesList; | ||
}; | ||
var processData = function processData(offset, order) { | ||
return function (series, data) { | ||
var stacks = getStacks(series); | ||
var ANIMATIONS = Symbol('animation'); | ||
var arrayOfStacks = Object.entries(stacks).reduce(function (prevValue, item) { | ||
return _extends({}, prevValue, defineProperty({}, item[0], stack().keys(item[1].keys).order(order).offset(offset)(data))); | ||
}, {}); | ||
var addKeyframe = function addKeyframe(name, def) { | ||
if (typeof document === 'undefined') { | ||
return; | ||
} | ||
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'; | ||
style.dataset[ANIMATIONS] = true; | ||
head.appendChild(style); | ||
} | ||
var content = style.textContent; | ||
if (!content.includes(name)) { | ||
style.textContent += '\n@keyframes ' + name + ' ' + def + '\n'; | ||
} | ||
}; | ||
return data.map(function (singleData, dataIndex) { | ||
return series.reduce(function (prevValue, _ref3, index) { | ||
var valueField = _ref3.valueField, | ||
name = _ref3.name, | ||
seriesStack = _ref3.stack; | ||
var getAreaAnimationName = function getAreaAnimationName() { | ||
var name = 'animation_transform'; | ||
addKeyframe(name, '{ from { transform: scaleY(0); } }'); | ||
return name; | ||
}; | ||
var seriesIndex = stacks[seriesStack].series.findIndex(function (item) { | ||
return item === index; | ||
var getScatterAnimationName = function getScatterAnimationName() { | ||
var name = 'animation_scatter'; | ||
addKeyframe(name, '{ 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1 } }'); | ||
return name; | ||
}; | ||
var getPieAnimationName = function getPieAnimationName() { | ||
var name = 'animation_pie'; | ||
addKeyframe(name, '{ from { transform: scale(0); } }'); | ||
return name; | ||
}; | ||
var getDefaultAreaAnimationOptions = function getDefaultAreaAnimationOptions() { | ||
return '1s'; | ||
}; | ||
var getDefaultPieAnimationOptions = function getDefaultPieAnimationOptions(_ref) { | ||
var index = _ref.index; | ||
return 0.7 + index * 0.1 + 's'; | ||
}; | ||
var getAreaAnimationStyle = function getAreaAnimationStyle(scales) { | ||
var animationStyle = { | ||
transformOrigin: '0px ' + scales.yScale.copy().clamp(true)(0) + 'px' | ||
}; | ||
var options = getDefaultAreaAnimationOptions(); | ||
return _extends({ | ||
animation: getAreaAnimationName() + ' ' + options | ||
}, animationStyle); | ||
}; | ||
var getPieAnimationStyle = function getPieAnimationStyle(scales, point) { | ||
var options = getDefaultPieAnimationOptions(point); | ||
return { | ||
animation: getPieAnimationName() + ' ' + options | ||
}; | ||
}; | ||
var getScatterAnimationStyle = function getScatterAnimationStyle() { | ||
var options = getDefaultAreaAnimationOptions(); | ||
return { | ||
animation: getScatterAnimationName() + ' ' + options | ||
}; | ||
}; | ||
var buildAnimatedStyleGetter = function buildAnimatedStyleGetter(style, getAnimationStyle, scales, point) { | ||
var animationStyle = getAnimationStyle(scales, point); | ||
return _extends({}, animationStyle, style); | ||
}; | ||
var isPointInRect = function isPointInRect(x, y, x1, x2, y1, y2) { | ||
return x1 <= x && x <= x2 && y1 <= y && y <= y2; | ||
}; | ||
var LINE_TOLERANCE = 10; | ||
// 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) { | ||
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); | ||
}); | ||
return _extends({}, prevValue, defineProperty({}, valueField + '-' + name + '-stack', arrayOfStacks[seriesStack][seriesIndex][dataIndex])); | ||
}, singleData); | ||
}); | ||
if (point) { | ||
hit.point = point.index; | ||
} | ||
} | ||
return hit; | ||
}; | ||
}; | ||
}; | ||
var seriesWithStacks = function seriesWithStacks(series) { | ||
return series.reduce(function (prevResult, singleSeries, index) { | ||
var _singleSeries$stack = singleSeries.stack, | ||
seriesStack = _singleSeries$stack === undefined ? 'stack' + index : _singleSeries$stack; | ||
var createAreaHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
var path = area(); | ||
path.x(dArea.x()); | ||
path.y1(dArea.y1()); | ||
path.y0(dArea.y0()); | ||
return path; | ||
}); | ||
var createLineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
var path = area(); | ||
var getY = dLine.y(); | ||
path.x(dLine.x()); | ||
path.y1(function (point) { | ||
return getY(point) - LINE_TOLERANCE; | ||
}); | ||
path.y0(function (point) { | ||
return getY(point) + LINE_TOLERANCE; | ||
}); | ||
return path; | ||
}); | ||
return [].concat(toConsumableArray(prevResult), [_extends({}, singleSeries, { stack: seriesStack })]); | ||
}, []); | ||
var createSplineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
var path = area(); | ||
var getY = dSpline.y(); | ||
path.x(dSpline.x()); | ||
path.y1(function (point) { | ||
return getY(point) - LINE_TOLERANCE; | ||
}); | ||
path.y0(function (point) { | ||
return getY(point) + LINE_TOLERANCE; | ||
}); | ||
path.curve(dSpline.curve()); | ||
return path; | ||
}); | ||
var createBarHitTester = function createBarHitTester(coordinates) { | ||
return function (_ref4) { | ||
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 stacks = function stacks(series) { | ||
return [].concat(toConsumableArray(new Set(series.filter(function (singleSeries) { | ||
return filtering(singleSeries); | ||
}).map(function (_ref4) { | ||
var seriesStack = _ref4.stack; | ||
return seriesStack; | ||
})))); | ||
// 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 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 palette = function palette(series, scheme) { | ||
return scaleOrdinal().domain(series.map(function (_ref) { | ||
var uniqueName = _ref.uniqueName; | ||
return uniqueName; | ||
})).range(scheme); | ||
var mapAngleTod3 = function mapAngleTod3(angle) { | ||
var ret = angle + Math.PI / 2; | ||
return ret >= 0 ? ret : ret + Math.PI * 2; | ||
}; | ||
var prepareData = function prepareData(data, series, processingData) { | ||
return processingData ? processingData(series, data) : data.map(function (singleData) { | ||
return series.reduce(function (prevValue, _ref) { | ||
var valueField = _ref.valueField, | ||
name = _ref.name; | ||
var createPieHitTester = function createPieHitTester(coordinates) { | ||
return function (_ref10) { | ||
var _ref11 = slicedToArray(_ref10, 2), | ||
px = _ref11[0], | ||
py = _ref11[1]; | ||
if (singleData[valueField] === undefined) { | ||
return prevValue; | ||
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 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; | ||
}; | ||
}; | ||
return _extends({}, prevValue, defineProperty({}, valueField + "-" + name + "-stack", [0, singleData[valueField]])); | ||
}, singleData); | ||
var buildFilter = function buildFilter(targets) { | ||
var result = {}; | ||
targets.forEach(function (_ref13) { | ||
var series = _ref13.series, | ||
point = _ref13.point; | ||
result[series] = result[series] || { points: {} }; | ||
if (point >= 0) { | ||
result[series].points[point] = true; | ||
} else { | ||
result[series].self = true; | ||
} | ||
}); | ||
return result; | ||
}; | ||
export { getValueDomainName, computeExtension, computeDomains, bBoxes, axisCoordinates, axesData, dArea, dLine, dSpline, xyScales, pieAttributes, coordinates, barCoordinates, findSeriesByName, dBar, pointAttributes, seriesData, getPieItems, createScale, getWidth, HORIZONTAL, VERTICAL, TOP, BOTTOM, LEFT, RIGHT, MIDDLE, END, START, LINEAR, BAND, ARGUMENT_DOMAIN, VALUE_DOMAIN, processData, seriesWithStacks, stacks, palette, prepareData }; | ||
var changeSeriesState = function changeSeriesState(seriesList, targets, state) { | ||
if (targets.length === 0) { | ||
return seriesList; | ||
} | ||
var filter = buildFilter(targets); | ||
var matches = 0; | ||
var result = seriesList.map(function (seriesItem) { | ||
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 _extends({}, seriesItem, props); | ||
}); | ||
// This is to prevent false rerenders. | ||
return matches > 0 ? result : seriesList; | ||
}; | ||
var getDefaultLegendItems = function getDefaultLegendItems(series) { | ||
return series.map(function (_ref) { | ||
var text = _ref.uniqueName, | ||
color = _ref.color; | ||
return { text: text, color: color }; | ||
}); | ||
}; | ||
var getPieLegendItems = function getPieLegendItems(series) { | ||
return series[0].points.map(function (_ref2) { | ||
var text = _ref2.id, | ||
color = _ref2.color; | ||
return { text: text, color: color }; | ||
}); | ||
}; | ||
// 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) { | ||
return series.length === 1 && series[0].seriesComponent.name === 'SliceCollection'; | ||
}; | ||
var getLegendItems = function getLegendItems(series) { | ||
return (isSinglePieSeriesCase(series) ? getPieLegendItems : getDefaultLegendItems)(series); | ||
}; | ||
// This function is called from event handlers (when DOM is available) - | ||
// *window* can be accessed safely. | ||
var getEventCoords = function getEventCoords(e) { | ||
var _window = window, | ||
pageXOffset = _window.pageXOffset, | ||
pageYOffset = _window.pageYOffset; // eslint-disable-line no-undef | ||
var _e$currentTarget$getB = e.currentTarget.getBoundingClientRect(), | ||
left = _e$currentTarget$getB.left, | ||
top = _e$currentTarget$getB.top; | ||
return [e.clientX - left - pageXOffset, e.clientY - top - pageYOffset]; | ||
}; | ||
var buildEventHandler = function buildEventHandler(seriesList, handlers) { | ||
var hitTesters = null; | ||
var createHitTesters = function createHitTesters() { | ||
var obj = {}; | ||
seriesList.forEach(function (seriesItem) { | ||
obj[seriesItem.symbolName] = seriesItem.createHitTester(seriesItem.points); | ||
}); | ||
return obj; | ||
}; | ||
return function (e) { | ||
var location = getEventCoords(e); | ||
hitTesters = hitTesters || createHitTesters(); | ||
var targets = []; | ||
seriesList.forEach(function (seriesItem) { | ||
var status = hitTesters[seriesItem.symbolName](location); | ||
if (status) { | ||
targets.push(_extends({ series: seriesItem.name }, status)); | ||
} | ||
}); | ||
var arg = { location: location, targets: targets }; | ||
handlers.forEach(function (handler) { | ||
return handler(arg); | ||
}); | ||
}; | ||
}; | ||
var buildLeaveEventHandler = function buildLeaveEventHandler(handlers) { | ||
return function (e) { | ||
var location = getEventCoords(e); | ||
var arg = { location: location, targets: [] }; | ||
handlers.forEach(function (handler) { | ||
return handler(arg); | ||
}); | ||
}; | ||
}; | ||
var buildEventHandlers = function buildEventHandlers(seriesList, _ref) { | ||
var clickHandlers = _ref.clickHandlers, | ||
pointerMoveHandlers = _ref.pointerMoveHandlers; | ||
var handlers = {}; | ||
if (clickHandlers.length) { | ||
handlers.click = buildEventHandler(seriesList, clickHandlers); | ||
} | ||
if (pointerMoveHandlers.length) { | ||
handlers.pointermove = buildEventHandler(seriesList, pointerMoveHandlers); | ||
handlers.pointerleave = buildLeaveEventHandler(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 }; | ||
//# sourceMappingURL=dx-chart-core.es.js.map |
/** | ||
* Bundle of @devexpress/dx-chart-core | ||
* Generated: 2018-10-04 | ||
* Version: 1.8.0 | ||
* Generated: 2018-11-07 | ||
* Version: 1.9.0 | ||
* License: https://js.devexpress.com/Licensing | ||
@@ -30,2 +30,21 @@ */ | ||
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) { | ||
@@ -60,2 +79,52 @@ if (key in obj) { | ||
var objectWithoutProperties = function (obj, keys) { | ||
var target = {}; | ||
for (var i in obj) { | ||
if (keys.indexOf(i) >= 0) continue; | ||
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; | ||
target[i] = obj[i]; | ||
} | ||
return target; | ||
}; | ||
var slicedToArray = function () { | ||
function sliceIterator(arr, i) { | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"]) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
return function (arr, i) { | ||
if (Array.isArray(arr)) { | ||
return arr; | ||
} else if (Symbol.iterator in Object(arr)) { | ||
return sliceIterator(arr, i); | ||
} else { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
} | ||
}; | ||
}(); | ||
var toConsumableArray = function (arr) { | ||
@@ -75,6 +144,2 @@ if (Array.isArray(arr)) { | ||
var getValueDomainName = function getValueDomainName(name) { | ||
return name || VALUE_DOMAIN; | ||
}; | ||
// TODO: Property name should not contain "axis" part as it actually means domain. | ||
@@ -85,35 +150,22 @@ var getSeriesValueDomainName = function getSeriesValueDomainName(series) { | ||
var calculateDomainField = function calculateDomainField(getFieldItemFirst, getFieldItemSecond, data, domain, type) { | ||
var getCategories = function getCategories(prev, cur) { | ||
var categories = getFieldItemFirst(cur); | ||
if (isDefined(categories)) { | ||
return [].concat(toConsumableArray(prev), [categories]); | ||
} | ||
return prev; | ||
}; | ||
if (type === BAND) { | ||
return [].concat(toConsumableArray(domain), toConsumableArray(data.reduce(getCategories, []))); | ||
} | ||
return d3Array.extent([].concat(toConsumableArray(domain), toConsumableArray(d3Array.extent(data, getFieldItemFirst)), toConsumableArray(d3Array.extent(data, getFieldItemSecond)))); | ||
var calculateDomainField = function calculateDomainField(items, domain, type) { | ||
return type === BAND ? [].concat(toConsumableArray(domain), toConsumableArray(items)) : d3Array.extent([].concat(toConsumableArray(domain), toConsumableArray(d3Array.extent(items)))); | ||
}; | ||
var getCorrectAxisType = function getCorrectAxisType(type, data, field) { | ||
if (!type && typeof data.find(function (item) { | ||
return isDefined(item[field]); | ||
})[field] === 'string') { | ||
return BAND; | ||
} | ||
return type || LINEAR; | ||
var getArgument = function getArgument(point) { | ||
return point.argument; | ||
}; | ||
var getFieldStack = function getFieldStack(index, object) { | ||
return object && isDefined(object[index]) ? object[index] : undefined; | ||
var getValue = function getValue(point) { | ||
return point.value; | ||
}; | ||
var calculateDomains = function calculateDomains(domains, seriesList, data) { | ||
var getCorrectAxisType = function getCorrectAxisType(type, points, getItem) { | ||
return type || points.length && typeof getItem(points[0]) === 'string' && BAND || LINEAR; | ||
}; | ||
var calculateDomains = function calculateDomains(domains, seriesList) { | ||
seriesList.forEach(function (seriesItem) { | ||
var valueDomainName = getSeriesValueDomainName(seriesItem); | ||
var argumentField = seriesItem.argumentField, | ||
valueField = seriesItem.valueField, | ||
name = seriesItem.name; | ||
var points = seriesItem.points; | ||
@@ -123,15 +175,13 @@ var argumentDomain = domains[ARGUMENT_DOMAIN]; | ||
var valueType = getCorrectAxisType(valueDomain.type, data, valueField); | ||
var argumentType = getCorrectAxisType(argumentDomain.type, data, argumentField); | ||
var valueType = getCorrectAxisType(valueDomain.type, points, getValue); | ||
var argumentType = getCorrectAxisType(argumentDomain.type, points, getArgument); | ||
valueDomain.domain = calculateDomainField(function (object) { | ||
return getFieldStack(1, object[valueField + '-' + name + '-stack']); | ||
}, valueDomain.isStartedFromZero ? function (object) { | ||
return getFieldStack(0, object[valueField + '-' + name + '-stack']); | ||
} : undefined, data, valueDomain.domain, valueType); | ||
// 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(function (object) { | ||
return object[argumentField]; | ||
}, null, data, argumentDomain.domain, argumentType); | ||
argumentDomain.domain = calculateDomainField(points.map(getArgument), argumentDomain.domain, argumentType); | ||
argumentDomain.type = argumentType; | ||
@@ -142,3 +192,5 @@ }); | ||
var computeExtension = function computeExtension(extension) { | ||
var defaultExtension = [{ type: LINEAR, constructor: d3Scale.scaleLinear }, { type: BAND, constructor: d3Scale.scaleBand }]; | ||
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); | ||
@@ -153,3 +205,5 @@ }; | ||
domains[name] = domain; | ||
domain.isStartedFromZero = domain.isStartedFromZero || seriesItem.isStartedFromZero; | ||
if (seriesItem.isStartedFromZero && domain.domain.length === 0) { | ||
domain.domain = [0]; | ||
} | ||
}); | ||
@@ -189,3 +243,3 @@ return domains; | ||
var computeDomains = function computeDomains(axes, series, data) { | ||
var computeDomains = function computeDomains(axes, series) { | ||
var result = collectDomains(series); | ||
@@ -195,3 +249,3 @@ // Axes options are taken in two steps because *type* is required for domains calculation | ||
takeTypeFromAxesOptions(result, axes); | ||
calculateDomains(result, series, data); | ||
calculateDomains(result, series); | ||
takeRestAxesOptions(result, axes); | ||
@@ -201,2 +255,22 @@ return result; | ||
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), | ||
name = _ref5[0], | ||
domain = _ref5[1]; | ||
var _scaleExtension$find = scaleExtension.find(function (item) { | ||
return item.type === domain.type; | ||
}), | ||
constructor = _scaleExtension$find.constructor; | ||
scales[name] = createScale(domain, width, height, constructor); | ||
}); | ||
return scales; | ||
}; | ||
var isEqual = function isEqual(_ref, _ref2) { | ||
@@ -218,18 +292,2 @@ var firstWidth = _ref.width, | ||
var createScale = function createScale(_ref, width, height, constructor) { | ||
var domain = _ref.domain, | ||
orientation = _ref.orientation; | ||
var padding = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; | ||
var scale = constructor(); | ||
if (scale.paddingInner) { | ||
scale.paddingInner(padding).paddingOuter(padding / 2); | ||
} | ||
return scale.domain(domain).range(orientation === HORIZONTAL ? [0, width] : [height, 0]); | ||
}; | ||
var getWidth = function getWidth(scale) { | ||
return scale.bandwidth ? scale.bandwidth() : 0; | ||
}; | ||
var getTicks = function getTicks(scale) { | ||
@@ -260,2 +318,3 @@ return scale.ticks ? scale.ticks() : scale.domain(); | ||
// 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) { | ||
@@ -278,3 +337,3 @@ var ticks = getTicks(scale); | ||
xText: coordinates, | ||
yText: position === TOP ? -tickSize - indentFromAxis : tickSize + indentFromAxis, | ||
yText: position === TOP ? -indentFromAxis : indentFromAxis, | ||
key: index | ||
@@ -291,3 +350,3 @@ }; | ||
text: getFormat(scale, tickFormat)(tick), | ||
xText: position === LEFT ? -tickSize - indentFromAxis : tickSize + indentFromAxis, | ||
xText: position === LEFT ? -indentFromAxis : indentFromAxis, | ||
yText: coordinates, | ||
@@ -302,6 +361,6 @@ key: index | ||
var axisCoordinates = function axisCoordinates(domainOptions, position, width, height, tickSize, indentFromAxis, constructor) { | ||
var scale = createScale(domainOptions, width, height, constructor); | ||
return calculateAxisCoordinates(scale, domainOptions.orientation, position, tickSize, indentFromAxis, domainOptions.tickFormat); | ||
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); | ||
}; | ||
@@ -334,89 +393,76 @@ | ||
var getConstructor = function getConstructor(scaleExtension, type) { | ||
return scaleExtension.find(function (item) { | ||
return item.type === type; | ||
}).constructor; | ||
}; | ||
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, | ||
valueScale = _ref4.valueScale, | ||
palette = _ref4.palette, | ||
points = _ref4.points; | ||
var xyScales = function xyScales(argumentDomainOptions, valueDomainOptions, _ref4, groupWidth, scaleExtension) { | ||
var width = _ref4.width, | ||
height = _ref4.height; | ||
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); | ||
var pieData = d3Shape.pie().sort(null).value(function (d) { | ||
return d.value; | ||
})(points); | ||
var inner = innerRadius * radius; | ||
var outer = outerRadius * radius; | ||
var gen = d3Shape.arc().innerRadius(inner).outerRadius(outer); | ||
var colorScale = d3Scale.scaleOrdinal().range(palette); | ||
return function (point) { | ||
var _pieData$point$index = pieData[point.index], | ||
startAngle = _pieData$point$index.startAngle, | ||
endAngle = _pieData$point$index.endAngle; | ||
var xConstructor = getConstructor(scaleExtension, argumentDomainOptions.type); | ||
var yConstructor = getConstructor(scaleExtension, valueDomainOptions.type); | ||
return { | ||
xScale: createScale(argumentDomainOptions, width, height, xConstructor, 1 - groupWidth), | ||
yScale: createScale(valueDomainOptions, width, height, yConstructor) | ||
return _extends({}, point, { | ||
// TODO: It should be calculated in *pointComponent*. | ||
d: gen.startAngle(startAngle).endAngle(endAngle)(), | ||
color: point.color || colorScale(point.index), | ||
x: x, | ||
y: y, | ||
innerRadius: inner, | ||
outerRadius: outer, | ||
startAngle: startAngle, | ||
endAngle: endAngle | ||
}); | ||
}; | ||
}; | ||
var pieAttributes = function pieAttributes(data, _ref5, argumentField, valueField, name, stack, stacks, _ref6) { | ||
var xScale = _ref5.xScale, | ||
yScale = _ref5.yScale; | ||
var _ref6$innerRadius = _ref6.innerRadius, | ||
innerRadius = _ref6$innerRadius === undefined ? 0 : _ref6$innerRadius, | ||
_ref6$outerRadius = _ref6.outerRadius, | ||
outerRadius = _ref6$outerRadius === undefined ? 1 : _ref6$outerRadius; | ||
var getAreaPointTransformer = function getAreaPointTransformer(_ref5) { | ||
var argumentScale = _ref5.argumentScale, | ||
valueScale = _ref5.valueScale; | ||
var width = Math.max.apply(null, xScale.range()); | ||
var height = Math.max.apply(null, yScale.range()); | ||
var radius = Math.min(width, height) / 2; | ||
var pieData = d3Shape.pie().sort(null).value(function (d) { | ||
return d[valueField]; | ||
})(data); | ||
return pieData.map(function (_ref7) { | ||
var startAngle = _ref7.startAngle, | ||
endAngle = _ref7.endAngle, | ||
value = _ref7.value, | ||
itemData = _ref7.data; | ||
return { | ||
d: d3Shape.arc().innerRadius(innerRadius * radius).outerRadius(outerRadius * radius).startAngle(startAngle).endAngle(endAngle)(), | ||
value: value, | ||
data: itemData, | ||
id: itemData[argumentField], | ||
x: width / 2, | ||
y: height / 2 | ||
}; | ||
}); | ||
var y1 = valueScale(0); | ||
var offset = getWidth(argumentScale) / 2; | ||
return function (point) { | ||
return _extends({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
y: valueScale(point.value), | ||
y1: y1 | ||
}); | ||
}; | ||
}; | ||
var coordinates = function coordinates(data, _ref8, argumentField, valueField, name) { | ||
var xScale = _ref8.xScale, | ||
yScale = _ref8.yScale; | ||
return data.reduce(function (result, dataItem, index) { | ||
if (dataItem[argumentField] !== undefined && dataItem[valueField] !== undefined) { | ||
return [].concat(toConsumableArray(result), [{ | ||
x: xScale(dataItem[argumentField]) + getWidth(xScale) / 2, | ||
y: yScale(dataItem[valueField + '-' + name + '-stack'][1]), | ||
y1: yScale(dataItem[valueField + '-' + name + '-stack'][0]), | ||
id: index, | ||
value: dataItem[valueField] | ||
}]); | ||
} | ||
return result; | ||
}, []); | ||
}; | ||
var getBarPointTransformer = function getBarPointTransformer(_ref6) { | ||
var argumentScale = _ref6.argumentScale, | ||
valueScale = _ref6.valueScale, | ||
barWidth = _ref6.barWidth; | ||
var barCoordinates = function barCoordinates(data, _ref9, argumentField, valueField, name, stack) { | ||
var xScale = _ref9.xScale, | ||
yScale = _ref9.yScale; | ||
var stacks = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : [undefined]; | ||
var _ref10 = arguments[7]; | ||
var _ref10$barWidth = _ref10.barWidth, | ||
barWidth = _ref10$barWidth === undefined ? 0.9 : _ref10$barWidth; | ||
var scaleExtension = arguments[8]; | ||
var rawCoordinates = coordinates(data, { xScale: xScale, yScale: yScale }, argumentField, valueField, name); | ||
var width = getWidth(xScale); | ||
var x0Scale = createScale({ | ||
domain: stacks | ||
}, width, width, getConstructor(scaleExtension, 'band'), 1 - barWidth); | ||
return rawCoordinates.map(function (item) { | ||
return _extends({}, item, { | ||
width: getWidth(x0Scale), | ||
x: item.x - width / 2 + x0Scale(stack) | ||
var y1 = valueScale(0); | ||
var categoryWidth = getWidth(argumentScale); | ||
var offset = categoryWidth * (1 - barWidth) / 2; | ||
var width = categoryWidth * barWidth; | ||
return function (point) { | ||
return _extends({}, point, { | ||
x: argumentScale(point.argument) + offset, | ||
y: valueScale(point.value), | ||
y1: y1, | ||
width: width | ||
}); | ||
}); | ||
}; | ||
}; | ||
// Used for Bar grouping. | ||
getBarPointTransformer.isBroad = true; | ||
@@ -429,7 +475,7 @@ var findSeriesByName = function findSeriesByName(name, series) { | ||
var dBar = function dBar(_ref11) { | ||
var x = _ref11.x, | ||
y = _ref11.y, | ||
y1 = _ref11.y1, | ||
width = _ref11.width; | ||
var dBar = function dBar(_ref7) { | ||
var x = _ref7.x, | ||
y = _ref7.y, | ||
y1 = _ref7.y1, | ||
width = _ref7.width; | ||
return { | ||
@@ -440,5 +486,5 @@ x: x, y: Math.min(y, y1), width: width || 2, height: Math.abs(y1 - y) | ||
var pointAttributes = function pointAttributes(_ref12) { | ||
var _ref12$size = _ref12.size, | ||
size = _ref12$size === undefined ? DEFAULT_POINT_SIZE : _ref12$size; | ||
var pointAttributes = function pointAttributes(_ref8) { | ||
var _ref8$size = _ref8.size, | ||
size = _ref8$size === undefined ? DEFAULT_POINT_SIZE : _ref8$size; | ||
@@ -448,2 +494,3 @@ var dPoint = d3Shape.symbol().size([Math.pow(size, 2)]).type(d3Shape.symbolCircle)(); | ||
return { | ||
// TODO: It should be calculated in *pointComponent*. | ||
d: dPoint, | ||
@@ -462,111 +509,623 @@ x: item.x, | ||
var seriesData = function seriesData() { | ||
var series = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | ||
var seriesProps = arguments[1]; | ||
var addItem = function addItem(list, item) { | ||
return list.find(function (obj) { | ||
return obj.uniqueName === item.uniqueName; | ||
}) ? addItem(list, _extends({}, item, { | ||
uniqueName: createNewUniqueName(item.uniqueName) | ||
})) : list.concat(item); | ||
}; | ||
if (series.find(function (_ref13) { | ||
var uniqueName = _ref13.uniqueName; | ||
return uniqueName === seriesProps.uniqueName; | ||
})) { | ||
return seriesData(series, _extends({}, seriesProps, { uniqueName: createNewUniqueName(seriesProps.uniqueName) })); | ||
// TODO: Memoization is much needed here. | ||
// Though "series" list never persists, single "series" item most often does. | ||
var createPoints = function createPoints(argumentField, valueField, data) { | ||
var points = []; | ||
data.forEach(function (dataItem, index) { | ||
var argument = dataItem[argumentField]; | ||
var value = dataItem[valueField]; | ||
if (argument !== undefined && value !== undefined) { | ||
points.push({ argument: argument, value: value, index: index }); | ||
} | ||
}); | ||
return points; | ||
}; | ||
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. | ||
// *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, { | ||
index: index, | ||
points: points, | ||
uniqueName: props.name, | ||
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. | ||
var scalePoints = function scalePoints(series, scales) { | ||
var getPointTransformer = series.getPointTransformer, | ||
rest = objectWithoutProperties(series, ['getPointTransformer']); | ||
var transform = getPointTransformer(_extends({}, series, { | ||
argumentScale: scales[ARGUMENT_DOMAIN], | ||
valueScale: scales[getValueDomainName(series.axisName)] | ||
})); | ||
return _extends({}, rest, { | ||
points: series.points.map(transform) | ||
}); | ||
}; | ||
var scaleSeriesPoints = function scaleSeriesPoints(series, scales) { | ||
return series.map(function (seriesItem) { | ||
return scalePoints(seriesItem, scales); | ||
}); | ||
}; | ||
// "Stack" plugin relies on "data" and "series" getters and | ||
// knowledge about "getPointTransformer" and "path" functions behavior. | ||
var buildSeriesToStackMap = function buildSeriesToStackMap(stacks) { | ||
var result = {}; | ||
stacks.forEach(function (_ref, i) { | ||
var series = _ref.series; | ||
series.forEach(function (name) { | ||
result[name] = i; | ||
}); | ||
}); | ||
return result; | ||
}; | ||
var getStackedPointTransformer = function getStackedPointTransformer(getPointTransformer) { | ||
var wrapper = function wrapper(series) { | ||
var transform = getPointTransformer(series); | ||
var valueScale = series.valueScale; | ||
return function (point) { | ||
var ret = transform(point); | ||
ret.y1 = valueScale(point.value0); | ||
return ret; | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
return wrapper; | ||
}; | ||
// TODO: Temporary - see corresponding note in *computeDomains*. | ||
var getValueDomain = function getValueDomain(points) { | ||
var items = []; | ||
points.forEach(function (point) { | ||
items.push(point.value, point.value0); | ||
}); | ||
return items; | ||
}; | ||
var collectStacks = function collectStacks(seriesList, seriesToStackMap) { | ||
var stacksKeys = {}; | ||
var seriesPositions = {}; | ||
seriesList.forEach(function (_ref2) { | ||
var name = _ref2.name, | ||
valueField = _ref2.valueField; | ||
var stackId = seriesToStackMap[name]; | ||
if (stackId === undefined) { | ||
return; | ||
} | ||
if (!stacksKeys[stackId]) { | ||
stacksKeys[stackId] = []; | ||
} | ||
seriesPositions[name] = stacksKeys[stackId].length; | ||
stacksKeys[stackId].push(valueField); | ||
}); | ||
// Stack cannot consist of single series. | ||
Object.keys(stacksKeys).forEach(function (stackId) { | ||
if (stacksKeys[stackId].length === 1) { | ||
delete stacksKeys[stackId]; | ||
} | ||
}); | ||
return [stacksKeys, seriesPositions]; | ||
}; | ||
var getStackedData = function getStackedData(stacksKeys, dataItems, offset, order) { | ||
var result = {}; | ||
Object.keys(stacksKeys).forEach(function (stackId) { | ||
result[stackId] = d3Shape.stack().keys(stacksKeys[stackId]).order(order).offset(offset)(dataItems); | ||
}); | ||
return result; | ||
}; | ||
var buildStackedSeries = function buildStackedSeries(series, dataItems) { | ||
var points = series.points.map(function (point) { | ||
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 }); | ||
}); | ||
var stackedSeries = _extends({}, series, { | ||
points: points | ||
}); | ||
if (series.isStartedFromZero) { | ||
stackedSeries.getPointTransformer = getStackedPointTransformer(series.getPointTransformer); | ||
stackedSeries.getValueDomain = getValueDomain; | ||
} | ||
return [].concat(toConsumableArray(series), [seriesProps]); | ||
return stackedSeries; | ||
}; | ||
var getPieItems = function getPieItems(series, domain) { | ||
return domain.map(function (uniqueName) { | ||
return { uniqueName: uniqueName }; | ||
var applyStacking = function applyStacking(seriesList, dataItems, seriesToStackMap, offset, order) { | ||
var _collectStacks = collectStacks(seriesList, seriesToStackMap), | ||
_collectStacks2 = slicedToArray(_collectStacks, 2), | ||
stacksKeys = _collectStacks2[0], | ||
seriesPositions = _collectStacks2[1]; | ||
if (Object.keys(stacksKeys).length === 0) { | ||
return seriesList; | ||
} | ||
var stackedData = getStackedData(stacksKeys, dataItems, offset, order); | ||
return seriesList.map(function (seriesItem) { | ||
var stackId = seriesToStackMap[seriesItem.name]; | ||
var stackData = stackedData[stackId]; | ||
if (!stackData) { | ||
return seriesItem; | ||
} | ||
var position = seriesPositions[seriesItem.name]; | ||
return buildStackedSeries(seriesItem, stackData[position]); | ||
}); | ||
}; | ||
var getStacks = function getStacks(series) { | ||
return series.reduce(function (prevValue, _ref, index) { | ||
var valueField = _ref.valueField, | ||
seriesStack = _ref.stack; | ||
var getGroupName = function getGroupName(series, i, seriesToStackMap) { | ||
var stackId = seriesToStackMap[series.name]; | ||
return stackId >= 0 ? String(stackId) : 'group-' + i; | ||
}; | ||
if (!prevValue[seriesStack]) { | ||
return _extends({}, prevValue, defineProperty({}, seriesStack, { | ||
keys: [valueField], | ||
series: [index] | ||
})); | ||
var getGroupedPointTransformer = function getGroupedPointTransformer(getPointTransformer, groupCount, groupOffset) { | ||
var wrapper = function wrapper(series) { | ||
var transform = getPointTransformer(series); | ||
var barWidth = series.barWidth; | ||
var widthCoeff = 1 / groupCount; | ||
var offsetCoeff = -(1 - barWidth) / 2 + groupOffset + widthCoeff * (1 - barWidth) / 2; | ||
return function (point) { | ||
var ret = transform(point); | ||
ret.x += ret.width / barWidth * offsetCoeff; | ||
ret.width *= widthCoeff; | ||
return ret; | ||
}; | ||
}; | ||
// Preserve static fields of original transformer. | ||
Object.assign(wrapper, getPointTransformer); | ||
return wrapper; | ||
}; | ||
var applyGrouping = function applyGrouping(seriesList, seriesToStackMap) { | ||
var groups = new Set(); | ||
seriesList.forEach(function (seriesItem, i) { | ||
if (seriesItem.getPointTransformer.isBroad) { | ||
groups.add(getGroupName(seriesItem, i, seriesToStackMap)); | ||
} | ||
return _extends({}, prevValue, defineProperty({}, seriesStack, { | ||
keys: [].concat(toConsumableArray(prevValue[seriesStack].keys), [valueField]), | ||
series: [].concat(toConsumableArray(prevValue[seriesStack].series), [index]) | ||
})); | ||
}, {}); | ||
}); | ||
// There cannot be single group. | ||
if (groups.size < 2) { | ||
return seriesList; | ||
} | ||
var scale = d3Scale.scaleBand().domain(Array.from(groups)).range([0, 1]); | ||
return seriesList.map(function (seriesItem, i) { | ||
if (!seriesItem.getPointTransformer.isBroad) { | ||
return seriesItem; | ||
} | ||
var getPointTransformer = getGroupedPointTransformer(seriesItem.getPointTransformer, groups.size, scale(getGroupName(seriesItem, i, seriesToStackMap))); | ||
return _extends({}, seriesItem, { | ||
getPointTransformer: getPointTransformer | ||
}); | ||
}); | ||
}; | ||
var filtering = function filtering(_ref2) { | ||
var seriesStack = _ref2.stack; | ||
return seriesStack; | ||
var getStackedSeries = function getStackedSeries(seriesList, dataItems, _ref3) { | ||
var stacks = _ref3.stacks, | ||
offset = _ref3.offset, | ||
order = _ref3.order; | ||
var map = buildSeriesToStackMap(stacks); | ||
var stackedSeriesList = applyStacking(seriesList, dataItems, map, offset, order); | ||
var groupedSeriesList = applyGrouping(stackedSeriesList, map); | ||
return groupedSeriesList; | ||
}; | ||
var processData = function processData(offset, order) { | ||
return function (series, data) { | ||
var stacks = getStacks(series); | ||
var ANIMATIONS = Symbol('animation'); | ||
var arrayOfStacks = Object.entries(stacks).reduce(function (prevValue, item) { | ||
return _extends({}, prevValue, defineProperty({}, item[0], d3Shape.stack().keys(item[1].keys).order(order).offset(offset)(data))); | ||
}, {}); | ||
var addKeyframe = function addKeyframe(name, def) { | ||
if (typeof document === 'undefined') { | ||
return; | ||
} | ||
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'; | ||
style.dataset[ANIMATIONS] = true; | ||
head.appendChild(style); | ||
} | ||
var content = style.textContent; | ||
if (!content.includes(name)) { | ||
style.textContent += '\n@keyframes ' + name + ' ' + def + '\n'; | ||
} | ||
}; | ||
return data.map(function (singleData, dataIndex) { | ||
return series.reduce(function (prevValue, _ref3, index) { | ||
var valueField = _ref3.valueField, | ||
name = _ref3.name, | ||
seriesStack = _ref3.stack; | ||
var getAreaAnimationName = function getAreaAnimationName() { | ||
var name = 'animation_transform'; | ||
addKeyframe(name, '{ from { transform: scaleY(0); } }'); | ||
return name; | ||
}; | ||
var seriesIndex = stacks[seriesStack].series.findIndex(function (item) { | ||
return item === index; | ||
var getScatterAnimationName = function getScatterAnimationName() { | ||
var name = 'animation_scatter'; | ||
addKeyframe(name, '{ 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1 } }'); | ||
return name; | ||
}; | ||
var getPieAnimationName = function getPieAnimationName() { | ||
var name = 'animation_pie'; | ||
addKeyframe(name, '{ from { transform: scale(0); } }'); | ||
return name; | ||
}; | ||
var getDefaultAreaAnimationOptions = function getDefaultAreaAnimationOptions() { | ||
return '1s'; | ||
}; | ||
var getDefaultPieAnimationOptions = function getDefaultPieAnimationOptions(_ref) { | ||
var index = _ref.index; | ||
return 0.7 + index * 0.1 + 's'; | ||
}; | ||
var getAreaAnimationStyle = function getAreaAnimationStyle(scales) { | ||
var animationStyle = { | ||
transformOrigin: '0px ' + scales.yScale.copy().clamp(true)(0) + 'px' | ||
}; | ||
var options = getDefaultAreaAnimationOptions(); | ||
return _extends({ | ||
animation: getAreaAnimationName() + ' ' + options | ||
}, animationStyle); | ||
}; | ||
var getPieAnimationStyle = function getPieAnimationStyle(scales, point) { | ||
var options = getDefaultPieAnimationOptions(point); | ||
return { | ||
animation: getPieAnimationName() + ' ' + options | ||
}; | ||
}; | ||
var getScatterAnimationStyle = function getScatterAnimationStyle() { | ||
var options = getDefaultAreaAnimationOptions(); | ||
return { | ||
animation: getScatterAnimationName() + ' ' + options | ||
}; | ||
}; | ||
var buildAnimatedStyleGetter = function buildAnimatedStyleGetter(style, getAnimationStyle, scales, point) { | ||
var animationStyle = getAnimationStyle(scales, point); | ||
return _extends({}, animationStyle, style); | ||
}; | ||
var isPointInRect = function isPointInRect(x, y, x1, x2, y1, y2) { | ||
return x1 <= x && x <= x2 && y1 <= y && y <= y2; | ||
}; | ||
var LINE_TOLERANCE = 10; | ||
// 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) { | ||
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); | ||
}); | ||
return _extends({}, prevValue, defineProperty({}, valueField + '-' + name + '-stack', arrayOfStacks[seriesStack][seriesIndex][dataIndex])); | ||
}, singleData); | ||
}); | ||
if (point) { | ||
hit.point = point.index; | ||
} | ||
} | ||
return hit; | ||
}; | ||
}; | ||
}; | ||
var seriesWithStacks = function seriesWithStacks(series) { | ||
return series.reduce(function (prevResult, singleSeries, index) { | ||
var _singleSeries$stack = singleSeries.stack, | ||
seriesStack = _singleSeries$stack === undefined ? 'stack' + index : _singleSeries$stack; | ||
var createAreaHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
var path = d3Shape.area(); | ||
path.x(dArea.x()); | ||
path.y1(dArea.y1()); | ||
path.y0(dArea.y0()); | ||
return path; | ||
}); | ||
var createLineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
var path = d3Shape.area(); | ||
var getY = dLine.y(); | ||
path.x(dLine.x()); | ||
path.y1(function (point) { | ||
return getY(point) - LINE_TOLERANCE; | ||
}); | ||
path.y0(function (point) { | ||
return getY(point) + LINE_TOLERANCE; | ||
}); | ||
return path; | ||
}); | ||
return [].concat(toConsumableArray(prevResult), [_extends({}, singleSeries, { stack: seriesStack })]); | ||
}, []); | ||
var createSplineHitTester = createCanvasAbusingHitTesterCreator(function () { | ||
var path = d3Shape.area(); | ||
var getY = dSpline.y(); | ||
path.x(dSpline.x()); | ||
path.y1(function (point) { | ||
return getY(point) - LINE_TOLERANCE; | ||
}); | ||
path.y0(function (point) { | ||
return getY(point) + LINE_TOLERANCE; | ||
}); | ||
path.curve(dSpline.curve()); | ||
return path; | ||
}); | ||
var createBarHitTester = function createBarHitTester(coordinates) { | ||
return function (_ref4) { | ||
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 stacks = function stacks(series) { | ||
return [].concat(toConsumableArray(new Set(series.filter(function (singleSeries) { | ||
return filtering(singleSeries); | ||
}).map(function (_ref4) { | ||
var seriesStack = _ref4.stack; | ||
return seriesStack; | ||
})))); | ||
// 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 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 palette = function palette(series, scheme) { | ||
return d3Scale.scaleOrdinal().domain(series.map(function (_ref) { | ||
var uniqueName = _ref.uniqueName; | ||
return uniqueName; | ||
})).range(scheme); | ||
var mapAngleTod3 = function mapAngleTod3(angle) { | ||
var ret = angle + Math.PI / 2; | ||
return ret >= 0 ? ret : ret + Math.PI * 2; | ||
}; | ||
var prepareData = function prepareData(data, series, processingData) { | ||
return processingData ? processingData(series, data) : data.map(function (singleData) { | ||
return series.reduce(function (prevValue, _ref) { | ||
var valueField = _ref.valueField, | ||
name = _ref.name; | ||
var createPieHitTester = function createPieHitTester(coordinates) { | ||
return function (_ref10) { | ||
var _ref11 = slicedToArray(_ref10, 2), | ||
px = _ref11[0], | ||
py = _ref11[1]; | ||
if (singleData[valueField] === undefined) { | ||
return prevValue; | ||
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 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; | ||
}; | ||
}; | ||
return _extends({}, prevValue, defineProperty({}, valueField + "-" + name + "-stack", [0, singleData[valueField]])); | ||
}, singleData); | ||
var buildFilter = function buildFilter(targets) { | ||
var result = {}; | ||
targets.forEach(function (_ref13) { | ||
var series = _ref13.series, | ||
point = _ref13.point; | ||
result[series] = result[series] || { points: {} }; | ||
if (point >= 0) { | ||
result[series].points[point] = true; | ||
} else { | ||
result[series].self = true; | ||
} | ||
}); | ||
return result; | ||
}; | ||
exports.getValueDomainName = getValueDomainName; | ||
var changeSeriesState = function changeSeriesState(seriesList, targets, state) { | ||
if (targets.length === 0) { | ||
return seriesList; | ||
} | ||
var filter = buildFilter(targets); | ||
var matches = 0; | ||
var result = seriesList.map(function (seriesItem) { | ||
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 _extends({}, seriesItem, props); | ||
}); | ||
// This is to prevent false rerenders. | ||
return matches > 0 ? result : seriesList; | ||
}; | ||
var getDefaultLegendItems = function getDefaultLegendItems(series) { | ||
return series.map(function (_ref) { | ||
var text = _ref.uniqueName, | ||
color = _ref.color; | ||
return { text: text, color: color }; | ||
}); | ||
}; | ||
var getPieLegendItems = function getPieLegendItems(series) { | ||
return series[0].points.map(function (_ref2) { | ||
var text = _ref2.id, | ||
color = _ref2.color; | ||
return { text: text, color: color }; | ||
}); | ||
}; | ||
// 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) { | ||
return series.length === 1 && series[0].seriesComponent.name === 'SliceCollection'; | ||
}; | ||
var getLegendItems = function getLegendItems(series) { | ||
return (isSinglePieSeriesCase(series) ? getPieLegendItems : getDefaultLegendItems)(series); | ||
}; | ||
// This function is called from event handlers (when DOM is available) - | ||
// *window* can be accessed safely. | ||
var getEventCoords = function getEventCoords(e) { | ||
var _window = window, | ||
pageXOffset = _window.pageXOffset, | ||
pageYOffset = _window.pageYOffset; // eslint-disable-line no-undef | ||
var _e$currentTarget$getB = e.currentTarget.getBoundingClientRect(), | ||
left = _e$currentTarget$getB.left, | ||
top = _e$currentTarget$getB.top; | ||
return [e.clientX - left - pageXOffset, e.clientY - top - pageYOffset]; | ||
}; | ||
var buildEventHandler = function buildEventHandler(seriesList, handlers) { | ||
var hitTesters = null; | ||
var createHitTesters = function createHitTesters() { | ||
var obj = {}; | ||
seriesList.forEach(function (seriesItem) { | ||
obj[seriesItem.symbolName] = seriesItem.createHitTester(seriesItem.points); | ||
}); | ||
return obj; | ||
}; | ||
return function (e) { | ||
var location = getEventCoords(e); | ||
hitTesters = hitTesters || createHitTesters(); | ||
var targets = []; | ||
seriesList.forEach(function (seriesItem) { | ||
var status = hitTesters[seriesItem.symbolName](location); | ||
if (status) { | ||
targets.push(_extends({ series: seriesItem.name }, status)); | ||
} | ||
}); | ||
var arg = { location: location, targets: targets }; | ||
handlers.forEach(function (handler) { | ||
return handler(arg); | ||
}); | ||
}; | ||
}; | ||
var buildLeaveEventHandler = function buildLeaveEventHandler(handlers) { | ||
return function (e) { | ||
var location = getEventCoords(e); | ||
var arg = { location: location, targets: [] }; | ||
handlers.forEach(function (handler) { | ||
return handler(arg); | ||
}); | ||
}; | ||
}; | ||
var buildEventHandlers = function buildEventHandlers(seriesList, _ref) { | ||
var clickHandlers = _ref.clickHandlers, | ||
pointerMoveHandlers = _ref.pointerMoveHandlers; | ||
var handlers = {}; | ||
if (clickHandlers.length) { | ||
handlers.click = buildEventHandler(seriesList, clickHandlers); | ||
} | ||
if (pointerMoveHandlers.length) { | ||
handlers.pointermove = buildEventHandler(seriesList, pointerMoveHandlers); | ||
handlers.pointerleave = buildLeaveEventHandler(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; | ||
exports.computeDomains = computeDomains; | ||
exports.buildScales = buildScales; | ||
exports.bBoxes = bBoxes; | ||
@@ -578,13 +1137,29 @@ exports.axisCoordinates = axisCoordinates; | ||
exports.dSpline = dSpline; | ||
exports.xyScales = xyScales; | ||
exports.pieAttributes = pieAttributes; | ||
exports.coordinates = coordinates; | ||
exports.barCoordinates = barCoordinates; | ||
exports.getPiePointTransformer = getPiePointTransformer; | ||
exports.getAreaPointTransformer = getAreaPointTransformer; | ||
exports.getBarPointTransformer = getBarPointTransformer; | ||
exports.findSeriesByName = findSeriesByName; | ||
exports.dBar = dBar; | ||
exports.pointAttributes = pointAttributes; | ||
exports.seriesData = seriesData; | ||
exports.getPieItems = getPieItems; | ||
exports.addSeries = addSeries; | ||
exports.scaleSeriesPoints = scaleSeriesPoints; | ||
exports.getStackedSeries = getStackedSeries; | ||
exports.getAreaAnimationStyle = getAreaAnimationStyle; | ||
exports.getPieAnimationStyle = getPieAnimationStyle; | ||
exports.getScatterAnimationStyle = getScatterAnimationStyle; | ||
exports.buildAnimatedStyleGetter = buildAnimatedStyleGetter; | ||
exports.createAreaHitTester = createAreaHitTester; | ||
exports.createLineHitTester = createLineHitTester; | ||
exports.createSplineHitTester = createSplineHitTester; | ||
exports.createBarHitTester = createBarHitTester; | ||
exports.createScatterHitTester = createScatterHitTester; | ||
exports.createPieHitTester = createPieHitTester; | ||
exports.changeSeriesState = changeSeriesState; | ||
exports.createScale = createScale; | ||
exports.getWidth = getWidth; | ||
exports.getValueDomainName = getValueDomainName; | ||
exports.getLegendItems = getLegendItems; | ||
exports.buildEventHandlers = buildEventHandlers; | ||
exports.processPointerMove = processPointerMove; | ||
exports.getHoverTargets = getHoverTargets; | ||
exports.HORIZONTAL = HORIZONTAL; | ||
@@ -603,7 +1178,4 @@ exports.VERTICAL = VERTICAL; | ||
exports.VALUE_DOMAIN = VALUE_DOMAIN; | ||
exports.processData = processData; | ||
exports.seriesWithStacks = seriesWithStacks; | ||
exports.stacks = stacks; | ||
exports.palette = palette; | ||
exports.prepareData = prepareData; | ||
exports.HOVERED = HOVERED; | ||
exports.SELECTED = SELECTED; | ||
@@ -610,0 +1182,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
{ | ||
"name": "@devexpress/dx-chart-core", | ||
"version": "1.8.0", | ||
"version": "1.9.0", | ||
"description": "Core library for the DevExtreme Reactive Chart component", | ||
@@ -43,3 +43,3 @@ "author": { | ||
"babel-core": "^6.26.3", | ||
"babel-jest": "^23.4.2", | ||
"babel-jest": "^23.6.0", | ||
"babel-plugin-external-helpers": "^6.22.0", | ||
@@ -50,9 +50,9 @@ "babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"core-js": "^2.5.7", | ||
"eslint": "^5.6.1", | ||
"eslint": "^5.8.0", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-plugin-filenames": "^1.3.2", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-jest": "^21.24.0", | ||
"eslint-plugin-jest": "^21.26.2", | ||
"jest": "^23.6.0", | ||
"rollup": "^0.66.2", | ||
"rollup": "^0.66.6", | ||
"rollup-plugin-babel": "^3.0.4", | ||
@@ -66,3 +66,3 @@ "rollup-plugin-license": "^0.7.0" | ||
}, | ||
"gitHead": "30dd98f003c170e60ce6eb79d48fe4e3ac99338d" | ||
"gitHead": "227293d65d3fc8972ff36981be7ec6789876dbe7" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
200525
1980
1