I have this function which draws a chart on several divs, This resize event handler code I came up with make the chart to be responsive, but, only in the following sequence: 1) Resize my browser , 2) Manually reloading the webpage.
when I resize the browser, the whole page becomes totally blank, then if I reload the browser the charts are drawn adjusting perfectly to the new dimensions, but this is not as it should be, as the end user wont be so happy having to reloading the page each time the browser is resized.
The problem is even bigger if the page is visualized in a mobile device, because when first loading the charts will adjust perfectlty to the device's dimensions, but if the user rotate the device and change to 'landscape' mode, as I mentioned the whole screen will get blank until the user make a reload. Can you see my code to give me some clues about what I am doing wrong? Thanks.
$(document).ready(function(){
draw("chartDivs1");
draw("chartDivs2");
draw("chartDivs3");
draw("chartDivs4");
$(window).resize(function() {
$(".chartDivs1,.chartDivs2,.chartDivs3,.chartDivs4,.chartDivs6,").empty();
draw("chartDivs1");
draw("chartDivs2");
draw("chartDivs3");
draw("chartDivs4");
});
})
function draw(chartDiv) {
//set width and height in function of the div where my chart will be rendered.
var width = $("."+chartDiv).width();
var height = $("."+chartDiv).height()
//declare the data (I must change this for a parameter).
var data = [
{ country: "Moon",growth: 40},
{ country: "India", growth: 35},
{country: "Indonesia",growth: 30},
{country: "Russia",growth: 25},
{country: "Mars",growth: 20},
{country: "Pluton",growth: 15},
{country: "House",growth: 10},
{country: "Neptune",growth: 5}
];
//set margins
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
};
var width = width - margin.left - margin.right * 2.5;
var height = height - margin.top - margin.bottom;
//set scales & ranges
var xScale = d3.scaleLinear()
.range([0, width * 1.1 ])
var yScale = d3.scaleBand()
.range([30, height]).padding(.3)
//draw the svg
var svg = d3.select("."+chartDiv)
.append("svg")
.attr("width", width + margin.left + margin.right * 3)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left *1.4 + "," + margin.top + ")")
//Add a Title
svg.append("text")
.attr("x", (width / 2))
.attr("y", 11 )
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "underline")
.text("Title");
//force data
data.forEach(function(d) {
return d.growth = +d.growth;
});
//set domains
yScale.domain(data.map(d => d.country))
xScale.domain([0, d3.max(data, d => d.growth)])
//add X & Y axes and append the bars to Y axis
var xAxis = svg.append("g")
.attr("class", xAxis)
.attr("transform", "translate(" + 0 + "," + height + ")")
.call(d3.axisBottom(xScale))
var yAxis = svg.append("g")
.attr("class", yAxis)
.call(d3.axisLeft(yScale))
.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("stroke", "transparent")
.attr("stroke-width", 4)
.attr("class", "bar")
.attr("height", yScale.bandwidth())
.attr("x", 0.5)
.attr("y", function(d) {
return yScale(d.country)
})
.attr("width", 0)
.transition()
.duration(3800)
.delay((d, i) => (i + 1) * 200)
.ease(d3.easeElastic)
.attr("width", function(d) {
return xScale(d.growth)
})
.style("fill", "#00338D")
.on('end', function() {
d3.select(this)
.on("mouseover", function() {
d3.select(this)
.transition().duration(600)
.attr("stroke", "#6D2077")
.attr("stroke-width", 3)
.style("fill", "#6D2077")
d3.selectAll(".textCircle")
.transition().duration(600)
.attr("r", yScale.bandwidth() / 1.9)
.attr("stroke", "#6D2077")
.attr("stroke-width", 1)
})
.on("mouseout", function() {
d3.select(this)
.transition()
.duration(600)
.attr("stroke", "transparent")
.attr("stroke-width", 0)
.style("fill", "#00338D")
d3.selectAll(".textCircle")
.transition().duration(600)
.attr("r", yScale.bandwidth() / 2)
.attr("stroke", "transparent")
})
})
var newG = svg.append("g")
newG.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("class", "textCircle")
.attr("cx", d => xScale(d.growth))
.attr("cy", d => yScale(d.country) + yScale.bandwidth() / 2)
.attr("r", 0)
.transition()
.duration(1200)
.delay((d, i) => (i + 1) * 450)
.attr("r", yScale.bandwidth() / 2)
.attr("opacity", 1)
.style("fill", "#005EB8")
.attr("stroke", "transparent")
.ease(d3.easeElastic)
var newG4text = svg.append("g").attr("class","newG4text")
newG4text.selectAll(".text").data(data)
.enter()
.append("text")
.attr("x", d => xScale(d.growth))
.attr("y", d => yScale(d.country) + yScale.bandwidth()/2)
.attr("dx","-.45em")
.attr("dy",".4em")
.style("font-size",".8em")
.style("fill","#FFF")
.text(d=>d.growth)
}
html{
height: 98%;
margin: 0;
padding: 0;
}
body{
min-height: 98%;
margin: 0;
padding: 0;
}
svg{
text-rendering: geometricPrecision;
shape-rendering:geometricPrecision;
}
.chCols{
border: 1px groove #333333;
}
.halfVh{
height: 50vh;
}
.flex-container{
display:flex;
-ms-align-items: ;
align-items: center;
justify-content: center;
}
<!-- CDNs-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.4/js/tether.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js"></script>
<!-- End of CDNs-->
<div class="container-fluid">
<div class="row halfVh">
<div class="col-4 chartDivs1 chCols "></div>
<div class="col-4 chartDivs2 chCols "></div>
<div class="col-4 chartDivs3 chCols"></div>
</div>
<div class="row halfVh">
<div class="col-4 chartDivs4 chCols flex-container"></div>
<div class="col-4 chartDivs5 chCols flex-container">
...coming soon.
</div>
<div class="col-4 chartDivs6 chCols flex-container">
...coming soon.
</div>
</div>
</div>
You have a typo on resize method. Remove the ,
from last when you are emptying the charts on resize.
$(".chartDivs1,.chartDivs2,.chartDivs3,.chartDivs4,.chartDivs6").empty();
Worked for me :)