javascript - 如何在 D3 轴和图表之间应用填充?

标签 javascript node.js d3.js

通常图表数据从 Y 轴底部和 X 轴左侧开始。但是,我尝试在 D3 中创建此条形图,它从 Y 轴底部上方 30px 和 X 轴左侧右侧 30px 处开始(请参阅模型设计以下)。顶部和右侧也应保持 30 像素的内边距。

我无法理解应该如何实现这一点,因为轴线仍然应该一直绘制,但刻度线和条形图数据应该一直填充 30 像素,并且应该保持比例.

注意:为了清楚起见,我删除了其余的刻度和刻度值。 X 轴刻度应放置在每个条的中间。

enter image description here

最佳答案

为了达到您想要的效果,您必须更改秤的设置。由于您有条形图,我假设您有:

  • x 位置的带刻度;
  • y 位置的线性刻度;

此外,因为您没有共享任何运行代码,所以我的回答将基于此 basic bar chart from d3noob .

第一步是设置填充:

const horPadding = 30;
const vertPadding = 30;

现在让我们改变比例:

带尺度

为了设置带尺度的填充,我们将使用 scale.paddingOuter

因为传递给该方法的值是 scale.step() 的倍数(也就是说,如果您传递 1,则等于传递 scale。 step()),我们将使用它来计算 30px 的填充量。数学很简单:

scale.paddingOuter(horPadding / x.step());

线性比例

这里的数学有点复杂。基本上,我们将计算要达到 30px 必须低于零的多少(假设您的下域为零,这是条形图中的一个非常基本的规则!)。

这可以用这个作为域的第一个值来完成,替换 0:

-(d3.max(data, function(d) {
    return d.sales;
}) * vertPadding / height)

这里,sales 是用于条形高度的属性,height 显然是用于刻度和轴的高度。根据您的需要更改它们。

然后,不要忘记使用 scale(0) 来设置矩形的底边。在我分享的那个 d3noob 代码中:

return y(0) - y(d.sales); 

这是结果:

var csv = `salesperson,sales
Bob,33
Robin,12
Anne,41
Mark,16
Joe,59
Eve,38`;

const horPadding = 30;
const vertPadding = 30;

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

var x = d3.scaleBand()
  .range([0, width])
  .padding(0.1);
var y = d3.scaleLinear()
  .range([height, 0]);

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

const data = d3.csvParse(csv, d3.autoType);

x.domain(data.map(function(d) {
    return d.salesperson;
  }))
  .paddingOuter(horPadding / x.step());

y.domain([-(d3.max(data, function(d) {
  return d.sales;
}) * vertPadding / height), d3.max(data, function(d) {
  return d.sales;
})])


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 y(0) - y(d.sales);
  });

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

svg.append("g")
  .call(d3.axisLeft(y));
.bar {
  fill: steelblue;
}
<script src="//d3js.org/d3.v4.min.js"></script>

关于javascript - 如何在 D3 轴和图表之间应用填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57101469/

相关文章:

javascript - Promise 中的代码执行和使用 return 语句

javascript - 如何添加 2 个开放功能但延迟一个?

javascript - 如何修复此 "Execution failed: These columns are out of bounds."错误?

javascript - RxJS Observable :'Skip is not a function'(或任何其他函数)

javascript - 将 Stringarray 交给 django 模板并在 d3 中使用它

javascript - 等待的 Promises 创建 Array.map 返回 <pending>

node.js - 在 globals.js 中注释 async 不会影响其在服务中的使用

javascript - x轴文本重叠c3js

javascript - 利用 d3 在 SVG 内渲染foreignObject 失败

d3.js - DC.js 折线图 - 没有显示折线