javascript - Chrome svg 渲染问题 - d3 - 折线

标签 javascript google-chrome d3.js svg

我在渲染带有折线的 d3 svg 图形时遇到问题。它确实适用于 chrome 版本 70.0.3538.67(官方构建)(64 位),但不适用于我当前的版本 78.0.3904.108(官方构建)(64 位)。我使用的是 d3 版本 v5.9.2。

当我删除连接我的 d3 渲染外来对象的多段线时,问题不会发生。

Chrome SVG d3 rendering issues

“阴影”根据我移动/缩放图片的方式移动,有时它们都消失了,但最常显示一些阴影。

我读到虚线可能会导致这种情况,但即使折线是正常的,我也有同样的问题。

我用于渲染 SVG 图形的代码如下所示:

// Function to generate entire d3 tree structure
function graphFoundObjects(response) {
    currentFlowchartView = "graphMode";
    var graphWidth = jQuery("#outputWrapperFlowchart").width();
    var graphHeight = jQuery("#outputWrapperFlowchart").height();

    var nodeWidth = 320;
    var nodeHeight = 90;

    var outputContainerFlowchart = createOutputContainerFlowchart("outputContainerFlowchartChart");
    appendElementToDom("outputWrapperFlowchart", outputContainerFlowchart);

    var graphWrapper = jQuery("#outputContainerFlowchartChart").append("<svg id='graphWrapper'></svg>");
    var graphSvg = d3.select("#graphWrapper").attr("width", graphWidth).attr("height", graphHeight);

    var simulation = d3.forceSimulation(response.nodes)
        .force("charge", d3.forceManyBody().strength(-78000))
        .force("center", d3.forceCenter(graphWidth / 2, graphHeight / 2))
        .force("link", d3.forceLink(response.links).id(function(d) {return d.uuid; }).distance(250).strength(1))
        .force("x", d3.forceX(graphWidth / 2).strength(1))
        .force("y", d3.forceY(graphHeight / 2).strength(1))
        .stop();

    // Fix setting instead so you can choose if you want to center root node by calling the function
    response.nodes[0].firstNode = true;
    function centerFirstNode() {
        graph.nodes[0].fixed = true;
        graph.nodes[0].fx = width / 2;
        graph.nodes[0].fy = height / 2;
    }

    d3.timeout(function() {
        for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
            simulation.tick();
        }

        var g = graphSvg.append("g")
                .attr("class", "everything");

        var arrow = g.append("defs").append("marker")
            .attr("id", "arrow")
            .attr("viewBox", "0 -5 10 10")
            .attr("refX", 0)
            .attr("refY", 0)
            .attr("markerWidth", 7)
            .attr("markerHeight", 7)
            .attr("orient", "auto")
            .attr("fill", "#7e7878")
            .append("svg:path")
            .attr("d", "M0,-5L10,0L0,5");


        var links = g.append("g")
            .attr("stroke", "#ebebeb")
            .attr("stroke-width", 2)
            .selectAll("polyline")
            .data(response.links)
            .enter().append("polyline")
            .attr("points", function(d) {
                return [
                    d.source.x, d.source.y,
                    d.source.x/2+d.target.x/2, d.source.y/2+d.target.y/2,
                    d.target.x, d.target.y
                ].join(',');
            })
            .style("marker-mid", "url(#arrow)");

        var nodes = g.selectAll("foreignObject")
            .data(response.nodes)
            .enter()
            .append("foreignObject")
            .attr("x", function(d) {
                return d.x - nodeWidth / 2;
            })
            .attr("y", function(d) {
                return d.y - nodeHeight / 2;
            })
            .attr("width", nodeWidth)
            .attr("height", nodeHeight)
            .attr("class", function(d) {
                return ("graphNode "+d.group)
            })
            .style("background-color", function(d) {
                return "#fffefe";
            })
            .append("xhtml:div")
            .attr("class", function(d) {
                if (d.firstNode !== undefined) {
                    return "graphNodeDiv graphFirstNode";
                } else {
                    return "graphNodeDiv";
                }
            })
            .html(function(d) {
                var nodeHtml = createNodeElement(d);
                var firstNodeClass = "";
                return nodeHtml.outerHTML;
            })
            .on("click", function(d) {
                renderPopupWindow(d, "#outputWrapperFlowchart");
            })
            .append("img")
                .attr("class", "optionsImg")
                .attr("src","/images/options-squares.svg")
                .on("click", function(d) {
                    currentTooltipObject = d;
                    renderTooltipDiv();
                });

        // Define the div for the tooltip
        var toolTip = d3.select("#outputWrapperFlowchart").append("div")
            .attr("class", "tooltip")
            .attr("id", "tooltip")
            .style("display", "none")
            .style("opacity", 1);

        // Add drag capabilities
        var drag_handler = d3.drag()
            .on("start", drag_start)
            .on("drag", drag_drag)
            .on("end", drag_end);

        drag_handler(nodes);

        // Add zoom capabilities
        var zoom_handler = d3.zoom()
                .on("zoom", zoom_actions);
        zoom_handler(graphSvg);

        // Drag functions
        function drag_start(d) {
            if (!d3.event.active) simulation.alphaTarget(0.3).restart();
                d.fx = d.x;
                d.fy = d.y;
        }

        // Make sure you can't drag the circle outside the box
        function drag_drag(d) {
            d.fx = d3.event.x;
            d.fy = d3.event.y;
        }

        function drag_end(d) {
            if (!d3.event.active) simulation.alphaTarget(0);
                d.fx = null;
                d.fy = null;
            }

        //Zoom functions
        function zoom_actions(){
            g.attr("transform", d3.event.transform)
        }

        function renderTooltipDiv() {
            event.stopPropagation();
            toolTip.transition()
                .duration(200)
                .style("opacity", .9);
            toolTip
                .style("left", (d3.event.pageX) + "px")
                .style("top", (d3.event.pageY - 28) + "px");
            jQuery(".tooltip").empty();
            toolTip.append("div").attr("class", "optionsActionWrapper").attr("id", "optionActionWrapperRedraw").append("div").attr("class", "optionText").text("Redraw");
            toolTip.append("div").attr("class", "optionsActionWrapper").attr("id", "optionActionWrapperModify").append("div").attr("class", "optionText").text("Modify");
            toolTip.append("div").attr("class", "optionsActionWrapper").attr("id", "optionActionWrapperRemove").append("div").attr("class", "optionText").text("Remove");
            jQuery("#optionActionWrapperRedraw").prepend("<img class=\"optionsIcon\" src=\"/images/redraw-icon.svg\">");
            jQuery("#optionActionWrapperModify").prepend("<img class=\"optionsIcon\" src=\"/images/modify-icon.svg\">");
            jQuery("#optionActionWrapperRemove").prepend("<img class=\"optionsIcon\" src=\"/images/remove-icon.svg\">");
            tooltipState = true;
            jQuery(".tooltip").css("display", "block");
        }
    });
}

我是不是做错了什么,或者我能以某种方式绕过这个(最有可能的)错误吗?

最佳答案

该错误是由 chrome 硬件加速导致的。当我禁用该功能时,它工作正常。 但是,这不是个好主意。即使我的案例不使用 d3 forceSimulation,您也可以尝试为该行提供值为“透明”的“填充”样式。它适用于我的情况。

关于javascript - Chrome svg 渲染问题 - d3 - 折线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58997729/

相关文章:

javascript - Angular 订阅并绑定(bind)到发出的事件

Javascript - 类型检查的正确方法

javascript - 尝试让一个新的JS类继承原类的方法

css - Chrome 在打印的透明 png/gif 中添加灰色轮廓

javascript - 访问 chrome/firefox 图像缓存

javascript - 奇怪的网格线行为

javascript - Jquery 复选框更改事件未触发

google-chrome - 如何手动触发后台同步(用于测试)?

d3.js - D3 中基于圆弧的文本对齐

javascript - 从 JSON 调用和重绘更新包布局的数据