首页 > 解决方案 > 无法在 D3 中生成区域

问题描述

我正在尝试复制此代码

但不确定为什么没有生成阴影区域(蓝色和红色)。

实际上,我希望面积 < 48 小时的折线图过渡用蓝色着色,48 小时后用红色着色。0正如上面链接中所建议的那样,我创建了一个从到的剪辑区域width。但不知何故,该区域没有生成。

线路径正在生成,但渐变区域路径没有成功:

在此处输入图像描述

这是 stackblitz链接

这是代码:

  this.g = d3
      .select("#svgcontainer")
      .append("svg")
      .attr("width", this.width + this.margin.left + this.margin.right)
      .attr("height", this.height + this.margin.top + this.margin.bottom)
      .append("g")
      .attr(
        "transform",
        "translate(" + this.margin.left + ", " + this.margin.top + ")"
      );

    this.defs = this.g.append("defs");
    const clip = this.defs.append("clipPath").attr("id", "clip");
    this.clipRect = clip
      .append("rect")
      .attr("width", 0)
      .attr("height", this.height);
    
  createArea(datum) {
    return d3
      .area()
      .y0(this.height)
      .y1((d: any) => this.yScale(d.adjCount))
      .x((d: any) => this.xScale(d.hrCount) + this.xScale.bandwidth() / 2)(
      datum
    );
  }
  
  createDataLine(): void {
    this.line = d3
      .line()
      .x((d: any) => this.xScale(d.hrCount) + this.xScale.bandwidth() / 2)
      .y((d: any) => this.yScale(d.adjCount));
  }
    
  createGradient(isShadowBefore48Hr: boolean): void {
    // Blue
    const colorArray1 = [ ... ];
    // Red
    const colorArray2 = [ ... ];
    const id: string = isShadowBefore48Hr ? "grad1" : "grad2";
    const angle: number = isShadowBefore48Hr ? -15 : 0;
    const grad = this.defs
      .append("linearGradient")
      .attr("id", id)
      .attr("x1", "0%")
      .attr("x2", "0%")
      .attr("y1", "0%")
      .attr("y2", "100%")
      .attr("gradientTransform", "rotate(" + angle + ")");
    grad
      .selectAll("stop")
      .data(isShadowBefore48Hr ? colorArray1 : colorArray2)
      .enter()
      .append("stop")
      .style("stop-color", (d: any) => { return d[0]; })
      .style("stop-opacity", (d: any) => { return d[1]; })
      .attr("offset", (d: any, i: any) => { return 100 * (i / 2) + "%"; });
  }

  createShadowArea(): void {
    // Add first area
    this.g
      .append("path")
      .data(this.graphData.filter(d => d.hrCount <= 48))
      .attr("class", "area")
      .attr("d", d => this.createArea(d))
      .attr("fill", "url(#" + "grad1" + ")")
      .attr("clip-path", "url(#clip)");

    // Add second area
    this.g
      .append("path")
      .data(this.graphData.filter(d => d.hrCount >= 48))
      .attr("class", "area")
      .attr("d", d => this.createArea(d))
      .attr("fill", "url(#" + "grad2" + ")")
      .attr("clip-path", "url(#clip)");

    // Add line path
    this.g
      .append("path")
      .attr("d", this.line(this.graphData))
      .attr("clip-path", "url(#clip)");
  }

  createTransition(): void {
    this.clipRect
      .transition()
      .duration(5000)
      .ease(d3.easeLinear)
      .attr("width", this.width);
  }

标签: d3.js

解决方案


您正在使用data()而不是datum()

这必须是

// Add first area
this.g
  .append("path")
  .datum(this.graphData.filter(d => d.hrCount <= 48))
  .attr("class", "area")
  .attr("d", d => this.createArea(d))
  .attr("fill", "url(#" + "grad1" + ")")
  .attr("clip-path", "url(#clip)");

// Add second area
this.g
  .append("path")
  .datum(this.graphData.filter(d => d.hrCount >= 48))
  .attr("class", "area")
  .attr("d", d => this.createArea(d))
  .attr("fill", "url(#" + "grad2" + ")")
  .attr("clip-path", "url(#clip)");

这是我的 stackblitz链接的分支


推荐阅读