隐形边缘布局问题

时间:2018-03-19 13:03:56

标签: graphviz dot

我有一个带有许多边的密集点图和一个与几乎任何其他节点都有连接的节点。

例如:

import {
  Pipe,
  PipeTransform
} from '@angular/core';


@Pipe({
  name: 'orderBy',
  pure: false
})
export class OrderByConnectedPipe implements PipeTransform {

  value: string[] = [];

  private static _orderByComparator(a: any, b: any): number {

    if ((a === null || a === undefined) && (b === null || b === undefined)) {
      return 0;
    }

    if (a === null || a === undefined) {
      a = (isNaN(parseFloat(b)) || !isFinite(b)) ? '' : 0;
    }

    if (b === null || b === undefined) {
      b = (isNaN(parseFloat(a)) || !isFinite(a)) ? '' : 0;
    }

    if ((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))) {
      if (a.toLocaleLowerCase() < b.toLocaleLowerCase()) {
        return -1;
      }
      if (a.toLocaleLowerCase() > b.toLocaleLowerCase()) {
        return 1;
      }
    } else {
      if (parseFloat(a) < parseFloat(b)) {
        return -1;
      }
      if (parseFloat(a) > parseFloat(b)) {
        return 1;
      }
    }

    return 0;
  }

  transform(input: any, config: string = '+'): any {

    //invalid input given
    if (!input) return input;

    //make a copy of the input's reference
    this.value = [...input];
    let value = this.value;

    if (!Array.isArray(value)) {
      return value;
    }

    if (!Array.isArray(config) || (Array.isArray(config) && config.length == 1)) {
      let propertyToCheck: string = !Array.isArray(config) ? config : config[0];
      let desc = propertyToCheck.substr(0, 1) == '-';

      //Basic array
      if (!propertyToCheck || propertyToCheck == '-' || propertyToCheck == '+') {
        return !desc ? value.sort() : value.sort().reverse();
      } else {
        let property: string = propertyToCheck.substr(0, 1) == '+' || propertyToCheck.substr(0, 1) == '-' ?
          propertyToCheck.substr(1) :
          propertyToCheck;


        return value.sort(function(a: any, b: any) {
          let aValue = a[property];
          let bValue = b[property];

          let propertySplit = property.split('.');

          if (typeof aValue === 'undefined' && typeof bValue === 'undefined' && propertySplit.length > 1) {
            aValue = a;
            bValue = b;
            for (let j = 0; j < propertySplit.length; j++) {
              aValue = aValue[propertySplit[j]];
              bValue = bValue[propertySplit[j]];
            }
          }

          return !desc ?
            OrderByConnectedPipe._orderByComparator(aValue, bValue) :
            -OrderByConnectedPipe._orderByComparator(aValue, bValue);
        });
      }
    } else {
      //Loop over property of the array in order and sort
      return value.sort(function(a: any, b: any) {
        for (let i: number = 0; i < config.length; i++) {
          let desc = config[i].substr(0, 1) == '-';
          let property = config[i].substr(0, 1) == '+' || config[i].substr(0, 1) == '-' ?
            config[i].substr(1) :
            config[i];

          let aValue = a[property];
          let bValue = b[property];

          let propertySplit = property.split('.');

          if (typeof aValue === 'undefined' && typeof bValue === 'undefined' && propertySplit.length > 1) {
            aValue = a;
            bValue = b;
            for (let j = 0; j < propertySplit.length; j++) {
              aValue = aValue[propertySplit[j]];
              bValue = bValue[propertySplit[j]];
            }
          }

          let comparison = !desc ?
            OrderByConnectedPipe._orderByComparator(aValue, bValue) :
            -OrderByConnectedPipe._orderByComparator(aValue, bValue);

          //Don't return 0 yet in case of needing to sort by next property
          if (comparison != 0) {
            return comparison;
          }
        }

        return 0; //equal each other
      });
    }
  }
}

export let ORDERBY_PROVIDERS = [
  OrderByConnectedPipe
];

我想隐藏digraph TEST { rankdir=LR; node [shape=plaintext]; graph [compound=true]; A[label=<<table border="0" cellspacing="0" cellborder="1" > <tr><td >A</td></tr> <tr><td port='a1'>a1</td></tr> <tr><td port='a2'>a2</td></tr> </table>>]; B; C; D; E; F; G; H; I; A:a1:e->B:w; A:a1:e->C:w; A:a1:e->D:w; A:a1:e->E:w; A:a1:e->F:w; A:a1:e->G:w; A:a1:e->H:w; A:a1:e->I:w; A:a2:e->B:w; B:e->C:w; C:e->D:w; D:e->E:w; E:e->F:w; E:e->G:w; E:e->H:w; F:e->I:w G:e->I:w H:e->I:w } 个连接并添加某种跳转标签,以便为读者提供信息。

例如:

a1

将属性 A:a1:e->{a1_out[label="a1"]}; {a1_Bin[label="a1"]}->B:w; {a1_Cin[label="a1"]}->C:w; {a1_Din[label="a1"]}->D:w; {a1_Ein[label="a1"]}->E:w; {a1_Fin[label="a1"]}->F:w; {a1_Gin[label="a1"]}->G:w; {a1_Hin[label="a1"]}->H:w; {a1_Iin[label="a1"]}->I:w; 添加到[style=invis] - 连接只是不渲染它们,但保持布局与它们一样。结果是由于空间和其他地方的密集连接,节点和标签的位置看起来很奇怪。 完全删除连接确实会改变图形的语义和图形节点的等级(不是在这个示例中,而是在其他示例中)。

所以我正在寻找一种方法来提供a1信息,以正确计算一侧节点之间的所有依赖关系并建议它,而不是绘制渲染并在另一侧绘制这些连接。

1 个答案:

答案 0 :(得分:1)

清理此图中边缘的方法可能是使用

concentrate=true

根据documentation,这将

  

...将多个边缘合并到一个边缘并导致部分平行   边缘分享他们的部分路径