简体   繁体   中英

Differentiating between bars in tooltip for stacked bar chart

Thanks to some great help on my previous post, I know have a working tooltip, the issue is now getting it to differentiate between the different values in each bar.

Ideally I would add some text eg green or orange depending on the stack, then the stack value, in the tooltip. Again it's probably completely trivial to someone who knows thier way around but to me a little less so!

Thanks in advance you wonderful people

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.bar2 {
    fill: #00AF9D; 
}

.bar{
    fill: #FF5A00;
}


.axis text {
 font-family: 'Open Sans', sans-serif;
            font-size: 2vw;
            color:grey;

}

.axis path, .axis line {

    fill: none;

    stroke: #000;

    shape-rendering: crispEdges;

}

.svg{ position: absolute;
            top: 5vh;
            left: 5vw;
            border: 1px solid #A0A0A0 ;
            height: 90vh;
            width: 90vw;
            border-radius: 25px;
            box-shadow: 3vh 3vh 3vh #D8D8D8 ;
            background-color:#FFFFFF;}

.lab{  font-family: 'Open Sans', sans-serif;
            font-size: 1vw;
            color:grey;
           }
.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>



<script>

var w = window.innerWidth;
        var h = window.innerHeight;


data = [{
    name: "A",
    value: 1,
    value2: 1
}, {
    name: "B",
    value: 4,
    value2: 5
}, {
    name: "C",
    value: 17,
    value2:18
}, {
    name: "D",
    value: 30,
    value2: 30
}, {
    name: "E",
    value: 60,
    value2: 60
}, {
    name: "F",
    value: 100,
    value2: 100
}]

var margin = {
    top: 0.01*h,
    right: 0.05*w,
    bottom:0.02*h,
    left: 0.05*w
},
width = 0.9*w - margin.left - margin.right,
    height =0.9*h - margin.top - margin.bottom;

var x = d3.scale.linear()
    .range([0, width])

var y = d3.scale.ordinal()
    .rangeRoundBands([0, height], .2);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");


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


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

x.domain([-100,100])
y.domain(data.map(function (d) {
    return d.name;
}));

svg.call(tip);

svg.selectAll(".bar")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function (d) {return x(Math.min(0, d.value));})
    .attr("y", function (d) {return y(d.name);})
    .attr("width", function (d) {return Math.abs(x(d.value) - x(0));})
    .attr("height", y.rangeBand())
  .on('mouseover', tip.show)
      .on('mouseout', tip.hide)
      .append("svg:title")
    .text("Majority");



    svg.selectAll("text")
   .data(data)
   .enter()
   .append("text")
   .attr("class", "lab")
   .text(function (d){return d.value+"%";})
   .attr("text-anchor", "middle")
                .attr("font-family", "sans-serif")
                .attr("font-size", "10px")
                .attr("fill", "black")
    .attr("x", function (d) {return x(Math.min(0, d.value))+(Math.abs(x(d.value) - x(0))/2);})
    .attr("y", function (d) {return y(d.name) + (y.rangeBand())/2 ;});





svg.selectAll(".bar2")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar2")
    .attr("x", function (d) {return x(Math.min(0, -d.value2));})
    .attr("y", function (d) {return y(d.name);})
    .attr("width", function (d) {return Math.abs(x(-d.value2) - x(0));})
    .attr("height", y.rangeBand())
  .on('mouseover', tip.show)
      .on('mouseout', tip.hide)
      .append("svg:title")
    .text("Minoirty")
      ;

svg.selectAll("text1")
   .data(data)
   .enter()
   .append("text")
   .attr("class", "lab")
   .text(function (d){return d.value2+"%";})
   .attr("text-anchor", "middle")
                .attr("font-family", "sans-serif")
                .attr("font-size", "10px")
                .attr("fill", "black")
    .attr("x",  function (d) {return x(Math.min(0, -d.value2))+(Math.abs(x(-d.value2) - x(0))/2);})
    .attr("y", function (d) {return y(d.name)+(y.rangeBand())/2;});


svg.selectAll("text2")
   .data(data)
   .enter()
   .append("text")
   .attr("class", "lab")
   .text(function (d){return "Grade "+ d.name;})
   .attr("text-anchor", "middle")
                .attr("font-family", "sans-serif")
                .attr("font-size", "10px")
                .attr("fill", "black")
   .attr("x", function (d) {return x(Math.min(0, 100))+(Math.abs(x(100) - x(0)))+0.02*w;})
   .attr("y", function (d) {return y(d.name)+(y.rangeBand())/2;});



svg.append("g")
    .attr("class", "x axis")
    .call(xAxis)
    .attr("transform", "translate(0," + (height -margin.bottom) + ")");


svg.append("g")
    .attr("class", "y axis")
    .append("line")
    .attr("x1", x(0))
    .attr("x2", x(0))
    .attr("y2", height -margin.bottom);



svg.append("g")
    .attr("class", "y axis")
    .append("line")
    .attr("x1", x(0))
    .attr("x2", x(0))
    .attr("y2", height -margin.bottom);




function type(d) {
    d.value = +d.value;
    return d;
};

//////////////////////////Tool Tip///////////////////////////////////












</script>
</body>
</html>

What you can do is pass a "wrapper" object to the tooltip's show method and then extract it in the tooltip function.

The wrapper object basically looks like this:

{
    value: d.value, // or d.value2
    color: 'red' // or 'green'
}

This is the final code:

<!DOCTYPE html>
<meta charset="utf-8">

