当鼠标悬停在d3中的图例上时,高亮堆叠条形图中的相应图层 [英] Hightlight the respective layer in stacked Bar chart when mouseover on legend in d3

查看:276
本文介绍了当鼠标悬停在d3中的图例上时,高亮堆叠条形图中的相应图层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经完成了一个堆叠的条形图现在我扩展图表功能,当鼠标悬停在图例上各个条应该突出。



我面临的问题是鼠标悬停事件只在最后一个图例上工作,但突出显示图表中的每个rect图层。



问题如下图所示此图片是当鼠标悬停在D_Lines图例矩形



我的代码部分是

  var svg = d3.select(body)
.append(svg)
.attr(width,width + margin.left + margin.right)
.attr(height,height + margin.top + margin.bottom)
.append(g)
.attr(transform,translate +,+ margin.top +));
var fData =

[{orders:A,Total_Orders:76,A_Lines:123,B_Lines:0,C_Lines:0, D_Lines:0,Total_Lines:123,Total_Units:3267},
{orders:B,Total_Orders:68,A_Lines:0,B_Lines:107, C_Lines:0,D_Lines:0,Total_Lines:107,Total_Units:3115},
{orders:C,Total_Orders B_Lines:0,C_Lines:123,D_Lines:0,Total_Lines:123,Total_Units:3690},
{orders:D,Total_Orders:113, A_Lines:0,B_Lines:0,C_Lines:0,D_Lines:203,Total_Lines:203,Total_Units:7863},
{orders Total_Orders:62,A_Lines:70,B_Lines:76,C_Lines:0,D_Lines:0,Total_Lines:146,Total_Units:1739},
{orders :AC,Total_Orders:64,A_Lines:77,B_Lines:0,C_Lines:79,D_Lines:0,Total_Lines:156,Total_Units:2027},
{orders:AD,Total_Orders:100,A_Lines:127,B_Lines:0,C_Lines:0,D_Lines:144,Total_Lines:271,Total_Units :6467},
{orders:BC,Total_Orders:64,A_Lines:0,B_Lines:80,C_Lines:84,D_Lines:0, :164,Total_Units:1845},
{orders:BD,Total_Orders:91,A_Lines:0,B_Lines:108,C_Lines:0,D_Lines :135,Total_Lines:243,Total_Units:4061},
{orders:CD,Total_Orders:111,A_Lines:0,B_Lines:0,C_Lines :132,D_Lines:147,Total_Lines:279,Total_Units:5011},
{orders:ABC,Total_Orders:45,A_Lines:58,B_Lines :63,C_Lines:55,D_Lines:0,Total_Lines:176,Total_Units:1245},
{orders:ABD,Total_Orders:69,A_Lines :105,B_Lines:87,C_Lines:0,D_Lines:116,Total_Lines:308,Total_Units:4538},
{orders:ACD,Total_Orders :66,A_Lines:91,B_Lines:0,C_Lines:88,D_Lines:132,Total_Lines:311,Total_Units:4446},{
{orders BCD,Total_Orders:68,A_Lines:0,B_Lines:84,C_Lines:95,D_Lines:111,Total_Lines:290,Total_Units:4187},
_Lines:93,D_Lines:143,Total_Lines:422,Total_Units:B_Lines:96, 6331}]

var headers = [A_Lines,B_Lines,C_Lines,D_Lines];

var layers = d3.layout.stack()(headers.map(function(count){
return fData.map(function(d){
// alert d);
return {x:d.ORDER_TYPE,y:+ d [count]};
});
}));
// StackedBar Rectangle Max

var yStackMax = d3.max(layers,function(layer){return d3.max(layer,function(d){return d.y0 + dy; });});
//设置x,y和颜色
var xScale = d3.scale.ordinal()
.domain(layers [0] .map(function(d){return dx;}) )
.rangeRoundBands([25,width],.08);
colors = [#9999CC,#F7A35C,#99CC99,#CCCC99];
var y = d3.scale.linear()
.domain([0,yStackMax])
.range([height,0]);
var colorScale = d3.scale.ordinal()
.domain(headers)
.range(colors);

//定义和绘制轴
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(1)
.tickPadding(6)
.orient(bottom);

var yAxis = d3.svg.axis()
.scale(y)
.orient(left)
.tickFormat(d3.format .2s))



