Incubator-echarts: 关系图graph支持两个data节点之间多条link,每个link代表一种关系,并可以筛选?

Created on 10 Oct 2017  ·  29Comments  ·  Source: apache/incubator-echarts

关系图graph支持两个data节点之间多条link,每个link代表一种关系,并可以筛选?
如两个人A、B:
A是B的同学
A是B的男朋友
A是B的老乡
A是B的。。。。

每一种关系用一条线相连,这样A和B之间应该有多条线。

并且可以通过同学、老乡这些条件筛选。

这个不知道怎么实现?

enhancement high graph

Most helpful comment

  • 使用 @HowToMeetYou 的方法可以解决问题,但是每次安装或者更新依赖后都需要手动更改源码,在持续集成环境中也不太好操作,这里附上一个重写 addEdge 的方法,具体操作参加下面代码:
import Graph from 'echarts/lib/data/Graph'
import echarts from 'echarts'

const Edge = Graph.Edge
const Node = Graph.Node

function generateNodeKey(id) {
  return '_EC_' + id;
}

Graph.prototype.addEdge = function (n1, n2, dataIndex) {
  var nodesMap = this._nodesMap;
  var edgesMap = this._edgesMap; // PNEDING

  if (typeof n1 === 'number') {
    n1 = this.nodes[n1];
  }

  if (typeof n2 === 'number') {
    n2 = this.nodes[n2];
  }

  if (!Node.isInstance(n1)) {
    n1 = nodesMap[generateNodeKey(n1)];
  }

  if (!Node.isInstance(n2)) {
    n2 = nodesMap[generateNodeKey(n2)];
  }

  if (!n1 || !n2) {
    return;
  }

  var key = n1.id + '-' + n2.id; // PENDING

  // if (edgesMap[key]) {
  //   return;
  // }

  var edge = new Edge(n1, n2, dataIndex);
  edge.hostGraph = this;

  if (this._directed) {
    n1.outEdges.push(edge);
    n2.inEdges.push(edge);
  }

  n1.edges.push(edge);

  if (n1 !== n2) {
    n2.edges.push(edge);
  }

  this.edges.push(edge);
  edgesMap[key] = edge;
  return edge;
}

  • 此外,代码中曲度使用随机可能导致图形不是很好看,这里附上一个曲度优先生成的列表,使用方法如下:
/**
 * 生成边曲度优先使用列表
 * @return  [0.2, -0.2, 0.4, -0.4, 0.6, -0.6, 0.8, -0.8, 1, -1, 0.1, -0.1, 0.3, -0.3, 0.5, -0.5, 0.7, -0.7, 0.9, -0.9]
 */
const CURVENESS_LIST = Array.from({ length: 20 })
.map((_, i) => (((i < 10 ? i + 2 : i - 9) - (i % 2)) / 10) * (i % 2 ? -1 : 1))

// 1. 已存在的边的列表
const data = []
// 2. 预期生成的优化曲度后的列表
const echartLinks = []

data.forEach(link => {
    // 3. 查询已优化的列表中,已存在的两个顶点相同的边
    const sameLink = echartLinks.filter(
        item =>
        item.source === link.source &&
        item.target === link.target
    )

    // 4. 优化曲度
    link.lineStyle.normal.curveness = CURVENESS_LIST[sameLink.length] || Math.random()

    echartLinks.push(link)
})

优化前:curveness: Math.random()
image

优化后:curveness: CURVENESS_LIST[sameLink.length] || Math.random()
image

All 29 comments

我有同样的需求。

同样需求,求解答

是目前还不支持吧?

我也是这个需求,我想实在找不到解决的只能修改源码了 专门为这个做一部分

@BerQin B 欢迎提 PR 啊!

@Ovilia 是不是可以这么做:
官方目前不支持 相同节点多条线, 但支持不同节点放在同一位置上~~
所以一条线就在相同位置上增加一个节点?

@wangcongyi @Ovilia 其实相同的 source 和 target点被过滤掉了,他在判断线ID生成上有些问题,只判断了线的目标点和出发点,其实还有一个因素决定了线的唯一性,就是value所以可以把生成线的那部分代码修改一下就行,如果在深入的修改需要判断线的偏移量那部分如果多先线的偏移量自动给加上,不过也可以让用户自己去设置curveness线的这个属性!我项目用就修改了这部分 没有在深入的研究

好像是 276 和 280部分

好像是 276 和 280部分

大神可以把具体修改的代码贴出来吗
我将graphProto.addEdge中
if (edgesMap[key]) {
return;
}
中的return注掉。
但是没起作用

请问 你们这个问题解决了吗?

修改源码且将关系连线改成曲线,修改代码稍后贴上

请问 你们这个问题解决了吗?
1.修改源码
nodemodules-echarts-lib-data-Graph.js中graphProto.addEdge:
if (edgesMap[key]) {
return;
}
return注释掉
2.代码中曲度改用随机
curveness: Math.random()

谢谢 我尝试一下

