text: import React, { Component } from "react";
  
  import { LinearGradient, Line, Text, Defs, Stop } from "react-native-svg";
  
  class AbstractChart extends Component {
    calcScaler = data => {
      if (this.props.fromZero) {
        return Math.max(...data, 0) - Math.min(...data, 0) || 1;
      } else {
        return Math.max(...data) - Math.min(...data) || 1;
      }
    };
  
    calcBaseHeight = (data, height) => {
      const min = Math.min(...data);
      const max = Math.max(...data);
      if (min >= 0 && max >= 0) {
        return height;
      } else if (min < 0 && max <= 0) {
        return 0;
      } else if (min < 0 && max > 0) {
        return (height * max) / this.calcScaler(data);
      }
    };
  
    calcHeight = (val, data, height) => {
      const max = Math.max(...data);
      const min = Math.min(...data);
      if (min < 0 && max > 0) {
        return height * (val / this.calcScaler(data));
      } else if (min >= 0 && max >= 0) {
        return this.props.fromZero
          ? height * (val / this.calcScaler(data))
          : height * ((val - min) / this.calcScaler(data));
      } else if (min < 0 && max <= 0) {
        return this.props.fromZero
          ? height * (val / this.calcScaler(data))
          : height * ((val - max) / this.calcScaler(data));
      }
    };
  
    getPropsForBackgroundLines() {
      const { propsForBackgroundLines = {} } = this.props.chartConfig;
      return {
        stroke: this.props.chartConfig.color(0.2),
        strokeDasharray: "5, 10",
        strokeWidth: 1,
        ...propsForBackgroundLines
      };
    }
  
    getPropsForLabels() {
      const {
        propsForLabels = {},
        color,
        labelColor = color
      } = this.props.chartConfig;
      return {
        fontSize: 12,
        fill: labelColor(0.8),
        ...propsForLabels
      };
    }
  
    renderHorizontalLines = config => {
      const { count, width, height, paddingTop, paddingRight } = config;
      const basePosition = height - height / 4;
  
      return [...new Array(count + 1)].map((_, i) => {
        const y = (basePosition / count) * i + paddingTop;
        return (
          <Line
            key={Math.random()}
            x1={paddingRight}
            y1={y}
            x2={width}
            y2={y}
            {...this.getPropsForBackgroundLines()}
          />
        );
      });
    };
  
    renderHorizontalLine = config => {
      const { width, height, paddingTop, paddingRight } = config;
      return (
        <Line
          key={Math.random()}
          x1={paddingRight}
          y1={height - height / 4 + paddingTop}
          x2={width}
          y2={height - height / 4 + paddingTop}
          {...this.getPropsForBackgroundLines()}
        />
      );
    };
  
    renderHorizontalLabels = config => {
      const {
        count,
        data,
        height,
        paddingTop,
        paddingRight,
        horizontalLabelRotation = 0,
        decimalPlaces = 2,
        formatYLabel = yLabel => yLabel
      } = config;
      const {
        yAxisLabel = "",
        yAxisSuffix = "",
        yLabelsOffset = 12
      } = this.props;
  
      return [...Array(count === 1 ? 1 : count + 1).keys()].map((i, _) => {
        let yLabel = i * count;
  
        if (count === 1) {
          yLabel = `${yAxisLabel}${formatYLabel(
            data[0].toFixed(decimalPlaces)
          )}${yAxisSuffix}`;
        } else {
          const label = this.props.fromZero
            ? (this.calcScaler(data) / count) * i + Math.min(...data, 0)
            : (this.calcScaler(data) / count) * i + Math.min(...data);
          yLabel = `${yAxisLabel}${formatYLabel(
            label.toFixed(decimalPlaces)
          )}${yAxisSuffix}`;
        }
  
        const basePosition = height - height / 4;
        const x = paddingRight - yLabelsOffset;
        const y =
          count === 1 && this.props.fromZero
            ? paddingTop + 4
            : (height * 3) / 4 - (basePosition / count) * i + paddingTop;
        return (
          <Text
            rotation={horizontalLabelRotation}
            origin={`${x}, ${y}`}
            key={Math.random()}
            x={x}
            textAnchor="end"
            y={y}
            {...this.getPropsForLabels()}
          >
            {yLabel}
          </Text>
        );
      });
    };
  
    renderVerticalLabels = config => {
      const {
        labels = [],
        width,
        height,
        paddingRight,
        paddingTop,
        horizontalOffset = 0,
        verticalLabelRotation = 0,
        formatXLabel = xLabel => xLabel
      } = config;
      const {
        xAxisLabel = "",
        xLabelsOffset = 0,
        hidePointsAtIndex = []
      } = this.props;
      const fontSize = 12;
      let fac = 1;
      return labels.map((label, i) => {
        if (hidePointsAtIndex.includes(i)) {
          return null;
        }
        const x =
          (((width - paddingRight) / labels.length) * i +
            paddingRight +
            horizontalOffset) *
          fac;
        const y = (height * 3) / 4 + paddingTop + fontSize * 2 + xLabelsOffset;
        return (
          <Text
            origin={`${x}, ${y}`}
            rotation={verticalLabelRotation}
            key={Math.random()}
            x={x}
            y={y}
            textAnchor={verticalLabelRotation === 0 ? "middle" : "start"}
            {...this.getPropsForLabels()}
          >
            {`${formatXLabel(label)}${xAxisLabel}`}
          </Text>
        );
      });
    };
  
    renderVerticalLines = config => {
      const { data, width, height, paddingTop, paddingRight } = config;
      const { yAxisInterval = 1 } = this.props;
      return [...new Array(Math.ceil(data.length / yAxisInterval))].map(
        (_, i) => {
          return (
            <Line
              key={Math.random()}
              x1={Math.floor(
                ((width - paddingRight) / (data.length / yAxisInterval)) * i +
                  paddingRight
              )}
              y1={0}
              x2={Math.floor(
                ((width - paddingRight) / (data.length / yAxisInterval)) * i +
                  paddingRight
              )}
              y2={height - height / 4 + paddingTop}
              {...this.getPropsForBackgroundLines()}
            />
          );
        }
      );
    };
  
    renderVerticalLine = config => {
      const { height, paddingTop, paddingRight } = config;
      return (
        <Line
          key={Math.random()}
          x1={Math.floor(paddingRight)}
          y1={0}
          x2={Math.floor(paddingRight)}
          y2={height - height / 4 + paddingTop}
          {...this.getPropsForBackgroundLines()}
        />
      );
    };
  
    renderDefs = config => {
      const {
        width,
        height,
        backgroundGradientFrom,
        backgroundGradientTo,
        useShadowColorFromDataset,
        data
      } = config;
      const fromOpacity = config.hasOwnProperty("backgroundGradientFromOpacity")
        ? config.backgroundGradientFromOpacity
        : 1.0;
      const toOpacity = config.hasOwnProperty("backgroundGradientToOpacity")
        ? config.backgroundGradientToOpacity
        : 1.0;
  
      const fillShadowGradient = config.hasOwnProperty("fillShadowGradient")
        ? config.fillShadowGradient
        : this.props.chartConfig.color();
  
      const fillShadowGradientOpacity = config.hasOwnProperty(
        "fillShadowGradientOpacity"
      )
        ? config.fillShadowGradientOpacity
        : 0.1;
  
      return (
        <Defs>
          <LinearGradient
            id="backgroundGradient"
            x1="0"
            y1={height}
            x2={width}
            y2={0}
          >
            <Stop
              offset="0"
              stopColor={backgroundGradientFrom}
              stopOpacity={fromOpacity}
            />
            <Stop
              offset="1"
              stopColor={backgroundGradientTo}
              stopOpacity={toOpacity}
            />
          </LinearGradient>
          {useShadowColorFromDataset ? (
            data.map((dataset, index) => (
              <LinearGradient
                id={`fillShadowGradient_${index}`}
                key={`${index}`}
                x1={0}
                y1={0}
                x2={0}
                y2={height}
              >
                <Stop
                  offset="0"
                  stopColor={dataset.color ? dataset.color() : fillShadowGradient}
                  stopOpacity={fillShadowGradientOpacity}
                />
                <Stop
                  offset="1"
                  stopColor={
                    dataset.color
                      ? dataset.color(fillShadowGradientOpacity)
                      : fillShadowGradient
                  }
                  stopOpacity="0"
                />
              </LinearGradient>
            ))
          ) : (
            <LinearGradient
              id="fillShadowGradient"
              x1={0}
              y1={0}
              x2={0}
              y2={height}
            >
              <Stop
                offset="0"
                stopColor={fillShadowGradient}
                stopOpacity={fillShadowGradientOpacity}
              />
              <Stop offset="1" stopColor={fillShadowGradient} stopOpacity="0" />
            </LinearGradient>
          )}
        </Defs>
      );
    };
  }
  
  export default AbstractChart;
  