function Chart({
  magnitude,
  height,
  data,
  color,
  tickXScale,
  renderTickY,
  renderTooltip,
  valueKey = "value",
  suggestedMin,
  suggestedMax,
}: Props) {
  const canvasRef = useRef(null);
  const chartRef = useRef(null);
  const theme = useTheme("colors.palette");
  const [tooltip, setTooltip] = useState();
  const valueKeyRef = useRef(valueKey);

  const generatedData = useMemo(
    () => ({
      datasets: [
        {
          label: "all accounts",
          borderColor: color,
          backgroundColor: ({ chart }) => {
            const gradient = chart.ctx.createLinearGradient(0, 0, 0, chart.height / 1.2);
            gradient.addColorStop(0, Color(color).alpha(0.4));
            gradient.addColorStop(1, Color(color).alpha(0.0));
            return gradient;
          },
          pointRadius: 0,
          borderWidth: 2,
          data: data.map((d, i) => ({
            x:
              tickXScale === "week"
                ? new Date(d.date)
                : tickXScale === "day"
                ? moment(new Date(d.date))
                    .startOf("hour")
                    .toDate()
                : tickXScale === "minute"
                ? moment()
                    .subtract(i * 5, "minutes")
                    .toDate()
                : moment(new Date(d.date))
                    .startOf("day")
                    .toDate(),
            y: d[valueKey],
          })),
        },
      ],
    }),
    [color, data, valueKey, tickXScale],
  );

  const generateOptions = useMemo(
    () => ({
      animation: {
        duration: 0,
      },
      responsive: true,
      maintainAspectRatio: false,
      tooltips: {
        enabled: false,
        intersect: false,
        mode: "index",
        custom: tooltip => setTooltip(tooltip),
      },
      legend: {
        display: false,
      },
      scales: {
        xAxes: [
          {
            type: "time",
            gridLines: {
              display: false,
              color: theme.text.shade10,
            },
            ticks: {
              fontColor: theme.text.shade60,
              fontFamily: "Inter",
              maxTicksLimit: 7,
              maxRotation: 0.1, // trick to make the graph fit the whole canvas regardless of data
              minRotation: 0,
              padding: 12,
            },
            time: {
              unit: tickXScale === "day" ? "hour" : tickXScale === "minute" ? "minute" : "day",
              displayFormats: {
                quarter: "MMM YYYY",
                minute: "HH:mm",
              },
            },
          },
        ],
        yAxes: [
          {
            gridLines: {
              color: theme.text.shade10,
              borderDash: [5, 5],
              drawTicks: false,
              drawBorder: false,
              zeroLineColor: theme.text.shade10,
            },
            ticks: {
              suggestedMin: suggestedMin || 0,
              suggestedMax: suggestedMin || 10 ** Math.max(magnitude - 4, 1),
              maxTicksLimit: 4,
              fontColor: theme.text.shade60,
              fontFamily: "Inter",
              padding: 10,
              callback: value => renderTickY(value),
            },
          },
        ],
      },
      layout: {
        padding: {
          left: 0,
          right: 10, // trick to make the graph fit the whole canvas regardless of data
          top: 0,
          bottom: 0,
        },
      },
    }),
    [
      theme.text.shade10,
      theme.text.shade60,
      tickXScale,
      magnitude,
      renderTickY,
      suggestedMin,
      suggestedMax,
    ],
  );

  useLayoutEffect(() => {
    if (chartRef.current) {
      let shouldAnimate = false;
      if (valueKeyRef.current !== valueKey) {
        valueKeyRef.current = valueKey;
        shouldAnimate = true;
      }

      chartRef.current.data.datasets[0].data = generatedData.datasets[0].data;
      chartRef.current.options = generateOptions;
      chartRef.current.update(shouldAnimate ? 500 : 0);
    } else {
      chartRef.current = new ChartJs(canvasRef.current, {
        type: "line",
        data: generatedData,
        options: generateOptions,
      });
    }
  }, [generateOptions, generatedData, valueKey]);

  return (
    <ChartContainer height={height}>
      <canvas ref={canvasRef} />
      {tooltip && renderTooltip ? (
        <Tooltip
          tooltip={tooltip}
          theme={theme}
          renderTooltip={renderTooltip}
          color={color}
          data={data}
        />
      ) : null}
    </ChartContainer>
  );
}
Chart
                                  -----

                                   XX
                                  XXXX
                         X       XX  X
                        XXXX    XX   X
                       XX  X  XX     X
                      X    XXXX       X     XX    X
                     XX     XX        X   XX XX  XX
                    XX                XX XX   XXXX
                                       XX
                                       XX
 Usage:

   <Chart
     data={data}
     color="#5f8ced"   // Main color for line, gradient, etc.
     height={300}      // Fix height. Width is responsive to container.
   />

   `data` looks like:

    [
      { date: '2018-01-01', value: 10 },
      { date: '2018-01-02', value: 25 },
      { date: '2018-01-03', value: 50 },
    ]