Categories
React D3

Adding Graphics to a React App with D3 — Format TSVs and Load CSVs

D3 lets us add graphics to a front-end web app easily.

Vue is a popular front end web framework.

They work great together. In this article, we’ll look at how to add graphics to a Vue app with D3.

tsvFormat

We can use the tsvFormat method to convert an array of objects into a tab-separated string.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

const data = [
  { year: 2011, population: 10 },
  { year: 2012, population: 20 },
  { year: 2013, population: 30 }
];
export default function App() {
  useEffect(() => {
    const string = d3.tsvFormat(data, ["year", "population"]);
    console.log(string);
  }, []);

  return <div className="App"></div>;
}

Then the string is:

year population
2011 10
2012 20
2013 30

We pass in an array of objects as the first argument.

The 2nd argument has an array of the column heading strings.

tsvFormatRows

We can call the tsvFormatRows method to convert a nested array into a tab-separated string.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

const data = [
  [2011, 10],
  [2012, 20],
  [2013, 30]
];
export default function App() {
  useEffect(() => {
    const string = d3.tsvFormatRows(data);
    console.log(string);
  }, []);

  return <div className="App"></div>;
}

to use the tsvFormatRows method with the data .

Then we get:

2011 10
2012 20
2013 30

logged.

Timer

We can add timers that come with D3 to add animations to a React app.

We can call the d3.timer method to create a timer:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const timer = d3.timer(function (duration) {
      console.log(duration);
      if (duration > 150) {
        timer.stop();
      }
    }, 100);
  }, []);

  return <div className="App"></div>;
}

We call timer with a callback that has the duration parameter with the callback in the duration.

Then if the duration is bigger than 150ms, then we call timer.stop to stop the timer.

Loading CSV

We can load CSVs in our React app with the d3.csv method.

For example, we can write:

public/data.csv

name,age
John,30
Jane,32

src/App.js

import React, { useEffect } from "react";
import * as d3 from "d3";

const readCsv = async () => {
  const data = await d3.csv("/data.csv");
  for (const { name, age } of data) {
    console.log(name, age);
  }
};

export default function App() {
  useEffect(() => {
    readCsv();
  }, []);

  return <div className="App"></div>;
}

We have the readCsv function to read the data from public/data.csv .

Then we loop through the data array, which has the parsed CSV rows.

And we get:

John 30
Jane 32

Conclusion

We can read and create CSVs and TSVs with D3 in our React app.

Categories
React D3

Adding Graphics to a React App with D3 — CSVs and TSVs

D3 lets us add graphics to a front-end web app easily.

Vue is a popular front end web framework.

They work great together. In this article, we’ll look at how to add graphics to a Vue app with D3.

csvParseRows

We can use the csvParseRows method to parse CSV strings into an array of objects.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

const string = `2011,10\n2012,20\n2013,30\n`;

export default function App() {
  useEffect(() => {
    const data = d3.csvParseRows(string, function ([year, population]) {
      return {
        year: new Date(+year, 0, 1),
        population
      };
    });
    console.log(data);
  }, []);

  return <div className="App"></div>;
}

We call csvParseRows with the CSV strings as the first argument.

The callback has the parsed entry and we can return what we want from it.

csvFormat

The csvFormat method formats the CSV rows and columns.

For instance, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

const data = [
  { year: 2011, population: 10 },
  { year: 2012, population: 20 },
  { year: 2013, population: 30 }
];
export default function App() {
  useEffect(() => {
    const string = d3.csvFormat(data, ["year", "population"]);
    console.log(string);
  }, []);

  return <div className="App"></div>;
}

We pass in an array of objects as the first argument.

Then we pass in an array of strings with the column names.

And then we get the value of string , which is the CSV string. Its value is:

year,population
2011,10
2012,20
2013,30

tsvParse

The tsvParse method lets us parse tab-separated strings.

For instance, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

const string = `year\tpopulation\n2011\t10\n2012\t20\n2013\t30\n`;

export default function App() {
  useEffect(() => {
    const data = d3.tsvParse(string, function ({ year, population }) {
      return {
        year: new Date(+year, 0, 1),
        population
      };
    });
    console.log(data);
  }, []);

  return <div className="App"></div>;
}

We have a tab-separated string and call tsvParse with it.

Then on the callback, we destructure the year and population properties from the parsed entry in the parameter.

And we return the object to return what we want.

tsvParseRows

The tsvParseRows method lets us parse the tab-separated string rows without the headings.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

const string = `2011t10n2012t20n2013t30n`;

export default function App() {
  useEffect(() => {
    const data = d3.tsvParseRows(string, function ([year, population]) {
      return {
        year: new Date(+year, 0, 1),
        population
      };
    });
    console.log(data);
  }, []);

return <div className="App"></div>;
}

We pass in a string without the headings.

Then we call tsvParseRows with the string and the callback that has the properties of the parsed row destructured.

And we return the object that we want to return for each entry.

Conclusion

