| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 | 
/** 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 echarts = require("../../echarts");var zrUtil = require("zrender/lib/core/util");var SymbolDraw = require("../helper/SymbolDraw");var LineDraw = require("../helper/LineDraw");var RoamController = require("../../component/helper/RoamController");var roamHelper = require("../../component/helper/roamHelper");var _cursorHelper = require("../../component/helper/cursorHelper");var onIrrelevantElement = _cursorHelper.onIrrelevantElement;var graphic = require("../../util/graphic");var adjustEdge = require("./adjustEdge");var _graphHelper = require("./graphHelper");var getNodeGlobalScale = _graphHelper.getNodeGlobalScale;/** 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 FOCUS_ADJACENCY = '__focusNodeAdjacency';var UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';var nodeOpacityPath = ['itemStyle', 'opacity'];var lineOpacityPath = ['lineStyle', 'opacity'];function getItemOpacity(item, opacityPath) {  var opacity = item.getVisual('opacity');  return opacity != null ? opacity : item.getModel().get(opacityPath);}function fadeOutItem(item, opacityPath, opacityRatio) {  var el = item.getGraphicEl();  var opacity = getItemOpacity(item, opacityPath);  if (opacityRatio != null) {    opacity == null && (opacity = 1);    opacity *= opacityRatio;  }  el.downplay && el.downplay();  el.traverse(function (child) {    if (!child.isGroup) {      var opct = child.lineLabelOriginalOpacity;      if (opct == null || opacityRatio != null) {        opct = opacity;      }      child.setStyle('opacity', opct);    }  });}function fadeInItem(item, opacityPath) {  var opacity = getItemOpacity(item, opacityPath);  var el = item.getGraphicEl(); // 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) {    !child.isGroup && child.setStyle('opacity', opacity);  });  el.highlight && el.highlight();}var _default = echarts.extendChartView({  type: 'graph',  init: function (ecModel, api) {    var symbolDraw = new SymbolDraw();    var lineDraw = new LineDraw();    var group = this.group;    this._controller = new RoamController(api.getZr());    this._controllerHost = {      target: group    };    group.add(symbolDraw.group);    group.add(lineDraw.group);    this._symbolDraw = symbolDraw;    this._lineDraw = lineDraw;    this._firstRender = true;  },  render: function (seriesModel, ecModel, api) {    var graphView = this;    var coordSys = seriesModel.coordinateSystem;    this._model = seriesModel;    var symbolDraw = this._symbolDraw;    var lineDraw = this._lineDraw;    var group = this.group;    if (coordSys.type === 'view') {      var groupNewProp = {        position: coordSys.position,        scale: coordSys.scale      };      if (this._firstRender) {        group.attr(groupNewProp);      } else {        graphic.updateProps(group, groupNewProp, seriesModel);      }    } // Fix edge contact point with node    adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));    var data = seriesModel.getData();    symbolDraw.updateData(data);    var edgeData = seriesModel.getEdgeData();    lineDraw.updateData(edgeData);    this._updateNodeAndLinkScale();    this._updateController(seriesModel, ecModel, api);    clearTimeout(this._layoutTimeout);    var forceLayout = seriesModel.forceLayout;    var layoutAnimation = seriesModel.get('force.layoutAnimation');    if (forceLayout) {      this._startForceLayoutIteration(forceLayout, layoutAnimation);    }    data.eachItemGraphicEl(function (el, idx) {      var itemModel = data.getItemModel(idx); // Update draggable      el.off('drag').off('dragend');      var draggable = itemModel.get('draggable');      if (draggable) {        el.on('drag', function () {          if (forceLayout) {            forceLayout.warmUp();            !this._layouting && this._startForceLayoutIteration(forceLayout, layoutAnimation);            forceLayout.setFixed(idx); // Write position back to layout            data.setItemLayout(idx, el.position);          }        }, this).on('dragend', function () {          if (forceLayout) {            forceLayout.setUnfixed(idx);          }        }, this);      }      el.setDraggable(draggable && forceLayout);      el[FOCUS_ADJACENCY] && el.off('mouseover', el[FOCUS_ADJACENCY]);      el[UNFOCUS_ADJACENCY] && el.off('mouseout', el[UNFOCUS_ADJACENCY]);      if (itemModel.get('focusNodeAdjacency')) {        el.on('mouseover', el[FOCUS_ADJACENCY] = function () {          graphView._clearTimer();          api.dispatchAction({            type: 'focusNodeAdjacency',            seriesId: seriesModel.id,            dataIndex: el.dataIndex          });        });        el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {          graphView._dispatchUnfocus(api);        });      }    }, this);    data.graph.eachEdge(function (edge) {      var el = edge.getGraphicEl();      el[FOCUS_ADJACENCY] && el.off('mouseover', el[FOCUS_ADJACENCY]);      el[UNFOCUS_ADJACENCY] && el.off('mouseout', el[UNFOCUS_ADJACENCY]);      if (edge.getModel().get('focusNodeAdjacency')) {        el.on('mouseover', el[FOCUS_ADJACENCY] = function () {          graphView._clearTimer();          api.dispatchAction({            type: 'focusNodeAdjacency',            seriesId: seriesModel.id,            edgeDataIndex: edge.dataIndex          });        });        el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {          graphView._dispatchUnfocus(api);        });      }    });    var circularRotateLabel = seriesModel.get('layout') === 'circular' && seriesModel.get('circular.rotateLabel');    var cx = data.getLayout('cx');    var cy = data.getLayout('cy');    data.eachItemGraphicEl(function (el, idx) {      var itemModel = data.getItemModel(idx);      var labelRotate = itemModel.get('label.rotate') || 0;      var symbolPath = el.getSymbolPath();      if (circularRotateLabel) {        var pos = data.getItemLayout(idx);        var rad = Math.atan2(pos[1] - cy, pos[0] - cx);        if (rad < 0) {          rad = Math.PI * 2 + rad;        }        var isLeft = pos[0] < cx;        if (isLeft) {          rad = rad - Math.PI;        }        var textPosition = isLeft ? 'left' : 'right';        graphic.modifyLabelStyle(symbolPath, {          textRotation: -rad,          textPosition: textPosition,          textOrigin: 'center'        }, {          textPosition: textPosition        });      } else {        graphic.modifyLabelStyle(symbolPath, {          textRotation: labelRotate *= Math.PI / 180        });      }    });    this._firstRender = false;  },  dispose: function () {    this._controller && this._controller.dispose();    this._controllerHost = {};    this._clearTimer();  },  _dispatchUnfocus: function (api, opt) {    var self = this;    this._clearTimer();    this._unfocusDelayTimer = setTimeout(function () {      self._unfocusDelayTimer = null;      api.dispatchAction({        type: 'unfocusNodeAdjacency',        seriesId: self._model.id      });    }, 500);  },  _clearTimer: function () {    if (this._unfocusDelayTimer) {      clearTimeout(this._unfocusDelayTimer);      this._unfocusDelayTimer = null;    }  },  focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {    var data = seriesModel.getData();    var graph = data.graph;    var dataIndex = payload.dataIndex;    var edgeDataIndex = payload.edgeDataIndex;    var node = graph.getNodeByIndex(dataIndex);    var edge = graph.getEdgeByIndex(edgeDataIndex);    if (!node && !edge) {      return;    }    graph.eachNode(function (node) {      fadeOutItem(node, nodeOpacityPath, 0.1);    });    graph.eachEdge(function (edge) {      fadeOutItem(edge, lineOpacityPath, 0.1);    });    if (node) {      fadeInItem(node, nodeOpacityPath);      zrUtil.each(node.edges, function (adjacentEdge) {        if (adjacentEdge.dataIndex < 0) {          return;        }        fadeInItem(adjacentEdge, lineOpacityPath);        fadeInItem(adjacentEdge.node1, nodeOpacityPath);        fadeInItem(adjacentEdge.node2, nodeOpacityPath);      });    }    if (edge) {      fadeInItem(edge, lineOpacityPath);      fadeInItem(edge.node1, nodeOpacityPath);      fadeInItem(edge.node2, nodeOpacityPath);    }  },  unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {    var graph = seriesModel.getData().graph;    graph.eachNode(function (node) {      fadeOutItem(node, nodeOpacityPath);    });    graph.eachEdge(function (edge) {      fadeOutItem(edge, lineOpacityPath);    });  },  _startForceLayoutIteration: function (forceLayout, layoutAnimation) {    var self = this;    (function step() {      forceLayout.step(function (stopped) {        self.updateLayout(self._model);        (self._layouting = !stopped) && (layoutAnimation ? self._layoutTimeout = setTimeout(step, 16) : step());      });    })();  },  _updateController: function (seriesModel, ecModel, api) {    var controller = this._controller;    var controllerHost = this._controllerHost;    var group = this.group;    controller.setPointerChecker(function (e, x, y) {      var rect = group.getBoundingRect();      rect.applyTransform(group.transform);      return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel);    });    if (seriesModel.coordinateSystem.type !== 'view') {      controller.disable();      return;    }    controller.enable(seriesModel.get('roam'));    controllerHost.zoomLimit = seriesModel.get('scaleLimit');    controllerHost.zoom = seriesModel.coordinateSystem.getZoom();    controller.off('pan').off('zoom').on('pan', function (e) {      roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);      api.dispatchAction({        seriesId: seriesModel.id,        type: 'graphRoam',        dx: e.dx,        dy: e.dy      });    }).on('zoom', function (e) {      roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);      api.dispatchAction({        seriesId: seriesModel.id,        type: 'graphRoam',        zoom: e.scale,        originX: e.originX,        originY: e.originY      });      this._updateNodeAndLinkScale();      adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));      this._lineDraw.updateLayout();    }, this);  },  _updateNodeAndLinkScale: function () {    var seriesModel = this._model;    var data = seriesModel.getData();    var nodeScale = getNodeGlobalScale(seriesModel);    var invScale = [nodeScale, nodeScale];    data.eachItemGraphicEl(function (el, idx) {      el.attr('scale', invScale);    });  },  updateLayout: function (seriesModel) {    adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));    this._symbolDraw.updateLayout();    this._lineDraw.updateLayout();  },  remove: function (ecModel, api) {    this._symbolDraw && this._symbolDraw.remove();    this._lineDraw && this._lineDraw.remove();  }});module.exports = _default;
 |