Echarts关系图(Graph)能否获取到力矢量布局(force)后点(node)的[x, y]坐标点

该博客主要讨论了如何修改Echarts的GraphView渲染方法以获取力矢量布局的x,y坐标,并在原始数据中写入这些坐标。内容涉及Graph实例的坐标系统处理、符号和边的绘制、节点和边的比例缩放更新,以及拖拽交互的实现。同时,博客还介绍了焦点邻接节点的处理和布局动画的控制,对于理解Echarts图形图表的动态交互和布局优化具有指导意义。
摘要由CSDN通过智能技术生成

修改lib/chart/graph/GraphView的render方法,拿到了力矢量布局的x,y坐标。
通过Graphinstance.getOption()可以获取到x,y坐标。

import * as GraphViewInstance from 'echarts/lib/chart/graph/GraphView';
import graphic from "echarts/lib/util/graphic";
import adjustEdge from 'echarts/lib/chart/graph/adjustEdge';
const getNodeGlobalScale = require("echarts/lib/chart/graph/graphHelper").getNodeGlobalScale;
var FOCUS_ADJACENCY = '__focusNodeAdjacency';
var UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';

GraphViewInstance.prototype.render = function (seriesModel, ecModel, api) {
  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();
  /** 在原始数据里写入layout的x,y坐标 */
  if (data._rawData && data._rawData._data) {
    data._rawData._data.forEach(function(item, _index) {
      if (data._graphicEls[_index]) {
        if (data._rawData._data[_index] && typeof data._rawData._data[_index].x !== 'number') {
          data._rawData._data[_index].x = data._graphicEls[_index].position[0];
        }
        if (data._rawData._data[_index] && typeof data._rawData._data[_index].y !== 'number') {
          data._rawData._data[_index].y = data._graphicEls[_index].position[1];
        }
      }
    })
  }
  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 () {
        api.dispatchAction({
          type: 'focusNodeAdjacency',
          seriesId: seriesModel.id,
          dataIndex: el.dataIndex
        });
      });
      el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
        api.dispatchAction({
          type: 'unfocusNodeAdjacency',
          seriesId: seriesModel.id
        });
      });
    }
  }, 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 () {
        api.dispatchAction({
          type: 'focusNodeAdjacency',
          seriesId: seriesModel.id,
          edgeDataIndex: edge.dataIndex
        });
      });
      el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
        api.dispatchAction({
          type: 'unfocusNodeAdjacency',
          seriesId: seriesModel.id
        });
      });
    }
  });
  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;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值