从D3图中的Y值计算以像素为单位的杆的高度

时间:2023-02-01 07:56:34

I have a quick question. I am trying to determine the height in pixels of a chart bar. This is for a D3 implementation, and my chart has a logarithmic y-axis.

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

  1. I know the Y value for the bar I am trying to plot.
  2. 我知道我要画的酒吧的Y值。
  3. I also know the height of the axis in pixels (600px).
  4. 我还知道以像素为单位的轴的高度(600px)。
  5. I know the min and the max of the Y-axis
  6. 我知道y轴的最小值和最大值

I have tried various computations but cannot seem to calculate the height of the bar so that it connects the Y value with the x-Axis.

我尝试过各种计算方法,但似乎无法计算杆的高度,使它将Y值与x轴连接起来。

The picture below should provide a visual illustration of what I am trying to do. Right now I can't seem to get it right ... I think this is essentially a problem in maths, not so much D3. Thank you!

下面的图片应该能提供我正在尝试做的事情的视觉说明。现在我似乎做得不对……我认为这本质上是一个数学问题,而不是D3。谢谢你!

*** EDIT ****

* * * * * * *进行编辑

This is the y axis scale that I am using:

这是我用的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;
    })
  ]);

从D3图中的Y值计算以像素为单位的杆的高度

1 个解决方案

#1


2  

I'm still not sure about your problem, because the actual height of the bar is being calculated by the very scale you use to append the rectangles. And, if you're in fact appending the rectangles, you're already setting the height attribute!

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

Let's see an example. This is a bar chart using your log scale (I'm using D3 v4 here, but the principle is the same) and this fake data:

让我们看看一个例子。这是一个柱状图,用的是你的日志标度(这里我用的是D3 v4,但原理是一样的)

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

As you can see, there is a minimum and a maximum. I put a padding of 20px in the scale:

正如你所看到的,有一个最小值和一个最大值。我在标尺上加了20px的填充:

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

So, our first value in the range is h - padding and our last value is just padding. Here is the chart:

我们在这个范围内的第一个值是h -填充,最后一个值就是填充。这是图表:

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>

Suppose you want to calculate the height of the first bar. We can see, by inspecting the DOM, that its height is 61.867984771728516 pixels:

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

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)
<script src="//d3js.org/d3.v4.min.js"></script>

But this is simply the first value in the range (height - padding) minus yScale(2000):

但这只是范围(身高-填充)- yScale(2000)中的第一个值:

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))
<script src="//d3js.org/d3.v4.min.js"></script>

Which, by the way, is the value used to set the height of the bars:

顺便说一下,它是用来设置栏高的值:

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

#1


2  

I'm still not sure about your problem, because the actual height of the bar is being calculated by the very scale you use to append the rectangles. And, if you're in fact appending the rectangles, you're already setting the height attribute!

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

Let's see an example. This is a bar chart using your log scale (I'm using D3 v4 here, but the principle is the same) and this fake data:

让我们看看一个例子。这是一个柱状图,用的是你的日志标度(这里我用的是D3 v4,但原理是一样的)

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

As you can see, there is a minimum and a maximum. I put a padding of 20px in the scale:

正如你所看到的,有一个最小值和一个最大值。我在标尺上加了20px的填充:

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

So, our first value in the range is h - padding and our last value is just padding. Here is the chart:

我们在这个范围内的第一个值是h -填充,最后一个值就是填充。这是图表:

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>

Suppose you want to calculate the height of the first bar. We can see, by inspecting the DOM, that its height is 61.867984771728516 pixels:

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

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)
<script src="//d3js.org/d3.v4.min.js"></script>

But this is simply the first value in the range (height - padding) minus yScale(2000):

但这只是范围(身高-填充)- yScale(2000)中的第一个值:

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))
<script src="//d3js.org/d3.v4.min.js"></script>

Which, by the way, is the value used to set the height of the bars:

顺便说一下,它是用来设置栏高的值:

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