Categories
React D3

Adding Graphics to a React App with D3 — Find Elements and Paths

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.

Find Elements in Selections

We can get elements with the given select with D3 in our React app.

To do this, we write:

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

export default function App() {
  useEffect(() => {
    let selection = d3.selectAll("b").filter(":nth-child(odd)").nodes();
    selection.forEach((e) => {
      console.log(e.textContent);
    });
  }, []);

  return (
    <div className="App">
      <div>
        <b>apple</b>
        <b>orange</b>
        <b>grape</b>
      </div>
    </div>
  );
}

We get all the b elements from the DOM that have even indexes with the select and filter methods.

filter lets us return the elements we want.

Then we call forEach to log the textContent of each element retrieved.

Also, we can use the d3.matcher method.

For example, we can write:

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

export default function App() {
  useEffect(() => {
    const heading = d3.selectAll("h5");
    const matcher = heading.filter(d3.matcher("h5")).node();
    const filter = heading.filter(d3.matcher("h5")).node();
    console.log(matcher);
    console.log(filter);
  }, []);

  return (
    <div className="App">
      <div>
        <h5>This is text1</h5>
        <h5>This is text2</h5>
        <h5>This is text3</h5>
        <h5>This is text4</h5>
      </div>
    </div>
  );
}

We call d3.selectAll to select all the h5 elements.

Also, we can call the d3.creator method to create an element.

Then we can use append to append it to another element:

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

