0

我正在尝试将徽章添加到我的 cytoscape.js 节点。徽章是 HTML 元素。我正在使用引导徽章

这是带有徽章的元素。(徽章的颜色无关紧要) 在此处输入图像描述

当我缩小时,徽章的位置设置不正确。他们向下向右一点。这是为什么?

徽章下降了一点

这是我设置位置的代码。我只是将徽章放在节点的左上角。但我删除了 HTML 元素的宽度,使其看起来像在节点内部

let z1 = cy.zoom() / 2; // badges look too big with normal size so I downscale them
// e is cytoscape.js element, a node
const p = e.renderedPosition();
const eW = e.renderedWidth() / 2;
const eH = e.renderedHeight() / 2;
// div is an HTML element which is the badge
const w = div.clientWidth;
div.style.transform = `translate(${p.x + eW - w * z1}px, ${p.y - eH}px) scale(${z1})`;
4

2 回答 2

1

我个人更喜欢使用 cytoscape.js 资源/扩展的解决方案,即 popper.js 扩展。

据我了解您的问题,您以某种方式将引导元素添加到 cytoscape.js(您没有指定这一点,所以我不得不猜测)。

通常,粘性 popper div 可以解决这个问题:

var cy = (window.cy = cytoscape({
  container: document.getElementById("cy"),

  style: [{
      selector: "node",
      css: {
        content: "data(id)",
        "text-valign": "center",
        "text-halign": "center",
        height: "60px",
        width: "160px",
        shape: "round-rectangle"
      }
    },
    {
      selector: "edge",
      css: {
        "target-arrow-shape": "triangle"
      }
    }
  ],

  elements: {
    nodes: [{
        data: {
          id: "n0"
        }
      },
      {
        data: {
          id: "n1"
        }
      },
      {
        data: {
          id: "n2"
        }
      },
      {
        data: {
          id: "n3"
        }
      },
      {
        data: {
          id: "n4"
        }
      },
      {
        data: {
          id: "n5"
        }
      },
      {
        data: {
          id: "n6"
        }
      },
      {
        data: {
          id: "n7"
        }
      },
      {
        data: {
          id: "n8"
        }
      },
      {
        data: {
          id: "n9"
        }
      },
      {
        data: {
          id: "n10"
        }
      },
      {
        data: {
          id: "n11"
        }
      },
      {
        data: {
          id: "n12"
        }
      },
      {
        data: {
          id: "n13"
        }
      },
      {
        data: {
          id: "n14"
        }
      },
      {
        data: {
          id: "n15"
        }
      },
      {
        data: {
          id: "n16"
        }
      }
    ],
    edges: [{
        data: {
          source: "n0",
          target: "n1"
        }
      },
      {
        data: {
          source: "n1",
          target: "n2"
        }
      },
      {
        data: {
          source: "n1",
          target: "n3"
        }
      },
      {
        data: {
          source: "n4",
          target: "n5"
        }
      },
      {
        data: {
          source: "n4",
          target: "n6"
        }
      },
      {
        data: {
          source: "n6",
          target: "n7"
        }
      },
      {
        data: {
          source: "n6",
          target: "n8"
        }
      },
      {
        data: {
          source: "n8",
          target: "n9"
        }
      },
      {
        data: {
          source: "n8",
          target: "n10"
        }
      },
      {
        data: {
          source: "n11",
          target: "n12"
        }
      },
      {
        data: {
          source: "n12",
          target: "n13"
        }
      },
      {
        data: {
          source: "n13",
          target: "n14"
        }
      },
      {
        data: {
          source: "n13",
          target: "n15"
        }
      }
    ]
  },

  layout: {
    name: "dagre",
    padding: 5,
    rankSep: 100
  }
}));

var makeTippy = function(node, text) {
  var ref = node.popperRef();
  var dummyDomEle = document.createElement("div");

  var tip = tippy(dummyDomEle, {
    onCreate: function(instance) {
      instance.popperInstance.reference = ref;
    },
    lazy: false, // mandatory
    trigger: "manual", // mandatory

    // dom element inside the tippy:
    content: function() {
      var div = document.createElement("div");
      div.innerHTML = text;
      return div;
    },

    // your own preferences:
    arrow: false,
    placement: 'top-end',
    hideOnClick: false,
    multiple: true,
    sticky: true
  });

  return tip;
};

cy.ready(function() {
  cy.zoom(0.75);
  cy.center();
  cy.ready(function() {
    let nodes = cy.nodes();
    nodes.each(function(node) {
      let tippy = makeTippy(node, node.id());
      tippy.show();
    });
  });
});
body {
  font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
}

.tippy-popper {
  transition: none !important;
}
<html>

<head>
  <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
  <script src="https://unpkg.com/dagre@0.7.4/dist/dagre.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre@2.1.0/cytoscape-dagre.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/cytoscape-popper@1.0.6/cytoscape-popper.min.js"></script>
  <script src="https://unpkg.com/tippy.js@5.1.3/dist/tippy-bundle.iife.min.js"></script>
  <link rel="stylesheet" href="https://unpkg.com/tippy.js@5.1.3/dist/tippy.css" />
</head>

<body>
  <div id="cy"></div>
</body>

</html>

此代码段切断了一些容器,因此请在您的应用程序中尝试此操作以获得更好的结果并查看此处使用的扩展

于 2020-02-05T10:14:48.957 回答
0

问题源于 CSS scale。当我缩放元素时,元素的中心点保持不变。下面的示例显示了我的意思

div {
  position: absolute;
}
span {
  font-size: 64px;
}

.s1 {
  transform: scale(1);
  background: red;
}

.s2 {
  transform: scale(0.5);
  background: blue;
}
<div class="s1"><span>00</span></div>
<div class="s2"><span>00</span></div>

所以我必须考虑div. 下面的代码做到了

let z1 = this._g.cy.zoom() / 2;
const bb = e.renderedBoundingBox({ includeLabels: false, includeOverlays: false });
const w = div.clientWidth;
const h = div.clientHeight;
const deltaW4Scale = (1 - z1) * w / 2;
const deltaH4Scale = (1 - z1) * h / 2;
div.style.transform = `translate(${bb.x2 - deltaW4Scale - w * z1}px, ${bb.y1 - deltaH4Scale}px) scale(${z1})`;
于 2020-02-06T09:37:16.187 回答