提交 6c846d69 编写于 作者: O Ovilia

Merge branch 'master' of github.com:ecomfe/echarts

......@@ -39,7 +39,7 @@ echarts.registerVisual(categoryVisual);
echarts.registerVisual(edgeVisual);
echarts.registerLayout(simpleLayout);
echarts.registerLayout(circularLayout);
echarts.registerLayout(echarts.PRIORITY.VISUAL.POST_CHART_LAYOUT, circularLayout);
echarts.registerLayout(forceLayout);
// Graph view coordinate system
......
......@@ -26,6 +26,7 @@ import * as roamHelper from '../../component/helper/roamHelper';
import {onIrrelevantElement} from '../../component/helper/cursorHelper';
import * as graphic from '../../util/graphic';
import adjustEdge from './adjustEdge';
import {getNodeGlobalScale} from './graphHelper';
var FOCUS_ADJACENCY = '__focusNodeAdjacency';
var UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';
......@@ -62,7 +63,7 @@ function fadeOutItem(item, opacityPath, opacityRatio) {
function fadeInItem(item, opacityPath) {
var opacity = getItemOpacity(item, opacityPath);
var el = item.getGraphicEl();
// Should go back to normal opacity first, consider hoverLayer,
// Should go back to normal opacity first, consider hoverLayer,
// where current state is copied to elMirror, and support
// emphasis opacity here.
el.traverse(function (child) {
......@@ -96,7 +97,6 @@ export default echarts.extendChartView({
var coordSys = seriesModel.coordinateSystem;
this._model = seriesModel;
this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');
var symbolDraw = this._symbolDraw;
var lineDraw = this._lineDraw;
......@@ -116,7 +116,7 @@ export default echarts.extendChartView({
}
}
// Fix edge contact point with node
adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
var data = seriesModel.getData();
symbolDraw.updateData(data);
......@@ -221,17 +221,25 @@ export default echarts.extendChartView({
rad = rad - Math.PI;
}
var textPosition = isLeft ? 'left' : 'right';
symbolPath.setStyle({
textRotation: -rad,
textPosition: textPosition,
textOrigin: 'center'
});
symbolPath.hoverStyle && (symbolPath.hoverStyle.textPosition = textPosition);
graphic.modifyLabelStyle(
symbolPath,
{
textRotation: -rad,
textPosition: textPosition,
textOrigin: 'center'
},
{
textPosition: textPosition
}
);
}
else {
symbolPath.setStyle({
textRotation: labelRotate *= Math.PI / 180
});
graphic.modifyLabelStyle(
symbolPath,
{
textRotation: labelRotate *= Math.PI / 180
}
);
}
});
......@@ -348,7 +356,7 @@ export default echarts.extendChartView({
originY: e.originY
});
this._updateNodeAndLinkScale();
adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
this._lineDraw.updateLayout();
}, this);
},
......@@ -357,7 +365,7 @@ export default echarts.extendChartView({
var seriesModel = this._model;
var data = seriesModel.getData();
var nodeScale = this._getNodeGlobalScale(seriesModel);
var nodeScale = getNodeGlobalScale(seriesModel);
var invScale = [nodeScale, nodeScale];
data.eachItemGraphicEl(function (el, idx) {
......@@ -365,25 +373,8 @@ export default echarts.extendChartView({
});
},
_getNodeGlobalScale: function (seriesModel) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys.type !== 'view') {
return 1;
}
var nodeScaleRatio = this._nodeScaleRatio;
var groupScale = coordSys.scale;
var groupZoom = (groupScale && groupScale[0]) || 1;
// Scale node when zoom changes
var roamZoom = coordSys.getZoom();
var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
return nodeScale / groupZoom;
},
updateLayout: function (seriesModel) {
adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
this._symbolDraw.updateLayout();
this._lineDraw.updateLayout();
......
......@@ -19,6 +19,7 @@
import * as curveTool from 'zrender/src/core/curve';
import * as vec2 from 'zrender/src/core/vector';
import {getSymbolSize} from './graphHelper';
var v1 = [];
var v2 = [];
......@@ -97,13 +98,6 @@ export default function (graph, scale) {
var v = [];
scale /= 2;
function getSymbolSize(node) {
var symbolSize = node.getVisual('symbolSize');
if (symbolSize instanceof Array) {
symbolSize = (symbolSize[0] + symbolSize[1]) / 2;
}
return symbolSize;
}
graph.eachEdge(function (edge, idx) {
var linePoints = edge.getLayout();
var fromSymbol = edge.getVisual('fromSymbol');
......
......@@ -22,7 +22,7 @@ import {circularLayout} from './circularLayoutHelper';
export default function (ecModel) {
ecModel.eachSeriesByType('graph', function (seriesModel) {
if (seriesModel.get('layout') === 'circular') {
circularLayout(seriesModel);
circularLayout(seriesModel, 'symbolSize');
}
});
}
......@@ -18,8 +18,35 @@
*/
import * as vec2 from 'zrender/src/core/vector';
import {getSymbolSize, getNodeGlobalScale} from './graphHelper';
export function circularLayout(seriesModel) {
var PI = Math.PI;
var _symbolRadiansHalf = [];
/**
* `basedOn` can be:
* 'value':
* This layout is not accurate and have same bad case. For example,
* if the min value is very smaller than the max value, the nodes
* with the min value probably overlap even though there is enough
* space to layout them. So we only use this approach in the as the
* init layout of the force layout.
* FIXME
* Probably we do not need this method any more but use
* `basedOn: 'symbolSize'` in force layout if
* delay its init operations to GraphView.
* 'symbolSize':
* This approach work only if all of the symbol size calculated.
* That is, the progressive rendering is not applied to graph.
* FIXME
* If progressive rendering is applied to graph some day,
* probably we have to use `basedOn: 'value'`.
*
* @param {module:echarts/src/model/Series} seriesModel
* @param {string} basedOn 'value' or 'symbolSize'
*/
export function circularLayout(seriesModel, basedOn) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.type !== 'view') {
return;
......@@ -30,33 +57,22 @@ export function circularLayout(seriesModel) {
var nodeData = seriesModel.getData();
var graph = nodeData.graph;
var angle = 0;
var sum = nodeData.getSum('value');
var unitAngle = Math.PI * 2 / (sum || nodeData.count());
var cx = rect.width / 2 + rect.x;
var cy = rect.height / 2 + rect.y;
var r = Math.min(rect.width, rect.height) / 2;
graph.eachNode(function (node) {
var value = node.getValue('value');
angle += unitAngle * (sum ? value : 1) / 2;
node.setLayout([
r * Math.cos(angle) + cx,
r * Math.sin(angle) + cy
]);
angle += unitAngle * (sum ? value : 1) / 2;
});
var count = nodeData.count();
nodeData.setLayout({
cx: cx,
cy: cy
});
if (!count) {
return;
}
_layoutNodesBasedOn[basedOn](seriesModel, coordSys, graph, nodeData, r, cx, cy, count);
graph.eachEdge(function (edge) {
var curveness = edge.getModel().get('lineStyle.curveness') || 0;
var p1 = vec2.clone(edge.node1.getLayout());
......@@ -73,4 +89,63 @@ export function circularLayout(seriesModel) {
}
edge.setLayout([p1, p2, cp1]);
});
}
\ No newline at end of file
}
var _layoutNodesBasedOn = {
value: function (seriesModel, coordSys, graph, nodeData, r, cx, cy, count) {
var angle = 0;
var sum = nodeData.getSum('value');
var unitAngle = Math.PI * 2 / (sum || count);
graph.eachNode(function (node) {
var value = node.getValue('value');
var radianHalf = unitAngle * (sum ? value : 1) / 2;
angle += radianHalf;
node.setLayout([
r * Math.cos(angle) + cx,
r * Math.sin(angle) + cy
]);
angle += radianHalf;
});
},
symbolSize: function (seriesModel, coordSys, graph, nodeData, r, cx, cy, count) {
var sumRadian = 0;
_symbolRadiansHalf.length = count;
var nodeScale = getNodeGlobalScale(seriesModel);
graph.eachNode(function (node) {
var symbolSize = getSymbolSize(node);
// Normally this case will not happen, but we still add
// some the defensive code (2px is an arbitrary value).
isNaN(symbolSize) && (symbolSize = 2);
symbolSize < 0 && (symbolSize = 0);
symbolSize *= nodeScale;
var symbolRadianHalf = Math.asin(symbolSize / 2 / r);
// when `symbolSize / 2` is bigger than `r`.
isNaN(symbolRadianHalf) && (symbolRadianHalf = PI / 2);
_symbolRadiansHalf[node.dataIndex] = symbolRadianHalf;
sumRadian += symbolRadianHalf * 2;
});
var halfRemainRadian = (2 * PI - sumRadian) / count / 2;
var angle = 0;
graph.eachNode(function (node) {
var radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex];
angle += radianHalf;
node.setLayout([
r * Math.cos(angle) + cx,
r * Math.sin(angle) + cy
]);
angle += radianHalf;
});
}
};
......@@ -47,7 +47,7 @@ export default function (ecModel) {
simpleLayout(graphSeries);
}
else if (initLayout === 'circular') {
circularLayout(graphSeries);
circularLayout(graphSeries, 'value');
}
var nodeDataExtent = nodeData.getDataExtent('value');
......
/*
* 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 function getNodeGlobalScale(seriesModel) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys.type !== 'view') {
return 1;
}
var nodeScaleRatio = seriesModel.option.nodeScaleRatio;
var groupScale = coordSys.scale;
var groupZoom = (groupScale && groupScale[0]) || 1;
// Scale node when zoom changes
var roamZoom = coordSys.getZoom();
var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
return nodeScale / groupZoom;
}
export function getSymbolSize(node) {
var symbolSize = node.getVisual('symbolSize');
if (symbolSize instanceof Array) {
symbolSize = (symbolSize[0] + symbolSize[1]) / 2;
}
return +symbolSize;
}
......@@ -32,6 +32,8 @@ export default SeriesModel.extend({
dependencies: ['grid', 'polar'],
preventUsingHoverLayer: true,
/**
* @type {module:echarts/data/Tree~Node}
*/
......@@ -40,7 +42,6 @@ export default SeriesModel.extend({
defaultOption: {
// Disable progressive rendering
progressive: 0,
hoverLayerThreshold: Infinity,
// center: ['50%', '50%'], // not supported in ec3.
// size: ['80%', '80%'], // deprecated, compatible with ec2.
left: 'center',
......
......@@ -238,7 +238,7 @@ BaseAxisPointer.prototype = {
*/
updatePointerEl: function (group, elOption, updateProps) {
var pointerEl = inner(group).pointerEl;
if (pointerEl) {
if (pointerEl && elOption.pointer) {
pointerEl.setStyle(elOption.pointer.style);
updateProps(pointerEl, {shape: elOption.pointer.shape});
}
......
......@@ -304,6 +304,21 @@ var List = function (dimensions, hostModel) {
* @private
*/
this._calculationInfo = {};
/**
* User output info of this data.
* DO NOT use it in other places!
*
* When preparing user params for user callbacks, we have
* to clone these inner data structures to prevent users
* from modifying them to effect built-in logic. And for
* performance consideration we make this `userOutput` to
* avoid clone them too many times.
*
* @type {Object}
* @readOnly
*/
this.userOutput = this._dimensionsSummary.userOutput;
};
var listProto = List.prototype;
......
......@@ -31,6 +31,12 @@ export function summarizeDimensions(data) {
var defaultedLabel = [];
var defaultedTooltip = [];
// See the comment of `List.js#userOutput`.
var userOutput = summary.userOutput = {
dimensionNames: data.dimensions.slice(),
encode: {}
};
each(data.dimensions, function (dimName) {
var dimItem = data.getDimensionInfo(dimName);
......@@ -39,11 +45,9 @@ export function summarizeDimensions(data) {
if (__DEV__) {
assert(OTHER_DIMENSIONS.get(coordDim) == null);
}
var coordDimArr = encode[coordDim];
if (!encode.hasOwnProperty(coordDim)) {
coordDimArr = encode[coordDim] = [];
}
coordDimArr[dimItem.coordDimIndex] = dimName;
var coordDimIndex = dimItem.coordDimIndex;
getOrCreateEncodeArr(encode, coordDim)[coordDimIndex] = dimName;
if (!dimItem.isExtraCoord) {
notExtraCoordDimMap.set(coordDim, 1);
......@@ -55,6 +59,10 @@ export function summarizeDimensions(data) {
if (mayLabelDimType(dimItem.type)) {
defaultedLabel[0] = dimName;
}
// User output encode do not contain generated coords.
// And it only has index. User can use index to retrieve value from the raw item array.
getOrCreateEncodeArr(userOutput.encode, coordDim)[coordDimIndex] = dimItem.index;
}
if (dimItem.defaultTooltip) {
defaultedTooltip.push(dimName);
......@@ -62,14 +70,11 @@ export function summarizeDimensions(data) {
}
OTHER_DIMENSIONS.each(function (v, otherDim) {
var otherDimArr = encode[otherDim];
if (!encode.hasOwnProperty(otherDim)) {
otherDimArr = encode[otherDim] = [];
}
var encodeArr = getOrCreateEncodeArr(encode, otherDim);
var dimIndex = dimItem.otherDims[otherDim];
if (dimIndex != null && dimIndex !== false) {
otherDimArr[dimIndex] = dimItem.name;
encodeArr[dimIndex] = dimItem.name;
}
});
});
......@@ -112,6 +117,13 @@ export function summarizeDimensions(data) {
return summary;
}
function getOrCreateEncodeArr(encode, dim) {
if (!encode.hasOwnProperty(dim)) {
encode[dim] = [];
}
return encode[dim];
}
export function getDimensionTypeByAxis(axisType) {
return axisType === 'category'
? 'ordinal'
......
......@@ -66,6 +66,7 @@ var PRIORITY_VISUAL_LAYOUT = 1000;
var PRIORITY_VISUAL_PROGRESSIVE_LAYOUT = 1100;
var PRIORITY_VISUAL_GLOBAL = 2000;
var PRIORITY_VISUAL_CHART = 3000;
var PRIORITY_VISUAL_POST_CHART_LAYOUT = 3500;
var PRIORITY_VISUAL_COMPONENT = 4000;
// FIXME
// necessary?
......@@ -81,6 +82,7 @@ export var PRIORITY = {
PROGRESSIVE_LAYOUT: PRIORITY_VISUAL_PROGRESSIVE_LAYOUT,
GLOBAL: PRIORITY_VISUAL_GLOBAL,
CHART: PRIORITY_VISUAL_CHART,
POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT,
COMPONENT: PRIORITY_VISUAL_COMPONENT,
BRUSH: PRIORITY_VISUAL_BRUSH
}
......@@ -1500,7 +1502,7 @@ function renderSeries(ecIns, ecModel, api, payload, dirtyMap) {
scheduler.unfinished |= unfinished;
// If use hover layer
updateHoverLayerStatus(ecIns._zr, ecModel);
updateHoverLayerStatus(ecIns, ecModel);
// Add aria
aria(ecIns._zr.dom, ecModel);
......@@ -1655,19 +1657,26 @@ echartsProto.dispose = function () {
zrUtil.mixin(ECharts, Eventful);
function updateHoverLayerStatus(zr, ecModel) {
function updateHoverLayerStatus(ecIns, ecModel) {
var zr = ecIns._zr;
var storage = zr.storage;
var elCount = 0;
storage.traverse(function (el) {
if (!el.isGroup) {
elCount++;
}
elCount++;
});
if (elCount > ecModel.get('hoverLayerThreshold') && !env.node) {
storage.traverse(function (el) {
if (!el.isGroup) {
// Don't switch back.
el.useHoverLayer = true;
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.preventUsingHoverLayer) {
return;
}
var chartView = ecIns._chartsMap[seriesModel.__viewId];
if (chartView.__alive) {
chartView.group.traverse(function (el) {
// Don't switch back.
el.useHoverLayer = true;
});
}
});
}
......
......@@ -43,6 +43,7 @@ export default {
var renderMode = getTooltipRenderMode(renderModeOption);
var mainType = this.mainType;
var isSeries = mainType === 'series';
var userOutput = data.userOutput;
return {
componentType: mainType,
......@@ -58,6 +59,8 @@ export default {
dataType: dataType,
value: rawValue,
color: color,
dimensionNames: userOutput ? userOutput.dimensionNames : null,
encode: userOutput ? userOutput.encode : null,
marker: getTooltipMarker({
color: color,
renderMode: renderMode
......@@ -73,7 +76,8 @@ export default {
* @param {number} dataIndex
* @param {string} [status='normal'] 'normal' or 'emphasis'
* @param {string} [dataType]
* @param {number} [dimIndex]
* @param {number} [dimIndex] Only used in some chart that
* use formatter in different dimensions, like radar.
* @param {string} [labelProp='label']
* @return {string} If not formatter, return null/undefined
*/
......
......@@ -657,6 +657,29 @@ export function setLabelStyle(
emphasisStyle.text = emphasisStyleText;
}
/**
* Modify label style manually.
* Only works after `setLabelStyle` and `setElementHoverStyle` called.
*
* @param {module:zrender/src/Element} el
* @param {Object} [normalStyleProps] optional
* @param {Object} [emphasisStyleProps] optional
*/
export function modifyLabelStyle(el, normalStyleProps, emphasisStyleProps) {
var elStyle = el.style;
if (normalStyleProps) {
rollbackDefaultTextStyle(elStyle);
el.setStyle(normalStyleProps);
applyDefaultTextStyle(elStyle);
}
elStyle = el.__hoverStl;
if (emphasisStyleProps && elStyle) {
rollbackDefaultTextStyle(elStyle);
zrUtil.extend(elStyle, emphasisStyleProps);
applyDefaultTextStyle(elStyle);
}
}
/**
* Set basic textStyle properties.
* See more info in `setTextStyleCommon`.
......@@ -842,10 +865,6 @@ function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isEm
globalTextStyle.textBorderWidth
);
// Save original textPosition, because style.textPosition will be repalced by
// real location (like [10, 30]) in zrender.
textStyle.insideRawTextPosition = textStyle.textPosition;
if (!isEmphasis) {
if (isBlock) {
textStyle.insideRollbackOpt = opt;
......@@ -936,7 +955,7 @@ function applyDefaultTextStyle(textStyle) {
}
var useInsideStyle = opt.useInsideStyle;
var textPosition = textStyle.insideRawTextPosition;
var textPosition = textStyle.textPosition;
var insideRollback;
var autoColor = opt.autoColor;
......
......@@ -96,7 +96,7 @@ under the License.
width: '25%',
height: '25%',
force: {
// initLayout: 'circular'
// initLayout: 'circular',
// gravity: 0
repulsion: 100,
edgeLength: 5
......
......@@ -70,7 +70,7 @@ under the License.
animation: false,
data: data,
force: {
// initLayout: 'circular'
// initLayout: 'circular',
// gravity: 0
repulsion: 100,
edgeLength: 5
......
此差异已折叠。
<!DOCTYPE html>
<!--
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.
-->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="lib/esl.js"></script>
<script src="lib/config.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/facePrint.js"></script>
<script src="lib/testHelper.js"></script>
<!-- <script src="ut/lib/canteen.js"></script> -->
<link rel="stylesheet" href="lib/reset.css" />
</head>
<body>
<style>
</style>
<div id="main0"></div>
<div id="main1"></div>
<script>
require([
'echarts'/*, 'map/js/china' */
], function (echarts) {
var option = {
dataset: {
dimensions: ['product', '2015', '2016', '2017'],
source: [
{product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
{product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
{product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
{product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}
]
},
xAxis: {
type: 'category'
},
yAxis: {},
series: [{
type: 'bar',
label: {
show: true,
formatter: function (params) {
// console.log(params);
return '(' + params.value[params.dimensionNames[params.encode.y[0]]] + ')';
}
}
}]
};
var chart = testHelper.create(echarts, 'main0', {
option: option,
title: [
'label should be (y axis value)'
]
});
});
</script>
<script>
var option;
require([
'echarts'/*, 'map/js/china' */
], function (echarts) {
var option = {
dataset: {
source: [
['Matcha Latte', 43.3, 85.8, 93.7],
['Milk Tea', 83.1, 73.4, 55.1],
['Cheese Cocoa', 86.4, 65.2, 82.5],
['Walnut Brownie', 72.4, 53.9, 39.1]
]
},
xAxis: {
type: 'category'
},
yAxis: {},
series: [{
type: 'bar',
label: {
show: true,
formatter: function (params) {
console.log(params);
return '(' + params.value[params.encode.y[0]] + ')';
}
}
}]
};
var chart = testHelper.create(echarts, 'main1', {
option: option,
title: [
'label should be (y axis value)'
]
});
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -460,7 +460,13 @@ under the License.
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
type: 'cross',
label: {
formatter: function (params) {
console.log(params);
return 'asdfa';
}
}
}
}
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册