export default function App() {
  useEffect(() => {
    const selection = d3.select("body");
    selection.append(d3.creator("div"));
    const div = document.querySelector("div");
    div.innerText = "hello world.";
  }, []);

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

We get the body with d3.select .

Then we create our div by calling d3.creator with the tag name of the element we want to create.

Then we can call querySelector to get it and set the text to what we want.

Paths

We can use the d3.line method to draw lines.

For example, we can write:

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

export default function App() {
  useEffect(() => {
    const data = [
      [0, 12],
      [50, 20],
      [100, 30],
      [200, 40],
      [300, 90]
    ];
    const lineGenerator = d3.line();
    const pathString = lineGenerator(data);
    d3.select("path").attr("d", pathString);
  }, []);

  return (
    <div className="App">
      <style>{`
        path {
          fill: blue;
          stroke: #aaa;
        }
      `}</style>
      <svg width="600" height="100">
        <path transform="translate(20, 0)" />
      </svg>
    </div>
  );
}

We have a nested array with the x and y coordinates of the points for our path.

Then we call the lineGenerator function that we created from the d3.line method to create the line.

We select the path element and then pass in our generated pathString into it.

Conclusion

We can find elements and work with them in our React app with D3.

Categories
React D3

Adding Graphics to a React App with D3 — Arrays, Collections, and Elements

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.

Arrays

We can use D3 to manipulate arrays.

For example, we can write:

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

export default function App() {
  useEffect(() => {
    const data = [20, 40, 60, 80, 100];
    console.log(d3.min(data));
    console.log(d3.max(data));
    console.log(d3.extent(data));
    console.log(d3.sum(data));
    console.log(d3.mean(data));
    console.log(d3.quantile(data, 0.5));
    console.log(d3.variance(data));
    console.log(d3.deviation(data));
  }, []);

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

to computed various kinds of information with D3.

min returns the min value of the array.

max returns the max value of the array.

extent returns the min and max value of the array.

sum returns the sum of the array values.

mean returns the average of the array values.

quantile returns the given quantile.

variance returns the variance.

And deviation returns the standard deviation.

Collections

D3 can also work with objects.

To work with objects, we need the d3-collection library.

We run:

npm i d3-collections

to install the d3-collections library.

For example, we can write:

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

export default function App() {
  useEffect(() => {
    const month = { jan: 1, Feb: 2, mar: 3, apr: 4 };
    console.log(d3.keys(month));
    console.log(d3.values(month));
    console.log(d3.entries(month));
  }, []);

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

Selecting Elements

We can select elements with D3.

For example, we can write:

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

export default function App() {
  useEffect(() => {
    d3.select("p").style("color", "red");
  }, []);

  return (
    <div className="App">
      <p>hello</p>
    </div>
  );
}

to get the p element and set its color to red .

Also, we can chain the methods.

For example, we can write:

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

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

  return (
    <div className="App">
      <p>
        <b>hello</b>
      </p>
    </div>
  );
}

to get the b element in the p element.

Also, we can get the tr elements with an even index by writing:

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

export default function App() {
  useEffect(() => {
    const even = d3.selectAll("tr").filter(":nth-child(odd)");
    console.log(even);
  }, []);

  return (
    <div className="App">
      <table>
        <tr>
          <td>foo</td>
        </tr>
        <tr>
          <td>bar</td>
        </tr>
        <tr>
          <td>baz</td>
        </tr>
      </table>
    </div>
  );
}

We can merge the selections with the merge method:

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

export default function App() {
  useEffect(() => {
    const width = 300;
    const height = 300;
    const svg = d3
      .select("#svgcontainer")
      .append("svg")
      .attr("width", width)
      .attr("height", height);
    const rect = svg
      .append("rect")
      .attr("x", 20)
      .attr("y", 20)
      .attr("width", 200)
      .attr("height", 100)
      .attr("fill", "green");

    const rect2 = svg
      .append("rect")
      .attr("x", 20)
      .attr("y", 20)
      .attr("width", 100)
      .attr("height", 100)
      .attr("fill", "blue");

    rect.enter().append("rect").merge(rect2);
  }, []);

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

We have 2 rectangles, rect and rect2 .

Then we have:

rect.enter().append("rect").merge(rect2);

to combine the 2 rectangles together.

Now we see the blue and green rectangles side by side.

Conclusion

We can work with arrays, objects, and DOM elements with D3 in React apps.

Categories
React D3

Adding Graphics to a React App with D3 — Line Graph

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.

Line Graph

We can add a line graph into our React app with D3.

To do this, we write:

public/data.csv

year,population
2006,20
2008,25
2010,38
2012,41
2014,53
2016,26
2017,42

App.js

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

const createLineChart = async () => {
  const margin = { top: 20, right: 20, bottom: 30, left: 50 },
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

  const x = d3.scaleTime().range([0, width]);
  const y = d3.scaleLinear().range([height, 0]);

  const valueline = d3
    .line()
    .x(function (d) {
      return x(d.year);
    })
    .y(function (d) {
      return y(d.population);
    });

  const svg = d3
    .select("body")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", `translate(${margin.left}, ${margin.top})`);

  const data = await d3.csv("/data.csv");

  data.forEach(function (d) {
    d.population = +d.population;
  });

  x.domain(
    d3.extent(data, function (d) {
      return d.year;
    })
  );

  y.domain([
    0,
    d3.max(data, function (d) {
      return d.population;
    })
  ]);

  svg.append("path").data([data]).attr("class", "line").attr("d", valueline);

  svg
    .append("g")
    .attr("transform", `translate(0, ${height})`)
    .call(d3.axisBottom(x));

svg.append("g").call(d3.axisLeft(y));
};

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

  return (
    <div className="App">
      <style>{`
        .line {
          fill: none;
          stroke: green;
          stroke-width: 5px;
        }
      `}</style>
    </div>
  );
}

We create the createLineChart function to create the line chart.

First, we write:

const margin = {
    top: 20,
    right: 20,
    bottom: 30,
    left: 50
  },
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

to set the margins, width, and height of the chart.

Then we add the x and y objects to let us add the min and max values for the lines:

const x = d3.scaleTime().range([0, width]);
const y = d3.scaleLinear().range([height, 0])

Then we set the data for the x and y axes:

const valueline = d3
  .line()
  .x(function(d) {
    return x(d.year);
  })
  .y(function(d) {
    return y(d.population);
  });

Next, we add the svg element into our component with:

const svg = d3
  .select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left}, ${margin.top})`);

Then we read the data from the CSV with:

const data = await d3.csv("/data.csv");

Then we add the x and y domains with:

data.forEach(function(d) {
  d.population = +d.population;
});

x.domain(
  d3.extent(data, function(d) {
    return d.year;
  })
);

y.domain([
  0,
  d3.max(data, function(d) {
    return d.population;
  })
]);

to return the labels for the x and y axes.

To add the line, we write:

svg.append("path").data([data]).attr("class", "line").attr("d", valueline);

We add the x-axis with:

svg
  .append("g")
  .attr("transform", `translate(0, ${height})`)
  .call(d3.axisBottom(x));

And we add the y-axis with:

svg.append("g").call(d3.axisLeft(y));

Conclusion

We can add a line graph with D3 into our React app.

Categories
React D3

Adding Graphics to a React App with D3 — Pie Chart

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.

Pie Chart

We can add a pie chart into our React app with D3.

For instance, we can write:

public/populations.csv

states,percent
California,38.00
New York,18.00
Texas,20.0

src/App.js

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

const createPieChart = async () => {
  const svg = d3.select("svg"),
    width = svg.attr("width"),
    height = svg.attr("height"),
    radius = Math.min(width, height) / 2;

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

  const color = d3.scaleOrdinal(["gray", "green", "brown"]);

  const pie = d3.pie().value(function (d) {
    return d.percent;
  });

  const path = d3
    .arc()
    .outerRadius(radius - 10)
    .innerRadius(0);

  const label = d3
    .arc()
    .outerRadius(radius)
    .innerRadius(radius - 80);

  const data = await d3.csv("/populations.csv");

  const arc = g
    .selectAll(".arc")
    .data(pie(data))
    .enter()
    .append("g")
    .attr("class", "arc");

  arc
    .append("path")
    .attr("d", path)
    .attr("fill", function (d) {
      return color(d.data.states);
    });

  arc
    .append("text")
    .attr("transform", function (d) {
      return `translate(${label.centroid(d)})`;
    })
    .text(function (d) {
      return d.data.states;
    });

svg
    .append("g")
    .attr("transform", `translate(${width / 2 - 120},20)`)
    .append("text")
    .text("Top population states in the US")
    .attr("class", "title");
};

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

  return (
    <div className="App">
      <style>{`
        .arc text {
          font: 12px arial;
          text-anchor: middle;
        }

        .arc path {
          stroke: #fff;
        }

        .title {
          fill: green;
          font-weight: italic;
        }
      `}</style>
      <svg width="600" height="400"></svg>
    </div>
  );
}

We put the CSV in the public folder so that we can read static files in our React code.

The createPieChart function lets us get the svg element.

And we set the width , height and radius of the pie chart.

We create the group for the pie with:

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

Then we add the colors with:

const color = d3.scaleOrdinal(["gray", "green", "brown"]);

Next, we add the pies with:

const pie = d3.pie().value(function(d) {
  return d.percent;
});

Then add the arcs for the pie with:

const path = d3
  .arc()
  .outerRadius(radius - 10)
  .innerRadius(0);

The labels are added with:

const label = d3
  .arc()
  .outerRadius(radius)
  .innerRadius(radius - 80);

Then we read the population.csv file with:

const data = await d3.csv("/populations.csv");

We set the lengths of the arc with:

const arc = g
  .selectAll(".arc")
  .data(pie(data))
  .enter()
  .append("g")
  .attr("class", "arc");

And we set the pie colors with:

arc
  .append("path")
  .attr("d", path)
  .attr("fill", function(d) {
    return color(d.data.states);
  });

And we set the text labels for the pies with:

arc
  .append("text")
  .attr("transform", function(d) {
    return `translate(${label.centroid(d)})`;
  })
  .text(function(d) {
    return d.data.states;
  });

Finally, we add the title of the chart with:

svg
  .append("g")
  .attr("transform", `translate(${width / 2 - 120},20)`)
  .append("text")
  .text("Top population states in the US")
  .attr("class", "title");

In App , we add the styles for the arc so that we can set the font and title color to what we want.

Conclusion

We can add a pie chart easily into our React app.

Categories
React D3

Adding Graphics to a React App with D3 — Circle Chart

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.

Circle Chart

We can create a circle chart with D3 in our React app.

For example, we can write:

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

export default function App() {
  useEffect(() => {
    const width = 400;
    const height = 400;
    const data = [10, 28, 35];
    const colors = ["green", "lightblue", "yellow"];

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

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

    g.append("circle")
      .attr("cx", function (d, i) {
        return i * 75 + 50;
      })
      .attr("cy", function (d, i) {
        return 75;
      })
      .attr("r", function (d) {
        return d * 1.5;
      })
      .attr("fill", function (d, i) {
        return colors[i];
      });

    g.append("text")
      .attr("x", function (d, i) {
        return i * 75 + 25;
      })
      .attr("y", 80)
      .attr("stroke", "teal")
      .attr("font-size", "10px")
      .attr("font-family", "sans-serif")
      .text((d) => {
        return d;
      });
  }, []);

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

We create the svg by selecting the body and then add the svg to it.

And we also set the width and height of the SVG.

This is done with:

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

Then we create the group with the data by writing:

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

data has the data.

Next, we add the circles by writing:

g.append("circle")
  .attr("cx", function(d, i) {
    return i * 75 + 50;
  })
  .attr("cy", function(d, i) {
    return 75;
  })
  .attr("r", function(d) {
    return d * 1.5;
  })
  .attr("fill", function(d, i) {
    return colors[i];
  });

We add the cx and cy attributes by call attr .

r has the radius, and fill has the background color for each circle.

Then we add the text that goes with the circles by writing:

g.append("text")
  .attr("x", function(d, i) {
    return i * 75 + 25;
  })
  .attr("y", 80)
  .attr("stroke", "teal")
  .attr("font-size", "10px")
  .attr("font-family", "sans-serif")
  .text((d) => {
    return d;
  });

We call append with the 'text' argument.

And then we set the x and y attributes of the position of the text.

Then we set the color of the text with the stroke .

font-size has the font size and font-family has the font family.

The text method takes a callback that returns the text.

Conclusion

We can add a circle chart into our React app with D3 easily.