从D3图中的Y值计算条形高度(以像素为单位)

时间:2017-03-08 12:26:44

标签: javascript math d3.js

我有一个简单的问题。我试图确定图表栏的高度(以像素为单位)。这是针对D3实现的,我的图表具有对数y轴。

  1. 我知道我试图绘制的条形码的Y值。
  2. 我也知道轴的高度(以像素为单位)(600px)。
  3. 我知道Y轴的最小值和最大值
  4. 我尝试了各种计算,但似乎无法计算条形的高度,因此它将Y值与x轴连接。

    下面的图片应该提供我想要做的事情的视觉说明。现在我似乎无法做到正确...我认为这在数学上基本上是一个问题,而不是D3。谢谢!

    ***编辑****

    这是我正在使用的y轴刻度:

    var y = d3.scale.log()
    .range([height, 0])
    .domain([d3.min(sampleData, function(d) {
          return d.y;
        }),
        d3.max(sampleData, function(d) {
          return d.y;
        })
      ]);
    

    enter image description here

1 个答案:

答案 0 :(得分:2)

我仍然不确定您的问题,因为条形的实际高度是通过您用来附加矩形的刻度来计算的。而且,如果您实际上附加了矩形,那么您已经设置了height属性!

让我们看一个例子。这是一个使用您的日志比例的条形图(我在这里使用D3 v4,但原理是相同的)和这个假数据:

var data = [2000, 5000, 3000, 8000, 1500];

如您所见,有最小值和最大值。我在比例尺上填了20px的填充物:

var yScale = d3.scaleLog()
    .range([height - padding, padding])
    .domain([d3.min(data), d3.max(data)]);

因此,我们在该范围内的第一个值是h - padding,我们的最后一个值只是padding。这是图表:



var width = 300,
  height = 400,
  padding = 20;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var data = [2000, 5000, 3000, 8000, 1500];

var xScale = d3.scaleBand()
  .range([50, width])
  .domain(d3.range(data.length))
  .padding(0.2);

var yScale = d3.scaleLog()
  .range([height - padding, padding])
  .domain([d3.min(data), d3.max(data)]);

var bars = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", (d, i) => xScale(i))
  .attr("width", xScale.bandwidth())
  .attr("height", d => height - padding - yScale(d))
  .attr("y", d => yScale(d))
  .attr("fill", "teal");

var gX = svg.append("g")
  .attr("transform", "translate(0," + (height - padding) + ")")
  .call(d3.axisBottom(xScale));

var gY = svg.append("g")
  .attr("transform", "translate(50,0)")
  .call(d3.axisLeft(yScale));

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

假设您要计算第一个柱的高度。通过检查DOM,我们可以看到它的高度为61.867984771728516像素:

&#13;
&#13;
var width = 300,
  height = 400,
  padding = 20;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var data = [2000, 5000, 3000, 8000, 1500];

var xScale = d3.scaleBand()
  .range([50, width])
  .domain(d3.range(data.length))
  .padding(0.2);

var yScale = d3.scaleLog()
  .range([height - padding, padding])
  .domain([d3.min(data), d3.max(data)]);

var bars = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", (d, i) => xScale(i))
  .attr("width", xScale.bandwidth())
  .attr("height", d => height - padding - yScale(d))
  .attr("y", d => yScale(d))
  .attr("fill", "teal");

var gX = svg.append("g")
  .attr("transform", "translate(0," + (height - padding) + ")")
  .call(d3.axisBottom(xScale));

var gY = svg.append("g")
  .attr("transform", "translate(50,0)")
  .call(d3.axisLeft(yScale));
  
console.log(d3.select("rect").node().height.animVal.value)
&#13;
<script src="//d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

但这只是范围中的第一个值(height - padding)减去yScale(2000)

&#13;
&#13;
var width = 300,
  height = 400,
  padding = 20;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var data = [2000, 5000, 3000, 8000, 1500];

var xScale = d3.scaleBand()
  .range([50, width])
  .domain(d3.range(data.length))
  .padding(0.2);

var yScale = d3.scaleLog()
  .range([height - padding, padding])
  .domain([d3.min(data), d3.max(data)]);

var bars = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", (d, i) => xScale(i))
  .attr("width", xScale.bandwidth())
  .attr("height", d => height - padding - yScale(d))
  .attr("y", d => yScale(d))
  .attr("fill", "teal");

var gX = svg.append("g")
  .attr("transform", "translate(0," + (height - padding) + ")")
  .call(d3.axisBottom(xScale));

var gY = svg.append("g")
  .attr("transform", "translate(50,0)")
  .call(d3.axisLeft(yScale));

console.log(height - padding - yScale(2000))
&#13;
<script src="//d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

顺便说一句,这是用于设置条形高度的值:

.attr("height", d => height - padding - yScale(d))