节点的徽章位置
badge position for nodes
我正在尝试为我的 cytoscape.js 节点添加徽章。徽章是 HTML 元素。我正在使用 bootstrap badges
这是带有徽章的元素。 (徽章的颜色无关紧要)
当我缩小时,徽章的位置设置不正确。他们 向下 并且 向右 一点。这是为什么?
这是我设置位置的代码。我只是徽章到节点的左上角。但是我删除了 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})`;
我个人更喜欢使用 cytoscape.js resources/extensions 的解决方案,即 popper.js 扩展。
据我了解你的问题,你以某种方式将 bootstrap 元素添加到 cytoscape.js(你没有指定这个,所以我不得不猜测)。
通常情况下,粘性爆米花 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>
此代码片段会切断一些容器,因此请在您的应用程序中尝试此操作以获得更好的结果,并查看使用的扩展 here
问题源于CSSscale
。当我缩放元素时,元素的中心点保持不变。下面的示例显示了我的意思
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})`;
我正在尝试为我的 cytoscape.js 节点添加徽章。徽章是 HTML 元素。我正在使用 bootstrap badges
这是带有徽章的元素。 (徽章的颜色无关紧要)
当我缩小时,徽章的位置设置不正确。他们 向下 并且 向右 一点。这是为什么?
这是我设置位置的代码。我只是徽章到节点的左上角。但是我删除了 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})`;
我个人更喜欢使用 cytoscape.js resources/extensions 的解决方案,即 popper.js 扩展。
据我了解你的问题,你以某种方式将 bootstrap 元素添加到 cytoscape.js(你没有指定这个,所以我不得不猜测)。
通常情况下,粘性爆米花 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>
此代码片段会切断一些容器,因此请在您的应用程序中尝试此操作以获得更好的结果,并查看使用的扩展 here
问题源于CSSscale
。当我缩放元素时,元素的中心点保持不变。下面的示例显示了我的意思
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})`;