Home > Enterprise >  D3.js graph shows up as text
D3.js graph shows up as text

Time:07-01

I want to open a graph as a modal after clicking another graph. However, what shows up in the modal is plain text, like such:

enter image description here

After inspecting the element, it seems like the text is the <g> tag that was in the svg, but I'm not sure what that means.

enter image description here enter image description here

^ The corresponding HTML code is <text fill="currentColor" x="-9" dy="0.32em">−1.5</text>

enter image description here

I'm not sure why this is happening and I can't find any similar problems online for this.

Here's my graph code:

function Wavelet() {

        const gWidth = window.innerWidth / 5
        const gWidth_modal = window.innerWidth/3
        var margin = {top: 20, right: 30, bottom: 30, left: 20},
        width = gWidth - margin.left - margin.right,
        height = 200 - margin.top - margin.bottom;

        var margin_modal = {top: 20, right: 30, bottom: 30, left: 20},
        width_modal = gWidth_modal - margin_modal.left - margin_modal.right,
        height_modal = 400 - margin_modal.top - margin_modal.bottom;
        

        // append the svg object to the body of the page
        var svg = d3.select("#contour").selectAll("*").remove();
        svg = d3.select("#contour").append("svg")
            .attr("width", gWidth   margin.left   margin.right)
            .attr("height", height   margin.top   margin.bottom)
            .append("g")

        var svg_modal = d3.select("#contour-modal").selectAll("*").remove();
        svg_modal = d3.select("#contour-modal").append("svg_modal")
            .attr("width", width_modal   margin_modal.left   margin_modal.right)
            .attr("height", height_modal   margin_modal.top   margin_modal.bottom)
            .append("g")
            .attr("transform", "translate("   margin_modal.left   ","   margin_modal.top   ")")
        
        var color = d3.scaleLinear()
            .domain([0, 0.01]) // Points per square pixel.
            .range(["#c3d7e8", "#23527a"])
      
        const data = [
            { x: 3.4, y: 4.2 },
            { x: -1, y: 4.2 },
            { x: -1, y: 2.8 },
            { x: 3.6, y: 4.3 },
            { x: -0.1, y: 3.7 },
            { x: 4.7, y: 2.5 },
            { x: 0.8, y: 3.6 },
            { x: 4.7, y: 3.7 },
            { x: -0.4, y: 4.2 },
            { x: 0.1, y: 2.2 },
            { x: 0.5, y: 3 },
            { x: 4.3, y: 4.5 },
            { x: 3.4, y: 2.7 },
            { x: 4.4, y: 3.6 },
            { x: 3.3, y: 0.6 },
            { x: 3, y: 3.4 },
            { x: 4.7, y: 0 },
            { x: -0.7, y: 2.7 },
            { x: 2.6, y: 2 },
            { x: 0, y: -1 },
            { x: 3.4, y: 4.5 },
            { x: 3.9, y: 4.6 },
            { x: 0.7, y: 3.9 },
            { x: 3, y: 0.2 }
            ];

        // Add X axis
        var x = d3.scaleLinear()
            .domain([-2, 6])
            .range([ 0, width ]);
        svg.append("g")
            .attr("transform", "translate(0,"   height   ")")
            .call(d3.axisBottom(x));

        var x_modal = d3.scaleLinear()
            .domain([-2, 6])
            .range([ 0, width_modal ]);
        svg_modal.append("g")
            .attr("transform", "translate(0,"   height_modal   ")")
            .call(d3.axisBottom(x_modal));

        // Add Y axis
        var y = d3.scaleLinear()
            .domain([-2, 5])
            .range([ height, 0 ]);
        svg.append("g")
            .call(d3.axisLeft(y));

        var y_modal = d3.scaleLinear()
            .domain([-2, 5])
            .range([ height_modal, 0 ]);
        svg_modal.append("g")
            .call(d3.axisLeft(y_modal));

        // compute the density data
        var densityData = d3.contourDensity()
            .x(function(d) { return x(d.x); })   // x and y = column name in .csv input data
            .y(function(d) { return y(d.y); })
            .size([width, height])
            .bandwidth(20)    // smaller = more precision in lines = more lines
            (data)

        // Add the contour: several "path"
        svg
            .selectAll("path")
            .data(densityData)
            .enter()
            .append("path")
            .attr("d", d3.geoPath())
            .attr("fill", function(d) { return color(d.value); })
            .attr("stroke", "#4285f4")
        
        svg_modal
            .selectAll("path")
            .data(densityData)
            .enter()
            .append("path")
            .attr("d", d3.geoPath())
            .attr("fill", function(d) { return color(d.value); })
            .attr("stroke", "#4285f4")
}

export default Wavelet

I have 2 svg as the one in the modal doesn't get rendered if I use the same one (for some reason). If that's what's causing me problems, please let me know how to fix it.

    useEffect(() => {
        (async () => {
            await Wavelet()
        })();
    });
    
    // const showModal = () => {setIsopen((prev) => !prev); console.log("aaaaaaaaaa");}
    function showModal  (id) {
        setIsopen((prev) => !prev); 
        setModalID(id)
    }

    function Graph() {
        const modal = <div>
            <div id="contour" onClick={() => showModal(4)}>
            </div>
            {isOpen && (modalID == 4) && (
                <ModalContent onClose={() => setIsopen(false)}>
                    <div className="modal_c">
                        <h3>{modalID}</h3>
                        <div id="contour-modal" >
                        </div>
                        <p> </p>
                    </div>
                </ModalContent>
            )}
            </div>
        return modal;
    }

}

My modal class if anybody wants to reference it:

const modal = {
  position: "fixed",
  zIndex: 1,
  left: 0,
  top: 0,
  width: "100vw",
  height: "100vh",
  overflow: "auto",
  backgroundColor: "rgba(192,192,192,0.5)",
  display: "flex",
  alignItems: "center"
}; 

