This commit is contained in:
2025-11-03 17:03:57 +08:00
commit 7a04b85667
16804 changed files with 2492292 additions and 0 deletions

46
frontend/node_modules/echarts/lib/component/aria.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './aria/install.js';
use(install);

View File

@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import ariaVisual from '../../visual/aria.js';
import ariaPreprocessor from './preprocessor.js';
export function install(registers) {
registers.registerPreprocessor(ariaPreprocessor);
registers.registerVisual(registers.PRIORITY.VISUAL.ARIA, ariaVisual);
}

View File

@@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
export default function ariaPreprocessor(option) {
if (!option || !option.aria) {
return;
}
var aria = option.aria;
// aria.show is deprecated and should use aria.enabled instead
if (aria.show != null) {
aria.enabled = aria.show;
}
aria.label = aria.label || {};
// move description, general, series, data to be under aria.label
zrUtil.each(['description', 'general', 'series', 'data'], function (name) {
if (aria[name] != null) {
aria.label[name] = aria[name];
}
});
}

View File

@@ -0,0 +1,323 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import { createTextStyle } from '../../label/labelStyle.js';
import Model from '../../model/Model.js';
import AxisView from './AxisView.js';
import AxisBuilder from './AxisBuilder.js';
import { getECData } from '../../util/innerStore.js';
var elementList = ['axisLine', 'axisLabel', 'axisTick', 'minorTick', 'splitLine', 'minorSplitLine', 'splitArea'];
function getAxisLineShape(polar, rExtent, angle) {
rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse());
var start = polar.coordToPoint([rExtent[0], angle]);
var end = polar.coordToPoint([rExtent[1], angle]);
return {
x1: start[0],
y1: start[1],
x2: end[0],
y2: end[1]
};
}
function getRadiusIdx(polar) {
var radiusAxis = polar.getRadiusAxis();
return radiusAxis.inverse ? 0 : 1;
}
// Remove the last tick which will overlap the first tick
function fixAngleOverlap(list) {
var firstItem = list[0];
var lastItem = list[list.length - 1];
if (firstItem && lastItem && Math.abs(Math.abs(firstItem.coord - lastItem.coord) - 360) < 1e-4) {
list.pop();
}
}
var AngleAxisView = /** @class */function (_super) {
__extends(AngleAxisView, _super);
function AngleAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = AngleAxisView.type;
_this.axisPointerClass = 'PolarAxisPointer';
return _this;
}
AngleAxisView.prototype.render = function (angleAxisModel, ecModel) {
this.group.removeAll();
if (!angleAxisModel.get('show')) {
return;
}
var angleAxis = angleAxisModel.axis;
var polar = angleAxis.polar;
var radiusExtent = polar.getRadiusAxis().getExtent();
var ticksAngles = angleAxis.getTicksCoords();
var minorTickAngles = angleAxis.getMinorTicksCoords();
var labels = zrUtil.map(angleAxis.getViewLabels(), function (labelItem) {
labelItem = zrUtil.clone(labelItem);
var scale = angleAxis.scale;
var tickValue = scale.type === 'ordinal' ? scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue;
labelItem.coord = angleAxis.dataToCoord(tickValue);
return labelItem;
});
fixAngleOverlap(labels);
fixAngleOverlap(ticksAngles);
zrUtil.each(elementList, function (name) {
if (angleAxisModel.get([name, 'show']) && (!angleAxis.scale.isBlank() || name === 'axisLine')) {
angelAxisElementsBuilders[name](this.group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels);
}
}, this);
};
AngleAxisView.type = 'angleAxis';
return AngleAxisView;
}(AxisView);
var angelAxisElementsBuilders = {
axisLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
var lineStyleModel = angleAxisModel.getModel(['axisLine', 'lineStyle']);
var angleAxis = polar.getAngleAxis();
var RADIAN = Math.PI / 180;
var angleExtent = angleAxis.getExtent();
// extent id of the axis radius (r0 and r)
var rId = getRadiusIdx(polar);
var r0Id = rId ? 0 : 1;
var shape;
var shapeType = Math.abs(angleExtent[1] - angleExtent[0]) === 360 ? 'Circle' : 'Arc';
if (radiusExtent[r0Id] === 0) {
shape = new graphic[shapeType]({
shape: {
cx: polar.cx,
cy: polar.cy,
r: radiusExtent[rId],
startAngle: -angleExtent[0] * RADIAN,
endAngle: -angleExtent[1] * RADIAN,
clockwise: angleAxis.inverse
},
style: lineStyleModel.getLineStyle(),
z2: 1,
silent: true
});
} else {
shape = new graphic.Ring({
shape: {
cx: polar.cx,
cy: polar.cy,
r: radiusExtent[rId],
r0: radiusExtent[r0Id]
},
style: lineStyleModel.getLineStyle(),
z2: 1,
silent: true
});
}
shape.style.fill = null;
group.add(shape);
},
axisTick: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
var tickModel = angleAxisModel.getModel('axisTick');
var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
var radius = radiusExtent[getRadiusIdx(polar)];
var lines = zrUtil.map(ticksAngles, function (tickAngleItem) {
return new graphic.Line({
shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord)
});
});
group.add(graphic.mergePath(lines, {
style: zrUtil.defaults(tickModel.getModel('lineStyle').getLineStyle(), {
stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color'])
})
}));
},
minorTick: function (group, angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) {
if (!minorTickAngles.length) {
return;
}
var tickModel = angleAxisModel.getModel('axisTick');
var minorTickModel = angleAxisModel.getModel('minorTick');
var tickLen = (tickModel.get('inside') ? -1 : 1) * minorTickModel.get('length');
var radius = radiusExtent[getRadiusIdx(polar)];
var lines = [];
for (var i = 0; i < minorTickAngles.length; i++) {
for (var k = 0; k < minorTickAngles[i].length; k++) {
lines.push(new graphic.Line({
shape: getAxisLineShape(polar, [radius, radius + tickLen], minorTickAngles[i][k].coord)
}));
}
}
group.add(graphic.mergePath(lines, {
style: zrUtil.defaults(minorTickModel.getModel('lineStyle').getLineStyle(), zrUtil.defaults(tickModel.getLineStyle(), {
stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color'])
}))
}));
},
axisLabel: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) {
var rawCategoryData = angleAxisModel.getCategories(true);
var commonLabelModel = angleAxisModel.getModel('axisLabel');
var labelMargin = commonLabelModel.get('margin');
var triggerEvent = angleAxisModel.get('triggerEvent');
// Use length of ticksAngles because it may remove the last tick to avoid overlapping
zrUtil.each(labels, function (labelItem, idx) {
var labelModel = commonLabelModel;
var tickValue = labelItem.tickValue;
var r = radiusExtent[getRadiusIdx(polar)];
var p = polar.coordToPoint([r + labelMargin, labelItem.coord]);
var cx = polar.cx;
var cy = polar.cy;
var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3 ? 'center' : p[0] > cx ? 'left' : 'right';
var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3 ? 'middle' : p[1] > cy ? 'top' : 'bottom';
if (rawCategoryData && rawCategoryData[tickValue]) {
var rawCategoryItem = rawCategoryData[tickValue];
if (zrUtil.isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
labelModel = new Model(rawCategoryItem.textStyle, commonLabelModel, commonLabelModel.ecModel);
}
}
var textEl = new graphic.Text({
silent: AxisBuilder.isLabelSilent(angleAxisModel),
style: createTextStyle(labelModel, {
x: p[0],
y: p[1],
fill: labelModel.getTextColor() || angleAxisModel.get(['axisLine', 'lineStyle', 'color']),
text: labelItem.formattedLabel,
align: labelTextAlign,
verticalAlign: labelTextVerticalAlign
})
});
group.add(textEl);
// Pack data for mouse event
if (triggerEvent) {
var eventData = AxisBuilder.makeAxisEventDataBase(angleAxisModel);
eventData.targetType = 'axisLabel';
eventData.value = labelItem.rawLabel;
getECData(textEl).eventData = eventData;
}
}, this);
},
splitLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
var splitLineModel = angleAxisModel.getModel('splitLine');
var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineColors = lineStyleModel.get('color');
var lineCount = 0;
lineColors = lineColors instanceof Array ? lineColors : [lineColors];
var splitLines = [];
for (var i = 0; i < ticksAngles.length; i++) {
var colorIndex = lineCount++ % lineColors.length;
splitLines[colorIndex] = splitLines[colorIndex] || [];
splitLines[colorIndex].push(new graphic.Line({
shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i].coord)
}));
}
// Simple optimization
// Batching the lines if color are the same
for (var i = 0; i < splitLines.length; i++) {
group.add(graphic.mergePath(splitLines[i], {
style: zrUtil.defaults({
stroke: lineColors[i % lineColors.length]
}, lineStyleModel.getLineStyle()),
silent: true,
z: angleAxisModel.get('z')
}));
}
},
minorSplitLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
if (!minorTickAngles.length) {
return;
}
var minorSplitLineModel = angleAxisModel.getModel('minorSplitLine');
var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
var lines = [];
for (var i = 0; i < minorTickAngles.length; i++) {
for (var k = 0; k < minorTickAngles[i].length; k++) {
lines.push(new graphic.Line({
shape: getAxisLineShape(polar, radiusExtent, minorTickAngles[i][k].coord)
}));
}
}
group.add(graphic.mergePath(lines, {
style: lineStyleModel.getLineStyle(),
silent: true,
z: angleAxisModel.get('z')
}));
},
splitArea: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
if (!ticksAngles.length) {
return;
}
var splitAreaModel = angleAxisModel.getModel('splitArea');
var areaStyleModel = splitAreaModel.getModel('areaStyle');
var areaColors = areaStyleModel.get('color');
var lineCount = 0;
areaColors = areaColors instanceof Array ? areaColors : [areaColors];
var splitAreas = [];
var RADIAN = Math.PI / 180;
var prevAngle = -ticksAngles[0].coord * RADIAN;
var r0 = Math.min(radiusExtent[0], radiusExtent[1]);
var r1 = Math.max(radiusExtent[0], radiusExtent[1]);
var clockwise = angleAxisModel.get('clockwise');
for (var i = 1, len = ticksAngles.length; i <= len; i++) {
var coord = i === len ? ticksAngles[0].coord : ticksAngles[i].coord;
var colorIndex = lineCount++ % areaColors.length;
splitAreas[colorIndex] = splitAreas[colorIndex] || [];
splitAreas[colorIndex].push(new graphic.Sector({
shape: {
cx: polar.cx,
cy: polar.cy,
r0: r0,
r: r1,
startAngle: prevAngle,
endAngle: -coord * RADIAN,
clockwise: clockwise
},
silent: true
}));
prevAngle = -coord * RADIAN;
}
// Simple optimization
// Batching the lines if color are the same
for (var i = 0; i < splitAreas.length; i++) {
group.add(graphic.mergePath(splitAreas[i], {
style: zrUtil.defaults({
fill: areaColors[i % areaColors.length]
}, areaStyleModel.getAreaStyle()),
silent: true
}));
}
}
};
export default AngleAxisView;

View File

@@ -0,0 +1,585 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { retrieve, defaults, extend, each, isObject, map, isString, isNumber, isFunction, retrieve2 } from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import { getECData } from '../../util/innerStore.js';
import { createTextStyle } from '../../label/labelStyle.js';
import Model from '../../model/Model.js';
import { isRadianAroundZero, remRadian } from '../../util/number.js';
import { createSymbol, normalizeSymbolOffset } from '../../util/symbol.js';
import * as matrixUtil from 'zrender/lib/core/matrix.js';
import { applyTransform as v2ApplyTransform } from 'zrender/lib/core/vector.js';
import { shouldShowAllLabels } from '../../coord/axisHelper.js';
import { prepareLayoutList, hideOverlap } from '../../label/labelLayoutHelper.js';
var PI = Math.PI;
/**
* A final axis is translated and rotated from a "standard axis".
* So opt.position and opt.rotation is required.
*
* A standard axis is and axis from [0, 0] to [0, axisExtent[1]],
* for example: (0, 0) ------------> (0, 50)
*
* nameDirection or tickDirection or labelDirection is 1 means tick
* or label is below the standard axis, whereas is -1 means above
* the standard axis. labelOffset means offset between label and axis,
* which is useful when 'onZero', where axisLabel is in the grid and
* label in outside grid.
*
* Tips: like always,
* positive rotation represents anticlockwise, and negative rotation
* represents clockwise.
* The direction of position coordinate is the same as the direction
* of screen coordinate.
*
* Do not need to consider axis 'inverse', which is auto processed by
* axis extent.
*/
var AxisBuilder = /** @class */function () {
function AxisBuilder(axisModel, opt) {
this.group = new graphic.Group();
this.opt = opt;
this.axisModel = axisModel;
// Default value
defaults(opt, {
labelOffset: 0,
nameDirection: 1,
tickDirection: 1,
labelDirection: 1,
silent: true,
handleAutoShown: function () {
return true;
}
});
// FIXME Not use a separate text group?
var transformGroup = new graphic.Group({
x: opt.position[0],
y: opt.position[1],
rotation: opt.rotation
});
// this.group.add(transformGroup);
// this._transformGroup = transformGroup;
transformGroup.updateTransform();
this._transformGroup = transformGroup;
}
AxisBuilder.prototype.hasBuilder = function (name) {
return !!builders[name];
};
AxisBuilder.prototype.add = function (name) {
builders[name](this.opt, this.axisModel, this.group, this._transformGroup);
};
AxisBuilder.prototype.getGroup = function () {
return this.group;
};
AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
var rotationDiff = remRadian(textRotation - axisRotation);
var textAlign;
var textVerticalAlign;
if (isRadianAroundZero(rotationDiff)) {
// Label is parallel with axis line.
textVerticalAlign = direction > 0 ? 'top' : 'bottom';
textAlign = 'center';
} else if (isRadianAroundZero(rotationDiff - PI)) {
// Label is inverse parallel with axis line.
textVerticalAlign = direction > 0 ? 'bottom' : 'top';
textAlign = 'center';
} else {
textVerticalAlign = 'middle';
if (rotationDiff > 0 && rotationDiff < PI) {
textAlign = direction > 0 ? 'right' : 'left';
} else {
textAlign = direction > 0 ? 'left' : 'right';
}
}
return {
rotation: rotationDiff,
textAlign: textAlign,
textVerticalAlign: textVerticalAlign
};
};
AxisBuilder.makeAxisEventDataBase = function (axisModel) {
var eventData = {
componentType: axisModel.mainType,
componentIndex: axisModel.componentIndex
};
eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
return eventData;
};
AxisBuilder.isLabelSilent = function (axisModel) {
var tooltipOpt = axisModel.get('tooltip');
return axisModel.get('silent')
// Consider mouse cursor, add these restrictions.
|| !(axisModel.get('triggerEvent') || tooltipOpt && tooltipOpt.show);
};
return AxisBuilder;
}();
;
var builders = {
axisLine: function (opt, axisModel, group, transformGroup) {
var shown = axisModel.get(['axisLine', 'show']);
if (shown === 'auto' && opt.handleAutoShown) {
shown = opt.handleAutoShown('axisLine');
}
if (!shown) {
return;
}
var extent = axisModel.axis.getExtent();
var matrix = transformGroup.transform;
var pt1 = [extent[0], 0];
var pt2 = [extent[1], 0];
var inverse = pt1[0] > pt2[0];
if (matrix) {
v2ApplyTransform(pt1, pt1, matrix);
v2ApplyTransform(pt2, pt2, matrix);
}
var lineStyle = extend({
lineCap: 'round'
}, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle());
var line = new graphic.Line({
shape: {
x1: pt1[0],
y1: pt1[1],
x2: pt2[0],
y2: pt2[1]
},
style: lineStyle,
strokeContainThreshold: opt.strokeContainThreshold || 5,
silent: true,
z2: 1
});
graphic.subPixelOptimizeLine(line.shape, line.style.lineWidth);
line.anid = 'line';
group.add(line);
var arrows = axisModel.get(['axisLine', 'symbol']);
if (arrows != null) {
var arrowSize = axisModel.get(['axisLine', 'symbolSize']);
if (isString(arrows)) {
// Use the same arrow for start and end point
arrows = [arrows, arrows];
}
if (isString(arrowSize) || isNumber(arrowSize)) {
// Use the same size for width and height
arrowSize = [arrowSize, arrowSize];
}
var arrowOffset = normalizeSymbolOffset(axisModel.get(['axisLine', 'symbolOffset']) || 0, arrowSize);
var symbolWidth_1 = arrowSize[0];
var symbolHeight_1 = arrowSize[1];
each([{
rotate: opt.rotation + Math.PI / 2,
offset: arrowOffset[0],
r: 0
}, {
rotate: opt.rotation - Math.PI / 2,
offset: arrowOffset[1],
r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1]))
}], function (point, index) {
if (arrows[index] !== 'none' && arrows[index] != null) {
var symbol = createSymbol(arrows[index], -symbolWidth_1 / 2, -symbolHeight_1 / 2, symbolWidth_1, symbolHeight_1, lineStyle.stroke, true);
// Calculate arrow position with offset
var r = point.r + point.offset;
var pt = inverse ? pt2 : pt1;
symbol.attr({
rotation: point.rotate,
x: pt[0] + r * Math.cos(opt.rotation),
y: pt[1] - r * Math.sin(opt.rotation),
silent: true,
z2: 11
});
group.add(symbol);
}
});
}
},
axisTickLabel: function (opt, axisModel, group, transformGroup) {
var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt);
var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt);
fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection);
// This bit fixes the label overlap issue for the time chart.
// See https://github.com/apache/echarts/issues/14266 for more.
if (axisModel.get(['axisLabel', 'hideOverlap'])) {
var labelList = prepareLayoutList(map(labelEls, function (label) {
return {
label: label,
priority: label.z2,
defaultAttr: {
ignore: label.ignore
}
};
}));
hideOverlap(labelList);
}
},
axisName: function (opt, axisModel, group, transformGroup) {
var name = retrieve(opt.axisName, axisModel.get('name'));
if (!name) {
return;
}
var nameLocation = axisModel.get('nameLocation');
var nameDirection = opt.nameDirection;
var textStyleModel = axisModel.getModel('nameTextStyle');
var gap = axisModel.get('nameGap') || 0;
var extent = axisModel.axis.getExtent();
var gapSignal = extent[0] > extent[1] ? -1 : 1;
var pos = [nameLocation === 'start' ? extent[0] - gapSignal * gap : nameLocation === 'end' ? extent[1] + gapSignal * gap : (extent[0] + extent[1]) / 2,
// Reuse labelOffset.
isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0];
var labelLayout;
var nameRotation = axisModel.get('nameRotate');
if (nameRotation != null) {
nameRotation = nameRotation * PI / 180; // To radian.
}
var axisNameAvailableWidth;
if (isNameLocationCenter(nameLocation)) {
labelLayout = AxisBuilder.innerTextLayout(opt.rotation, nameRotation != null ? nameRotation : opt.rotation,
// Adapt to axis.
nameDirection);
} else {
labelLayout = endTextLayout(opt.rotation, nameLocation, nameRotation || 0, extent);
axisNameAvailableWidth = opt.axisNameAvailableWidth;
if (axisNameAvailableWidth != null) {
axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation));
!isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null);
}
}
var textFont = textStyleModel.getFont();
var truncateOpt = axisModel.get('nameTruncate', true) || {};
var ellipsis = truncateOpt.ellipsis;
var maxWidth = retrieve(opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth);
var textEl = new graphic.Text({
x: pos[0],
y: pos[1],
rotation: labelLayout.rotation,
silent: AxisBuilder.isLabelSilent(axisModel),
style: createTextStyle(textStyleModel, {
text: name,
font: textFont,
overflow: 'truncate',
width: maxWidth,
ellipsis: ellipsis,
fill: textStyleModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']),
align: textStyleModel.get('align') || labelLayout.textAlign,
verticalAlign: textStyleModel.get('verticalAlign') || labelLayout.textVerticalAlign
}),
z2: 1
});
graphic.setTooltipConfig({
el: textEl,
componentModel: axisModel,
itemName: name
});
textEl.__fullText = name;
// Id for animation
textEl.anid = 'name';
if (axisModel.get('triggerEvent')) {
var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
eventData.targetType = 'axisName';
eventData.name = name;
getECData(textEl).eventData = eventData;
}
// FIXME
transformGroup.add(textEl);
textEl.updateTransform();
group.add(textEl);
textEl.decomposeTransform();
}
};
function endTextLayout(rotation, textPosition, textRotate, extent) {
var rotationDiff = remRadian(textRotate - rotation);
var textAlign;
var textVerticalAlign;
var inverse = extent[0] > extent[1];
var onLeft = textPosition === 'start' && !inverse || textPosition !== 'start' && inverse;
if (isRadianAroundZero(rotationDiff - PI / 2)) {
textVerticalAlign = onLeft ? 'bottom' : 'top';
textAlign = 'center';
} else if (isRadianAroundZero(rotationDiff - PI * 1.5)) {
textVerticalAlign = onLeft ? 'top' : 'bottom';
textAlign = 'center';
} else {
textVerticalAlign = 'middle';
if (rotationDiff < PI * 1.5 && rotationDiff > PI / 2) {
textAlign = onLeft ? 'left' : 'right';
} else {
textAlign = onLeft ? 'right' : 'left';
}
}
return {
rotation: rotationDiff,
textAlign: textAlign,
textVerticalAlign: textVerticalAlign
};
}
function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
if (shouldShowAllLabels(axisModel.axis)) {
return;
}
// If min or max are user set, we need to check
// If the tick on min(max) are overlap on their neighbour tick
// If they are overlapped, we need to hide the min(max) tick label
var showMinLabel = axisModel.get(['axisLabel', 'showMinLabel']);
var showMaxLabel = axisModel.get(['axisLabel', 'showMaxLabel']);
// FIXME
// Have not consider onBand yet, where tick els is more than label els.
labelEls = labelEls || [];
tickEls = tickEls || [];
var firstLabel = labelEls[0];
var nextLabel = labelEls[1];
var lastLabel = labelEls[labelEls.length - 1];
var prevLabel = labelEls[labelEls.length - 2];
var firstTick = tickEls[0];
var nextTick = tickEls[1];
var lastTick = tickEls[tickEls.length - 1];
var prevTick = tickEls[tickEls.length - 2];
if (showMinLabel === false) {
ignoreEl(firstLabel);
ignoreEl(firstTick);
} else if (isTwoLabelOverlapped(firstLabel, nextLabel)) {
if (showMinLabel) {
ignoreEl(nextLabel);
ignoreEl(nextTick);
} else {
ignoreEl(firstLabel);
ignoreEl(firstTick);
}
}
if (showMaxLabel === false) {
ignoreEl(lastLabel);
ignoreEl(lastTick);
} else if (isTwoLabelOverlapped(prevLabel, lastLabel)) {
if (showMaxLabel) {
ignoreEl(prevLabel);
ignoreEl(prevTick);
} else {
ignoreEl(lastLabel);
ignoreEl(lastTick);
}
}
}
function ignoreEl(el) {
el && (el.ignore = true);
}
function isTwoLabelOverlapped(current, next) {
// current and next has the same rotation.
var firstRect = current && current.getBoundingRect().clone();
var nextRect = next && next.getBoundingRect().clone();
if (!firstRect || !nextRect) {
return;
}
// When checking intersect of two rotated labels, we use mRotationBack
// to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`.
var mRotationBack = matrixUtil.identity([]);
matrixUtil.rotate(mRotationBack, mRotationBack, -current.rotation);
firstRect.applyTransform(matrixUtil.mul([], mRotationBack, current.getLocalTransform()));
nextRect.applyTransform(matrixUtil.mul([], mRotationBack, next.getLocalTransform()));
return firstRect.intersect(nextRect);
}
function isNameLocationCenter(nameLocation) {
return nameLocation === 'middle' || nameLocation === 'center';
}
function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, anidPrefix) {
var tickEls = [];
var pt1 = [];
var pt2 = [];
for (var i = 0; i < ticksCoords.length; i++) {
var tickCoord = ticksCoords[i].coord;
pt1[0] = tickCoord;
pt1[1] = 0;
pt2[0] = tickCoord;
pt2[1] = tickEndCoord;
if (tickTransform) {
v2ApplyTransform(pt1, pt1, tickTransform);
v2ApplyTransform(pt2, pt2, tickTransform);
}
// Tick line, Not use group transform to have better line draw
var tickEl = new graphic.Line({
shape: {
x1: pt1[0],
y1: pt1[1],
x2: pt2[0],
y2: pt2[1]
},
style: tickLineStyle,
z2: 2,
autoBatch: true,
silent: true
});
graphic.subPixelOptimizeLine(tickEl.shape, tickEl.style.lineWidth);
tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
tickEls.push(tickEl);
}
return tickEls;
}
function buildAxisMajorTicks(group, transformGroup, axisModel, opt) {
var axis = axisModel.axis;
var tickModel = axisModel.getModel('axisTick');
var shown = tickModel.get('show');
if (shown === 'auto' && opt.handleAutoShown) {
shown = opt.handleAutoShown('axisTick');
}
if (!shown || axis.scale.isBlank()) {
return;
}
var lineStyleModel = tickModel.getModel('lineStyle');
var tickEndCoord = opt.tickDirection * tickModel.get('length');
var ticksCoords = axis.getTicksCoords();
var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(lineStyleModel.getLineStyle(), {
stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
}), 'ticks');
for (var i = 0; i < ticksEls.length; i++) {
group.add(ticksEls[i]);
}
return ticksEls;
}
function buildAxisMinorTicks(group, transformGroup, axisModel, tickDirection) {
var axis = axisModel.axis;
var minorTickModel = axisModel.getModel('minorTick');
if (!minorTickModel.get('show') || axis.scale.isBlank()) {
return;
}
var minorTicksCoords = axis.getMinorTicksCoords();
if (!minorTicksCoords.length) {
return;
}
var lineStyleModel = minorTickModel.getModel('lineStyle');
var tickEndCoord = tickDirection * minorTickModel.get('length');
var minorTickLineStyle = defaults(lineStyleModel.getLineStyle(), defaults(axisModel.getModel('axisTick').getLineStyle(), {
stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
}));
for (var i = 0; i < minorTicksCoords.length; i++) {
var minorTicksEls = createTicks(minorTicksCoords[i], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i);
for (var k = 0; k < minorTicksEls.length; k++) {
group.add(minorTicksEls[k]);
}
}
}
function buildAxisLabel(group, transformGroup, axisModel, opt) {
var axis = axisModel.axis;
var show = retrieve(opt.axisLabelShow, axisModel.get(['axisLabel', 'show']));
if (!show || axis.scale.isBlank()) {
return;
}
var labelModel = axisModel.getModel('axisLabel');
var labelMargin = labelModel.get('margin');
var labels = axis.getViewLabels();
// Special label rotate.
var labelRotation = (retrieve(opt.labelRotate, labelModel.get('rotate')) || 0) * PI / 180;
var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true);
var labelEls = [];
var silent = AxisBuilder.isLabelSilent(axisModel);
var triggerEvent = axisModel.get('triggerEvent');
each(labels, function (labelItem, index) {
var tickValue = axis.scale.type === 'ordinal' ? axis.scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue;
var formattedLabel = labelItem.formattedLabel;
var rawLabel = labelItem.rawLabel;
var itemLabelModel = labelModel;
if (rawCategoryData && rawCategoryData[tickValue]) {
var rawCategoryItem = rawCategoryData[tickValue];
if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
itemLabelModel = new Model(rawCategoryItem.textStyle, labelModel, axisModel.ecModel);
}
}
var textColor = itemLabelModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']);
var tickCoord = axis.dataToCoord(tickValue);
var align = itemLabelModel.getShallow('align', true) || labelLayout.textAlign;
var alignMin = retrieve2(itemLabelModel.getShallow('alignMinLabel', true), align);
var alignMax = retrieve2(itemLabelModel.getShallow('alignMaxLabel', true), align);
var verticalAlign = itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign;
var verticalAlignMin = retrieve2(itemLabelModel.getShallow('verticalAlignMinLabel', true), verticalAlign);
var verticalAlignMax = retrieve2(itemLabelModel.getShallow('verticalAlignMaxLabel', true), verticalAlign);
var textEl = new graphic.Text({
x: tickCoord,
y: opt.labelOffset + opt.labelDirection * labelMargin,
rotation: labelLayout.rotation,
silent: silent,
z2: 10 + (labelItem.level || 0),
style: createTextStyle(itemLabelModel, {
text: formattedLabel,
align: index === 0 ? alignMin : index === labels.length - 1 ? alignMax : align,
verticalAlign: index === 0 ? verticalAlignMin : index === labels.length - 1 ? verticalAlignMax : verticalAlign,
fill: isFunction(textColor) ? textColor(
// (1) In category axis with data zoom, tick is not the original
// index of axis.data. So tick should not be exposed to user
// in category axis.
// (2) Compatible with previous version, which always use formatted label as
// input. But in interval scale the formatted label is like '223,445', which
// maked user replace ','. So we modify it to return original val but remain
// it as 'string' to avoid error in replacing.
axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, index) : textColor
})
});
textEl.anid = 'label_' + tickValue;
graphic.setTooltipConfig({
el: textEl,
componentModel: axisModel,
itemName: formattedLabel,
formatterParamsExtra: {
isTruncated: function () {
return textEl.isTruncated;
},
value: rawLabel,
tickIndex: index
}
});
// Pack data for mouse event
if (triggerEvent) {
var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
eventData.targetType = 'axisLabel';
eventData.value = rawLabel;
eventData.tickIndex = index;
if (axis.type === 'category') {
eventData.dataIndex = tickValue;
}
getECData(textEl).eventData = eventData;
}
// FIXME
transformGroup.add(textEl);
textEl.updateTransform();
labelEls.push(textEl);
group.add(textEl);
textEl.decomposeTransform();
});
return labelEls;
}
export default AxisBuilder;

View File

@@ -0,0 +1,119 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as axisPointerModelHelper from '../axisPointer/modelHelper.js';
import ComponentView from '../../view/Component.js';
var axisPointerClazz = {};
/**
* Base class of AxisView.
*/
var AxisView = /** @class */function (_super) {
__extends(AxisView, _super);
function AxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = AxisView.type;
return _this;
}
/**
* @override
*/
AxisView.prototype.render = function (axisModel, ecModel, api, payload) {
// FIXME
// This process should proformed after coordinate systems updated
// (axis scale updated), and should be performed each time update.
// So put it here temporarily, although it is not appropriate to
// put a model-writing procedure in `view`.
this.axisPointerClass && axisPointerModelHelper.fixValue(axisModel);
_super.prototype.render.apply(this, arguments);
this._doUpdateAxisPointerClass(axisModel, api, true);
};
/**
* Action handler.
*/
AxisView.prototype.updateAxisPointer = function (axisModel, ecModel, api, payload) {
this._doUpdateAxisPointerClass(axisModel, api, false);
};
/**
* @override
*/
AxisView.prototype.remove = function (ecModel, api) {
var axisPointer = this._axisPointer;
axisPointer && axisPointer.remove(api);
};
/**
* @override
*/
AxisView.prototype.dispose = function (ecModel, api) {
this._disposeAxisPointer(api);
_super.prototype.dispose.apply(this, arguments);
};
AxisView.prototype._doUpdateAxisPointerClass = function (axisModel, api, forceRender) {
var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass);
if (!Clazz) {
return;
}
var axisPointerModel = axisPointerModelHelper.getAxisPointerModel(axisModel);
axisPointerModel ? (this._axisPointer || (this._axisPointer = new Clazz())).render(axisModel, axisPointerModel, api, forceRender) : this._disposeAxisPointer(api);
};
AxisView.prototype._disposeAxisPointer = function (api) {
this._axisPointer && this._axisPointer.dispose(api);
this._axisPointer = null;
};
AxisView.registerAxisPointerClass = function (type, clazz) {
if (process.env.NODE_ENV !== 'production') {
if (axisPointerClazz[type]) {
throw new Error('axisPointer ' + type + ' exists');
}
}
axisPointerClazz[type] = clazz;
};
;
AxisView.getAxisPointerClass = function (type) {
return type && axisPointerClazz[type];
};
;
AxisView.type = 'axis';
return AxisView;
}(ComponentView);
export default AxisView;

View File

@@ -0,0 +1,237 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import AxisBuilder from './AxisBuilder.js';
import AxisView from './AxisView.js';
import * as cartesianAxisHelper from '../../coord/cartesian/cartesianAxisHelper.js';
import { rectCoordAxisBuildSplitArea, rectCoordAxisHandleRemove } from './axisSplitHelper.js';
import { isIntervalOrLogScale } from '../../scale/helper.js';
var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName'];
var selfBuilderAttrs = ['splitArea', 'splitLine', 'minorSplitLine'];
var CartesianAxisView = /** @class */function (_super) {
__extends(CartesianAxisView, _super);
function CartesianAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = CartesianAxisView.type;
_this.axisPointerClass = 'CartesianAxisPointer';
return _this;
}
/**
* @override
*/
CartesianAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
this.group.removeAll();
var oldAxisGroup = this._axisGroup;
this._axisGroup = new graphic.Group();
this.group.add(this._axisGroup);
if (!axisModel.get('show')) {
return;
}
var gridModel = axisModel.getCoordSysModel();
var layout = cartesianAxisHelper.layout(gridModel, axisModel);
var axisBuilder = new AxisBuilder(axisModel, zrUtil.extend({
handleAutoShown: function (elementType) {
var cartesians = gridModel.coordinateSystem.getCartesians();
for (var i = 0; i < cartesians.length; i++) {
if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) {
// Still show axis tick or axisLine if other axis is value / log
return true;
}
}
// Not show axisTick or axisLine if other axis is category / time
return false;
}
}, layout));
zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
this._axisGroup.add(axisBuilder.getGroup());
zrUtil.each(selfBuilderAttrs, function (name) {
if (axisModel.get([name, 'show'])) {
axisElementBuilders[name](this, this._axisGroup, axisModel, gridModel);
}
}, this);
// THIS is a special case for bar racing chart.
// Update the axis label from the natural initial layout to
// sorted layout should has no animation.
var isInitialSortFromBarRacing = payload && payload.type === 'changeAxisOrder' && payload.isInitSort;
if (!isInitialSortFromBarRacing) {
graphic.groupTransition(oldAxisGroup, this._axisGroup, axisModel);
}
_super.prototype.render.call(this, axisModel, ecModel, api, payload);
};
CartesianAxisView.prototype.remove = function () {
rectCoordAxisHandleRemove(this);
};
CartesianAxisView.type = 'cartesianAxis';
return CartesianAxisView;
}(AxisView);
var axisElementBuilders = {
splitLine: function (axisView, axisGroup, axisModel, gridModel) {
var axis = axisModel.axis;
if (axis.scale.isBlank()) {
return;
}
var splitLineModel = axisModel.getModel('splitLine');
var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineColors = lineStyleModel.get('color');
var showMinLine = splitLineModel.get('showMinLine') !== false;
var showMaxLine = splitLineModel.get('showMaxLine') !== false;
lineColors = zrUtil.isArray(lineColors) ? lineColors : [lineColors];
var gridRect = gridModel.coordinateSystem.getRect();
var isHorizontal = axis.isHorizontal();
var lineCount = 0;
var ticksCoords = axis.getTicksCoords({
tickModel: splitLineModel
});
var p1 = [];
var p2 = [];
var lineStyle = lineStyleModel.getLineStyle();
for (var i = 0; i < ticksCoords.length; i++) {
var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
if (i === 0 && !showMinLine || i === ticksCoords.length - 1 && !showMaxLine) {
continue;
}
var tickValue = ticksCoords[i].tickValue;
if (isHorizontal) {
p1[0] = tickCoord;
p1[1] = gridRect.y;
p2[0] = tickCoord;
p2[1] = gridRect.y + gridRect.height;
} else {
p1[0] = gridRect.x;
p1[1] = tickCoord;
p2[0] = gridRect.x + gridRect.width;
p2[1] = tickCoord;
}
var colorIndex = lineCount++ % lineColors.length;
var line = new graphic.Line({
anid: tickValue != null ? 'line_' + tickValue : null,
autoBatch: true,
shape: {
x1: p1[0],
y1: p1[1],
x2: p2[0],
y2: p2[1]
},
style: zrUtil.defaults({
stroke: lineColors[colorIndex]
}, lineStyle),
silent: true
});
graphic.subPixelOptimizeLine(line.shape, lineStyle.lineWidth);
axisGroup.add(line);
}
},
minorSplitLine: function (axisView, axisGroup, axisModel, gridModel) {
var axis = axisModel.axis;
var minorSplitLineModel = axisModel.getModel('minorSplitLine');
var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
var gridRect = gridModel.coordinateSystem.getRect();
var isHorizontal = axis.isHorizontal();
var minorTicksCoords = axis.getMinorTicksCoords();
if (!minorTicksCoords.length) {
return;
}
var p1 = [];
var p2 = [];
var lineStyle = lineStyleModel.getLineStyle();
for (var i = 0; i < minorTicksCoords.length; i++) {
for (var k = 0; k < minorTicksCoords[i].length; k++) {
var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);
if (isHorizontal) {
p1[0] = tickCoord;
p1[1] = gridRect.y;
p2[0] = tickCoord;
p2[1] = gridRect.y + gridRect.height;
} else {
p1[0] = gridRect.x;
p1[1] = tickCoord;
p2[0] = gridRect.x + gridRect.width;
p2[1] = tickCoord;
}
var line = new graphic.Line({
anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
autoBatch: true,
shape: {
x1: p1[0],
y1: p1[1],
x2: p2[0],
y2: p2[1]
},
style: lineStyle,
silent: true
});
graphic.subPixelOptimizeLine(line.shape, lineStyle.lineWidth);
axisGroup.add(line);
}
}
},
splitArea: function (axisView, axisGroup, axisModel, gridModel) {
rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel);
}
};
var CartesianXAxisView = /** @class */function (_super) {
__extends(CartesianXAxisView, _super);
function CartesianXAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = CartesianXAxisView.type;
return _this;
}
CartesianXAxisView.type = 'xAxis';
return CartesianXAxisView;
}(CartesianAxisView);
export { CartesianXAxisView };
var CartesianYAxisView = /** @class */function (_super) {
__extends(CartesianYAxisView, _super);
function CartesianYAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = CartesianXAxisView.type;
return _this;
}
CartesianYAxisView.type = 'yAxis';
return CartesianYAxisView;
}(CartesianAxisView);
export { CartesianYAxisView };
export default CartesianAxisView;

View File

@@ -0,0 +1,174 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import AxisBuilder from './AxisBuilder.js';
import BrushController from '../helper/BrushController.js';
import * as brushHelper from '../helper/brushHelper.js';
import * as graphic from '../../util/graphic.js';
import ComponentView from '../../view/Component.js';
var elementList = ['axisLine', 'axisTickLabel', 'axisName'];
var ParallelAxisView = /** @class */function (_super) {
__extends(ParallelAxisView, _super);
function ParallelAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = ParallelAxisView.type;
return _this;
}
ParallelAxisView.prototype.init = function (ecModel, api) {
_super.prototype.init.apply(this, arguments);
(this._brushController = new BrushController(api.getZr())).on('brush', zrUtil.bind(this._onBrush, this));
};
ParallelAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
if (fromAxisAreaSelect(axisModel, ecModel, payload)) {
return;
}
this.axisModel = axisModel;
this.api = api;
this.group.removeAll();
var oldAxisGroup = this._axisGroup;
this._axisGroup = new graphic.Group();
this.group.add(this._axisGroup);
if (!axisModel.get('show')) {
return;
}
var coordSysModel = getCoordSysModel(axisModel, ecModel);
var coordSys = coordSysModel.coordinateSystem;
var areaSelectStyle = axisModel.getAreaSelectStyle();
var areaWidth = areaSelectStyle.width;
var dim = axisModel.axis.dim;
var axisLayout = coordSys.getAxisLayout(dim);
var builderOpt = zrUtil.extend({
strokeContainThreshold: areaWidth
}, axisLayout);
var axisBuilder = new AxisBuilder(axisModel, builderOpt);
zrUtil.each(elementList, axisBuilder.add, axisBuilder);
this._axisGroup.add(axisBuilder.getGroup());
this._refreshBrushController(builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api);
graphic.groupTransition(oldAxisGroup, this._axisGroup, axisModel);
};
// /**
// * @override
// */
// updateVisual(axisModel, ecModel, api, payload) {
// this._brushController && this._brushController
// .updateCovers(getCoverInfoList(axisModel));
// }
ParallelAxisView.prototype._refreshBrushController = function (builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api) {
// After filtering, axis may change, select area needs to be update.
var extent = axisModel.axis.getExtent();
var extentLen = extent[1] - extent[0];
var extra = Math.min(30, Math.abs(extentLen) * 0.1); // Arbitrary value.
// width/height might be negative, which will be
// normalized in BoundingRect.
var rect = graphic.BoundingRect.create({
x: extent[0],
y: -areaWidth / 2,
width: extentLen,
height: areaWidth
});
rect.x -= extra;
rect.width += 2 * extra;
this._brushController.mount({
enableGlobalPan: true,
rotation: builderOpt.rotation,
x: builderOpt.position[0],
y: builderOpt.position[1]
}).setPanels([{
panelId: 'pl',
clipPath: brushHelper.makeRectPanelClipPath(rect),
isTargetByCursor: brushHelper.makeRectIsTargetByCursor(rect, api, coordSysModel),
getLinearBrushOtherExtent: brushHelper.makeLinearBrushOtherExtent(rect, 0)
}]).enableBrush({
brushType: 'lineX',
brushStyle: areaSelectStyle,
removeOnClick: true
}).updateCovers(getCoverInfoList(axisModel));
};
ParallelAxisView.prototype._onBrush = function (eventParam) {
var coverInfoList = eventParam.areas;
// Do not cache these object, because the mey be changed.
var axisModel = this.axisModel;
var axis = axisModel.axis;
var intervals = zrUtil.map(coverInfoList, function (coverInfo) {
return [axis.coordToData(coverInfo.range[0], true), axis.coordToData(coverInfo.range[1], true)];
});
// If realtime is true, action is not dispatched on drag end, because
// the drag end emits the same params with the last drag move event,
// and may have some delay when using touch pad.
if (!axisModel.option.realtime === eventParam.isEnd || eventParam.removeOnClick) {
// jshint ignore:line
this.api.dispatchAction({
type: 'axisAreaSelect',
parallelAxisId: axisModel.id,
intervals: intervals
});
}
};
ParallelAxisView.prototype.dispose = function () {
this._brushController.dispose();
};
ParallelAxisView.type = 'parallelAxis';
return ParallelAxisView;
}(ComponentView);
function fromAxisAreaSelect(axisModel, ecModel, payload) {
return payload && payload.type === 'axisAreaSelect' && ecModel.findComponents({
mainType: 'parallelAxis',
query: payload
})[0] === axisModel;
}
function getCoverInfoList(axisModel) {
var axis = axisModel.axis;
return zrUtil.map(axisModel.activeIntervals, function (interval) {
return {
brushType: 'lineX',
panelId: 'pl',
range: [axis.dataToCoord(interval[0], true), axis.dataToCoord(interval[1], true)]
};
});
}
function getCoordSysModel(axisModel, ecModel) {
return ecModel.getComponent('parallel', axisModel.get('parallelIndex'));
}
export default ParallelAxisView;

View File

@@ -0,0 +1,206 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import AxisBuilder from './AxisBuilder.js';
import AxisView from './AxisView.js';
var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName'];
var selfBuilderAttrs = ['splitLine', 'splitArea', 'minorSplitLine'];
var RadiusAxisView = /** @class */function (_super) {
__extends(RadiusAxisView, _super);
function RadiusAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = RadiusAxisView.type;
_this.axisPointerClass = 'PolarAxisPointer';
return _this;
}
RadiusAxisView.prototype.render = function (radiusAxisModel, ecModel) {
this.group.removeAll();
if (!radiusAxisModel.get('show')) {
return;
}
var oldAxisGroup = this._axisGroup;
var newAxisGroup = this._axisGroup = new graphic.Group();
this.group.add(newAxisGroup);
var radiusAxis = radiusAxisModel.axis;
var polar = radiusAxis.polar;
var angleAxis = polar.getAngleAxis();
var ticksCoords = radiusAxis.getTicksCoords();
var minorTicksCoords = radiusAxis.getMinorTicksCoords();
var axisAngle = angleAxis.getExtent()[0];
var radiusExtent = radiusAxis.getExtent();
var layout = layoutAxis(polar, radiusAxisModel, axisAngle);
var axisBuilder = new AxisBuilder(radiusAxisModel, layout);
zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
newAxisGroup.add(axisBuilder.getGroup());
graphic.groupTransition(oldAxisGroup, newAxisGroup, radiusAxisModel);
zrUtil.each(selfBuilderAttrs, function (name) {
if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) {
axisElementBuilders[name](this.group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords);
}
}, this);
};
RadiusAxisView.type = 'radiusAxis';
return RadiusAxisView;
}(AxisView);
var axisElementBuilders = {
splitLine: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
var splitLineModel = radiusAxisModel.getModel('splitLine');
var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineColors = lineStyleModel.get('color');
var lineCount = 0;
var angleAxis = polar.getAngleAxis();
var RADIAN = Math.PI / 180;
var angleExtent = angleAxis.getExtent();
var shapeType = Math.abs(angleExtent[1] - angleExtent[0]) === 360 ? 'Circle' : 'Arc';
lineColors = lineColors instanceof Array ? lineColors : [lineColors];
var splitLines = [];
for (var i = 0; i < ticksCoords.length; i++) {
var colorIndex = lineCount++ % lineColors.length;
splitLines[colorIndex] = splitLines[colorIndex] || [];
splitLines[colorIndex].push(new graphic[shapeType]({
shape: {
cx: polar.cx,
cy: polar.cy,
// ensure circle radius >= 0
r: Math.max(ticksCoords[i].coord, 0),
startAngle: -angleExtent[0] * RADIAN,
endAngle: -angleExtent[1] * RADIAN,
clockwise: angleAxis.inverse
}
}));
}
// Simple optimization
// Batching the lines if color are the same
for (var i = 0; i < splitLines.length; i++) {
group.add(graphic.mergePath(splitLines[i], {
style: zrUtil.defaults({
stroke: lineColors[i % lineColors.length],
fill: null
}, lineStyleModel.getLineStyle()),
silent: true
}));
}
},
minorSplitLine: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
if (!minorTicksCoords.length) {
return;
}
var minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine');
var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
var lines = [];
for (var i = 0; i < minorTicksCoords.length; i++) {
for (var k = 0; k < minorTicksCoords[i].length; k++) {
lines.push(new graphic.Circle({
shape: {
cx: polar.cx,
cy: polar.cy,
r: minorTicksCoords[i][k].coord
}
}));
}
}
group.add(graphic.mergePath(lines, {
style: zrUtil.defaults({
fill: null
}, lineStyleModel.getLineStyle()),
silent: true
}));
},
splitArea: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
if (!ticksCoords.length) {
return;
}
var splitAreaModel = radiusAxisModel.getModel('splitArea');
var areaStyleModel = splitAreaModel.getModel('areaStyle');
var areaColors = areaStyleModel.get('color');
var lineCount = 0;
areaColors = areaColors instanceof Array ? areaColors : [areaColors];
var splitAreas = [];
var prevRadius = ticksCoords[0].coord;
for (var i = 1; i < ticksCoords.length; i++) {
var colorIndex = lineCount++ % areaColors.length;
splitAreas[colorIndex] = splitAreas[colorIndex] || [];
splitAreas[colorIndex].push(new graphic.Sector({
shape: {
cx: polar.cx,
cy: polar.cy,
r0: prevRadius,
r: ticksCoords[i].coord,
startAngle: 0,
endAngle: Math.PI * 2
},
silent: true
}));
prevRadius = ticksCoords[i].coord;
}
// Simple optimization
// Batching the lines if color are the same
for (var i = 0; i < splitAreas.length; i++) {
group.add(graphic.mergePath(splitAreas[i], {
style: zrUtil.defaults({
fill: areaColors[i % areaColors.length]
}, areaStyleModel.getAreaStyle()),
silent: true
}));
}
}
};
/**
* @inner
*/
function layoutAxis(polar, radiusAxisModel, axisAngle) {
return {
position: [polar.cx, polar.cy],
rotation: axisAngle / 180 * Math.PI,
labelDirection: -1,
tickDirection: -1,
nameDirection: 1,
labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'),
// Over splitLine and splitArea
z2: 1
};
}
export default RadiusAxisView;

View File

@@ -0,0 +1,146 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import AxisBuilder from './AxisBuilder.js';
import * as graphic from '../../util/graphic.js';
import * as singleAxisHelper from '../../coord/single/singleAxisHelper.js';
import AxisView from './AxisView.js';
import { rectCoordAxisBuildSplitArea, rectCoordAxisHandleRemove } from './axisSplitHelper.js';
var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName'];
var selfBuilderAttrs = ['splitArea', 'splitLine'];
var SingleAxisView = /** @class */function (_super) {
__extends(SingleAxisView, _super);
function SingleAxisView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SingleAxisView.type;
_this.axisPointerClass = 'SingleAxisPointer';
return _this;
}
SingleAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
var group = this.group;
group.removeAll();
var oldAxisGroup = this._axisGroup;
this._axisGroup = new graphic.Group();
var layout = singleAxisHelper.layout(axisModel);
var axisBuilder = new AxisBuilder(axisModel, layout);
zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
group.add(this._axisGroup);
group.add(axisBuilder.getGroup());
zrUtil.each(selfBuilderAttrs, function (name) {
if (axisModel.get([name, 'show'])) {
axisElementBuilders[name](this, this.group, this._axisGroup, axisModel);
}
}, this);
graphic.groupTransition(oldAxisGroup, this._axisGroup, axisModel);
_super.prototype.render.call(this, axisModel, ecModel, api, payload);
};
SingleAxisView.prototype.remove = function () {
rectCoordAxisHandleRemove(this);
};
SingleAxisView.type = 'singleAxis';
return SingleAxisView;
}(AxisView);
var axisElementBuilders = {
splitLine: function (axisView, group, axisGroup, axisModel) {
var axis = axisModel.axis;
if (axis.scale.isBlank()) {
return;
}
var splitLineModel = axisModel.getModel('splitLine');
var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineColors = lineStyleModel.get('color');
lineColors = lineColors instanceof Array ? lineColors : [lineColors];
var lineWidth = lineStyleModel.get('width');
var gridRect = axisModel.coordinateSystem.getRect();
var isHorizontal = axis.isHorizontal();
var splitLines = [];
var lineCount = 0;
var ticksCoords = axis.getTicksCoords({
tickModel: splitLineModel
});
var p1 = [];
var p2 = [];
for (var i = 0; i < ticksCoords.length; ++i) {
var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
if (isHorizontal) {
p1[0] = tickCoord;
p1[1] = gridRect.y;
p2[0] = tickCoord;
p2[1] = gridRect.y + gridRect.height;
} else {
p1[0] = gridRect.x;
p1[1] = tickCoord;
p2[0] = gridRect.x + gridRect.width;
p2[1] = tickCoord;
}
var line = new graphic.Line({
shape: {
x1: p1[0],
y1: p1[1],
x2: p2[0],
y2: p2[1]
},
silent: true
});
graphic.subPixelOptimizeLine(line.shape, lineWidth);
var colorIndex = lineCount++ % lineColors.length;
splitLines[colorIndex] = splitLines[colorIndex] || [];
splitLines[colorIndex].push(line);
}
var lineStyle = lineStyleModel.getLineStyle(['color']);
for (var i = 0; i < splitLines.length; ++i) {
group.add(graphic.mergePath(splitLines[i], {
style: zrUtil.defaults({
stroke: lineColors[i % lineColors.length]
}, lineStyle),
silent: true
}));
}
},
splitArea: function (axisView, group, axisGroup, axisModel) {
rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, axisModel);
}
};
export default SingleAxisView;

View File

@@ -0,0 +1,124 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import { makeInner } from '../../util/model.js';
var inner = makeInner();
export function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) {
var axis = axisModel.axis;
if (axis.scale.isBlank()) {
return;
}
// TODO: TYPE
var splitAreaModel = axisModel.getModel('splitArea');
var areaStyleModel = splitAreaModel.getModel('areaStyle');
var areaColors = areaStyleModel.get('color');
var gridRect = gridModel.coordinateSystem.getRect();
var ticksCoords = axis.getTicksCoords({
tickModel: splitAreaModel,
clamp: true
});
if (!ticksCoords.length) {
return;
}
// For Making appropriate splitArea animation, the color and anid
// should be corresponding to previous one if possible.
var areaColorsLen = areaColors.length;
var lastSplitAreaColors = inner(axisView).splitAreaColors;
var newSplitAreaColors = zrUtil.createHashMap();
var colorIndex = 0;
if (lastSplitAreaColors) {
for (var i = 0; i < ticksCoords.length; i++) {
var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue);
if (cIndex != null) {
colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen;
break;
}
}
}
var prev = axis.toGlobalCoord(ticksCoords[0].coord);
var areaStyle = areaStyleModel.getAreaStyle();
areaColors = zrUtil.isArray(areaColors) ? areaColors : [areaColors];
for (var i = 1; i < ticksCoords.length; i++) {
var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
var x = void 0;
var y = void 0;
var width = void 0;
var height = void 0;
if (axis.isHorizontal()) {
x = prev;
y = gridRect.y;
width = tickCoord - x;
height = gridRect.height;
prev = x + width;
} else {
x = gridRect.x;
y = prev;
width = gridRect.width;
height = tickCoord - y;
prev = y + height;
}
var tickValue = ticksCoords[i - 1].tickValue;
tickValue != null && newSplitAreaColors.set(tickValue, colorIndex);
axisGroup.add(new graphic.Rect({
anid: tickValue != null ? 'area_' + tickValue : null,
shape: {
x: x,
y: y,
width: width,
height: height
},
style: zrUtil.defaults({
fill: areaColors[colorIndex]
}, areaStyle),
autoBatch: true,
silent: true
}));
colorIndex = (colorIndex + 1) % areaColorsLen;
}
inner(axisView).splitAreaColors = newSplitAreaColors;
}
export function rectCoordAxisHandleRemove(axisView) {
inner(axisView).splitAreaColors = null;
}

View File

@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var actionInfo = {
type: 'axisAreaSelect',
event: 'axisAreaSelected'
// update: 'updateVisual'
};
export function installParallelActions(registers) {
registers.registerAction(actionInfo, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'parallelAxis',
query: payload
}, function (parallelAxisModel) {
parallelAxisModel.axis.model.setActiveIntervals(payload.intervals);
});
});
/**
* @payload
*/
registers.registerAction('parallelAxisExpand', function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'parallel',
query: payload
}, function (parallelModel) {
parallelModel.setAxisExpand(payload);
});
});
}

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './axisPointer/install.js';
use(install);

View File

@@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* regarding copyright ownership. The ASF licenses this file
* distributed with this work for additional information
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export {};

View File

@@ -0,0 +1,112 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import ComponentModel from '../../model/Component.js';
var AxisPointerModel = /** @class */function (_super) {
__extends(AxisPointerModel, _super);
function AxisPointerModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = AxisPointerModel.type;
return _this;
}
AxisPointerModel.type = 'axisPointer';
AxisPointerModel.defaultOption = {
// 'auto' means that show when triggered by tooltip or handle.
show: 'auto',
// zlevel: 0,
z: 50,
type: 'line',
// axispointer triggered by tootip determine snap automatically,
// see `modelHelper`.
snap: false,
triggerTooltip: true,
triggerEmphasis: true,
value: null,
status: null,
link: [],
// Do not set 'auto' here, otherwise global animation: false
// will not effect at this axispointer.
animation: null,
animationDurationUpdate: 200,
lineStyle: {
color: '#B9BEC9',
width: 1,
type: 'dashed'
},
shadowStyle: {
color: 'rgba(210,219,238,0.2)'
},
label: {
show: true,
formatter: null,
precision: 'auto',
margin: 3,
color: '#fff',
padding: [5, 7, 5, 7],
backgroundColor: 'auto',
borderColor: null,
borderWidth: 0,
borderRadius: 3
},
handle: {
show: false,
// eslint-disable-next-line
icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z',
size: 45,
// handle margin is from symbol center to axis, which is stable when circular move.
margin: 50,
// color: '#1b8bbd'
// color: '#2f4554'
color: '#333',
shadowBlur: 3,
shadowColor: '#aaa',
shadowOffsetX: 0,
shadowOffsetY: 2,
// For mobile performance
throttle: 40
}
};
return AxisPointerModel;
}(ComponentModel);
export default AxisPointerModel;

View File

@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as globalListener from './globalListener.js';
import ComponentView from '../../view/Component.js';
var AxisPointerView = /** @class */function (_super) {
__extends(AxisPointerView, _super);
function AxisPointerView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = AxisPointerView.type;
return _this;
}
AxisPointerView.prototype.render = function (globalAxisPointerModel, ecModel, api) {
var globalTooltipModel = ecModel.getComponent('tooltip');
var triggerOn = globalAxisPointerModel.get('triggerOn') || globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click';
// Register global listener in AxisPointerView to enable
// AxisPointerView to be independent to Tooltip.
globalListener.register('axisPointer', api, function (currTrigger, e, dispatchAction) {
// If 'none', it is not controlled by mouse totally.
if (triggerOn !== 'none' && (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0)) {
dispatchAction({
type: 'updateAxisPointer',
currTrigger: currTrigger,
x: e && e.offsetX,
y: e && e.offsetY
});
}
});
};
AxisPointerView.prototype.remove = function (ecModel, api) {
globalListener.unregister('axisPointer', api);
};
AxisPointerView.prototype.dispose = function (ecModel, api) {
globalListener.unregister('axisPointer', api);
};
AxisPointerView.type = 'axisPointer';
return AxisPointerView;
}(ComponentView);
export default AxisPointerView;

View File

@@ -0,0 +1,392 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import * as axisPointerModelHelper from './modelHelper.js';
import * as eventTool from 'zrender/lib/core/event.js';
import * as throttleUtil from '../../util/throttle.js';
import { makeInner } from '../../util/model.js';
var inner = makeInner();
var clone = zrUtil.clone;
var bind = zrUtil.bind;
/**
* Base axis pointer class in 2D.
*/
var BaseAxisPointer = /** @class */function () {
function BaseAxisPointer() {
this._dragging = false;
/**
* In px, arbitrary value. Do not set too small,
* no animation is ok for most cases.
*/
this.animationThreshold = 15;
}
/**
* @implement
*/
BaseAxisPointer.prototype.render = function (axisModel, axisPointerModel, api, forceRender) {
var value = axisPointerModel.get('value');
var status = axisPointerModel.get('status');
// Bind them to `this`, not in closure, otherwise they will not
// be replaced when user calling setOption in not merge mode.
this._axisModel = axisModel;
this._axisPointerModel = axisPointerModel;
this._api = api;
// Optimize: `render` will be called repeatedly during mouse move.
// So it is power consuming if performing `render` each time,
// especially on mobile device.
if (!forceRender && this._lastValue === value && this._lastStatus === status) {
return;
}
this._lastValue = value;
this._lastStatus = status;
var group = this._group;
var handle = this._handle;
if (!status || status === 'hide') {
// Do not clear here, for animation better.
group && group.hide();
handle && handle.hide();
return;
}
group && group.show();
handle && handle.show();
// Otherwise status is 'show'
var elOption = {};
this.makeElOption(elOption, value, axisModel, axisPointerModel, api);
// Enable change axis pointer type.
var graphicKey = elOption.graphicKey;
if (graphicKey !== this._lastGraphicKey) {
this.clear(api);
}
this._lastGraphicKey = graphicKey;
var moveAnimation = this._moveAnimation = this.determineAnimation(axisModel, axisPointerModel);
if (!group) {
group = this._group = new graphic.Group();
this.createPointerEl(group, elOption, axisModel, axisPointerModel);
this.createLabelEl(group, elOption, axisModel, axisPointerModel);
api.getZr().add(group);
} else {
var doUpdateProps = zrUtil.curry(updateProps, axisPointerModel, moveAnimation);
this.updatePointerEl(group, elOption, doUpdateProps);
this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
}
updateMandatoryProps(group, axisPointerModel, true);
this._renderHandle(value);
};
/**
* @implement
*/
BaseAxisPointer.prototype.remove = function (api) {
this.clear(api);
};
/**
* @implement
*/
BaseAxisPointer.prototype.dispose = function (api) {
this.clear(api);
};
/**
* @protected
*/
BaseAxisPointer.prototype.determineAnimation = function (axisModel, axisPointerModel) {
var animation = axisPointerModel.get('animation');
var axis = axisModel.axis;
var isCategoryAxis = axis.type === 'category';
var useSnap = axisPointerModel.get('snap');
// Value axis without snap always do not snap.
if (!useSnap && !isCategoryAxis) {
return false;
}
if (animation === 'auto' || animation == null) {
var animationThreshold = this.animationThreshold;
if (isCategoryAxis && axis.getBandWidth() > animationThreshold) {
return true;
}
// It is important to auto animation when snap used. Consider if there is
// a dataZoom, animation will be disabled when too many points exist, while
// it will be enabled for better visual effect when little points exist.
if (useSnap) {
var seriesDataCount = axisPointerModelHelper.getAxisInfo(axisModel).seriesDataCount;
var axisExtent = axis.getExtent();
// Approximate band width
return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold;
}
return false;
}
return animation === true;
};
/**
* add {pointer, label, graphicKey} to elOption
* @protected
*/
BaseAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
// Should be implemenented by sub-class.
};
/**
* @protected
*/
BaseAxisPointer.prototype.createPointerEl = function (group, elOption, axisModel, axisPointerModel) {
var pointerOption = elOption.pointer;
if (pointerOption) {
var pointerEl = inner(group).pointerEl = new graphic[pointerOption.type](clone(elOption.pointer));
group.add(pointerEl);
}
};
/**
* @protected
*/
BaseAxisPointer.prototype.createLabelEl = function (group, elOption, axisModel, axisPointerModel) {
if (elOption.label) {
var labelEl = inner(group).labelEl = new graphic.Text(clone(elOption.label));
group.add(labelEl);
updateLabelShowHide(labelEl, axisPointerModel);
}
};
/**
* @protected
*/
BaseAxisPointer.prototype.updatePointerEl = function (group, elOption, updateProps) {
var pointerEl = inner(group).pointerEl;
if (pointerEl && elOption.pointer) {
pointerEl.setStyle(elOption.pointer.style);
updateProps(pointerEl, {
shape: elOption.pointer.shape
});
}
};
/**
* @protected
*/
BaseAxisPointer.prototype.updateLabelEl = function (group, elOption, updateProps, axisPointerModel) {
var labelEl = inner(group).labelEl;
if (labelEl) {
labelEl.setStyle(elOption.label.style);
updateProps(labelEl, {
// Consider text length change in vertical axis, animation should
// be used on shape, otherwise the effect will be weird.
// TODOTODO
// shape: elOption.label.shape,
x: elOption.label.x,
y: elOption.label.y
});
updateLabelShowHide(labelEl, axisPointerModel);
}
};
/**
* @private
*/
BaseAxisPointer.prototype._renderHandle = function (value) {
if (this._dragging || !this.updateHandleTransform) {
return;
}
var axisPointerModel = this._axisPointerModel;
var zr = this._api.getZr();
var handle = this._handle;
var handleModel = axisPointerModel.getModel('handle');
var status = axisPointerModel.get('status');
if (!handleModel.get('show') || !status || status === 'hide') {
handle && zr.remove(handle);
this._handle = null;
return;
}
var isInit;
if (!this._handle) {
isInit = true;
handle = this._handle = graphic.createIcon(handleModel.get('icon'), {
cursor: 'move',
draggable: true,
onmousemove: function (e) {
// For mobile device, prevent screen slider on the button.
eventTool.stop(e.event);
},
onmousedown: bind(this._onHandleDragMove, this, 0, 0),
drift: bind(this._onHandleDragMove, this),
ondragend: bind(this._onHandleDragEnd, this)
});
zr.add(handle);
}
updateMandatoryProps(handle, axisPointerModel, false);
// update style
handle.setStyle(handleModel.getItemStyle(null, ['color', 'borderColor', 'borderWidth', 'opacity', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY']));
// update position
var handleSize = handleModel.get('size');
if (!zrUtil.isArray(handleSize)) {
handleSize = [handleSize, handleSize];
}
handle.scaleX = handleSize[0] / 2;
handle.scaleY = handleSize[1] / 2;
throttleUtil.createOrUpdate(this, '_doDispatchAxisPointer', handleModel.get('throttle') || 0, 'fixRate');
this._moveHandleToValue(value, isInit);
};
BaseAxisPointer.prototype._moveHandleToValue = function (value, isInit) {
updateProps(this._axisPointerModel, !isInit && this._moveAnimation, this._handle, getHandleTransProps(this.getHandleTransform(value, this._axisModel, this._axisPointerModel)));
};
BaseAxisPointer.prototype._onHandleDragMove = function (dx, dy) {
var handle = this._handle;
if (!handle) {
return;
}
this._dragging = true;
// Persistent for throttle.
var trans = this.updateHandleTransform(getHandleTransProps(handle), [dx, dy], this._axisModel, this._axisPointerModel);
this._payloadInfo = trans;
handle.stopAnimation();
handle.attr(getHandleTransProps(trans));
inner(handle).lastProp = null;
this._doDispatchAxisPointer();
};
/**
* Throttled method.
*/
BaseAxisPointer.prototype._doDispatchAxisPointer = function () {
var handle = this._handle;
if (!handle) {
return;
}
var payloadInfo = this._payloadInfo;
var axisModel = this._axisModel;
this._api.dispatchAction({
type: 'updateAxisPointer',
x: payloadInfo.cursorPoint[0],
y: payloadInfo.cursorPoint[1],
tooltipOption: payloadInfo.tooltipOption,
axesInfo: [{
axisDim: axisModel.axis.dim,
axisIndex: axisModel.componentIndex
}]
});
};
BaseAxisPointer.prototype._onHandleDragEnd = function () {
this._dragging = false;
var handle = this._handle;
if (!handle) {
return;
}
var value = this._axisPointerModel.get('value');
// Consider snap or categroy axis, handle may be not consistent with
// axisPointer. So move handle to align the exact value position when
// drag ended.
this._moveHandleToValue(value);
// For the effect: tooltip will be shown when finger holding on handle
// button, and will be hidden after finger left handle button.
this._api.dispatchAction({
type: 'hideTip'
});
};
/**
* @private
*/
BaseAxisPointer.prototype.clear = function (api) {
this._lastValue = null;
this._lastStatus = null;
var zr = api.getZr();
var group = this._group;
var handle = this._handle;
if (zr && group) {
this._lastGraphicKey = null;
group && zr.remove(group);
handle && zr.remove(handle);
this._group = null;
this._handle = null;
this._payloadInfo = null;
}
throttleUtil.clear(this, '_doDispatchAxisPointer');
};
/**
* @protected
*/
BaseAxisPointer.prototype.doClear = function () {
// Implemented by sub-class if necessary.
};
BaseAxisPointer.prototype.buildLabel = function (xy, wh, xDimIndex) {
xDimIndex = xDimIndex || 0;
return {
x: xy[xDimIndex],
y: xy[1 - xDimIndex],
width: wh[xDimIndex],
height: wh[1 - xDimIndex]
};
};
return BaseAxisPointer;
}();
function updateProps(animationModel, moveAnimation, el, props) {
// Animation optimize.
if (!propsEqual(inner(el).lastProp, props)) {
inner(el).lastProp = props;
moveAnimation ? graphic.updateProps(el, props, animationModel) : (el.stopAnimation(), el.attr(props));
}
}
function propsEqual(lastProps, newProps) {
if (zrUtil.isObject(lastProps) && zrUtil.isObject(newProps)) {
var equals_1 = true;
zrUtil.each(newProps, function (item, key) {
equals_1 = equals_1 && propsEqual(lastProps[key], item);
});
return !!equals_1;
} else {
return lastProps === newProps;
}
}
function updateLabelShowHide(labelEl, axisPointerModel) {
labelEl[axisPointerModel.get(['label', 'show']) ? 'show' : 'hide']();
}
function getHandleTransProps(trans) {
return {
x: trans.x || 0,
y: trans.y || 0,
rotation: trans.rotation || 0
};
}
function updateMandatoryProps(group, axisPointerModel, silent) {
var z = axisPointerModel.get('z');
var zlevel = axisPointerModel.get('zlevel');
group && group.traverse(function (el) {
if (el.type !== 'group') {
z != null && (el.z = z);
zlevel != null && (el.zlevel = zlevel);
el.silent = silent;
}
});
}
export default BaseAxisPointer;

View File

@@ -0,0 +1,148 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import BaseAxisPointer from './BaseAxisPointer.js';
import * as viewHelper from './viewHelper.js';
import * as cartesianAxisHelper from '../../coord/cartesian/cartesianAxisHelper.js';
var CartesianAxisPointer = /** @class */function (_super) {
__extends(CartesianAxisPointer, _super);
function CartesianAxisPointer() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* @override
*/
CartesianAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
var axis = axisModel.axis;
var grid = axis.grid;
var axisPointerType = axisPointerModel.get('type');
var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true));
if (axisPointerType && axisPointerType !== 'none') {
var elStyle = viewHelper.buildElStyle(axisPointerModel);
var pointerOption = pointerShapeBuilder[axisPointerType](axis, pixelValue, otherExtent);
pointerOption.style = elStyle;
elOption.graphicKey = pointerOption.type;
elOption.pointer = pointerOption;
}
var layoutInfo = cartesianAxisHelper.layout(grid.model, axisModel);
viewHelper.buildCartesianSingleLabelElOption(
// @ts-ignore
value, elOption, layoutInfo, axisModel, axisPointerModel, api);
};
/**
* @override
*/
CartesianAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) {
var layoutInfo = cartesianAxisHelper.layout(axisModel.axis.grid.model, axisModel, {
labelInside: false
});
// @ts-ignore
layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
var pos = viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo);
return {
x: pos[0],
y: pos[1],
rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
};
};
/**
* @override
*/
CartesianAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) {
var axis = axisModel.axis;
var grid = axis.grid;
var axisExtent = axis.getGlobalExtent(true);
var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
var dimIndex = axis.dim === 'x' ? 0 : 1;
var currPosition = [transform.x, transform.y];
currPosition[dimIndex] += delta[dimIndex];
currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
var cursorPoint = [cursorOtherValue, cursorOtherValue];
cursorPoint[dimIndex] = currPosition[dimIndex];
// Make tooltip do not overlap axisPointer and in the middle of the grid.
var tooltipOptions = [{
verticalAlign: 'middle'
}, {
align: 'center'
}];
return {
x: currPosition[0],
y: currPosition[1],
rotation: transform.rotation,
cursorPoint: cursorPoint,
tooltipOption: tooltipOptions[dimIndex]
};
};
return CartesianAxisPointer;
}(BaseAxisPointer);
function getCartesian(grid, axis) {
var opt = {};
opt[axis.dim + 'AxisIndex'] = axis.index;
return grid.getCartesian(opt);
}
var pointerShapeBuilder = {
line: function (axis, pixelValue, otherExtent) {
var targetShape = viewHelper.makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getAxisDimIndex(axis));
return {
type: 'Line',
subPixelOptimize: true,
shape: targetShape
};
},
shadow: function (axis, pixelValue, otherExtent) {
var bandWidth = Math.max(1, axis.getBandWidth());
var span = otherExtent[1] - otherExtent[0];
return {
type: 'Rect',
shape: viewHelper.makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getAxisDimIndex(axis))
};
}
};
function getAxisDimIndex(axis) {
return axis.dim === 'x' ? 0 : 1;
}
export default CartesianAxisPointer;

View File

@@ -0,0 +1,144 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import BaseAxisPointer from './BaseAxisPointer.js';
import * as graphic from '../../util/graphic.js';
import * as viewHelper from './viewHelper.js';
import * as matrix from 'zrender/lib/core/matrix.js';
import AxisBuilder from '../axis/AxisBuilder.js';
var PolarAxisPointer = /** @class */function (_super) {
__extends(PolarAxisPointer, _super);
function PolarAxisPointer() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* @override
*/
PolarAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
var axis = axisModel.axis;
if (axis.dim === 'angle') {
this.animationThreshold = Math.PI / 18;
}
var polar = axis.polar;
var otherAxis = polar.getOtherAxis(axis);
var otherExtent = otherAxis.getExtent();
var coordValue = axis.dataToCoord(value);
var axisPointerType = axisPointerModel.get('type');
if (axisPointerType && axisPointerType !== 'none') {
var elStyle = viewHelper.buildElStyle(axisPointerModel);
var pointerOption = pointerShapeBuilder[axisPointerType](axis, polar, coordValue, otherExtent);
pointerOption.style = elStyle;
elOption.graphicKey = pointerOption.type;
elOption.pointer = pointerOption;
}
var labelMargin = axisPointerModel.get(['label', 'margin']);
var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin);
viewHelper.buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos);
};
return PolarAxisPointer;
}(BaseAxisPointer);
;
function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) {
var axis = axisModel.axis;
var coord = axis.dataToCoord(value);
var axisAngle = polar.getAngleAxis().getExtent()[0];
axisAngle = axisAngle / 180 * Math.PI;
var radiusExtent = polar.getRadiusAxis().getExtent();
var position;
var align;
var verticalAlign;
if (axis.dim === 'radius') {
var transform = matrix.create();
matrix.rotate(transform, transform, axisAngle);
matrix.translate(transform, transform, [polar.cx, polar.cy]);
position = graphic.applyTransform([coord, -labelMargin], transform);
var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0;
// @ts-ignore
var labelLayout = AxisBuilder.innerTextLayout(axisAngle, labelRotation * Math.PI / 180, -1);
align = labelLayout.textAlign;
verticalAlign = labelLayout.textVerticalAlign;
} else {
// angle axis
var r = radiusExtent[1];
position = polar.coordToPoint([r + labelMargin, coord]);
var cx = polar.cx;
var cy = polar.cy;
align = Math.abs(position[0] - cx) / r < 0.3 ? 'center' : position[0] > cx ? 'left' : 'right';
verticalAlign = Math.abs(position[1] - cy) / r < 0.3 ? 'middle' : position[1] > cy ? 'top' : 'bottom';
}
return {
position: position,
align: align,
verticalAlign: verticalAlign
};
}
var pointerShapeBuilder = {
line: function (axis, polar, coordValue, otherExtent) {
return axis.dim === 'angle' ? {
type: 'Line',
shape: viewHelper.makeLineShape(polar.coordToPoint([otherExtent[0], coordValue]), polar.coordToPoint([otherExtent[1], coordValue]))
} : {
type: 'Circle',
shape: {
cx: polar.cx,
cy: polar.cy,
r: coordValue
}
};
},
shadow: function (axis, polar, coordValue, otherExtent) {
var bandWidth = Math.max(1, axis.getBandWidth());
var radian = Math.PI / 180;
return axis.dim === 'angle' ? {
type: 'Sector',
shape: viewHelper.makeSectorShape(polar.cx, polar.cy, otherExtent[0], otherExtent[1],
// In ECharts y is negative if angle is positive
(-coordValue - bandWidth / 2) * radian, (-coordValue + bandWidth / 2) * radian)
} : {
type: 'Sector',
shape: viewHelper.makeSectorShape(polar.cx, polar.cy, coordValue - bandWidth / 2, coordValue + bandWidth / 2, 0, Math.PI * 2)
};
}
};
export default PolarAxisPointer;

View File

@@ -0,0 +1,145 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import BaseAxisPointer from './BaseAxisPointer.js';
import * as viewHelper from './viewHelper.js';
import * as singleAxisHelper from '../../coord/single/singleAxisHelper.js';
var XY = ['x', 'y'];
var WH = ['width', 'height'];
var SingleAxisPointer = /** @class */function (_super) {
__extends(SingleAxisPointer, _super);
function SingleAxisPointer() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* @override
*/
SingleAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
var axis = axisModel.axis;
var coordSys = axis.coordinateSystem;
var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis));
var pixelValue = coordSys.dataToPoint(value)[0];
var axisPointerType = axisPointerModel.get('type');
if (axisPointerType && axisPointerType !== 'none') {
var elStyle = viewHelper.buildElStyle(axisPointerModel);
var pointerOption = pointerShapeBuilder[axisPointerType](axis, pixelValue, otherExtent);
pointerOption.style = elStyle;
elOption.graphicKey = pointerOption.type;
elOption.pointer = pointerOption;
}
var layoutInfo = singleAxisHelper.layout(axisModel);
viewHelper.buildCartesianSingleLabelElOption(
// @ts-ignore
value, elOption, layoutInfo, axisModel, axisPointerModel, api);
};
/**
* @override
*/
SingleAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) {
var layoutInfo = singleAxisHelper.layout(axisModel, {
labelInside: false
});
// @ts-ignore
layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
var position = viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo);
return {
x: position[0],
y: position[1],
rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
};
};
/**
* @override
*/
SingleAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) {
var axis = axisModel.axis;
var coordSys = axis.coordinateSystem;
var dimIndex = getPointDimIndex(axis);
var axisExtent = getGlobalExtent(coordSys, dimIndex);
var currPosition = [transform.x, transform.y];
currPosition[dimIndex] += delta[dimIndex];
currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
var otherExtent = getGlobalExtent(coordSys, 1 - dimIndex);
var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
var cursorPoint = [cursorOtherValue, cursorOtherValue];
cursorPoint[dimIndex] = currPosition[dimIndex];
return {
x: currPosition[0],
y: currPosition[1],
rotation: transform.rotation,
cursorPoint: cursorPoint,
tooltipOption: {
verticalAlign: 'middle'
}
};
};
return SingleAxisPointer;
}(BaseAxisPointer);
var pointerShapeBuilder = {
line: function (axis, pixelValue, otherExtent) {
var targetShape = viewHelper.makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getPointDimIndex(axis));
return {
type: 'Line',
subPixelOptimize: true,
shape: targetShape
};
},
shadow: function (axis, pixelValue, otherExtent) {
var bandWidth = axis.getBandWidth();
var span = otherExtent[1] - otherExtent[0];
return {
type: 'Rect',
shape: viewHelper.makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getPointDimIndex(axis))
};
}
};
function getPointDimIndex(axis) {
return axis.isHorizontal() ? 0 : 1;
}
function getGlobalExtent(coordSys, dimIndex) {
var rect = coordSys.getRect();
return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]];
}
export default SingleAxisPointer;

View File

@@ -0,0 +1,378 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { makeInner } from '../../util/model.js';
import * as modelHelper from './modelHelper.js';
import findPointFromSeries from './findPointFromSeries.js';
import { each, curry, bind, extend } from 'zrender/lib/core/util.js';
var inner = makeInner();
/**
* Basic logic: check all axis, if they do not demand show/highlight,
* then hide/downplay them.
*
* @return content of event obj for echarts.connect.
*/
export default function axisTrigger(payload, ecModel, api) {
var currTrigger = payload.currTrigger;
var point = [payload.x, payload.y];
var finder = payload;
var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api);
var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;
// Pending
// See #6121. But we are not able to reproduce it yet.
if (!coordSysAxesInfo) {
return;
}
if (illegalPoint(point)) {
// Used in the default behavior of `connection`: use the sample seriesIndex
// and dataIndex. And also used in the tooltipView trigger.
point = findPointFromSeries({
seriesIndex: finder.seriesIndex,
// Do not use dataIndexInside from other ec instance.
// FIXME: auto detect it?
dataIndex: finder.dataIndex
}, ecModel).point;
}
var isIllegalPoint = illegalPoint(point);
// Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}).
// Notice: In this case, it is difficult to get the `point` (which is necessary to show
// tooltip, so if point is not given, we just use the point found by sample seriesIndex
// and dataIndex.
var inputAxesInfo = finder.axesInfo;
var axesInfo = coordSysAxesInfo.axesInfo;
var shouldHide = currTrigger === 'leave' || illegalPoint(point);
var outputPayload = {};
var showValueMap = {};
var dataByCoordSys = {
list: [],
map: {}
};
var updaters = {
showPointer: curry(showPointer, showValueMap),
showTooltip: curry(showTooltip, dataByCoordSys)
};
// Process for triggered axes.
each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) {
// If a point given, it must be contained by the coordinate system.
var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point);
each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
var axis = axisInfo.axis;
var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo);
// If no inputAxesInfo, no axis is restricted.
if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) {
var val = inputAxisInfo && inputAxisInfo.value;
if (val == null && !isIllegalPoint) {
val = axis.pointToData(point);
}
val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload);
}
});
});
// Process for linked axes.
var linkTriggers = {};
each(axesInfo, function (tarAxisInfo, tarKey) {
var linkGroup = tarAxisInfo.linkGroup;
// If axis has been triggered in the previous stage, it should not be triggered by link.
if (linkGroup && !showValueMap[tarKey]) {
each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) {
var srcValItem = showValueMap[srcKey];
// If srcValItem exist, source axis is triggered, so link to target axis.
if (srcAxisInfo !== tarAxisInfo && srcValItem) {
var val = srcValItem.value;
linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo))));
linkTriggers[tarAxisInfo.key] = val;
}
});
}
});
each(linkTriggers, function (val, tarKey) {
processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload);
});
updateModelActually(showValueMap, axesInfo, outputPayload);
dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
dispatchHighDownActually(axesInfo, dispatchAction, api);
return outputPayload;
}
function processOnAxis(axisInfo, newValue, updaters, noSnap, outputFinder) {
var axis = axisInfo.axis;
if (axis.scale.isBlank() || !axis.containData(newValue)) {
return;
}
if (!axisInfo.involveSeries) {
updaters.showPointer(axisInfo, newValue);
return;
}
// Heavy calculation. So put it after axis.containData checking.
var payloadInfo = buildPayloadsBySeries(newValue, axisInfo);
var payloadBatch = payloadInfo.payloadBatch;
var snapToValue = payloadInfo.snapToValue;
// Fill content of event obj for echarts.connect.
// By default use the first involved series data as a sample to connect.
if (payloadBatch[0] && outputFinder.seriesIndex == null) {
extend(outputFinder, payloadBatch[0]);
}
// If no linkSource input, this process is for collecting link
// target, where snap should not be accepted.
if (!noSnap && axisInfo.snap) {
if (axis.containData(snapToValue) && snapToValue != null) {
newValue = snapToValue;
}
}
updaters.showPointer(axisInfo, newValue, payloadBatch);
// Tooltip should always be snapToValue, otherwise there will be
// incorrect "axis value ~ series value" mapping displayed in tooltip.
updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
}
function buildPayloadsBySeries(value, axisInfo) {
var axis = axisInfo.axis;
var dim = axis.dim;
var snapToValue = value;
var payloadBatch = [];
var minDist = Number.MAX_VALUE;
var minDiff = -1;
each(axisInfo.seriesModels, function (series, idx) {
var dataDim = series.getData().mapDimensionsAll(dim);
var seriesNestestValue;
var dataIndices;
if (series.getAxisTooltipData) {
var result = series.getAxisTooltipData(dataDim, value, axis);
dataIndices = result.dataIndices;
seriesNestestValue = result.nestestValue;
} else {
dataIndices = series.getData().indicesOfNearest(dataDim[0], value,
// Add a threshold to avoid find the wrong dataIndex
// when data length is not same.
// false,
axis.type === 'category' ? 0.5 : null);
if (!dataIndices.length) {
return;
}
seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
}
if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
return;
}
var diff = value - seriesNestestValue;
var dist = Math.abs(diff);
// Consider category case
if (dist <= minDist) {
if (dist < minDist || diff >= 0 && minDiff < 0) {
minDist = dist;
minDiff = diff;
snapToValue = seriesNestestValue;
payloadBatch.length = 0;
}
each(dataIndices, function (dataIndex) {
payloadBatch.push({
seriesIndex: series.seriesIndex,
dataIndexInside: dataIndex,
dataIndex: series.getData().getRawIndex(dataIndex)
});
});
}
});
return {
payloadBatch: payloadBatch,
snapToValue: snapToValue
};
}
function showPointer(showValueMap, axisInfo, value, payloadBatch) {
showValueMap[axisInfo.key] = {
value: value,
payloadBatch: payloadBatch
};
}
function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
var payloadBatch = payloadInfo.payloadBatch;
var axis = axisInfo.axis;
var axisModel = axis.model;
var axisPointerModel = axisInfo.axisPointerModel;
// If no data, do not create anything in dataByCoordSys,
// whose length will be used to judge whether dispatch action.
if (!axisInfo.triggerTooltip || !payloadBatch.length) {
return;
}
var coordSysModel = axisInfo.coordSys.model;
var coordSysKey = modelHelper.makeKey(coordSysModel);
var coordSysItem = dataByCoordSys.map[coordSysKey];
if (!coordSysItem) {
coordSysItem = dataByCoordSys.map[coordSysKey] = {
coordSysId: coordSysModel.id,
coordSysIndex: coordSysModel.componentIndex,
coordSysType: coordSysModel.type,
coordSysMainType: coordSysModel.mainType,
dataByAxis: []
};
dataByCoordSys.list.push(coordSysItem);
}
coordSysItem.dataByAxis.push({
axisDim: axis.dim,
axisIndex: axisModel.componentIndex,
axisType: axisModel.type,
axisId: axisModel.id,
value: value,
// Caustion: viewHelper.getValueLabel is actually on "view stage", which
// depends that all models have been updated. So it should not be performed
// here. Considering axisPointerModel used here is volatile, which is hard
// to be retrieve in TooltipView, we prepare parameters here.
valueLabelOpt: {
precision: axisPointerModel.get(['label', 'precision']),
formatter: axisPointerModel.get(['label', 'formatter'])
},
seriesDataIndices: payloadBatch.slice()
});
}
function updateModelActually(showValueMap, axesInfo, outputPayload) {
var outputAxesInfo = outputPayload.axesInfo = [];
// Basic logic: If no 'show' required, 'hide' this axisPointer.
each(axesInfo, function (axisInfo, key) {
var option = axisInfo.axisPointerModel.option;
var valItem = showValueMap[key];
if (valItem) {
!axisInfo.useHandle && (option.status = 'show');
option.value = valItem.value;
// For label formatter param and highlight.
option.seriesDataIndices = (valItem.payloadBatch || []).slice();
}
// When always show (e.g., handle used), remain
// original value and status.
else {
// If hide, value still need to be set, consider
// click legend to toggle axis blank.
!axisInfo.useHandle && (option.status = 'hide');
}
// If status is 'hide', should be no info in payload.
option.status === 'show' && outputAxesInfo.push({
axisDim: axisInfo.axis.dim,
axisIndex: axisInfo.axis.model.componentIndex,
value: option.value
});
});
}
function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
// Basic logic: If no showTip required, hideTip will be dispatched.
if (illegalPoint(point) || !dataByCoordSys.list.length) {
dispatchAction({
type: 'hideTip'
});
return;
}
// In most case only one axis (or event one series is used). It is
// convenient to fetch payload.seriesIndex and payload.dataIndex
// directly. So put the first seriesIndex and dataIndex of the first
// axis on the payload.
var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};
dispatchAction({
type: 'showTip',
escapeConnect: true,
x: point[0],
y: point[1],
tooltipOption: payload.tooltipOption,
position: payload.position,
dataIndexInside: sampleItem.dataIndexInside,
dataIndex: sampleItem.dataIndex,
seriesIndex: sampleItem.seriesIndex,
dataByCoordSys: dataByCoordSys.list
});
}
function dispatchHighDownActually(axesInfo, dispatchAction, api) {
// FIXME
// highlight status modification should be a stage of main process?
// (Consider confilct (e.g., legend and axisPointer) and setOption)
var zr = api.getZr();
var highDownKey = 'axisPointerLastHighlights';
var lastHighlights = inner(zr)[highDownKey] || {};
var newHighlights = inner(zr)[highDownKey] = {};
// Update highlight/downplay status according to axisPointer model.
// Build hash map and remove duplicate incidentally.
each(axesInfo, function (axisInfo, key) {
var option = axisInfo.axisPointerModel.option;
option.status === 'show' && axisInfo.triggerEmphasis && each(option.seriesDataIndices, function (batchItem) {
var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex;
newHighlights[key] = batchItem;
});
});
// Diff.
var toHighlight = [];
var toDownplay = [];
each(lastHighlights, function (batchItem, key) {
!newHighlights[key] && toDownplay.push(batchItem);
});
each(newHighlights, function (batchItem, key) {
!lastHighlights[key] && toHighlight.push(batchItem);
});
toDownplay.length && api.dispatchAction({
type: 'downplay',
escapeConnect: true,
// Not blur others when highlight in axisPointer.
notBlur: true,
batch: toDownplay
});
toHighlight.length && api.dispatchAction({
type: 'highlight',
escapeConnect: true,
// Not blur others when highlight in axisPointer.
notBlur: true,
batch: toHighlight
});
}
function findInputAxisInfo(inputAxesInfo, axisInfo) {
for (var i = 0; i < (inputAxesInfo || []).length; i++) {
var inputAxisInfo = inputAxesInfo[i];
if (axisInfo.axis.dim === inputAxisInfo.axisDim && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex) {
return inputAxisInfo;
}
}
}
function makeMapperParam(axisInfo) {
var axisModel = axisInfo.axis.model;
var item = {};
var dim = item.axisDim = axisInfo.axis.dim;
item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex;
item.axisName = item[dim + 'AxisName'] = axisModel.name;
item.axisId = item[dim + 'AxisId'] = axisModel.id;
return item;
}
function illegalPoint(point) {
return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]);
}

View File

@@ -0,0 +1,98 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import * as modelUtil from '../../util/model.js';
/**
* @param finder contains {seriesIndex, dataIndex, dataIndexInside}
* @param ecModel
* @return {point: [x, y], el: ...} point Will not be null.
*/
export default function findPointFromSeries(finder, ecModel) {
var point = [];
var seriesIndex = finder.seriesIndex;
var seriesModel;
if (seriesIndex == null || !(seriesModel = ecModel.getSeriesByIndex(seriesIndex))) {
return {
point: []
};
}
var data = seriesModel.getData();
var dataIndex = modelUtil.queryDataIndex(data, finder);
if (dataIndex == null || dataIndex < 0 || zrUtil.isArray(dataIndex)) {
return {
point: []
};
}
var el = data.getItemGraphicEl(dataIndex);
var coordSys = seriesModel.coordinateSystem;
if (seriesModel.getTooltipPosition) {
point = seriesModel.getTooltipPosition(dataIndex) || [];
} else if (coordSys && coordSys.dataToPoint) {
if (finder.isStacked) {
var baseAxis = coordSys.getBaseAxis();
var valueAxis = coordSys.getOtherAxis(baseAxis);
var valueAxisDim = valueAxis.dim;
var baseAxisDim = baseAxis.dim;
var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
var baseDim = data.mapDimension(baseAxisDim);
var stackedData = [];
stackedData[baseDataOffset] = data.get(baseDim, dataIndex);
stackedData[1 - baseDataOffset] = data.get(data.getCalculationInfo('stackResultDimension'), dataIndex);
point = coordSys.dataToPoint(stackedData) || [];
} else {
point = coordSys.dataToPoint(data.getValues(zrUtil.map(coordSys.dimensions, function (dim) {
return data.mapDimension(dim);
}), dataIndex)) || [];
}
} else if (el) {
// Use graphic bounding rect
var rect = el.getBoundingRect().clone();
rect.applyTransform(el.transform);
point = [rect.x + rect.width / 2, rect.y + rect.height / 2];
}
return {
point: point,
el: el
};
}

View File

@@ -0,0 +1,138 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import env from 'zrender/lib/core/env.js';
import { makeInner } from '../../util/model.js';
var inner = makeInner();
var each = zrUtil.each;
/**
* @param {string} key
* @param {module:echarts/ExtensionAPI} api
* @param {Function} handler
* param: {string} currTrigger
* param: {Array.<number>} point
*/
export function register(key, api, handler) {
if (env.node) {
return;
}
var zr = api.getZr();
inner(zr).records || (inner(zr).records = {});
initGlobalListeners(zr, api);
var record = inner(zr).records[key] || (inner(zr).records[key] = {});
record.handler = handler;
}
function initGlobalListeners(zr, api) {
if (inner(zr).initialized) {
return;
}
inner(zr).initialized = true;
useHandler('click', zrUtil.curry(doEnter, 'click'));
useHandler('mousemove', zrUtil.curry(doEnter, 'mousemove'));
// useHandler('mouseout', onLeave);
useHandler('globalout', onLeave);
function useHandler(eventType, cb) {
zr.on(eventType, function (e) {
var dis = makeDispatchAction(api);
each(inner(zr).records, function (record) {
record && cb(record, e, dis.dispatchAction);
});
dispatchTooltipFinally(dis.pendings, api);
});
}
}
function dispatchTooltipFinally(pendings, api) {
var showLen = pendings.showTip.length;
var hideLen = pendings.hideTip.length;
var actuallyPayload;
if (showLen) {
actuallyPayload = pendings.showTip[showLen - 1];
} else if (hideLen) {
actuallyPayload = pendings.hideTip[hideLen - 1];
}
if (actuallyPayload) {
actuallyPayload.dispatchAction = null;
api.dispatchAction(actuallyPayload);
}
}
function onLeave(record, e, dispatchAction) {
record.handler('leave', null, dispatchAction);
}
function doEnter(currTrigger, record, e, dispatchAction) {
record.handler(currTrigger, e, dispatchAction);
}
function makeDispatchAction(api) {
var pendings = {
showTip: [],
hideTip: []
};
// FIXME
// better approach?
// 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip,
// which may be conflict, (axisPointer call showTip but tooltip call hideTip);
// So we have to add "final stage" to merge those dispatched actions.
var dispatchAction = function (payload) {
var pendingList = pendings[payload.type];
if (pendingList) {
pendingList.push(payload);
} else {
payload.dispatchAction = dispatchAction;
api.dispatchAction(payload);
}
};
return {
dispatchAction: dispatchAction,
pendings: pendings
};
}
export function unregister(key, api) {
if (env.node) {
return;
}
var zr = api.getZr();
var record = (inner(zr).records || {})[key];
if (record) {
inner(zr).records[key] = null;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import AxisView from '../axis/AxisView.js';
import CartesianAxisPointer from './CartesianAxisPointer.js';
import AxisPointerModel from './AxisPointerModel.js';
import AxisPointerView from './AxisPointerView.js';
import { isArray } from 'zrender/lib/core/util.js';
import { collect } from './modelHelper.js';
import axisTrigger from './axisTrigger.js';
export function install(registers) {
// CartesianAxisPointer is not supposed to be required here. But consider
// echarts.simple.js and online build tooltip, which only require gridSimple,
// CartesianAxisPointer should be able to required somewhere.
AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);
registers.registerComponentModel(AxisPointerModel);
registers.registerComponentView(AxisPointerView);
registers.registerPreprocessor(function (option) {
// Always has a global axisPointerModel for default setting.
if (option) {
(!option.axisPointer || option.axisPointer.length === 0) && (option.axisPointer = {});
var link = option.axisPointer.link;
// Normalize to array to avoid object mergin. But if link
// is not set, remain null/undefined, otherwise it will
// override existent link setting.
if (link && !isArray(link)) {
option.axisPointer.link = [link];
}
}
});
// This process should proformed after coordinate systems created
// and series data processed. So put it on statistic processing stage.
registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) {
// Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
// allAxesInfo should be updated when setOption performed.
ecModel.getComponent('axisPointer').coordSysAxesInfo = collect(ecModel, api);
});
// Broadcast to all views.
registers.registerAction({
type: 'updateAxisPointer',
event: 'updateAxisPointer',
update: ':updateAxisPointer'
}, axisTrigger);
}

View File

@@ -0,0 +1,295 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import Model from '../../model/Model.js';
import { each, curry, clone, defaults, isArray, indexOf } from 'zrender/lib/core/util.js';
// Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
// allAxesInfo should be updated when setOption performed.
export function collect(ecModel, api) {
var result = {
/**
* key: makeKey(axis.model)
* value: {
* axis,
* coordSys,
* axisPointerModel,
* triggerTooltip,
* triggerEmphasis,
* involveSeries,
* snap,
* seriesModels,
* seriesDataCount
* }
*/
axesInfo: {},
seriesInvolved: false,
/**
* key: makeKey(coordSys.model)
* value: Object: key makeKey(axis.model), value: axisInfo
*/
coordSysAxesInfo: {},
coordSysMap: {}
};
collectAxesInfo(result, ecModel, api);
// Check seriesInvolved for performance, in case too many series in some chart.
result.seriesInvolved && collectSeriesInfo(result, ecModel);
return result;
}
function collectAxesInfo(result, ecModel, api) {
var globalTooltipModel = ecModel.getComponent('tooltip');
var globalAxisPointerModel = ecModel.getComponent('axisPointer');
// links can only be set on global.
var linksOption = globalAxisPointerModel.get('link', true) || [];
var linkGroups = [];
// Collect axes info.
each(api.getCoordinateSystems(), function (coordSys) {
// Some coordinate system do not support axes, like geo.
if (!coordSys.axisPointerEnabled) {
return;
}
var coordSysKey = makeKey(coordSys.model);
var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
result.coordSysMap[coordSysKey] = coordSys;
// Set tooltip (like 'cross') is a convenient way to show axisPointer
// for user. So we enable setting tooltip on coordSys model.
var coordSysModel = coordSys.model;
var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);
each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null));
// If axis tooltip used, choose tooltip axis for each coordSys.
// Notice this case: coordSys is `grid` but not `cartesian2D` here.
if (coordSys.getTooltipAxes && globalTooltipModel
// If tooltip.showContent is set as false, tooltip will not
// show but axisPointer will show as normal.
&& baseTooltipModel.get('show')) {
// Compatible with previous logic. But series.tooltip.trigger: 'axis'
// or series.data[n].tooltip.trigger: 'axis' are not support any more.
var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
var cross = baseTooltipModel.get(['axisPointer', 'type']) === 'cross';
var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get(['axisPointer', 'axis']));
if (triggerAxis || cross) {
each(tooltipAxes.baseAxes, curry(saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis));
}
if (cross) {
each(tooltipAxes.otherAxes, curry(saveTooltipAxisInfo, 'cross', false));
}
}
// fromTooltip: true | false | 'cross'
// triggerTooltip: true | false | null
function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);
var axisPointerShow = axisPointerModel.get('show');
if (!axisPointerShow || axisPointerShow === 'auto' && !fromTooltip && !isHandleTrigger(axisPointerModel)) {
return;
}
if (triggerTooltip == null) {
triggerTooltip = axisPointerModel.get('triggerTooltip');
}
axisPointerModel = fromTooltip ? makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) : axisPointerModel;
var snap = axisPointerModel.get('snap');
var triggerEmphasis = axisPointerModel.get('triggerEmphasis');
var axisKey = makeKey(axis.model);
var involveSeries = triggerTooltip || snap || axis.type === 'category';
// If result.axesInfo[key] exist, override it (tooltip has higher priority).
var axisInfo = result.axesInfo[axisKey] = {
key: axisKey,
axis: axis,
coordSys: coordSys,
axisPointerModel: axisPointerModel,
triggerTooltip: triggerTooltip,
triggerEmphasis: triggerEmphasis,
involveSeries: involveSeries,
snap: snap,
useHandle: isHandleTrigger(axisPointerModel),
seriesModels: [],
linkGroup: null
};
axesInfoInCoordSys[axisKey] = axisInfo;
result.seriesInvolved = result.seriesInvolved || involveSeries;
var groupIndex = getLinkGroupIndex(linksOption, axis);
if (groupIndex != null) {
var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {
axesInfo: {}
});
linkGroup.axesInfo[axisKey] = axisInfo;
linkGroup.mapper = linksOption[groupIndex].mapper;
axisInfo.linkGroup = linkGroup;
}
}
});
}
function makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) {
var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
var fields = ['type', 'snap', 'lineStyle', 'shadowStyle', 'label', 'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'];
var volatileOption = {};
each(fields, function (field) {
volatileOption[field] = clone(tooltipAxisPointerModel.get(field));
});
// category axis do not auto snap, otherwise some tick that do not
// has value can not be hovered. value/time/log axis default snap if
// triggered from tooltip and trigger tooltip.
volatileOption.snap = axis.type !== 'category' && !!triggerTooltip;
// Compatible with previous behavior, tooltip axis does not show label by default.
// Only these properties can be overridden from tooltip to axisPointer.
if (tooltipAxisPointerModel.get('type') === 'cross') {
volatileOption.type = 'line';
}
var labelOption = volatileOption.label || (volatileOption.label = {});
// Follow the convention, do not show label when triggered by tooltip by default.
labelOption.show == null && (labelOption.show = false);
if (fromTooltip === 'cross') {
// When 'cross', both axes show labels.
var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get(['label', 'show']);
labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true;
// If triggerTooltip, this is a base axis, which should better not use cross style
// (cross style is dashed by default)
if (!triggerTooltip) {
var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
crossStyle && defaults(labelOption, crossStyle.textStyle);
}
}
return axis.model.getModel('axisPointer', new Model(volatileOption, globalAxisPointerModel, ecModel));
}
function collectSeriesInfo(result, ecModel) {
// Prepare data for axis trigger
ecModel.eachSeries(function (seriesModel) {
// Notice this case: this coordSys is `cartesian2D` but not `grid`.
var coordSys = seriesModel.coordinateSystem;
var seriesTooltipTrigger = seriesModel.get(['tooltip', 'trigger'], true);
var seriesTooltipShow = seriesModel.get(['tooltip', 'show'], true);
if (!coordSys || seriesTooltipTrigger === 'none' || seriesTooltipTrigger === false || seriesTooltipTrigger === 'item' || seriesTooltipShow === false || seriesModel.get(['axisPointer', 'show'], true) === false) {
return;
}
each(result.coordSysAxesInfo[makeKey(coordSys.model)], function (axisInfo) {
var axis = axisInfo.axis;
if (coordSys.getAxis(axis.dim) === axis) {
axisInfo.seriesModels.push(seriesModel);
axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0);
axisInfo.seriesDataCount += seriesModel.getData().count();
}
});
});
}
/**
* For example:
* {
* axisPointer: {
* links: [{
* xAxisIndex: [2, 4],
* yAxisIndex: 'all'
* }, {
* xAxisId: ['a5', 'a7'],
* xAxisName: 'xxx'
* }]
* }
* }
*/
function getLinkGroupIndex(linksOption, axis) {
var axisModel = axis.model;
var dim = axis.dim;
for (var i = 0; i < linksOption.length; i++) {
var linkOption = linksOption[i] || {};
if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id) || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex) || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)) {
return i;
}
}
}
function checkPropInLink(linkPropValue, axisPropValue) {
return linkPropValue === 'all' || isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0 || linkPropValue === axisPropValue;
}
export function fixValue(axisModel) {
var axisInfo = getAxisInfo(axisModel);
if (!axisInfo) {
return;
}
var axisPointerModel = axisInfo.axisPointerModel;
var scale = axisInfo.axis.scale;
var option = axisPointerModel.option;
var status = axisPointerModel.get('status');
var value = axisPointerModel.get('value');
// Parse init value for category and time axis.
if (value != null) {
value = scale.parse(value);
}
var useHandle = isHandleTrigger(axisPointerModel);
// If `handle` used, `axisPointer` will always be displayed, so value
// and status should be initialized.
if (status == null) {
option.status = useHandle ? 'show' : 'hide';
}
var extent = scale.getExtent().slice();
extent[0] > extent[1] && extent.reverse();
if (
// Pick a value on axis when initializing.
value == null
// If both `handle` and `dataZoom` are used, value may be out of axis extent,
// where we should re-pick a value to keep `handle` displaying normally.
|| value > extent[1]) {
// Make handle displayed on the end of the axis when init, which looks better.
value = extent[1];
}
if (value < extent[0]) {
value = extent[0];
}
option.value = value;
if (useHandle) {
option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show';
}
}
export function getAxisInfo(axisModel) {
var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
}
export function getAxisPointerModel(axisModel) {
var axisInfo = getAxisInfo(axisModel);
return axisInfo && axisInfo.axisPointerModel;
}
function isHandleTrigger(axisPointerModel) {
return !!axisPointerModel.get(['handle', 'show']);
}
/**
* @param {module:echarts/model/Model} model
* @return {string} unique key
*/
export function makeKey(model) {
return model.type + '||' + model.id;
}

View File

@@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import * as textContain from 'zrender/lib/contain/text.js';
import * as formatUtil from '../../util/format.js';
import * as matrix from 'zrender/lib/core/matrix.js';
import * as axisHelper from '../../coord/axisHelper.js';
import AxisBuilder from '../axis/AxisBuilder.js';
import { createTextStyle } from '../../label/labelStyle.js';
export function buildElStyle(axisPointerModel) {
var axisPointerType = axisPointerModel.get('type');
var styleModel = axisPointerModel.getModel(axisPointerType + 'Style');
var style;
if (axisPointerType === 'line') {
style = styleModel.getLineStyle();
style.fill = null;
} else if (axisPointerType === 'shadow') {
style = styleModel.getAreaStyle();
style.stroke = null;
}
return style;
}
/**
* @param {Function} labelPos {align, verticalAlign, position}
*/
export function buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos) {
var value = axisPointerModel.get('value');
var text = getValueLabel(value, axisModel.axis, axisModel.ecModel, axisPointerModel.get('seriesDataIndices'), {
precision: axisPointerModel.get(['label', 'precision']),
formatter: axisPointerModel.get(['label', 'formatter'])
});
var labelModel = axisPointerModel.getModel('label');
var paddings = formatUtil.normalizeCssArray(labelModel.get('padding') || 0);
var font = labelModel.getFont();
var textRect = textContain.getBoundingRect(text, font);
var position = labelPos.position;
var width = textRect.width + paddings[1] + paddings[3];
var height = textRect.height + paddings[0] + paddings[2];
// Adjust by align.
var align = labelPos.align;
align === 'right' && (position[0] -= width);
align === 'center' && (position[0] -= width / 2);
var verticalAlign = labelPos.verticalAlign;
verticalAlign === 'bottom' && (position[1] -= height);
verticalAlign === 'middle' && (position[1] -= height / 2);
// Not overflow ec container
confineInContainer(position, width, height, api);
var bgColor = labelModel.get('backgroundColor');
if (!bgColor || bgColor === 'auto') {
bgColor = axisModel.get(['axisLine', 'lineStyle', 'color']);
}
elOption.label = {
// shape: {x: 0, y: 0, width: width, height: height, r: labelModel.get('borderRadius')},
x: position[0],
y: position[1],
style: createTextStyle(labelModel, {
text: text,
font: font,
fill: labelModel.getTextColor(),
padding: paddings,
backgroundColor: bgColor
}),
// Label should be over axisPointer.
z2: 10
};
}
// Do not overflow ec container
function confineInContainer(position, width, height, api) {
var viewWidth = api.getWidth();
var viewHeight = api.getHeight();
position[0] = Math.min(position[0] + width, viewWidth) - width;
position[1] = Math.min(position[1] + height, viewHeight) - height;
position[0] = Math.max(position[0], 0);
position[1] = Math.max(position[1], 0);
}
export function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
value = axis.scale.parse(value);
var text = axis.scale.getLabel({
value: value
}, {
// If `precision` is set, width can be fixed (like '12.00500'), which
// helps to debounce when when moving label.
precision: opt.precision
});
var formatter = opt.formatter;
if (formatter) {
var params_1 = {
value: axisHelper.getAxisRawValue(axis, {
value: value
}),
axisDimension: axis.dim,
axisIndex: axis.index,
seriesData: []
};
zrUtil.each(seriesDataIndices, function (idxItem) {
var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
var dataIndex = idxItem.dataIndexInside;
var dataParams = series && series.getDataParams(dataIndex);
dataParams && params_1.seriesData.push(dataParams);
});
if (zrUtil.isString(formatter)) {
text = formatter.replace('{value}', text);
} else if (zrUtil.isFunction(formatter)) {
text = formatter(params_1);
}
}
return text;
}
export function getTransformedPosition(axis, value, layoutInfo) {
var transform = matrix.create();
matrix.rotate(transform, transform, layoutInfo.rotation);
matrix.translate(transform, transform, layoutInfo.position);
return graphic.applyTransform([axis.dataToCoord(value), (layoutInfo.labelOffset || 0) + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)], transform);
}
export function buildCartesianSingleLabelElOption(value, elOption, layoutInfo, axisModel, axisPointerModel, api) {
// @ts-ignore
var textLayout = AxisBuilder.innerTextLayout(layoutInfo.rotation, 0, layoutInfo.labelDirection);
layoutInfo.labelMargin = axisPointerModel.get(['label', 'margin']);
buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
position: getTransformedPosition(axisModel.axis, value, layoutInfo),
align: textLayout.textAlign,
verticalAlign: textLayout.textVerticalAlign
});
}
export function makeLineShape(p1, p2, xDimIndex) {
xDimIndex = xDimIndex || 0;
return {
x1: p1[xDimIndex],
y1: p1[1 - xDimIndex],
x2: p2[xDimIndex],
y2: p2[1 - xDimIndex]
};
}
export function makeRectShape(xy, wh, xDimIndex) {
xDimIndex = xDimIndex || 0;
return {
x: xy[xDimIndex],
y: xy[1 - xDimIndex],
width: wh[xDimIndex],
height: wh[1 - xDimIndex]
};
}
export function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {
return {
cx: cx,
cy: cy,
r0: r0,
r: r,
startAngle: startAngle,
endAngle: endAngle,
clockwise: true
};
}

46
frontend/node_modules/echarts/lib/component/brush.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './brush/install.js';
use(install);

View File

@@ -0,0 +1,136 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import * as visualSolution from '../../visual/visualSolution.js';
import Model from '../../model/Model.js';
import ComponentModel from '../../model/Component.js';
var DEFAULT_OUT_OF_BRUSH_COLOR = '#ddd';
var BrushModel = /** @class */function (_super) {
__extends(BrushModel, _super);
function BrushModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = BrushModel.type;
/**
* @readOnly
*/
_this.areas = [];
/**
* Current brush painting area settings.
* @readOnly
*/
_this.brushOption = {};
return _this;
}
BrushModel.prototype.optionUpdated = function (newOption, isInit) {
var thisOption = this.option;
!isInit && visualSolution.replaceVisualOption(thisOption, newOption, ['inBrush', 'outOfBrush']);
var inBrush = thisOption.inBrush = thisOption.inBrush || {};
// Always give default visual, consider setOption at the second time.
thisOption.outOfBrush = thisOption.outOfBrush || {
color: DEFAULT_OUT_OF_BRUSH_COLOR
};
if (!inBrush.hasOwnProperty('liftZ')) {
// Bigger than the highlight z lift, otherwise it will
// be effected by the highlight z when brush.
inBrush.liftZ = 5;
}
};
/**
* If `areas` is null/undefined, range state remain.
*/
BrushModel.prototype.setAreas = function (areas) {
if (process.env.NODE_ENV !== 'production') {
zrUtil.assert(zrUtil.isArray(areas));
zrUtil.each(areas, function (area) {
zrUtil.assert(area.brushType, 'Illegal areas');
});
}
// If areas is null/undefined, range state remain.
// This helps user to dispatchAction({type: 'brush'}) with no areas
// set but just want to get the current brush select info from a `brush` event.
if (!areas) {
return;
}
this.areas = zrUtil.map(areas, function (area) {
return generateBrushOption(this.option, area);
}, this);
};
/**
* Set the current painting brush option.
*/
BrushModel.prototype.setBrushOption = function (brushOption) {
this.brushOption = generateBrushOption(this.option, brushOption);
this.brushType = this.brushOption.brushType;
};
BrushModel.type = 'brush';
BrushModel.dependencies = ['geo', 'grid', 'xAxis', 'yAxis', 'parallel', 'series'];
BrushModel.defaultOption = {
seriesIndex: 'all',
brushType: 'rect',
brushMode: 'single',
transformable: true,
brushStyle: {
borderWidth: 1,
color: 'rgba(210,219,238,0.3)',
borderColor: '#D2DBEE'
},
throttleType: 'fixRate',
throttleDelay: 0,
removeOnClick: true,
z: 10000
};
return BrushModel;
}(ComponentModel);
function generateBrushOption(option, brushOption) {
return zrUtil.merge({
brushType: option.brushType,
brushMode: option.brushMode,
transformable: option.transformable,
brushStyle: new Model(option.brushStyle).getItemStyle(),
removeOnClick: option.removeOnClick,
z: option.z
}, brushOption, true);
}
export default BrushModel;

View File

@@ -0,0 +1,111 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import BrushController from '../helper/BrushController.js';
import { layoutCovers } from './visualEncoding.js';
import ComponentView from '../../view/Component.js';
var BrushView = /** @class */function (_super) {
__extends(BrushView, _super);
function BrushView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = BrushView.type;
return _this;
}
BrushView.prototype.init = function (ecModel, api) {
this.ecModel = ecModel;
this.api = api;
this.model;
(this._brushController = new BrushController(api.getZr())).on('brush', zrUtil.bind(this._onBrush, this)).mount();
};
BrushView.prototype.render = function (brushModel, ecModel, api, payload) {
this.model = brushModel;
this._updateController(brushModel, ecModel, api, payload);
};
BrushView.prototype.updateTransform = function (brushModel, ecModel, api, payload) {
// PENDING: `updateTransform` is a little tricky, whose layout need
// to be calculate mandatorily and other stages will not be performed.
// Take care the correctness of the logic. See #11754 .
layoutCovers(ecModel);
this._updateController(brushModel, ecModel, api, payload);
};
BrushView.prototype.updateVisual = function (brushModel, ecModel, api, payload) {
this.updateTransform(brushModel, ecModel, api, payload);
};
BrushView.prototype.updateView = function (brushModel, ecModel, api, payload) {
this._updateController(brushModel, ecModel, api, payload);
};
BrushView.prototype._updateController = function (brushModel, ecModel, api, payload) {
// Do not update controller when drawing.
(!payload || payload.$from !== brushModel.id) && this._brushController.setPanels(brushModel.brushTargetManager.makePanelOpts(api)).enableBrush(brushModel.brushOption).updateCovers(brushModel.areas.slice());
};
// updateLayout: updateController,
// updateVisual: updateController,
BrushView.prototype.dispose = function () {
this._brushController.dispose();
};
BrushView.prototype._onBrush = function (eventParam) {
var modelId = this.model.id;
var areas = this.model.brushTargetManager.setOutputRanges(eventParam.areas, this.ecModel);
// Action is not dispatched on drag end, because the drag end
// emits the same params with the last drag move event, and
// may have some delay when using touch pad, which makes
// animation not smooth (when using debounce).
(!eventParam.isEnd || eventParam.removeOnClick) && this.api.dispatchAction({
type: 'brush',
brushId: modelId,
areas: zrUtil.clone(areas),
$from: modelId
});
eventParam.isEnd && this.api.dispatchAction({
type: 'brushEnd',
brushId: modelId,
areas: zrUtil.clone(areas),
$from: modelId
});
};
BrushView.type = 'brush';
return BrushView;
}(ComponentView);
export default BrushView;

View File

@@ -0,0 +1,101 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import brushPreprocessor from './preprocessor.js';
import BrushView from './BrushView.js';
import BrushModel from './BrushModel.js';
import brushVisual from './visualEncoding.js';
// TODO
import BrushFeature from '../toolbox/feature/Brush.js';
import { registerFeature } from '../toolbox/featureManager.js';
import { noop } from 'zrender/lib/core/util.js';
export function install(registers) {
registers.registerComponentView(BrushView);
registers.registerComponentModel(BrushModel);
registers.registerPreprocessor(brushPreprocessor);
registers.registerVisual(registers.PRIORITY.VISUAL.BRUSH, brushVisual);
registers.registerAction({
type: 'brush',
event: 'brush',
update: 'updateVisual'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'brush',
query: payload
}, function (brushModel) {
brushModel.setAreas(payload.areas);
});
});
/**
* payload: {
* brushComponents: [
* {
* brushId,
* brushIndex,
* brushName,
* series: [
* {
* seriesId,
* seriesIndex,
* seriesName,
* rawIndices: [21, 34, ...]
* },
* ...
* ]
* },
* ...
* ]
* }
*/
registers.registerAction({
type: 'brushSelect',
event: 'brushSelected',
update: 'none'
}, noop);
registers.registerAction({
type: 'brushEnd',
event: 'brushEnd',
update: 'none'
}, noop);
registerFeature('brush', BrushFeature);
}

View File

@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import { normalizeToArray } from '../../util/model.js';
var DEFAULT_TOOLBOX_BTNS = ['rect', 'polygon', 'keep', 'clear'];
export default function brushPreprocessor(option, isNew) {
var brushComponents = normalizeToArray(option ? option.brush : []);
if (!brushComponents.length) {
return;
}
var brushComponentSpecifiedBtns = [];
zrUtil.each(brushComponents, function (brushOpt) {
var tbs = brushOpt.hasOwnProperty('toolbox') ? brushOpt.toolbox : [];
if (tbs instanceof Array) {
brushComponentSpecifiedBtns = brushComponentSpecifiedBtns.concat(tbs);
}
});
var toolbox = option && option.toolbox;
if (zrUtil.isArray(toolbox)) {
toolbox = toolbox[0];
}
if (!toolbox) {
toolbox = {
feature: {}
};
option.toolbox = [toolbox];
}
var toolboxFeature = toolbox.feature || (toolbox.feature = {});
var toolboxBrush = toolboxFeature.brush || (toolboxFeature.brush = {});
var brushTypes = toolboxBrush.type || (toolboxBrush.type = []);
brushTypes.push.apply(brushTypes, brushComponentSpecifiedBtns);
removeDuplicate(brushTypes);
if (isNew && !brushTypes.length) {
brushTypes.push.apply(brushTypes, DEFAULT_TOOLBOX_BTNS);
}
}
function removeDuplicate(arr) {
var map = {};
zrUtil.each(arr, function (val) {
map[val] = 1;
});
arr.length = 0;
zrUtil.each(map, function (flag, val) {
arr.push(val);
});
}

View File

@@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as polygonContain from 'zrender/lib/contain/polygon.js';
import BoundingRect from 'zrender/lib/core/BoundingRect.js';
import { linePolygonIntersect } from '../../util/graphic.js';
export function makeBrushCommonSelectorForSeries(area) {
var brushType = area.brushType;
// Do not use function binding or curry for performance.
var selectors = {
point: function (itemLayout) {
return selector[brushType].point(itemLayout, selectors, area);
},
rect: function (itemLayout) {
return selector[brushType].rect(itemLayout, selectors, area);
}
};
return selectors;
}
var selector = {
lineX: getLineSelectors(0),
lineY: getLineSelectors(1),
rect: {
point: function (itemLayout, selectors, area) {
return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]);
},
rect: function (itemLayout, selectors, area) {
return itemLayout && area.boundingRect.intersect(itemLayout);
}
},
polygon: {
point: function (itemLayout, selectors, area) {
return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]) && polygonContain.contain(area.range, itemLayout[0], itemLayout[1]);
},
rect: function (itemLayout, selectors, area) {
var points = area.range;
if (!itemLayout || points.length <= 1) {
return false;
}
var x = itemLayout.x;
var y = itemLayout.y;
var width = itemLayout.width;
var height = itemLayout.height;
var p = points[0];
if (polygonContain.contain(points, x, y) || polygonContain.contain(points, x + width, y) || polygonContain.contain(points, x, y + height) || polygonContain.contain(points, x + width, y + height) || BoundingRect.create(itemLayout).contain(p[0], p[1]) || linePolygonIntersect(x, y, x + width, y, points) || linePolygonIntersect(x, y, x, y + height, points) || linePolygonIntersect(x + width, y, x + width, y + height, points) || linePolygonIntersect(x, y + height, x + width, y + height, points)) {
return true;
}
}
}
};
function getLineSelectors(xyIndex) {
var xy = ['x', 'y'];
var wh = ['width', 'height'];
return {
point: function (itemLayout, selectors, area) {
if (itemLayout) {
var range = area.range;
var p = itemLayout[xyIndex];
return inLineRange(p, range);
}
},
rect: function (itemLayout, selectors, area) {
if (itemLayout) {
var range = area.range;
var layoutRange = [itemLayout[xy[xyIndex]], itemLayout[xy[xyIndex]] + itemLayout[wh[xyIndex]]];
layoutRange[1] < layoutRange[0] && layoutRange.reverse();
return inLineRange(layoutRange[0], range) || inLineRange(layoutRange[1], range) || inLineRange(range[0], layoutRange) || inLineRange(range[1], layoutRange);
}
}
};
}
function inLineRange(p, range) {
return range[0] <= p && p <= range[1];
}
export default selector;

View File

@@ -0,0 +1,257 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import BoundingRect from 'zrender/lib/core/BoundingRect.js';
import * as visualSolution from '../../visual/visualSolution.js';
import { makeBrushCommonSelectorForSeries } from './selector.js';
import * as throttleUtil from '../../util/throttle.js';
import BrushTargetManager from '../helper/BrushTargetManager.js';
var STATE_LIST = ['inBrush', 'outOfBrush'];
var DISPATCH_METHOD = '__ecBrushSelect';
var DISPATCH_FLAG = '__ecInBrushSelectEvent';
;
export function layoutCovers(ecModel) {
ecModel.eachComponent({
mainType: 'brush'
}, function (brushModel) {
var brushTargetManager = brushModel.brushTargetManager = new BrushTargetManager(brushModel.option, ecModel);
brushTargetManager.setInputRanges(brushModel.areas, ecModel);
});
}
/**
* Register the visual encoding if this modules required.
*/
export default function brushVisual(ecModel, api, payload) {
var brushSelected = [];
var throttleType;
var throttleDelay;
ecModel.eachComponent({
mainType: 'brush'
}, function (brushModel) {
payload && payload.type === 'takeGlobalCursor' && brushModel.setBrushOption(payload.key === 'brush' ? payload.brushOption : {
brushType: false
});
});
layoutCovers(ecModel);
ecModel.eachComponent({
mainType: 'brush'
}, function (brushModel, brushIndex) {
var thisBrushSelected = {
brushId: brushModel.id,
brushIndex: brushIndex,
brushName: brushModel.name,
areas: zrUtil.clone(brushModel.areas),
selected: []
};
// Every brush component exists in event params, convenient
// for user to find by index.
brushSelected.push(thisBrushSelected);
var brushOption = brushModel.option;
var brushLink = brushOption.brushLink;
var linkedSeriesMap = [];
var selectedDataIndexForLink = [];
var rangeInfoBySeries = [];
var hasBrushExists = false;
if (!brushIndex) {
// Only the first throttle setting works.
throttleType = brushOption.throttleType;
throttleDelay = brushOption.throttleDelay;
}
// Add boundingRect and selectors to range.
var areas = zrUtil.map(brushModel.areas, function (area) {
var builder = boundingRectBuilders[area.brushType];
var selectableArea = zrUtil.defaults({
boundingRect: builder ? builder(area) : void 0
}, area);
selectableArea.selectors = makeBrushCommonSelectorForSeries(selectableArea);
return selectableArea;
});
var visualMappings = visualSolution.createVisualMappings(brushModel.option, STATE_LIST, function (mappingOption) {
mappingOption.mappingMethod = 'fixed';
});
zrUtil.isArray(brushLink) && zrUtil.each(brushLink, function (seriesIndex) {
linkedSeriesMap[seriesIndex] = 1;
});
function linkOthers(seriesIndex) {
return brushLink === 'all' || !!linkedSeriesMap[seriesIndex];
}
// If no supported brush or no brush on the series,
// all visuals should be in original state.
function brushed(rangeInfoList) {
return !!rangeInfoList.length;
}
/**
* Logic for each series: (If the logic has to be modified one day, do it carefully!)
*
* ( brushed ┬ && ┬hasBrushExist ┬ && linkOthers ) => StepA: ┬record, ┬ StepB: ┬visualByRecord.
* !brushed┘ ├hasBrushExist ┤ └nothing,┘ ├visualByRecord.
* └!hasBrushExist┘ └nothing.
* ( !brushed && ┬hasBrushExist ┬ && linkOthers ) => StepA: nothing, StepB: ┬visualByRecord.
* └!hasBrushExist┘ └nothing.
* ( brushed ┬ && !linkOthers ) => StepA: nothing, StepB: ┬visualByCheck.
* !brushed┘ └nothing.
* ( !brushed && !linkOthers ) => StepA: nothing, StepB: nothing.
*/
// Step A
ecModel.eachSeries(function (seriesModel, seriesIndex) {
var rangeInfoList = rangeInfoBySeries[seriesIndex] = [];
seriesModel.subType === 'parallel' ? stepAParallel(seriesModel, seriesIndex) : stepAOthers(seriesModel, seriesIndex, rangeInfoList);
});
function stepAParallel(seriesModel, seriesIndex) {
var coordSys = seriesModel.coordinateSystem;
hasBrushExists = hasBrushExists || coordSys.hasAxisBrushed();
linkOthers(seriesIndex) && coordSys.eachActiveState(seriesModel.getData(), function (activeState, dataIndex) {
activeState === 'active' && (selectedDataIndexForLink[dataIndex] = 1);
});
}
function stepAOthers(seriesModel, seriesIndex, rangeInfoList) {
if (!seriesModel.brushSelector || brushModelNotControll(brushModel, seriesIndex)) {
return;
}
zrUtil.each(areas, function (area) {
if (brushModel.brushTargetManager.controlSeries(area, seriesModel, ecModel)) {
rangeInfoList.push(area);
}
hasBrushExists = hasBrushExists || brushed(rangeInfoList);
});
if (linkOthers(seriesIndex) && brushed(rangeInfoList)) {
var data_1 = seriesModel.getData();
data_1.each(function (dataIndex) {
if (checkInRange(seriesModel, rangeInfoList, data_1, dataIndex)) {
selectedDataIndexForLink[dataIndex] = 1;
}
});
}
}
// Step B
ecModel.eachSeries(function (seriesModel, seriesIndex) {
var seriesBrushSelected = {
seriesId: seriesModel.id,
seriesIndex: seriesIndex,
seriesName: seriesModel.name,
dataIndex: []
};
// Every series exists in event params, convenient
// for user to find series by seriesIndex.
thisBrushSelected.selected.push(seriesBrushSelected);
var rangeInfoList = rangeInfoBySeries[seriesIndex];
var data = seriesModel.getData();
var getValueState = linkOthers(seriesIndex) ? function (dataIndex) {
return selectedDataIndexForLink[dataIndex] ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : 'outOfBrush';
} : function (dataIndex) {
return checkInRange(seriesModel, rangeInfoList, data, dataIndex) ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : 'outOfBrush';
};
// If no supported brush or no brush, all visuals are in original state.
(linkOthers(seriesIndex) ? hasBrushExists : brushed(rangeInfoList)) && visualSolution.applyVisual(STATE_LIST, visualMappings, data, getValueState);
});
});
dispatchAction(api, throttleType, throttleDelay, brushSelected, payload);
}
;
function dispatchAction(api, throttleType, throttleDelay, brushSelected, payload) {
// This event will not be triggered when `setOpion`, otherwise dead lock may
// triggered when do `setOption` in event listener, which we do not find
// satisfactory way to solve yet. Some considered resolutions:
// (a) Diff with prevoius selected data ant only trigger event when changed.
// But store previous data and diff precisely (i.e., not only by dataIndex, but
// also detect value changes in selected data) might bring complexity or fragility.
// (b) Use spectial param like `silent` to suppress event triggering.
// But such kind of volatile param may be weird in `setOption`.
if (!payload) {
return;
}
var zr = api.getZr();
if (zr[DISPATCH_FLAG]) {
return;
}
if (!zr[DISPATCH_METHOD]) {
zr[DISPATCH_METHOD] = doDispatch;
}
var fn = throttleUtil.createOrUpdate(zr, DISPATCH_METHOD, throttleDelay, throttleType);
fn(api, brushSelected);
}
function doDispatch(api, brushSelected) {
if (!api.isDisposed()) {
var zr = api.getZr();
zr[DISPATCH_FLAG] = true;
api.dispatchAction({
type: 'brushSelect',
batch: brushSelected
});
zr[DISPATCH_FLAG] = false;
}
}
function checkInRange(seriesModel, rangeInfoList, data, dataIndex) {
for (var i = 0, len = rangeInfoList.length; i < len; i++) {
var area = rangeInfoList[i];
if (seriesModel.brushSelector(dataIndex, data, area.selectors, area)) {
return true;
}
}
}
function brushModelNotControll(brushModel, seriesIndex) {
var seriesIndices = brushModel.option.seriesIndex;
return seriesIndices != null && seriesIndices !== 'all' && (zrUtil.isArray(seriesIndices) ? zrUtil.indexOf(seriesIndices, seriesIndex) < 0 : seriesIndex !== seriesIndices);
}
var boundingRectBuilders = {
rect: function (area) {
return getBoundingRectFromMinMax(area.range);
},
polygon: function (area) {
var minMax;
var range = area.range;
for (var i = 0, len = range.length; i < len; i++) {
minMax = minMax || [[Infinity, -Infinity], [Infinity, -Infinity]];
var rg = range[i];
rg[0] < minMax[0][0] && (minMax[0][0] = rg[0]);
rg[0] > minMax[0][1] && (minMax[0][1] = rg[0]);
rg[1] < minMax[1][0] && (minMax[1][0] = rg[1]);
rg[1] > minMax[1][1] && (minMax[1][1] = rg[1]);
}
return minMax && getBoundingRectFromMinMax(minMax);
}
};
function getBoundingRectFromMinMax(minMax) {
return new BoundingRect(minMax[0][0], minMax[1][0], minMax[0][1] - minMax[0][0], minMax[1][1] - minMax[1][0]);
}

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './calendar/install.js';
use(install);

View File

@@ -0,0 +1,395 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import { isString, extend, map, isFunction } from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import { createTextStyle } from '../../label/labelStyle.js';
import { formatTplSimple } from '../../util/format.js';
import { parsePercent } from '../../util/number.js';
import ComponentView from '../../view/Component.js';
import { getLocaleModel } from '../../core/locale.js';
var CalendarView = /** @class */function (_super) {
__extends(CalendarView, _super);
function CalendarView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = CalendarView.type;
return _this;
}
CalendarView.prototype.render = function (calendarModel, ecModel, api) {
var group = this.group;
group.removeAll();
var coordSys = calendarModel.coordinateSystem;
// range info
var rangeData = coordSys.getRangeInfo();
var orient = coordSys.getOrient();
// locale
var localeModel = ecModel.getLocaleModel();
this._renderDayRect(calendarModel, rangeData, group);
// _renderLines must be called prior to following function
this._renderLines(calendarModel, rangeData, orient, group);
this._renderYearText(calendarModel, rangeData, orient, group);
this._renderMonthText(calendarModel, localeModel, orient, group);
this._renderWeekText(calendarModel, localeModel, rangeData, orient, group);
};
// render day rect
CalendarView.prototype._renderDayRect = function (calendarModel, rangeData, group) {
var coordSys = calendarModel.coordinateSystem;
var itemRectStyleModel = calendarModel.getModel('itemStyle').getItemStyle();
var sw = coordSys.getCellWidth();
var sh = coordSys.getCellHeight();
for (var i = rangeData.start.time; i <= rangeData.end.time; i = coordSys.getNextNDay(i, 1).time) {
var point = coordSys.dataToRect([i], false).tl;
// every rect
var rect = new graphic.Rect({
shape: {
x: point[0],
y: point[1],
width: sw,
height: sh
},
cursor: 'default',
style: itemRectStyleModel
});
group.add(rect);
}
};
// render separate line
CalendarView.prototype._renderLines = function (calendarModel, rangeData, orient, group) {
var self = this;
var coordSys = calendarModel.coordinateSystem;
var lineStyleModel = calendarModel.getModel(['splitLine', 'lineStyle']).getLineStyle();
var show = calendarModel.get(['splitLine', 'show']);
var lineWidth = lineStyleModel.lineWidth;
this._tlpoints = [];
this._blpoints = [];
this._firstDayOfMonth = [];
this._firstDayPoints = [];
var firstDay = rangeData.start;
for (var i = 0; firstDay.time <= rangeData.end.time; i++) {
addPoints(firstDay.formatedDate);
if (i === 0) {
firstDay = coordSys.getDateInfo(rangeData.start.y + '-' + rangeData.start.m);
}
var date = firstDay.date;
date.setMonth(date.getMonth() + 1);
firstDay = coordSys.getDateInfo(date);
}
addPoints(coordSys.getNextNDay(rangeData.end.time, 1).formatedDate);
function addPoints(date) {
self._firstDayOfMonth.push(coordSys.getDateInfo(date));
self._firstDayPoints.push(coordSys.dataToRect([date], false).tl);
var points = self._getLinePointsOfOneWeek(calendarModel, date, orient);
self._tlpoints.push(points[0]);
self._blpoints.push(points[points.length - 1]);
show && self._drawSplitline(points, lineStyleModel, group);
}
// render top/left line
show && this._drawSplitline(self._getEdgesPoints(self._tlpoints, lineWidth, orient), lineStyleModel, group);
// render bottom/right line
show && this._drawSplitline(self._getEdgesPoints(self._blpoints, lineWidth, orient), lineStyleModel, group);
};
// get points at both ends
CalendarView.prototype._getEdgesPoints = function (points, lineWidth, orient) {
var rs = [points[0].slice(), points[points.length - 1].slice()];
var idx = orient === 'horizontal' ? 0 : 1;
// both ends of the line are extend half lineWidth
rs[0][idx] = rs[0][idx] - lineWidth / 2;
rs[1][idx] = rs[1][idx] + lineWidth / 2;
return rs;
};
// render split line
CalendarView.prototype._drawSplitline = function (points, lineStyle, group) {
var poyline = new graphic.Polyline({
z2: 20,
shape: {
points: points
},
style: lineStyle
});
group.add(poyline);
};
// render month line of one week points
CalendarView.prototype._getLinePointsOfOneWeek = function (calendarModel, date, orient) {
var coordSys = calendarModel.coordinateSystem;
var parsedDate = coordSys.getDateInfo(date);
var points = [];
for (var i = 0; i < 7; i++) {
var tmpD = coordSys.getNextNDay(parsedDate.time, i);
var point = coordSys.dataToRect([tmpD.time], false);
points[2 * tmpD.day] = point.tl;
points[2 * tmpD.day + 1] = point[orient === 'horizontal' ? 'bl' : 'tr'];
}
return points;
};
CalendarView.prototype._formatterLabel = function (formatter, params) {
if (isString(formatter) && formatter) {
return formatTplSimple(formatter, params);
}
if (isFunction(formatter)) {
return formatter(params);
}
return params.nameMap;
};
CalendarView.prototype._yearTextPositionControl = function (textEl, point, orient, position, margin) {
var x = point[0];
var y = point[1];
var aligns = ['center', 'bottom'];
if (position === 'bottom') {
y += margin;
aligns = ['center', 'top'];
} else if (position === 'left') {
x -= margin;
} else if (position === 'right') {
x += margin;
aligns = ['center', 'top'];
} else {
// top
y -= margin;
}
var rotate = 0;
if (position === 'left' || position === 'right') {
rotate = Math.PI / 2;
}
return {
rotation: rotate,
x: x,
y: y,
style: {
align: aligns[0],
verticalAlign: aligns[1]
}
};
};
// render year
CalendarView.prototype._renderYearText = function (calendarModel, rangeData, orient, group) {
var yearLabel = calendarModel.getModel('yearLabel');
if (!yearLabel.get('show')) {
return;
}
var margin = yearLabel.get('margin');
var pos = yearLabel.get('position');
if (!pos) {
pos = orient !== 'horizontal' ? 'top' : 'left';
}
var points = [this._tlpoints[this._tlpoints.length - 1], this._blpoints[0]];
var xc = (points[0][0] + points[1][0]) / 2;
var yc = (points[0][1] + points[1][1]) / 2;
var idx = orient === 'horizontal' ? 0 : 1;
var posPoints = {
top: [xc, points[idx][1]],
bottom: [xc, points[1 - idx][1]],
left: [points[1 - idx][0], yc],
right: [points[idx][0], yc]
};
var name = rangeData.start.y;
if (+rangeData.end.y > +rangeData.start.y) {
name = name + '-' + rangeData.end.y;
}
var formatter = yearLabel.get('formatter');
var params = {
start: rangeData.start.y,
end: rangeData.end.y,
nameMap: name
};
var content = this._formatterLabel(formatter, params);
var yearText = new graphic.Text({
z2: 30,
style: createTextStyle(yearLabel, {
text: content
}),
silent: yearLabel.get('silent')
});
yearText.attr(this._yearTextPositionControl(yearText, posPoints[pos], orient, pos, margin));
group.add(yearText);
};
CalendarView.prototype._monthTextPositionControl = function (point, isCenter, orient, position, margin) {
var align = 'left';
var vAlign = 'top';
var x = point[0];
var y = point[1];
if (orient === 'horizontal') {
y = y + margin;
if (isCenter) {
align = 'center';
}
if (position === 'start') {
vAlign = 'bottom';
}
} else {
x = x + margin;
if (isCenter) {
vAlign = 'middle';
}
if (position === 'start') {
align = 'right';
}
}
return {
x: x,
y: y,
align: align,
verticalAlign: vAlign
};
};
// render month and year text
CalendarView.prototype._renderMonthText = function (calendarModel, localeModel, orient, group) {
var monthLabel = calendarModel.getModel('monthLabel');
if (!monthLabel.get('show')) {
return;
}
var nameMap = monthLabel.get('nameMap');
var margin = monthLabel.get('margin');
var pos = monthLabel.get('position');
var align = monthLabel.get('align');
var termPoints = [this._tlpoints, this._blpoints];
if (!nameMap || isString(nameMap)) {
if (nameMap) {
// case-sensitive
localeModel = getLocaleModel(nameMap) || localeModel;
}
// PENDING
// for ZH locale, original form is `一月` but current form is `1月`
nameMap = localeModel.get(['time', 'monthAbbr']) || [];
}
var idx = pos === 'start' ? 0 : 1;
var axis = orient === 'horizontal' ? 0 : 1;
margin = pos === 'start' ? -margin : margin;
var isCenter = align === 'center';
var labelSilent = monthLabel.get('silent');
for (var i = 0; i < termPoints[idx].length - 1; i++) {
var tmp = termPoints[idx][i].slice();
var firstDay = this._firstDayOfMonth[i];
if (isCenter) {
var firstDayPoints = this._firstDayPoints[i];
tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2;
}
var formatter = monthLabel.get('formatter');
var name_1 = nameMap[+firstDay.m - 1];
var params = {
yyyy: firstDay.y,
yy: (firstDay.y + '').slice(2),
MM: firstDay.m,
M: +firstDay.m,
nameMap: name_1
};
var content = this._formatterLabel(formatter, params);
var monthText = new graphic.Text({
z2: 30,
style: extend(createTextStyle(monthLabel, {
text: content
}), this._monthTextPositionControl(tmp, isCenter, orient, pos, margin)),
silent: labelSilent
});
group.add(monthText);
}
};
CalendarView.prototype._weekTextPositionControl = function (point, orient, position, margin, cellSize) {
var align = 'center';
var vAlign = 'middle';
var x = point[0];
var y = point[1];
var isStart = position === 'start';
if (orient === 'horizontal') {
x = x + margin + (isStart ? 1 : -1) * cellSize[0] / 2;
align = isStart ? 'right' : 'left';
} else {
y = y + margin + (isStart ? 1 : -1) * cellSize[1] / 2;
vAlign = isStart ? 'bottom' : 'top';
}
return {
x: x,
y: y,
align: align,
verticalAlign: vAlign
};
};
// render weeks
CalendarView.prototype._renderWeekText = function (calendarModel, localeModel, rangeData, orient, group) {
var dayLabel = calendarModel.getModel('dayLabel');
if (!dayLabel.get('show')) {
return;
}
var coordSys = calendarModel.coordinateSystem;
var pos = dayLabel.get('position');
var nameMap = dayLabel.get('nameMap');
var margin = dayLabel.get('margin');
var firstDayOfWeek = coordSys.getFirstDayOfWeek();
if (!nameMap || isString(nameMap)) {
if (nameMap) {
// case-sensitive
localeModel = getLocaleModel(nameMap) || localeModel;
}
// Use the first letter of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file
var dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort']);
nameMap = dayOfWeekShort || map(localeModel.get(['time', 'dayOfWeekAbbr']), function (val) {
return val[0];
});
}
var start = coordSys.getNextNDay(rangeData.end.time, 7 - rangeData.lweek).time;
var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()];
margin = parsePercent(margin, Math.min(cellSize[1], cellSize[0]));
if (pos === 'start') {
start = coordSys.getNextNDay(rangeData.start.time, -(7 + rangeData.fweek)).time;
margin = -margin;
}
var labelSilent = dayLabel.get('silent');
for (var i = 0; i < 7; i++) {
var tmpD = coordSys.getNextNDay(start, i);
var point = coordSys.dataToRect([tmpD.time], false).center;
var day = i;
day = Math.abs((i + firstDayOfWeek) % 7);
var weekText = new graphic.Text({
z2: 30,
style: extend(createTextStyle(dayLabel, {
text: nameMap[day]
}), this._weekTextPositionControl(point, orient, pos, margin, cellSize)),
silent: labelSilent
});
group.add(weekText);
}
};
CalendarView.type = 'calendar';
return CalendarView;
}(ComponentView);
export default CalendarView;

View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import CalendarModel from '../../coord/calendar/CalendarModel.js';
import CalendarView from './CalendarView.js';
import Calendar from '../../coord/calendar/Calendar.js';
export function install(registers) {
registers.registerComponentModel(CalendarModel);
registers.registerComponentView(CalendarView);
registers.registerCoordinateSystem('calendar', Calendar);
}

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './dataZoom/install.js';
use(install);

View File

@@ -0,0 +1,341 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import * as numberUtil from '../../util/number.js';
import sliderMove from '../helper/sliderMove.js';
import { unionAxisExtentFromData } from '../../coord/axisHelper.js';
import { ensureScaleRawExtentInfo } from '../../coord/scaleRawExtentInfo.js';
import { getAxisMainType, isCoordSupported } from './helper.js';
import { SINGLE_REFERRING } from '../../util/model.js';
var each = zrUtil.each;
var asc = numberUtil.asc;
/**
* Operate single axis.
* One axis can only operated by one axis operator.
* Different dataZoomModels may be defined to operate the same axis.
* (i.e. 'inside' data zoom and 'slider' data zoom components)
* So dataZoomModels share one axisProxy in that case.
*/
var AxisProxy = /** @class */function () {
function AxisProxy(dimName, axisIndex, dataZoomModel, ecModel) {
this._dimName = dimName;
this._axisIndex = axisIndex;
this.ecModel = ecModel;
this._dataZoomModel = dataZoomModel;
// /**
// * @readOnly
// * @private
// */
// this.hasSeriesStacked;
}
/**
* Whether the axisProxy is hosted by dataZoomModel.
*/
AxisProxy.prototype.hostedBy = function (dataZoomModel) {
return this._dataZoomModel === dataZoomModel;
};
/**
* @return Value can only be NaN or finite value.
*/
AxisProxy.prototype.getDataValueWindow = function () {
return this._valueWindow.slice();
};
/**
* @return {Array.<number>}
*/
AxisProxy.prototype.getDataPercentWindow = function () {
return this._percentWindow.slice();
};
AxisProxy.prototype.getTargetSeriesModels = function () {
var seriesModels = [];
this.ecModel.eachSeries(function (seriesModel) {
if (isCoordSupported(seriesModel)) {
var axisMainType = getAxisMainType(this._dimName);
var axisModel = seriesModel.getReferringComponents(axisMainType, SINGLE_REFERRING).models[0];
if (axisModel && this._axisIndex === axisModel.componentIndex) {
seriesModels.push(seriesModel);
}
}
}, this);
return seriesModels;
};
AxisProxy.prototype.getAxisModel = function () {
return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex);
};
AxisProxy.prototype.getMinMaxSpan = function () {
return zrUtil.clone(this._minMaxSpan);
};
/**
* Only calculate by given range and this._dataExtent, do not change anything.
*/
AxisProxy.prototype.calculateDataWindow = function (opt) {
var dataExtent = this._dataExtent;
var axisModel = this.getAxisModel();
var scale = axisModel.axis.scale;
var rangePropMode = this._dataZoomModel.getRangePropMode();
var percentExtent = [0, 100];
var percentWindow = [];
var valueWindow = [];
var hasPropModeValue;
each(['start', 'end'], function (prop, idx) {
var boundPercent = opt[prop];
var boundValue = opt[prop + 'Value'];
// Notice: dataZoom is based either on `percentProp` ('start', 'end') or
// on `valueProp` ('startValue', 'endValue'). (They are based on the data extent
// but not min/max of axis, which will be calculated by data window then).
// The former one is suitable for cases that a dataZoom component controls multiple
// axes with different unit or extent, and the latter one is suitable for accurate
// zoom by pixel (e.g., in dataZoomSelect).
// we use `getRangePropMode()` to mark which prop is used. `rangePropMode` is updated
// only when setOption or dispatchAction, otherwise it remains its original value.
// (Why not only record `percentProp` and always map to `valueProp`? Because
// the map `valueProp` -> `percentProp` -> `valueProp` probably not the original
// `valueProp`. consider two axes constrolled by one dataZoom. They have different
// data extent. All of values that are overflow the `dataExtent` will be calculated
// to percent '100%').
if (rangePropMode[idx] === 'percent') {
boundPercent == null && (boundPercent = percentExtent[idx]);
// Use scale.parse to math round for category or time axis.
boundValue = scale.parse(numberUtil.linearMap(boundPercent, percentExtent, dataExtent));
} else {
hasPropModeValue = true;
boundValue = boundValue == null ? dataExtent[idx] : scale.parse(boundValue);
// Calculating `percent` from `value` may be not accurate, because
// This calculation can not be inversed, because all of values that
// are overflow the `dataExtent` will be calculated to percent '100%'
boundPercent = numberUtil.linearMap(boundValue, dataExtent, percentExtent);
}
// valueWindow[idx] = round(boundValue);
// percentWindow[idx] = round(boundPercent);
// fallback to extent start/end when parsed value or percent is invalid
valueWindow[idx] = boundValue == null || isNaN(boundValue) ? dataExtent[idx] : boundValue;
percentWindow[idx] = boundPercent == null || isNaN(boundPercent) ? percentExtent[idx] : boundPercent;
});
asc(valueWindow);
asc(percentWindow);
// The windows from user calling of `dispatchAction` might be out of the extent,
// or do not obey the `min/maxSpan`, `min/maxValueSpan`. But we don't restrict window
// by `zoomLock` here, because we see `zoomLock` just as a interaction constraint,
// where API is able to initialize/modify the window size even though `zoomLock`
// specified.
var spans = this._minMaxSpan;
hasPropModeValue ? restrictSet(valueWindow, percentWindow, dataExtent, percentExtent, false) : restrictSet(percentWindow, valueWindow, percentExtent, dataExtent, true);
function restrictSet(fromWindow, toWindow, fromExtent, toExtent, toValue) {
var suffix = toValue ? 'Span' : 'ValueSpan';
sliderMove(0, fromWindow, fromExtent, 'all', spans['min' + suffix], spans['max' + suffix]);
for (var i = 0; i < 2; i++) {
toWindow[i] = numberUtil.linearMap(fromWindow[i], fromExtent, toExtent, true);
toValue && (toWindow[i] = scale.parse(toWindow[i]));
}
}
return {
valueWindow: valueWindow,
percentWindow: percentWindow
};
};
/**
* Notice: reset should not be called before series.restoreData() is called,
* so it is recommended to be called in "process stage" but not "model init
* stage".
*/
AxisProxy.prototype.reset = function (dataZoomModel) {
if (dataZoomModel !== this._dataZoomModel) {
return;
}
var targetSeries = this.getTargetSeriesModels();
// Culculate data window and data extent, and record them.
this._dataExtent = calculateDataExtent(this, this._dimName, targetSeries);
// `calculateDataWindow` uses min/maxSpan.
this._updateMinMaxSpan();
var dataWindow = this.calculateDataWindow(dataZoomModel.settledOption);
this._valueWindow = dataWindow.valueWindow;
this._percentWindow = dataWindow.percentWindow;
// Update axis setting then.
this._setAxisModel();
};
AxisProxy.prototype.filterData = function (dataZoomModel, api) {
if (dataZoomModel !== this._dataZoomModel) {
return;
}
var axisDim = this._dimName;
var seriesModels = this.getTargetSeriesModels();
var filterMode = dataZoomModel.get('filterMode');
var valueWindow = this._valueWindow;
if (filterMode === 'none') {
return;
}
// FIXME
// Toolbox may has dataZoom injected. And if there are stacked bar chart
// with NaN data, NaN will be filtered and stack will be wrong.
// So we need to force the mode to be set empty.
// In fect, it is not a big deal that do not support filterMode-'filter'
// when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis
// selection" some day, which might need "adapt to data extent on the
// otherAxis", which is disabled by filterMode-'empty'.
// But currently, stack has been fixed to based on value but not index,
// so this is not an issue any more.
// let otherAxisModel = this.getOtherAxisModel();
// if (dataZoomModel.get('$fromToolbox')
// && otherAxisModel
// && otherAxisModel.hasSeriesStacked
// ) {
// filterMode = 'empty';
// }
// TODO
// filterMode 'weakFilter' and 'empty' is not optimized for huge data yet.
each(seriesModels, function (seriesModel) {
var seriesData = seriesModel.getData();
var dataDims = seriesData.mapDimensionsAll(axisDim);
if (!dataDims.length) {
return;
}
if (filterMode === 'weakFilter') {
var store_1 = seriesData.getStore();
var dataDimIndices_1 = zrUtil.map(dataDims, function (dim) {
return seriesData.getDimensionIndex(dim);
}, seriesData);
seriesData.filterSelf(function (dataIndex) {
var leftOut;
var rightOut;
var hasValue;
for (var i = 0; i < dataDims.length; i++) {
var value = store_1.get(dataDimIndices_1[i], dataIndex);
var thisHasValue = !isNaN(value);
var thisLeftOut = value < valueWindow[0];
var thisRightOut = value > valueWindow[1];
if (thisHasValue && !thisLeftOut && !thisRightOut) {
return true;
}
thisHasValue && (hasValue = true);
thisLeftOut && (leftOut = true);
thisRightOut && (rightOut = true);
}
// If both left out and right out, do not filter.
return hasValue && leftOut && rightOut;
});
} else {
each(dataDims, function (dim) {
if (filterMode === 'empty') {
seriesModel.setData(seriesData = seriesData.map(dim, function (value) {
return !isInWindow(value) ? NaN : value;
}));
} else {
var range = {};
range[dim] = valueWindow;
// console.time('select');
seriesData.selectRange(range);
// console.timeEnd('select');
}
});
}
each(dataDims, function (dim) {
seriesData.setApproximateExtent(valueWindow, dim);
});
});
function isInWindow(value) {
return value >= valueWindow[0] && value <= valueWindow[1];
}
};
AxisProxy.prototype._updateMinMaxSpan = function () {
var minMaxSpan = this._minMaxSpan = {};
var dataZoomModel = this._dataZoomModel;
var dataExtent = this._dataExtent;
each(['min', 'max'], function (minMax) {
var percentSpan = dataZoomModel.get(minMax + 'Span');
var valueSpan = dataZoomModel.get(minMax + 'ValueSpan');
valueSpan != null && (valueSpan = this.getAxisModel().axis.scale.parse(valueSpan));
// minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan
if (valueSpan != null) {
percentSpan = numberUtil.linearMap(dataExtent[0] + valueSpan, dataExtent, [0, 100], true);
} else if (percentSpan != null) {
valueSpan = numberUtil.linearMap(percentSpan, [0, 100], dataExtent, true) - dataExtent[0];
}
minMaxSpan[minMax + 'Span'] = percentSpan;
minMaxSpan[minMax + 'ValueSpan'] = valueSpan;
}, this);
};
AxisProxy.prototype._setAxisModel = function () {
var axisModel = this.getAxisModel();
var percentWindow = this._percentWindow;
var valueWindow = this._valueWindow;
if (!percentWindow) {
return;
}
// [0, 500]: arbitrary value, guess axis extent.
var precision = numberUtil.getPixelPrecision(valueWindow, [0, 500]);
precision = Math.min(precision, 20);
// For value axis, if min/max/scale are not set, we just use the extent obtained
// by series data, which may be a little different from the extent calculated by
// `axisHelper.getScaleExtent`. But the different just affects the experience a
// little when zooming. So it will not be fixed until some users require it strongly.
var rawExtentInfo = axisModel.axis.scale.rawExtentInfo;
if (percentWindow[0] !== 0) {
rawExtentInfo.setDeterminedMinMax('min', +valueWindow[0].toFixed(precision));
}
if (percentWindow[1] !== 100) {
rawExtentInfo.setDeterminedMinMax('max', +valueWindow[1].toFixed(precision));
}
rawExtentInfo.freeze();
};
return AxisProxy;
}();
function calculateDataExtent(axisProxy, axisDim, seriesModels) {
var dataExtent = [Infinity, -Infinity];
each(seriesModels, function (seriesModel) {
unionAxisExtentFromData(dataExtent, seriesModel.getData(), axisDim);
});
// It is important to get "consistent" extent when more then one axes is
// controlled by a `dataZoom`, otherwise those axes will not be synchronized
// when zooming. But it is difficult to know what is "consistent", considering
// axes have different type or even different meanings (For example, two
// time axes are used to compare data of the same date in different years).
// So basically dataZoom just obtains extent by series.data (in category axis
// extent can be obtained from axis.data).
// Nevertheless, user can set min/max/scale on axes to make extent of axes
// consistent.
var axisModel = axisProxy.getAxisModel();
var rawExtentResult = ensureScaleRawExtentInfo(axisModel.axis.scale, axisModel, dataExtent).calculate();
return [rawExtentResult.min, rawExtentResult.max];
}
export default AxisProxy;

View File

@@ -0,0 +1,429 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import { each, createHashMap, merge, assert } from 'zrender/lib/core/util.js';
import ComponentModel from '../../model/Component.js';
import { getAxisMainType, DATA_ZOOM_AXIS_DIMENSIONS } from './helper.js';
import { MULTIPLE_REFERRING, SINGLE_REFERRING } from '../../util/model.js';
var DataZoomAxisInfo = /** @class */function () {
function DataZoomAxisInfo() {
this.indexList = [];
this.indexMap = [];
}
DataZoomAxisInfo.prototype.add = function (axisCmptIdx) {
// Remove duplication.
if (!this.indexMap[axisCmptIdx]) {
this.indexList.push(axisCmptIdx);
this.indexMap[axisCmptIdx] = true;
}
};
return DataZoomAxisInfo;
}();
var DataZoomModel = /** @class */function (_super) {
__extends(DataZoomModel, _super);
function DataZoomModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = DataZoomModel.type;
_this._autoThrottle = true;
_this._noTarget = true;
/**
* It is `[rangeModeForMin, rangeModeForMax]`.
* The optional values for `rangeMode`:
* + `'value'` mode: the axis extent will always be determined by
* `dataZoom.startValue` and `dataZoom.endValue`, despite
* how data like and how `axis.min` and `axis.max` are.
* + `'percent'` mode: `100` represents 100% of the `[dMin, dMax]`,
* where `dMin` is `axis.min` if `axis.min` specified, otherwise `data.extent[0]`,
* and `dMax` is `axis.max` if `axis.max` specified, otherwise `data.extent[1]`.
* Axis extent will be determined by the result of the percent of `[dMin, dMax]`.
*
* For example, when users are using dynamic data (update data periodically via `setOption`),
* if in `'value`' mode, the window will be kept in a fixed value range despite how
* data are appended, while if in `'percent'` mode, whe window range will be changed alone with
* the appended data (suppose `axis.min` and `axis.max` are not specified).
*/
_this._rangePropMode = ['percent', 'percent'];
return _this;
}
DataZoomModel.prototype.init = function (option, parentModel, ecModel) {
var inputRawOption = retrieveRawOption(option);
/**
* Suppose a "main process" start at the point that model prepared (that is,
* model initialized or merged or method called in `action`).
* We should keep the `main process` idempotent, that is, given a set of values
* on `option`, we get the same result.
*
* But sometimes, values on `option` will be updated for providing users
* a "final calculated value" (`dataZoomProcessor` will do that). Those value
* should not be the base/input of the `main process`.
*
* So in that case we should save and keep the input of the `main process`
* separately, called `settledOption`.
*
* For example, consider the case:
* (Step_1) brush zoom the grid by `toolbox.dataZoom`,
* where the original input `option.startValue`, `option.endValue` are earsed by
* calculated value.
* (Step)2) click the legend to hide and show a series,
* where the new range is calculated by the earsed `startValue` and `endValue`,
* which brings incorrect result.
*/
this.settledOption = inputRawOption;
this.mergeDefaultAndTheme(option, ecModel);
this._doInit(inputRawOption);
};
DataZoomModel.prototype.mergeOption = function (newOption) {
var inputRawOption = retrieveRawOption(newOption);
// FIX #2591
merge(this.option, newOption, true);
merge(this.settledOption, inputRawOption, true);
this._doInit(inputRawOption);
};
DataZoomModel.prototype._doInit = function (inputRawOption) {
var thisOption = this.option;
this._setDefaultThrottle(inputRawOption);
this._updateRangeUse(inputRawOption);
var settledOption = this.settledOption;
each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
// start/end has higher priority over startValue/endValue if they
// both set, but we should make chart.setOption({endValue: 1000})
// effective, rather than chart.setOption({endValue: 1000, end: null}).
if (this._rangePropMode[index] === 'value') {
thisOption[names[0]] = settledOption[names[0]] = null;
}
// Otherwise do nothing and use the merge result.
}, this);
this._resetTarget();
};
DataZoomModel.prototype._resetTarget = function () {
var optionOrient = this.get('orient', true);
var targetAxisIndexMap = this._targetAxisInfoMap = createHashMap();
var hasAxisSpecified = this._fillSpecifiedTargetAxis(targetAxisIndexMap);
if (hasAxisSpecified) {
this._orient = optionOrient || this._makeAutoOrientByTargetAxis();
} else {
this._orient = optionOrient || 'horizontal';
this._fillAutoTargetAxisByOrient(targetAxisIndexMap, this._orient);
}
this._noTarget = true;
targetAxisIndexMap.each(function (axisInfo) {
if (axisInfo.indexList.length) {
this._noTarget = false;
}
}, this);
};
DataZoomModel.prototype._fillSpecifiedTargetAxis = function (targetAxisIndexMap) {
var hasAxisSpecified = false;
each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
var refering = this.getReferringComponents(getAxisMainType(axisDim), MULTIPLE_REFERRING);
// When user set axisIndex as a empty array, we think that user specify axisIndex
// but do not want use auto mode. Because empty array may be encountered when
// some error occurred.
if (!refering.specified) {
return;
}
hasAxisSpecified = true;
var axisInfo = new DataZoomAxisInfo();
each(refering.models, function (axisModel) {
axisInfo.add(axisModel.componentIndex);
});
targetAxisIndexMap.set(axisDim, axisInfo);
}, this);
return hasAxisSpecified;
};
DataZoomModel.prototype._fillAutoTargetAxisByOrient = function (targetAxisIndexMap, orient) {
var ecModel = this.ecModel;
var needAuto = true;
// Find axis that parallel to dataZoom as default.
if (needAuto) {
var axisDim = orient === 'vertical' ? 'y' : 'x';
var axisModels = ecModel.findComponents({
mainType: axisDim + 'Axis'
});
setParallelAxis(axisModels, axisDim);
}
// Find axis that parallel to dataZoom as default.
if (needAuto) {
var axisModels = ecModel.findComponents({
mainType: 'singleAxis',
filter: function (axisModel) {
return axisModel.get('orient', true) === orient;
}
});
setParallelAxis(axisModels, 'single');
}
function setParallelAxis(axisModels, axisDim) {
// At least use the first parallel axis as the target axis.
var axisModel = axisModels[0];
if (!axisModel) {
return;
}
var axisInfo = new DataZoomAxisInfo();
axisInfo.add(axisModel.componentIndex);
targetAxisIndexMap.set(axisDim, axisInfo);
needAuto = false;
// Find parallel axes in the same grid.
if (axisDim === 'x' || axisDim === 'y') {
var gridModel_1 = axisModel.getReferringComponents('grid', SINGLE_REFERRING).models[0];
gridModel_1 && each(axisModels, function (axModel) {
if (axisModel.componentIndex !== axModel.componentIndex && gridModel_1 === axModel.getReferringComponents('grid', SINGLE_REFERRING).models[0]) {
axisInfo.add(axModel.componentIndex);
}
});
}
}
if (needAuto) {
// If no parallel axis, find the first category axis as default. (Also consider polar).
each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
if (!needAuto) {
return;
}
var axisModels = ecModel.findComponents({
mainType: getAxisMainType(axisDim),
filter: function (axisModel) {
return axisModel.get('type', true) === 'category';
}
});
if (axisModels[0]) {
var axisInfo = new DataZoomAxisInfo();
axisInfo.add(axisModels[0].componentIndex);
targetAxisIndexMap.set(axisDim, axisInfo);
needAuto = false;
}
}, this);
}
};
DataZoomModel.prototype._makeAutoOrientByTargetAxis = function () {
var dim;
// Find the first axis
this.eachTargetAxis(function (axisDim) {
!dim && (dim = axisDim);
}, this);
return dim === 'y' ? 'vertical' : 'horizontal';
};
DataZoomModel.prototype._setDefaultThrottle = function (inputRawOption) {
// When first time user set throttle, auto throttle ends.
if (inputRawOption.hasOwnProperty('throttle')) {
this._autoThrottle = false;
}
if (this._autoThrottle) {
var globalOption = this.ecModel.option;
this.option.throttle = globalOption.animation && globalOption.animationDurationUpdate > 0 ? 100 : 20;
}
};
DataZoomModel.prototype._updateRangeUse = function (inputRawOption) {
var rangePropMode = this._rangePropMode;
var rangeModeInOption = this.get('rangeMode');
each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
var percentSpecified = inputRawOption[names[0]] != null;
var valueSpecified = inputRawOption[names[1]] != null;
if (percentSpecified && !valueSpecified) {
rangePropMode[index] = 'percent';
} else if (!percentSpecified && valueSpecified) {
rangePropMode[index] = 'value';
} else if (rangeModeInOption) {
rangePropMode[index] = rangeModeInOption[index];
} else if (percentSpecified) {
// percentSpecified && valueSpecified
rangePropMode[index] = 'percent';
}
// else remain its original setting.
});
};
DataZoomModel.prototype.noTarget = function () {
return this._noTarget;
};
DataZoomModel.prototype.getFirstTargetAxisModel = function () {
var firstAxisModel;
this.eachTargetAxis(function (axisDim, axisIndex) {
if (firstAxisModel == null) {
firstAxisModel = this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
}
}, this);
return firstAxisModel;
};
/**
* @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel
*/
DataZoomModel.prototype.eachTargetAxis = function (callback, context) {
this._targetAxisInfoMap.each(function (axisInfo, axisDim) {
each(axisInfo.indexList, function (axisIndex) {
callback.call(context, axisDim, axisIndex);
});
});
};
/**
* @return If not found, return null/undefined.
*/
DataZoomModel.prototype.getAxisProxy = function (axisDim, axisIndex) {
var axisModel = this.getAxisModel(axisDim, axisIndex);
if (axisModel) {
return axisModel.__dzAxisProxy;
}
};
/**
* @return If not found, return null/undefined.
*/
DataZoomModel.prototype.getAxisModel = function (axisDim, axisIndex) {
if (process.env.NODE_ENV !== 'production') {
assert(axisDim && axisIndex != null);
}
var axisInfo = this._targetAxisInfoMap.get(axisDim);
if (axisInfo && axisInfo.indexMap[axisIndex]) {
return this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
}
};
/**
* If not specified, set to undefined.
*/
DataZoomModel.prototype.setRawRange = function (opt) {
var thisOption = this.option;
var settledOption = this.settledOption;
each([['start', 'startValue'], ['end', 'endValue']], function (names) {
// Consider the pair <start, startValue>:
// If one has value and the other one is `null/undefined`, we both set them
// to `settledOption`. This strategy enables the feature to clear the original
// value in `settledOption` to `null/undefined`.
// But if both of them are `null/undefined`, we do not set them to `settledOption`
// and keep `settledOption` with the original value. This strategy enables users to
// only set <end or endValue> but not set <start or startValue> when calling
// `dispatchAction`.
// The pair <end, endValue> is treated in the same way.
if (opt[names[0]] != null || opt[names[1]] != null) {
thisOption[names[0]] = settledOption[names[0]] = opt[names[0]];
thisOption[names[1]] = settledOption[names[1]] = opt[names[1]];
}
}, this);
this._updateRangeUse(opt);
};
DataZoomModel.prototype.setCalculatedRange = function (opt) {
var option = this.option;
each(['start', 'startValue', 'end', 'endValue'], function (name) {
option[name] = opt[name];
});
};
DataZoomModel.prototype.getPercentRange = function () {
var axisProxy = this.findRepresentativeAxisProxy();
if (axisProxy) {
return axisProxy.getDataPercentWindow();
}
};
/**
* For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0);
*
* @return [startValue, endValue] value can only be '-' or finite number.
*/
DataZoomModel.prototype.getValueRange = function (axisDim, axisIndex) {
if (axisDim == null && axisIndex == null) {
var axisProxy = this.findRepresentativeAxisProxy();
if (axisProxy) {
return axisProxy.getDataValueWindow();
}
} else {
return this.getAxisProxy(axisDim, axisIndex).getDataValueWindow();
}
};
/**
* @param axisModel If axisModel given, find axisProxy
* corresponding to the axisModel
*/
DataZoomModel.prototype.findRepresentativeAxisProxy = function (axisModel) {
if (axisModel) {
return axisModel.__dzAxisProxy;
}
// Find the first hosted axisProxy
var firstProxy;
var axisDimList = this._targetAxisInfoMap.keys();
for (var i = 0; i < axisDimList.length; i++) {
var axisDim = axisDimList[i];
var axisInfo = this._targetAxisInfoMap.get(axisDim);
for (var j = 0; j < axisInfo.indexList.length; j++) {
var proxy = this.getAxisProxy(axisDim, axisInfo.indexList[j]);
if (proxy.hostedBy(this)) {
return proxy;
}
if (!firstProxy) {
firstProxy = proxy;
}
}
}
// If no hosted proxy found, still need to return a proxy.
// This case always happens in toolbox dataZoom, where axes are all hosted by
// other dataZooms.
return firstProxy;
};
DataZoomModel.prototype.getRangePropMode = function () {
return this._rangePropMode.slice();
};
DataZoomModel.prototype.getOrient = function () {
if (process.env.NODE_ENV !== 'production') {
// Should not be called before initialized.
assert(this._orient);
}
return this._orient;
};
DataZoomModel.type = 'dataZoom';
DataZoomModel.dependencies = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series', 'toolbox'];
DataZoomModel.defaultOption = {
// zlevel: 0,
z: 4,
filterMode: 'filter',
start: 0,
end: 100
};
return DataZoomModel;
}(ComponentModel);
/**
* Retrieve those raw params from option, which will be cached separately,
* because they will be overwritten by normalized/calculated values in the main
* process.
*/
function retrieveRawOption(option) {
var ret = {};
each(['start', 'end', 'startValue', 'endValue', 'throttle'], function (name) {
option.hasOwnProperty(name) && (ret[name] = option[name]);
});
return ret;
}
export default DataZoomModel;

View File

@@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import ComponentView from '../../view/Component.js';
var DataZoomView = /** @class */function (_super) {
__extends(DataZoomView, _super);
function DataZoomView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = DataZoomView.type;
return _this;
}
DataZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
this.dataZoomModel = dataZoomModel;
this.ecModel = ecModel;
this.api = api;
};
DataZoomView.type = 'dataZoom';
return DataZoomView;
}(ComponentView);
export default DataZoomView;

View File

@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import DataZoomModel from './DataZoomModel.js';
import { inheritDefaultOption } from '../../util/component.js';
var InsideZoomModel = /** @class */function (_super) {
__extends(InsideZoomModel, _super);
function InsideZoomModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = InsideZoomModel.type;
return _this;
}
InsideZoomModel.type = 'dataZoom.inside';
InsideZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, {
disabled: false,
zoomLock: false,
zoomOnMouseWheel: true,
moveOnMouseMove: true,
moveOnMouseWheel: false,
preventDefaultMouseMove: true
});
return InsideZoomModel;
}(DataZoomModel);
export default InsideZoomModel;

View File

@@ -0,0 +1,198 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import DataZoomView from './DataZoomView.js';
import sliderMove from '../helper/sliderMove.js';
import * as roams from './roams.js';
import { bind } from 'zrender/lib/core/util.js';
var InsideZoomView = /** @class */function (_super) {
__extends(InsideZoomView, _super);
function InsideZoomView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = 'dataZoom.inside';
return _this;
}
InsideZoomView.prototype.render = function (dataZoomModel, ecModel, api) {
_super.prototype.render.apply(this, arguments);
if (dataZoomModel.noTarget()) {
this._clear();
return;
}
// Hence the `throttle` util ensures to preserve command order,
// here simply updating range all the time will not cause missing
// any of the the roam change.
this.range = dataZoomModel.getPercentRange();
// Reset controllers.
roams.setViewInfoToCoordSysRecord(api, dataZoomModel, {
pan: bind(getRangeHandlers.pan, this),
zoom: bind(getRangeHandlers.zoom, this),
scrollMove: bind(getRangeHandlers.scrollMove, this)
});
};
InsideZoomView.prototype.dispose = function () {
this._clear();
_super.prototype.dispose.apply(this, arguments);
};
InsideZoomView.prototype._clear = function () {
roams.disposeCoordSysRecordIfNeeded(this.api, this.dataZoomModel);
this.range = null;
};
InsideZoomView.type = 'dataZoom.inside';
return InsideZoomView;
}(DataZoomView);
var getRangeHandlers = {
zoom: function (coordSysInfo, coordSysMainType, controller, e) {
var lastRange = this.range;
var range = lastRange.slice();
// Calculate transform by the first axis.
var axisModel = coordSysInfo.axisModels[0];
if (!axisModel) {
return;
}
var directionInfo = getDirectionInfo[coordSysMainType](null, [e.originX, e.originY], axisModel, controller, coordSysInfo);
var percentPoint = (directionInfo.signal > 0 ? directionInfo.pixelStart + directionInfo.pixelLength - directionInfo.pixel : directionInfo.pixel - directionInfo.pixelStart) / directionInfo.pixelLength * (range[1] - range[0]) + range[0];
var scale = Math.max(1 / e.scale, 0);
range[0] = (range[0] - percentPoint) * scale + percentPoint;
range[1] = (range[1] - percentPoint) * scale + percentPoint;
// Restrict range.
var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);
this.range = range;
if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
return range;
}
},
pan: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
var directionInfo = getDirectionInfo[coordSysMainType]([e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordSysInfo);
return directionInfo.signal * (range[1] - range[0]) * directionInfo.pixel / directionInfo.pixelLength;
}),
scrollMove: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
var directionInfo = getDirectionInfo[coordSysMainType]([0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordSysInfo);
return directionInfo.signal * (range[1] - range[0]) * e.scrollDelta;
})
};
function makeMover(getPercentDelta) {
return function (coordSysInfo, coordSysMainType, controller, e) {
var lastRange = this.range;
var range = lastRange.slice();
// Calculate transform by the first axis.
var axisModel = coordSysInfo.axisModels[0];
if (!axisModel) {
return;
}
var percentDelta = getPercentDelta(range, axisModel, coordSysInfo, coordSysMainType, controller, e);
sliderMove(percentDelta, range, [0, 100], 'all');
this.range = range;
if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
return range;
}
};
}
var getDirectionInfo = {
grid: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) {
var axis = axisModel.axis;
var ret = {};
var rect = coordSysInfo.model.coordinateSystem.getRect();
oldPoint = oldPoint || [0, 0];
if (axis.dim === 'x') {
ret.pixel = newPoint[0] - oldPoint[0];
ret.pixelLength = rect.width;
ret.pixelStart = rect.x;
ret.signal = axis.inverse ? 1 : -1;
} else {
// axis.dim === 'y'
ret.pixel = newPoint[1] - oldPoint[1];
ret.pixelLength = rect.height;
ret.pixelStart = rect.y;
ret.signal = axis.inverse ? -1 : 1;
}
return ret;
},
polar: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) {
var axis = axisModel.axis;
var ret = {};
var polar = coordSysInfo.model.coordinateSystem;
var radiusExtent = polar.getRadiusAxis().getExtent();
var angleExtent = polar.getAngleAxis().getExtent();
oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0];
newPoint = polar.pointToCoord(newPoint);
if (axisModel.mainType === 'radiusAxis') {
ret.pixel = newPoint[0] - oldPoint[0];
// ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]);
// ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]);
ret.pixelLength = radiusExtent[1] - radiusExtent[0];
ret.pixelStart = radiusExtent[0];
ret.signal = axis.inverse ? 1 : -1;
} else {
// 'angleAxis'
ret.pixel = newPoint[1] - oldPoint[1];
// ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]);
// ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]);
ret.pixelLength = angleExtent[1] - angleExtent[0];
ret.pixelStart = angleExtent[0];
ret.signal = axis.inverse ? -1 : 1;
}
return ret;
},
singleAxis: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) {
var axis = axisModel.axis;
var rect = coordSysInfo.model.coordinateSystem.getRect();
var ret = {};
oldPoint = oldPoint || [0, 0];
if (axis.orient === 'horizontal') {
ret.pixel = newPoint[0] - oldPoint[0];
ret.pixelLength = rect.width;
ret.pixelStart = rect.x;
ret.signal = axis.inverse ? 1 : -1;
} else {
// 'vertical'
ret.pixel = newPoint[1] - oldPoint[1];
ret.pixelLength = rect.height;
ret.pixelStart = rect.y;
ret.signal = axis.inverse ? -1 : 1;
}
return ret;
}
};
export default InsideZoomView;

View File

@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import DataZoomModel from './DataZoomModel.js';
var SelectDataZoomModel = /** @class */function (_super) {
__extends(SelectDataZoomModel, _super);
function SelectDataZoomModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SelectDataZoomModel.type;
return _this;
}
SelectDataZoomModel.type = 'dataZoom.select';
return SelectDataZoomModel;
}(DataZoomModel);
export default SelectDataZoomModel;

View File

@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import DataZoomView from './DataZoomView.js';
var SelectDataZoomView = /** @class */function (_super) {
__extends(SelectDataZoomView, _super);
function SelectDataZoomView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SelectDataZoomView.type;
return _this;
}
SelectDataZoomView.type = 'dataZoom.select';
return SelectDataZoomView;
}(DataZoomView);
export default SelectDataZoomView;

View File

@@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import DataZoomModel from './DataZoomModel.js';
import { inheritDefaultOption } from '../../util/component.js';
var SliderZoomModel = /** @class */function (_super) {
__extends(SliderZoomModel, _super);
function SliderZoomModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SliderZoomModel.type;
return _this;
}
SliderZoomModel.type = 'dataZoom.slider';
SliderZoomModel.layoutMode = 'box';
SliderZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, {
show: true,
// deault value can only be drived in view stage.
right: 'ph',
top: 'ph',
width: 'ph',
height: 'ph',
left: null,
bottom: null,
borderColor: '#d2dbee',
borderRadius: 3,
backgroundColor: 'rgba(47,69,84,0)',
// dataBackgroundColor: '#ddd',
dataBackground: {
lineStyle: {
color: '#d2dbee',
width: 0.5
},
areaStyle: {
color: '#d2dbee',
opacity: 0.2
}
},
selectedDataBackground: {
lineStyle: {
color: '#8fb0f7',
width: 0.5
},
areaStyle: {
color: '#8fb0f7',
opacity: 0.2
}
},
// Color of selected window.
fillerColor: 'rgba(135,175,274,0.2)',
handleIcon: 'path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z',
// Percent of the slider height
handleSize: '100%',
handleStyle: {
color: '#fff',
borderColor: '#ACB8D1'
},
moveHandleSize: 7,
moveHandleIcon: 'path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z',
moveHandleStyle: {
color: '#D2DBEE',
opacity: 0.7
},
showDetail: true,
showDataShadow: 'auto',
realtime: true,
zoomLock: false,
textStyle: {
color: '#6E7079'
},
brushSelect: true,
brushStyle: {
color: 'rgba(135,175,274,0.15)'
},
emphasis: {
handleLabel: {
show: true
},
handleStyle: {
borderColor: '#8FB0F7'
},
moveHandleStyle: {
color: '#8FB0F7'
}
}
});
return SliderZoomModel;
}(DataZoomModel);
export default SliderZoomModel;

View File

@@ -0,0 +1,822 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import { bind, each, isFunction, isString, indexOf } from 'zrender/lib/core/util.js';
import * as eventTool from 'zrender/lib/core/event.js';
import * as graphic from '../../util/graphic.js';
import * as throttle from '../../util/throttle.js';
import DataZoomView from './DataZoomView.js';
import { linearMap, asc, parsePercent } from '../../util/number.js';
import * as layout from '../../util/layout.js';
import sliderMove from '../helper/sliderMove.js';
import { getAxisMainType, collectReferCoordSysModelInfo } from './helper.js';
import { enableHoverEmphasis } from '../../util/states.js';
import { createSymbol, symbolBuildProxies } from '../../util/symbol.js';
import { deprecateLog } from '../../util/log.js';
import { createTextStyle } from '../../label/labelStyle.js';
var Rect = graphic.Rect;
// Constants
var DEFAULT_LOCATION_EDGE_GAP = 7;
var DEFAULT_FRAME_BORDER_WIDTH = 1;
var DEFAULT_FILLER_SIZE = 30;
var DEFAULT_MOVE_HANDLE_SIZE = 7;
var HORIZONTAL = 'horizontal';
var VERTICAL = 'vertical';
var LABEL_GAP = 5;
var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];
var REALTIME_ANIMATION_CONFIG = {
easing: 'cubicOut',
duration: 100,
delay: 0
};
var SliderZoomView = /** @class */function (_super) {
__extends(SliderZoomView, _super);
function SliderZoomView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SliderZoomView.type;
_this._displayables = {};
return _this;
}
SliderZoomView.prototype.init = function (ecModel, api) {
this.api = api;
// A unique handler for each dataZoom component
this._onBrush = bind(this._onBrush, this);
this._onBrushEnd = bind(this._onBrushEnd, this);
};
SliderZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
_super.prototype.render.apply(this, arguments);
throttle.createOrUpdate(this, '_dispatchZoomAction', dataZoomModel.get('throttle'), 'fixRate');
this._orient = dataZoomModel.getOrient();
if (dataZoomModel.get('show') === false) {
this.group.removeAll();
return;
}
if (dataZoomModel.noTarget()) {
this._clear();
this.group.removeAll();
return;
}
// Notice: this._resetInterval() should not be executed when payload.type
// is 'dataZoom', origin this._range should be maintained, otherwise 'pan'
// or 'zoom' info will be missed because of 'throttle' of this.dispatchAction,
if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) {
this._buildView();
}
this._updateView();
};
SliderZoomView.prototype.dispose = function () {
this._clear();
_super.prototype.dispose.apply(this, arguments);
};
SliderZoomView.prototype._clear = function () {
throttle.clear(this, '_dispatchZoomAction');
var zr = this.api.getZr();
zr.off('mousemove', this._onBrush);
zr.off('mouseup', this._onBrushEnd);
};
SliderZoomView.prototype._buildView = function () {
var thisGroup = this.group;
thisGroup.removeAll();
this._brushing = false;
this._displayables.brushRect = null;
this._resetLocation();
this._resetInterval();
var barGroup = this._displayables.sliderGroup = new graphic.Group();
this._renderBackground();
this._renderHandle();
this._renderDataShadow();
thisGroup.add(barGroup);
this._positionGroup();
};
SliderZoomView.prototype._resetLocation = function () {
var dataZoomModel = this.dataZoomModel;
var api = this.api;
var showMoveHandle = dataZoomModel.get('brushSelect');
var moveHandleSize = showMoveHandle ? DEFAULT_MOVE_HANDLE_SIZE : 0;
// If some of x/y/width/height are not specified,
// auto-adapt according to target grid.
var coordRect = this._findCoordRect();
var ecSize = {
width: api.getWidth(),
height: api.getHeight()
};
// Default align by coordinate system rect.
var positionInfo = this._orient === HORIZONTAL ? {
// Why using 'right', because right should be used in vertical,
// and it is better to be consistent for dealing with position param merge.
right: ecSize.width - coordRect.x - coordRect.width,
top: ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP - moveHandleSize,
width: coordRect.width,
height: DEFAULT_FILLER_SIZE
} : {
right: DEFAULT_LOCATION_EDGE_GAP,
top: coordRect.y,
width: DEFAULT_FILLER_SIZE,
height: coordRect.height
};
// Do not write back to option and replace value 'ph', because
// the 'ph' value should be recalculated when resize.
var layoutParams = layout.getLayoutParams(dataZoomModel.option);
// Replace the placeholder value.
each(['right', 'top', 'width', 'height'], function (name) {
if (layoutParams[name] === 'ph') {
layoutParams[name] = positionInfo[name];
}
});
var layoutRect = layout.getLayoutRect(layoutParams, ecSize);
this._location = {
x: layoutRect.x,
y: layoutRect.y
};
this._size = [layoutRect.width, layoutRect.height];
this._orient === VERTICAL && this._size.reverse();
};
SliderZoomView.prototype._positionGroup = function () {
var thisGroup = this.group;
var location = this._location;
var orient = this._orient;
// Just use the first axis to determine mapping.
var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel();
var inverse = targetAxisModel && targetAxisModel.get('inverse');
var sliderGroup = this._displayables.sliderGroup;
var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse;
// Transform barGroup.
sliderGroup.attr(orient === HORIZONTAL && !inverse ? {
scaleY: otherAxisInverse ? 1 : -1,
scaleX: 1
} : orient === HORIZONTAL && inverse ? {
scaleY: otherAxisInverse ? 1 : -1,
scaleX: -1
} : orient === VERTICAL && !inverse ? {
scaleY: otherAxisInverse ? -1 : 1,
scaleX: 1,
rotation: Math.PI / 2
}
// Don't use Math.PI, considering shadow direction.
: {
scaleY: otherAxisInverse ? -1 : 1,
scaleX: -1,
rotation: Math.PI / 2
});
// Position barGroup
var rect = thisGroup.getBoundingRect([sliderGroup]);
thisGroup.x = location.x - rect.x;
thisGroup.y = location.y - rect.y;
thisGroup.markRedraw();
};
SliderZoomView.prototype._getViewExtent = function () {
return [0, this._size[0]];
};
SliderZoomView.prototype._renderBackground = function () {
var dataZoomModel = this.dataZoomModel;
var size = this._size;
var barGroup = this._displayables.sliderGroup;
var brushSelect = dataZoomModel.get('brushSelect');
barGroup.add(new Rect({
silent: true,
shape: {
x: 0,
y: 0,
width: size[0],
height: size[1]
},
style: {
fill: dataZoomModel.get('backgroundColor')
},
z2: -40
}));
// Click panel, over shadow, below handles.
var clickPanel = new Rect({
shape: {
x: 0,
y: 0,
width: size[0],
height: size[1]
},
style: {
fill: 'transparent'
},
z2: 0,
onclick: bind(this._onClickPanel, this)
});
var zr = this.api.getZr();
if (brushSelect) {
clickPanel.on('mousedown', this._onBrushStart, this);
clickPanel.cursor = 'crosshair';
zr.on('mousemove', this._onBrush);
zr.on('mouseup', this._onBrushEnd);
} else {
zr.off('mousemove', this._onBrush);
zr.off('mouseup', this._onBrushEnd);
}
barGroup.add(clickPanel);
};
SliderZoomView.prototype._renderDataShadow = function () {
var info = this._dataShadowInfo = this._prepareDataShadowInfo();
this._displayables.dataShadowSegs = [];
if (!info) {
return;
}
var size = this._size;
var oldSize = this._shadowSize || [];
var seriesModel = info.series;
var data = seriesModel.getRawData();
var candlestickDim = seriesModel.getShadowDim && seriesModel.getShadowDim();
var otherDim = candlestickDim && data.getDimensionInfo(candlestickDim) ? seriesModel.getShadowDim() // @see candlestick
: info.otherDim;
if (otherDim == null) {
return;
}
var polygonPts = this._shadowPolygonPts;
var polylinePts = this._shadowPolylinePts;
// Not re-render if data doesn't change.
if (data !== this._shadowData || otherDim !== this._shadowDim || size[0] !== oldSize[0] || size[1] !== oldSize[1]) {
var otherDataExtent_1 = data.getDataExtent(otherDim);
// Nice extent.
var otherOffset = (otherDataExtent_1[1] - otherDataExtent_1[0]) * 0.3;
otherDataExtent_1 = [otherDataExtent_1[0] - otherOffset, otherDataExtent_1[1] + otherOffset];
var otherShadowExtent_1 = [0, size[1]];
var thisShadowExtent = [0, size[0]];
var areaPoints_1 = [[size[0], 0], [0, 0]];
var linePoints_1 = [];
var step_1 = thisShadowExtent[1] / (data.count() - 1);
var thisCoord_1 = 0;
// Optimize for large data shadow
var stride_1 = Math.round(data.count() / size[0]);
var lastIsEmpty_1;
data.each([otherDim], function (value, index) {
if (stride_1 > 0 && index % stride_1) {
thisCoord_1 += step_1;
return;
}
// FIXME
// Should consider axis.min/axis.max when drawing dataShadow.
// FIXME
// 应该使用统一的空判断还是在list里进行空判断
var isEmpty = value == null || isNaN(value) || value === '';
// See #4235.
var otherCoord = isEmpty ? 0 : linearMap(value, otherDataExtent_1, otherShadowExtent_1, true);
// Attempt to draw data shadow precisely when there are empty value.
if (isEmpty && !lastIsEmpty_1 && index) {
areaPoints_1.push([areaPoints_1[areaPoints_1.length - 1][0], 0]);
linePoints_1.push([linePoints_1[linePoints_1.length - 1][0], 0]);
} else if (!isEmpty && lastIsEmpty_1) {
areaPoints_1.push([thisCoord_1, 0]);
linePoints_1.push([thisCoord_1, 0]);
}
areaPoints_1.push([thisCoord_1, otherCoord]);
linePoints_1.push([thisCoord_1, otherCoord]);
thisCoord_1 += step_1;
lastIsEmpty_1 = isEmpty;
});
polygonPts = this._shadowPolygonPts = areaPoints_1;
polylinePts = this._shadowPolylinePts = linePoints_1;
}
this._shadowData = data;
this._shadowDim = otherDim;
this._shadowSize = [size[0], size[1]];
var dataZoomModel = this.dataZoomModel;
function createDataShadowGroup(isSelectedArea) {
var model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground');
var group = new graphic.Group();
var polygon = new graphic.Polygon({
shape: {
points: polygonPts
},
segmentIgnoreThreshold: 1,
style: model.getModel('areaStyle').getAreaStyle(),
silent: true,
z2: -20
});
var polyline = new graphic.Polyline({
shape: {
points: polylinePts
},
segmentIgnoreThreshold: 1,
style: model.getModel('lineStyle').getLineStyle(),
silent: true,
z2: -19
});
group.add(polygon);
group.add(polyline);
return group;
}
// let dataBackgroundModel = dataZoomModel.getModel('dataBackground');
for (var i = 0; i < 3; i++) {
var group = createDataShadowGroup(i === 1);
this._displayables.sliderGroup.add(group);
this._displayables.dataShadowSegs.push(group);
}
};
SliderZoomView.prototype._prepareDataShadowInfo = function () {
var dataZoomModel = this.dataZoomModel;
var showDataShadow = dataZoomModel.get('showDataShadow');
if (showDataShadow === false) {
return;
}
// Find a representative series.
var result;
var ecModel = this.ecModel;
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
var seriesModels = dataZoomModel.getAxisProxy(axisDim, axisIndex).getTargetSeriesModels();
each(seriesModels, function (seriesModel) {
if (result) {
return;
}
if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) {
return;
}
var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis;
var otherDim = getOtherDim(axisDim);
var otherAxisInverse;
var coordSys = seriesModel.coordinateSystem;
if (otherDim != null && coordSys.getOtherAxis) {
otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse;
}
otherDim = seriesModel.getData().mapDimension(otherDim);
result = {
thisAxis: thisAxis,
series: seriesModel,
thisDim: axisDim,
otherDim: otherDim,
otherAxisInverse: otherAxisInverse
};
}, this);
}, this);
return result;
};
SliderZoomView.prototype._renderHandle = function () {
var thisGroup = this.group;
var displayables = this._displayables;
var handles = displayables.handles = [null, null];
var handleLabels = displayables.handleLabels = [null, null];
var sliderGroup = this._displayables.sliderGroup;
var size = this._size;
var dataZoomModel = this.dataZoomModel;
var api = this.api;
var borderRadius = dataZoomModel.get('borderRadius') || 0;
var brushSelect = dataZoomModel.get('brushSelect');
var filler = displayables.filler = new Rect({
silent: brushSelect,
style: {
fill: dataZoomModel.get('fillerColor')
},
textConfig: {
position: 'inside'
}
});
sliderGroup.add(filler);
// Frame border.
sliderGroup.add(new Rect({
silent: true,
subPixelOptimize: true,
shape: {
x: 0,
y: 0,
width: size[0],
height: size[1],
r: borderRadius
},
style: {
// deprecated option
stroke: dataZoomModel.get('dataBackgroundColor') || dataZoomModel.get('borderColor'),
lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
fill: 'rgba(0,0,0,0)'
}
}));
// Left and right handle to resize
each([0, 1], function (handleIndex) {
var iconStr = dataZoomModel.get('handleIcon');
if (!symbolBuildProxies[iconStr] && iconStr.indexOf('path://') < 0 && iconStr.indexOf('image://') < 0) {
// Compatitable with the old icon parsers. Which can use a path string without path://
iconStr = 'path://' + iconStr;
if (process.env.NODE_ENV !== 'production') {
deprecateLog('handleIcon now needs \'path://\' prefix when using a path string');
}
}
var path = createSymbol(iconStr, -1, 0, 2, 2, null, true);
path.attr({
cursor: getCursor(this._orient),
draggable: true,
drift: bind(this._onDragMove, this, handleIndex),
ondragend: bind(this._onDragEnd, this),
onmouseover: bind(this._showDataInfo, this, true),
onmouseout: bind(this._showDataInfo, this, false),
z2: 5
});
var bRect = path.getBoundingRect();
var handleSize = dataZoomModel.get('handleSize');
this._handleHeight = parsePercent(handleSize, this._size[1]);
this._handleWidth = bRect.width / bRect.height * this._handleHeight;
path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle());
path.style.strokeNoScale = true;
path.rectHover = true;
path.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'handleStyle']).getItemStyle();
enableHoverEmphasis(path);
var handleColor = dataZoomModel.get('handleColor'); // deprecated option
// Compatitable with previous version
if (handleColor != null) {
path.style.fill = handleColor;
}
sliderGroup.add(handles[handleIndex] = path);
var textStyleModel = dataZoomModel.getModel('textStyle');
var handleLabel = dataZoomModel.get('handleLabel') || {};
var handleLabelShow = handleLabel.show || false;
thisGroup.add(handleLabels[handleIndex] = new graphic.Text({
silent: true,
invisible: !handleLabelShow,
style: createTextStyle(textStyleModel, {
x: 0,
y: 0,
text: '',
verticalAlign: 'middle',
align: 'center',
fill: textStyleModel.getTextColor(),
font: textStyleModel.getFont()
}),
z2: 10
}));
}, this);
// Handle to move. Only visible when brushSelect is set true.
var actualMoveZone = filler;
if (brushSelect) {
var moveHandleHeight = parsePercent(dataZoomModel.get('moveHandleSize'), size[1]);
var moveHandle_1 = displayables.moveHandle = new graphic.Rect({
style: dataZoomModel.getModel('moveHandleStyle').getItemStyle(),
silent: true,
shape: {
r: [0, 0, 2, 2],
y: size[1] - 0.5,
height: moveHandleHeight
}
});
var iconSize = moveHandleHeight * 0.8;
var moveHandleIcon = displayables.moveHandleIcon = createSymbol(dataZoomModel.get('moveHandleIcon'), -iconSize / 2, -iconSize / 2, iconSize, iconSize, '#fff', true);
moveHandleIcon.silent = true;
moveHandleIcon.y = size[1] + moveHandleHeight / 2 - 0.5;
moveHandle_1.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'moveHandleStyle']).getItemStyle();
var moveZoneExpandSize = Math.min(size[1] / 2, Math.max(moveHandleHeight, 10));
actualMoveZone = displayables.moveZone = new graphic.Rect({
invisible: true,
shape: {
y: size[1] - moveZoneExpandSize,
height: moveHandleHeight + moveZoneExpandSize
}
});
actualMoveZone.on('mouseover', function () {
api.enterEmphasis(moveHandle_1);
}).on('mouseout', function () {
api.leaveEmphasis(moveHandle_1);
});
sliderGroup.add(moveHandle_1);
sliderGroup.add(moveHandleIcon);
sliderGroup.add(actualMoveZone);
}
actualMoveZone.attr({
draggable: true,
cursor: getCursor(this._orient),
drift: bind(this._onDragMove, this, 'all'),
ondragstart: bind(this._showDataInfo, this, true),
ondragend: bind(this._onDragEnd, this),
onmouseover: bind(this._showDataInfo, this, true),
onmouseout: bind(this._showDataInfo, this, false)
});
};
SliderZoomView.prototype._resetInterval = function () {
var range = this._range = this.dataZoomModel.getPercentRange();
var viewExtent = this._getViewExtent();
this._handleEnds = [linearMap(range[0], [0, 100], viewExtent, true), linearMap(range[1], [0, 100], viewExtent, true)];
};
SliderZoomView.prototype._updateInterval = function (handleIndex, delta) {
var dataZoomModel = this.dataZoomModel;
var handleEnds = this._handleEnds;
var viewExtend = this._getViewExtent();
var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
var percentExtent = [0, 100];
sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null);
var lastRange = this._range;
var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]);
return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
};
SliderZoomView.prototype._updateView = function (nonRealtime) {
var displaybles = this._displayables;
var handleEnds = this._handleEnds;
var handleInterval = asc(handleEnds.slice());
var size = this._size;
each([0, 1], function (handleIndex) {
// Handles
var handle = displaybles.handles[handleIndex];
var handleHeight = this._handleHeight;
handle.attr({
scaleX: handleHeight / 2,
scaleY: handleHeight / 2,
// This is a trick, by adding an extra tiny offset to let the default handle's end point align to the drag window.
// NOTE: It may affect some custom shapes a bit. But we prefer to have better result by default.
x: handleEnds[handleIndex] + (handleIndex ? -1 : 1),
y: size[1] / 2 - handleHeight / 2
});
}, this);
// Filler
displaybles.filler.setShape({
x: handleInterval[0],
y: 0,
width: handleInterval[1] - handleInterval[0],
height: size[1]
});
var viewExtent = {
x: handleInterval[0],
width: handleInterval[1] - handleInterval[0]
};
// Move handle
if (displaybles.moveHandle) {
displaybles.moveHandle.setShape(viewExtent);
displaybles.moveZone.setShape(viewExtent);
// Force update path on the invisible object
displaybles.moveZone.getBoundingRect();
displaybles.moveHandleIcon && displaybles.moveHandleIcon.attr('x', viewExtent.x + viewExtent.width / 2);
}
// update clip path of shadow.
var dataShadowSegs = displaybles.dataShadowSegs;
var segIntervals = [0, handleInterval[0], handleInterval[1], size[0]];
for (var i = 0; i < dataShadowSegs.length; i++) {
var segGroup = dataShadowSegs[i];
var clipPath = segGroup.getClipPath();
if (!clipPath) {
clipPath = new graphic.Rect();
segGroup.setClipPath(clipPath);
}
clipPath.setShape({
x: segIntervals[i],
y: 0,
width: segIntervals[i + 1] - segIntervals[i],
height: size[1]
});
}
this._updateDataInfo(nonRealtime);
};
SliderZoomView.prototype._updateDataInfo = function (nonRealtime) {
var dataZoomModel = this.dataZoomModel;
var displaybles = this._displayables;
var handleLabels = displaybles.handleLabels;
var orient = this._orient;
var labelTexts = ['', ''];
// FIXME
// date型支持formatterautoformatterec2 date.getAutoFormatter
if (dataZoomModel.get('showDetail')) {
var axisProxy = dataZoomModel.findRepresentativeAxisProxy();
if (axisProxy) {
var axis = axisProxy.getAxisModel().axis;
var range = this._range;
var dataInterval = nonRealtime
// See #4434, data and axis are not processed and reset yet in non-realtime mode.
? axisProxy.calculateDataWindow({
start: range[0],
end: range[1]
}).valueWindow : axisProxy.getDataValueWindow();
labelTexts = [this._formatLabel(dataInterval[0], axis), this._formatLabel(dataInterval[1], axis)];
}
}
var orderedHandleEnds = asc(this._handleEnds.slice());
setLabel.call(this, 0);
setLabel.call(this, 1);
function setLabel(handleIndex) {
// Label
// Text should not transform by barGroup.
// Ignore handlers transform
var barTransform = graphic.getTransform(displaybles.handles[handleIndex].parent, this.group);
var direction = graphic.transformDirection(handleIndex === 0 ? 'right' : 'left', barTransform);
var offset = this._handleWidth / 2 + LABEL_GAP;
var textPoint = graphic.applyTransform([orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset), this._size[1] / 2], barTransform);
handleLabels[handleIndex].setStyle({
x: textPoint[0],
y: textPoint[1],
verticalAlign: orient === HORIZONTAL ? 'middle' : direction,
align: orient === HORIZONTAL ? direction : 'center',
text: labelTexts[handleIndex]
});
}
};
SliderZoomView.prototype._formatLabel = function (value, axis) {
var dataZoomModel = this.dataZoomModel;
var labelFormatter = dataZoomModel.get('labelFormatter');
var labelPrecision = dataZoomModel.get('labelPrecision');
if (labelPrecision == null || labelPrecision === 'auto') {
labelPrecision = axis.getPixelPrecision();
}
var valueStr = value == null || isNaN(value) ? ''
// FIXME Glue code
: axis.type === 'category' || axis.type === 'time' ? axis.scale.getLabel({
value: Math.round(value)
})
// param of toFixed should less then 20.
: value.toFixed(Math.min(labelPrecision, 20));
return isFunction(labelFormatter) ? labelFormatter(value, valueStr) : isString(labelFormatter) ? labelFormatter.replace('{value}', valueStr) : valueStr;
};
/**
* @param isEmphasis true: show, false: hide
*/
SliderZoomView.prototype._showDataInfo = function (isEmphasis) {
var handleLabel = this.dataZoomModel.get('handleLabel') || {};
var normalShow = handleLabel.show || false;
var emphasisHandleLabel = this.dataZoomModel.getModel(['emphasis', 'handleLabel']);
var emphasisShow = emphasisHandleLabel.get('show') || false;
// Dragging is considered as emphasis, unless emphasisShow is false
var toShow = isEmphasis || this._dragging ? emphasisShow : normalShow;
var displayables = this._displayables;
var handleLabels = displayables.handleLabels;
handleLabels[0].attr('invisible', !toShow);
handleLabels[1].attr('invisible', !toShow);
// Highlight move handle
displayables.moveHandle && this.api[toShow ? 'enterEmphasis' : 'leaveEmphasis'](displayables.moveHandle, 1);
};
SliderZoomView.prototype._onDragMove = function (handleIndex, dx, dy, event) {
this._dragging = true;
// For mobile device, prevent screen slider on the button.
eventTool.stop(event.event);
// Transform dx, dy to bar coordination.
var barTransform = this._displayables.sliderGroup.getLocalTransform();
var vertex = graphic.applyTransform([dx, dy], barTransform, true);
var changed = this._updateInterval(handleIndex, vertex[0]);
var realtime = this.dataZoomModel.get('realtime');
this._updateView(!realtime);
// Avoid dispatch dataZoom repeatly but range not changed,
// which cause bad visual effect when progressive enabled.
changed && realtime && this._dispatchZoomAction(true);
};
SliderZoomView.prototype._onDragEnd = function () {
this._dragging = false;
this._showDataInfo(false);
// While in realtime mode and stream mode, dispatch action when
// drag end will cause the whole view rerender, which is unnecessary.
var realtime = this.dataZoomModel.get('realtime');
!realtime && this._dispatchZoomAction(false);
};
SliderZoomView.prototype._onClickPanel = function (e) {
var size = this._size;
var localPoint = this._displayables.sliderGroup.transformCoordToLocal(e.offsetX, e.offsetY);
if (localPoint[0] < 0 || localPoint[0] > size[0] || localPoint[1] < 0 || localPoint[1] > size[1]) {
return;
}
var handleEnds = this._handleEnds;
var center = (handleEnds[0] + handleEnds[1]) / 2;
var changed = this._updateInterval('all', localPoint[0] - center);
this._updateView();
changed && this._dispatchZoomAction(false);
};
SliderZoomView.prototype._onBrushStart = function (e) {
var x = e.offsetX;
var y = e.offsetY;
this._brushStart = new graphic.Point(x, y);
this._brushing = true;
this._brushStartTime = +new Date();
// this._updateBrushRect(x, y);
};
SliderZoomView.prototype._onBrushEnd = function (e) {
if (!this._brushing) {
return;
}
var brushRect = this._displayables.brushRect;
this._brushing = false;
if (!brushRect) {
return;
}
brushRect.attr('ignore', true);
var brushShape = brushRect.shape;
var brushEndTime = +new Date();
// console.log(brushEndTime - this._brushStartTime);
if (brushEndTime - this._brushStartTime < 200 && Math.abs(brushShape.width) < 5) {
// Will treat it as a click
return;
}
var viewExtend = this._getViewExtent();
var percentExtent = [0, 100];
this._range = asc([linearMap(brushShape.x, viewExtend, percentExtent, true), linearMap(brushShape.x + brushShape.width, viewExtend, percentExtent, true)]);
this._handleEnds = [brushShape.x, brushShape.x + brushShape.width];
this._updateView();
this._dispatchZoomAction(false);
};
SliderZoomView.prototype._onBrush = function (e) {
if (this._brushing) {
// For mobile device, prevent screen slider on the button.
eventTool.stop(e.event);
this._updateBrushRect(e.offsetX, e.offsetY);
}
};
SliderZoomView.prototype._updateBrushRect = function (mouseX, mouseY) {
var displayables = this._displayables;
var dataZoomModel = this.dataZoomModel;
var brushRect = displayables.brushRect;
if (!brushRect) {
brushRect = displayables.brushRect = new Rect({
silent: true,
style: dataZoomModel.getModel('brushStyle').getItemStyle()
});
displayables.sliderGroup.add(brushRect);
}
brushRect.attr('ignore', false);
var brushStart = this._brushStart;
var sliderGroup = this._displayables.sliderGroup;
var endPoint = sliderGroup.transformCoordToLocal(mouseX, mouseY);
var startPoint = sliderGroup.transformCoordToLocal(brushStart.x, brushStart.y);
var size = this._size;
endPoint[0] = Math.max(Math.min(size[0], endPoint[0]), 0);
brushRect.setShape({
x: startPoint[0],
y: 0,
width: endPoint[0] - startPoint[0],
height: size[1]
});
};
/**
* This action will be throttled.
*/
SliderZoomView.prototype._dispatchZoomAction = function (realtime) {
var range = this._range;
this.api.dispatchAction({
type: 'dataZoom',
from: this.uid,
dataZoomId: this.dataZoomModel.id,
animation: realtime ? REALTIME_ANIMATION_CONFIG : null,
start: range[0],
end: range[1]
});
};
SliderZoomView.prototype._findCoordRect = function () {
// Find the grid corresponding to the first axis referred by dataZoom.
var rect;
var coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList;
if (!rect && coordSysInfoList.length) {
var coordSys = coordSysInfoList[0].model.coordinateSystem;
rect = coordSys.getRect && coordSys.getRect();
}
if (!rect) {
var width = this.api.getWidth();
var height = this.api.getHeight();
rect = {
x: width * 0.2,
y: height * 0.2,
width: width * 0.6,
height: height * 0.6
};
}
return rect;
};
SliderZoomView.type = 'dataZoom.slider';
return SliderZoomView;
}(DataZoomView);
function getOtherDim(thisDim) {
// FIXME
// 这个逻辑和getOtherAxis里一致但是写在这里是否不好
var map = {
x: 'y',
y: 'x',
radius: 'angle',
angle: 'radius'
};
return map[thisDim];
}
function getCursor(orient) {
return orient === 'vertical' ? 'ns-resize' : 'ew-resize';
}
export default SliderZoomView;

View File

@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { findEffectedDataZooms } from './helper.js';
import { each } from 'zrender/lib/core/util.js';
export default function installDataZoomAction(registers) {
registers.registerAction('dataZoom', function (payload, ecModel) {
var effectedModels = findEffectedDataZooms(ecModel, payload);
each(effectedModels, function (dataZoomModel) {
dataZoomModel.setRawRange({
start: payload.start,
end: payload.end,
startValue: payload.startValue,
endValue: payload.endValue
});
});
});
}

View File

@@ -0,0 +1,130 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { createHashMap, each } from 'zrender/lib/core/util.js';
import { getAxisMainType } from './helper.js';
import AxisProxy from './AxisProxy.js';
var dataZoomProcessor = {
// `dataZoomProcessor` will only be performed in needed series. Consider if
// there is a line series and a pie series, it is better not to update the
// line series if only pie series is needed to be updated.
getTargetSeries: function (ecModel) {
function eachAxisModel(cb) {
ecModel.eachComponent('dataZoom', function (dataZoomModel) {
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
cb(axisDim, axisIndex, axisModel, dataZoomModel);
});
});
}
// FIXME: it brings side-effect to `getTargetSeries`.
// Prepare axis proxies.
eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) {
// dispose all last axis proxy, in case that some axis are deleted.
axisModel.__dzAxisProxy = null;
});
var proxyList = [];
eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) {
// Different dataZooms may constrol the same axis. In that case,
// an axisProxy serves both of them.
if (!axisModel.__dzAxisProxy) {
// Use the first dataZoomModel as the main model of axisProxy.
axisModel.__dzAxisProxy = new AxisProxy(axisDim, axisIndex, dataZoomModel, ecModel);
proxyList.push(axisModel.__dzAxisProxy);
}
});
var seriesModelMap = createHashMap();
each(proxyList, function (axisProxy) {
each(axisProxy.getTargetSeriesModels(), function (seriesModel) {
seriesModelMap.set(seriesModel.uid, seriesModel);
});
});
return seriesModelMap;
},
// Consider appendData, where filter should be performed. Because data process is
// in block mode currently, it is not need to worry about that the overallProgress
// execute every frame.
overallReset: function (ecModel, api) {
ecModel.eachComponent('dataZoom', function (dataZoomModel) {
// We calculate window and reset axis here but not in model
// init stage and not after action dispatch handler, because
// reset should be called after seriesData.restoreData.
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
dataZoomModel.getAxisProxy(axisDim, axisIndex).reset(dataZoomModel);
});
// Caution: data zoom filtering is order sensitive when using
// percent range and no min/max/scale set on axis.
// For example, we have dataZoom definition:
// [
// {xAxisIndex: 0, start: 30, end: 70},
// {yAxisIndex: 0, start: 20, end: 80}
// ]
// In this case, [20, 80] of y-dataZoom should be based on data
// that have filtered by x-dataZoom using range of [30, 70],
// but should not be based on full raw data. Thus sliding
// x-dataZoom will change both ranges of xAxis and yAxis,
// while sliding y-dataZoom will only change the range of yAxis.
// So we should filter x-axis after reset x-axis immediately,
// and then reset y-axis and filter y-axis.
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
dataZoomModel.getAxisProxy(axisDim, axisIndex).filterData(dataZoomModel, api);
});
});
ecModel.eachComponent('dataZoom', function (dataZoomModel) {
// Fullfill all of the range props so that user
// is able to get them from chart.getOption().
var axisProxy = dataZoomModel.findRepresentativeAxisProxy();
if (axisProxy) {
var percentRange = axisProxy.getDataPercentWindow();
var valueRange = axisProxy.getDataValueWindow();
dataZoomModel.setCalculatedRange({
start: percentRange[0],
end: percentRange[1],
startValue: valueRange[0],
endValue: valueRange[1]
});
}
});
}
};
export default dataZoomProcessor;

View File

@@ -0,0 +1,172 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { indexOf, createHashMap, assert } from 'zrender/lib/core/util.js';
export var DATA_ZOOM_AXIS_DIMENSIONS = ['x', 'y', 'radius', 'angle', 'single'];
// Supported coords.
// FIXME: polar has been broken (but rarely used).
var SERIES_COORDS = ['cartesian2d', 'polar', 'singleAxis'];
export function isCoordSupported(seriesModel) {
var coordType = seriesModel.get('coordinateSystem');
return indexOf(SERIES_COORDS, coordType) >= 0;
}
export function getAxisMainType(axisDim) {
if (process.env.NODE_ENV !== 'production') {
assert(axisDim);
}
return axisDim + 'Axis';
}
export function getAxisIndexPropName(axisDim) {
if (process.env.NODE_ENV !== 'production') {
assert(axisDim);
}
return axisDim + 'AxisIndex';
}
export function getAxisIdPropName(axisDim) {
if (process.env.NODE_ENV !== 'production') {
assert(axisDim);
}
return axisDim + 'AxisId';
}
/**
* If two dataZoomModels has the same axis controlled, we say that they are 'linked'.
* This function finds all linked dataZoomModels start from the given payload.
*/
export function findEffectedDataZooms(ecModel, payload) {
// Key: `DataZoomAxisDimension`
var axisRecords = createHashMap();
var effectedModels = [];
// Key: uid of dataZoomModel
var effectedModelMap = createHashMap();
// Find the dataZooms specified by payload.
ecModel.eachComponent({
mainType: 'dataZoom',
query: payload
}, function (dataZoomModel) {
if (!effectedModelMap.get(dataZoomModel.uid)) {
addToEffected(dataZoomModel);
}
});
// Start from the given dataZoomModels, travel the graph to find
// all of the linked dataZoom models.
var foundNewLink;
do {
foundNewLink = false;
ecModel.eachComponent('dataZoom', processSingle);
} while (foundNewLink);
function processSingle(dataZoomModel) {
if (!effectedModelMap.get(dataZoomModel.uid) && isLinked(dataZoomModel)) {
addToEffected(dataZoomModel);
foundNewLink = true;
}
}
function addToEffected(dataZoom) {
effectedModelMap.set(dataZoom.uid, true);
effectedModels.push(dataZoom);
markAxisControlled(dataZoom);
}
function isLinked(dataZoomModel) {
var isLink = false;
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
var axisIdxArr = axisRecords.get(axisDim);
if (axisIdxArr && axisIdxArr[axisIndex]) {
isLink = true;
}
});
return isLink;
}
function markAxisControlled(dataZoomModel) {
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
(axisRecords.get(axisDim) || axisRecords.set(axisDim, []))[axisIndex] = true;
});
}
return effectedModels;
}
/**
* Find the first target coordinate system.
* Available after model built.
*
* @return Like {
* grid: [
* {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
* {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
* ...
* ], // cartesians must not be null/undefined.
* polar: [
* {model: coord0, axisModels: [axis4], coordIndex: 0},
* ...
* ], // polars must not be null/undefined.
* singleAxis: [
* {model: coord0, axisModels: [], coordIndex: 0}
* ]
* }
*/
export function collectReferCoordSysModelInfo(dataZoomModel) {
var ecModel = dataZoomModel.ecModel;
var coordSysInfoWrap = {
infoList: [],
infoMap: createHashMap()
};
dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
if (!axisModel) {
return;
}
var coordSysModel = axisModel.getCoordSysModel();
if (!coordSysModel) {
return;
}
var coordSysUid = coordSysModel.uid;
var coordSysInfo = coordSysInfoWrap.infoMap.get(coordSysUid);
if (!coordSysInfo) {
coordSysInfo = {
model: coordSysModel,
axisModels: []
};
coordSysInfoWrap.infoList.push(coordSysInfo);
coordSysInfoWrap.infoMap.set(coordSysUid, coordSysInfo);
}
coordSysInfo.axisModels.push(axisModel);
});
return coordSysInfoWrap;
}

View File

@@ -0,0 +1,116 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import { makeInner } from '../../util/model.js';
var each = zrUtil.each;
var inner = makeInner();
/**
* @param ecModel
* @param newSnapshot key is dataZoomId
*/
export function push(ecModel, newSnapshot) {
var storedSnapshots = getStoreSnapshots(ecModel);
// If previous dataZoom can not be found,
// complete an range with current range.
each(newSnapshot, function (batchItem, dataZoomId) {
var i = storedSnapshots.length - 1;
for (; i >= 0; i--) {
var snapshot = storedSnapshots[i];
if (snapshot[dataZoomId]) {
break;
}
}
if (i < 0) {
// No origin range set, create one by current range.
var dataZoomModel = ecModel.queryComponents({
mainType: 'dataZoom',
subType: 'select',
id: dataZoomId
})[0];
if (dataZoomModel) {
var percentRange = dataZoomModel.getPercentRange();
storedSnapshots[0][dataZoomId] = {
dataZoomId: dataZoomId,
start: percentRange[0],
end: percentRange[1]
};
}
}
});
storedSnapshots.push(newSnapshot);
}
export function pop(ecModel) {
var storedSnapshots = getStoreSnapshots(ecModel);
var head = storedSnapshots[storedSnapshots.length - 1];
storedSnapshots.length > 1 && storedSnapshots.pop();
// Find top for all dataZoom.
var snapshot = {};
each(head, function (batchItem, dataZoomId) {
for (var i = storedSnapshots.length - 1; i >= 0; i--) {
batchItem = storedSnapshots[i][dataZoomId];
if (batchItem) {
snapshot[dataZoomId] = batchItem;
break;
}
}
});
return snapshot;
}
export function clear(ecModel) {
inner(ecModel).snapshots = null;
}
export function count(ecModel) {
return getStoreSnapshots(ecModel).length;
}
/**
* History length of each dataZoom may be different.
* this._history[0] is used to store origin range.
*/
function getStoreSnapshots(ecModel) {
var store = inner(ecModel);
if (!store.snapshots) {
store.snapshots = [{}];
}
return store.snapshots;
}

View File

@@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../../extension.js';
import { install as installDataZoomInside } from './installDataZoomInside.js';
import { install as installDataZoomSlider } from './installDataZoomSlider.js';
export function install(registers) {
use(installDataZoomInside);
use(installDataZoomSlider);
// Do not install './dataZoomSelect',
// since it only work for toolbox dataZoom.
}

View File

@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import dataZoomProcessor from './dataZoomProcessor.js';
import installDataZoomAction from './dataZoomAction.js';
var installed = false;
export default function installCommon(registers) {
if (installed) {
return;
}
installed = true;
registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, dataZoomProcessor);
installDataZoomAction(registers);
registers.registerSubTypeDefaulter('dataZoom', function () {
// Default 'slider' when no type specified.
return 'slider';
});
}

View File

@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import InsideZoomModel from './InsideZoomModel.js';
import InsideZoomView from './InsideZoomView.js';
import { installDataZoomRoamProcessor } from './roams.js';
import installCommon from './installCommon.js';
export function install(registers) {
installCommon(registers);
registers.registerComponentModel(InsideZoomModel);
registers.registerComponentView(InsideZoomView);
installDataZoomRoamProcessor(registers);
}

View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import SelectZoomModel from './SelectZoomModel.js';
import SelectZoomView from './SelectZoomView.js';
import installCommon from './installCommon.js';
export function install(registers) {
registers.registerComponentModel(SelectZoomModel);
registers.registerComponentView(SelectZoomView);
installCommon(registers);
}

View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import SliderZoomModel from './SliderZoomModel.js';
import SliderZoomView from './SliderZoomView.js';
import installCommon from './installCommon.js';
export function install(registers) {
registers.registerComponentModel(SliderZoomModel);
registers.registerComponentView(SliderZoomView);
installCommon(registers);
}

View File

@@ -0,0 +1,227 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Only create one roam controller for each coordinate system.
// one roam controller might be refered by two inside data zoom
// components (for example, one for x and one for y). When user
// pan or zoom, only dispatch one action for those data zoom
// components.
import RoamController from '../../component/helper/RoamController.js';
import * as throttleUtil from '../../util/throttle.js';
import { makeInner } from '../../util/model.js';
import { each, curry, createHashMap } from 'zrender/lib/core/util.js';
import { collectReferCoordSysModelInfo } from './helper.js';
var inner = makeInner();
export function setViewInfoToCoordSysRecord(api, dataZoomModel, getRange) {
inner(api).coordSysRecordMap.each(function (coordSysRecord) {
var dzInfo = coordSysRecord.dataZoomInfoMap.get(dataZoomModel.uid);
if (dzInfo) {
dzInfo.getRange = getRange;
}
});
}
export function disposeCoordSysRecordIfNeeded(api, dataZoomModel) {
var coordSysRecordMap = inner(api).coordSysRecordMap;
var coordSysKeyArr = coordSysRecordMap.keys();
for (var i = 0; i < coordSysKeyArr.length; i++) {
var coordSysKey = coordSysKeyArr[i];
var coordSysRecord = coordSysRecordMap.get(coordSysKey);
var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;
if (dataZoomInfoMap) {
var dzUid = dataZoomModel.uid;
var dzInfo = dataZoomInfoMap.get(dzUid);
if (dzInfo) {
dataZoomInfoMap.removeKey(dzUid);
if (!dataZoomInfoMap.keys().length) {
disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
}
}
}
}
}
function disposeCoordSysRecord(coordSysRecordMap, coordSysRecord) {
if (coordSysRecord) {
coordSysRecordMap.removeKey(coordSysRecord.model.uid);
var controller = coordSysRecord.controller;
controller && controller.dispose();
}
}
function createCoordSysRecord(api, coordSysModel) {
// These init props will never change after record created.
var coordSysRecord = {
model: coordSysModel,
containsPoint: curry(containsPoint, coordSysModel),
dispatchAction: curry(dispatchAction, api),
dataZoomInfoMap: null,
controller: null
};
// Must not do anything depends on coordSysRecord outside the event handler here,
// because coordSysRecord not completed yet.
var controller = coordSysRecord.controller = new RoamController(api.getZr());
each(['pan', 'zoom', 'scrollMove'], function (eventName) {
controller.on(eventName, function (event) {
var batch = [];
coordSysRecord.dataZoomInfoMap.each(function (dzInfo) {
// Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove,
// moveOnMouseWheel, ...) enabled.
if (!event.isAvailableBehavior(dzInfo.model.option)) {
return;
}
var method = (dzInfo.getRange || {})[eventName];
var range = method && method(dzInfo.dzReferCoordSysInfo, coordSysRecord.model.mainType, coordSysRecord.controller, event);
!dzInfo.model.get('disabled', true) && range && batch.push({
dataZoomId: dzInfo.model.id,
start: range[0],
end: range[1]
});
});
batch.length && coordSysRecord.dispatchAction(batch);
});
});
return coordSysRecord;
}
/**
* This action will be throttled.
*/
function dispatchAction(api, batch) {
if (!api.isDisposed()) {
api.dispatchAction({
type: 'dataZoom',
animation: {
easing: 'cubicOut',
duration: 100
},
batch: batch
});
}
}
function containsPoint(coordSysModel, e, x, y) {
return coordSysModel.coordinateSystem.containPoint([x, y]);
}
/**
* Merge roamController settings when multiple dataZooms share one roamController.
*/
function mergeControllerParams(dataZoomInfoMap) {
var controlType;
// DO NOT use reserved word (true, false, undefined) as key literally. Even if encapsulated
// as string, it is probably revert to reserved word by compress tool. See #7411.
var prefix = 'type_';
var typePriority = {
'type_true': 2,
'type_move': 1,
'type_false': 0,
'type_undefined': -1
};
var preventDefaultMouseMove = true;
dataZoomInfoMap.each(function (dataZoomInfo) {
var dataZoomModel = dataZoomInfo.model;
var oneType = dataZoomModel.get('disabled', true) ? false : dataZoomModel.get('zoomLock', true) ? 'move' : true;
if (typePriority[prefix + oneType] > typePriority[prefix + controlType]) {
controlType = oneType;
}
// Prevent default move event by default. If one false, do not prevent. Otherwise
// users may be confused why it does not work when multiple insideZooms exist.
preventDefaultMouseMove = preventDefaultMouseMove && dataZoomModel.get('preventDefaultMouseMove', true);
});
return {
controlType: controlType,
opt: {
// RoamController will enable all of these functionalities,
// and the final behavior is determined by its event listener
// provided by each inside zoom.
zoomOnMouseWheel: true,
moveOnMouseMove: true,
moveOnMouseWheel: true,
preventDefaultMouseMove: !!preventDefaultMouseMove
}
};
}
export function installDataZoomRoamProcessor(registers) {
registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, function (ecModel, api) {
var apiInner = inner(api);
var coordSysRecordMap = apiInner.coordSysRecordMap || (apiInner.coordSysRecordMap = createHashMap());
coordSysRecordMap.each(function (coordSysRecord) {
// `coordSysRecordMap` always exists (because it holds the `roam controller`, which should
// better not re-create each time), but clear `dataZoomInfoMap` each round of the workflow.
coordSysRecord.dataZoomInfoMap = null;
});
ecModel.eachComponent({
mainType: 'dataZoom',
subType: 'inside'
}, function (dataZoomModel) {
var dzReferCoordSysWrap = collectReferCoordSysModelInfo(dataZoomModel);
each(dzReferCoordSysWrap.infoList, function (dzCoordSysInfo) {
var coordSysUid = dzCoordSysInfo.model.uid;
var coordSysRecord = coordSysRecordMap.get(coordSysUid) || coordSysRecordMap.set(coordSysUid, createCoordSysRecord(api, dzCoordSysInfo.model));
var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap || (coordSysRecord.dataZoomInfoMap = createHashMap());
// Notice these props might be changed each time for a single dataZoomModel.
dataZoomInfoMap.set(dataZoomModel.uid, {
dzReferCoordSysInfo: dzCoordSysInfo,
model: dataZoomModel,
getRange: null
});
});
});
// (1) Merge dataZoom settings for each coord sys and set to the roam controller.
// (2) Clear coord sys if not refered by any dataZoom.
coordSysRecordMap.each(function (coordSysRecord) {
var controller = coordSysRecord.controller;
var firstDzInfo;
var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;
if (dataZoomInfoMap) {
var firstDzKey = dataZoomInfoMap.keys()[0];
if (firstDzKey != null) {
firstDzInfo = dataZoomInfoMap.get(firstDzKey);
}
}
if (!firstDzInfo) {
disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
return;
}
var controllerParams = mergeControllerParams(dataZoomInfoMap);
controller.enable(controllerParams.controlType, controllerParams.opt);
controller.setPointerChecker(coordSysRecord.containsPoint);
throttleUtil.createOrUpdate(coordSysRecord, 'dispatchAction', firstDzInfo.model.get('throttle', true), 'fixRate');
});
});
}

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './dataZoom/installDataZoomInside.js';
use(install);

View File

@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Only work for toolbox dataZoom. User
* MUST NOT import this module directly.
*/
import { use } from '../extension.js';
import { install } from './dataZoom/installDataZoomSelect.js';
use(install);

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './dataZoom/installDataZoomSlider.js';
use(install);

46
frontend/node_modules/echarts/lib/component/dataset.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './dataset/install.js';
use(install);

View File

@@ -0,0 +1,99 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
/**
* This module is imported by echarts directly.
*
* Notice:
* Always keep this file exists for backward compatibility.
* Because before 4.1.0, dataset is an optional component,
* some users may import this module manually.
*/
import ComponentModel from '../../model/Component.js';
import ComponentView from '../../view/Component.js';
import { SERIES_LAYOUT_BY_COLUMN } from '../../util/types.js';
import { disableTransformOptionMerge, SourceManager } from '../../data/helper/sourceManager.js';
var DatasetModel = /** @class */function (_super) {
__extends(DatasetModel, _super);
function DatasetModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = 'dataset';
return _this;
}
DatasetModel.prototype.init = function (option, parentModel, ecModel) {
_super.prototype.init.call(this, option, parentModel, ecModel);
this._sourceManager = new SourceManager(this);
disableTransformOptionMerge(this);
};
DatasetModel.prototype.mergeOption = function (newOption, ecModel) {
_super.prototype.mergeOption.call(this, newOption, ecModel);
disableTransformOptionMerge(this);
};
DatasetModel.prototype.optionUpdated = function () {
this._sourceManager.dirty();
};
DatasetModel.prototype.getSourceManager = function () {
return this._sourceManager;
};
DatasetModel.type = 'dataset';
DatasetModel.defaultOption = {
seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN
};
return DatasetModel;
}(ComponentModel);
export { DatasetModel };
var DatasetView = /** @class */function (_super) {
__extends(DatasetView, _super);
function DatasetView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = 'dataset';
return _this;
}
DatasetView.type = 'dataset';
return DatasetView;
}(ComponentView);
export function install(registers) {
registers.registerComponentModel(DatasetModel);
registers.registerComponentView(DatasetView);
}

46
frontend/node_modules/echarts/lib/component/geo.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './geo/install.js';
use(install);

View File

@@ -0,0 +1,110 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import MapDraw from '../helper/MapDraw.js';
import ComponentView from '../../view/Component.js';
import { getECData } from '../../util/innerStore.js';
import { findEventDispatcher } from '../../util/event.js';
var GeoView = /** @class */function (_super) {
__extends(GeoView, _super);
function GeoView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = GeoView.type;
_this.focusBlurEnabled = true;
return _this;
}
GeoView.prototype.init = function (ecModel, api) {
this._api = api;
};
GeoView.prototype.render = function (geoModel, ecModel, api, payload) {
this._model = geoModel;
if (!geoModel.get('show')) {
this._mapDraw && this._mapDraw.remove();
this._mapDraw = null;
return;
}
if (!this._mapDraw) {
this._mapDraw = new MapDraw(api);
}
var mapDraw = this._mapDraw;
mapDraw.draw(geoModel, ecModel, api, this, payload);
mapDraw.group.on('click', this._handleRegionClick, this);
mapDraw.group.silent = geoModel.get('silent');
this.group.add(mapDraw.group);
this.updateSelectStatus(geoModel, ecModel, api);
};
GeoView.prototype._handleRegionClick = function (e) {
var eventData;
findEventDispatcher(e.target, function (current) {
return (eventData = getECData(current).eventData) != null;
}, true);
if (eventData) {
this._api.dispatchAction({
type: 'geoToggleSelect',
geoId: this._model.id,
name: eventData.name
});
}
};
GeoView.prototype.updateSelectStatus = function (model, ecModel, api) {
var _this = this;
this._mapDraw.group.traverse(function (node) {
var eventData = getECData(node).eventData;
if (eventData) {
_this._model.isSelected(eventData.name) ? api.enterSelect(node) : api.leaveSelect(node);
// No need to traverse children.
return true;
}
});
};
GeoView.prototype.findHighDownDispatchers = function (name) {
return this._mapDraw && this._mapDraw.findHighDownDispatchers(name, this._model);
};
GeoView.prototype.dispose = function () {
this._mapDraw && this._mapDraw.remove();
};
GeoView.type = 'geo';
return GeoView;
}(ComponentView);
export default GeoView;

View File

@@ -0,0 +1,141 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import GeoModel from '../../coord/geo/GeoModel.js';
import geoCreator from '../../coord/geo/geoCreator.js';
import { each } from 'zrender/lib/core/util.js';
import { updateCenterAndZoom } from '../../action/roamHelper.js';
import GeoView from './GeoView.js';
import geoSourceManager from '../../coord/geo/geoSourceManager.js';
function registerMap(mapName, geoJson, specialAreas) {
geoSourceManager.registerMap(mapName, geoJson, specialAreas);
}
export function install(registers) {
registers.registerCoordinateSystem('geo', geoCreator);
registers.registerComponentModel(GeoModel);
registers.registerComponentView(GeoView);
registers.registerImpl('registerMap', registerMap);
registers.registerImpl('getMap', function (mapName) {
return geoSourceManager.getMapForUser(mapName);
});
function makeAction(method, actionInfo) {
actionInfo.update = 'geo:updateSelectStatus';
registers.registerAction(actionInfo, function (payload, ecModel) {
var selected = {};
var allSelected = [];
ecModel.eachComponent({
mainType: 'geo',
query: payload
}, function (geoModel) {
geoModel[method](payload.name);
var geo = geoModel.coordinateSystem;
each(geo.regions, function (region) {
selected[region.name] = geoModel.isSelected(region.name) || false;
});
// Notice: there might be duplicated name in different regions.
var names = [];
each(selected, function (v, name) {
selected[name] && names.push(name);
});
allSelected.push({
geoIndex: geoModel.componentIndex,
// Use singular, the same naming convention as the event `selectchanged`.
name: names
});
});
return {
selected: selected,
allSelected: allSelected,
name: payload.name
};
});
}
makeAction('toggleSelected', {
type: 'geoToggleSelect',
event: 'geoselectchanged'
});
makeAction('select', {
type: 'geoSelect',
event: 'geoselected'
});
makeAction('unSelect', {
type: 'geoUnSelect',
event: 'geounselected'
});
/**
* @payload
* @property {string} [componentType=series]
* @property {number} [dx]
* @property {number} [dy]
* @property {number} [zoom]
* @property {number} [originX]
* @property {number} [originY]
*/
registers.registerAction({
type: 'geoRoam',
event: 'geoRoam',
update: 'updateTransform'
}, function (payload, ecModel, api) {
var componentType = payload.componentType || 'series';
ecModel.eachComponent({
mainType: componentType,
query: payload
}, function (componentModel) {
var geo = componentModel.coordinateSystem;
if (geo.type !== 'geo') {
return;
}
var res = updateCenterAndZoom(geo, payload, componentModel.get('scaleLimit'), api);
componentModel.setCenter && componentModel.setCenter(res.center);
componentModel.setZoom && componentModel.setZoom(res.zoom);
// All map series with same `map` use the same geo coordinate system
// So the center and zoom must be in sync. Include the series not selected by legend
if (componentType === 'series') {
each(componentModel.seriesGroup, function (seriesModel) {
seriesModel.setCenter(res.center);
seriesModel.setZoom(res.zoom);
});
}
});
});
}

46
frontend/node_modules/echarts/lib/component/graphic.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './graphic/install.js';
use(install);

View File

@@ -0,0 +1,246 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import * as modelUtil from '../../util/model.js';
import ComponentModel from '../../model/Component.js';
import { copyLayoutParams, mergeLayoutParam } from '../../util/layout.js';
;
;
;
export function setKeyInfoToNewElOption(resultItem, newElOption) {
var existElOption = resultItem.existing;
// Set id and type after id assigned.
newElOption.id = resultItem.keyInfo.id;
!newElOption.type && existElOption && (newElOption.type = existElOption.type);
// Set parent id if not specified
if (newElOption.parentId == null) {
var newElParentOption = newElOption.parentOption;
if (newElParentOption) {
newElOption.parentId = newElParentOption.id;
} else if (existElOption) {
newElOption.parentId = existElOption.parentId;
}
}
// Clear
newElOption.parentOption = null;
}
function isSetLoc(obj, props) {
var isSet;
zrUtil.each(props, function (prop) {
obj[prop] != null && obj[prop] !== 'auto' && (isSet = true);
});
return isSet;
}
function mergeNewElOptionToExist(existList, index, newElOption) {
// Update existing options, for `getOption` feature.
var newElOptCopy = zrUtil.extend({}, newElOption);
var existElOption = existList[index];
var $action = newElOption.$action || 'merge';
if ($action === 'merge') {
if (existElOption) {
if (process.env.NODE_ENV !== 'production') {
var newType = newElOption.type;
zrUtil.assert(!newType || existElOption.type === newType, 'Please set $action: "replace" to change `type`');
}
// We can ensure that newElOptCopy and existElOption are not
// the same object, so `merge` will not change newElOptCopy.
zrUtil.merge(existElOption, newElOptCopy, true);
// Rigid body, use ignoreSize.
mergeLayoutParam(existElOption, newElOptCopy, {
ignoreSize: true
});
// Will be used in render.
copyLayoutParams(newElOption, existElOption);
// Copy transition info to new option so it can be used in the transition.
// DO IT AFTER merge
copyTransitionInfo(newElOption, existElOption);
copyTransitionInfo(newElOption, existElOption, 'shape');
copyTransitionInfo(newElOption, existElOption, 'style');
copyTransitionInfo(newElOption, existElOption, 'extra');
// Copy clipPath
newElOption.clipPath = existElOption.clipPath;
} else {
existList[index] = newElOptCopy;
}
} else if ($action === 'replace') {
existList[index] = newElOptCopy;
} else if ($action === 'remove') {
// null will be cleaned later.
existElOption && (existList[index] = null);
}
}
var TRANSITION_PROPS_TO_COPY = ['transition', 'enterFrom', 'leaveTo'];
var ROOT_TRANSITION_PROPS_TO_COPY = TRANSITION_PROPS_TO_COPY.concat(['enterAnimation', 'updateAnimation', 'leaveAnimation']);
function copyTransitionInfo(target, source, targetProp) {
if (targetProp) {
if (!target[targetProp] && source[targetProp]) {
// TODO avoid creating this empty object when there is no transition configuration.
target[targetProp] = {};
}
target = target[targetProp];
source = source[targetProp];
}
if (!target || !source) {
return;
}
var props = targetProp ? TRANSITION_PROPS_TO_COPY : ROOT_TRANSITION_PROPS_TO_COPY;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
if (target[prop] == null && source[prop] != null) {
target[prop] = source[prop];
}
}
}
function setLayoutInfoToExist(existItem, newElOption) {
if (!existItem) {
return;
}
existItem.hv = newElOption.hv = [
// Rigid body, don't care about `width`.
isSetLoc(newElOption, ['left', 'right']),
// Rigid body, don't care about `height`.
isSetLoc(newElOption, ['top', 'bottom'])];
// Give default group size. Otherwise layout error may occur.
if (existItem.type === 'group') {
var existingGroupOpt = existItem;
var newGroupOpt = newElOption;
existingGroupOpt.width == null && (existingGroupOpt.width = newGroupOpt.width = 0);
existingGroupOpt.height == null && (existingGroupOpt.height = newGroupOpt.height = 0);
}
}
var GraphicComponentModel = /** @class */function (_super) {
__extends(GraphicComponentModel, _super);
function GraphicComponentModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = GraphicComponentModel.type;
_this.preventAutoZ = true;
return _this;
}
GraphicComponentModel.prototype.mergeOption = function (option, ecModel) {
// Prevent default merge to elements
var elements = this.option.elements;
this.option.elements = null;
_super.prototype.mergeOption.call(this, option, ecModel);
this.option.elements = elements;
};
GraphicComponentModel.prototype.optionUpdated = function (newOption, isInit) {
var thisOption = this.option;
var newList = (isInit ? thisOption : newOption).elements;
var existList = thisOption.elements = isInit ? [] : thisOption.elements;
var flattenedList = [];
this._flatten(newList, flattenedList, null);
var mappingResult = modelUtil.mappingToExists(existList, flattenedList, 'normalMerge');
// Clear elOptionsToUpdate
var elOptionsToUpdate = this._elOptionsToUpdate = [];
zrUtil.each(mappingResult, function (resultItem, index) {
var newElOption = resultItem.newOption;
if (process.env.NODE_ENV !== 'production') {
zrUtil.assert(zrUtil.isObject(newElOption) || resultItem.existing, 'Empty graphic option definition');
}
if (!newElOption) {
return;
}
elOptionsToUpdate.push(newElOption);
setKeyInfoToNewElOption(resultItem, newElOption);
mergeNewElOptionToExist(existList, index, newElOption);
setLayoutInfoToExist(existList[index], newElOption);
}, this);
// Clean
thisOption.elements = zrUtil.filter(existList, function (item) {
// $action should be volatile, otherwise option gotten from
// `getOption` will contain unexpected $action.
item && delete item.$action;
return item != null;
});
};
/**
* Convert
* [{
* type: 'group',
* id: 'xx',
* children: [{type: 'circle'}, {type: 'polygon'}]
* }]
* to
* [
* {type: 'group', id: 'xx'},
* {type: 'circle', parentId: 'xx'},
* {type: 'polygon', parentId: 'xx'}
* ]
*/
GraphicComponentModel.prototype._flatten = function (optionList, result, parentOption) {
zrUtil.each(optionList, function (option) {
if (!option) {
return;
}
if (parentOption) {
option.parentOption = parentOption;
}
result.push(option);
var children = option.children;
// here we don't judge if option.type is `group`
// when new option doesn't provide `type`, it will cause that the children can't be updated.
if (children && children.length) {
this._flatten(children, result, option);
}
// Deleting for JSON output, and for not affecting group creation.
delete option.children;
}, this);
};
// FIXME
// Pass to view using payload? setOption has a payload?
GraphicComponentModel.prototype.useElOptionsToUpdate = function () {
var els = this._elOptionsToUpdate;
// Clear to avoid render duplicately when zooming.
this._elOptionsToUpdate = null;
return els;
};
GraphicComponentModel.type = 'graphic';
GraphicComponentModel.defaultOption = {
elements: []
// parentId: null
};
return GraphicComponentModel;
}(ComponentModel);
export { GraphicComponentModel };

View File

@@ -0,0 +1,391 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import Displayable from 'zrender/lib/graphic/Displayable.js';
import * as modelUtil from '../../util/model.js';
import * as graphicUtil from '../../util/graphic.js';
import * as layoutUtil from '../../util/layout.js';
import { parsePercent } from '../../util/number.js';
import ComponentView from '../../view/Component.js';
import { getECData } from '../../util/innerStore.js';
import { isEC4CompatibleStyle, convertFromEC4CompatibleStyle } from '../../util/styleCompat.js';
import { applyLeaveTransition, applyUpdateTransition, isTransitionAll, updateLeaveTo } from '../../animation/customGraphicTransition.js';
import { updateProps } from '../../animation/basicTransition.js';
import { applyKeyframeAnimation, stopPreviousKeyframeAnimationAndRestore } from '../../animation/customGraphicKeyframeAnimation.js';
var nonShapeGraphicElements = {
// Reserved but not supported in graphic component.
path: null,
compoundPath: null,
// Supported in graphic component.
group: graphicUtil.Group,
image: graphicUtil.Image,
text: graphicUtil.Text
};
export var inner = modelUtil.makeInner();
// ------------------------
// View
// ------------------------
var GraphicComponentView = /** @class */function (_super) {
__extends(GraphicComponentView, _super);
function GraphicComponentView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = GraphicComponentView.type;
return _this;
}
GraphicComponentView.prototype.init = function () {
this._elMap = zrUtil.createHashMap();
};
GraphicComponentView.prototype.render = function (graphicModel, ecModel, api) {
// Having leveraged between use cases and algorithm complexity, a very
// simple layout mechanism is used:
// The size(width/height) can be determined by itself or its parent (not
// implemented yet), but can not by its children. (Top-down travel)
// The location(x/y) can be determined by the bounding rect of itself
// (can including its descendants or not) and the size of its parent.
// (Bottom-up travel)
// When `chart.clear()` or `chart.setOption({...}, true)` with the same id,
// view will be reused.
if (graphicModel !== this._lastGraphicModel) {
this._clear();
}
this._lastGraphicModel = graphicModel;
this._updateElements(graphicModel);
this._relocate(graphicModel, api);
};
/**
* Update graphic elements.
*/
GraphicComponentView.prototype._updateElements = function (graphicModel) {
var elOptionsToUpdate = graphicModel.useElOptionsToUpdate();
if (!elOptionsToUpdate) {
return;
}
var elMap = this._elMap;
var rootGroup = this.group;
var globalZ = graphicModel.get('z');
var globalZLevel = graphicModel.get('zlevel');
// Top-down tranverse to assign graphic settings to each elements.
zrUtil.each(elOptionsToUpdate, function (elOption) {
var id = modelUtil.convertOptionIdName(elOption.id, null);
var elExisting = id != null ? elMap.get(id) : null;
var parentId = modelUtil.convertOptionIdName(elOption.parentId, null);
var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup;
var elType = elOption.type;
var elOptionStyle = elOption.style;
if (elType === 'text' && elOptionStyle) {
// In top/bottom mode, textVerticalAlign should not be used, which cause
// inaccurately locating.
if (elOption.hv && elOption.hv[1]) {
elOptionStyle.textVerticalAlign = elOptionStyle.textBaseline = elOptionStyle.verticalAlign = elOptionStyle.align = null;
}
}
var textContentOption = elOption.textContent;
var textConfig = elOption.textConfig;
if (elOptionStyle && isEC4CompatibleStyle(elOptionStyle, elType, !!textConfig, !!textContentOption)) {
var convertResult = convertFromEC4CompatibleStyle(elOptionStyle, elType, true);
if (!textConfig && convertResult.textConfig) {
textConfig = elOption.textConfig = convertResult.textConfig;
}
if (!textContentOption && convertResult.textContent) {
textContentOption = convertResult.textContent;
}
}
// Remove unnecessary props to avoid potential problems.
var elOptionCleaned = getCleanedElOption(elOption);
// For simple, do not support parent change, otherwise reorder is needed.
if (process.env.NODE_ENV !== 'production') {
elExisting && zrUtil.assert(targetElParent === elExisting.parent, 'Changing parent is not supported.');
}
var $action = elOption.$action || 'merge';
var isMerge = $action === 'merge';
var isReplace = $action === 'replace';
if (isMerge) {
var isInit = !elExisting;
var el_1 = elExisting;
if (isInit) {
el_1 = createEl(id, targetElParent, elOption.type, elMap);
} else {
el_1 && (inner(el_1).isNew = false);
// Stop and restore before update any other attributes.
stopPreviousKeyframeAnimationAndRestore(el_1);
}
if (el_1) {
applyUpdateTransition(el_1, elOptionCleaned, graphicModel, {
isInit: isInit
});
updateCommonAttrs(el_1, elOption, globalZ, globalZLevel);
}
} else if (isReplace) {
removeEl(elExisting, elOption, elMap, graphicModel);
var el_2 = createEl(id, targetElParent, elOption.type, elMap);
if (el_2) {
applyUpdateTransition(el_2, elOptionCleaned, graphicModel, {
isInit: true
});
updateCommonAttrs(el_2, elOption, globalZ, globalZLevel);
}
} else if ($action === 'remove') {
updateLeaveTo(elExisting, elOption);
removeEl(elExisting, elOption, elMap, graphicModel);
}
var el = elMap.get(id);
if (el && textContentOption) {
if (isMerge) {
var textContentExisting = el.getTextContent();
textContentExisting ? textContentExisting.attr(textContentOption) : el.setTextContent(new graphicUtil.Text(textContentOption));
} else if (isReplace) {
el.setTextContent(new graphicUtil.Text(textContentOption));
}
}
if (el) {
var clipPathOption = elOption.clipPath;
if (clipPathOption) {
var clipPathType = clipPathOption.type;
var clipPath = void 0;
var isInit = false;
if (isMerge) {
var oldClipPath = el.getClipPath();
isInit = !oldClipPath || inner(oldClipPath).type !== clipPathType;
clipPath = isInit ? newEl(clipPathType) : oldClipPath;
} else if (isReplace) {
isInit = true;
clipPath = newEl(clipPathType);
}
el.setClipPath(clipPath);
applyUpdateTransition(clipPath, clipPathOption, graphicModel, {
isInit: isInit
});
applyKeyframeAnimation(clipPath, clipPathOption.keyframeAnimation, graphicModel);
}
var elInner = inner(el);
el.setTextConfig(textConfig);
elInner.option = elOption;
setEventData(el, graphicModel, elOption);
graphicUtil.setTooltipConfig({
el: el,
componentModel: graphicModel,
itemName: el.name,
itemTooltipOption: elOption.tooltip
});
applyKeyframeAnimation(el, elOption.keyframeAnimation, graphicModel);
}
});
};
/**
* Locate graphic elements.
*/
GraphicComponentView.prototype._relocate = function (graphicModel, api) {
var elOptions = graphicModel.option.elements;
var rootGroup = this.group;
var elMap = this._elMap;
var apiWidth = api.getWidth();
var apiHeight = api.getHeight();
var xy = ['x', 'y'];
// Top-down to calculate percentage width/height of group
for (var i = 0; i < elOptions.length; i++) {
var elOption = elOptions[i];
var id = modelUtil.convertOptionIdName(elOption.id, null);
var el = id != null ? elMap.get(id) : null;
if (!el || !el.isGroup) {
continue;
}
var parentEl = el.parent;
var isParentRoot = parentEl === rootGroup;
// Like 'position:absolut' in css, default 0.
var elInner = inner(el);
var parentElInner = inner(parentEl);
elInner.width = parsePercent(elInner.option.width, isParentRoot ? apiWidth : parentElInner.width) || 0;
elInner.height = parsePercent(elInner.option.height, isParentRoot ? apiHeight : parentElInner.height) || 0;
}
// Bottom-up tranvese all elements (consider ec resize) to locate elements.
for (var i = elOptions.length - 1; i >= 0; i--) {
var elOption = elOptions[i];
var id = modelUtil.convertOptionIdName(elOption.id, null);
var el = id != null ? elMap.get(id) : null;
if (!el) {
continue;
}
var parentEl = el.parent;
var parentElInner = inner(parentEl);
var containerInfo = parentEl === rootGroup ? {
width: apiWidth,
height: apiHeight
} : {
width: parentElInner.width,
height: parentElInner.height
};
// PENDING
// Currently, when `bounding: 'all'`, the union bounding rect of the group
// does not include the rect of [0, 0, group.width, group.height], which
// is probably weird for users. Should we make a break change for it?
var layoutPos = {};
var layouted = layoutUtil.positionElement(el, elOption, containerInfo, null, {
hv: elOption.hv,
boundingMode: elOption.bounding
}, layoutPos);
if (!inner(el).isNew && layouted) {
var transition = elOption.transition;
var animatePos = {};
for (var k = 0; k < xy.length; k++) {
var key = xy[k];
var val = layoutPos[key];
if (transition && (isTransitionAll(transition) || zrUtil.indexOf(transition, key) >= 0)) {
animatePos[key] = val;
} else {
el[key] = val;
}
}
updateProps(el, animatePos, graphicModel, 0);
} else {
el.attr(layoutPos);
}
}
};
/**
* Clear all elements.
*/
GraphicComponentView.prototype._clear = function () {
var _this = this;
var elMap = this._elMap;
elMap.each(function (el) {
removeEl(el, inner(el).option, elMap, _this._lastGraphicModel);
});
this._elMap = zrUtil.createHashMap();
};
GraphicComponentView.prototype.dispose = function () {
this._clear();
};
GraphicComponentView.type = 'graphic';
return GraphicComponentView;
}(ComponentView);
export { GraphicComponentView };
function newEl(graphicType) {
if (process.env.NODE_ENV !== 'production') {
zrUtil.assert(graphicType, 'graphic type MUST be set');
}
var Clz = zrUtil.hasOwn(nonShapeGraphicElements, graphicType)
// Those graphic elements are not shapes. They should not be
// overwritten by users, so do them first.
? nonShapeGraphicElements[graphicType] : graphicUtil.getShapeClass(graphicType);
if (process.env.NODE_ENV !== 'production') {
zrUtil.assert(Clz, "graphic type " + graphicType + " can not be found");
}
var el = new Clz({});
inner(el).type = graphicType;
return el;
}
function createEl(id, targetElParent, graphicType, elMap) {
var el = newEl(graphicType);
targetElParent.add(el);
elMap.set(id, el);
inner(el).id = id;
inner(el).isNew = true;
return el;
}
function removeEl(elExisting, elOption, elMap, graphicModel) {
var existElParent = elExisting && elExisting.parent;
if (existElParent) {
elExisting.type === 'group' && elExisting.traverse(function (el) {
removeEl(el, elOption, elMap, graphicModel);
});
applyLeaveTransition(elExisting, elOption, graphicModel);
elMap.removeKey(inner(elExisting).id);
}
}
function updateCommonAttrs(el, elOption, defaultZ, defaultZlevel) {
if (!el.isGroup) {
zrUtil.each([['cursor', Displayable.prototype.cursor],
// We should not support configure z and zlevel in the element level.
// But seems we didn't limit it previously. So here still use it to avoid breaking.
['zlevel', defaultZlevel || 0], ['z', defaultZ || 0],
// z2 must not be null/undefined, otherwise sort error may occur.
['z2', 0]], function (item) {
var prop = item[0];
if (zrUtil.hasOwn(elOption, prop)) {
el[prop] = zrUtil.retrieve2(elOption[prop], item[1]);
} else if (el[prop] == null) {
el[prop] = item[1];
}
});
}
zrUtil.each(zrUtil.keys(elOption), function (key) {
// Assign event handlers.
// PENDING: should enumerate all event names or use pattern matching?
if (key.indexOf('on') === 0) {
var val = elOption[key];
el[key] = zrUtil.isFunction(val) ? val : null;
}
});
if (zrUtil.hasOwn(elOption, 'draggable')) {
el.draggable = elOption.draggable;
}
// Other attributes
elOption.name != null && (el.name = elOption.name);
elOption.id != null && (el.id = elOption.id);
}
// Remove unnecessary props to avoid potential problems.
function getCleanedElOption(elOption) {
elOption = zrUtil.extend({}, elOption);
zrUtil.each(['id', 'parentId', '$action', 'hv', 'bounding', 'textContent', 'clipPath'].concat(layoutUtil.LOCATION_PARAMS), function (name) {
delete elOption[name];
});
return elOption;
}
function setEventData(el, graphicModel, elOption) {
var eventData = getECData(el).eventData;
// Simple optimize for large amount of elements that no need event.
if (!el.silent && !el.ignore && !eventData) {
eventData = getECData(el).eventData = {
componentType: 'graphic',
componentIndex: graphicModel.componentIndex,
name: el.name
};
}
// `elOption.info` enables user to mount some info on
// elements and use them in event handlers.
if (eventData) {
eventData.info = elOption.info;
}
}

View File

@@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { isArray } from 'zrender/lib/core/util.js';
import { GraphicComponentModel } from './GraphicModel.js';
import { GraphicComponentView } from './GraphicView.js';
export function install(registers) {
registers.registerComponentModel(GraphicComponentModel);
registers.registerComponentView(GraphicComponentView);
registers.registerPreprocessor(function (option) {
var graphicOption = option.graphic;
// Convert
// {graphic: [{left: 10, type: 'circle'}, ...]}
// or
// {graphic: {left: 10, type: 'circle'}}
// to
// {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]}
if (isArray(graphicOption)) {
if (!graphicOption[0] || !graphicOption[0].elements) {
option.graphic = [{
elements: graphicOption
}];
} else {
// Only one graphic instance can be instantiated. (We don't
// want that too many views are created in echarts._viewMap.)
option.graphic = [option.graphic[0]];
}
} else if (graphicOption && !graphicOption.elements) {
option.graphic = [{
elements: [graphicOption]
}];
}
});
}

46
frontend/node_modules/echarts/lib/component/grid.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './grid/install.js';
use(install);

View File

@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { install as installSimple } from './installSimple.js';
import { install as installAxisPointer } from '../axisPointer/install.js';
import { use } from '../../extension.js';
export function install(registers) {
use(installSimple);
use(installAxisPointer);
}

View File

@@ -0,0 +1,96 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import ComponentView from '../../view/Component.js';
import GridModel from '../../coord/cartesian/GridModel.js';
import { Rect } from '../../util/graphic.js';
import { defaults } from 'zrender/lib/core/util.js';
import { CartesianAxisModel } from '../../coord/cartesian/AxisModel.js';
import axisModelCreator from '../../coord/axisModelCreator.js';
import Grid from '../../coord/cartesian/Grid.js';
import { CartesianXAxisView, CartesianYAxisView } from '../axis/CartesianAxisView.js';
// Grid view
var GridView = /** @class */function (_super) {
__extends(GridView, _super);
function GridView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = 'grid';
return _this;
}
GridView.prototype.render = function (gridModel, ecModel) {
this.group.removeAll();
if (gridModel.get('show')) {
this.group.add(new Rect({
shape: gridModel.coordinateSystem.getRect(),
style: defaults({
fill: gridModel.get('backgroundColor')
}, gridModel.getItemStyle()),
silent: true,
z2: -1
}));
}
};
GridView.type = 'grid';
return GridView;
}(ComponentView);
var extraOption = {
// gridIndex: 0,
// gridId: '',
offset: 0
};
export function install(registers) {
registers.registerComponentView(GridView);
registers.registerComponentModel(GridModel);
registers.registerCoordinateSystem('cartesian2d', Grid);
axisModelCreator(registers, 'x', CartesianAxisModel, extraOption);
axisModelCreator(registers, 'y', CartesianAxisModel, extraOption);
registers.registerComponentView(CartesianXAxisView);
registers.registerComponentView(CartesianYAxisView);
registers.registerPreprocessor(function (option) {
// Only create grid when need
if (option.xAxis && option.yAxis && !option.grid) {
option.grid = {};
}
});
}

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './grid/installSimple.js';
use(install);

View File

@@ -0,0 +1,745 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import { curry, each, map, bind, merge, clone, defaults, assert } from 'zrender/lib/core/util.js';
import Eventful from 'zrender/lib/core/Eventful.js';
import * as graphic from '../../util/graphic.js';
import * as interactionMutex from './interactionMutex.js';
import DataDiffer from '../../data/DataDiffer.js';
var BRUSH_PANEL_GLOBAL = true;
var mathMin = Math.min;
var mathMax = Math.max;
var mathPow = Math.pow;
var COVER_Z = 10000;
var UNSELECT_THRESHOLD = 6;
var MIN_RESIZE_LINE_WIDTH = 6;
var MUTEX_RESOURCE_KEY = 'globalPan';
var DIRECTION_MAP = {
w: [0, 0],
e: [0, 1],
n: [1, 0],
s: [1, 1]
};
var CURSOR_MAP = {
w: 'ew',
e: 'ew',
n: 'ns',
s: 'ns',
ne: 'nesw',
sw: 'nesw',
nw: 'nwse',
se: 'nwse'
};
var DEFAULT_BRUSH_OPT = {
brushStyle: {
lineWidth: 2,
stroke: 'rgba(210,219,238,0.3)',
fill: '#D2DBEE'
},
transformable: true,
brushMode: 'single',
removeOnClick: false
};
var baseUID = 0;
/**
* params:
* areas: Array.<Array>, coord relates to container group,
* If no container specified, to global.
* opt {
* isEnd: boolean,
* removeOnClick: boolean
* }
*/
var BrushController = /** @class */function (_super) {
__extends(BrushController, _super);
function BrushController(zr) {
var _this = _super.call(this) || this;
/**
* @internal
*/
_this._track = [];
/**
* @internal
*/
_this._covers = [];
_this._handlers = {};
if (process.env.NODE_ENV !== 'production') {
assert(zr);
}
_this._zr = zr;
_this.group = new graphic.Group();
_this._uid = 'brushController_' + baseUID++;
each(pointerHandlers, function (handler, eventName) {
this._handlers[eventName] = bind(handler, this);
}, _this);
return _this;
}
/**
* If set to `false`, select disabled.
*/
BrushController.prototype.enableBrush = function (brushOption) {
if (process.env.NODE_ENV !== 'production') {
assert(this._mounted);
}
this._brushType && this._doDisableBrush();
brushOption.brushType && this._doEnableBrush(brushOption);
return this;
};
BrushController.prototype._doEnableBrush = function (brushOption) {
var zr = this._zr;
// Consider roam, which takes globalPan too.
if (!this._enableGlobalPan) {
interactionMutex.take(zr, MUTEX_RESOURCE_KEY, this._uid);
}
each(this._handlers, function (handler, eventName) {
zr.on(eventName, handler);
});
this._brushType = brushOption.brushType;
this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
};
BrushController.prototype._doDisableBrush = function () {
var zr = this._zr;
interactionMutex.release(zr, MUTEX_RESOURCE_KEY, this._uid);
each(this._handlers, function (handler, eventName) {
zr.off(eventName, handler);
});
this._brushType = this._brushOption = null;
};
/**
* @param panelOpts If not pass, it is global brush.
*/
BrushController.prototype.setPanels = function (panelOpts) {
if (panelOpts && panelOpts.length) {
var panels_1 = this._panels = {};
each(panelOpts, function (panelOpts) {
panels_1[panelOpts.panelId] = clone(panelOpts);
});
} else {
this._panels = null;
}
return this;
};
BrushController.prototype.mount = function (opt) {
opt = opt || {};
if (process.env.NODE_ENV !== 'production') {
this._mounted = true; // should be at first.
}
this._enableGlobalPan = opt.enableGlobalPan;
var thisGroup = this.group;
this._zr.add(thisGroup);
thisGroup.attr({
x: opt.x || 0,
y: opt.y || 0,
rotation: opt.rotation || 0,
scaleX: opt.scaleX || 1,
scaleY: opt.scaleY || 1
});
this._transform = thisGroup.getLocalTransform();
return this;
};
// eachCover(cb, context): void {
// each(this._covers, cb, context);
// }
/**
* Update covers.
* @param coverConfigList
* If coverConfigList is null/undefined, all covers removed.
*/
BrushController.prototype.updateCovers = function (coverConfigList) {
if (process.env.NODE_ENV !== 'production') {
assert(this._mounted);
}
coverConfigList = map(coverConfigList, function (coverConfig) {
return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true);
});
var tmpIdPrefix = '\0-brush-index-';
var oldCovers = this._covers;
var newCovers = this._covers = [];
var controller = this;
var creatingCover = this._creatingCover;
new DataDiffer(oldCovers, coverConfigList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
return this;
function getKey(brushOption, index) {
return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
}
function oldGetKey(cover, index) {
return getKey(cover.__brushOption, index);
}
function addOrUpdate(newIndex, oldIndex) {
var newBrushInternal = coverConfigList[newIndex];
// Consider setOption in event listener of brushSelect,
// where updating cover when creating should be forbidden.
if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
newCovers[newIndex] = oldCovers[oldIndex];
} else {
var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal));
updateCoverAfterCreation(controller, cover);
}
}
function remove(oldIndex) {
if (oldCovers[oldIndex] !== creatingCover) {
controller.group.remove(oldCovers[oldIndex]);
}
}
};
BrushController.prototype.unmount = function () {
if (process.env.NODE_ENV !== 'production') {
if (!this._mounted) {
return;
}
}
this.enableBrush(false);
// container may 'removeAll' outside.
clearCovers(this);
this._zr.remove(this.group);
if (process.env.NODE_ENV !== 'production') {
this._mounted = false; // should be at last.
}
return this;
};
BrushController.prototype.dispose = function () {
this.unmount();
this.off();
};
return BrushController;
}(Eventful);
function createCover(controller, brushOption) {
var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
cover.__brushOption = brushOption;
updateZ(cover, brushOption);
controller.group.add(cover);
return cover;
}
function endCreating(controller, creatingCover) {
var coverRenderer = getCoverRenderer(creatingCover);
if (coverRenderer.endCreating) {
coverRenderer.endCreating(controller, creatingCover);
updateZ(creatingCover, creatingCover.__brushOption);
}
return creatingCover;
}
function updateCoverShape(controller, cover) {
var brushOption = cover.__brushOption;
getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
}
function updateZ(cover, brushOption) {
var z = brushOption.z;
z == null && (z = COVER_Z);
cover.traverse(function (el) {
el.z = z;
el.z2 = z; // Consider in given container.
});
}
function updateCoverAfterCreation(controller, cover) {
getCoverRenderer(cover).updateCommon(controller, cover);
updateCoverShape(controller, cover);
}
function getCoverRenderer(cover) {
return coverRenderers[cover.__brushOption.brushType];
}
// return target panel or `true` (means global panel)
function getPanelByPoint(controller, e, localCursorPoint) {
var panels = controller._panels;
if (!panels) {
return BRUSH_PANEL_GLOBAL; // Global panel
}
var panel;
var transform = controller._transform;
each(panels, function (pn) {
pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
});
return panel;
}
// Return a panel or true
function getPanelByCover(controller, cover) {
var panels = controller._panels;
if (!panels) {
return BRUSH_PANEL_GLOBAL; // Global panel
}
var panelId = cover.__brushOption.panelId;
// User may give cover without coord sys info,
// which is then treated as global panel.
return panelId != null ? panels[panelId] : BRUSH_PANEL_GLOBAL;
}
function clearCovers(controller) {
var covers = controller._covers;
var originalLength = covers.length;
each(covers, function (cover) {
controller.group.remove(cover);
}, controller);
covers.length = 0;
return !!originalLength;
}
function trigger(controller, opt) {
var areas = map(controller._covers, function (cover) {
var brushOption = cover.__brushOption;
var range = clone(brushOption.range);
return {
brushType: brushOption.brushType,
panelId: brushOption.panelId,
range: range
};
});
controller.trigger('brush', {
areas: areas,
isEnd: !!opt.isEnd,
removeOnClick: !!opt.removeOnClick
});
}
function shouldShowCover(controller) {
var track = controller._track;
if (!track.length) {
return false;
}
var p2 = track[track.length - 1];
var p1 = track[0];
var dx = p2[0] - p1[0];
var dy = p2[1] - p1[1];
var dist = mathPow(dx * dx + dy * dy, 0.5);
return dist > UNSELECT_THRESHOLD;
}
function getTrackEnds(track) {
var tail = track.length - 1;
tail < 0 && (tail = 0);
return [track[0], track[tail]];
}
;
function createBaseRectCover(rectRangeConverter, controller, brushOption, edgeNameSequences) {
var cover = new graphic.Group();
cover.add(new graphic.Rect({
name: 'main',
style: makeStyle(brushOption),
silent: true,
draggable: true,
cursor: 'move',
drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']),
ondragend: curry(trigger, controller, {
isEnd: true
})
}));
each(edgeNameSequences, function (nameSequence) {
cover.add(new graphic.Rect({
name: nameSequence.join(''),
style: {
opacity: 0
},
draggable: true,
silent: true,
invisible: true,
drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence),
ondragend: curry(trigger, controller, {
isEnd: true
})
}));
});
return cover;
}
function updateBaseRect(controller, cover, localRange, brushOption) {
var lineWidth = brushOption.brushStyle.lineWidth || 0;
var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH);
var x = localRange[0][0];
var y = localRange[1][0];
var xa = x - lineWidth / 2;
var ya = y - lineWidth / 2;
var x2 = localRange[0][1];
var y2 = localRange[1][1];
var x2a = x2 - handleSize + lineWidth / 2;
var y2a = y2 - handleSize + lineWidth / 2;
var width = x2 - x;
var height = y2 - y;
var widtha = width + lineWidth;
var heighta = height + lineWidth;
updateRectShape(controller, cover, 'main', x, y, width, height);
if (brushOption.transformable) {
updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
}
}
function updateCommon(controller, cover) {
var brushOption = cover.__brushOption;
var transformable = brushOption.transformable;
var mainEl = cover.childAt(0);
mainEl.useStyle(makeStyle(brushOption));
mainEl.attr({
silent: !transformable,
cursor: transformable ? 'move' : 'default'
});
each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) {
var el = cover.childOfName(nameSequence.join(''));
var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence);
el && el.attr({
silent: !transformable,
invisible: !transformable,
cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
});
});
}
function updateRectShape(controller, cover, name, x, y, w, h) {
var el = cover.childOfName(name);
el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
}
function makeStyle(brushOption) {
return defaults({
strokeNoScale: true
}, brushOption.brushStyle);
}
function formatRectRange(x, y, x2, y2) {
var min = [mathMin(x, x2), mathMin(y, y2)];
var max = [mathMax(x, x2), mathMax(y, y2)];
return [[min[0], max[0]], [min[1], max[1]] // y range
];
}
function getTransform(controller) {
return graphic.getTransform(controller.group);
}
function getGlobalDirection1(controller, localDirName) {
var map = {
w: 'left',
e: 'right',
n: 'top',
s: 'bottom'
};
var inverseMap = {
left: 'w',
right: 'e',
top: 'n',
bottom: 's'
};
var dir = graphic.transformDirection(map[localDirName], getTransform(controller));
return inverseMap[dir];
}
function getGlobalDirection2(controller, localDirNameSeq) {
var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])];
(globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
return globalDir.join('');
}
function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) {
var brushOption = cover.__brushOption;
var rectRange = rectRangeConverter.toRectRange(brushOption.range);
var localDelta = toLocalDelta(controller, dx, dy);
each(dirNameSequence, function (dirName) {
var ind = DIRECTION_MAP[dirName];
rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
});
brushOption.range = rectRangeConverter.fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
updateCoverAfterCreation(controller, cover);
trigger(controller, {
isEnd: false
});
}
function driftPolygon(controller, cover, dx, dy) {
var range = cover.__brushOption.range;
var localDelta = toLocalDelta(controller, dx, dy);
each(range, function (point) {
point[0] += localDelta[0];
point[1] += localDelta[1];
});
updateCoverAfterCreation(controller, cover);
trigger(controller, {
isEnd: false
});
}
function toLocalDelta(controller, dx, dy) {
var thisGroup = controller.group;
var localD = thisGroup.transformCoordToLocal(dx, dy);
var localZero = thisGroup.transformCoordToLocal(0, 0);
return [localD[0] - localZero[0], localD[1] - localZero[1]];
}
function clipByPanel(controller, cover, data) {
var panel = getPanelByCover(controller, cover);
return panel && panel !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data);
}
function pointsToRect(points) {
var xmin = mathMin(points[0][0], points[1][0]);
var ymin = mathMin(points[0][1], points[1][1]);
var xmax = mathMax(points[0][0], points[1][0]);
var ymax = mathMax(points[0][1], points[1][1]);
return {
x: xmin,
y: ymin,
width: xmax - xmin,
height: ymax - ymin
};
}
function resetCursor(controller, e, localCursorPoint) {
if (
// Check active
!controller._brushType
// resetCursor should be always called when mouse is in zr area,
// but not called when mouse is out of zr area to avoid bad influence
// if `mousemove`, `mouseup` are triggered from `document` event.
|| isOutsideZrArea(controller, e.offsetX, e.offsetY)) {
return;
}
var zr = controller._zr;
var covers = controller._covers;
var currPanel = getPanelByPoint(controller, e, localCursorPoint);
// Check whether in covers.
if (!controller._dragging) {
for (var i = 0; i < covers.length; i++) {
var brushOption = covers[i].__brushOption;
if (currPanel && (currPanel === BRUSH_PANEL_GLOBAL || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
// Use cursor style set on cover.
return;
}
}
}
currPanel && zr.setCursorStyle('crosshair');
}
function preventDefault(e) {
var rawE = e.event;
rawE.preventDefault && rawE.preventDefault();
}
function mainShapeContain(cover, x, y) {
return cover.childOfName('main').contain(x, y);
}
function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
var creatingCover = controller._creatingCover;
var panel = controller._creatingPanel;
var thisBrushOption = controller._brushOption;
var eventParams;
controller._track.push(localCursorPoint.slice());
if (shouldShowCover(controller) || creatingCover) {
if (panel && !creatingCover) {
thisBrushOption.brushMode === 'single' && clearCovers(controller);
var brushOption = clone(thisBrushOption);
brushOption.brushType = determineBrushType(brushOption.brushType, panel);
brushOption.panelId = panel === BRUSH_PANEL_GLOBAL ? null : panel.panelId;
creatingCover = controller._creatingCover = createCover(controller, brushOption);
controller._covers.push(creatingCover);
}
if (creatingCover) {
var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
var coverBrushOption = creatingCover.__brushOption;
coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));
if (isEnd) {
endCreating(controller, creatingCover);
coverRenderer.updateCommon(controller, creatingCover);
}
updateCoverShape(controller, creatingCover);
eventParams = {
isEnd: isEnd
};
}
} else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
// Help user to remove covers easily, only by a tiny drag, in 'single' mode.
// But a single click do not clear covers, because user may have casual
// clicks (for example, click on other component and do not expect covers
// disappear).
// Only some cover removed, trigger action, but not every click trigger action.
if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
eventParams = {
isEnd: isEnd,
removeOnClick: true
};
}
}
return eventParams;
}
function determineBrushType(brushType, panel) {
if (brushType === 'auto') {
if (process.env.NODE_ENV !== 'production') {
assert(panel && panel.defaultBrushType, 'MUST have defaultBrushType when brushType is "atuo"');
}
return panel.defaultBrushType;
}
return brushType;
}
var pointerHandlers = {
mousedown: function (e) {
if (this._dragging) {
// In case some browser do not support globalOut,
// and release mouse out side the browser.
handleDragEnd(this, e);
} else if (!e.target || !e.target.draggable) {
preventDefault(e);
var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
this._creatingCover = null;
var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);
if (panel) {
this._dragging = true;
this._track = [localCursorPoint.slice()];
}
}
},
mousemove: function (e) {
var x = e.offsetX;
var y = e.offsetY;
var localCursorPoint = this.group.transformCoordToLocal(x, y);
resetCursor(this, e, localCursorPoint);
if (this._dragging) {
preventDefault(e);
var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
eventParams && trigger(this, eventParams);
}
},
mouseup: function (e) {
handleDragEnd(this, e);
}
};
function handleDragEnd(controller, e) {
if (controller._dragging) {
preventDefault(e);
var x = e.offsetX;
var y = e.offsetY;
var localCursorPoint = controller.group.transformCoordToLocal(x, y);
var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
controller._dragging = false;
controller._track = [];
controller._creatingCover = null;
// trigger event should be at final, after procedure will be nested.
eventParams && trigger(controller, eventParams);
}
}
function isOutsideZrArea(controller, x, y) {
var zr = controller._zr;
return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
}
/**
* key: brushType
*/
var coverRenderers = {
lineX: getLineRenderer(0),
lineY: getLineRenderer(1),
rect: {
createCover: function (controller, brushOption) {
function returnInput(range) {
return range;
}
return createBaseRectCover({
toRectRange: returnInput,
fromRectRange: returnInput
}, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]);
},
getCreatingRange: function (localTrack) {
var ends = getTrackEnds(localTrack);
return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
},
updateCoverShape: function (controller, cover, localRange, brushOption) {
updateBaseRect(controller, cover, localRange, brushOption);
},
updateCommon: updateCommon,
contain: mainShapeContain
},
polygon: {
createCover: function (controller, brushOption) {
var cover = new graphic.Group();
// Do not use graphic.Polygon because graphic.Polyline do not close the
// border of the shape when drawing, which is a better experience for user.
cover.add(new graphic.Polyline({
name: 'main',
style: makeStyle(brushOption),
silent: true
}));
return cover;
},
getCreatingRange: function (localTrack) {
return localTrack;
},
endCreating: function (controller, cover) {
cover.remove(cover.childAt(0));
// Use graphic.Polygon close the shape.
cover.add(new graphic.Polygon({
name: 'main',
draggable: true,
drift: curry(driftPolygon, controller, cover),
ondragend: curry(trigger, controller, {
isEnd: true
})
}));
},
updateCoverShape: function (controller, cover, localRange, brushOption) {
cover.childAt(0).setShape({
points: clipByPanel(controller, cover, localRange)
});
},
updateCommon: updateCommon,
contain: mainShapeContain
}
};
function getLineRenderer(xyIndex) {
return {
createCover: function (controller, brushOption) {
return createBaseRectCover({
toRectRange: function (range) {
var rectRange = [range, [0, 100]];
xyIndex && rectRange.reverse();
return rectRange;
},
fromRectRange: function (rectRange) {
return rectRange[xyIndex];
}
}, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]);
},
getCreatingRange: function (localTrack) {
var ends = getTrackEnds(localTrack);
var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]);
var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]);
return [min, max];
},
updateCoverShape: function (controller, cover, localRange, brushOption) {
var otherExtent;
// If brushWidth not specified, fit the panel.
var panel = getPanelByCover(controller, cover);
if (panel !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) {
otherExtent = panel.getLinearBrushOtherExtent(xyIndex);
} else {
var zr = controller._zr;
otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
}
var rectRange = [localRange, otherExtent];
xyIndex && rectRange.reverse();
updateBaseRect(controller, cover, rectRange, brushOption);
},
updateCommon: updateCommon,
contain: mainShapeContain
};
}
export default BrushController;

View File

@@ -0,0 +1,343 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { each, indexOf, curry, assert, map, createHashMap } from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import * as brushHelper from './brushHelper.js';
import { parseFinder as modelUtilParseFinder } from '../../util/model.js';
// FIXME
// how to genarialize to more coordinate systems.
var INCLUDE_FINDER_MAIN_TYPES = ['grid', 'xAxis', 'yAxis', 'geo', 'graph', 'polar', 'radiusAxis', 'angleAxis', 'bmap'];
var BrushTargetManager = /** @class */function () {
/**
* @param finder contains Index/Id/Name of xAxis/yAxis/geo/grid
* Each can be {number|Array.<number>}. like: {xAxisIndex: [3, 4]}
* @param opt.include include coordinate system types.
*/
function BrushTargetManager(finder, ecModel, opt) {
var _this = this;
this._targetInfoList = [];
var foundCpts = parseFinder(ecModel, finder);
each(targetInfoBuilders, function (builder, type) {
if (!opt || !opt.include || indexOf(opt.include, type) >= 0) {
builder(foundCpts, _this._targetInfoList);
}
});
}
BrushTargetManager.prototype.setOutputRanges = function (areas, ecModel) {
this.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
(area.coordRanges || (area.coordRanges = [])).push(coordRange);
// area.coordRange is the first of area.coordRanges
if (!area.coordRange) {
area.coordRange = coordRange;
// In 'category' axis, coord to pixel is not reversible, so we can not
// rebuild range by coordRange accrately, which may bring trouble when
// brushing only one item. So we use __rangeOffset to rebuilding range
// by coordRange. And this it only used in brush component so it is no
// need to be adapted to coordRanges.
var result = coordConvert[area.brushType](0, coordSys, coordRange);
area.__rangeOffset = {
offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]),
xyMinMax: result.xyMinMax
};
}
});
return areas;
};
BrushTargetManager.prototype.matchOutputRanges = function (areas, ecModel, cb) {
each(areas, function (area) {
var targetInfo = this.findTargetInfo(area, ecModel);
if (targetInfo && targetInfo !== true) {
each(targetInfo.coordSyses, function (coordSys) {
var result = coordConvert[area.brushType](1, coordSys, area.range, true);
cb(area, result.values, coordSys, ecModel);
});
}
}, this);
};
/**
* the `areas` is `BrushModel.areas`.
* Called in layout stage.
* convert `area.coordRange` to global range and set panelId to `area.range`.
*/
BrushTargetManager.prototype.setInputRanges = function (areas, ecModel) {
each(areas, function (area) {
var targetInfo = this.findTargetInfo(area, ecModel);
if (process.env.NODE_ENV !== 'production') {
assert(!targetInfo || targetInfo === true || area.coordRange, 'coordRange must be specified when coord index specified.');
assert(!targetInfo || targetInfo !== true || area.range, 'range must be specified in global brush.');
}
area.range = area.range || [];
// convert coordRange to global range and set panelId.
if (targetInfo && targetInfo !== true) {
area.panelId = targetInfo.panelId;
// (1) area.range should always be calculate from coordRange but does
// not keep its original value, for the sake of the dataZoom scenario,
// where area.coordRange remains unchanged but area.range may be changed.
// (2) Only support converting one coordRange to pixel range in brush
// component. So do not consider `coordRanges`.
// (3) About __rangeOffset, see comment above.
var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
var rangeOffset = area.__rangeOffset;
area.range = rangeOffset ? diffProcessor[area.brushType](result.values, rangeOffset.offset, getScales(result.xyMinMax, rangeOffset.xyMinMax)) : result.values;
}
}, this);
};
BrushTargetManager.prototype.makePanelOpts = function (api, getDefaultBrushType) {
return map(this._targetInfoList, function (targetInfo) {
var rect = targetInfo.getPanelRect();
return {
panelId: targetInfo.panelId,
defaultBrushType: getDefaultBrushType ? getDefaultBrushType(targetInfo) : null,
clipPath: brushHelper.makeRectPanelClipPath(rect),
isTargetByCursor: brushHelper.makeRectIsTargetByCursor(rect, api, targetInfo.coordSysModel),
getLinearBrushOtherExtent: brushHelper.makeLinearBrushOtherExtent(rect)
};
});
};
BrushTargetManager.prototype.controlSeries = function (area, seriesModel, ecModel) {
// Check whether area is bound in coord, and series do not belong to that coord.
// If do not do this check, some brush (like lineX) will controll all axes.
var targetInfo = this.findTargetInfo(area, ecModel);
return targetInfo === true || targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0;
};
/**
* If return Object, a coord found.
* If return true, global found.
* Otherwise nothing found.
*/
BrushTargetManager.prototype.findTargetInfo = function (area, ecModel) {
var targetInfoList = this._targetInfoList;
var foundCpts = parseFinder(ecModel, area);
for (var i = 0; i < targetInfoList.length; i++) {
var targetInfo = targetInfoList[i];
var areaPanelId = area.panelId;
if (areaPanelId) {
if (targetInfo.panelId === areaPanelId) {
return targetInfo;
}
} else {
for (var j = 0; j < targetInfoMatchers.length; j++) {
if (targetInfoMatchers[j](foundCpts, targetInfo)) {
return targetInfo;
}
}
}
}
return true;
};
return BrushTargetManager;
}();
function formatMinMax(minMax) {
minMax[0] > minMax[1] && minMax.reverse();
return minMax;
}
function parseFinder(ecModel, finder) {
return modelUtilParseFinder(ecModel, finder, {
includeMainTypes: INCLUDE_FINDER_MAIN_TYPES
});
}
var targetInfoBuilders = {
grid: function (foundCpts, targetInfoList) {
var xAxisModels = foundCpts.xAxisModels;
var yAxisModels = foundCpts.yAxisModels;
var gridModels = foundCpts.gridModels;
// Remove duplicated.
var gridModelMap = createHashMap();
var xAxesHas = {};
var yAxesHas = {};
if (!xAxisModels && !yAxisModels && !gridModels) {
return;
}
each(xAxisModels, function (axisModel) {
var gridModel = axisModel.axis.grid.model;
gridModelMap.set(gridModel.id, gridModel);
xAxesHas[gridModel.id] = true;
});
each(yAxisModels, function (axisModel) {
var gridModel = axisModel.axis.grid.model;
gridModelMap.set(gridModel.id, gridModel);
yAxesHas[gridModel.id] = true;
});
each(gridModels, function (gridModel) {
gridModelMap.set(gridModel.id, gridModel);
xAxesHas[gridModel.id] = true;
yAxesHas[gridModel.id] = true;
});
gridModelMap.each(function (gridModel) {
var grid = gridModel.coordinateSystem;
var cartesians = [];
each(grid.getCartesians(), function (cartesian, index) {
if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0 || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0) {
cartesians.push(cartesian);
}
});
targetInfoList.push({
panelId: 'grid--' + gridModel.id,
gridModel: gridModel,
coordSysModel: gridModel,
// Use the first one as the representitive coordSys.
coordSys: cartesians[0],
coordSyses: cartesians,
getPanelRect: panelRectBuilders.grid,
xAxisDeclared: xAxesHas[gridModel.id],
yAxisDeclared: yAxesHas[gridModel.id]
});
});
},
geo: function (foundCpts, targetInfoList) {
each(foundCpts.geoModels, function (geoModel) {
var coordSys = geoModel.coordinateSystem;
targetInfoList.push({
panelId: 'geo--' + geoModel.id,
geoModel: geoModel,
coordSysModel: geoModel,
coordSys: coordSys,
coordSyses: [coordSys],
getPanelRect: panelRectBuilders.geo
});
});
}
};
var targetInfoMatchers = [
// grid
function (foundCpts, targetInfo) {
var xAxisModel = foundCpts.xAxisModel;
var yAxisModel = foundCpts.yAxisModel;
var gridModel = foundCpts.gridModel;
!gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model);
!gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model);
return gridModel && gridModel === targetInfo.gridModel;
},
// geo
function (foundCpts, targetInfo) {
var geoModel = foundCpts.geoModel;
return geoModel && geoModel === targetInfo.geoModel;
}];
var panelRectBuilders = {
grid: function () {
// grid is not Transformable.
return this.coordSys.master.getRect().clone();
},
geo: function () {
var coordSys = this.coordSys;
var rect = coordSys.getBoundingRect().clone();
// geo roam and zoom transform
rect.applyTransform(graphic.getTransform(coordSys));
return rect;
}
};
var coordConvert = {
lineX: curry(axisConvert, 0),
lineY: curry(axisConvert, 1),
rect: function (to, coordSys, rangeOrCoordRange, clamp) {
var xminymin = to ? coordSys.pointToData([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp);
var xmaxymax = to ? coordSys.pointToData([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp);
var values = [formatMinMax([xminymin[0], xmaxymax[0]]), formatMinMax([xminymin[1], xmaxymax[1]])];
return {
values: values,
xyMinMax: values
};
},
polygon: function (to, coordSys, rangeOrCoordRange, clamp) {
var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
var values = map(rangeOrCoordRange, function (item) {
var p = to ? coordSys.pointToData(item, clamp) : coordSys.dataToPoint(item, clamp);
xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]);
xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]);
xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]);
xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]);
return p;
});
return {
values: values,
xyMinMax: xyMinMax
};
}
};
function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) {
if (process.env.NODE_ENV !== 'production') {
assert(coordSys.type === 'cartesian2d', 'lineX/lineY brush is available only in cartesian2d.');
}
var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]);
var values = formatMinMax(map([0, 1], function (i) {
return to ? axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i]), true) : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i]));
}));
var xyMinMax = [];
xyMinMax[axisNameIndex] = values;
xyMinMax[1 - axisNameIndex] = [NaN, NaN];
return {
values: values,
xyMinMax: xyMinMax
};
}
var diffProcessor = {
lineX: curry(axisDiffProcessor, 0),
lineY: curry(axisDiffProcessor, 1),
rect: function (values, refer, scales) {
return [[values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]], [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]];
},
polygon: function (values, refer, scales) {
return map(values, function (item, idx) {
return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]];
});
}
};
function axisDiffProcessor(axisNameIndex, values, refer, scales) {
return [values[0] - scales[axisNameIndex] * refer[0], values[1] - scales[axisNameIndex] * refer[1]];
}
// We have to process scale caused by dataZoom manually,
// although it might be not accurate.
// Return [0~1, 0~1]
function getScales(xyMinMaxCurr, xyMinMaxOrigin) {
var sizeCurr = getSize(xyMinMaxCurr);
var sizeOrigin = getSize(xyMinMaxOrigin);
var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]];
isNaN(scales[0]) && (scales[0] = 1);
isNaN(scales[1]) && (scales[1] = 1);
return scales;
}
function getSize(xyMinMax) {
return xyMinMax ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : [NaN, NaN];
}
export default BrushTargetManager;

View File

@@ -0,0 +1,678 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import RoamController from './RoamController.js';
import * as roamHelper from '../../component/helper/roamHelper.js';
import { onIrrelevantElement } from '../../component/helper/cursorHelper.js';
import * as graphic from '../../util/graphic.js';
import { toggleHoverEmphasis, enableComponentHighDownFeatures, setDefaultStateProxy } from '../../util/states.js';
import geoSourceManager from '../../coord/geo/geoSourceManager.js';
import { getUID } from '../../util/component.js';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle.js';
import { getECData } from '../../util/innerStore.js';
import { createOrUpdatePatternFromDecal } from '../../util/decal.js';
import Displayable from 'zrender/lib/graphic/Displayable.js';
import { makeInner } from '../../util/model.js';
/**
* Only these tags enable use `itemStyle` if they are named in SVG.
* Other tags like <text> <tspan> <image> might not suitable for `itemStyle`.
* They will not be considered to be styled until some requirements come.
*/
var OPTION_STYLE_ENABLED_TAGS = ['rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path'];
var OPTION_STYLE_ENABLED_TAG_MAP = zrUtil.createHashMap(OPTION_STYLE_ENABLED_TAGS);
var STATE_TRIGGER_TAG_MAP = zrUtil.createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g']));
var LABEL_HOST_MAP = zrUtil.createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g']));
var mapLabelRaw = makeInner();
function getFixedItemStyle(model) {
var itemStyle = model.getItemStyle();
var areaColor = model.get('areaColor');
// If user want the color not to be changed when hover,
// they should both set areaColor and color to be null.
if (areaColor != null) {
itemStyle.fill = areaColor;
}
return itemStyle;
}
// Only stroke can be used for line.
// Using fill in style if stroke not exits.
// TODO Not sure yet. Perhaps a separate `lineStyle`?
function fixLineStyle(styleHost) {
var style = styleHost.style;
if (style) {
style.stroke = style.stroke || style.fill;
style.fill = null;
}
}
var MapDraw = /** @class */function () {
function MapDraw(api) {
var group = new graphic.Group();
this.uid = getUID('ec_map_draw');
this._controller = new RoamController(api.getZr());
this._controllerHost = {
target: group
};
this.group = group;
group.add(this._regionsGroup = new graphic.Group());
group.add(this._svgGroup = new graphic.Group());
}
MapDraw.prototype.draw = function (mapOrGeoModel, ecModel, api, fromView, payload) {
var isGeo = mapOrGeoModel.mainType === 'geo';
// Map series has data. GEO model that controlled by map series
// will be assigned with map data. Other GEO model has no data.
var data = mapOrGeoModel.getData && mapOrGeoModel.getData();
isGeo && ecModel.eachComponent({
mainType: 'series',
subType: 'map'
}, function (mapSeries) {
if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) {
data = mapSeries.getData();
}
});
var geo = mapOrGeoModel.coordinateSystem;
var regionsGroup = this._regionsGroup;
var group = this.group;
var transformInfo = geo.getTransformInfo();
var transformInfoRaw = transformInfo.raw;
var transformInfoRoam = transformInfo.roam;
// No animation when first draw or in action
var isFirstDraw = !regionsGroup.childAt(0) || payload;
if (isFirstDraw) {
group.x = transformInfoRoam.x;
group.y = transformInfoRoam.y;
group.scaleX = transformInfoRoam.scaleX;
group.scaleY = transformInfoRoam.scaleY;
group.dirty();
} else {
graphic.updateProps(group, transformInfoRoam, mapOrGeoModel);
}
var isVisualEncodedByVisualMap = data && data.getVisual('visualMeta') && data.getVisual('visualMeta').length > 0;
var viewBuildCtx = {
api: api,
geo: geo,
mapOrGeoModel: mapOrGeoModel,
data: data,
isVisualEncodedByVisualMap: isVisualEncodedByVisualMap,
isGeo: isGeo,
transformInfoRaw: transformInfoRaw
};
if (geo.resourceType === 'geoJSON') {
this._buildGeoJSON(viewBuildCtx);
} else if (geo.resourceType === 'geoSVG') {
this._buildSVG(viewBuildCtx);
}
this._updateController(mapOrGeoModel, ecModel, api);
this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView);
};
MapDraw.prototype._buildGeoJSON = function (viewBuildCtx) {
var regionsGroupByName = this._regionsGroupByName = zrUtil.createHashMap();
var regionsInfoByName = zrUtil.createHashMap();
var regionsGroup = this._regionsGroup;
var transformInfoRaw = viewBuildCtx.transformInfoRaw;
var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
var data = viewBuildCtx.data;
var projection = viewBuildCtx.geo.projection;
var projectionStream = projection && projection.stream;
function transformPoint(point, project) {
if (project) {
// projection may return null point.
point = project(point);
}
return point && [point[0] * transformInfoRaw.scaleX + transformInfoRaw.x, point[1] * transformInfoRaw.scaleY + transformInfoRaw.y];
}
;
function transformPolygonPoints(inPoints) {
var outPoints = [];
// If projectionStream is provided. Use it instead of single point project.
var project = !projectionStream && projection && projection.project;
for (var i = 0; i < inPoints.length; ++i) {
var newPt = transformPoint(inPoints[i], project);
newPt && outPoints.push(newPt);
}
return outPoints;
}
function getPolyShape(points) {
return {
shape: {
points: transformPolygonPoints(points)
}
};
}
regionsGroup.removeAll();
// Only when the resource is GeoJSON, there is `geo.regions`.
zrUtil.each(viewBuildCtx.geo.regions, function (region) {
var regionName = region.name;
// Consider in GeoJson properties.name may be duplicated, for example,
// there is multiple region named "United Kindom" or "France" (so many
// colonies). And it is not appropriate to merge them in geo, which
// will make them share the same label and bring trouble in label
// location calculation.
var regionGroup = regionsGroupByName.get(regionName);
var _a = regionsInfoByName.get(regionName) || {},
dataIdx = _a.dataIdx,
regionModel = _a.regionModel;
if (!regionGroup) {
regionGroup = regionsGroupByName.set(regionName, new graphic.Group());
regionsGroup.add(regionGroup);
dataIdx = data ? data.indexOfName(regionName) : null;
regionModel = viewBuildCtx.isGeo ? mapOrGeoModel.getRegionModel(regionName) : data ? data.getItemModel(dataIdx) : null;
var silent = regionModel.get('silent', true);
silent != null && (regionGroup.silent = silent);
regionsInfoByName.set(regionName, {
dataIdx: dataIdx,
regionModel: regionModel
});
}
var polygonSubpaths = [];
var polylineSubpaths = [];
zrUtil.each(region.geometries, function (geometry) {
// Polygon and MultiPolygon
if (geometry.type === 'polygon') {
var polys = [geometry.exterior].concat(geometry.interiors || []);
if (projectionStream) {
polys = projectPolys(polys, projectionStream);
}
zrUtil.each(polys, function (poly) {
polygonSubpaths.push(new graphic.Polygon(getPolyShape(poly)));
});
}
// LineString and MultiLineString
else {
var points = geometry.points;
if (projectionStream) {
points = projectPolys(points, projectionStream, true);
}
zrUtil.each(points, function (points) {
polylineSubpaths.push(new graphic.Polyline(getPolyShape(points)));
});
}
});
var centerPt = transformPoint(region.getCenter(), projection && projection.project);
function createCompoundPath(subpaths, isLine) {
if (!subpaths.length) {
return;
}
var compoundPath = new graphic.CompoundPath({
culling: true,
segmentIgnoreThreshold: 1,
shape: {
paths: subpaths
}
});
regionGroup.add(compoundPath);
applyOptionStyleForRegion(viewBuildCtx, compoundPath, dataIdx, regionModel);
resetLabelForRegion(viewBuildCtx, compoundPath, regionName, regionModel, mapOrGeoModel, dataIdx, centerPt);
if (isLine) {
fixLineStyle(compoundPath);
zrUtil.each(compoundPath.states, fixLineStyle);
}
}
createCompoundPath(polygonSubpaths);
createCompoundPath(polylineSubpaths, true);
});
// Ensure children have been added to `regionGroup` before calling them.
regionsGroupByName.each(function (regionGroup, regionName) {
var _a = regionsInfoByName.get(regionName),
dataIdx = _a.dataIdx,
regionModel = _a.regionModel;
resetEventTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel, dataIdx);
resetTooltipForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
resetStateTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
}, this);
};
MapDraw.prototype._buildSVG = function (viewBuildCtx) {
var mapName = viewBuildCtx.geo.map;
var transformInfoRaw = viewBuildCtx.transformInfoRaw;
this._svgGroup.x = transformInfoRaw.x;
this._svgGroup.y = transformInfoRaw.y;
this._svgGroup.scaleX = transformInfoRaw.scaleX;
this._svgGroup.scaleY = transformInfoRaw.scaleY;
if (this._svgResourceChanged(mapName)) {
this._freeSVG();
this._useSVG(mapName);
}
var svgDispatcherMap = this._svgDispatcherMap = zrUtil.createHashMap();
var focusSelf = false;
zrUtil.each(this._svgGraphicRecord.named, function (namedItem) {
// Note that we also allow different elements have the same name.
// For example, a glyph of a city and the label of the city have
// the same name and their tooltip info can be defined in a single
// region option.
var regionName = namedItem.name;
var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
var data = viewBuildCtx.data;
var svgNodeTagLower = namedItem.svgNodeTagLower;
var el = namedItem.el;
var dataIdx = data ? data.indexOfName(regionName) : null;
var regionModel = mapOrGeoModel.getRegionModel(regionName);
if (OPTION_STYLE_ENABLED_TAG_MAP.get(svgNodeTagLower) != null && el instanceof Displayable) {
applyOptionStyleForRegion(viewBuildCtx, el, dataIdx, regionModel);
}
if (el instanceof Displayable) {
el.culling = true;
}
var silent = regionModel.get('silent', true);
silent != null && (el.silent = silent);
// We do not know how the SVG like so we'd better not to change z2.
// Otherwise it might bring some unexpected result. For example,
// an area hovered that make some inner city can not be clicked.
el.z2EmphasisLift = 0;
// If self named:
if (!namedItem.namedFrom) {
// label should batter to be displayed based on the center of <g>
// if it is named rather than displayed on each child.
if (LABEL_HOST_MAP.get(svgNodeTagLower) != null) {
resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, null);
}
resetEventTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx);
resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);
if (STATE_TRIGGER_TAG_MAP.get(svgNodeTagLower) != null) {
var focus_1 = resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);
if (focus_1 === 'self') {
focusSelf = true;
}
var els = svgDispatcherMap.get(regionName) || svgDispatcherMap.set(regionName, []);
els.push(el);
}
}
}, this);
this._enableBlurEntireSVG(focusSelf, viewBuildCtx);
};
MapDraw.prototype._enableBlurEntireSVG = function (focusSelf, viewBuildCtx) {
// It's a little complicated to support blurring the entire geoSVG in series-map.
// So do not support it until some requirements come.
// At present, in series-map, only regions can be blurred.
if (focusSelf && viewBuildCtx.isGeo) {
var blurStyle = viewBuildCtx.mapOrGeoModel.getModel(['blur', 'itemStyle']).getItemStyle();
// Only support `opacity` here. Because not sure that other props are suitable for
// all of the elements generated by SVG (especially for Text/TSpan/Image/... ).
var opacity_1 = blurStyle.opacity;
this._svgGraphicRecord.root.traverse(function (el) {
if (!el.isGroup) {
// PENDING: clear those settings to SVG elements when `_freeSVG`.
// (Currently it happen not to be needed.)
setDefaultStateProxy(el);
var style = el.ensureState('blur').style || {};
// Do not overwrite the region style that already set from region option.
if (style.opacity == null && opacity_1 != null) {
style.opacity = opacity_1;
}
// If `ensureState('blur').style = {}`, there will be default opacity.
// Enable `stateTransition` (animation).
el.ensureState('emphasis');
}
});
}
};
MapDraw.prototype.remove = function () {
this._regionsGroup.removeAll();
this._regionsGroupByName = null;
this._svgGroup.removeAll();
this._freeSVG();
this._controller.dispose();
this._controllerHost = null;
};
MapDraw.prototype.findHighDownDispatchers = function (name, geoModel) {
if (name == null) {
return [];
}
var geo = geoModel.coordinateSystem;
if (geo.resourceType === 'geoJSON') {
var regionsGroupByName = this._regionsGroupByName;
if (regionsGroupByName) {
var regionGroup = regionsGroupByName.get(name);
return regionGroup ? [regionGroup] : [];
}
} else if (geo.resourceType === 'geoSVG') {
return this._svgDispatcherMap && this._svgDispatcherMap.get(name) || [];
}
};
MapDraw.prototype._svgResourceChanged = function (mapName) {
return this._svgMapName !== mapName;
};
MapDraw.prototype._useSVG = function (mapName) {
var resource = geoSourceManager.getGeoResource(mapName);
if (resource && resource.type === 'geoSVG') {
var svgGraphic = resource.useGraphic(this.uid);
this._svgGroup.add(svgGraphic.root);
this._svgGraphicRecord = svgGraphic;
this._svgMapName = mapName;
}
};
MapDraw.prototype._freeSVG = function () {
var mapName = this._svgMapName;
if (mapName == null) {
return;
}
var resource = geoSourceManager.getGeoResource(mapName);
if (resource && resource.type === 'geoSVG') {
resource.freeGraphic(this.uid);
}
this._svgGraphicRecord = null;
this._svgDispatcherMap = null;
this._svgGroup.removeAll();
this._svgMapName = null;
};
MapDraw.prototype._updateController = function (mapOrGeoModel, ecModel, api) {
var geo = mapOrGeoModel.coordinateSystem;
var controller = this._controller;
var controllerHost = this._controllerHost;
// @ts-ignore FIXME:TS
controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit');
controllerHost.zoom = geo.getZoom();
// roamType is will be set default true if it is null
// @ts-ignore FIXME:TS
controller.enable(mapOrGeoModel.get('roam') || false);
var mainType = mapOrGeoModel.mainType;
function makeActionBase() {
var action = {
type: 'geoRoam',
componentType: mainType
};
action[mainType + 'Id'] = mapOrGeoModel.id;
return action;
}
controller.off('pan').on('pan', function (e) {
this._mouseDownFlag = false;
roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
api.dispatchAction(zrUtil.extend(makeActionBase(), {
dx: e.dx,
dy: e.dy,
animation: {
duration: 0
}
}));
}, this);
controller.off('zoom').on('zoom', function (e) {
this._mouseDownFlag = false;
roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
api.dispatchAction(zrUtil.extend(makeActionBase(), {
totalZoom: controllerHost.zoom,
zoom: e.scale,
originX: e.originX,
originY: e.originY,
animation: {
duration: 0
}
}));
}, this);
controller.setPointerChecker(function (e, x, y) {
return geo.containPoint([x, y]) && !onIrrelevantElement(e, api, mapOrGeoModel);
});
};
/**
* FIXME: this is a temporarily workaround.
* When `geoRoam` the elements need to be reset in `MapView['render']`, because the props like
* `ignore` might have been modified by `LabelManager`, and `LabelManager#addLabelsOfSeries`
* will subsequently cache `defaultAttr` like `ignore`. If do not do this reset, the modified
* props will have no chance to be restored.
* Note: This reset should be after `clearStates` in `renderSeries` because `useStates` in
* `renderSeries` will cache the modified `ignore` to `el._normalState`.
* TODO:
* Use clone/immutable in `LabelManager`?
*/
MapDraw.prototype.resetForLabelLayout = function () {
this.group.traverse(function (el) {
var label = el.getTextContent();
if (label) {
label.ignore = mapLabelRaw(label).ignore;
}
});
};
MapDraw.prototype._updateMapSelectHandler = function (mapOrGeoModel, regionsGroup, api, fromView) {
var mapDraw = this;
regionsGroup.off('mousedown');
regionsGroup.off('click');
// @ts-ignore FIXME:TS resolve type conflict
if (mapOrGeoModel.get('selectedMode')) {
regionsGroup.on('mousedown', function () {
mapDraw._mouseDownFlag = true;
});
regionsGroup.on('click', function (e) {
if (!mapDraw._mouseDownFlag) {
return;
}
mapDraw._mouseDownFlag = false;
});
}
};
return MapDraw;
}();
;
function applyOptionStyleForRegion(viewBuildCtx, el, dataIndex, regionModel) {
// All of the path are using `itemStyle`, because
// (1) Some SVG also use fill on polyline (The different between
// polyline and polygon is "open" or "close" but not fill or not).
// (2) For the common props like opacity, if some use itemStyle
// and some use `lineStyle`, it might confuse users.
// (3) Most SVG use <path>, where can not detect whether to draw a "line"
// or a filled shape, so use `itemStyle` for <path>.
var normalStyleModel = regionModel.getModel('itemStyle');
var emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']);
var blurStyleModel = regionModel.getModel(['blur', 'itemStyle']);
var selectStyleModel = regionModel.getModel(['select', 'itemStyle']);
// NOTE: DON'T use 'style' in visual when drawing map.
// This component is used for drawing underlying map for both geo component and map series.
var normalStyle = getFixedItemStyle(normalStyleModel);
var emphasisStyle = getFixedItemStyle(emphasisStyleModel);
var selectStyle = getFixedItemStyle(selectStyleModel);
var blurStyle = getFixedItemStyle(blurStyleModel);
// Update the itemStyle if has data visual
var data = viewBuildCtx.data;
if (data) {
// Only visual color of each item will be used. It can be encoded by visualMap
// But visual color of series is used in symbol drawing
// Visual color for each series is for the symbol draw
var style = data.getItemVisual(dataIndex, 'style');
var decal = data.getItemVisual(dataIndex, 'decal');
if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) {
normalStyle.fill = style.fill;
}
if (decal) {
normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
}
}
// SVG text, tspan and image can be named but not supporeted
// to be styled by region option yet.
el.setStyle(normalStyle);
el.style.strokeNoScale = true;
el.ensureState('emphasis').style = emphasisStyle;
el.ensureState('select').style = selectStyle;
el.ensureState('blur').style = blurStyle;
// Enable blur
setDefaultStateProxy(el);
}
function resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel,
// Exist only if `viewBuildCtx.data` exists.
dataIdx,
// If labelXY not provided, use `textConfig.position: 'inside'`
labelXY) {
var data = viewBuildCtx.data;
var isGeo = viewBuildCtx.isGeo;
var isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx));
var itemLayout = data && data.getItemLayout(dataIdx);
// In the following cases label will be drawn
// 1. In map series and data value is NaN
// 2. In geo component
// 3. Region has no series legendIcon, which will be add a showLabel flag in mapSymbolLayout
if (isGeo || isDataNaN || itemLayout && itemLayout.showLabel) {
var query = !isGeo ? dataIdx : regionName;
var labelFetcher = void 0;
// Consider dataIdx not found.
if (!data || dataIdx >= 0) {
labelFetcher = mapOrGeoModel;
}
var specifiedTextOpt = labelXY ? {
normal: {
align: 'center',
verticalAlign: 'middle'
}
} : null;
// Caveat: must be called after `setDefaultStateProxy(el);` called.
// because textContent will be assign with `el.stateProxy` inside.
setLabelStyle(el, getLabelStatesModels(regionModel), {
labelFetcher: labelFetcher,
labelDataIndex: query,
defaultText: regionName
}, specifiedTextOpt);
var textEl = el.getTextContent();
if (textEl) {
mapLabelRaw(textEl).ignore = textEl.ignore;
if (el.textConfig && labelXY) {
// Compute a relative offset based on the el bounding rect.
var rect = el.getBoundingRect().clone();
// Need to make sure the percent position base on the same rect in normal and
// emphasis state. Otherwise if using boundingRect of el, but the emphasis state
// has borderWidth (even 0.5px), the text position will be changed obviously
// if the position is very big like ['1234%', '1345%'].
el.textConfig.layoutRect = rect;
el.textConfig.position = [(labelXY[0] - rect.x) / rect.width * 100 + '%', (labelXY[1] - rect.y) / rect.height * 100 + '%'];
}
}
// PENDING:
// If labelLayout is enabled (test/label-layout.html), el.dataIndex should be specified.
// But el.dataIndex is also used to determine whether user event should be triggered,
// where el.seriesIndex or el.dataModel must be specified. At present for a single el
// there is not case that "only label layout enabled but user event disabled", so here
// we depends `resetEventTriggerForRegion` to do the job of setting `el.dataIndex`.
el.disableLabelAnimation = true;
} else {
el.removeTextContent();
el.removeTextConfig();
el.disableLabelAnimation = null;
}
}
function resetEventTriggerForRegion(viewBuildCtx, eventTrigger, regionName, regionModel, mapOrGeoModel,
// Exist only if `viewBuildCtx.data` exists.
dataIdx) {
// setItemGraphicEl, setHoverStyle after all polygons and labels
// are added to the regionGroup
if (viewBuildCtx.data) {
// FIXME: when series-map use a SVG map, and there are duplicated name specified
// on different SVG elements, after `data.setItemGraphicEl(...)`:
// (1) all of them will be mounted with `dataIndex`, `seriesIndex`, so that tooltip
// can be triggered only mouse hover. That's correct.
// (2) only the last element will be kept in `data`, so that if trigger tooltip
// by `dispatchAction`, only the last one can be found and triggered. That might be
// not correct. We will fix it in future if anyone demanding that.
viewBuildCtx.data.setItemGraphicEl(dataIdx, eventTrigger);
}
// series-map will not trigger "geoselectchange" no matter it is
// based on a declared geo component. Because series-map will
// trigger "selectchange". If it trigger both the two events,
// If users call `chart.dispatchAction({type: 'toggleSelect'})`,
// it not easy to also fire event "geoselectchanged".
else {
// Package custom mouse event for geo component
getECData(eventTrigger).eventData = {
componentType: 'geo',
componentIndex: mapOrGeoModel.componentIndex,
geoIndex: mapOrGeoModel.componentIndex,
name: regionName,
region: regionModel && regionModel.option || {}
};
}
}
function resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) {
if (!viewBuildCtx.data) {
graphic.setTooltipConfig({
el: el,
componentModel: mapOrGeoModel,
itemName: regionName,
// @ts-ignore FIXME:TS fix the "compatible with each other"?
itemTooltipOption: regionModel.get('tooltip')
});
}
}
function resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) {
// @ts-ignore FIXME:TS fix the "compatible with each other"?
el.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
// @ts-ignore FIXME:TS fix the "compatible with each other"?
var emphasisModel = regionModel.getModel('emphasis');
var focus = emphasisModel.get('focus');
toggleHoverEmphasis(el, focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
if (viewBuildCtx.isGeo) {
enableComponentHighDownFeatures(el, mapOrGeoModel, regionName);
}
return focus;
}
function projectPolys(rings,
// Polygons include exterior and interiors. Or polylines.
createStream, isLine) {
var polygons = [];
var curPoly;
function startPolygon() {
curPoly = [];
}
function endPolygon() {
if (curPoly.length) {
polygons.push(curPoly);
curPoly = [];
}
}
var stream = createStream({
polygonStart: startPolygon,
polygonEnd: endPolygon,
lineStart: startPolygon,
lineEnd: endPolygon,
point: function (x, y) {
// May have NaN values from stream.
if (isFinite(x) && isFinite(y)) {
curPoly.push([x, y]);
}
},
sphere: function () {}
});
!isLine && stream.polygonStart();
zrUtil.each(rings, function (ring) {
stream.lineStart();
for (var i = 0; i < ring.length; i++) {
stream.point(ring[i][0], ring[i][1]);
}
stream.lineEnd();
});
!isLine && stream.polygonEnd();
return polygons;
}
export default MapDraw;
// @ts-ignore FIXME:TS fix the "compatible with each other"?

View File

@@ -0,0 +1,245 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import Eventful from 'zrender/lib/core/Eventful.js';
import * as eventTool from 'zrender/lib/core/event.js';
import * as interactionMutex from './interactionMutex.js';
import { isString, bind, defaults, clone } from 'zrender/lib/core/util.js';
;
var RoamController = /** @class */function (_super) {
__extends(RoamController, _super);
function RoamController(zr) {
var _this = _super.call(this) || this;
_this._zr = zr;
// Avoid two roamController bind the same handler
var mousedownHandler = bind(_this._mousedownHandler, _this);
var mousemoveHandler = bind(_this._mousemoveHandler, _this);
var mouseupHandler = bind(_this._mouseupHandler, _this);
var mousewheelHandler = bind(_this._mousewheelHandler, _this);
var pinchHandler = bind(_this._pinchHandler, _this);
/**
* Notice: only enable needed types. For example, if 'zoom'
* is not needed, 'zoom' should not be enabled, otherwise
* default mousewheel behaviour (scroll page) will be disabled.
*/
_this.enable = function (controlType, opt) {
// Disable previous first
this.disable();
this._opt = defaults(clone(opt) || {}, {
zoomOnMouseWheel: true,
moveOnMouseMove: true,
// By default, wheel do not trigger move.
moveOnMouseWheel: false,
preventDefaultMouseMove: true
});
if (controlType == null) {
controlType = true;
}
if (controlType === true || controlType === 'move' || controlType === 'pan') {
zr.on('mousedown', mousedownHandler);
zr.on('mousemove', mousemoveHandler);
zr.on('mouseup', mouseupHandler);
}
if (controlType === true || controlType === 'scale' || controlType === 'zoom') {
zr.on('mousewheel', mousewheelHandler);
zr.on('pinch', pinchHandler);
}
};
_this.disable = function () {
zr.off('mousedown', mousedownHandler);
zr.off('mousemove', mousemoveHandler);
zr.off('mouseup', mouseupHandler);
zr.off('mousewheel', mousewheelHandler);
zr.off('pinch', pinchHandler);
};
return _this;
}
RoamController.prototype.isDragging = function () {
return this._dragging;
};
RoamController.prototype.isPinching = function () {
return this._pinching;
};
RoamController.prototype.setPointerChecker = function (pointerChecker) {
this.pointerChecker = pointerChecker;
};
RoamController.prototype.dispose = function () {
this.disable();
};
RoamController.prototype._mousedownHandler = function (e) {
if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
return;
}
var el = e.target;
while (el) {
if (el.draggable) {
return;
}
// check if host is draggable
el = el.__hostTarget || el.parent;
}
var x = e.offsetX;
var y = e.offsetY;
// Only check on mosedown, but not mousemove.
// Mouse can be out of target when mouse moving.
if (this.pointerChecker && this.pointerChecker(e, x, y)) {
this._x = x;
this._y = y;
this._dragging = true;
}
};
RoamController.prototype._mousemoveHandler = function (e) {
if (!this._dragging || !isAvailableBehavior('moveOnMouseMove', e, this._opt) || e.gestureEvent === 'pinch' || interactionMutex.isTaken(this._zr, 'globalPan')) {
return;
}
var x = e.offsetX;
var y = e.offsetY;
var oldX = this._x;
var oldY = this._y;
var dx = x - oldX;
var dy = y - oldY;
this._x = x;
this._y = y;
this._opt.preventDefaultMouseMove && eventTool.stop(e.event);
trigger(this, 'pan', 'moveOnMouseMove', e, {
dx: dx,
dy: dy,
oldX: oldX,
oldY: oldY,
newX: x,
newY: y,
isAvailableBehavior: null
});
};
RoamController.prototype._mouseupHandler = function (e) {
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
this._dragging = false;
}
};
RoamController.prototype._mousewheelHandler = function (e) {
var shouldZoom = isAvailableBehavior('zoomOnMouseWheel', e, this._opt);
var shouldMove = isAvailableBehavior('moveOnMouseWheel', e, this._opt);
var wheelDelta = e.wheelDelta;
var absWheelDeltaDelta = Math.abs(wheelDelta);
var originX = e.offsetX;
var originY = e.offsetY;
// wheelDelta maybe -0 in chrome mac.
if (wheelDelta === 0 || !shouldZoom && !shouldMove) {
return;
}
// If both `shouldZoom` and `shouldMove` is true, trigger
// their event both, and the final behavior is determined
// by event listener themselves.
if (shouldZoom) {
// Convenience:
// Mac and VM Windows on Mac: scroll up: zoom out.
// Windows: scroll up: zoom in.
// FIXME: Should do more test in different environment.
// wheelDelta is too complicated in difference nvironment
// (https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel),
// although it has been normallized by zrender.
// wheelDelta of mouse wheel is bigger than touch pad.
var factor = absWheelDeltaDelta > 3 ? 1.4 : absWheelDeltaDelta > 1 ? 1.2 : 1.1;
var scale = wheelDelta > 0 ? factor : 1 / factor;
checkPointerAndTrigger(this, 'zoom', 'zoomOnMouseWheel', e, {
scale: scale,
originX: originX,
originY: originY,
isAvailableBehavior: null
});
}
if (shouldMove) {
// FIXME: Should do more test in different environment.
var absDelta = Math.abs(wheelDelta);
// wheelDelta of mouse wheel is bigger than touch pad.
var scrollDelta = (wheelDelta > 0 ? 1 : -1) * (absDelta > 3 ? 0.4 : absDelta > 1 ? 0.15 : 0.05);
checkPointerAndTrigger(this, 'scrollMove', 'moveOnMouseWheel', e, {
scrollDelta: scrollDelta,
originX: originX,
originY: originY,
isAvailableBehavior: null
});
}
};
RoamController.prototype._pinchHandler = function (e) {
if (interactionMutex.isTaken(this._zr, 'globalPan')) {
return;
}
var scale = e.pinchScale > 1 ? 1.1 : 1 / 1.1;
checkPointerAndTrigger(this, 'zoom', null, e, {
scale: scale,
originX: e.pinchX,
originY: e.pinchY,
isAvailableBehavior: null
});
};
return RoamController;
}(Eventful);
function checkPointerAndTrigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
if (controller.pointerChecker && controller.pointerChecker(e, contollerEvent.originX, contollerEvent.originY)) {
// When mouse is out of roamController rect,
// default befavoius should not be be disabled, otherwise
// page sliding is disabled, contrary to expectation.
eventTool.stop(e.event);
trigger(controller, eventName, behaviorToCheck, e, contollerEvent);
}
}
function trigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
// Also provide behavior checker for event listener, for some case that
// multiple components share one listener.
contollerEvent.isAvailableBehavior = bind(isAvailableBehavior, null, behaviorToCheck, e);
// TODO should not have type issue.
controller.trigger(eventName, contollerEvent);
}
// settings: {
// zoomOnMouseWheel
// moveOnMouseMove
// moveOnMouseWheel
// }
// The value can be: true / false / 'shift' / 'ctrl' / 'alt'.
function isAvailableBehavior(behaviorToCheck, e, settings) {
var setting = settings[behaviorToCheck];
return !behaviorToCheck || setting && (!isString(setting) || e.event[setting + 'Key']);
}
export default RoamController;

View File

@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import BoundingRect from 'zrender/lib/core/BoundingRect.js';
import { onIrrelevantElement } from './cursorHelper.js';
import * as graphicUtil from '../../util/graphic.js';
export function makeRectPanelClipPath(rect) {
rect = normalizeRect(rect);
return function (localPoints) {
return graphicUtil.clipPointsByRect(localPoints, rect);
};
}
export function makeLinearBrushOtherExtent(rect, specifiedXYIndex) {
rect = normalizeRect(rect);
return function (xyIndex) {
var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex;
var brushWidth = idx ? rect.width : rect.height;
var base = idx ? rect.x : rect.y;
return [base, base + (brushWidth || 0)];
};
}
export function makeRectIsTargetByCursor(rect, api, targetModel) {
var boundingRect = normalizeRect(rect);
return function (e, localCursorPoint) {
return boundingRect.contain(localCursorPoint[0], localCursorPoint[1]) && !onIrrelevantElement(e, api, targetModel);
};
}
// Consider width/height is negative.
function normalizeRect(rect) {
return BoundingRect.create(rect);
}

View File

@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var IRRELEVANT_EXCLUDES = {
'axisPointer': 1,
'tooltip': 1,
'brush': 1
};
/**
* Avoid that: mouse click on a elements that is over geo or graph,
* but roam is triggered.
*/
export function onIrrelevantElement(e, api, targetCoordSysModel) {
var model = api.getComponentByElement(e.topTarget);
// If model is axisModel, it works only if it is injected with coordinateSystem.
var coordSys = model && model.coordinateSystem;
return model && model !== targetCoordSysModel && !IRRELEVANT_EXCLUDES.hasOwnProperty(model.mainType) && coordSys && coordSys.model !== targetCoordSysModel;
}

View File

@@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// @ts-nocheck
import * as echarts from '../../core/echarts.js';
import { noop } from 'zrender/lib/core/util.js';
var ATTR = '\0_ec_interaction_mutex';
export function take(zr, resourceKey, userKey) {
var store = getStore(zr);
store[resourceKey] = userKey;
}
export function release(zr, resourceKey, userKey) {
var store = getStore(zr);
var uKey = store[resourceKey];
if (uKey === userKey) {
store[resourceKey] = null;
}
}
export function isTaken(zr, resourceKey) {
return !!getStore(zr)[resourceKey];
}
function getStore(zr) {
return zr[ATTR] || (zr[ATTR] = {});
}
/**
* payload: {
* type: 'takeGlobalCursor',
* key: 'dataZoomSelect', or 'brush', or ...,
* If no userKey, release global cursor.
* }
*/
// TODO: SELF REGISTERED.
echarts.registerAction({
type: 'takeGlobalCursor',
event: 'globalCursorTaken',
update: 'update'
}, noop);

View File

@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// @ts-nocheck
import { getLayoutRect, box as layoutBox, positionElement } from '../../util/layout.js';
import * as formatUtil from '../../util/format.js';
import * as graphic from '../../util/graphic.js';
/**
* Layout list like component.
* It will box layout each items in group of component and then position the whole group in the viewport
* @param {module:zrender/group/Group} group
* @param {module:echarts/model/Component} componentModel
* @param {module:echarts/ExtensionAPI}
*/
export function layout(group, componentModel, api) {
var boxLayoutParams = componentModel.getBoxLayoutParams();
var padding = componentModel.get('padding');
var viewportSize = {
width: api.getWidth(),
height: api.getHeight()
};
var rect = getLayoutRect(boxLayoutParams, viewportSize, padding);
layoutBox(componentModel.get('orient'), group, componentModel.get('itemGap'), rect.width, rect.height);
positionElement(group, boxLayoutParams, viewportSize, padding);
}
export function makeBackground(rect, componentModel) {
var padding = formatUtil.normalizeCssArray(componentModel.get('padding'));
var style = componentModel.getItemStyle(['color', 'opacity']);
style.fill = componentModel.get('backgroundColor');
rect = new graphic.Rect({
shape: {
x: rect.x - padding[3],
y: rect.y - padding[0],
width: rect.width + padding[1] + padding[3],
height: rect.height + padding[0] + padding[2],
r: componentModel.get('borderRadius')
},
style: style,
silent: true,
z2: -1
});
// FIXME
// `subPixelOptimizeRect` may bring some gap between edge of viewpart
// and background rect when setting like `left: 0`, `top: 0`.
// graphic.subPixelOptimizeRect(rect);
return rect;
}

View File

@@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* For geo and graph.
*/
export function updateViewOnPan(controllerHost, dx, dy) {
var target = controllerHost.target;
target.x += dx;
target.y += dy;
target.dirty();
}
/**
* For geo and graph.
*/
export function updateViewOnZoom(controllerHost, zoomDelta, zoomX, zoomY) {
var target = controllerHost.target;
var zoomLimit = controllerHost.zoomLimit;
var newZoom = controllerHost.zoom = controllerHost.zoom || 1;
newZoom *= zoomDelta;
if (zoomLimit) {
var zoomMin = zoomLimit.min || 0;
var zoomMax = zoomLimit.max || Infinity;
newZoom = Math.max(Math.min(zoomMax, newZoom), zoomMin);
}
var zoomScale = newZoom / controllerHost.zoom;
controllerHost.zoom = newZoom;
// Keep the mouse center when scaling
target.x -= (zoomX - target.x) * (zoomScale - 1);
target.y -= (zoomY - target.y) * (zoomScale - 1);
target.scaleX *= zoomScale;
target.scaleY *= zoomScale;
target.dirty();
}

View File

@@ -0,0 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Calculate slider move result.
* Usage:
* (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as
* maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`.
* (2) If handle0 is forbidden to cross handle1, set minSpan as `0`.
*
* @param delta Move length.
* @param handleEnds handleEnds[0] can be bigger then handleEnds[1].
* handleEnds will be modified in this method.
* @param extent handleEnds is restricted by extent.
* extent[0] should less or equals than extent[1].
* @param handleIndex Can be 'all', means that both move the two handleEnds.
* @param minSpan The range of dataZoom can not be smaller than that.
* If not set, handle0 and cross handle1. If set as a non-negative
* number (including `0`), handles will push each other when reaching
* the minSpan.
* @param maxSpan The range of dataZoom can not be larger than that.
* @return The input handleEnds.
*/
export default function sliderMove(delta, handleEnds, extent, handleIndex, minSpan, maxSpan) {
delta = delta || 0;
var extentSpan = extent[1] - extent[0];
// Notice maxSpan and minSpan can be null/undefined.
if (minSpan != null) {
minSpan = restrict(minSpan, [0, extentSpan]);
}
if (maxSpan != null) {
maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0);
}
if (handleIndex === 'all') {
var handleSpan = Math.abs(handleEnds[1] - handleEnds[0]);
handleSpan = restrict(handleSpan, [0, extentSpan]);
minSpan = maxSpan = restrict(handleSpan, [minSpan, maxSpan]);
handleIndex = 0;
}
handleEnds[0] = restrict(handleEnds[0], extent);
handleEnds[1] = restrict(handleEnds[1], extent);
var originalDistSign = getSpanSign(handleEnds, handleIndex);
handleEnds[handleIndex] += delta;
// Restrict in extent.
var extentMinSpan = minSpan || 0;
var realExtent = extent.slice();
originalDistSign.sign < 0 ? realExtent[0] += extentMinSpan : realExtent[1] -= extentMinSpan;
handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent);
// Expand span.
var currDistSign;
currDistSign = getSpanSign(handleEnds, handleIndex);
if (minSpan != null && (currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan)) {
// If minSpan exists, 'cross' is forbidden.
handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan;
}
// Shrink span.
currDistSign = getSpanSign(handleEnds, handleIndex);
if (maxSpan != null && currDistSign.span > maxSpan) {
handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan;
}
return handleEnds;
}
function getSpanSign(handleEnds, handleIndex) {
var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex];
// If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0]
// is at left of handleEnds[1] for non-cross case.
return {
span: Math.abs(dist),
sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1
};
}
function restrict(value, extend) {
return Math.min(extend[1] != null ? extend[1] : Infinity, Math.max(extend[0] != null ? extend[0] : -Infinity, value));
}

47
frontend/node_modules/echarts/lib/component/legend.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Do not contain scrollable legend, for sake of file size.
import { use } from '../extension.js';
import { install } from './legend/install.js';
use(install);

View File

@@ -0,0 +1,317 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import Model from '../../model/Model.js';
import { isNameSpecified } from '../../util/model.js';
import ComponentModel from '../../model/Component.js';
var getDefaultSelectorOptions = function (ecModel, type) {
if (type === 'all') {
return {
type: 'all',
title: ecModel.getLocaleModel().get(['legend', 'selector', 'all'])
};
} else if (type === 'inverse') {
return {
type: 'inverse',
title: ecModel.getLocaleModel().get(['legend', 'selector', 'inverse'])
};
}
};
var LegendModel = /** @class */function (_super) {
__extends(LegendModel, _super);
function LegendModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = LegendModel.type;
_this.layoutMode = {
type: 'box',
// legend.width/height are maxWidth/maxHeight actually,
// whereas real width/height is calculated by its content.
// (Setting {left: 10, right: 10} does not make sense).
// So consider the case:
// `setOption({legend: {left: 10});`
// then `setOption({legend: {right: 10});`
// The previous `left` should be cleared by setting `ignoreSize`.
ignoreSize: true
};
return _this;
}
LegendModel.prototype.init = function (option, parentModel, ecModel) {
this.mergeDefaultAndTheme(option, ecModel);
option.selected = option.selected || {};
this._updateSelector(option);
};
LegendModel.prototype.mergeOption = function (option, ecModel) {
_super.prototype.mergeOption.call(this, option, ecModel);
this._updateSelector(option);
};
LegendModel.prototype._updateSelector = function (option) {
var selector = option.selector;
var ecModel = this.ecModel;
if (selector === true) {
selector = option.selector = ['all', 'inverse'];
}
if (zrUtil.isArray(selector)) {
zrUtil.each(selector, function (item, index) {
zrUtil.isString(item) && (item = {
type: item
});
selector[index] = zrUtil.merge(item, getDefaultSelectorOptions(ecModel, item.type));
});
}
};
LegendModel.prototype.optionUpdated = function () {
this._updateData(this.ecModel);
var legendData = this._data;
// If selectedMode is single, try to select one
if (legendData[0] && this.get('selectedMode') === 'single') {
var hasSelected = false;
// If has any selected in option.selected
for (var i = 0; i < legendData.length; i++) {
var name_1 = legendData[i].get('name');
if (this.isSelected(name_1)) {
// Force to unselect others
this.select(name_1);
hasSelected = true;
break;
}
}
// Try select the first if selectedMode is single
!hasSelected && this.select(legendData[0].get('name'));
}
};
LegendModel.prototype._updateData = function (ecModel) {
var potentialData = [];
var availableNames = [];
ecModel.eachRawSeries(function (seriesModel) {
var seriesName = seriesModel.name;
availableNames.push(seriesName);
var isPotential;
if (seriesModel.legendVisualProvider) {
var provider = seriesModel.legendVisualProvider;
var names = provider.getAllNames();
if (!ecModel.isSeriesFiltered(seriesModel)) {
availableNames = availableNames.concat(names);
}
if (names.length) {
potentialData = potentialData.concat(names);
} else {
isPotential = true;
}
} else {
isPotential = true;
}
if (isPotential && isNameSpecified(seriesModel)) {
potentialData.push(seriesModel.name);
}
});
/**
* @type {Array.<string>}
* @private
*/
this._availableNames = availableNames;
// If legend.data is not specified in option, use availableNames as data,
// which is convenient for user preparing option.
var rawData = this.get('data') || potentialData;
var legendNameMap = zrUtil.createHashMap();
var legendData = zrUtil.map(rawData, function (dataItem) {
// Can be string or number
if (zrUtil.isString(dataItem) || zrUtil.isNumber(dataItem)) {
dataItem = {
name: dataItem
};
}
if (legendNameMap.get(dataItem.name)) {
// remove legend name duplicate
return null;
}
legendNameMap.set(dataItem.name, true);
return new Model(dataItem, this, this.ecModel);
}, this);
/**
* @type {Array.<module:echarts/model/Model>}
* @private
*/
this._data = zrUtil.filter(legendData, function (item) {
return !!item;
});
};
LegendModel.prototype.getData = function () {
return this._data;
};
LegendModel.prototype.select = function (name) {
var selected = this.option.selected;
var selectedMode = this.get('selectedMode');
if (selectedMode === 'single') {
var data = this._data;
zrUtil.each(data, function (dataItem) {
selected[dataItem.get('name')] = false;
});
}
selected[name] = true;
};
LegendModel.prototype.unSelect = function (name) {
if (this.get('selectedMode') !== 'single') {
this.option.selected[name] = false;
}
};
LegendModel.prototype.toggleSelected = function (name) {
var selected = this.option.selected;
// Default is true
if (!selected.hasOwnProperty(name)) {
selected[name] = true;
}
this[selected[name] ? 'unSelect' : 'select'](name);
};
LegendModel.prototype.allSelect = function () {
var data = this._data;
var selected = this.option.selected;
zrUtil.each(data, function (dataItem) {
selected[dataItem.get('name', true)] = true;
});
};
LegendModel.prototype.inverseSelect = function () {
var data = this._data;
var selected = this.option.selected;
zrUtil.each(data, function (dataItem) {
var name = dataItem.get('name', true);
// Initially, default value is true
if (!selected.hasOwnProperty(name)) {
selected[name] = true;
}
selected[name] = !selected[name];
});
};
LegendModel.prototype.isSelected = function (name) {
var selected = this.option.selected;
return !(selected.hasOwnProperty(name) && !selected[name]) && zrUtil.indexOf(this._availableNames, name) >= 0;
};
LegendModel.prototype.getOrient = function () {
return this.get('orient') === 'vertical' ? {
index: 1,
name: 'vertical'
} : {
index: 0,
name: 'horizontal'
};
};
LegendModel.type = 'legend.plain';
LegendModel.dependencies = ['series'];
LegendModel.defaultOption = {
// zlevel: 0,
z: 4,
show: true,
orient: 'horizontal',
left: 'center',
// right: 'center',
top: 0,
// bottom: null,
align: 'auto',
backgroundColor: 'rgba(0,0,0,0)',
borderColor: '#ccc',
borderRadius: 0,
borderWidth: 0,
padding: 5,
itemGap: 10,
itemWidth: 25,
itemHeight: 14,
symbolRotate: 'inherit',
symbolKeepAspect: true,
inactiveColor: '#ccc',
inactiveBorderColor: '#ccc',
inactiveBorderWidth: 'auto',
itemStyle: {
color: 'inherit',
opacity: 'inherit',
borderColor: 'inherit',
borderWidth: 'auto',
borderCap: 'inherit',
borderJoin: 'inherit',
borderDashOffset: 'inherit',
borderMiterLimit: 'inherit'
},
lineStyle: {
width: 'auto',
color: 'inherit',
inactiveColor: '#ccc',
inactiveWidth: 2,
opacity: 'inherit',
type: 'inherit',
cap: 'inherit',
join: 'inherit',
dashOffset: 'inherit',
miterLimit: 'inherit'
},
textStyle: {
color: '#333'
},
selectedMode: true,
selector: false,
selectorLabel: {
show: true,
borderRadius: 10,
padding: [3, 5, 3, 5],
fontSize: 12,
fontFamily: 'sans-serif',
color: '#666',
borderWidth: 1,
borderColor: '#666'
},
emphasis: {
selectorLabel: {
show: true,
color: '#eee',
backgroundColor: '#666'
}
},
selectorPosition: 'auto',
selectorItemGap: 7,
selectorButtonGap: 10,
tooltip: {
show: false
}
};
return LegendModel;
}(ComponentModel);
export default LegendModel;

View File

@@ -0,0 +1,525 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import { parse, stringify } from 'zrender/lib/tool/color.js';
import * as graphic from '../../util/graphic.js';
import { enableHoverEmphasis } from '../../util/states.js';
import { setLabelStyle, createTextStyle } from '../../label/labelStyle.js';
import { makeBackground } from '../helper/listComponent.js';
import * as layoutUtil from '../../util/layout.js';
import ComponentView from '../../view/Component.js';
import { createSymbol } from '../../util/symbol.js';
import { createOrUpdatePatternFromDecal } from '../../util/decal.js';
import { getECData } from '../../util/innerStore.js';
var curry = zrUtil.curry;
var each = zrUtil.each;
var Group = graphic.Group;
var LegendView = /** @class */function (_super) {
__extends(LegendView, _super);
function LegendView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = LegendView.type;
_this.newlineDisabled = false;
return _this;
}
LegendView.prototype.init = function () {
this.group.add(this._contentGroup = new Group());
this.group.add(this._selectorGroup = new Group());
this._isFirstRender = true;
};
/**
* @protected
*/
LegendView.prototype.getContentGroup = function () {
return this._contentGroup;
};
/**
* @protected
*/
LegendView.prototype.getSelectorGroup = function () {
return this._selectorGroup;
};
/**
* @override
*/
LegendView.prototype.render = function (legendModel, ecModel, api) {
var isFirstRender = this._isFirstRender;
this._isFirstRender = false;
this.resetInner();
if (!legendModel.get('show', true)) {
return;
}
var itemAlign = legendModel.get('align');
var orient = legendModel.get('orient');
if (!itemAlign || itemAlign === 'auto') {
itemAlign = legendModel.get('left') === 'right' && orient === 'vertical' ? 'right' : 'left';
}
// selector has been normalized to an array in model
var selector = legendModel.get('selector', true);
var selectorPosition = legendModel.get('selectorPosition', true);
if (selector && (!selectorPosition || selectorPosition === 'auto')) {
selectorPosition = orient === 'horizontal' ? 'end' : 'start';
}
this.renderInner(itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition);
// Perform layout.
var positionInfo = legendModel.getBoxLayoutParams();
var viewportSize = {
width: api.getWidth(),
height: api.getHeight()
};
var padding = legendModel.get('padding');
var maxSize = layoutUtil.getLayoutRect(positionInfo, viewportSize, padding);
var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition);
// Place mainGroup, based on the calculated `mainRect`.
var layoutRect = layoutUtil.getLayoutRect(zrUtil.defaults({
width: mainRect.width,
height: mainRect.height
}, positionInfo), viewportSize, padding);
this.group.x = layoutRect.x - mainRect.x;
this.group.y = layoutRect.y - mainRect.y;
this.group.markRedraw();
// Render background after group is layout.
this.group.add(this._backgroundEl = makeBackground(mainRect, legendModel));
};
LegendView.prototype.resetInner = function () {
this.getContentGroup().removeAll();
this._backgroundEl && this.group.remove(this._backgroundEl);
this.getSelectorGroup().removeAll();
};
LegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
var contentGroup = this.getContentGroup();
var legendDrawnMap = zrUtil.createHashMap();
var selectMode = legendModel.get('selectedMode');
var excludeSeriesId = [];
ecModel.eachRawSeries(function (seriesModel) {
!seriesModel.get('legendHoverLink') && excludeSeriesId.push(seriesModel.id);
});
each(legendModel.getData(), function (legendItemModel, dataIndex) {
var name = legendItemModel.get('name');
// Use empty string or \n as a newline string
if (!this.newlineDisabled && (name === '' || name === '\n')) {
var g = new Group();
// @ts-ignore
g.newline = true;
contentGroup.add(g);
return;
}
// Representitive series.
var seriesModel = ecModel.getSeriesByName(name)[0];
if (legendDrawnMap.get(name)) {
// Have been drawn
return;
}
// Legend to control series.
if (seriesModel) {
var data = seriesModel.getData();
var lineVisualStyle = data.getVisual('legendLineStyle') || {};
var legendIcon = data.getVisual('legendIcon');
/**
* `data.getVisual('style')` may be the color from the register
* in series. For example, for line series,
*/
var style = data.getVisual('style');
var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, style, legendIcon, selectMode, api);
itemGroup.on('click', curry(dispatchSelectAction, name, null, api, excludeSeriesId)).on('mouseover', curry(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId)).on('mouseout', curry(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId));
if (ecModel.ssr) {
itemGroup.eachChild(function (child) {
var ecData = getECData(child);
ecData.seriesIndex = seriesModel.seriesIndex;
ecData.dataIndex = dataIndex;
ecData.ssrType = 'legend';
});
}
legendDrawnMap.set(name, true);
} else {
// Legend to control data. In pie and funnel.
ecModel.eachRawSeries(function (seriesModel) {
// In case multiple series has same data name
if (legendDrawnMap.get(name)) {
return;
}
if (seriesModel.legendVisualProvider) {
var provider = seriesModel.legendVisualProvider;
if (!provider.containName(name)) {
return;
}
var idx = provider.indexOfName(name);
var style = provider.getItemVisual(idx, 'style');
var legendIcon = provider.getItemVisual(idx, 'legendIcon');
var colorArr = parse(style.fill);
// Color may be set to transparent in visualMap when data is out of range.
// Do not show nothing.
if (colorArr && colorArr[3] === 0) {
colorArr[3] = 0.2;
// TODO color is set to 0, 0, 0, 0. Should show correct RGBA
style = zrUtil.extend(zrUtil.extend({}, style), {
fill: stringify(colorArr, 'rgba')
});
}
var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, {}, style, legendIcon, selectMode, api);
// FIXME: consider different series has items with the same name.
itemGroup.on('click', curry(dispatchSelectAction, null, name, api, excludeSeriesId))
// Should not specify the series name, consider legend controls
// more than one pie series.
.on('mouseover', curry(dispatchHighlightAction, null, name, api, excludeSeriesId)).on('mouseout', curry(dispatchDownplayAction, null, name, api, excludeSeriesId));
if (ecModel.ssr) {
itemGroup.eachChild(function (child) {
var ecData = getECData(child);
ecData.seriesIndex = seriesModel.seriesIndex;
ecData.dataIndex = dataIndex;
ecData.ssrType = 'legend';
});
}
legendDrawnMap.set(name, true);
}
}, this);
}
if (process.env.NODE_ENV !== 'production') {
if (!legendDrawnMap.get(name)) {
console.warn(name + ' series not exists. Legend data should be same with series name or data name.');
}
}
}, this);
if (selector) {
this._createSelector(selector, legendModel, api, orient, selectorPosition);
}
};
LegendView.prototype._createSelector = function (selector, legendModel, api, orient, selectorPosition) {
var selectorGroup = this.getSelectorGroup();
each(selector, function createSelectorButton(selectorItem) {
var type = selectorItem.type;
var labelText = new graphic.Text({
style: {
x: 0,
y: 0,
align: 'center',
verticalAlign: 'middle'
},
onclick: function () {
api.dispatchAction({
type: type === 'all' ? 'legendAllSelect' : 'legendInverseSelect',
legendId: legendModel.id
});
}
});
selectorGroup.add(labelText);
var labelModel = legendModel.getModel('selectorLabel');
var emphasisLabelModel = legendModel.getModel(['emphasis', 'selectorLabel']);
setLabelStyle(labelText, {
normal: labelModel,
emphasis: emphasisLabelModel
}, {
defaultText: selectorItem.title
});
enableHoverEmphasis(labelText);
});
};
LegendView.prototype._createItem = function (seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, itemVisualStyle, legendIcon, selectMode, api) {
var drawType = seriesModel.visualDrawType;
var itemWidth = legendModel.get('itemWidth');
var itemHeight = legendModel.get('itemHeight');
var isSelected = legendModel.isSelected(name);
var iconRotate = legendItemModel.get('symbolRotate');
var symbolKeepAspect = legendItemModel.get('symbolKeepAspect');
var legendIconType = legendItemModel.get('icon');
legendIcon = legendIconType || legendIcon || 'roundRect';
var style = getLegendStyle(legendIcon, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api);
var itemGroup = new Group();
var textStyleModel = legendItemModel.getModel('textStyle');
if (zrUtil.isFunction(seriesModel.getLegendIcon) && (!legendIconType || legendIconType === 'inherit')) {
// Series has specific way to define legend icon
itemGroup.add(seriesModel.getLegendIcon({
itemWidth: itemWidth,
itemHeight: itemHeight,
icon: legendIcon,
iconRotate: iconRotate,
itemStyle: style.itemStyle,
lineStyle: style.lineStyle,
symbolKeepAspect: symbolKeepAspect
}));
} else {
// Use default legend icon policy for most series
var rotate = legendIconType === 'inherit' && seriesModel.getData().getVisual('symbol') ? iconRotate === 'inherit' ? seriesModel.getData().getVisual('symbolRotate') : iconRotate : 0; // No rotation for no icon
itemGroup.add(getDefaultLegendIcon({
itemWidth: itemWidth,
itemHeight: itemHeight,
icon: legendIcon,
iconRotate: rotate,
itemStyle: style.itemStyle,
lineStyle: style.lineStyle,
symbolKeepAspect: symbolKeepAspect
}));
}
var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
var textAlign = itemAlign;
var formatter = legendModel.get('formatter');
var content = name;
if (zrUtil.isString(formatter) && formatter) {
content = formatter.replace('{name}', name != null ? name : '');
} else if (zrUtil.isFunction(formatter)) {
content = formatter(name);
}
var textColor = isSelected ? textStyleModel.getTextColor() : legendItemModel.get('inactiveColor');
itemGroup.add(new graphic.Text({
style: createTextStyle(textStyleModel, {
text: content,
x: textX,
y: itemHeight / 2,
fill: textColor,
align: textAlign,
verticalAlign: 'middle'
}, {
inheritColor: textColor
})
}));
// Add a invisible rect to increase the area of mouse hover
var hitRect = new graphic.Rect({
shape: itemGroup.getBoundingRect(),
style: {
// Cannot use 'invisible' because SVG SSR will miss the node
fill: 'transparent'
}
});
var tooltipModel = legendItemModel.getModel('tooltip');
if (tooltipModel.get('show')) {
graphic.setTooltipConfig({
el: hitRect,
componentModel: legendModel,
itemName: name,
itemTooltipOption: tooltipModel.option
});
}
itemGroup.add(hitRect);
itemGroup.eachChild(function (child) {
child.silent = true;
});
hitRect.silent = !selectMode;
this.getContentGroup().add(itemGroup);
enableHoverEmphasis(itemGroup);
// @ts-ignore
itemGroup.__legendDataIndex = dataIndex;
return itemGroup;
};
LegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
var contentGroup = this.getContentGroup();
var selectorGroup = this.getSelectorGroup();
// Place items in contentGroup.
layoutUtil.box(legendModel.get('orient'), contentGroup, legendModel.get('itemGap'), maxSize.width, maxSize.height);
var contentRect = contentGroup.getBoundingRect();
var contentPos = [-contentRect.x, -contentRect.y];
selectorGroup.markRedraw();
contentGroup.markRedraw();
if (selector) {
// Place buttons in selectorGroup
layoutUtil.box(
// Buttons in selectorGroup always layout horizontally
'horizontal', selectorGroup, legendModel.get('selectorItemGap', true));
var selectorRect = selectorGroup.getBoundingRect();
var selectorPos = [-selectorRect.x, -selectorRect.y];
var selectorButtonGap = legendModel.get('selectorButtonGap', true);
var orientIdx = legendModel.getOrient().index;
var wh = orientIdx === 0 ? 'width' : 'height';
var hw = orientIdx === 0 ? 'height' : 'width';
var yx = orientIdx === 0 ? 'y' : 'x';
if (selectorPosition === 'end') {
selectorPos[orientIdx] += contentRect[wh] + selectorButtonGap;
} else {
contentPos[orientIdx] += selectorRect[wh] + selectorButtonGap;
}
// Always align selector to content as 'middle'
selectorPos[1 - orientIdx] += contentRect[hw] / 2 - selectorRect[hw] / 2;
selectorGroup.x = selectorPos[0];
selectorGroup.y = selectorPos[1];
contentGroup.x = contentPos[0];
contentGroup.y = contentPos[1];
var mainRect = {
x: 0,
y: 0
};
mainRect[wh] = contentRect[wh] + selectorButtonGap + selectorRect[wh];
mainRect[hw] = Math.max(contentRect[hw], selectorRect[hw]);
mainRect[yx] = Math.min(0, selectorRect[yx] + selectorPos[1 - orientIdx]);
return mainRect;
} else {
contentGroup.x = contentPos[0];
contentGroup.y = contentPos[1];
return this.group.getBoundingRect();
}
};
/**
* @protected
*/
LegendView.prototype.remove = function () {
this.getContentGroup().removeAll();
this._isFirstRender = true;
};
LegendView.type = 'legend.plain';
return LegendView;
}(ComponentView);
function getLegendStyle(iconType, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api) {
/**
* Use series style if is inherit;
* elsewise, use legend style
*/
function handleCommonProps(style, visualStyle) {
// If lineStyle.width is 'auto', it is set to be 2 if series has border
if (style.lineWidth === 'auto') {
style.lineWidth = visualStyle.lineWidth > 0 ? 2 : 0;
}
each(style, function (propVal, propName) {
style[propName] === 'inherit' && (style[propName] = visualStyle[propName]);
});
}
// itemStyle
var itemStyleModel = legendItemModel.getModel('itemStyle');
var itemStyle = itemStyleModel.getItemStyle();
var iconBrushType = iconType.lastIndexOf('empty', 0) === 0 ? 'fill' : 'stroke';
var decalStyle = itemStyleModel.getShallow('decal');
itemStyle.decal = !decalStyle || decalStyle === 'inherit' ? itemVisualStyle.decal : createOrUpdatePatternFromDecal(decalStyle, api);
if (itemStyle.fill === 'inherit') {
/**
* Series with visualDrawType as 'stroke' should have
* series stroke as legend fill
*/
itemStyle.fill = itemVisualStyle[drawType];
}
if (itemStyle.stroke === 'inherit') {
/**
* icon type with "emptyXXX" should use fill color
* in visual style
*/
itemStyle.stroke = itemVisualStyle[iconBrushType];
}
if (itemStyle.opacity === 'inherit') {
/**
* Use lineStyle.opacity if drawType is stroke
*/
itemStyle.opacity = (drawType === 'fill' ? itemVisualStyle : lineVisualStyle).opacity;
}
handleCommonProps(itemStyle, itemVisualStyle);
// lineStyle
var legendLineModel = legendItemModel.getModel('lineStyle');
var lineStyle = legendLineModel.getLineStyle();
handleCommonProps(lineStyle, lineVisualStyle);
// Fix auto color to real color
itemStyle.fill === 'auto' && (itemStyle.fill = itemVisualStyle.fill);
itemStyle.stroke === 'auto' && (itemStyle.stroke = itemVisualStyle.fill);
lineStyle.stroke === 'auto' && (lineStyle.stroke = itemVisualStyle.fill);
if (!isSelected) {
var borderWidth = legendItemModel.get('inactiveBorderWidth');
/**
* Since stroke is set to be inactiveBorderColor, it may occur that
* there is no border in series but border in legend, so we need to
* use border only when series has border if is set to be auto
*/
var visualHasBorder = itemStyle[iconBrushType];
itemStyle.lineWidth = borderWidth === 'auto' ? itemVisualStyle.lineWidth > 0 && visualHasBorder ? 2 : 0 : itemStyle.lineWidth;
itemStyle.fill = legendItemModel.get('inactiveColor');
itemStyle.stroke = legendItemModel.get('inactiveBorderColor');
lineStyle.stroke = legendLineModel.get('inactiveColor');
lineStyle.lineWidth = legendLineModel.get('inactiveWidth');
}
return {
itemStyle: itemStyle,
lineStyle: lineStyle
};
}
function getDefaultLegendIcon(opt) {
var symboType = opt.icon || 'roundRect';
var icon = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
icon.setStyle(opt.itemStyle);
icon.rotation = (opt.iconRotate || 0) * Math.PI / 180;
icon.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);
if (symboType.indexOf('empty') > -1) {
icon.style.stroke = icon.style.fill;
icon.style.fill = '#fff';
icon.style.lineWidth = 2;
}
return icon;
}
function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) {
// downplay before unselect
dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId);
api.dispatchAction({
type: 'legendToggleSelect',
name: seriesName != null ? seriesName : dataName
});
// highlight after select
// TODO highlight immediately may cause animation loss.
dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId);
}
function isUseHoverLayer(api) {
var list = api.getZr().storage.getDisplayList();
var emphasisState;
var i = 0;
var len = list.length;
while (i < len && !(emphasisState = list[i].states.emphasis)) {
i++;
}
return emphasisState && emphasisState.hoverLayer;
}
function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) {
// If element hover will move to a hoverLayer.
if (!isUseHoverLayer(api)) {
api.dispatchAction({
type: 'highlight',
seriesName: seriesName,
name: dataName,
excludeSeriesId: excludeSeriesId
});
}
}
function dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId) {
// If element hover will move to a hoverLayer.
if (!isUseHoverLayer(api)) {
api.dispatchAction({
type: 'downplay',
seriesName: seriesName,
name: dataName,
excludeSeriesId: excludeSeriesId
});
}
}
export default LegendView;

View File

@@ -0,0 +1,105 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import LegendModel from './LegendModel.js';
import { mergeLayoutParam, getLayoutParams } from '../../util/layout.js';
import { inheritDefaultOption } from '../../util/component.js';
var ScrollableLegendModel = /** @class */function (_super) {
__extends(ScrollableLegendModel, _super);
function ScrollableLegendModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = ScrollableLegendModel.type;
return _this;
}
/**
* @param {number} scrollDataIndex
*/
ScrollableLegendModel.prototype.setScrollDataIndex = function (scrollDataIndex) {
this.option.scrollDataIndex = scrollDataIndex;
};
ScrollableLegendModel.prototype.init = function (option, parentModel, ecModel) {
var inputPositionParams = getLayoutParams(option);
_super.prototype.init.call(this, option, parentModel, ecModel);
mergeAndNormalizeLayoutParams(this, option, inputPositionParams);
};
/**
* @override
*/
ScrollableLegendModel.prototype.mergeOption = function (option, ecModel) {
_super.prototype.mergeOption.call(this, option, ecModel);
mergeAndNormalizeLayoutParams(this, this.option, option);
};
ScrollableLegendModel.type = 'legend.scroll';
ScrollableLegendModel.defaultOption = inheritDefaultOption(LegendModel.defaultOption, {
scrollDataIndex: 0,
pageButtonItemGap: 5,
pageButtonGap: null,
pageButtonPosition: 'end',
pageFormatter: '{current}/{total}',
pageIcons: {
horizontal: ['M0,0L12,-10L12,10z', 'M0,0L-12,-10L-12,10z'],
vertical: ['M0,0L20,0L10,-20z', 'M0,0L20,0L10,20z']
},
pageIconColor: '#2f4554',
pageIconInactiveColor: '#aaa',
pageIconSize: 15,
pageTextStyle: {
color: '#333'
},
animationDurationUpdate: 800
});
return ScrollableLegendModel;
}(LegendModel);
;
// Do not `ignoreSize` to enable setting {left: 10, right: 10}.
function mergeAndNormalizeLayoutParams(legendModel, target, raw) {
var orient = legendModel.getOrient();
var ignoreSize = [1, 1];
ignoreSize[orient.index] = 0;
mergeLayoutParam(target, raw, {
type: 'box',
ignoreSize: !!ignoreSize
});
}
export default ScrollableLegendModel;

View File

@@ -0,0 +1,401 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
/**
* Separate legend and scrollable legend to reduce package size.
*/
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import * as layoutUtil from '../../util/layout.js';
import LegendView from './LegendView.js';
var Group = graphic.Group;
var WH = ['width', 'height'];
var XY = ['x', 'y'];
var ScrollableLegendView = /** @class */function (_super) {
__extends(ScrollableLegendView, _super);
function ScrollableLegendView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = ScrollableLegendView.type;
_this.newlineDisabled = true;
_this._currentIndex = 0;
return _this;
}
ScrollableLegendView.prototype.init = function () {
_super.prototype.init.call(this);
this.group.add(this._containerGroup = new Group());
this._containerGroup.add(this.getContentGroup());
this.group.add(this._controllerGroup = new Group());
};
/**
* @override
*/
ScrollableLegendView.prototype.resetInner = function () {
_super.prototype.resetInner.call(this);
this._controllerGroup.removeAll();
this._containerGroup.removeClipPath();
this._containerGroup.__rectSize = null;
};
/**
* @override
*/
ScrollableLegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
var self = this;
// Render content items.
_super.prototype.renderInner.call(this, itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition);
var controllerGroup = this._controllerGroup;
// FIXME: support be 'auto' adapt to size number text length,
// e.g., '3/12345' should not overlap with the control arrow button.
var pageIconSize = legendModel.get('pageIconSize', true);
var pageIconSizeArr = zrUtil.isArray(pageIconSize) ? pageIconSize : [pageIconSize, pageIconSize];
createPageButton('pagePrev', 0);
var pageTextStyleModel = legendModel.getModel('pageTextStyle');
controllerGroup.add(new graphic.Text({
name: 'pageText',
style: {
// Placeholder to calculate a proper layout.
text: 'xx/xx',
fill: pageTextStyleModel.getTextColor(),
font: pageTextStyleModel.getFont(),
verticalAlign: 'middle',
align: 'center'
},
silent: true
}));
createPageButton('pageNext', 1);
function createPageButton(name, iconIdx) {
var pageDataIndexName = name + 'DataIndex';
var icon = graphic.createIcon(legendModel.get('pageIcons', true)[legendModel.getOrient().name][iconIdx], {
// Buttons will be created in each render, so we do not need
// to worry about avoiding using legendModel kept in scope.
onclick: zrUtil.bind(self._pageGo, self, pageDataIndexName, legendModel, api)
}, {
x: -pageIconSizeArr[0] / 2,
y: -pageIconSizeArr[1] / 2,
width: pageIconSizeArr[0],
height: pageIconSizeArr[1]
});
icon.name = name;
controllerGroup.add(icon);
}
};
/**
* @override
*/
ScrollableLegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
var selectorGroup = this.getSelectorGroup();
var orientIdx = legendModel.getOrient().index;
var wh = WH[orientIdx];
var xy = XY[orientIdx];
var hw = WH[1 - orientIdx];
var yx = XY[1 - orientIdx];
selector && layoutUtil.box(
// Buttons in selectorGroup always layout horizontally
'horizontal', selectorGroup, legendModel.get('selectorItemGap', true));
var selectorButtonGap = legendModel.get('selectorButtonGap', true);
var selectorRect = selectorGroup.getBoundingRect();
var selectorPos = [-selectorRect.x, -selectorRect.y];
var processMaxSize = zrUtil.clone(maxSize);
selector && (processMaxSize[wh] = maxSize[wh] - selectorRect[wh] - selectorButtonGap);
var mainRect = this._layoutContentAndController(legendModel, isFirstRender, processMaxSize, orientIdx, wh, hw, yx, xy);
if (selector) {
if (selectorPosition === 'end') {
selectorPos[orientIdx] += mainRect[wh] + selectorButtonGap;
} else {
var offset = selectorRect[wh] + selectorButtonGap;
selectorPos[orientIdx] -= offset;
mainRect[xy] -= offset;
}
mainRect[wh] += selectorRect[wh] + selectorButtonGap;
selectorPos[1 - orientIdx] += mainRect[yx] + mainRect[hw] / 2 - selectorRect[hw] / 2;
mainRect[hw] = Math.max(mainRect[hw], selectorRect[hw]);
mainRect[yx] = Math.min(mainRect[yx], selectorRect[yx] + selectorPos[1 - orientIdx]);
selectorGroup.x = selectorPos[0];
selectorGroup.y = selectorPos[1];
selectorGroup.markRedraw();
}
return mainRect;
};
ScrollableLegendView.prototype._layoutContentAndController = function (legendModel, isFirstRender, maxSize, orientIdx, wh, hw, yx, xy) {
var contentGroup = this.getContentGroup();
var containerGroup = this._containerGroup;
var controllerGroup = this._controllerGroup;
// Place items in contentGroup.
layoutUtil.box(legendModel.get('orient'), contentGroup, legendModel.get('itemGap'), !orientIdx ? null : maxSize.width, orientIdx ? null : maxSize.height);
layoutUtil.box(
// Buttons in controller are layout always horizontally.
'horizontal', controllerGroup, legendModel.get('pageButtonItemGap', true));
var contentRect = contentGroup.getBoundingRect();
var controllerRect = controllerGroup.getBoundingRect();
var showController = this._showController = contentRect[wh] > maxSize[wh];
// In case that the inner elements of contentGroup layout do not based on [0, 0]
var contentPos = [-contentRect.x, -contentRect.y];
// Remain contentPos when scroll animation perfroming.
// If first rendering, `contentGroup.position` is [0, 0], which
// does not make sense and may cause unexepcted animation if adopted.
if (!isFirstRender) {
contentPos[orientIdx] = contentGroup[xy];
}
// Layout container group based on 0.
var containerPos = [0, 0];
var controllerPos = [-controllerRect.x, -controllerRect.y];
var pageButtonGap = zrUtil.retrieve2(legendModel.get('pageButtonGap', true), legendModel.get('itemGap', true));
// Place containerGroup and controllerGroup and contentGroup.
if (showController) {
var pageButtonPosition = legendModel.get('pageButtonPosition', true);
// controller is on the right / bottom.
if (pageButtonPosition === 'end') {
controllerPos[orientIdx] += maxSize[wh] - controllerRect[wh];
}
// controller is on the left / top.
else {
containerPos[orientIdx] += controllerRect[wh] + pageButtonGap;
}
}
// Always align controller to content as 'middle'.
controllerPos[1 - orientIdx] += contentRect[hw] / 2 - controllerRect[hw] / 2;
contentGroup.setPosition(contentPos);
containerGroup.setPosition(containerPos);
controllerGroup.setPosition(controllerPos);
// Calculate `mainRect` and set `clipPath`.
// mainRect should not be calculated by `this.group.getBoundingRect()`
// for sake of the overflow.
var mainRect = {
x: 0,
y: 0
};
// Consider content may be overflow (should be clipped).
mainRect[wh] = showController ? maxSize[wh] : contentRect[wh];
mainRect[hw] = Math.max(contentRect[hw], controllerRect[hw]);
// `containerRect[yx] + containerPos[1 - orientIdx]` is 0.
mainRect[yx] = Math.min(0, controllerRect[yx] + controllerPos[1 - orientIdx]);
containerGroup.__rectSize = maxSize[wh];
if (showController) {
var clipShape = {
x: 0,
y: 0
};
clipShape[wh] = Math.max(maxSize[wh] - controllerRect[wh] - pageButtonGap, 0);
clipShape[hw] = mainRect[hw];
containerGroup.setClipPath(new graphic.Rect({
shape: clipShape
}));
// Consider content may be larger than container, container rect
// can not be obtained from `containerGroup.getBoundingRect()`.
containerGroup.__rectSize = clipShape[wh];
} else {
// Do not remove or ignore controller. Keep them set as placeholders.
controllerGroup.eachChild(function (child) {
child.attr({
invisible: true,
silent: true
});
});
}
// Content translate animation.
var pageInfo = this._getPageInfo(legendModel);
pageInfo.pageIndex != null && graphic.updateProps(contentGroup, {
x: pageInfo.contentPosition[0],
y: pageInfo.contentPosition[1]
},
// When switch from "show controller" to "not show controller", view should be
// updated immediately without animation, otherwise causes weird effect.
showController ? legendModel : null);
this._updatePageInfoView(legendModel, pageInfo);
return mainRect;
};
ScrollableLegendView.prototype._pageGo = function (to, legendModel, api) {
var scrollDataIndex = this._getPageInfo(legendModel)[to];
scrollDataIndex != null && api.dispatchAction({
type: 'legendScroll',
scrollDataIndex: scrollDataIndex,
legendId: legendModel.id
});
};
ScrollableLegendView.prototype._updatePageInfoView = function (legendModel, pageInfo) {
var controllerGroup = this._controllerGroup;
zrUtil.each(['pagePrev', 'pageNext'], function (name) {
var key = name + 'DataIndex';
var canJump = pageInfo[key] != null;
var icon = controllerGroup.childOfName(name);
if (icon) {
icon.setStyle('fill', canJump ? legendModel.get('pageIconColor', true) : legendModel.get('pageIconInactiveColor', true));
icon.cursor = canJump ? 'pointer' : 'default';
}
});
var pageText = controllerGroup.childOfName('pageText');
var pageFormatter = legendModel.get('pageFormatter');
var pageIndex = pageInfo.pageIndex;
var current = pageIndex != null ? pageIndex + 1 : 0;
var total = pageInfo.pageCount;
pageText && pageFormatter && pageText.setStyle('text', zrUtil.isString(pageFormatter) ? pageFormatter.replace('{current}', current == null ? '' : current + '').replace('{total}', total == null ? '' : total + '') : pageFormatter({
current: current,
total: total
}));
};
/**
* contentPosition: Array.<number>, null when data item not found.
* pageIndex: number, null when data item not found.
* pageCount: number, always be a number, can be 0.
* pagePrevDataIndex: number, null when no previous page.
* pageNextDataIndex: number, null when no next page.
* }
*/
ScrollableLegendView.prototype._getPageInfo = function (legendModel) {
var scrollDataIndex = legendModel.get('scrollDataIndex', true);
var contentGroup = this.getContentGroup();
var containerRectSize = this._containerGroup.__rectSize;
var orientIdx = legendModel.getOrient().index;
var wh = WH[orientIdx];
var xy = XY[orientIdx];
var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);
var children = contentGroup.children();
var targetItem = children[targetItemIndex];
var itemCount = children.length;
var pCount = !itemCount ? 0 : 1;
var result = {
contentPosition: [contentGroup.x, contentGroup.y],
pageCount: pCount,
pageIndex: pCount - 1,
pagePrevDataIndex: null,
pageNextDataIndex: null
};
if (!targetItem) {
return result;
}
var targetItemInfo = getItemInfo(targetItem);
result.contentPosition[orientIdx] = -targetItemInfo.s;
// Strategy:
// (1) Always align based on the left/top most item.
// (2) It is user-friendly that the last item shown in the
// current window is shown at the begining of next window.
// Otherwise if half of the last item is cut by the window,
// it will have no chance to display entirely.
// (3) Consider that item size probably be different, we
// have calculate pageIndex by size rather than item index,
// and we can not get page index directly by division.
// (4) The window is to narrow to contain more than
// one item, we should make sure that the page can be fliped.
for (var i = targetItemIndex + 1, winStartItemInfo = targetItemInfo, winEndItemInfo = targetItemInfo, currItemInfo = null; i <= itemCount; ++i) {
currItemInfo = getItemInfo(children[i]);
if (
// Half of the last item is out of the window.
!currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize
// If the current item does not intersect with the window, the new page
// can be started at the current item or the last item.
|| currItemInfo && !intersect(currItemInfo, winStartItemInfo.s)) {
if (winEndItemInfo.i > winStartItemInfo.i) {
winStartItemInfo = winEndItemInfo;
} else {
// e.g., when page size is smaller than item size.
winStartItemInfo = currItemInfo;
}
if (winStartItemInfo) {
if (result.pageNextDataIndex == null) {
result.pageNextDataIndex = winStartItemInfo.i;
}
++result.pageCount;
}
}
winEndItemInfo = currItemInfo;
}
for (var i = targetItemIndex - 1, winStartItemInfo = targetItemInfo, winEndItemInfo = targetItemInfo, currItemInfo = null; i >= -1; --i) {
currItemInfo = getItemInfo(children[i]);
if (
// If the the end item does not intersect with the window started
// from the current item, a page can be settled.
(!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s)
// e.g., when page size is smaller than item size.
) && winStartItemInfo.i < winEndItemInfo.i) {
winEndItemInfo = winStartItemInfo;
if (result.pagePrevDataIndex == null) {
result.pagePrevDataIndex = winStartItemInfo.i;
}
++result.pageCount;
++result.pageIndex;
}
winStartItemInfo = currItemInfo;
}
return result;
function getItemInfo(el) {
if (el) {
var itemRect = el.getBoundingRect();
var start = itemRect[xy] + el[xy];
return {
s: start,
e: start + itemRect[wh],
i: el.__legendDataIndex
};
}
}
function intersect(itemInfo, winStart) {
return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
}
};
ScrollableLegendView.prototype._findTargetItemIndex = function (targetDataIndex) {
if (!this._showController) {
return 0;
}
var index;
var contentGroup = this.getContentGroup();
var defaultIndex;
contentGroup.eachChild(function (child, idx) {
var legendDataIdx = child.__legendDataIndex;
// FIXME
// If the given targetDataIndex (from model) is illegal,
// we use defaultIndex. But the index on the legend model and
// action payload is still illegal. That case will not be
// changed until some scenario requires.
if (defaultIndex == null && legendDataIdx != null) {
defaultIndex = idx;
}
if (legendDataIdx === targetDataIndex) {
index = idx;
}
});
return index != null ? index : defaultIndex;
};
ScrollableLegendView.type = 'legend.scroll';
return ScrollableLegendView;
}(LegendView);
export default ScrollableLegendView;

View File

@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../../extension.js';
import { install as installLegendPlain } from './installLegendPlain.js';
import { install as installLegendScroll } from './installLegendScroll.js';
export function install(registers) {
use(installLegendPlain);
use(installLegendScroll);
}

View File

@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import LegendModel from './LegendModel.js';
import LegendView from './LegendView.js';
import legendFilter from './legendFilter.js';
import { installLegendAction } from './legendAction.js';
export function install(registers) {
registers.registerComponentModel(LegendModel);
registers.registerComponentView(LegendView);
registers.registerProcessor(registers.PRIORITY.PROCESSOR.SERIES_FILTER, legendFilter);
registers.registerSubTypeDefaulter('legend', function () {
return 'plain';
});
installLegendAction(registers);
}

View File

@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../../extension.js';
import { install as installLegendPlain } from './installLegendPlain.js';
import ScrollableLegendModel from './ScrollableLegendModel.js';
import ScrollableLegendView from './ScrollableLegendView.js';
import installScrollableLegendAction from './scrollableLegendAction.js';
export function install(registers) {
use(installLegendPlain);
registers.registerComponentModel(ScrollableLegendModel);
registers.registerComponentView(ScrollableLegendView);
installScrollableLegendAction(registers);
}

View File

@@ -0,0 +1,126 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { curry, each, hasOwn } from 'zrender/lib/core/util.js';
function legendSelectActionHandler(methodName, payload, ecModel) {
var isAllSelect = methodName === 'allSelect' || methodName === 'inverseSelect';
var selectedMap = {};
var actionLegendIndices = [];
ecModel.eachComponent({
mainType: 'legend',
query: payload
}, function (legendModel) {
if (isAllSelect) {
legendModel[methodName]();
} else {
legendModel[methodName](payload.name);
}
makeSelectedMap(legendModel, selectedMap);
actionLegendIndices.push(legendModel.componentIndex);
});
var allSelectedMap = {};
// make selectedMap from all legend components
ecModel.eachComponent('legend', function (legendModel) {
each(selectedMap, function (isSelected, name) {
// Force other legend has same selected status
// Or the first is toggled to true and other are toggled to false
// In the case one legend has some item unSelected in option. And if other legend
// doesn't has the item, they will assume it is selected.
legendModel[isSelected ? 'select' : 'unSelect'](name);
});
makeSelectedMap(legendModel, allSelectedMap);
});
// Return the event explicitly
return isAllSelect ? {
selected: allSelectedMap,
// return legendIndex array to tell the developers which legends are allSelect / inverseSelect
legendIndex: actionLegendIndices
} : {
name: payload.name,
selected: allSelectedMap
};
}
function makeSelectedMap(legendModel, out) {
var selectedMap = out || {};
each(legendModel.getData(), function (model) {
var name = model.get('name');
// Wrap element
if (name === '\n' || name === '') {
return;
}
var isItemSelected = legendModel.isSelected(name);
if (hasOwn(selectedMap, name)) {
// Unselected if any legend is unselected
selectedMap[name] = selectedMap[name] && isItemSelected;
} else {
selectedMap[name] = isItemSelected;
}
});
return selectedMap;
}
export function installLegendAction(registers) {
/**
* @event legendToggleSelect
* @type {Object}
* @property {string} type 'legendToggleSelect'
* @property {string} [from]
* @property {string} name Series name or data item name
*/
registers.registerAction('legendToggleSelect', 'legendselectchanged', curry(legendSelectActionHandler, 'toggleSelected'));
registers.registerAction('legendAllSelect', 'legendselectall', curry(legendSelectActionHandler, 'allSelect'));
registers.registerAction('legendInverseSelect', 'legendinverseselect', curry(legendSelectActionHandler, 'inverseSelect'));
/**
* @event legendSelect
* @type {Object}
* @property {string} type 'legendSelect'
* @property {string} name Series name or data item name
*/
registers.registerAction('legendSelect', 'legendselected', curry(legendSelectActionHandler, 'select'));
/**
* @event legendUnSelect
* @type {Object}
* @property {string} type 'legendUnSelect'
* @property {string} name Series name or data item name
*/
registers.registerAction('legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect'));
}

View File

@@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export default function legendFilter(ecModel) {
var legendModels = ecModel.findComponents({
mainType: 'legend'
});
if (legendModels && legendModels.length) {
ecModel.filterSeries(function (series) {
// If in any legend component the status is not selected.
// Because in legend series is assumed selected when it is not in the legend data.
for (var i = 0; i < legendModels.length; i++) {
if (!legendModels[i].isSelected(series.name)) {
return false;
}
}
return true;
});
}
}

View File

@@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export default function installScrollableLegendAction(registers) {
/**
* @event legendScroll
* @type {Object}
* @property {string} type 'legendScroll'
* @property {string} scrollDataIndex
*/
registers.registerAction('legendScroll', 'legendscroll', function (payload, ecModel) {
var scrollDataIndex = payload.scrollDataIndex;
scrollDataIndex != null && ecModel.eachComponent({
mainType: 'legend',
subType: 'scroll',
query: payload
}, function (legendModel) {
legendModel.setScrollDataIndex(scrollDataIndex);
});
});
}

View File

@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Do not contain scrollable legend, for sake of file size.
import { use } from '../extension.js';
import { install } from './legend/installLegendPlain.js';
use(install);

View File

@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Legend component entry file8
*/
import { use } from '../extension.js';
import { install } from './legend/installLegendScroll.js';
use(install);

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './marker/installMarkArea.js';
use(install);

View File

@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { use } from '../extension.js';
import { install } from './marker/installMarkLine.js';
use(install);

View File

@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// HINT Markpoint can't be used too much
import { use } from '../extension.js';
import { install } from './marker/installMarkPoint.js';
use(install);

View File

@@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
import MarkerModel from './MarkerModel.js';
var MarkAreaModel = /** @class */function (_super) {
__extends(MarkAreaModel, _super);
function MarkAreaModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = MarkAreaModel.type;
return _this;
}
MarkAreaModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
return new MarkAreaModel(markerOpt, masterMarkerModel, ecModel);
};
MarkAreaModel.type = 'markArea';
MarkAreaModel.defaultOption = {
// zlevel: 0,
// PENDING
z: 1,
tooltip: {
trigger: 'item'
},
// markArea should fixed on the coordinate system
animation: false,
label: {
show: true,
position: 'top'
},
itemStyle: {
// color and borderColor default to use color from series
// color: 'auto'
// borderColor: 'auto'
borderWidth: 0
},
emphasis: {
label: {
show: true,
position: 'top'
}
}
};
return MarkAreaModel;
}(MarkerModel);
export default MarkAreaModel;

View File

@@ -0,0 +1,362 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __extends } from "tslib";
// TODO Optimize on polar
import * as colorUtil from 'zrender/lib/tool/color.js';
import SeriesData from '../../data/SeriesData.js';
import * as numberUtil from '../../util/number.js';
import * as graphic from '../../util/graphic.js';
import { toggleHoverEmphasis, setStatesStylesFromModel } from '../../util/states.js';
import * as markerHelper from './markerHelper.js';
import MarkerView from './MarkerView.js';
import { retrieve, mergeAll, map, curry, filter, extend, isString } from 'zrender/lib/core/util.js';
import { isCoordinateSystemType } from '../../coord/CoordinateSystem.js';
import MarkerModel from './MarkerModel.js';
import { makeInner } from '../../util/model.js';
import { getVisualFromData } from '../../visual/helper.js';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle.js';
import { getECData } from '../../util/innerStore.js';
import { parseDataValue } from '../../data/helper/dataValueHelper.js';
var inner = makeInner();
var markAreaTransform = function (seriesModel, coordSys, maModel, item) {
// item may be null
var item0 = item[0];
var item1 = item[1];
if (!item0 || !item1) {
return;
}
var lt = markerHelper.dataTransform(seriesModel, item0);
var rb = markerHelper.dataTransform(seriesModel, item1);
// FIXME make sure lt is less than rb
var ltCoord = lt.coord;
var rbCoord = rb.coord;
ltCoord[0] = retrieve(ltCoord[0], -Infinity);
ltCoord[1] = retrieve(ltCoord[1], -Infinity);
rbCoord[0] = retrieve(rbCoord[0], Infinity);
rbCoord[1] = retrieve(rbCoord[1], Infinity);
// Merge option into one
var result = mergeAll([{}, lt, rb]);
result.coord = [lt.coord, rb.coord];
result.x0 = lt.x;
result.y0 = lt.y;
result.x1 = rb.x;
result.y1 = rb.y;
return result;
};
function isInfinity(val) {
return !isNaN(val) && !isFinite(val);
}
// If a markArea has one dim
function ifMarkAreaHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
var otherDimIndex = 1 - dimIndex;
return isInfinity(fromCoord[otherDimIndex]) && isInfinity(toCoord[otherDimIndex]);
}
function markAreaFilter(coordSys, item) {
var fromCoord = item.coord[0];
var toCoord = item.coord[1];
var item0 = {
coord: fromCoord,
x: item.x0,
y: item.y0
};
var item1 = {
coord: toCoord,
x: item.x1,
y: item.y1
};
if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
// In case
// {
// markArea: {
// data: [{ yAxis: 2 }]
// }
// }
if (fromCoord && toCoord && (ifMarkAreaHasOnlyDim(1, fromCoord, toCoord, coordSys) || ifMarkAreaHasOnlyDim(0, fromCoord, toCoord, coordSys))) {
return true;
}
// Directly returning true may also do the work,
// because markArea will not be shown automatically
// when it's not included in coordinate system.
// But filtering ahead can avoid keeping rendering markArea
// when there are too many of them.
return markerHelper.zoneFilter(coordSys, item0, item1);
}
return markerHelper.dataFilter(coordSys, item0) || markerHelper.dataFilter(coordSys, item1);
}
// dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']
function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) {
var coordSys = seriesModel.coordinateSystem;
var itemModel = data.getItemModel(idx);
var point;
var xPx = numberUtil.parsePercent(itemModel.get(dims[0]), api.getWidth());
var yPx = numberUtil.parsePercent(itemModel.get(dims[1]), api.getHeight());
if (!isNaN(xPx) && !isNaN(yPx)) {
point = [xPx, yPx];
} else {
// Chart like bar may have there own marker positioning logic
if (seriesModel.getMarkerPosition) {
// Consider the case that user input the right-bottom point first
// Pick the larger x and y as 'x1' and 'y1'
var pointValue0 = data.getValues(['x0', 'y0'], idx);
var pointValue1 = data.getValues(['x1', 'y1'], idx);
var clampPointValue0 = coordSys.clampData(pointValue0);
var clampPointValue1 = coordSys.clampData(pointValue1);
var pointValue = [];
if (dims[0] === 'x0') {
pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue1[0] : pointValue0[0];
} else {
pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue0[0] : pointValue1[0];
}
if (dims[1] === 'y0') {
pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue1[1] : pointValue0[1];
} else {
pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue0[1] : pointValue1[1];
}
// Use the getMarkerPosition
point = seriesModel.getMarkerPosition(pointValue, dims, true);
} else {
var x = data.get(dims[0], idx);
var y = data.get(dims[1], idx);
var pt = [x, y];
coordSys.clampData && coordSys.clampData(pt, pt);
point = coordSys.dataToPoint(pt, true);
}
if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
// TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug
var xAxis = coordSys.getAxis('x');
var yAxis = coordSys.getAxis('y');
var x = data.get(dims[0], idx);
var y = data.get(dims[1], idx);
if (isInfinity(x)) {
point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
} else if (isInfinity(y)) {
point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]);
}
}
// Use x, y if has any
if (!isNaN(xPx)) {
point[0] = xPx;
}
if (!isNaN(yPx)) {
point[1] = yPx;
}
}
return point;
}
export var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']];
var MarkAreaView = /** @class */function (_super) {
__extends(MarkAreaView, _super);
function MarkAreaView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = MarkAreaView.type;
return _this;
}
MarkAreaView.prototype.updateTransform = function (markAreaModel, ecModel, api) {
ecModel.eachSeries(function (seriesModel) {
var maModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markArea');
if (maModel) {
var areaData_1 = maModel.getData();
areaData_1.each(function (idx) {
var points = map(dimPermutations, function (dim) {
return getSingleMarkerEndPoint(areaData_1, idx, dim, seriesModel, api);
});
// Layout
areaData_1.setItemLayout(idx, points);
var el = areaData_1.getItemGraphicEl(idx);
el.setShape('points', points);
});
}
}, this);
};
MarkAreaView.prototype.renderSeries = function (seriesModel, maModel, ecModel, api) {
var coordSys = seriesModel.coordinateSystem;
var seriesId = seriesModel.id;
var seriesData = seriesModel.getData();
var areaGroupMap = this.markerGroupMap;
var polygonGroup = areaGroupMap.get(seriesId) || areaGroupMap.set(seriesId, {
group: new graphic.Group()
});
this.group.add(polygonGroup.group);
this.markKeep(polygonGroup);
var areaData = createList(coordSys, seriesModel, maModel);
// Line data for tooltip and formatter
maModel.setData(areaData);
// Update visual and layout of line
areaData.each(function (idx) {
// Layout
var points = map(dimPermutations, function (dim) {
return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
});
var xAxisScale = coordSys.getAxis('x').scale;
var yAxisScale = coordSys.getAxis('y').scale;
var xAxisExtent = xAxisScale.getExtent();
var yAxisExtent = yAxisScale.getExtent();
var xPointExtent = [xAxisScale.parse(areaData.get('x0', idx)), xAxisScale.parse(areaData.get('x1', idx))];
var yPointExtent = [yAxisScale.parse(areaData.get('y0', idx)), yAxisScale.parse(areaData.get('y1', idx))];
numberUtil.asc(xPointExtent);
numberUtil.asc(yPointExtent);
var overlapped = !(xAxisExtent[0] > xPointExtent[1] || xAxisExtent[1] < xPointExtent[0] || yAxisExtent[0] > yPointExtent[1] || yAxisExtent[1] < yPointExtent[0]);
// If none of the area is inside coordSys, allClipped is set to be true
// in layout so that label will not be displayed. See #12591
var allClipped = !overlapped;
areaData.setItemLayout(idx, {
points: points,
allClipped: allClipped
});
var style = areaData.getItemModel(idx).getModel('itemStyle').getItemStyle();
var color = getVisualFromData(seriesData, 'color');
if (!style.fill) {
style.fill = color;
if (isString(style.fill)) {
style.fill = colorUtil.modifyAlpha(style.fill, 0.4);
}
}
if (!style.stroke) {
style.stroke = color;
}
// Visual
areaData.setItemVisual(idx, 'style', style);
});
areaData.diff(inner(polygonGroup).data).add(function (idx) {
var layout = areaData.getItemLayout(idx);
if (!layout.allClipped) {
var polygon = new graphic.Polygon({
shape: {
points: layout.points
}
});
areaData.setItemGraphicEl(idx, polygon);
polygonGroup.group.add(polygon);
}
}).update(function (newIdx, oldIdx) {
var polygon = inner(polygonGroup).data.getItemGraphicEl(oldIdx);
var layout = areaData.getItemLayout(newIdx);
if (!layout.allClipped) {
if (polygon) {
graphic.updateProps(polygon, {
shape: {
points: layout.points
}
}, maModel, newIdx);
} else {
polygon = new graphic.Polygon({
shape: {
points: layout.points
}
});
}
areaData.setItemGraphicEl(newIdx, polygon);
polygonGroup.group.add(polygon);
} else if (polygon) {
polygonGroup.group.remove(polygon);
}
}).remove(function (idx) {
var polygon = inner(polygonGroup).data.getItemGraphicEl(idx);
polygonGroup.group.remove(polygon);
}).execute();
areaData.eachItemGraphicEl(function (polygon, idx) {
var itemModel = areaData.getItemModel(idx);
var style = areaData.getItemVisual(idx, 'style');
polygon.useStyle(areaData.getItemVisual(idx, 'style'));
setLabelStyle(polygon, getLabelStatesModels(itemModel), {
labelFetcher: maModel,
labelDataIndex: idx,
defaultText: areaData.getName(idx) || '',
inheritColor: isString(style.fill) ? colorUtil.modifyAlpha(style.fill, 1) : '#000'
});
setStatesStylesFromModel(polygon, itemModel);
toggleHoverEmphasis(polygon, null, null, itemModel.get(['emphasis', 'disabled']));
getECData(polygon).dataModel = maModel;
});
inner(polygonGroup).data = areaData;
polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent');
};
MarkAreaView.type = 'markArea';
return MarkAreaView;
}(MarkerView);
function createList(coordSys, seriesModel, maModel) {
var areaData;
var dataDims;
var dims = ['x0', 'y0', 'x1', 'y1'];
if (coordSys) {
var coordDimsInfos_1 = map(coordSys && coordSys.dimensions, function (coordDim) {
var data = seriesModel.getData();
var info = data.getDimensionInfo(data.mapDimension(coordDim)) || {};
// In map series data don't have lng and lat dimension. Fallback to same with coordSys
return extend(extend({}, info), {
name: coordDim,
// DON'T use ordinalMeta to parse and collect ordinal.
ordinalMeta: null
});
});
dataDims = map(dims, function (dim, idx) {
return {
name: dim,
type: coordDimsInfos_1[idx % 2].type
};
});
areaData = new SeriesData(dataDims, maModel);
} else {
dataDims = [{
name: 'value',
type: 'float'
}];
areaData = new SeriesData(dataDims, maModel);
}
var optData = map(maModel.get('data'), curry(markAreaTransform, seriesModel, coordSys, maModel));
if (coordSys) {
optData = filter(optData, curry(markAreaFilter, coordSys));
}
var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) {
// TODO should convert to ParsedValue?
var rawVal = item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
return parseDataValue(rawVal, dataDims[dimIndex]);
} : function (item, dimName, dataIndex, dimIndex) {
return parseDataValue(item.value, dataDims[dimIndex]);
};
areaData.initData(optData, null, dimValueGetter);
areaData.hasItemOption = true;
return areaData;
}
export default MarkAreaView;

Some files were not shown because too many files have changed in this diff Show More