I m试图将Html标签放在Dagre-d3 SVG图表中,它正在做以下工作:herein> 和“ Chrome”,但在Safari增加相对或绝对立场时,似乎存在问题。
var ready = false;
var sourceActions = {
"A": { "type": "drop", "status": 0 },
"B": { "type": "rename", "status": 0 },
"C": { "type": "save", "status": 1 },
"D": { "type": "drop", "status": null },
"E": { "type": "set", "status": null },
"F": { "type": "drop", "status": null },
"X": { "type": "rename", "status": 2 },
"Y": { "type": "drop", "status": 2 },
"Z": { "type": "drop", "status": 1 },
"Filter": { "type": "drop", "status": 0 },
"And this one": { "type": "drop", "status": 2 },
};
var sourceEdges = [
{ "from": "A", "to": "B" },
{ "from": "B", "to": "C" },
{ "from": "C", "to": "D" },
{ "from": "E", "to": "F" },
{ "from": "X", "to": "Y" },
{ "from": "Y", "to": "Z" },
{ "from": "Z", "to": "C" },
];
var contextMenuItems = [
{ text: "Menu 1", id: "m1" },
{ text: "Menu 2", id: "m2" },
{ text: "Menu 3", id: "m3" },
{ text: "Menu 4", id: "m4" }
];
// Set up zoom support
var svg = d3.select("svg"),
inner = svg.select("g"),
zoom = d3.zoom().on("zoom", function () {
inner.attr("transform", d3.event.transform);
});
svg.call(zoom);
var render = new dagreD3.render();
// Left-to-right layout
var graph = new dagreD3.graphlib.Graph();
graph.setGraph({
nodesep: 70,
ranksep: 50,
rankdir: "LR",
marginx: 20,
marginy: 20
});
function init(isUpdate) {
ready = true;
update(sourceActions, sourceEdges);
initEvents(graph);
}
function update(actions, edges) {
if (!ready) {
return;
}
for (var key in actions) {
var action = actions[key];
graph.setNode(key, {
labelType: "html",
label: createNode(key, action),
rx: 0,
ry: 0,
padding: 0,
marginx: 10,
marginy: 10,
});
}
for (var i = 0; i < edges.length; i++) {
var edge = edges[i];
graph.setEdge(edge.from, edge.to, {
label: createEdgeLable(edge.from, edge.to),
width: 40,
labelType: "html",
arrowhead: "undirected"
// curve: d3.curveBasis
});
}
inner.call(render, graph);
// Zoom and scale to fit
var graphWidth = graph.graph().width + 80;
var graphHeight = graph.graph().height + 40;
var width = parseInt(svg.style("width").replace(/px/, ""));
var height = parseInt(svg.style("height").replace(/px/, ""));
var zoomScale = Math.min(width / graphWidth, height / graphHeight);
var translateX = (width / 2) - ((graphWidth * zoomScale) / 2)
var translateY = (height / 2) - ((graphHeight * zoomScale) / 2);
//var svgZoom = isUpdate ? svg.transition().duration(500) : svg;
var svgZoom = svg;
svgZoom.call(zoom.transform, d3.zoomIdentity.translate(translateX, translateY).scale(zoomScale));
}
function initEvents() {
var node = inner.selectAll("g.node");
if (node == undefined) {
alert( No node found );
return false;
}
node.on( click , function (id, index, nodes) {
log("id: " + id);
log("index: " + index);
log(nodes);
});
}
function createEdgeLable(from, to) {
return `<button class="edge-btn" data-from="${from}" data-to="${to}" onclick="onEdgeClick(this, event);">{ ${from} , ${to} } </button>`
}
function onEdgeClick(btn, ev) {
// Todo
}
function onPointClick(circularPoint, ev) {
// Todo
}
function createNode(key, action) {
if (key == undefined ) {
alert( Node id required )
return false;
}
var status = action.status || 0;
var cls = (
status === 0 ? "status-yellow" :
status === 1 ? "status-green" :
status === 2 ? "status-red" :
"status-yellow"
);
return `<div id= "${key}" class="rectangle">
<span class="status ${cls}"></span>
<span class="contents">
<span class="name">${action.type}</span>
<span class="queue">
<span class="counter">${key}</span>
</span>
</span>
<span class="plus right" onClick="onPointClick(this, event);"></span>
<span class="plus left" onclick="onPointClick(this, event);"></span>
</div>
`;
}
function log(data) {
console.log(data)
}
// Initial draw, once the DOM is ready
document.addEventListener("DOMContentLoaded", init);
我在这里是:
body {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 0;
padding: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
background: #1f1f1f;
}
.grid {
background-size: 10px 10px;
background-image: repeating-linear-gradient(0deg, #212121, #252525 1px, transparent 1px, transparent 10px),repeating-linear-gradient(-90deg, #252525, #1f1f1f 1px, transparent 1px, transparent 10px);
width: 100%;
position: absolute;
left: 0;
}
@-webkit-keyframes flash {
0%, 50%,100% {
opacity: 1;
}
25%, 75% {
opacity: 0.2;
}
}
@keyframes flash {
0%,50%,100% {
opacity: 1;
}
25%,75% {
opacity: 0.2;
}
}
.warn {
-webkit-animation-duration: 5s;
animation-duration: 5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
.graph {
width: 100%;
height: 100%;
}
svg {
width: 100%;
height: 100%;
overflow: hidden;
}
.graph text {
font-weight: 300;
font-size: 22px;
}
.status {
height: 100%;
width: 15px;
position: absolute;
left: 0;
background-color: #edc508;
}
.status-yellow {
background-color: #edc508;
}
.status-green {
background-color: #3ccc1a;
}
.status-red {
background-color: #fb5050;
}
.warn {
-webkit-animation-name: flash;
animation-name: flash;
}
.graph .name {
margin-top: 5px;
}
.graph .name text {
font-size: 28px;
}
.graph .edgeLabel text {
width: 50px;
fill: #fff;
font-size: 32px;
}
.graph .edgePath path {
stroke: #999;
stroke-width: 1.5px;
fill: #999;
}
.graph .node rect {
stroke-width: 1px;
stroke: #232323;
fill: #666;
}
.graph .node g .rectangle {
width: 250px;
height: 60px;
color: #fff;
background: #666;
display: table;
position: relative;
transition: all .3s ease;
}
.graph .node g .rectangle:hover, .graph .node g .rectangle.selected {
background: #ccc8c8;
cursor: pointer;
color: #333;
box-shadow: 1px 1px 15px #000;
}
.graph .node g .rectangle:hover .name, .graph .node g .rectangle:hover .queue {
color: #333;
}
.graph .node g .rectangle .contents {
width: 100%;
display: table-cell;
vertical-align: middle;
text-align: center;
color: #FFFFFF;
text-decoration: none;
}
.graph .node g .rectangle .plus {
color: #fff;
top: 50%;
position: absolute;
transform: translateY(-50%);
width: 20px;
height: 20px;
text-align: center;
background: #0e8ca9;
border-radius: 50%;
line-height: 20px;
border: 1px solid #037c98;
transition: all .3s ease;
}
.graph .node g .rectangle .plus::before {
content: "+";
position: absolute;
width: 20px;
height: 20px;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.graph .node g .rectangle .plus.left {
left: -10px;
}
.graph .node g .rectangle .plus.right {
right: -10px;
}
.graph .node g .rectangle .plus.left:hover {
background: #0e8ca9;
color: #eee;
border: 1px solid #0e8ca9;
box-shadow: 1px 1px 5px #010c15;
}
.graph .node g .rectangle .plus.right:hover {
background: #0e8ca9;
color: #eee;
border: 1px solid #0e8ca9;
box-shadow: 1px 1px 5px #010c15;
}
.graph .node g foreignObject {
overflow: visible !important;
}
.edge-btn {
background: #0e8ca9;
color: #fff;
border: 1px solid #0e8ca9;
border-radius: 3px;
padding: 3px 7px;
font-size: 12px;
cursor: pointer;
}
.edge-btn:hover {
background: #185b93;
color: #fff;
border: 1px solid #185b93;
}
.arrowheadClass {
display: none;
}
传真:
<div class="graph grid">
<svg>
<g />
</svg>
</div>
产出:
增 编