<head>
    <style>
        .bar2 {
            fill: #00AF9D;
        }

        .bar {
            fill: #FF5A00;
        }

        .axis text {
            font-family: 'Open Sans', sans-serif;
            font-size: 2vw;
            color: grey;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: #000;
            shape-rendering: crispEdges;
        }

        .svg {
            position: absolute;
            top: 5vh;
            left: 5vw;
            border: 1px solid #A0A0A0;
            height: 90vh;
            width: 90vw;
            border-radius: 25px;
            box-shadow: 3vh 3vh 3vh #D8D8D8;
            background-color: #FFFFFF;
        }

        .lab {
            font-family: 'Open Sans', sans-serif;
            font-size: 1vw;
            color: grey;
        }

        .d3-tip {
            line-height: 1;
            font-weight: bold;
            padding: 12px;
            background: rgba(0, 0, 0, 0.8);
            color: #fff;
            border-radius: 2px;
        }
        /* Creates a small triangle extender for the tooltip */

        .d3-tip:after {
            box-sizing: border-box;
            display: inline;
            font-size: 10px;
            width: 100%;
            line-height: 1;
            color: rgba(0, 0, 0, 0.8);
            content: "\25BC";
            position: absolute;
            text-align: center;
        }
        /* Style northward tooltips differently */

        .d3-tip.n:after {
            margin: -1px 0 0 0;
            top: 100%;
            left: 0;
        }
    </style>
</head>

<body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>



    <script>
        var w = window.innerWidth;
        var h = window.innerHeight;


        data = [{
            name: "A",
            value: 1,
            value2: 1
    }, {
            name: "B",
            value: 4,
            value2: 5
    }, {
            name: "C",
            value: 17,
            value2: 18
    }, {
            name: "D",
            value: 30,
            value2: 30
    }, {
            name: "E",
            value: 60,
            value2: 60
    }, {
            name: "F",
            value: 100,
            value2: 100
    }]

        var margin = {
                top: 0.01 * h,
                right: 0.05 * w,
                bottom: 0.02 * h,
                left: 0.05 * w
            },
            width = 0.9 * w - margin.left - margin.right,
            height = 0.9 * h - margin.top - margin.bottom;

        var x = d3.scale.linear()
            .range([0, width])

        var y = d3.scale.ordinal()
            .rangeRoundBands([0, height], .2);

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");


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

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

        x.domain([-100, 100])
        y.domain(data.map(function (d) {
            return d.name;
        }));

        svg.call(tip);

        svg.selectAll(".bar")
            .data(data)
            .enter().append("rect")
            .attr("class", "bar")
            .attr("x", function (d) {
                return x(Math.min(0, d.value));
            })
            .attr("y", function (d) {
                return y(d.name);
            })
            .attr("width", function (d) {
                return Math.abs(x(d.value) - x(0));
            })
            .attr("height", y.rangeBand())
            .on('mouseover', function (d) {
                tip.show({
                    value: d.value,
                    color: 'red'
                });
            })
            .on('mouseout', tip.hide)
            .append("svg:title")
            .text("Majority");

        svg.selectAll("text")
            .data(data)
            .enter()
            .append("text")
            .attr("class", "lab")
            .text(function (d) {
                return d.value + "%";
            })
            .attr("text-anchor", "middle")
            .attr("font-family", "sans-serif")
            .attr("font-size", "10px")
            .attr("fill", "black")
            .attr("x", function (d) {
                return x(Math.min(0, d.value)) + (Math.abs(x(d.value) - x(0)) / 2);
            })
            .attr("y", function (d) {
                return y(d.name) + (y.rangeBand()) / 2;
            });

        svg.selectAll(".bar2")
            .data(data)
            .enter().append("rect")
            .attr("class", "bar2")
            .attr("x", function (d) {
                return x(Math.min(0, -d.value2));
            })
            .attr("y", function (d) {
                return y(d.name);
            })
            .attr("width", function (d) {
                return Math.abs(x(-d.value2) - x(0));
            })
            .attr("height", y.rangeBand())
            .on('mouseover', function (d) {
                tip.show({
                    value: d.value2,
                    color: 'green'
                });
            })
            .on('mouseout', tip.hide)
            .append("svg:title")
            .text("Minoirty");

        svg.selectAll("text1")
            .data(data)
            .enter()
            .append("text")
            .attr("class", "lab")
            .text(function (d) {
                return d.value2 + "%";
            })
            .attr("text-anchor", "middle")
            .attr("font-family", "sans-serif")
            .attr("font-size", "10px")
            .attr("fill", "black")
            .attr("x", function (d) {
                return x(Math.min(0, -d.value2)) + (Math.abs(x(-d.value2) - x(0)) / 2);
            })
            .attr("y", function (d) {
                return y(d.name) + (y.rangeBand()) / 2;
            });


        svg.selectAll("text2")
            .data(data)
            .enter()
            .append("text")
            .attr("class", "lab")
            .text(function (d) {
                return "Grade " + d.name;
            })
            .attr("text-anchor", "middle")
            .attr("font-family", "sans-serif")
            .attr("font-size", "10px")
            .attr("fill", "black")
            .attr("x", function (d) {
                return x(Math.min(0, 100)) + (Math.abs(x(100) - x(0))) + 0.02 * w;
            })
            .attr("y", function (d) {
                return y(d.name) + (y.rangeBand()) / 2;
            });

        svg.append("g")
            .attr("class", "x axis")
            .call(xAxis)
            .attr("transform", "translate(0," + (height - margin.bottom) + ")");


        svg.append("g")
            .attr("class", "y axis")
            .append("line")
            .attr("x1", x(0))
            .attr("x2", x(0))
            .attr("y2", height - margin.bottom);

        svg.append("g")
            .attr("class", "y axis")
            .append("line")
            .attr("x1", x(0))
            .attr("x2", x(0))
            .attr("y2", height - margin.bottom);

        function type(d) {
            d.value = +d.value;
            return d;
        };

        //////////////////////////Tool Tip///////////////////////////////////
    </script>
</body>

</html>

</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM