0
votes

I have a stacked bar chart. And I'd like a draw a line like grouping few bars of a stacked bar chart.

Something like this.enter image description here

So to do this I need to find the y coordinate of the 2nd and the last bar.

Some one please help in drawing those line using d3.

JS:


var width = 750,
      height = 500;

  var x = d3.scale.ordinal()
            .rangeRoundBands([0, width], .1);

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

  var color = d3.scale.ordinal()
                .range(["#D70B16", "#154CEF", "#1A8A55"]);

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

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

  var tip = d3.tip()
            .attr('class', 'd3-tip')
            .offset([-10, 0])
            .html(function(d) {
            return "Value: " + (d.y1 - d.y0) + "";
            })

  var svgContainer = d3.select("body")
                        .append("svg")
                        .attr("width", width)
                        .attr("height", height)
                        .append("g")
                        .attr("transform", "translate(" + 30 + "," + 30 + ")");


  d3.csv("data.csv", function(error, data) {
    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "circle"; }));

    data.forEach(function(d) {
      var y0 = 0;
      d.hours = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });

      d3.select('body').append('pre')
              .text(JSON.stringify(d.hours, null, '  '));


      d.total = d.hours[d.hours.length - 1].y1;
    });

    x.domain(data.map(function(d) {return d.circle;}));
    y.domain([0, d3.max(data, function(d) {return d.total;})])

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

    svgContainer.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Login Hours");

    var circle = svgContainer.selectAll(".circle")
                    .data(data)
                    .enter().append("g")
                    .attr("class", "g")
                    .attr("transform", function(d) { return "translate(" + x(d.circle) + ",0)"; });

    circle.selectAll("rect")
          .data(function(d) { return d.hours; })
          .enter()
          .append("rect")
          .attr("width", x.rangeBand())
          .attr("y", function(d) { return y(d.y1); })
          .attr("height", function(d) { return y(d.y0) - y(d.y1); })
          .on("mouseover", tip.show)
          .on("mouseout", tip.hide)
          .style("fill", function(d) { return color(d.name); });


    circle.selectAll("text")
          .data(function(d) { return d.hours; })
          .enter()
          .append("text")
          .attr("x", 75)
          .attr("y", function(d, i) { return y(d.y1) ; })
          .style("text-anchor", "middle")
          .text("test")

  })
1
Do those bars correspond to the 2nd and last data items? If so, you can do bars.data(secondItem).attr("y") etc.Lars Kotthoff
We need to use like firstItem, secondItem and so on huh?Unknown User
Not necessarily, it depends how exactly you want to identify those bars. Could you post a complete working example please?Lars Kotthoff
Looks like you should be able to get the coordinate directly from the data item -- y(d.y1).Lars Kotthoff
How do i need to do it for those selective bars? Running y(d.y1) will run through all the data in the array. But here i need to take the second bar and third bar. How will i do it?Unknown User

1 Answers

2
votes

How you determine those values (and the bars) depends on how you can identify them. In this particular case, you don't actually need to get the rect items because the underlying data gives you access to everything you need.

To, for example, get the y coordinate of the second bar in the first column, you can use the following code:

var yCoord = y(data[0].hours[1].y1);