Not able to fit my d3js svg histogram into a div container

37 Views Asked by At

I created a histogram with d3 and I want to include it inside a box container. Below I have attached my expectation with the layout of the histogram.

My code for creating the histogram is (I have removed the x and y labels since that was the requirement):

createGraph(data){  
        let width = (parentWidth > 900) ? 900 : parentWidth;
        let height = (parentWidth > 700) ? 350 : 250;
        const margin = { top: 0, right: 0, bottom: 0, left: 0 };

        // Get the maximum value of the "current" key for scaling
        const maxValue = d5.max(data, d => parseFloat(d.current));

        // Set up the scales
        const xScale = d5.scaleBand()
            .domain(data.map(d => d.label))
            .range([margin.left, width - margin.right])
            .padding(1); // Adjust the padding as needed

        const maxDataValue = d3.max(data, d => +d.current);
        const yScale = d5.scaleLinear()
            .range([height, 0])
            .domain([0, maxDataValue])
            .nice();


        // Create the SVG container
        const svg = d5.select("#yourDivId") // Replace 'yourDivId' with the actual ID of your div
            .append("svg")
            .style("width", width)
            .style("transform", "translate(-16px, -10px)")
            .style("height", height)
            .style("padding", "0")
            .style("margin", "0");

        // Add rectangles for each data point
        svg.selectAll("rect")
            .data(data)
            .enter().append("rect")
            .attr("x", d => xScale(d.label))
            .attr("y", d => yScale(parseFloat(d.current)))
            .attr("width", '21px')
            .attr("height", d => height - yScale(parseFloat(d.current)) - margin.bottom)
            .attr("fill", "#3D8BF7")
            .attr('rx', '2')
            .attr('ry', '2')


        // Optional: Add axes and remove labels
        svg.append("g")
            .attr("transform", `translate(0, ${height - margin.bottom})`)
            .call(d5.axisBottom(xScale).tickSize(0))
            .selectAll("text").remove(); // Remove x-axis labels

        svg.append("g")
            .attr("transform", `translate(${margin.left}, 0)`)
            .call(d5.axisLeft(yScale).tickSize(0))
            .select(".domain").remove(); // Remove y-axis line


        // Return the SVG element.
        const divElement = document.getElementById('yourDivId'); // Replace 'yourDivId' with the actual ID of your div

        // Append the SVG to the div element
        divElement.appendChild(svg.node());

HTML:

<div>
    <div class="col-md-12 summary-graphs-for-addr-correction">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <div class="panelHeadingTbl">
                        <div class="panelHeadingTd">
                            <h3 class="panel-title pull-left">Summary</h3>    
                        </div>
                    </div>
                </div>
                <div class="panel-body tbl">
                    <div class="flex-container-for-graphs">
                        <div class="col-md-3">
                            <div class="box-widget">
                                Box 1
                                <bar-graph :graphdata="dataForHistogram"></bar-graph>
                            </div>
                        </div>
    
                        </div>
                    </div>
                </div>
            </div>
</div>

Expected:

enter image description here

Actual:

enter image description here

I tried setting viewBox of svg but that did not work. ALso tried setting width and height of box to a specific value and svg width height as 100% still the svg is cut off.

How can I achieve this? Can I scale my svg and retain its width height and fit in container? Expected width and height of svg is 364x50 (width will be dynamic)

0

There are 0 best solutions below