javascript - 区域填充的 D3 图不起作用

标签 javascript d3.js grid axis area

我想让折线图中的区域正确填充。 (看图看问题)

注意填充区域和填充下方的文本:

enter image description here

代码如下:

<!DOCTYPE html>
<style type="text/css">

.area {
    fill: lightsteelblue;
    stroke-width: 0;
}

</style>
<svg width="860" height="400"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var parseTime = d3.timeParse("%d-%b-%y");

var x = d3.scaleTime()
    .range([0, width]);

var y = d3.scaleLinear()
    .range([height, 0]);

var line = d3.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.close); });

d3.tsv("data.tsv", function(d) {
  d.date = parseTime(d.date);
  d.close = +d.close;
  return d;
}, function(error, data) {
  if (error) throw error;

  x.domain(d3.extent(data, function(d) { return d.date; }));
  y.domain([0, d3.max(data, function(d) { return d.close; })]);

var xAxis = d3.axisBottom(x)
    .ticks(d3.timeYear);

var yAxis = d3.axisRight(y)
    .tickSize(width);

var area = d3.area()
    .x0(function () {
    return 0,width;
})
    .x1(function (d) {
    return x(d.date);
}).y0(function () {
    return height,height;
})
    .y1(function (d) {
    return y(d.close);
});

var valueline = d3.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.close); });

g.append("g")
    .attr("transform", "translate(0," + height + ")")
    .call(customXAxis);

g.append("g")
    .call(customYAxis);

function customXAxis(g) {
  g.call(xAxis);
  g.select(".domain").remove();
  g.selectAll(".tick line")
  .attr("stroke", "#e9e9e9")
  .attr("height","510px")
  .attr("transform", "translate(0," + -height + ")");
}

function customYAxis(g) {
  g.call(yAxis);
  g.select(".domain").remove();
  g.selectAll(".tick:not(:first-of-type) line").attr("stroke", "#e9e9e9");
  g.selectAll(".tick text").attr("x", width - 18).attr("dy", -4);
}

  g.append("path")
      .datum(data)
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", 1.5)
      .attr("d", line);

g.append("path")
    .datum(data)
    .attr("class", "area")
    .attr("d", area);

});

</script>

此外,如果可能的话,如果有人知道,如何让区域填充不与 y Axis 文本和所有轴线重叠,以便文本和轴线位于区域填充之上。

还有一件事,我已经尝试了几个小时。如何获取 x 轴线与灰色 y 轴线一起创建网格?

如有任何帮助,我将不胜感激。谢谢。

最佳答案

对于您的主要问题:

您正在使用线生成器来创建面积图 - 在填充生成的路径时,您只需连接第一个点和最后一个点,即您的图像。生成器如何“知道”填充区域的底部应该在哪里? y Axis 值为零对于基数来说可能很常见,但它肯定不是通用的。 在任何情况下,线生成器都需要包含缩放 y 值为 0 的点以创建正确的填充 - 这不会是表示数据的准确线,除非起点和终点的 y 值为 0,这就是 d3 除了线生成器之外还提供区域生成器的原因。

使用 d3.area ( also, here's a canonical example likely using your data ) 而不是 d3.line:

var area = d3.area()
    .x(function(d) { return x(d.date); })
    .y1(function(d) { return y(d.close); })   // top of area
    .y0(yScale(0));                           // bottom of area

.y0 方法是可选的,如果未指定,则默认为零,但这里是关于它的文档:

If y is specified, sets the y0 accessor to the specified function or number and returns this area generator. If y is not specified, returns the current y0 accessor, which defaults to:

function y() { return 0; }

When an area is generated, the y0 accessor will be invoked for each defined element in the input data array, being passed the element d, the index i, and the array data as three arguments. See area.x0 for more information. (source).

y1 方法代表图表的顶部(与折线图中的 y 访问器相同),y0 方法代表底部,在您的情况下它是常量。

关于javascript - 区域填充的 D3 图不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49744686/

相关文章:

javascript - 如何在一组图像中创建单个图像翻转效果?

javascript - 如何使用 Webpack 同时创建 'web' 和 'node' 版本的包?

php - 换行会导致代码中断

javascript - d3.js 层次树中的直 Angular 链接样式

javascript - d3.js 在线聊天网格问题

python - Tkinter Canvas 和带网格的滚动条

javascript - 许多 Canvas 对象导致 "InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable"

javascript - 使用 d3.js 以 3x3 格式绘制多个圆圈

css - Bootstrap 和手机方向 - 表单按钮定位

css - 如何在 Bootstrap 3x 中指定一次网格宽度(而不是每个媒体大小一次)?