We can parse and create CSVs and TSVs with D3 and use them in our React app.

Categories
React D3

Adding Graphics to a React App with D3 — Lab Color, Drag and Drop, and Zoom

D3 lets us add graphics to a front-end web app easily.

Vue is a popular front end web framework.

They work great together. In this article, we’ll look at how to add graphics to a Vue app with D3.

Lab Color

The d3.lab method creates a new lab color.

To use it, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const lab = d3.lab("blue");
    console.log(lab);
  }, []);

  return <div className="App"></div>;
}

Then we see:

{l: 29.567572863553245, a: 68.29865326565671, b: -112.02942991288025, opacity: 1}

logged.

Transitions

We can add transitions with D3 into our React app.

To do this, we write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    d3.selectAll("body")
      .transition()
      .style("background-color", "yellow")
      .transition()
      .delay(5000)
      .style("background-color", "green")
      .delay(2000)
      .remove();
  }, []);

  return <div className="App"></div>;
}

We select the body element.

Then we call the transition method to create the transition.

The style method sets the style for the background color transition to yellow.

Then we have a delay of 5 seconds.

Then we set the background color to green.

And then we call delay to show the green background for 2 seconds.

Then finally we call remove to remove the transition.

Drag and Drop

With D3, we can add drag and drop into our React app.

For instance, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    d3.select("g")
      .datum({
        x: 0,
        y: 0
      })
      .call(
        d3.drag().on("drag", function (d) {
          d3.select(this).attr("transform", `translate(${d.x} , ${d.y})`);
        })
      );
  }, []);

  return (
    <div className="App">
      <svg>
        <g>
          <rect x="40" y="10" width="50" height="50" fill="teal"></rect>
        </g>
      </svg>
    </div>
  );
}

to add a rectangle and enable drag and drop for it.

We get the g element.

Then we call the call method to watch for drag events on the g element to set the translate CSS property to move the rectangle’s position.

Zooming

We can add zoom to shapes.

Then we can use the mouse wheel to zoom in and out of an SVG.

For instance, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const svg = d3
      .select("#zoom")
      .append("svg")
      .attr("width", 460)
      .attr("height", 460)
      .call(
        d3.zoom().on("zoom", function (d) {
          svg.attr("transform", d.transform);
        })
      )
      .append("g");

    svg
      .append("circle")
      .attr("cx", 100)
      .attr("cy", 100)
      .attr("r", 40)
      .style("fill", "#68b2a1");
  }, []);

  return (
    <div className="App">
      <div id="zoom"></div>
    </div>
  );
}

We get the div with ID zoom , then we add the svg into it and set the width and height for the svg .

Then we call the call method to let us listen to the zoom event and apply the transform accordingly.

Next, we add the circle that with the cx and cy for x and y coordinates of the center of the circle.

The r has the radius, and the fill has the circle’s background color.

Now we can use the mouse wheel to zoom in and out.

Conclusion

We can create a lab color, add transitions, drag and drop, and zoom with D3 into a React app.

Categories
React D3

Adding Graphics to a React App with D3 — Shapes and Colors

D3 lets us add graphics to a front-end web app easily.

Vue is a popular front end web framework.

They work great together. In this article, we’ll look at how to add graphics to a Vue app with D3.

Shapes

We can add shapes with D3 into our React app.

For example, we can use the d3.arc method to create an arc.

We can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const arc = d3.arc().innerRadius(50).outerRadius(40).cornerRadius(15);

    const svg = d3.select("svg"),
      width = +svg.attr("width"),
      height = +svg.attr("height"),
      g = svg
        .append("g")
        .attr("transform", `translate(${width / 2} , ${height / 2})`);

    const data = [1, 1, 2, 3, 5, 8, 63, 31];
    const arcs = d3.pie()(data);
    g.selectAll("path")
      .data(arcs)
      .enter()
      .append("path")
      .style("fill", function (d, i) {
        return d3.color(`hsl(120, 50%, ${d.value}%)`);
      })
      .attr("d", arc);
  }, []);

  return (
    <div className="App">
      <svg width="400" height="300"></svg>
    </div>
  );
}

First, we create the arc by writing:

const arc = d3.arc().innerRadius(50).outerRadius(40).cornerRadius(15);

We specify the inner radius, outer radius, and corner radius respectively.

Then we get the svg element om our App component.

We get the width and height of it.

Next, we create our g element so we can add the arcs into our SVG.

Then we add the arcs with various shades by writing:

const data = [1, 1, 2, 3, 5, 8, 63, 31];
const arcs = d3.pie()(data);
g.selectAll("path")
  .data(arcs)
  .enter()
  .append("path")
  .style("fill", function(d, i) {
    return d3.color(`hsl(120, 50%, ${d.value}%)`);
  })
  .attr("d", arc);

data has the data we want to add.

The path element will have the arcs.

We add the arcs by appending another path element inside it.

Then we call style to change the fill color of each arc.

And then we call attr to set the d attribute to the arc to add them.

Colors

