Reactjs D3js Responsiveness With SVG's

Reactjs D3js Responsiveness With SVG's
0

Hello there,

I’m new to both Reactjs and D3js and I’m trying to create a responsiveness svg. I went down a rabbit hole in the internet, and I worked out a simple solution that follows a concept of allowing D3js to take over the DOM for the svg element specifically. I’m aware that Reactjs and D3js can clash because they both manipulate the DOM, so I’m trying to do this carefully.

import React, { Component } from 'react';
import { select } from 'd3';

class SvgComponent extends Component {
  constructor(){
    super();

    this.svgPlayground = this.svgPlayground.bind(this);
  }

  componentDidMount(){

    // Initially invoking the function at least once, and then allowing the event listener to invoke again
    window.addEventListener('resize', this.svgPlayground);
    this.svgPlayground();
  }

  shouldComponentUpdate(){
    return false; // Preventing re-rendering???
  }

  componentWillUnmount(){
    window.removeEventListener('resize', this.svgPlayground);
  }

  svgPlayground() { 
    const node = this.node;
    let { width, height } = node.getBoundingClientRect(); // Getting current width and height of the svg elem


    // Using General Update Pattern to assign/update the dimensions of both svg and the rect
    let svg = select(node).data([null]);
    svg.enter().append('svg')
    .merge(svg)
    .attr('width', width)
    .attr('height', height);
  
    const rect = svg.selectAll('rect').data([null]);
    rect.enter().append('rect')
    .merge(rect)
    .attr('width', width)
    .attr('height', height)
    .attr('rx', 100);
  }




  render() {
    /* In my SCSS file I have set svg to 100% for both width/height to a svg container of 
    width: 1100px and  height: 50vh  */
    return(
      <svg ref={ node => this.node = node }></svg>
    );
  }
}

export default SvgComponent;

I’m unsure if my code is following this approach correctly, or if I’m doing it wrong.

An article of the concept I’m mentioning (scroll down to where it says “Approaches” and specifically “D3js within Reactjs”): https://www.smashingmagazine.com/2018/02/react-d3-ecosystem/

A youtube video that I also try to follow (Just for the first portion of where he mentions D3js renders DOM): https://www.youtube.com/watch?v=5FEzELkLsYw

Option 1

Combine viewbox with CSS you can set it to display as block and give it a max-width setting.

The problem with this approach is that the svg will indead shrink when the window does, but any text in it will to.

Option 2

Get the window width, and use that to decide the width of your svg. This should allow you to keep the text size the same, or adjust in a still readable manor, and make the resulting svg image smaller.

Hey thanks for the response! I didn’t even know about the first option, I’ll check that out!

The second option I believe I was able to get the width with the getBoundingClientRect() since it returns the size of the element. Initially the size of the svg is set by my CSS file to fully fit in its container. With the width value being changed by the eventlistener and D3js general update pattern I made the svg responsive. I wanted to make sure that the values of the svg were changed by D3js and prevent Reactjs from re-rendering or causing any DOM changes on that component itself.

Thanks for the help!