diff --git a/src/chart/sunburst/SunburstPiece.js b/src/chart/sunburst/SunburstPiece.js index e71f467ddf6dccff1f79ec689e7d913a61e719cf..1d56f5f305cff3d3d6e3bc0a4a8b2bbb1b81b15f 100644 --- a/src/chart/sunburst/SunburstPiece.js +++ b/src/chart/sunburst/SunburstPiece.js @@ -34,9 +34,7 @@ function SunburstPiece(node, seriesModel, ecModel) { this.node = node; - var highlightPolicy = seriesModel.getShallow('highlightPolicy'); - - this.updateData(true, seriesModel, ecModel, highlightPolicy); + this.updateData(true, node, seriesModel, ecModel); // Hover to change label and labelLine function onEmphasis() { @@ -55,13 +53,15 @@ var SunburstPieceProto = SunburstPiece.prototype; SunburstPieceProto.updateData = function ( firstCreate, + node, seriesModel, - ecModel, - highlightPolicy + ecModel ) { + this.node = node; + node.piece = this; + var sector = this.childAt(0); - var node = this.node; var itemModel = node.getModel(); var layout = node.getLayout(); var sectorShape = zrUtil.extend({}, layout); @@ -106,6 +106,7 @@ SunburstPieceProto.updateData = function ( var cursorStyle = itemModel.getShallow('cursor'); cursorStyle && sector.attr('cursor', cursorStyle); + var highlightPolicy = seriesModel.getShallow('highlightPolicy'); this._initEvents(sector, node, seriesModel, highlightPolicy); this._updateLabel(seriesModel, ecModel); diff --git a/src/chart/sunburst/SunburstView.js b/src/chart/sunburst/SunburstView.js index 415ea1bbb1095ea643f65ae2c6a02b39dbbe8d04..f2ed0f422b4afe379e01d6d88eacfd2f70638989 100644 --- a/src/chart/sunburst/SunburstView.js +++ b/src/chart/sunburst/SunburstView.js @@ -4,24 +4,6 @@ import ChartView from '../../view/Chart'; import SunburstPiece from './SunburstPiece'; import DataDiffer from '../../data/DataDiffer'; -/** - * @param {module:echarts/model/Series} seriesModel - * @param {boolean} hasAnimation - * @inner - */ -function updateDataSelected(uid, seriesModel, hasAnimation, api) { - var treeRoot = seriesModel.getData(); - var dataIndex = this.dataIndex; - var name = treeRoot.getName(dataIndex); - - api.dispatchAction({ - type: 'SunburstToggleSelect', - from: uid, - name: name, - seriesId: seriesModel.id - }); -} - var SunburstView = ChartView.extend({ type: 'sunburst', @@ -29,6 +11,12 @@ var SunburstView = ChartView.extend({ init: function () { var sectorGroup = new graphic.Group(); this._sectorGroup = sectorGroup; + + /** + * @private + * @type {module:echarts/data/Tree} + */ + this._oldTree; }, render: function (seriesModel, ecModel, api, payload) { @@ -36,69 +24,89 @@ var SunburstView = ChartView.extend({ return; } - var treeRoot = seriesModel.getData().tree.root; - var oldData = this._data; + var oldTree = this._oldTree; + var newTree = seriesModel.getData().tree; + // var treeRoot = seriesModel.getData().tree.root; + + // var oldData = this._data; var group = this.group; - var hasAnimation = ecModel.get('animation'); - var isFirstRender = !oldData; - var animationType = seriesModel.get('animationType'); + // var hasAnimation = ecModel.get('animation'); + // var isFirstRender = !oldData; + // var animationType = seriesModel.get('animationType'); // var onSectorClick = zrUtil.curry( // updateDataSelected, this.uid, seriesModel, hasAnimation, api // ); - treeRoot.eachNode(function (node) { - if (node !== treeRoot) { - var piece = new SunburstPiece(node, seriesModel, ecModel); - node.piece = piece; - group.add(piece); + // treeRoot.eachNode(function (node) { + // if (node !== treeRoot) { + // var piece = new SunburstPiece(node, seriesModel, ecModel); + // node.piece = piece; + // group.add(piece); + // } + // }); + + dualTravel( + newTree.root ? [newTree.root] : [], + (oldTree && oldTree.root) ? [oldTree.root] : [] + ); + + this._data = newTree.root; + this._oldTree = newTree; + + function dualTravel(newChildren, oldChildren) { + if (newChildren.length === 0 && oldChildren.length === 0) { + return; + } + + new DataDiffer(oldChildren, newChildren, getKey, getKey) + .add(processNode) + .update(processNode) + .remove(zrUtil.curry(processNode, null)) + .execute(); + + function getKey(node) { + return node.getId(); } - }); - // treeRoot.diff(oldData) - // .add(function (idx) { - // var sunburstPiece = new SunburstPiece(treeRoot, idx); - // // Default expansion animation - // if (isFirstRender && animationType !== 'scale') { - // sunburstPiece.eachChild(function (child) { - // child.stopAnimation(true); - // }); - // } - - // treeRoot.setItemGraphicEl(idx, sunburstPiece); - - // group.add(sunburstPiece); - // }) - // .update(function (newIdx, oldIdx) { - // var sunburstPiece = oldData.getItemGraphicEl(oldIdx); - - // sunburstPiece.updateData(treeRoot, newIdx); - - // group.add(sunburstPiece); - // treeRoot.setItemGraphicEl(newIdx, sunburstPiece); - // }) - // .remove(function (idx) { - // var sunburstPiece = oldData.getItemGraphicEl(idx); - // group.remove(sunburstPiece); - // }) - // .execute(); - - // if ( - // hasAnimation && isFirstRender && treeRoot.count() > 0 - // // Default expansion animation - // && animationType !== 'scale' - // ) { - // var shape = treeRoot.getLayout(); - // var r = Math.max(api.getWidth(), api.getHeight()) / 2; - - // var removeClipPath = zrUtil.bind(group.removeClipPath, group); - // group.setClipPath(this._createClipPath( - // shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel - // )); - // } - - this._data = treeRoot; + function processNode(newId, oldId) { + var newNode = newId == null ? null : newChildren[newId]; + var oldNode = oldId == null ? null : oldChildren[oldId]; + + doRenderNode(newNode, oldNode); + + dualTravel( + newNode && newNode.children || [], + oldNode && oldNode.children || [] + ); + } + } + + function doRenderNode(newNode, oldNode) { + if (newNode !== newTree.root) { + if (oldNode && oldNode.piece) { + if (newNode) { + // Update + oldNode.piece + .updateData(false, newNode, seriesModel, ecModel); + } + else { + // Remove + group.remove(oldNode.piece); + } + } + else { + // Add + var piece = new SunburstPiece( + newNode, + seriesModel, + ecModel + ); + group.add(piece); + } + } + } }, dispose: function () {}, diff --git a/test/sunburst.html b/test/sunburst.html index 1b4fd8ec8e90b55ce5b579e34317340964faac25..10b8a7164a24164f8d0e93fc3d6c1da0a626e3e3 100644 --- a/test/sunburst.html +++ b/test/sunburst.html @@ -24,95 +24,125 @@ // renderer: 'svg' }); - chart.setOption({ - series: { - type: 'sunburst', - highlightPolicy: 'ancestor', - data: [{ - name: 'Grandpa', - children: [{ - name: 'Uncle Leo', - value: 15, - children: [{ - name: 'Cousin Jack', - value: 2 - }, { - name: 'Cousin Mary', - value: 5, - itemStyle: { - normal: { - opacity: 0.2 - } - } - }, { - name: 'Cousin Ben', - value: 4 - }], - itemStyle: { - normal: { - color: '#ff0' - } + var data = [{ + name: 'Grandpa', + children: [{ + name: 'Uncle Leo', + value: 15, + children: [{ + name: 'Cousin Jack', + value: 2 + }, { + name: 'Cousin Mary', + value: 5, + itemStyle: { + normal: { + opacity: 0.2 } - }, { - name: 'Aunt Jane', - children: [{ - name: 'Cousin Kate', - value: 4, - itemStyle: { - normal: { - color: 'blue' - } - } - }] - }, { - name: 'Father', - value: 10, - children: [{ - name: 'Me', - value: 5 - }, { - name: 'Brother Peter', - value: 1, - itemStyle: { - downplay: { - opacity: 0.1 - } - } - }] - }], + } + }, { + name: 'Cousin Ben', + value: 4 + }], + itemStyle: { + normal: { + color: '#660' + } + } + }, { + name: 'Aunt Jane', + children: [{ + name: 'Cousin Kate', + value: 4, itemStyle: { - downplay: { - opacity: 0.8 + normal: { + color: 'blue' } } + }] + }, { + name: 'Father', + value: 10, + children: [{ + name: 'Me', + value: 5 }, { - name: 'Grandpa\'s friend Mike', - children: [{ - name: 'Uncle Dan', - children: [{ - name: 'Cousin Lucy', - value: 3 - }, { - name: 'Cousin Luck', - value: 4 - }] - }] + name: 'Brother Peter', + value: 1 + }], + itemStyle: { + downplay: { + opacity: 0.1 + } + } + }], + itemStyle: { + downplay: { + opacity: 0.8 + } + } + }, { + name: 'Grandpa\'s friend Mike', + children: [{ + name: 'Uncle Dan', + children: [{ + name: 'Cousin Lucy', + value: 3 }, { - name: 'Grandpa\'s friend Nancy', - children: [{ - name: 'Uncle Dan', - children: [{ - name: 'Cousin Lucy', - value: 1 - }, { - name: 'Cousin Luck', - value: 2 - }] - }] + name: 'Cousin Luck', + value: 4 }] + }] + }, { + name: 'Grandpa\'s friend Nancy', + children: [{ + name: 'Uncle Dan', + children: [{ + name: 'Cousin Lucy', + value: 1 + }, { + name: 'Cousin Luck', + value: 2 + }] + }] + }]; + + chart.setOption({ + series: { + type: 'sunburst', + // highlightPolicy: 'ancestor', + data: data } }); + setTimeout(function () { + data.push({ + name: 'Stranger', + children: [{ + name: 'S1', + value: 4 + }, { + name: 'S2', + value: 1 + }] + }); + chart.setOption({ + series: { + data: data + } + }); + }, 3000); + + setTimeout(function () { + data.splice(1, 1); + data[0].value = 32; + chart.setOption({ + series: { + data: data + } + }); + }, 6000); + });