We can create a color with the d3.color method.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const color = d3.color("green");
    console.log(color);
  }, []);

  return <div className="App"></div>;
}

to create the color.

Then color is:

{r: 0, g: 128, b: 0, opacity: 1}

We get the same thing with the color.rgb() method:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const color = d3.color("green");
    console.log(color.rgb());
  }, []);

  return <div className="App"></div>;
}

We can get the string representation of the color with toString :

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const color = d3.color("green");
    console.log(color.toString());
  }, []);

  return <div className="App"></div>;
}

Then the console log would log:

rgb(0, 128, 0)

Conclusion

We can add shapes and create colors in our React app with D3.

Categories
React D3

Adding Graphics to a React App with D3 — Scales and Axes

D3 lets us add graphics to a front-end web app easily.

Vue is a popular front end web framework.

They work great together. In this article, we’ll look at how to add graphics to a Vue app with D3.

Scales

We can use the scales API to transform data.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const data = [100, 220, 330, 350, 400, 250];
    const width = 500,
      barHeight = 20,
      margin = 1;

    const scale = d3
      .scaleLinear()
      .domain([d3.min(data), d3.max(data)])
      .range([100, 400]);

    const svg = d3
      .select("body")
      .append("svg")
      .attr("width", width)
      .attr("height", barHeight * data.length);

    const g = svg
      .selectAll("g")
      .data(data)
      .enter()
      .append("g")
      .attr("transform", function (d, i) {
        return `translate(0, ${i * barHeight})`;
      });

    g.append("rect")
      .attr("width", function (d) {
        return scale(d);
      })
      .attr("height", barHeight - margin);

    g.append("text")
      .attr("x", function (d) {
        return scale(d);
      })
      .attr("y", barHeight / 2)
      .attr("dy", ".35em")
      .text(function (d) {
        return d;
      });
  }, []);

  return <div className="App"></div>;
}

We have the data that we want to display as bars in our code.

Then we specify the width for the chart and the barHeight for each bar.

Next, we create a scale with the min and max values for our chart:

const scale = d3
  .scaleLinear()
  .domain([d3.min(data), d3.max(data)])
  .range([100, 400]);

This will be used when we create our bar to scale the bars’ widths.

Next, we create our group object by writing:

const svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", barHeight * data.length);

We add the svg element and set the width and height for the bar chart.

Then we set the dimensions for the bars with:

g.append("rect")
  .attr("width", function(d) {
    return scale(d);
  })
  .attr("height", barHeight - margin);

We call scale to scale bars to be proportional to the width of the svg .

And finally, we add the bars with:

g.append("text")
  .attr("x", function(d) {
    return scale(d);
  })
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .text(function(d) {
    return d;
  });

We call scale to position the bar.

y has the y coordinate of the bar.

dy adds the gap for each bar.

text has the text for the bar.

Axis

We can add axes to our graphs.

For example, we can write:

import React, { useEffect } from "react";
import * as d3 from "d3";

export default function App() {
  useEffect(() => {
    const width = 400,
      height = 400;
    const data = [100, 120, 140, 160, 180, 200];
    const svg = d3
      .select("body")
      .append("svg")
      .attr("width", width)
      .attr("height", height);

    const xscale = d3
      .scaleLinear()
      .domain([0, d3.max(data)])
      .range([0, width - 100]);

    const yscale = d3
      .scaleLinear()
      .domain([0, d3.max(data)])
      .range([height / 2, 0]);

    const xAxis = d3.axisBottom().scale(xscale);
    const yAxis = d3.axisLeft().scale(yscale);
    svg.append("g").attr("transform", "translate(50, 10)").call(yAxis);
    const xAxisTranslate = height / 2 + 10;

    svg
      .append("g")
      .attr("transform", `translate(50, ${xAxisTranslate})`)
      .call(xAxis);
  }, []);

  return <div className="App"></div>;
}

We add the svg to the body with:

const svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

Then we create the scale function for the x-axis by writing:

const xscale = d3
  .scaleLinear()
  .domain([0, d3.max(data)])
  .range([0, width - 100]);

This lets us scale the x-axis to be proportional to the width of the SVG.

Similar, we create a function to scale the y-axis:

const yscale = d3
  .scaleLinear()
  .domain([0, d3.max(data)])
  .range([height / 2, 0]);

Next, we create the x and y axes by writing:

const xAxis = d3.axisBottom().scale(xscale);
const yAxis = d3.axisLeft().scale(yscale);

Then we move the y-axis right and down by writing:

svg.append("g").attr("transform", "translate(50, 10)").call(yAxis);

by the given number of pixels.

And then we add the x-axis and translate it so that it forms a right angle with the y-axis by writing:

const xAxisTranslate = height / 2 + 10;

svg
  .append("g")
  .attr("transform", `translate(50, ${xAxisTranslate})`)
  .call(xAxis);

Now we should see the axes for a graph.

Conclusion

We can add scales and axes to our graph by using the D3 library in our React app.