| /* |
| * 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/src/core/util'; |
| import ChartView from '../../view/Chart'; |
| import SunburstPiece from './SunburstPiece'; |
| import DataDiffer from '../../data/DataDiffer'; |
| var ROOT_TO_NODE_ACTION = 'sunburstRootToNode'; |
| var SunburstView = ChartView.extend({ |
| type: 'sunburst', |
| init: function () {}, |
| render: function (seriesModel, ecModel, api, payload) { |
| var that = this; |
| this.seriesModel = seriesModel; |
| this.api = api; |
| this.ecModel = ecModel; |
| var data = seriesModel.getData(); |
| var virtualRoot = data.tree.root; |
| var newRoot = seriesModel.getViewRoot(); |
| var group = this.group; |
| var renderLabelForZeroData = seriesModel.get('renderLabelForZeroData'); |
| var newChildren = []; |
| newRoot.eachNode(function (node) { |
| newChildren.push(node); |
| }); |
| var oldChildren = this._oldChildren || []; |
| dualTravel(newChildren, oldChildren); |
| renderRollUp(virtualRoot, newRoot); |
| |
| if (payload && payload.highlight && payload.highlight.piece) { |
| var highlightPolicy = seriesModel.getShallow('highlightPolicy'); |
| payload.highlight.piece.onEmphasis(highlightPolicy); |
| } else if (payload && payload.unhighlight) { |
| var piece = this.virtualPiece; |
| |
| if (!piece && virtualRoot.children.length) { |
| piece = virtualRoot.children[0].piece; |
| } |
| |
| if (piece) { |
| piece.onNormal(); |
| } |
| } |
| |
| this._initEvents(); |
| |
| this._oldChildren = newChildren; |
| |
| 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(); |
| } |
| |
| function processNode(newId, oldId) { |
| var newNode = newId == null ? null : newChildren[newId]; |
| var oldNode = oldId == null ? null : oldChildren[oldId]; |
| doRenderNode(newNode, oldNode); |
| } |
| } |
| |
| function doRenderNode(newNode, oldNode) { |
| if (!renderLabelForZeroData && newNode && !newNode.getValue()) { |
| // Not render data with value 0 |
| newNode = null; |
| } |
| |
| if (newNode !== virtualRoot && oldNode !== virtualRoot) { |
| if (oldNode && oldNode.piece) { |
| if (newNode) { |
| // Update |
| oldNode.piece.updateData(false, newNode, 'normal', seriesModel, ecModel); // For tooltip |
| |
| data.setItemGraphicEl(newNode.dataIndex, oldNode.piece); |
| } else { |
| // Remove |
| removeNode(oldNode); |
| } |
| } else if (newNode) { |
| // Add |
| var piece = new SunburstPiece(newNode, seriesModel, ecModel); |
| group.add(piece); // For tooltip |
| |
| data.setItemGraphicEl(newNode.dataIndex, piece); |
| } |
| } |
| } |
| |
| function removeNode(node) { |
| if (!node) { |
| return; |
| } |
| |
| if (node.piece) { |
| group.remove(node.piece); |
| node.piece = null; |
| } |
| } |
| |
| function renderRollUp(virtualRoot, viewRoot) { |
| if (viewRoot.depth > 0) { |
| // Render |
| if (that.virtualPiece) { |
| // Update |
| that.virtualPiece.updateData(false, virtualRoot, 'normal', seriesModel, ecModel); |
| } else { |
| // Add |
| that.virtualPiece = new SunburstPiece(virtualRoot, seriesModel, ecModel); |
| group.add(that.virtualPiece); |
| } |
| |
| if (viewRoot.piece._onclickEvent) { |
| viewRoot.piece.off('click', viewRoot.piece._onclickEvent); |
| } |
| |
| var event = function (e) { |
| that._rootToNode(viewRoot.parentNode); |
| }; |
| |
| viewRoot.piece._onclickEvent = event; |
| that.virtualPiece.on('click', event); |
| } else if (that.virtualPiece) { |
| // Remove |
| group.remove(that.virtualPiece); |
| that.virtualPiece = null; |
| } |
| } |
| }, |
| dispose: function () {}, |
| |
| /** |
| * @private |
| */ |
| _initEvents: function () { |
| var that = this; |
| |
| var event = function (e) { |
| var targetFound = false; |
| var viewRoot = that.seriesModel.getViewRoot(); |
| viewRoot.eachNode(function (node) { |
| if (!targetFound && node.piece && node.piece.childAt(0) === e.target) { |
| var nodeClick = node.getModel().get('nodeClick'); |
| |
| if (nodeClick === 'rootToNode') { |
| that._rootToNode(node); |
| } else if (nodeClick === 'link') { |
| var itemModel = node.getModel(); |
| var link = itemModel.get('link'); |
| |
| if (link) { |
| var linkTarget = itemModel.get('target', true) || '_blank'; |
| window.open(link, linkTarget); |
| } |
| } |
| |
| targetFound = true; |
| } |
| }); |
| }; |
| |
| if (this.group._onclickEvent) { |
| this.group.off('click', this.group._onclickEvent); |
| } |
| |
| this.group.on('click', event); |
| this.group._onclickEvent = event; |
| }, |
| |
| /** |
| * @private |
| */ |
| _rootToNode: function (node) { |
| if (node !== this.seriesModel.getViewRoot()) { |
| this.api.dispatchAction({ |
| type: ROOT_TO_NODE_ACTION, |
| from: this.uid, |
| seriesId: this.seriesModel.id, |
| targetNode: node |
| }); |
| } |
| }, |
| |
| /** |
| * @implement |
| */ |
| containPoint: function (point, seriesModel) { |
| var treeRoot = seriesModel.getData(); |
| var itemLayout = treeRoot.getItemLayout(0); |
| |
| if (itemLayout) { |
| var dx = point[0] - itemLayout.cx; |
| var dy = point[1] - itemLayout.cy; |
| var radius = Math.sqrt(dx * dx + dy * dy); |
| return radius <= itemLayout.r && radius >= itemLayout.r0; |
| } |
| } |
| }); |
| export default SunburstView; |