D3.js d3面积图在x下方填充

D3.js d3面积图在x下方填充,d3.js,D3.js,我试图画面积图,但它在x轴下填充。在下面的代码中,我使用了y0(yScale(0)),正如我在许多示例中看到的那样,我还试图给出y0(高度),但它没有给出正确的输出。我希望该区域仅在x轴上方填充,若y轴值为+ve,若y轴值为-ve,则该区域将高于y轴的最大刻度 const D3Node = require('d3-node'); getGraphString: (data,yAxisTickFormat) => { const d3n = new D3Node() // init

我试图画面积图,但它在x轴下填充。在下面的代码中,我使用了y0(yScale(0)),正如我在许多示例中看到的那样,我还试图给出y0(高度),但它没有给出正确的输出。我希望该区域仅在x轴上方填充,若y轴值为+ve,若y轴值为-ve,则该区域将高于y轴的最大刻度

const D3Node = require('d3-node');

getGraphString: (data,yAxisTickFormat) => {
    const d3n = new D3Node() // initializes D3 with container element
    const d3 = d3n.d3;

    let margin = { top: 20, right: 30, bottom: 20, left: 40 },
      width = 275,
      height = 200;

    let svg = d3n.createSVG(width, height+margin.top+margin.bottom);
    let xScale = d3.scaleTime().range([margin.left, width - margin.right])
      .domain(d3.extent(data, function (d) { return d.date })), 
    yScale = d3.scaleLinear().range([height - margin.top, margin.bottom])
        .domain(d3.extent(data, function (d) { return d.value }));
  
    svg.append('g').attr("class", "xAxis")
      .attr("transform", "translate(0," + (height - margin.bottom) + ")") //The transforms are SVG transforms
      .call(d3.axisBottom(xScale).ticks(d3.timeYear).tickFormat(d3.timeFormat('%Y')))
      .selectAll("text")
      .style("text-anchor","end")
      .attr("dx", "-.9em")
      .attr("dy", ".50em")
      .attr("transform","rotate(-45)")

    svg.append("g") //We create an SVG Group Element to hold all the elements that the axis function produces.
      .attr("transform", "translate(" + (margin.left) + ",0)")
      .attr("class","yAxis")
      .call(d3.axisLeft(yScale).ticks(4).tickFormat(d3.format(yAxisTickFormat)))
      .selectAll("text")
      .style("text-anchor","end")
      .attr("dy", "0.32em")
      .attr("dx", "-0.4em")

    let lineFunc = d3.line().x(function (obj) { return xScale(obj.date) })
      .y(function (obj) { return yScale(obj.value) })
    svg.append("path")
      .attr("d", lineFunc(data))
      .attr("stroke", '#002046')
      .attr("stroke-width", 3)
      .attr("fill", "none");
    
    let area = d3.area()
      .curve(d3.curveLinear)
      .x(function (d) { return xScale(d.date); })
      .y0(yScale(0))
      .y1(function (d) { return yScale(d.value); });

    svg.append("path")
      .style("fill", "#002046")
      .attr("d", area(data));
    return d3n.svgString();
  }
    let data =[ { date: 2019-01-01T00:00:00.000Z, value: 0.6330419130189774 },
  { date: 2018-01-01T00:00:00.000Z, value: 0.6266752649582236 },
  { date: 2017-01-01T00:00:00.000Z, value: 0.6403446517126394 },
  { date: 2016-01-01T00:00:00.000Z, value: 0.6432956408788177 } ];
getGraphString(data,'.0%');


问题

如果y轴(缩放域)从0开始,则
yScale(0)
是该区域的适当基线。但是,刻度的域范围不是从0开始的,它取决于数据集:

 yScale = d3.scaleLinear().range([height - margin.top, margin.bottom])
    .domain(d3.extent(data, function (d) { return d.value }));
数据集中的最低值是
0.6266…
而不是零。在使用
yScale(0)
D3插值,其中
y(0)
将是,在您的情况下,这将需要将轴沿页面向下延伸一点并脱离SVG

解决方案

我们可以手动设置基线,例如:
area.y0(yScale(0.6266…)
。这会将基线放置在y轴的底部。但您不需要手动设置,因为您可以使用以下选项进行设置:

 area.y0(yScale.range()[0]);
range()返回一个数组,其中包含yScale的缩放范围(因此y轴),我们希望该区域的底面与轴相同

yScale.range()-如果0是域的最小值(
0==yScale.domain()[0]
),则它是到常用的
区域的一个短跳转。y0(yScale(0))

备选方案

或者,如果希望轴包含零,可以将
yScale(0)
作为基线,并将0设置为刻度域的最小值:

 .domain([0,d3.max(function(d) { return d.value; })])

无论哪种方式,如果希望区域底部与轴底部对齐,则作为标尺范围和面积的最小值提供的值.y0应相同。(此值通常也应等于x轴的y平移值)。

是,此操作有效。但若我在y轴上只有-ve值,我得到的是图中线条下方的图表区域,而不是线条上方的区域。嗨,安德鲁,你们能帮我查询一下吗?这是个新问题。