Skip to content

Instantly share code, notes, and snippets.

@CosAnca
Forked from sebastiandedeyne/LineChart.tsx
Created September 27, 2019 19:54
Show Gist options
  • Select an option

  • Save CosAnca/fd5ed2d881ee006b7f8c7cdfbba7388a to your computer and use it in GitHub Desktop.

Select an option

Save CosAnca/fd5ed2d881ee006b7f8c7cdfbba7388a to your computer and use it in GitHub Desktop.

Revisions

  1. @sebastiandedeyne sebastiandedeyne revised this gist Sep 27, 2019. No changes.
  2. @sebastiandedeyne sebastiandedeyne created this gist Sep 27, 2019.
    55 changes: 55 additions & 0 deletions LineChart.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,55 @@
    import React from 'react';

    type Props = {
    data: Array<[number, string]>;
    };

    export default function LineChart({ data }: Props) {
    if (!data.length) {
    return null;
    }

    const maxValue = Math.max(...data.map(([value]) => value));

    const points = data
    .map(([value], index) => {
    return `L ${index} ${maxValue - value}`;
    })
    .join(' ');

    return (
    <div className="linechart">
    {data.map(([value, label], index) => (
    <div key={index} className="linechart-x-line" style={{ left: `${(index / (data.length - 1)) * 100}%` }}>
    <div className="linechart-x-label">{label}</div>
    <div className="linechart-x-value" style={{ bottom: `${(value / maxValue) * 100}%` }}>
    {value}
    </div>
    </div>
    ))}
    <div className="linechart-y-line" style={{ bottom: '100%' }}>
    <div className="linechart-y-label">{maxValue}</div>
    </div>
    <div className="linechart-y-line" style={{ bottom: '50%' }} />
    <div className="linechart-y-line" style={{ bottom: '0' }} />
    <svg className="linechart-chart" viewBox={`0 0 ${data.length - 1} ${maxValue}`} preserveAspectRatio="none">
    <defs>
    <linearGradient id="background" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" style={{ stopColor: '#5d78ff', stopOpacity: 0.4 }} />
    <stop offset="100%" style={{ stopColor: '#5d78ff', stopOpacity: 0 }} />
    </linearGradient>
    </defs>
    <path d={`M 0 ${maxValue + 1} ${points} L 23 ${maxValue + 1} Z`} fill="url(#background)" />
    <path
    d={points.replace('L', 'M')}
    fill="none"
    stroke="#5d78ff"
    strokeOpacity="0.3"
    strokeWidth="1"
    strokeLinecap="round"
    vectorEffect="non-scaling-stroke"
    />
    </svg>
    </div>
    );
    }
    54 changes: 54 additions & 0 deletions linechart.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    .linechart {
    font-size: 10px;
    height: 200px;
    position: relative;
    width: 100%;
    font-variant-numeric: tabular-nums;
    }

    .linechart-x-line {
    background-color: var(--secondary);
    bottom: 0;
    position: absolute;
    top: 0;
    width: 1px;
    }

    .linechart-x-label {
    bottom: -20px;
    left: 50%;
    position: absolute;
    transform: translateX(-50%);
    }

    .linechart-x-value {
    background-color: var(--primary);
    border-radius: 4px;
    color: white;
    font-weight: 600;
    left: 50%;
    padding: 0 3px;
    position: absolute;
    text-align: center;
    transform: translateX(-50%) translateY(6px);
    z-index: 10;
    }

    .linechart-y-line {
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background-color: var(--secondary);
    font-size: 10px;
    }

    .linechart-y-label {
    transform: translateX(-15px) translateY(-7px);
    }

    .linechart-chart {
    height: 100%;
    position: relative;
    width: 100%;
    }