在d3中获取有序比例轴的点之间

时间:2018-03-15 12:28:56

标签: d3.js

我很难找到给定X比例域之间的点。 例如。我有一个条形图,其X轴值为

[Bob,Robin,Anne,Mark,Joe,Eve,Karen,Kirsty,Chris,Lisa,Tom,Stacy,Charles,Mary]

以上值用于绘制x轴。我使用了scaleBand方法,因为值是离散的。

  var x = d3.scaleBand()
          .range([0, width])
          .padding(0.1);
  x.domain(data.map(function(d) { return d.salesperson; })); 

我的目标是在给定点的x刻度之间找到点,即 有没有什么方法可以找到Bob,RobinRobin,Anne之间的点,这样我就可以在给出Y轴值的情况下绘制一个点。

我添加了plunker,其中显示了具有上述x轴的条形图。我需要在图表上绘制一个点,其中X值点位于Bob,Robin之间 和Y值为30(any value on Y axis)

1 个答案:

答案 0 :(得分:1)

如果RobinBob之后的离散值,则可以使用bandwidth()step()的组合:

x("Bob") + x.bandwidth() + (x.step()-x.bandwidth()) / 2

丑陋,但它确实有效。谈论丑陋,如果你想要一个更丑陋的数学,你也可以使用step()paddingInner()的组合:

x("Bob") + x.step() * (1 - x.paddingInner() / 2))

这是一个演示,我把重点放在y(10)上,这样你就可以更好地看到它将在" Bob"之间。和#34;罗宾"柱:



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

// set the ranges
var x = d3.scaleBand()
          .range([0, width])
          .padding(0.1);
var y = d3.scaleLinear()
          .range([height, 0]);
          
// append the svg object to the body of the page
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
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 data = [
  {
    "salesperson": "Bob",
    "sales": 33
  },
  {
    "salesperson": "Robin",
    "sales": 12
  },
  {
    "salesperson": "Anne",
    "sales": 41
  },
  {
    "salesperson": "Mark",
    "sales": 16
  },
  {
    "salesperson": "Joe",
    "sales": 59
  },
  {
    "salesperson": "Eve",
    "sales": 38
  },
  {
    "salesperson": "Karen",
    "sales": 21
  },
  {
    "salesperson": "Kirsty",
    "sales": 25
  },
  {
    "salesperson": "Chris",
    "sales": 30
  },
  {
    "salesperson": "Lisa",
    "sales": 47
  },
  {
    "salesperson": "Tom",
    "sales": 5
  },
  {
    "salesperson": "Stacy",
    "sales": 20
  },
  {
    "salesperson": "Charles",
    "sales": 13
  },
  {
    "salesperson": "Mary",
    "sales": 29
  }
];
  // format the data
  data.forEach(function(d) {
    d.sales = +d.sales;
  });

  // Scale the range of the data in the domains
  x.domain(data.map(function(d) { return d.salesperson; }));
  y.domain([0, d3.max(data, function(d) { return d.sales; })]);

  // append the rectangles for the bar chart
  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.salesperson); })
      .attr("width", x.bandwidth())
      .attr("y", function(d) { return y(d.sales); })
      .attr("height", function(d) { return height - y(d.sales); });

  // add the x Axis
  svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

  // add the y Axis
  svg.append("g")
      .call(d3.axisLeft(y));
      
  var pointBetween = svg.append("circle")
    .attr("r", 2)
    .attr("cy", y(10))
    .attr("cx", x("Bob") + x.bandwidth() + (x.step()-x.bandwidth())/2)

.bar { fill: steelblue; }

<script src="//d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;