d3.js v4堆积条工具提示/悬停(使用修改后的d3-tip)偏移问题

时间:2018-04-22 21:24:45

标签: d3.js

我在尝试创建悬停效果的d3.js v4堆积条形图时遇到了一些麻烦

目标是在整个堆栈突出显示并在悬停时显示工具提示。我想我正在寻找获取矩形的位置坐标和大小来绘制整个堆栈

我正在使用这个经过修改的d3-tip库为v4提供工具提示 https://github.com/VACLab/d3-tip

这个问题的图片说了千言万语: http://nicholasmahoney.com/gj/ex.jpg - 在那里,我可以非常接近x位置,我可以通过使用x(d.fellow)和x.bandwith获得宽度,但不能找出y分量。我希望此示例中的黑条与堆叠条的位置和大小相同

EDIt:添加jsfiddle代码和数据,

这里是确切的代码: http://jsfiddle.net/nickmahoney/ddjbumrx/6/

<svg width="500" height="500">
    </svg>

<script>
        var svg = d3.select("svg"),
            margin = {
              top: 40,
              right: 20,
              bottom: 30,
              left: 40
                },
            width = +svg.attr("width") - margin.left - margin.right,
            height = +svg.attr("height") - margin.top - margin.bottom,
            g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

          var x = d3.scaleBand()
            .rangeRound([0, width])
            .paddingInner(0.05)
            .align(0.1);

          var y = d3.scaleLinear()
            .rangeRound([height, 0]);

          var z = d3.scaleOrdinal()
            .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);


          var data =  [ { "fellow": "demo", "primary": 1, "assistant": 1, "observer": 0, "instructor": 0 }, { "fellow": "alpha", "primary": 22, "assistant": 8, "observer": 0, "instructor": 0 }, { "fellow": "betta", "primary": 0, "assistant": 4, "observer": 0, "instructor": 0 }, { "fellow": "gamma", "primary": 4, "assistant": 2, "observer": 0, "instructor": 0 }, { "fellow": "donkey", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 },{ "fellow": "donkey", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 } , { "fellow": "eeee", "primary": 22, "assistant": 8, "observer": 0, "instructor": 0 }, { "fellow": "ffff", "primary": 0, "assistant": 4, "observer": 0, "instructor": 0 }, { "fellow": "gaggggmma", "primary": 4, "assistant": 2, "observer": 0, "instructor": 0 }, { "fellow": "aaaa", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 },{ "fellow": "ddddddefef", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 }];

          // fix pre-processing
          var keys = [];
          for (key in data[0]){
            if (key != "fellow")
              keys.push(key);}
          data.forEach(function(d){
            d.total = 0;
            keys.forEach(function(k){
              d.total += d[k];
                })
            });


        var tip = d3.tip()
          .attr('class', 'd3-tip')
          .offset([-10, 0])
          .html(function(d) {
            return "<strong>Name:</strong> <span style='color:red'>" + d.fellow + "<br><strong>Primary:</strong>" + d.primary + "</span>";
          })




        svg.call(tip);



        //data.sort(function(a, b) { return b.total - a.total; });
        x.domain(data.map(function(d) { return d.fellow; }));
        y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
        z.domain(keys);


        g.append("g")
            .selectAll("g")
            .data(d3.stack().keys(keys)(data))
            .enter().append("g")
            .attr("fill", function(d) { return z(d.key); })
            .selectAll("rect")
            .data(function(d) { return d; })
            .enter().append("rect")
            .attr("x", function(d) { return x(d.data.fellow); })
            .attr("y", function(d) { return y(d[1]); })
            .attr("height", function(d) { return y(d[0]) - y(d[1]); })
            .attr("width", x.bandwidth())
            ;

            //tooltip bars    
            svg.selectAll(".bar")
              .data(data)
              .enter().append("rect")
              .attr("class", "bar")
              .attr("x", function(d) { return  40+ x(d.fellow) ; })
              .attr("width", x.bandwidth())
              .attr("y", function(d) { return  y(d.primary) ;  })
              .attr("height", function(d) { return y(d.primary) ; })
              .on('mouseover', tip.show)
              .on('mouseout', tip.hide)





           g.append("g")
              .attr("class", "axis")
              .attr("transform", "translate(0," + height + ")")
              .call(d3.axisBottom(x))
                ;


          g.append("g")
              .attr("class", "axis")
              .call(d3.axisLeft(y).ticks(null, "s"))
              .append("text")
              .attr("x", 2)
              .attr("y", y(y.ticks().pop()) + 0.5)
              .attr("dy", "0.32em")
              .attr("fill", "#000")
              .attr("font-weight", "bold")
              .attr("text-anchor", "start")
                ;





            var legend = g.append("g")
                .attr("font-family", "sans-serif")
                .attr("font-size", 10)
                .attr("text-anchor", "end")
                .selectAll("g")
                .data(keys.slice().reverse())
                .enter().append("g")
                .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });


            legend.append("rect")
                .attr("x", width - 19)
                .attr("width", 19)
                .attr("height", 19)
                .attr("fill", z);

            legend.append("text")
                .attr("x", width - 24)
                .attr("y", 9.5)
                .attr("dy", "0.32em")
                .text(function(d) {return d;});
        </script>

1 个答案:

答案 0 :(得分:1)

这是你小提琴的一个分支:http://jsfiddle.net/s54tbyxb/

您已根据所需键计算total值。我只是使用该值来确定y组件和height

代码中的相关更改:

.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("x", function(d) { return x(d.fellow) ; })
.attr("width", x.bandwidth())
.attr("y", function(d) { 
  return  y(d.total) ;  
})
.attr("height", function(d) { return height-y(d.total) ; })

希望这有帮助。