【问题标题】:Chrome svg rendering issues - d3 - polylinesChrome svg 渲染问题 - d3 - 折线
【发布时间】:2020-03-18 17:33:46
【问题描述】:

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

当我删除连接我的 d3 渲染外物的折线时,不会出现此问题。

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

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

我用于渲染 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");
        }
    });
}

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

【问题讨论】:

  • 我可以确认我有同样的问题。遗憾的是我还没有找到绕过它的方法。

标签: javascript google-chrome d3.js svg


【解决方案1】:

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

【讨论】:

  • 你是个传奇!太感谢了。将 css 属性填充设置为透明可解决此问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多