1.修改源码
nodemodules-echarts-lib-data-Graph.js中graphProto.addEdge:
if (edgesMap[key]) {
return;
}
return注释掉
2.代码中曲度改用随机
curveness: Math.random()

用上述方法好像还是没有效果, 另外改node-modules里的方法还是不太方便,以后版本迭代了针对源码的这个改动肯定就忘记了。有没有在业务代码中实现这个效果的方法

上述方法有效了,是我第二步没做对

有同样需求
19 年了,这需求貌似还没办法解决~

顶一下,有同样需求。希望能够有这个功能。

上述方法有效了,是我第二步没做对

请问下注释后,第二步改成随机曲度没有用是怎么回事?

上述方法有效了,是我第二步没做对

请问下注释后,第二步改成随机曲度没有用是怎么回事?

我是注释加了,没效果,随机曲度没问题,echart是不是最多两条,还是只能显示一样的数据
image

  • 使用 @HowToMeetYou 的方法可以解决问题,但是每次安装或者更新依赖后都需要手动更改源码,在持续集成环境中也不太好操作,这里附上一个重写 addEdge 的方法,具体操作参加下面代码:
import Graph from 'echarts/lib/data/Graph'
import echarts from 'echarts'

const Edge = Graph.Edge
const Node = Graph.Node

function generateNodeKey(id) {
  return '_EC_' + id;
}

Graph.prototype.addEdge = function (n1, n2, dataIndex) {
  var nodesMap = this._nodesMap;
  var edgesMap = this._edgesMap; // PNEDING

  if (typeof n1 === 'number') {
    n1 = this.nodes[n1];
  }

  if (typeof n2 === 'number') {
    n2 = this.nodes[n2];
  }

  if (!Node.isInstance(n1)) {
    n1 = nodesMap[generateNodeKey(n1)];
  }

  if (!Node.isInstance(n2)) {
    n2 = nodesMap[generateNodeKey(n2)];
  }

  if (!n1 || !n2) {
    return;
  }

  var key = n1.id + '-' + n2.id; // PENDING

  // if (edgesMap[key]) {
  //   return;
  // }

  var edge = new Edge(n1, n2, dataIndex);
  edge.hostGraph = this;

  if (this._directed) {
    n1.outEdges.push(edge);
    n2.inEdges.push(edge);
  }

  n1.edges.push(edge);

  if (n1 !== n2) {
    n2.edges.push(edge);
  }

  this.edges.push(edge);
  edgesMap[key] = edge;
  return edge;
}

  • 此外,代码中曲度使用随机可能导致图形不是很好看,这里附上一个曲度优先生成的列表,使用方法如下:
/**
 * 生成边曲度优先使用列表
 * @return  [0.2, -0.2, 0.4, -0.4, 0.6, -0.6, 0.8, -0.8, 1, -1, 0.1, -0.1, 0.3, -0.3, 0.5, -0.5, 0.7, -0.7, 0.9, -0.9]
 */
const CURVENESS_LIST = Array.from({ length: 20 })
.map((_, i) => (((i < 10 ? i + 2 : i - 9) - (i % 2)) / 10) * (i % 2 ? -1 : 1))

// 1. 已存在的边的列表
const data = []
// 2. 预期生成的优化曲度后的列表
const echartLinks = []

data.forEach(link => {
    // 3. 查询已优化的列表中,已存在的两个顶点相同的边
    const sameLink = echartLinks.filter(
        item =>
        item.source === link.source &&
        item.target === link.target
    )

    // 4. 优化曲度
    link.lineStyle.normal.curveness = CURVENESS_LIST[sameLink.length] || Math.random()

    echartLinks.push(link)
})

优化前:curveness: Math.random()
image

优化后:curveness: CURVENESS_LIST[sameLink.length] || Math.random()
image

请问这个 issue 现在遗留的具体需求是什么?如果有的话可以优先支持

@Ovilia 我觉得主要的一点是: 两个节点间同方向的连线应该允许多于一条的连线。现在的版本只允许一条连线。打个比方,从北京(节点1)到上海(节点2)有两条路线可以走,现在的版本只能显示其中的一条路线。
如果新版本允许一条以上相同方向的连线的话,还需有一定的算法保证这多条连线不重合(有不同的curveness)。

注释掉return后,我的实验结果和topvis一致,多条显示线是重合的,但是category值是叠加在一起的。是否内部可以实现算法根据category值自适应不一样的curveness;注;将curveness改成随机,其也是重叠的,并没有因为category值不同而产生两个不同曲度的线。

@singlelonghair 非常欢迎 pull request,愿意尝试一下吗?

我在使用中发现一个新问题,发现同一个节点不能被多次target,请问这个现在有解决办法没?

pull request可以的。

11260

我在使用中发现一个新问题,发现同一个节点不能被多次target,请问这个现在有解决办法没?

我这可以指向多个target。版本:echarts 4.6.0 上面解答的注释return的方案也行的通,random修改曲率也行得通。
感觉是echarts的bug啊

mark 两点之间 支持多条links

Was this page helpful?
0 / 5 - 0 ratings