var layer = svg.selectAll(。layer)
.data(layers)
.enter .append(g)
.attr(class,layer)
.style(fill,function(d,i){return colorScale(i);}

var rect = layer.selectAll(rect)
.data(function(d){return d;})
.enter )
.attr(x,function(d){return xScale(dx);})
.attr(y,height)
.attr(width,xScale .rangeBand())
.attr(height,0)
.attr(class,function(d){
returnrect bordered+color- (d.value).substring(1);
});
debugger;
layer.selectAll(text.rect)
.data(function(layer){return layer;})
.enter()。append(text)
.attr(text-anchor,middle)
.attr(x,function(d){return xScale(dx)+ xScale.rangeBand()/ 2;})
。 attr(y,function(d){return y(dy + d.y0)-3;})
.text(function(d){return dy + d.y0;})
.style(fill,4682b4);

// ********** AXES ************

svg.append(g)
.attr(class,x axis)
.attr(transformation,translate(0,+ height +))
.call(xAxis)
.selectAll(text)。style(text-anchor,end)
.attr(dx,-.8em)
。 .15em)
.attr(transform,function(d){
returnrotate(-45)
});

svg.attr(class,x axis)
.append(text)
.attr(text-anchor,end)/ /这使得当变换应用到锚定时容易将文本居中
.attr(transform,translate(+(width / 2)+,+(height + 60)+ ))//居中在轴下
.text(Order Velocity Group);


svg.append(g)
.attr(class,y axis)
.attr(transform,translate 20,0)
.call(yAxis)
.append(text)
.attr(transform,rotate(-90))
。 attr({x:-75,y:-70})
.attr(dy,.75em)
.style(text-anchor )
.text(No。Of Lines);

// ********** LEGEND ************
var legend = svg.selectAll(。legend)
.data(headers.slice()。reverse())
.enter()。append(g)
.attr(class,legend)
.attr(transform,function(d,i){returntranslate(+ i *( - 100)+,+(height + 50)+);}

debugger;
legend.append(rect)
.attr(x,width - 18)
.attr(width,18)
.attr ,18)
.style(fill,function(d,i){return colors [i];})
.on(mouseover,function(d,i){
svg.selectAll(rect.color-+ colors [i] .substring(1))。style(stroke,blue);
})
.on ,function(d,i){
svg.selectAll(rect.color-+ colors [i] .substring(1))。style(stroke,white);
} );

legend.append(text)
.attr(x,width - 24)
.attr(y,9)
.attr (dy,.35em)
.style(text-anchor,end)
.text(function(d){return d;});


transitionStacked();
function transitionStacked(){

y.domain([0,yStackMax]);

rect.transition()
.duration(500)
.delay(function(d,i){return i * 10;})
.attr y函数(d){return y(d.y0 + dy);})
.attr(height,function(d){return y(d.y0) + dy);})
.transr(x,function(d){return xScale(dx);})
.attr(width,xScale .rangeBand());

};

}

任何人都可以帮助我克服这个问题。 p>

解决方案

您正在追加同一个类别: color-9999CC code> rect 元素,所以一旦你悬停最后一个有颜色的图例项:#9999CC all rect 元素。



要正确创建所需的类,可以在

我添加了一个颜色属性,值为项的颜色:

  var layers = d3 .layout.stack()(
headers.map(function(count){
return fData.map(function(d,i){
return {x:d.orders,y: + d [count],color:colorScale(count)};
/ * color = current headers item color * /

}
}));

然后在创建 rect 通过访问其颜色属性为每个元素添加如下:

  var rect = layer.selectAll(rect)
.data(function(d){return d;})
.....
.attr(class,function(d){
returnrect bordered +color-+ d.color.substring(1);
});



完整代码:



 

 < script src =https:// dns p> 


I have Done a stacked Bar chart now I am extending the Chart feature as when mouseover on the legend the Respective Bars should highlight.

The Problem I am facing is the mouseover event is working on the Last legend only but but highlighting the every rect layer in chart.

The Problem shown in below fig. This image is when I mouseover on D_Lines Legend Rect

My Code part is

var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var fData = 

[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},{
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}] 

