Skip to content

Instantly share code, notes, and snippets.

@joshblack
Last active June 24, 2016 20:59
Show Gist options
  • Save joshblack/09226f76ca55c5c82be1f2766c1fdc23 to your computer and use it in GitHub Desktop.
Save joshblack/09226f76ca55c5c82be1f2766c1fdc23 to your computer and use it in GitHub Desktop.

Creating a line in D3 in React

import {
  scaleLinear,
  scaleTime,
} from 'd3-scale';
import {
  line
} from 'd3-shape';
import {
  extent
} from 'd3-array';
import {
  timeParse
} from 'd3-time-format';

class Line extends React.Component {
  render() {
    const x = scaleTime()
      .domain(extent(data, (d) => d.date))
      .range([0, 960]);
    
    const y = scaleLinear()
      .domain(extent(data, (d) => d.close))
      .range([500, 0]);
    
    const l = line()
      .x((d) => x(d.date))
      .y((d) => y(d.close));
    
    const p = l(data);
    
    return (
      <g>
        <path style={{
          fill: 'none',
          stroke: 'steelblue',
          strokeWidth: '1.5px',
        }} d={p} />
      </g>
    );
  }
}

Basically all you need to do is setup your x and y values, calculate the path for your line and pass that into your DOME node.

import React from 'react';
import {
  axisTop,
  axisRight,
  axisBottom,
  axisLeft
} from 'd3-axis';
import {
  scaleLinear,
  scaleTime,
  scaleOrdinal,
  schemeCategory10,
} from 'd3-scale';
import {
  line
} from 'd3-shape';
import {
  extent,
  min,
  max,
} from 'd3-array';
import {
  timeParse
} from 'd3-time-format';
import { stockData, multiLineData } from './data';

const translateX = (scale0, scale1, d) => {
  const x = scale0(d);

  return `translate(${(isFinite(x) ? x : scale1(x))},0)`;
};

const translateY = (scale0, scale1, d) => {
  const y = scale0(d);

  return `translate(0,${(isFinite(y) ? y : scale1(d))})`;
};

// const formatDate = timeParse('%d-%b-%y');
// const data = stockData.map(({ date, close }) => ({
  // date: formatDate(date),
  // close: +close,
// }));

const formatDate = timeParse('%Y%m%d');
const data = multiLineData.map(({
  date,
  'New York': ny,
  'San Francisco': sf,
  'Austin': au
}) => ({
  date: formatDate(date),
  'New York': +ny,
  'San Francisco': +sf,
  'Austin': +au,
}));

class XAxis extends React.Component {
  render() {
    console.clear();

    const color = scaleOrdinal(schemeCategory10)
      .domain(Object.keys(data[0]).filter((key) => key !== 'date'));
    const cities = color.domain().map((name) => {
      return {
        name,
        values: data.map((d) => ({
          date: d.date,
          temperature: +d[name],
        })),
      };
    });

    const x = scaleTime()
      .domain(extent(data, (d) => d.date))
      .range([0, 960]);

    const y = scaleLinear()
      .domain([
        min(cities, (c) => min(c.values, (v) => v.temperature)),
        max(cities, (c) => max(c.values, (v) => v.temperature))
      ])
      .range([0, 500]);

    const generateLine = line()
      .x((d) => x(d.date))
      .y((d) => y(d.temperature));

    // const lines = cities.map((city) => {
      // console.log(city);
      // return generateLine(city.values);
    // });

    return (
      <g>
        {cities.map(({ name, values }, i) => (
          <path key={i} fill="none" strokeWidth="1.5" stroke={color(name)} d={generateLine(values)} />
        ))}
      </g>
    )
  }
}

export class App extends React.Component {
  render() {
    return (
      <section>
        <svg width="960" height="500">
          <XAxis />
        </svg>
      </section>
    );
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment