diff --git a/src/chart/graph.js b/src/chart/graph.js index 9e81fa4600..6bcf09fbd3 100644 --- a/src/chart/graph.js +++ b/src/chart/graph.js @@ -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 diff --git a/src/chart/graph/GraphView.js b/src/chart/graph/GraphView.js index e9f5529258..6be154891b 100644 --- a/src/chart/graph/GraphView.js +++ b/src/chart/graph/GraphView.js @@ -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'; @@ -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); @@ -356,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); }, @@ -365,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) { @@ -373,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(); diff --git a/src/chart/graph/adjustEdge.js b/src/chart/graph/adjustEdge.js index d36a0a63df..dc407674b5 100644 --- a/src/chart/graph/adjustEdge.js +++ b/src/chart/graph/adjustEdge.js @@ -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'); diff --git a/src/chart/graph/circularLayout.js b/src/chart/graph/circularLayout.js index 1495f6fb6b..9637fbffea 100644 --- a/src/chart/graph/circularLayout.js +++ b/src/chart/graph/circularLayout.js @@ -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'); } }); } diff --git a/src/chart/graph/circularLayoutHelper.js b/src/chart/graph/circularLayoutHelper.js index 2bf5d88645..3552c626df 100644 --- a/src/chart/graph/circularLayoutHelper.js +++ b/src/chart/graph/circularLayoutHelper.js @@ -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; + }); + } +}; diff --git a/src/chart/graph/forceLayout.js b/src/chart/graph/forceLayout.js index 36291baa24..af999bfb46 100644 --- a/src/chart/graph/forceLayout.js +++ b/src/chart/graph/forceLayout.js @@ -47,7 +47,7 @@ export default function (ecModel) { simpleLayout(graphSeries); } else if (initLayout === 'circular') { - circularLayout(graphSeries); + circularLayout(graphSeries, 'value'); } var nodeDataExtent = nodeData.getDataExtent('value'); diff --git a/src/chart/graph/graphHelper.js b/src/chart/graph/graphHelper.js new file mode 100644 index 0000000000..fc87b9e30e --- /dev/null +++ b/src/chart/graph/graphHelper.js @@ -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. +*/ + +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; +} + diff --git a/src/echarts.js b/src/echarts.js index e6ab5f13e7..6edca4af36 100644 --- a/src/echarts.js +++ b/src/echarts.js @@ -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 } diff --git a/test/force.html b/test/force.html index e3fb5a1c69..e330971dc4 100644 --- a/test/force.html +++ b/test/force.html @@ -96,7 +96,7 @@ width: '25%', height: '25%', force: { - // initLayout: 'circular' + // initLayout: 'circular', // gravity: 0 repulsion: 100, edgeLength: 5 diff --git a/test/force3.html b/test/force3.html index ffcd4a2503..e7ad1ae60c 100644 --- a/test/force3.html +++ b/test/force3.html @@ -70,7 +70,7 @@ animation: false, data: data, force: { - // initLayout: 'circular' + // initLayout: 'circular', // gravity: 0 repulsion: 100, edgeLength: 5 diff --git a/test/graph-circular.html b/test/graph-circular.html new file mode 100644 index 0000000000..e57b3a9d27 --- /dev/null +++ b/test/graph-circular.html @@ -0,0 +1,767 @@ +<!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> + <div id="main2"></div> + <div id="main3"></div> + <div id="main4"></div> + <div id="main5"></div> + <div id="main6"></div> + <div id="main7"></div> + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + data: [ + { + itemStyle: null, + name: 'DRD2', + value: 40, + symbolSize: 40 + }, + { + itemStyle: null, + name: 'ADORA2A', + value: 0, + symbolSize: 20 + }, + { + itemStyle: null, + name: 'ARRB2', + value: 30, + symbolSize: 20, + }, + { + itemStyle: null, + name: 'CALM1', + value: 20, + symbolSize: 40 + }, + { + itemStyle: null, + name: 'CALM2', + value: 0, + symbolSize: 20 + }, + { + itemStyle: null, + name: 'FLNA', + value: 0, + symbolSize: 20 + }, + { + itemStyle: null, + name: 'NSF', + value: 0, + symbolSize: 20 + } + ], + links: [ + { + source: 'DRD2', + target: 'ADORA2A' + }, + { + source: 'DRD2', + target: 'ARRB2' + }, + { + source: 'DRD2', + target: 'CALM1' + }, + { + source: 'DRD2', + target: 'CALM2' + }, + { + source: 'DRD2', + target: 'FLNA' + }, + { + source: 'DRD2', + target: 'NSF' + }, + { + source: 'CALM1', + target: 'ADORA2A' + }, + { + source: 'CALM1', + target: 'ARRB2' + }, + { + source: 'CALM1', + target: 'CALM2' + }, + { + source: 'CALM1', + target: 'FLNA' + }, + { + source: 'CALM1', + target: 'NSF' + }, + ] + }] + }; + + var chart = testHelper.create(echarts, 'main0', { + option: option, + title: 'has 0 value nodes' + // recordCanvas: true + }); + }); + + </script> + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + left: 50, + width: 100, + top: 50, + height: 100, + roam: true, + data: [ + { + name: 'DRD2', + value: 40, + symbolSize: 50 * Math.pow(2, 0.5) + }, + { + name: 'ADORA2A', + value: 0, + symbolSize: 50 * Math.pow(2, 0.5) + }, + { + name: 'ARRB2', + value: 30, + symbolSize: 50 * Math.pow(2, 0.5) + }, + { + name: 'CALM1', + value: 20, + symbolSize: 50 * Math.pow(2, 0.5) + } + ], + links: [ + { + source: 'DRD2', + target: 'ADORA2A' + }, + { + source: 'DRD2', + target: 'ARRB2' + } + ] + }] + }; + + var chart = testHelper.create(echarts, 'main1', { + option: option, + title: 'all the same' + // recordCanvas: true + }); + }); + + </script> + + + + + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + left: 50, + width: 100, + top: 50, + height: 100, + data: [ + { + name: 'DRD2', + value: 40, + symbolSize: 50 * Math.pow(2, 0.5) + }, + { + name: 'ADORA2A', + value: 0, + symbolSize: 50 * Math.pow(2, 0.5) + }, + { + name: 'ARRB2', + value: 30, + symbolSize: 50 * Math.pow(2, 0.5) + }, + { + name: 'CALM1', + value: 20, + symbolSize: 100 * Math.pow(2, 0.5) + } + ], + links: [ + { + source: 'DRD2', + target: 'ADORA2A' + }, + { + source: 'DRD2', + target: 'ARRB2' + } + ] + }] + }; + + var chart = testHelper.create(echarts, 'main2', { + option: option, + title: 'one symbol contains the center of the circular layout.' + // recordCanvas: true + }); + }); + + </script> + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + left: 50, + width: 100, + top: 50, + height: 100, + data: [ + { + name: 'DRD2', + value: 40, + symbolSize: 70 * Math.pow(2, 0.5) + }, + { + name: 'ADORA2A', + value: 0, + symbolSize: 70 * Math.pow(2, 0.5) + }, + { + name: 'ARRB2', + value: 30, + symbolSize: 70 * Math.pow(2, 0.5) + }, + { + name: 'CALM1', + value: 20, + symbolSize: 70 * Math.pow(2, 0.5) + } + ], + links: [ + { + source: 'DRD2', + target: 'ADORA2A' + }, + { + source: 'DRD2', + target: 'ARRB2' + } + ] + }] + }; + + var chart = testHelper.create(echarts, 'main3', { + option: option, + title: 'overlapped' + // recordCanvas: true + }); + }); + + </script> + + + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + left: 50, + width: 100, + top: 50, + height: 100, + data: [ + { + name: 'DRD2', + value: 40, + symbolSize: 30 * Math.pow(2, 0.5) + } + ], + }] + }; + + var chart = testHelper.create(echarts, 'main4', { + option: option, + title: 'one node' + // recordCanvas: true + }); + }); + + </script> + + + + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + left: 50, + width: 100, + top: 50, + height: 100, + data: [ + { + name: 'DRD2', + value: 40, + symbolSize: 30 * Math.pow(2, 0.5) + }, + { + name: 'ADORA2A', + value: 0, + symbolSize: 70 * Math.pow(2, 0.5) + } + ], + }] + }; + + var chart = testHelper.create(echarts, 'main5', { + option: option, + title: 'two nodes' + // recordCanvas: true + }); + }); + + </script> + + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + option = { + tooltip: {}, + legend: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + left: 50, + width: 100, + top: 50, + height: 100, + data: [ + { + name: 'DRD2', + value: 40, + symbolSize: 70 * Math.pow(2, 0.5) + }, + { + name: 'ADORA2A', + value: 0, + symbolSize: 10 * Math.pow(2, 0.5) + }, + { + name: 'ARRB2', + value: 30, + symbolSize: 10 * Math.pow(2, 0.5) + } + ], + }] + }; + + var chart = testHelper.create(echarts, 'main6', { + option: option, + title: 'three nodes' + // recordCanvas: true + }); + }); + + </script> + + + + + + + + + <script> + + var option; + + require([ + 'echarts'/*, 'map/js/china' */ + ], function (echarts) { + + var nodes = []; + for (var i = 0; i < 50; i++) { + nodes.push({ + name: 'node_' + i, + value: 40, + symbolSize: 7 + (i > 7 && i < 15 ? 40 : 0) + }); + } + + option = { + tooltip: {}, + series: [{ + type: 'graph', + name: 'Gene', + layout: 'circular', + circular: { + rotateLabel: true + }, + roam: true, + focusNodeAdjacency: true, + zoom: 0.5, + label: { + show: true + }, + lineStyle: { + color: 'source', + curveness: 0.3 + }, + itemStyle: { + opacity: 0.8 + }, + emphasis: { + label: { + color: 'blue' + }, + lineStyle: { + width: 10 + } + }, + roam: true, + data: nodes + }] + }; + + var chart = testHelper.create(echarts, 'main7', { + option: option, + height: 400, + title: [ + 'scaled (symbol should not be overlapped)', + 'also check circular layout in **test/graph.html**', + 'where also has symbols scaled.' + ] + }); + }); + + </script> + + + + + + + + + </body> +</html> \ No newline at end of file