const close = {
  position: "absolute",
  top: "11vh",
  right: "27vw",
  color: "#000000",
  fontSize: 40,
  fontWeight: "bold",
  cursor: "pointer"
};

const modalContent = {
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  width: "50%",
  height: "80%",
  margin: "auto",
  backgroundColor: "white"
  // border: "2px solid #000000"
};

export const Modal = ({ onOpen, children }) => {
  console.log(children)
  return <div onClick={onOpen}> {children}</div>;
};

export const ModalContent = ({ onClose, children }) => {
  return (
    <div style={modal}>
      <div style={modalContent}>
        <span style={close} onClick={onClose}>
          &times;
        </span>
        {children}</div>
    </div>
  );
};

CodePudding user response:

Problem is with your this statement : d3.select("#contour-modal").append("svg_modal").In order to render the elements correctly, you need to append them to svg. d3.select("#contour-modal").append("svg") . svg_modal is an invalid tag for your requirement. Kindly read more about svg rendering. Done a basic test of your code:

const gWidth = window.innerWidth / 5
const gWidth_modal = window.innerWidth / 3
var margin = {
    top: 20,
    right: 30,
    bottom: 30,
    left: 20
  },
  width = gWidth - margin.left - margin.right,
  height = 200 - margin.top - margin.bottom;

var margin_modal = {
    top: 20,
    right: 30,
    bottom: 30,
    left: 20
  },
  width_modal = gWidth_modal - margin_modal.left - margin_modal.right,
  height_modal = 200 - margin_modal.top - margin_modal.bottom;


// append the svg object to the body of the page
var svg = d3.select("#contour").selectAll("*").remove();
svg = d3.select("#contour").append("svg")
  .attr("width", gWidth   margin.left   margin.right)
  .attr("height", height   margin.top   margin.bottom)
  .append("g")

var svg_modal = d3.select("#contour-modal").selectAll("*").remove();
svg_modal = d3.select("#contour-modal").append("svg")
  .attr("width", width_modal   margin_modal.left   margin_modal.right)
  .attr("height", height_modal   margin_modal.top   margin_modal.bottom)
  .append("g")
  .attr("transform", "translate("   margin_modal.left   ","   margin_modal.top   ")")

var color = d3.scaleLinear()
  .domain([0, 0.01]) // Points per square pixel.
  .range(["#c3d7e8", "#23527a"])

const data = [{
    x: 3.4,
    y: 4.2
  },
  {
    x: -1,
    y: 4.2
  },
  {
    x: -1,
    y: 2.8
  },
  {
    x: 3.6,
    y: 4.3
  },
  {
    x: -0.1,
    y: 3.7
  },
  {
    x: 4.7,
    y: 2.5
  },
  {
    x: 0.8,
    y: 3.6
  },
  {
    x: 4.7,
    y: 3.7
  },
  {
    x: -0.4,
    y: 4.2
  },
  {
    x: 0.1,
    y: 2.2
  },
  {
    x: 0.5,
    y: 3
  },
  {
    x: 4.3,
    y: 4.5
  },
  {
    x: 3.4,
    y: 2.7
  },
  {
    x: 4.4,
    y: 3.6
  },
  {
    x: 3.3,
    y: 0.6
  },
  {
    x: 3,
    y: 3.4
  },
  {
    x: 4.7,
    y: 0
  },
  {
    x: -0.7,
    y: 2.7
  },
  {
    x: 2.6,
    y: 2
  },
  {
    x: 0,
    y: -1
  },
  {
    x: 3.4,
    y: 4.5
  },
  {
    x: 3.9,
    y: 4.6
  },
  {
    x: 0.7,
    y: 3.9
  },
  {
    x: 3,
    y: 0.2
  }
];

// Add X axis
var x = d3.scaleLinear()
  .domain([-2, 6])
  .range([0, width]);
svg.append("g")
  .attr("transform", "translate(0,"   height   ")")
  .call(d3.axisBottom(x));

var x_modal = d3.scaleLinear()
  .domain([-2, 6])
  .range([0, width_modal]);
svg_modal.append("g")
  .attr("transform", "translate(0,"   height_modal   ")")
  .call(d3.axisBottom(x_modal));

// Add Y axis
var y = d3.scaleLinear()
  .domain([-2, 5])
  .range([height, 0]);
svg.append("g")
  .call(d3.axisLeft(y));

var y_modal = d3.scaleLinear()
  .domain([-2, 5])
  .range([height_modal, 0]);
svg_modal.append("g")
  .call(d3.axisLeft(y_modal));

// compute the density data
var densityData = d3.contourDensity()
  .x(function(d) {
    return x(d.x);
  }) // x and y = column name in .csv input data
  .y(function(d) {
    return y(d.y);
  })
  .size([width, height])
  .bandwidth(20) // smaller = more precision in lines = more lines
(data)


// Add the contour: several "path"
svg
  .selectAll("path")
  .data(densityData)
  .enter()
  .append("path")
  .attr("d", d3.geoPath())
  .attr("fill", function(d) {
    return color(d.value);
  })
  .attr("stroke", "#4285f4")

svg_modal
  .selectAll("path")
  .data(densityData)
  .enter()
  .append("path")
  .attr("d", d3.geoPath())
  .attr("fill", function(d) {
    return color(d.value);
  })
  .attr("stroke", "#4285f4")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.5.0/d3.min.js" integrity="sha512- rnC6CO1Ofm09H411e0Ux7O9kqwM5/FlEHul4OsPk4QIHIYAiM77uZnQyIqcyWaZ4ddHFCvZGwUVGwuo0DPOnQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="contour">
</div>
<div id="contour-modal">
</div>

  • Related