var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];

        var layers = d3.layout.stack()(headers.map(function (count) {
            return fData.map(function (d) {
                // alert(d);
                return { x: d.ORDER_TYPE, y: +d[count] };
            });
        }));
        //StackedBar Rectangle Max

        var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
        // Set x, y and colors
        var xScale = d3.scale.ordinal()
     .domain(layers[0].map(function (d) { return d.x; }))
     .rangeRoundBands([25, width], .08);
        colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
        var y = d3.scale.linear()
            .domain([0, yStackMax])
            .range([height, 0]);
        var colorScale = d3.scale.ordinal()
    .domain(headers)
     .range(colors);

        // Define and draw axes
        var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .tickSize(1)
                    .tickPadding(6)
                    .orient("bottom");

        var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .tickFormat(d3.format(".2s"))



        var layer = svg.selectAll(".layer")
            .data(layers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function (d, i) { return colorScale(i); });

        var rect = layer.selectAll("rect")
            .data(function (d) { return d; })
            .enter().append("rect")
            .attr("x", function (d) { return xScale(d.x); })
            .attr("y", height)
            .attr("width", xScale.rangeBand())
            .attr("height", 0)
             .attr("class", function (d) {
                 return "rect bordered " + "color-" + colorScale(d.value).substring(1);
             });
        debugger;
        layer.selectAll("text.rect")
            .data(function (layer) { return layer; })
            .enter().append("text")
            .attr("text-anchor", "middle")
            .attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
            .attr("y", function (d) { return y(d.y + d.y0) - 3; })
            .text(function (d) { return d.y + d.y0; })
            .style("fill", "4682b4");

        //********** AXES ************

        svg.append("g")
             .attr("class", "x axis")
             .attr("transform", "translate(0," + height + ")")
             .call(xAxis)
             .selectAll("text").style("text-anchor", "end")
                 .attr("dx", "-.8em")
                 .attr("dy", ".15em")
                 .attr("transform", function (d) {
                     return "rotate(-45)"
                 });

        svg.attr("class", "x axis")
           .append("text")
           .attr("text-anchor", "end")  // this makes it easy to centre the text as the transform is applied to the anchor
           .attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")")  // centre below axis
           .text("Order Velocity Group");


        svg.append("g")
            .attr("class", "y axis")
            .attr("transform", "translate(20,0)")
            .call(yAxis)
          .append("text")
            .attr("transform", "rotate(-90)")
            .attr({ "x": -75, "y": -70 })
            .attr("dy", ".75em")
            .style("text-anchor", "end")
            .text("No. Of Lines");

        //********** LEGEND ************
        var legend = svg.selectAll(".legend")
                    .data(headers.slice().reverse())
                .enter().append("g")
                .attr("class", "legend")
                .attr("transform", function (d, i) { return "translate(" + i * (-100) + "," + (height + 50) + ")"; });

        debugger;
        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", function (d, i) { return colors[i]; })
        .on("mouseover", function (d, i) {
            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
        })
        .on("mouseout", function (d, i) {
            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
        });

        legend.append("text")
              .attr("x", width - 24)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "end")
              .text(function (d) { return d; });


        transitionStacked();
        function transitionStacked() {

            y.domain([0, yStackMax]);

            rect.transition()
                .duration(500)
                .delay(function (d, i) { return i * 10; })
                .attr("y", function (d) { return y(d.y0 + d.y); })
                .attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
              .transition()
                .attr("x", function (d) { return xScale(d.x); })
                .attr("width", xScale.rangeBand());

        };

   }

Can any one help me to overcome this problem.

解决方案

You are appending the same class : color-9999CC to all your rect elements, so once you hover the last legend item having color : #9999CC all rect element will be selected.

To create the required class properly, you can add the corresponding color info to each element in your layers object while creating it.

I added a color property that has as value the color of the corresponding headers item:

var layers = d3.layout.stack()(
     headers.map(function (count) {
            return fData.map(function (d,i) {
               return { x: d.orders, y: +d[count] , color:  colorScale(count)}; 
                                                   /*color = current headers item color */

            }); 
     }));

