相对位置在 Safari 11 Dagre-d3 svg 中不起作用

问题描述 投票:0回答:2

我正在尝试将 Html 标签放入 dagre-d3 SVG 图中,它在 Firefox 和 Chrome 中工作正常here,但在 Safari 中在自定义 HTML 中添加相对或绝对位置时似乎出现问题。

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);

这是我的CSS:

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;
}

HTML:

<div class="graph grid">
    <svg>
        <g />
    </svg>
</div>

镀铬输出:

Safari 中的问题:

谢谢

css d3.js svg safari dagre-d3
2个回答
0
投票

我在 Safari 上也遇到了类似的问题。我对图表内的 div 使用 bootstrap 。就我而言,div 和文本都错位了。以下是我的观察:

  • 我提供静态宽度和高度(通过 css)以与 chrome 兼容。当我删除 的 css 时,div 就位了。
  • 我还使用了引导程序“list-group”和“list-group-item”以及 ul 和 li 元素。当我删除类时,文本就在 div 内就位了。

所以我想,这与某些宽度或定位问题有关。不确定它对您的情况有何帮助,但您可能会得到一些想法。


0
投票

我也遇到了同样的问题,在GitHub上找不到相关内容。我猜可能是以下几个问题造成的。

  1. 纯粹的风格问题,但经过测试,发现不是这样的

  2. 由foreignObject标签引起,但我目前不确定

请问这个问题最后解决了吗,是怎么解决的

© www.soinside.com 2019 - 2024. All rights reserved.