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.

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.