首页 > 解决方案 > Svg“图表”填充

问题描述

我在 React 中有一个“图表”。我想为图表实现动画填充。我想调整 x 坐标,直到它应该在图表线下用一种颜色填充。目前,整个图表都充满了rgba(0,0,0,0.4). 第一个makePath用于填充,第二个用于线条。你能帮我解决如何在线下实现这种填充吗?目前我试图设置this.getSvgX(maxX)为 some data[xy].x,但后来我有一个对角线填充。否则你知道提供这个动画填充的库吗?谢谢!

  makePath() {
    const {data, color} = this.props;
    const minX = this.getMinX(), maxX = this.getMaxX();
    const minY = this.getMinY(), maxY = this.getMaxY();

    let pathD = "M " + this.getSvgX(data[0].x) + " " + this.getSvgY(data[0].y) + " ";

    pathD += data.map((point, i) => {
      return "L " + this.getSvgX(point.x) + " " + this.getSvgY(point.y) + " ";
    });

    pathD += "L " + this.getSvgX(maxX) + "," + this.getSvgY(minY) + " L " + this.getSvgX(minX) + "," + this.getSvgY(minY)  + " Z";

    return (
      <path className="linechart_path" d={pathD} style={{stroke: 'none', fill: 'rgba(0,0,0,0.4)'}} />
    );
  }

  makePath2() {
    const {data, color} = this.props;
    let pathD = "M " + this.getSvgX(data[0].x) + " " + this.getSvgY(data[0].y) + " ";

    pathD += data.map((point, i) => {
      return "L " + this.getSvgX(point.x) + " " + this.getSvgY(point.y) + " ";
    });

    return (
      <path className="linechart_path" d={pathD} style={{fill: 'none', stroke: 'black'}} />
    );
  }

完成 LineChart.js

import React, {Component} from "react";
import "./LineChart.css"

class LineChart extends Component {
  // GET MAX & MIN X
  getMinX() {
    const {data} = this.props;
    return data[0].x;
  }
  getMaxX() {
    const {data} = this.props;
    return data[data.length - 1].x;
  }
  // GET MAX & MIN Y
  getMinY() {
    const {data} = this.props;
    return data.reduce((min, p) => p.y < min ? p.y : min, data[0].y);
  }
  getMaxY() {
    const {data} = this.props;
    return data.reduce((max, p) => p.y > max ? p.y : max, data[0].y);
  }
  // GET SVG COORDINATES
  getSvgX(x) {
    const {svgWidth} = this.props;
    return (x / this.getMaxX() * svgWidth);
  }
  getSvgY(y) {
    const {svgHeight} = this.props;
    return svgHeight - (y / this.getMaxY() * svgHeight);
  }
  // BUILD SVG PATH
  makePath() {
    const {data, color} = this.props;
    const minX = this.getMinX(), maxX = this.getMaxX();
    const minY = this.getMinY(), maxY = this.getMaxY();

    let pathD = "M " + this.getSvgX(data[0].x) + " " + this.getSvgY(data[0].y) + " ";

    pathD += data.map((point, i) => {
      return "L " + this.getSvgX(point.x) + " " + this.getSvgY(point.y) + " ";
    });

    pathD += "L " + this.getSvgX(maxX) + "," + this.getSvgY(minY) + " L " + this.getSvgX(minX) + "," + this.getSvgY(minY)  + " Z";

    return (
      <path className="linechart_path" d={pathD} style={{stroke: 'none', fill: 'gray'}} />
    );
  }

  makePath2() {
    const {data, color} = this.props;
    let pathD = "M " + this.getSvgX(data[0].x) + " " + this.getSvgY(data[0].y) + " ";

    pathD += data.map((point, i) => {
      return "L " + this.getSvgX(point.x) + " " + this.getSvgY(point.y) + " ";
    });

    return (
      <path className="linechart_path" d={pathD} style={{fill: 'none', stroke: 'red'}} />
    );
  }
  // BUILD GRID AXIS
  makeAxis() {
  const minX = this.getMinX(), maxX = this.getMaxX();
  const minY = this.getMinY(), maxY = this.getMaxY();

  return (
    <g className="linechart_axis">
      <line
        x1={this.getSvgX(minX)} y1={this.getSvgY(minY)}
        x2={this.getSvgX(maxX)} y2={this.getSvgY(minY)} />
      <line
        x1={this.getSvgX(minX)} y1={this.getSvgY(minY)}
        x2={this.getSvgX(minX)} y2={this.getSvgY(maxY)} />
    </g>
    );
  }
  // RENDER & RETURN SVG PATH AND AXIS
  render() {
    const {svgHeight, svgWidth} = this.props;

    return (
      <svg style={{ position: 'absolute', zIndex: 5, top: 10, left: 100 }}  width="38%" height="17%" viewBox={`0 0 ${svgWidth} ${svgHeight}`}>
        {this.makePath()}
        {this.makePath2()}
        {this.makeAxis()}
      </svg>
    );
  }
}
// DEFAULT PROPS
LineChart.defaultProps = {
  data: [],
  color: '#2196F3',
  svgHeight: 200,
  svgWidth: 1200
}

export default LineChart;

标签: javascriptreactjssvggraphcharts

解决方案


推荐阅读