@antv/g2plot
Version:
G2 Plot, a market of plots built with the Grammar of Graphics'
951 lines • 43.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var _ = tslib_1.__importStar(require("@antv/util"));
var domUtil = tslib_1.__importStar(require("@antv/dom-util"));
var g2_1 = require("@antv/g2");
var theme_1 = tslib_1.__importDefault(require("@antv/component/lib/tooltip/theme"));
var global_1 = require("../../base/global");
var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer"));
var factory_1 = require("../../geoms/factory");
require("./theme");
require("./component/label/funnel-label");
require("./animation/funnel-scale-in-x");
require("./animation/funnel-scale-in-y");
require("./geometry/shape/funnel-basic-rect");
require("./geometry/shape/funnel-dynamic-rect");
var funnel_label_parser_1 = tslib_1.__importDefault(require("./component/label/funnel-label-parser"));
function lerp(a, b, factor) {
return (1 - factor) * a + factor * b;
}
var G2_GEOM_MAP = {
column: 'interval',
};
var PLOT_GEOM_MAP = {
interval: 'funnel',
};
var FunnelLayer = /** @class */ (function (_super) {
tslib_1.__extends(FunnelLayer, _super);
function FunnelLayer(props) {
var _this = _super.call(this, props) || this;
_this.type = 'funnel';
_this.legendsListenerAttached = false;
_this.shouldShowLabels = false;
_this.shouldResetPercentages = true;
_this.shouldResetCompareTexts = true;
_this._onLegendContainerMouseDown = function (e) {
var props = _this.options;
if (e.target.name == 'legend-item') {
_this.refreshPercentages();
if (props.dynamicHeight) {
var data = _this._findCheckedDataByMouseDownLegendItem(e.target);
_this._genCustomFieldForDynamicHeight(data);
}
if (props.compareField) {
var data = _this._findCheckedDataByMouseDownLegendItem(e.target);
_this._updateDataForCompare(data);
_this.refreshCompareTexts();
}
}
};
_this.adjustProps(_this.options);
if (props.dynamicHeight) {
_this._genCustomFieldForDynamicHeight(_this.getData());
}
if (props.compareField) {
_this.options.data = _this._reduceDataForCompare(_this.getData());
}
return _this;
}
FunnelLayer.getDefaultOptions = function (props) {
var cfg = {
label: {
visible: true,
adjustColor: true,
formatter: props && (props.compareField || props.transpose)
? function (xValue, item, idx, yValue, yValueTop) { return "" + yValue; }
: function (xValue, item, idx, yValue, yValueTop) { return xValue + " " + yValue; },
},
percentage: {
visible: true,
offsetX: props.transpose ? 0 : 40,
offsetY: props.transpose ? 40 : 0,
spacing: 4,
line: {
visible: true,
style: {
lineWidth: 1,
stroke: 'rgba(0, 0, 0, 0.15)',
},
},
text: {
content: '转化率',
style: {
fill: 'rgba(0, 0, 0, 0.65)',
},
},
value: {
visible: true,
style: {
fill: 'black',
},
formatter: function (yValueUpper, yValueLower) { return ((100 * yValueLower) / yValueUpper).toFixed(2) + "%"; },
},
},
tooltip: {
visible: true,
shared: true,
showTitle: false,
crosshairs: {
type: 'cross',
style: {
stroke: null,
},
},
},
animation: _.deepMix({}, g2_1.Animate.defaultCfg, {
appear: {
duration: 800,
},
}),
dynamicHeight: false,
compareText: {
visible: true,
offsetX: -16,
offsetY: -16,
style: {
fill: 'black',
},
},
};
return _.deepMix({}, _super.getDefaultOptions.call(this), cfg);
};
FunnelLayer.prototype.coord = function () {
var props = this.options;
var coordConfig = {
actions: props.transpose
? props.dynamicHeight
? [['transpose'], ['scale', 1, -1]]
: [['scale', 1, -1]]
: props.dynamicHeight
? []
: [['transpose'], ['scale', 1, -1]],
};
this.setConfig('coord', coordConfig);
};
FunnelLayer.prototype.axis = function () {
this.setConfig('axes', false);
};
FunnelLayer.prototype.adjustFunnel = function (funnel) {
var props = this.options;
funnel.shape = {
values: [props.dynamicHeight ? 'funnel-dynamic-rect' : 'funnel-basic-rect'],
};
funnel.color = {
fields: [props.xField],
values: props.color && (Array.isArray(props.color) ? props.color : [props.color]),
};
if (_.isFunction(props.funnelStyle)) {
// @ts-ignore
funnel.style = { callback: props.funnelStyle };
}
else {
// @ts-ignore
funnel.style = { cfg: props.funnelStyle };
}
funnel.adjust = [
{
type: props.dynamicHeight ? 'stack' : 'symmetric',
},
];
};
FunnelLayer.prototype.tooltip = function () {
var props = this.options;
if (props.compareField) {
_.deepMix(props.tooltip, {
htmlContent: function (title, items) {
var clss, el, color, elMarker;
clss = 'g2-tooltip';
el = domUtil.createDom("<div class=\"" + clss + "\"></div>");
domUtil.modifyCSS(el, theme_1.default[clss]);
var elRoot = el;
if (title) {
clss = 'g2-tooltip-title';
el = domUtil.createDom("<div class=\"" + clss + "\"></div>");
domUtil.modifyCSS(el, theme_1.default[clss]);
elRoot.appendChild(el);
var elTitle = el;
clss = 'g2-tooltip-marker';
el = domUtil.createDom("<span class=\"" + clss + "\"></span>");
domUtil.modifyCSS(el, theme_1.default[clss]);
domUtil.modifyCSS(el, { width: '10px', height: '10px' });
elTitle.appendChild(el);
elMarker = el;
el = domUtil.createDom("<span>" + title + "</span>");
elTitle.appendChild(el);
}
if (items) {
clss = 'g2-tooltip-list';
el = domUtil.createDom("<ul class=\"" + clss + "\"></ul>");
domUtil.modifyCSS(el, theme_1.default[clss]);
elRoot.appendChild(el);
var elList_1 = el;
items
.reduce(function (pairs, item) {
if (!color) {
color = item.color;
}
var compareValues = _.get(item, 'point._origin.__compare__.compareValues');
var yValues = _.get(item, 'point._origin.__compare__.yValues');
yValues.forEach(function (yValue, i) { return pairs.push([compareValues[i], yValue]); });
return pairs;
}, [])
.forEach(function (_a, index) {
var compareValue = _a[0], yValue = _a[1];
clss = 'g2-tooltip-list-item';
el = domUtil.createDom("<li class=\"" + clss + "\" data-index=" + index + "></li>");
domUtil.modifyCSS(el, theme_1.default[clss]);
elList_1.appendChild(el);
var elListItem = el;
el = domUtil.createDom("<span>" + compareValue + "</span>");
elListItem.appendChild(el);
clss = 'g2-tooltip-value';
el = domUtil.createDom("<span class=\"" + clss + "\">" + yValue + "</span>");
domUtil.modifyCSS(el, theme_1.default[clss]);
elListItem.appendChild(el);
});
}
if (color && elMarker) {
domUtil.modifyCSS(elMarker, { backgroundColor: color });
}
return elRoot;
},
});
}
_super.prototype.tooltip.call(this);
};
FunnelLayer.prototype.addGeometry = function () {
var props = this.options;
var funnel = factory_1.getGeom('interval', 'main', {
positionFields: [props.dynamicHeight ? '_' : props.xField, props.yField],
plot: this,
});
if (props.label) {
funnel.label = this.extractLabel();
}
this.adjustFunnel(funnel);
this.funnel = funnel;
this.setConfig('element', funnel);
};
FunnelLayer.prototype.animation = function () {
var _this = this;
var props = this.options;
if (props.animation === false) {
/** 关闭动画 */
this.funnel.animate = false;
this.shouldShowLabels = true;
}
else {
var appearDuration = _.get(props, 'animation.appear.duration');
var appearDurationEach_1 = appearDuration / (this.getData().length || 1);
if (this.animationAppearTimeoutHandler) {
clearTimeout(this.animationAppearTimeoutHandler);
delete this.animationAppearTimeoutHandler;
}
this.animationAppearTimeoutHandler = setTimeout(function () {
_this._teardownAnimationMask();
_this.shouldShowLabels = true;
_this.fadeInPercentages(appearDurationEach_1);
if (props.compareField) {
_this.fadeInCompareTexts(appearDurationEach_1);
}
delete _this.animationAppearTimeoutHandler;
}, appearDuration);
this.funnel.animate = _.deepMix({}, props.animation, {
appear: {
animation: props.transpose ? 'funnelScaleInX' : 'funnelScaleInY',
duration: appearDurationEach_1,
reverse: props.dynamicHeight && !props.transpose,
callback: function (shape) {
_this.shouldShowLabels = true;
_this.showLabels(shape);
},
},
});
}
};
FunnelLayer.prototype.geometryParser = function (dim, type) {
if (dim === 'g2') {
return G2_GEOM_MAP[type];
}
return PLOT_GEOM_MAP[type];
};
FunnelLayer.prototype.afterRender = function () {
var props = this.options;
this.resetPercentages();
if (props.compareField) {
this.resetCompareTexts();
}
if (props.padding == 'auto') {
var percentageContainer = this._findPercentageContainer();
if (percentageContainer) {
this.paddingController.registerPadding(percentageContainer, 'inner', true);
}
var compareTextContainer = this._findCompareTextContainer();
if (compareTextContainer) {
this.paddingController.registerPadding(compareTextContainer, 'inner', true);
}
}
_super.prototype.afterRender.call(this);
if (this.animationAppearTimeoutHandler) {
this._setupAnimationMask();
if (props.compareField) {
this.fadeInCompareTexts();
}
}
this.showLabels();
if (props.animation === false) {
this.fadeInPercentages();
if (props.compareField) {
this.fadeInCompareTexts();
}
}
if (!this.legendsListenerAttached) {
this.legendsListenerAttached = true;
var legendContainer = this.view.get('legendController').container;
legendContainer.on('mousedown', this._onLegendContainerMouseDown);
}
};
FunnelLayer.prototype.updateConfig = function (cfg) {
cfg = this.adjustProps(cfg);
_super.prototype.updateConfig.call(this, cfg);
this.legendsListenerAttached = false;
this.shouldShowLabels = false;
};
FunnelLayer.prototype.changeData = function (data) {
var props = this.options;
if (props.animation !== false) {
this.shouldResetPercentages = false;
this.shouldResetCompareTexts = false;
}
if (props.dynamicHeight) {
var checkedData = this._findCheckedDataInNewData(data);
this._genCustomFieldForDynamicHeight(checkedData);
}
if (props.compareField) {
data = this._reduceDataForCompare(data);
var checkedData = this._findCheckedDataInNewData(data);
this._updateDataForCompare(checkedData);
}
_super.prototype.changeData.call(this, data);
this.refreshPercentages();
if (props.compareField) {
this.refreshCompareTexts();
}
this._refreshAnimationMaskForPercentageRefresh();
};
FunnelLayer.prototype.extractLabel = function () {
var props = this.options;
var label = props.label;
if (label && label.visible === false) {
return false;
}
var labelConfig = new funnel_label_parser_1.default(_.deepMix({
textStyle: {
stroke: null,
},
}, label, {
plot: this,
labelType: 'funnelLabel',
position: 'middle',
textStyle: {
opacity: 0,
},
fields: [props.xField, props.yField],
})).getConfig();
return labelConfig;
};
FunnelLayer.prototype.showLabels = function (shape) {
if (!this.shouldShowLabels)
return;
this.view.get('elements').forEach(function (element) {
var labelsContainer = element.get('labelController').labelsContainer;
if (labelsContainer) {
labelsContainer
.get('labelsRenderer')
.get('group')
.get('children')
.forEach(function (label) {
if (shape) {
if (element.getShapeId(label.get('origin')) == shape.id) {
label.attr('opacity', 1);
}
}
else {
label.attr('opacity', 1);
}
});
}
});
};
FunnelLayer.prototype.adjustProps = function (props) {
if (props.compareField) {
props.dynamicHeight = false;
}
if (props.dynamicHeight) {
_.set(props, "meta." + props.yField + ".nice", false);
_.set(props, 'tooltip.shared', false);
}
return props;
};
FunnelLayer.prototype.resetPercentages = function () {
var _this = this;
if (!this.shouldResetPercentages)
return;
var props = this.options;
var _a = props.percentage || {}, offsetX = _a.offsetX, offsetY = _a.offsetY, spacing = _a.spacing, _b = _a.line, percentageLine = _b === void 0 ? {} : _b, _c = _a.text, percentageText = _c === void 0 ? {} : _c, _d = _a.value, percentageValue = _d === void 0 ? {} : _d;
var adjustTimestamp = Date.now();
var container = this._findPercentageContainer(true);
var coord = this.view.get('coord');
var i = 0;
var datumUpper;
this.view.eachShape(function (datumLower, shape) {
if (i++ > 0) {
var _a = shape.getBBox(), minX = _a.minX, maxX = _a.maxX, maxY = _a.maxY, minY = _a.minY;
var _b = coord.invertMatrix(props.transpose ? minX : maxX, props.transpose ? (props.compareField ? minY : maxY) : props.dynamicHeight ? minY : maxY, 1), x1 = _b[0], y1 = _b[1];
var _c = _this._findPercentageMembersInContainerByShape(container, shape, true), line_1 = _c.line, text_1 = _c.text, value_1 = _c.value;
var eachProcs_1 = [
function (x, y, line, text, value) {
if (line) {
line.attr(_.deepMix({}, percentageLine.style, {
x1: x,
y1: y,
x2: props.transpose ? x + offsetX : x - offsetX,
y2: y - offsetY,
opacity: 0,
}));
line.set('adjustTimestamp', adjustTimestamp);
}
var textWidth = 0;
var valueWidth = 0;
var textProc = function () {
if (text) {
text.attr(_.deepMix({}, percentageText.style, {
x: props.transpose ? x + offsetX : x - offsetX - spacing - valueWidth - spacing,
y: props.transpose ? y - offsetY - spacing : y - offsetY,
opacity: 0,
text: percentageText.content,
textAlign: props.transpose ? 'left' : 'right',
textBaseline: props.transpose ? 'bottom' : 'middle',
}));
text.set('adjustTimestamp', adjustTimestamp);
textWidth = text.getBBox().width;
}
};
var valueProc = function () {
if (value) {
value.attr(_.deepMix({}, percentageValue.style, {
x: props.transpose ? x + offsetX + textWidth + spacing : x - offsetX - spacing,
y: props.transpose ? y - offsetY - spacing : y - offsetY,
opacity: 0,
text: _.isFunction(percentageValue.formatter)
? props.compareField
? percentageValue.formatter(_.get(datumUpper, '__compare__.yValues.0'), _.get(datumLower, '__compare__.yValues.0'))
: percentageValue.formatter(datumUpper[props.yField], datumLower[props.yField])
: '',
textAlign: props.transpose ? 'left' : 'right',
textBaseline: props.transpose ? 'bottom' : 'middle',
}));
value.set('adjustTimestamp', adjustTimestamp);
valueWidth = value.getBBox().width;
}
};
if (props.transpose) {
textProc();
valueProc();
}
else {
valueProc();
textProc();
}
},
function (x, y, line, text, value) {
if (line) {
line.attr(_.deepMix({}, percentageLine.style, {
x1: x,
y1: y,
x2: x + offsetX,
y2: props.transpose ? (props.compareField ? y + offsetY : y - offsetY) : y + offsetY,
opacity: 0,
}));
line.set('adjustTimestamp', adjustTimestamp);
}
var textWidth = 0;
if (text) {
text.attr(_.deepMix({}, percentageText.style, {
x: props.transpose ? x + offsetX : x + offsetX + spacing,
y: props.transpose
? props.compareField
? y + offsetY + spacing
: y - offsetY - spacing
: y + offsetY,
opacity: 0,
text: percentageText.content,
textAlign: 'left',
textBaseline: props.transpose ? (props.compareField ? 'top' : 'bottom') : 'middle',
}));
text.set('adjustTimestamp', adjustTimestamp);
textWidth = text.getBBox().width;
}
if (value) {
value.attr(_.deepMix({}, percentageValue.style, {
x: props.transpose ? x + offsetX + textWidth + spacing : x + offsetX + spacing + textWidth + spacing,
y: props.transpose
? props.compareField
? y + offsetY + spacing
: y - offsetY - spacing
: y + offsetY,
opacity: 0,
text: _.isFunction(percentageValue.formatter)
? props.compareField
? percentageValue.formatter(_.get(datumUpper, "__compare__.yValues.1"), _.get(datumLower, "__compare__.yValues.1"))
: percentageValue.formatter(datumUpper[props.yField], datumLower[props.yField])
: '',
textAlign: 'left',
textBaseline: props.transpose ? (props.compareField ? 'top' : 'bottom') : 'middle',
}));
value.set('adjustTimestamp', adjustTimestamp);
}
},
];
if (props.compareField) {
var _d = coord.invertMatrix(minX, maxY, 1), x0 = _d[0], y0 = _d[1];
[
[x0, y0],
[x1, y1],
].forEach(function (_a, i) {
var x = _a[0], y = _a[1];
return eachProcs_1[i](x, y, line_1 && line_1[i], text_1 && text_1[i], value_1 && value_1[i]);
});
}
else {
eachProcs_1[1](x1, y1, line_1, text_1, value_1);
}
}
datumUpper = datumLower;
});
container.get('children').forEach(function (child) {
if (child.get('adjustTimestamp') != adjustTimestamp) {
child.attr({ opacity: 0 });
container.set(child.get('id'), null);
setTimeout(function () { return child.remove(); });
}
});
};
FunnelLayer.prototype.fadeInPercentages = function (duration, callback) {
var _this = this;
var props = this.options;
var container = this._findPercentageContainer();
var eachProc = function (i) {
var lastBBox = { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity };
_this.view.eachShape(function (datum, shape) {
var members = _this._findPercentageMembersInContainerByShape(container, shape);
var currBBox = { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity };
var eachCalc = function (member) {
if (member && member.get('type') == 'text') {
var _a = member.getBBox(), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY;
if (minX < currBBox.minX)
currBBox.minX = minX;
if (maxX > currBBox.maxX)
currBBox.maxX = maxX;
if (minY < currBBox.minY)
currBBox.minY = minY;
if (maxY > currBBox.maxY)
currBBox.maxY = maxY;
}
};
_.each(members, function (member) { return (_.isArray(member) ? eachCalc(member[i]) : eachCalc(member)); });
if (currBBox.minX > lastBBox.maxX ||
currBBox.maxX < lastBBox.minX ||
currBBox.minY > lastBBox.maxY ||
currBBox.maxY < lastBBox.minY) {
var eachShow_1 = function (member) {
if (member) {
var attrs = {
opacity: 1,
};
duration ? member.animate(attrs, duration) : member.attr(attrs);
}
};
_.each(members, function (member) { return (_.isArray(member) ? eachShow_1(member[i]) : eachShow_1(member)); });
_.assign(lastBBox, currBBox);
}
});
};
props.compareField ? [0, 1].forEach(eachProc) : eachProc();
duration && callback && setTimeout(callback, duration);
};
FunnelLayer.prototype.fadeOutPercentages = function (duration, callback) {
var _this = this;
var container = this._findPercentageContainer();
this.view.eachShape(function (datum, shape) {
var members = _this._findPercentageMembersInContainerByShape(container, shape);
var eachProc = function (member) {
if (member) {
var attrs = {
opacity: 0,
};
duration ? member.animate(attrs, duration) : member.attr(attrs);
}
};
_.each(members, function (member) { return (_.isArray(member) ? member.forEach(eachProc) : eachProc(member)); });
});
duration && callback && setTimeout(callback, duration);
};
FunnelLayer.prototype.refreshPercentages = function (callback) {
var _this = this;
var props = this.options;
if (props.animation !== false) {
var _a = this._calcRefreshFadeDurations(), fadeOutDuration = _a.fadeOutDuration, fadeInDuration_1 = _a.fadeInDuration;
this.shouldResetPercentages = false;
this.fadeOutPercentages(fadeOutDuration, function () {
_this.shouldResetPercentages = true;
_this.resetPercentages();
_this.fadeInPercentages(fadeInDuration_1, callback);
});
}
};
FunnelLayer.prototype._calcRefreshFadeDurations = function () {
var props = this.options;
var updateDuration = _.get(props, 'animation.update.duration');
var enterDuration = _.get(props, 'animation.enter.duration');
var fadeInDuration = Math.min(enterDuration, updateDuration) * 0.6;
var fadeOutDuration = Math.max(enterDuration, updateDuration) * 1.2;
return { fadeInDuration: fadeInDuration, fadeOutDuration: fadeOutDuration };
};
FunnelLayer.prototype._findPercentageContainer = function (createIfNotFound) {
if (createIfNotFound === void 0) { createIfNotFound = false; }
var percentageContainer;
if (this.view) {
var elements = this.view.get('elements');
elements.find(function (element) {
return (percentageContainer = element.get('percentageContainer'));
});
if (!percentageContainer && createIfNotFound) {
if (elements.length) {
var element = elements[0];
percentageContainer = element.get('container').addGroup();
element.set('percentageContainer', percentageContainer);
}
}
}
return percentageContainer;
};
FunnelLayer.prototype._findPercentageMembersInContainerByShape = function (container, shape, createIfNotFound) {
if (createIfNotFound === void 0) { createIfNotFound = false; }
var props = this.options;
var _a = props.percentage || {}, visible = _a.visible, _b = _a.line, percentageLine = _b === void 0 ? {} : _b, _c = _a.text, percentageText = _c === void 0 ? {} : _c, _d = _a.value, percentageValue = _d === void 0 ? {} : _d;
var members = {
line: undefined,
text: undefined,
value: undefined,
};
if (visible === false || !container) {
return members;
}
if (percentageLine.visible !== false) {
var find = function (i) {
var lineId = "_percentage-line-" + shape.id + "-" + i;
var line = container.get(lineId);
if (!line && createIfNotFound) {
line = container.addShape('line', { id: lineId });
container.set(lineId, line);
}
return line;
};
var line = props.compareField ? [0, 1].map(find) : find(0);
members.line = line;
}
if (percentageText.visible !== false) {
var find = function (i) {
var textId = "_percentage-text-" + shape.id + "-" + i;
var text = container.get(textId);
if (!text && createIfNotFound) {
text = container.addShape('text', { id: textId });
container.set(textId, text);
}
return text;
};
var text = props.compareField ? [0, 1].map(find) : find(0);
members.text = text;
}
if (percentageValue.visible !== false) {
var find = function (i) {
var valueId = "_percentage-value-" + shape.id + "-" + i;
var value = container.get(valueId);
if (!value && createIfNotFound) {
value = container.addShape('text', { id: valueId });
container.set(valueId, value);
}
return value;
};
var value = props.compareField ? [0, 1].map(find) : find(0);
members.value = value;
}
return members;
};
FunnelLayer.prototype._genCustomFieldForDynamicHeight = function (data) {
var props = this.options;
var total = data.reduce(function (total, datum) { return total + datum[props.yField]; }, 0);
var ratioUpper = 1;
data.forEach(function (datum, index) {
var value = datum[props.yField];
var share = value / total;
var ratioLower = ratioUpper - share;
datum['__custom__'] = {
datumIndex: index,
dataLength: data.length,
ratioUpper: ratioUpper,
ratioLower: ratioLower,
reverse: props.transpose,
};
ratioUpper = ratioLower;
});
};
FunnelLayer.prototype.resetCompareTexts = function () {
if (!this.shouldResetCompareTexts)
return;
var props = this.options;
var shapeParentBBox;
var compare;
var targetDatum = this._findCheckedData(this.getData())[0];
this.view.eachShape(function (datum, shape) {
if (datum == targetDatum) {
shapeParentBBox = shape.get('parent').getBBox();
compare = _.get(datum, '__compare__');
}
});
if (shapeParentBBox && compare && _.get(props, 'compareText.visible') !== false) {
var coord = this.view.get('coord');
var container_1 = this._findCompareTextContainer(true);
var yValuesMax_1 = compare.yValuesMax, compareValues_1 = compare.compareValues;
var pStart = coord.invertMatrix(shapeParentBBox.minX, shapeParentBBox.minY, 1);
var pEnd = coord.invertMatrix(shapeParentBBox.maxX, shapeParentBBox.maxY, 1);
var minX_1 = Math.min(pStart[0], pEnd[0]);
var maxX_1 = Math.max(pStart[0], pEnd[0]);
var minY_1 = Math.min(pStart[1], pEnd[1]);
var maxY_1 = Math.max(pStart[1], pEnd[1]);
var compareTexts_1 = container_1.get('children');
[0, 1].forEach(function (i) {
var compareText = compareTexts_1[i];
if (!compareText) {
compareText = container_1.addShape('text');
}
compareText.attr(_.deepMix({}, _.get(props, 'compareText.style'), {
text: props.transpose ? compareValues_1[i] : i ? " " + compareValues_1[i] : compareValues_1[i] + " ",
x: props.transpose
? minX_1 + _.get(props, 'compareText.offsetX')
: lerp(minX_1, maxX_1, yValuesMax_1[0] / (yValuesMax_1[0] + yValuesMax_1[1])),
y: props.transpose
? lerp(minY_1, maxY_1, yValuesMax_1[0] / (yValuesMax_1[0] + yValuesMax_1[1])) + (i ? 8 : -8)
: minY_1 + _.get(props, 'compareText.offsetY'),
opacity: 0,
textAlign: props.transpose ? 'right' : i ? 'left' : 'right',
textBaseline: props.transpose ? (i ? 'top' : 'bottom') : 'bottom',
}));
});
}
};
FunnelLayer.prototype.fadeInCompareTexts = function (duration, callback) {
var container = this._findCompareTextContainer();
if (container) {
var compareTexts_2 = container.get('children');
[0, 1].forEach(function (i) {
var compareText = compareTexts_2[i];
if (compareText) {
var attrs = {
opacity: 1,
};
duration ? compareText.animate(attrs, duration) : compareText.attr(attrs);
}
});
}
duration && callback && setTimeout(callback, duration);
};
FunnelLayer.prototype.fadeOutCompareTexts = function (duration, callback) {
var container = this._findCompareTextContainer();
if (container) {
var compareTexts_3 = container.get('children');
[0, 1].forEach(function (i) {
var compareText = compareTexts_3[i];
if (compareText) {
var attrs = {
opacity: 0,
};
duration ? compareText.animate(attrs, duration) : compareText.attr(attrs);
}
});
}
duration && callback && setTimeout(callback, duration);
};
FunnelLayer.prototype.refreshCompareTexts = function (callback) {
var _this = this;
var props = this.options;
if (props.animation !== false) {
var _a = this._calcRefreshFadeDurations(), fadeInDuration_2 = _a.fadeInDuration, fadeOutDuration = _a.fadeOutDuration;
this.shouldResetCompareTexts = false;
this.fadeOutCompareTexts(fadeOutDuration, function () {
_this.shouldResetCompareTexts = true;
_this.resetCompareTexts();
_this.fadeInCompareTexts(fadeInDuration_2, callback);
});
}
};
FunnelLayer.prototype._findCompareTextContainer = function (createIfNotFound) {
if (createIfNotFound === void 0) { createIfNotFound = false; }
var compareTextContainer;
if (this.view) {
var elements = this.view.get('elements');
elements.find(function (element) {
return (compareTextContainer = element.get('compareTextContainer'));
});
if (!compareTextContainer && createIfNotFound) {
if (elements.length) {
var element = elements[0];
compareTextContainer = element.get('container').addGroup();
element.set('compareTextContainer', compareTextContainer);
}
}
}
return compareTextContainer;
};
FunnelLayer.prototype._reduceDataForCompare = function (data) {
var props = this.options;
var compareValueFirstVisited;
var yValuesMax = [-Infinity, -Infinity];
data = data.reduce(function (newData, datum) {
var _a;
var xValue = datum[props.xField];
var yValue = datum[props.yField];
var compareValue = datum[props.compareField];
if (!compareValueFirstVisited)
compareValueFirstVisited = compareValue;
var newDatum = newData.find(function (newDatum) { return newDatum[props.xField] == xValue; });
if (!newDatum) {
newDatum = (_a = {},
_a[props.xField] = xValue,
_a[props.yField] = 0,
_a['__compare__'] = {
compareValues: [],
yValues: [],
yValuesMax: [],
yValuesNext: undefined,
transpose: props.transpose,
},
_a);
newData.push(newDatum);
}
var idx = compareValue == compareValueFirstVisited ? 0 : 1;
newDatum['__compare__'].yValues[idx] = yValue;
if (yValuesMax[idx] < yValue) {
yValuesMax[idx] = yValue;
}
newDatum['__compare__'].compareValues[idx] = compareValue;
return newData;
}, []);
data.forEach(function (datum, index) {
datum[props.yField] = _.get(datum, '__compare__.yValues', []).reduce(function (yTotal, yValue) { return (yTotal += yValue); }, 0);
_.set(datum, '__compare__.yValuesMax', yValuesMax);
_.set(datum, '__compare__.yValuesNext', _.get(data, index + 1 + ".__compare__.yValues"));
});
return data;
};
FunnelLayer.prototype._updateDataForCompare = function (data) {
var yValuesMax = [-Infinity, -Infinity];
data.forEach(function (datum) {
var yValues = _.get(datum, '__compare__.yValues');
[0, 1].forEach(function (i) {
if (yValues[i] > yValuesMax[i]) {
yValuesMax[i] = yValues[i];
}
});
});
data.forEach(function (datum, index) {
_.set(datum, '__compare__.yValuesMax', yValuesMax);
_.set(datum, '__compare__.yValuesNext', _.get(data, index + 1 + ".__compare__.yValues"));
});
};
FunnelLayer.prototype._findCheckedData = function (data) {
var props = this.options;
var legendValues = this.view
.get('canvas')
.findAll(function (shape) { return shape.name == 'legend-item' && shape.get('parent').get('checked'); })
.map(function (shape) { return shape.get('origin').value; });
return data.filter(function (datum) { return _.contains(legendValues, datum[props.xField]); });
};
FunnelLayer.prototype._findCheckedDataInNewData = function (newData) {
var props = this.options;
var legendValues = this.view
.get('canvas')
.findAll(function (shape) { return shape.name == 'legend-item' && shape.get('parent').get('checked'); })
.map(function (shape) { return shape.get('origin').value; });
var oldData = this.getData();
var uncheckedValues = oldData
.map(function (oldDatum) { return oldDatum[props.xField]; })
.filter(function (xValue) { return !_.contains(legendValues, xValue); });
return newData.filter(function (newDatum) { return !_.contains(uncheckedValues, newDatum[props.xField]); });
};
FunnelLayer.prototype._findCheckedDataByMouseDownLegendItem = function (legendItem) {
var props = this.options;
var legendItemOrigin = legendItem.get('origin');
var brotherValues = legendItem
.get('parent')
.get('parent')
.findAll(function (shape) { return shape != legendItem && shape.name == 'legend-item' && shape.get('parent').get('checked'); })
.map(function (shape) { return shape.get('origin').value; });
var data = [];
this.getData().forEach(function (datum) {
var xValue = datum[props.xField];
if ((legendItemOrigin.value == xValue && !legendItem.get('parent').get('checked')) ||
_.contains(brotherValues, xValue)) {
data.push(datum);
}
});
return data;
};
FunnelLayer.prototype._setupAnimationMask = function () {
var canvas = this.view.get('canvas');
var animationMask = canvas.get('animation-mask');
if (!animationMask) {
animationMask = canvas.addShape('rect');
canvas.set('animation-mask', animationMask);
}
animationMask.attr({
x: 0,
y: 0,
fill: 'transparent',
width: canvas.get('width'),
height: canvas.get('height'),
});
};
FunnelLayer.prototype._teardownAnimationMask = function () {
var canvas = this.view.get('canvas');
var animationMask = canvas.get('animation-mask');
if (animationMask) {
animationMask.attr({ x: -canvas.get('width') });
}
};
FunnelLayer.prototype._refreshAnimationMaskForPercentageRefresh = function () {
var _this = this;
var props = this.options;
if (props.animation !== false) {
var _a = this._calcRefreshFadeDurations(), fadeOutDuration = _a.fadeOutDuration, fadeInDuration = _a.fadeInDuration;
this._setupAnimationMask();
setTimeout(function () { return _this._teardownAnimationMask(); }, fadeOutDuration + fadeInDuration);
}
};
return FunnelLayer;
}(view_layer_1.default));
exports.default = FunnelLayer;
global_1.registerPlotType('funnel', FunnelLayer);
//# sourceMappingURL=layer.js.map