javascript - Sunburst D3 文本问题

标签 javascript d3.js tooltip sunburst-diagram

我正在使用这个型号:http://www.jasondavies.com/coffee-wheel/ :

enter image description here

我制作了一个效果很好的旭日,除了当我放大或缩小时,有时它会改变当前节点。

当我查看工具提示时,我可以看到“区域”没有引用正确的元素,它会将我发送到这个错误的元素。我不知道那是从哪里来的。

enter image description here

name 应该是“LDG”,但是有一个小区域,其中引用了另一个元素。

loadSunburstTree: function() {
        var width = 960,
        height = width,
        radius = Math.min(width, height) / 2,
        padding = 5,
        duration = 1000;

        var x = d3.scale.linear().range([0, 2 * Math.PI]);

        var y = d3.scale.sqrt().range([0, radius]);

        var color = d3.scale.category20c();

        var path = null;
        var arc = null;
        var text = null;

        $.ajax({
            url: $("#path").val() + ".json",
            method: "GET",
            success: function(result) {

                var data = {
                         "name": "home",
                         "level" : "root",
                         "children": []
                    };

                [...] // filling the variable data here (data are correct),

                var svg = d3.select("#graph").append("svg")
                    .attr("width", width)
                    .attr("height", height + 50)
                    .datum(data)
                    .append("g")
                    .attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");

                var partition = d3.layout.partition()
                    .value(function(d) { return d.size; });

                arc = d3.svg.arc()
                    .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
                    .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
                    .innerRadius(function(d) { return Math.max(0, y(d.y)); })
                    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });

                path = svg.selectAll("path")
                    .data(partition.nodes)
                    .enter().append("path")
                    .attr("d", arc)
                    .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
                    .on("click", click);

                text = svg.selectAll("text").data(partition.nodes);
                text.enter().append("text")
                      .style("full-opacity", 1)
                      .style("fill", function(d) {
                        return brightness(d3.rgb(colour(d))) < 125 ? "#eee" : "#000";
                      })
                      .attr("text-anchor", function(d) {
                        return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
                      })
                      .attr("dy", ".2em")
                      .attr("transform", function(d) {
                        var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
                            rotate = angle;
                        return "rotate(" + rotate + ")translate(" + (y(d.y) + padding) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
                      })
                        .text(function(d) {
                            if( d.dx < .01){
                                  d3.select(this).style("display","none");
                              }
                              return d.depth ? d.name : "";
                        })
                      .on("click", click);
            }
        });

        function click(d) {
            path.transition()
            .duration(duration)
            .attrTween("d", arcTween(d));

            text.transition()
            .duration(duration)
            .attrTween("transform", function(d) {
              return function() {
                var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90;
                    var  rotate = angle;                    
                return "rotate(" + rotate + ")translate(" + (y(d.y) + padding) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
                                };
                        })
            .attrTween("text-anchor", function(d) {
                return function() {
                return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
                                };
                        })
            .style("fill-opacity", function(e) { return isParentOf(d, e) ? 1 : 1e-6; })
            .each("end", function(e) {  
                d3.select(this).style("display","");
                var st = e;
                    if (st.dx / d.dx < 0.01) {
                        d3.select(this).style("display","none");
                    } else {
                        d3.select(this).style("display","");
                    }
            });
        }

        d3.select(self.frameElement).style("height", height + "px");

        // Interpolate the scales!
        function arcTween(d) {
          var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
              yd = d3.interpolate(y.domain(), [d.y, 1]),
              yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
          return function(d, i) {
            return i
                ? function(t) { return arc(d); }
                : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
          };
        }

        function isParentOf(p, c) {
              if (p === c) return true;
              if (p.children) {
                return p.children.some(function(d) {
                  return isParentOf(d, c);
                });
              }
              return false;
            }

        function colour(d) {
              if (d.children) {
                // There is a maximum of two children!
                var colours = d.children.map(colour),
                    a = d3.hsl(colours[0]),
                    b = d3.hsl(colours[1]);
                // L*a*b* might be better here...
                return d3.hsl((a.h + b.h) / 2, a.s * 1.2, a.l / 1.2);
              }
              return d.colour || "#fff";
            }

        function brightness(rgb) {
              return rgb.r * .299 + rgb.g * .587 + rgb.b * .114;
            }
    }
};

PS:貌似demo也有这个问题,只是比较难注意到,因为没有工具提示。

PPS:可点击的元素是文本! (在大多数情况下)文本只有 opacity = 0 并且仍在 View 上。这就是问题所在。它们不得被正确隐藏。仍在努力。

最佳答案

问题就这样解决了。文本工具提示不再可见,也不再可单击: 只需编辑 function click(d) 的文本代码,如下所示:

        function click(d) {
            path.transition()
            .duration(duration)
            .attrTween("d", arcTween(d));

            text.transition()
            .duration(duration)
            .attrTween("transform", function(d) {
                return function() {
                    var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90;
                    var  rotate = angle;                    
                    return "rotate(" + rotate + ")translate(" + (y(d.y) + padding) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
                };
            })
            .attrTween("text-anchor", function(d) {
                return function() {
                    return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
                };
            })
//modified from here
            .style("fill-opacity", function(e) {
                if (isParentOf(d, e)) {
                    return 1;
                } else {
                    return 0;
                }
            })
            .each("end", function(e) {
                if (e.dx / d.dx < 0.01 || $(this).css("fill-opacity") == 0) {
                    d3.select(this).style("display","none");
                } else {
                    d3.select(this).style("display","");
                }
            });
//to here
        }

关于javascript - Sunburst D3 文本问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24079314/

相关文章:

javascript - 检查当前上下文是否是 jQuery 堆栈

javascript - d3 轴刻度未更新

javascript - 使用 D3.JS 而非纯 Javascript 查找数组数组的最小值和最大值

d3.js - 在这个 D3 示例中,点击事件是否会改变源 json?

reactjs - 尽管将 props 传播到该组件,但 Material UI 工具提示不会显示在自定义组件上

javascript - 带有 html 内容的工具提示出现在右侧,有工作代码,但它仅适用于 1 个提示,我希望它是动态的

javascript - 订阅推送通知时总是抛出注册失败错误

javascript - JS 显示 SWF 的 bytesLoaded

javascript - 将对象地址转换为字符串

javascript - 动态定位 Bootstrap 工具提示(用于动态生成的元素)