kleros/kleros-v2

View on GitHub
web/src/pages/Home/CourtOverview/TimeSeriesChart.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import React from "react";
import styled, { useTheme } from "styled-components";

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  TimeScale,
  Tooltip,
  ScriptableContext,
} from "chart.js";
import { Line } from "react-chartjs-2";
import "chartjs-adapter-moment";

const LineContainer = styled.div`
  height: 220px;
  margin-top: 16px;
`;

ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, TimeScale, Tooltip);

interface ITimeSeriesChart {
  data: { x: number; y: number }[];
}

const TimeSeriesChart: React.FC<ITimeSeriesChart> = ({ data }) => {
  const theme = useTheme();
  const options = {
    responsive: true,
    maintainAspectRatio: false,
    elements: {
      point: {
        radius: 0,
      },
    },
    interaction: {
      axis: "x",
      intersect: false,
    },
    tooltips: {
      position: "nearest",
    },
    scales: {
      x: {
        type: "time",
        grid: { display: false },
        ticks: {
          color: theme.secondaryText,
        },
      },
      y: {
        grid: { color: theme.stroke },
        ticks: {
          color: theme.secondaryText,
        },
        suggestedMin: 0,
      },
    },
    plugins: {
      tooltip: {
        position: "custom",
        backgroundColor: theme.whiteBackground,
        titleColor: theme.primaryText,
        borderColor: theme.stroke,
        borderWidth: 1,
        displayColors: false,
        callbacks: {
          labelTextColor: () => theme.primaryText,
        },
      },
    },
  };

  return (
    <LineContainer>
      {
        // eslint-disable-next-line
        // @ts-ignore
        <Line
          {...{
            data: {
              datasets: [
                {
                  data,
                  // borderColor: theme.primaryBlue,
                  stepped: true,
                  cubicInterpolationMode: "monotone",
                  borderColor: (context: ScriptableContext<"line">) => {
                    const ctx = context.chart.ctx;
                    const gradient = ctx.createLinearGradient(0, 0, 0, 200);
                    gradient.addColorStop(0, theme.primaryBlue);
                    gradient.addColorStop(1, theme.secondaryPurple);
                    return gradient;
                  },
                },
              ],
            },
            options,
          }}
          plugins={[
            {
              id: "line-draw",
              afterDatasetsDraw: (chart) => {
                if (chart.tooltip?._active?.length) {
                  const x = chart.tooltip._active[0].element.x;
                  const y = chart.tooltip._active[0].element.y;
                  const yAxis = chart.scales.y;

                  const ctx = chart.ctx;
                  ctx.save();
                  ctx.beginPath();
                  ctx.moveTo(x, y);
                  ctx.lineTo(x, yAxis.bottom);
                  ctx.lineWidth = 1;
                  ctx.strokeStyle = theme.secondaryPurple;
                  ctx.setLineDash([4, 4]);
                  ctx.stroke();
                  ctx.restore();
                }
              },
            },
          ]}
        />
      }
    </LineContainer>
  );
};
export default TimeSeriesChart;