_getScaleSettings() {
    const {data, dataFilter, xDomain, yDomain, getX, getY0, getY} = this.props;

    if (xDomain && yDomain) {
      return {xDomain, yDomain};
    }

    let x = xDomain || [Infinity, -Infinity];
    let y = yDomain || [0, 0];

    for (const key in data) {
      if (dataFilter(key)) {
        const values = data[key];
        if (Array.isArray(values) && values.length > 0) {
          x =
            xDomain ||
            values.reduce((acc, d) => {
              const x0 = getX(d);
              acc[0] = Math.min(acc[0], x0);
              acc[1] = Math.max(acc[1], x0);
              return acc;
            }, x);
          y =
            yDomain ||
            values.reduce((acc, d) => {
              const y1 = getY(d);
              const y0 = getY0(d);
              acc[0] = Math.min(acc[0], y1);
              acc[1] = Math.max(acc[1], y1);
              if (Number.isFinite(y0)) {
                acc[0] = Math.min(acc[0], y0);
                acc[1] = Math.max(acc[1], y0);
              }
              return acc;
            }, y);
        }
      }
    }

    if (!yDomain) {
      // Snap the bounds to nice round numbers
      y = scaleLinear()
        .domain(y)
        .nice()
        .domain();
    }

    return {xDomain: x, yDomain: y};
  }
A metric chart draws a chart with optional percentiles and lags