工具提示不填充:D3堆积条形图

时间:2015-11-20 00:09:44

标签: d3.js stacked

我疯狂地尝试将描述字段填入工具提示中。如果有人能帮助我理解为什么它不起作用,我将非常感谢这种见解。我先发布了数据,然后是脚本

数据:

Dates    Meals & Entertainment  Hotels  Travel  Misc    descrip
Jan-12  406.78  0   0   0   "DESCRIPTION"
Feb-12  0   0   0   0   0
Mar-12  0   466.2   0   0   
Apr-12  0   534.5   0   0   
May-12  189.9   129.92  0   0   
Jun-12  146.83  0   0   0   
Jul-12  117.65  0   0   0   
Aug-12  0   0   0   0   
Sep-12  169.02  122.84  0   0   
Oct-12  182.86  0   0   0   
Nov-12  0   229.95  0   0   
Dec-12  0   114.12  0   0   
Jan-13  100.63  0   0   0   
Feb-13  0   0   0   0   
Mar-13  136.61  469.53  0   0   
Apr-13  0   446.5   0   0   
May-13  169.22  758.14  0   0   
Jun-13  0   0   0   0   
Jul-13  1   0   0   0   0
Aug-13  0   280.28  0   0   
Sep-13  182.38  0   0   0   
Oct-13  65.26   0   0   0   
Nov-13  158.6   0   0   0   
Dec-13  813.87  0   0   231.24  
Jan-14  158.86  0   0   0   
Feb-14  0   0   0   0   
Mar-14  64.35   658.06  0   0   
Apr-14  255.44  507.24  0   0   
May-14  134.93  0   0   0   
Jun-14  592.57  0   0   0   
Jul-14  50.7    0   0   0   
Aug-14  0   0   0   0   
Sep-14  110.79  0   0   0   
Oct-14  50  908.41  242.91  0   
Nov-14  0   0   0   0   
Dec-14  0   0   0   0   

代码:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="style.css">
        <meta charset="utf-8">
        <script src="http://d3js.org/d3.v3.min.js"></script>
    </head>

    <div class = wrap>
    <div class = title><h1>Title</h1></div>
    <div class= main></div>
    </div>
<script>

var margin = {top: 20, right: 20, bottom: 90, left: 30},
    width = 970 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

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

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

var color = d3.scale.ordinal()
    .range(["4A5E40", "ACCD9D","ACCD9D","DBDBDA"]);

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

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

var tooltip = d3.select(".main").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

var svg = d3.select(".main").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 + ")");



d3.tsv("data.tsv", function(error, data) {
  if (error) throw error;



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

  data.forEach(function(d) {
    var descrip = +d.descrip;
    var y0 = 0;
    d.spending = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
    d.total = d.spending[d.spending.length - 1].y1;
  });


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

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .selectAll("text")
        .attr("y", 0)
        .attr("x", 9)
        .attr("dy", ".35em")
        .attr("transform", "rotate(45)")
        .style("text-anchor", "start");

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")


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


  Dates.selectAll(".rect")
      .data(function(d) { return d.spending; })
    .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); })
      .style("fill", function(d) { return color(d.name); })
      .on("mouseover", function(d) {                                
          tooltip.transition()
               .duration(200)
               .style("opacity", .9);
               tooltip.html( "On " + d.y0)
               .style("left", (d3.event.pageX - 65) + "px")
               .style("top", (d3.event.pageY - 80) + "px")
               d3.select(this).style("fill", "#B19330");
      })
      .on("mouseout", function(d) {
          tooltip.transition()
               .duration(500)
               .style("opacity", 0),
               d3.select(this).style("fill", function(d) { return  color(d.name); });

      });



  svg.append("rect")
      .attr("x", width - 895)
      .attr("y", 0)
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", "4A5E40");

  svg.append("rect")
      .attr("x", width - 895)
      .attr("y", 25)
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", "ACCD9D");

  svg.append("rect")
      .attr("x", width - 895)
      .attr("y", 50)      
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", "DBDBDA");

  svg.append("text")
      .attr("x", width - 865)
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "start")
      .text(function(d) { return "Meals & Entertainment"; });

  svg.append("text")
      .attr("x", width - 865)
      .attr("y", 34)
      .attr("dy", ".35em")
      .style("text-anchor", "start")
      .text(function(d) { return "Hotels & Travel"; });

  svg.append("text")
      .attr("x", width - 865)
      .attr("y", 59)
      .attr("dy", ".35em")
      .style("text-anchor", "start")
      .text(function(d) { return "Misc."; });      
});

