首页 > 解决方案 > 如何为条形图分配 id

问题描述

如何根据名称分配 id?控制台屏幕截图的链接在下面。谢谢

在此处输入图像描述

serie.selectAll("rect")
    .data(function(d) { return d; })
    .enter().append("rect")
    .attr("class","bar")
      .attr("x", function(d) { return x(d.data.Company); })
      .attr("y", function(d) { return y(d[1]); })
      .attr("height", function(d) { return y(d[0]) - y(d[1]); })
      .attr("width", x.bandwidth())
      .attr("id",function(d,i){
        return "id"+ d.name;
      })

标签: d3.js

解决方案


I discourage assigning ids to every bar as ids need to be unique. Its better to have a class instead. But as requested, I have posted a fiddle below. Hover on the bars to get the id. And you also said you need the id for animating so I've also added some animations when the chart loads (If that's what you meant by animation).

// Setup svg using Bostock's margin convention

var margin = {
  top: 20,
  right: 160,
  bottom: 35,
  left: 30
};

var width = 700 - margin.left - margin.right,
  height = 300 - margin.top - margin.bottom;

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 + ")");


/* Data in strings like it would be if imported from a csv */

var data = [{
  mystate: "Intuit",
  name: "Asian",
  y0: 53,
  y1: 1824,
  value: "1771"
}, {
  mystate: "Intuit",
  name: "Latino",
  y0: 2707,
  y1: 1231,
  value: "1771"
}, {
  mystate: "Intuit",
  name: "Black_or_African_American",
  y0: 2060,
  y1: 1824,
  value: "1771"
}, {
  mystate: "Intuit",
  name: "Caucasian",
  y0: 355,
  y1: 1024,
  value: "1771"
}];


// Transpose the data into layers
var dataset = d3.layout.stack()(['y0', 'y1'].map(function(values) {
  return data.map(function(d) {
    return {
      x: d.name,
      y: +d[values],
    };
  });
}));


// Set x, y and colors
var x = d3.scale.ordinal()
  .domain(dataset[0].map(function(d) {
    return d.x;
  }))
  .rangeRoundBands([10, width - 10], 0.02);

var y = d3.scale.linear()
  .domain([0, d3.max(dataset, function(d) {
    return d3.max(d, function(d) {
      return d.y0 + d.y;
    });
  })])
  .range([height, 0]);

var colors = ["b33040", "#d25c4d", "#f2b447", "#d9d574"];


// Define and draw axes
var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .ticks(5)
  .tickSize(-width, 0, 0)
  .tickFormat(function(d) {
    return d
  });

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


svg.append("g")
  .attr("class", "y axis")
  .call(yAxis);

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


// Create groups for each series, rects for each segment 
var groups = svg.selectAll("g.cost")
  .data(dataset)
  .enter().append("g")
  .attr("class", "cost")
  .style("fill", function(d, i) {
    return colors[i];
  });

var rect = groups.selectAll("rect")
  .data(function(d) {
    return d;
  })
  .enter()
  .append("rect")
  .attr("x", function(d) {
    return x(d.x);
  })
  .attr("y", function(d) {
    return height;
  })
  .attr("height", function(d) {
    return 0;
  })
  .attr("width", x.rangeBand())
  .attr('id', function(d) {
    return 'id' + d.x;
  })
  .on("mouseover", function() {
    console.log(d3.select(this).attr('id'));
    tooltip.style("display", null);
  })
  .on("mouseout", function() {
    tooltip.style("display", "none");
  })
  .on("mousemove", function(d) {
    var xPosition = d3.mouse(this)[0] - 15;
    var yPosition = d3.mouse(this)[1] - 25;
    tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
    tooltip.select("text").text(d.y);
  }).transition().duration(1000)
  .delay(function(d, i) {
    return i * 300;
  })
  .attr("height", function(d) {
    return y(d.y0) - y(d.y0 + d.y);
  }).attr("y", function(d) {
    return y(d.y0 + d.y);
  });





// Prep the tooltip bits, initial display is hidden
var tooltip = svg.append("g")
  .attr("class", "tooltip")
  .style("display", "none");

tooltip.append("rect")
  .attr("width", 30)
  .attr("height", 20)
  .attr("fill", "white")
  .style("opacity", 0.5);

tooltip.append("text")
  .attr("x", 15)
  .attr("dy", "1.2em")
  .style("text-anchor", "middle")
  .attr("font-size", "12px")
  .attr("font-weight", "bold");
svg {
  font: 10px sans-serif;
  shape-rendering: crispEdges;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
}

path.domain {
  stroke: none;
}

.y .tick line {
  stroke: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>

Now coming back to your code, when you transform the data by using d3.layout.stack() there is no property called name in your new data (I suppose) and hence your ids are idundefined


推荐阅读