block by curran 6b5a43a958e7d9adea657a984ce1fbd6

Marks and Channels

Full Screen

A port of VizHub: Marks and Channels to vanilla JavaScript.

A demonstration of basic D3 usage to implement the concept of Marks and Channels. Includes usage of:

Part of the Constructing Visualizations Playlist.

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Marks and Channels</title>
    <script src="https://unpkg.com/d3@7.6.1/dist/d3.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
  <script>
    const xPosition = (
      selection,
      { data, height }
    ) => {
      selection
        .selectAll('circle')
        .data(data)
        .join('circle')
        .attr('cx', (d) => d * 70 + 60)
        .attr('cy', height / 2)
        .attr('r', 30);
    };

    const yPosition = (
      selection,
      { data, width }
    ) => {
      selection
        .selectAll('circle')
        .data(data)
        .join('circle')
        .attr('cx', width / 2)
        .attr('cy', (d) => d * 28 + 20)
        .attr('r', 12);
    };

    const length = (
      selection,
      { data, height }
    ) => {
      const barHeight = (d) => d * 25 + 10;
      selection
        .selectAll('rect')
        .data(data)
        .join('rect')
        .attr('x', (d) => d * 80 + 20)
        .attr('y', (d) => height / 2 - barHeight(d))
        .attr('width', 50)
        .attr('height', barHeight);
    };

    const size = (
      selection,
      { data, height }
    ) => {
      selection
        .selectAll('circle')
        .data(data)
        .join('circle')
        .attr('cx', (d) => d * 70 + 60)
        .attr('cy', height / 2)
        .attr('r', (d) => Math.sqrt(d * 200) + 1);
    };

    const shape = (
      selection,
      { data, height }
    ) => {
      const symbolGenerator = d3.symbol();

      selection
        .selectAll('path')
        .data(data)
        .join('path')
        .attr(
          'transform',
          (d) =>
            `translate(${d * 70 + 60},${height / 2})`
        )
        .attr('d', (d, i) =>
          symbolGenerator
            .type(d3.symbolsFill[i])
            .size(2000)()
        );
    };

    const hue = (
      selection,
      { data, height }
    ) => {
      selection
        .selectAll('circle')
        .data(data)
        .join('circle')
        .attr('cx', (d) => d * 70 + 60)
        .attr('cy', height / 2)
        .attr('r', 30)
        .attr('fill', (d, i) => d3.schemeCategory10[i]);
    };

    const data = [0, 1, 2, 3, 4];
    const height = 150;
    const width = 400;

    const viz = (container) => {
      const svg = d3.select(container)
        .selectAll('svg')
        .data([
          xPosition,
          yPosition,
          size,
          length,
          shape,
          hue,
        ])
        .join('svg')
        .attr('width', width)
        .attr('height', height)
        .each(function (d) {
          d(d3.select(this), { data, width, height });
        });
    };

    const container = d3.select('#app').node();

    viz(container);
  </script>
</html>