Then while creating your rect items you can add to each element a class by accessing its color property like this:

var rect = layer.selectAll("rect")
            .data(function (d) { return d; })
            .....
            .attr("class", function (d) {
                    return "rect bordered " + "color-" +d.color.substring(1);
            });

complete code:

var margin = {top:10, right: 10, bottom: 80, left: 50},
    width =960,
    height=650;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var fData = 

[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}] 

var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];
         var colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
          var colorScale = d3.scale.ordinal()
                             .domain(headers)
                             .range(colors);
        var layers = d3.layout.stack()(
           headers.map(function (count) {
            return fData.map(function (d,i) {
               return { x: d.orders, y: +d[count] , color:  colorScale(count)};
                
            }); 
        }));
        //StackedBar Rectangle Max

        var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
        // Set x, y and colors
        var xScale = d3.scale.ordinal()
     .domain(layers[0].map(function (d) { return d.x; }))
     .rangeRoundBands([25, width], .08);
       
        var y = d3.scale.linear()
            .domain([0, yStackMax])
            .range([height, 0]);
       
 
        // Define and draw axes
        var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .tickSize(1)
                    .tickPadding(6)
                    .orient("bottom");

        var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .tickFormat(d3.format(".2s"))



        var layer = svg.selectAll(".layer")
            .data(layers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function (d, i) { return colorScale(i); });
            

        var rect = layer.selectAll("rect")
            .data(function (d) { return d; })
            .enter().append("rect")
            .attr("x", function (d) { return xScale(d.x); })
            .attr("y", height)
            .attr("width", xScale.rangeBand())
            .attr("height", 0)
            .attr("class", function (d,i) {
                    return "rect bordered " + "color-" +d.color.substring(1);
            });
           
         
            
        layer.selectAll("text.rect")
            .data(function (layer) { return layer; })
            .enter().append("text")
            .attr("text-anchor", "middle")
            .attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
            .attr("y", function (d) { return y(d.y + d.y0) - 3; })
            .text(function (d) { return d.y + d.y0; })
            .style("fill", "4682b4");

        //********** AXES ************

        svg.append("g")
             .attr("class", "x axis")
             .attr("transform", "translate(0," + height + ")")
             .call(xAxis)
             .selectAll("text").style("text-anchor", "end")
                 .attr("dx", "-.8em")
                 .attr("dy", ".15em")
                 .attr("transform", function (d) {
                     return "rotate(-45)"
                 });

        svg.attr("class", "x axis")
           .append("text")
           .attr("text-anchor", "end")  // this makes it easy to centre the text as the transform is applied to the anchor
           .attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")")  // centre below axis
           .text("Order Velocity Group");


        svg.append("g")
            .attr("class", "y axis")
            .attr("transform", "translate(20,0)")
            .call(yAxis)
          .append("text")
            .attr("transform", "rotate(-90)")
            .attr({ "x": -75, "y": -70 })
            .attr("dy", ".75em")
            .style("text-anchor", "end")
            .text("No. Of Lines");

        //********** LEGEND ************
        var legend = svg.selectAll(".legend")
                    .data(headers)
                    .enter().append("g")
                    .attr("class", "legend")
                    .attr("transform", function (d, i) { return "translate(" +  (headers.length-(i+1))*-100 + "," + (height + 50) + ")"; });
        
        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", function (d, i) { return colors[i]; })
        .on("mouseover", function (d, i) {
        svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
        })
        .on("mouseout", function (d, i) {
            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
        });

        legend.append("text")
              .attr("x", width - 24)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "end")
              .text(function (d) { return d; });


        transitionStacked();
        function transitionStacked() {

            y.domain([0, yStackMax]);

            rect.transition()
                .duration(500)
                .delay(function (d, i) { return i * 10; })
                .attr("y", function (d) { return y(d.y0 + d.y); })
                .attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
              .transition()
                .attr("x", function (d) { return xScale(d.x); })
                .attr("width", xScale.rangeBand());

        };

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.0/d3.min.js"></script>
<body></body>

这篇关于当鼠标悬停在d3中的图例上时,高亮堆叠条形图中的相应图层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