</script>

1 个答案:

答案 0 :(得分:1)

希望此示例代码有所帮助。

var margin = {
    top: 20,
    right: 20,
    bottom: 90,
    left: 30
  },
  width = 970 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

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

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

var color = d3.scale.ordinal()
  .range(["4A5E40", "ACCD9D", "ACCD9D", "DBDBDA"]);

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

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

var tooltip = d3.select(".main").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

var svg = d3.select(".main").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 data = [{
  "Dates": "Jan-12",
  "Meals & Entertainment": 406.78,
  "Hotels & Travel": 0,
  "Misc": 0,
  "descrip": 0
}, {
  "Dates": "Feb-12",
  "Meals & Entertainment": 0,
  "Hotels & Travel": 0,
  "Misc": 0,
  "descrip": 0
}, {
  "Dates": "Mar-12",
  "Meals & Entertainment": 0,
  "Hotels & Travel": 466.2,
  "Misc": 0,
  "descrip": 0
}, {
  "Dates": "Apr-12",
  "Meals & Entertainment": 0,
  "Hotels & Travel": 534.5,
  "Misc": 0,
  "descrip": 0
}, {
  "Dates": "May-12",
  "Meals & Entertainment": 189.9,
  "Hotels & Travel": 139.92,
  "Misc": 0,
  "descrip": 0
}, {
  "Dates": "Jun-12 146.83 0",
  "Meals & Entertainment": 0,
  "Hotels & Travel": 0,
  "Misc": 0,
  "descrip": 0
}];



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

data.forEach(function(d) {
  var descrip = +d.descrip;
  var y0 = 0;
  d.spending = color.domain().map(function(name) {
    return {
      name: name,
      descrip: descrip,
      y0: y0,
      y1: y0 += +d[name]
    };
  });
  d.total = d.spending[d.spending.length - 1].y1;
});


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

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)
  .selectAll("text")
  .attr("y", 0)
  .attr("x", 9)
  .attr("dy", ".35em")
  .attr("transform", "rotate(45)")
  .style("text-anchor", "start");

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")


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


Dates.selectAll(".rect")
  .data(function(d) {
    return d.spending;
  })
  .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);
  })
  .style("fill", function(d) {
    return color(d.name);
  })
  .on("mouseover", function(d) {
    console.log(d);
    tooltip.transition()
      .duration(200)
      .style("opacity", .9);
    tooltip.html("On " + d.y0 + "Description : " + d.descrip)
      .style("left", (d3.event.pageX - 65) + "px")
      .style("top", (d3.event.pageY - 80) + "px")
    d3.select(this).style("fill", "#B19330");
  })
  .on("mouseout", function(d) {
    tooltip.transition()
      .duration(500)
      .style("opacity", 0),
      d3.select(this).style("fill", function(d) {
        return color(d.name);
      });

  });



svg.append("rect")
  .attr("x", width - 895)
  .attr("y", 0)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", "4A5E40");

svg.append("rect")
  .attr("x", width - 895)
  .attr("y", 25)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", "ACCD9D");

svg.append("rect")
  .attr("x", width - 895)
  .attr("y", 50)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", "DBDBDA");

svg.append("text")
  .attr("x", width - 865)
  .attr("y", 9)
  .attr("dy", ".35em")
  .style("text-anchor", "start")
  .text(function(d) {
    return "Meals & Entertainment";
  });

svg.append("text")
  .attr("x", width - 865)
  .attr("y", 34)
  .attr("dy", ".35em")
  .style("text-anchor", "start")
  .text(function(d) {
    return "Hotels & Travel";
  });

svg.append("text")
  .attr("x", width - 865)
  .attr("y", 59)
  .attr("dy", ".35em")
  .style("text-anchor", "start")
  .text(function(d) {
    return "Misc.";
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class=wrap>
  <div class=title>
    <h1>Title</h1>
  </div>
  <div class=main></div>