Reputation: 332
I am trying to make a responsive page with an SVG and some text. Basically I would like the SVG to appear on the left side of the page, and the header and paragraph to appear on the right until the viewing window becomes too small and then to have the elements stack (in the order of: header, paragraph, svg).
I have two problems right now: 1. The header and text run on top of the svg (click on a node in the fiddle below to get the paragraph text to appear). 2. When the viewing window becomes very small, the text seems to disappear off the left side of the browser.
Here’s the jsfiddle: http://jsfiddle.net/westcoast_509/xgafy1to/
And here's the javascript:
var diameter = 960;
var tree = d3.layout.tree()
.size([360, diameter / 2 - 200])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var diagonal = d3.svg.diagonal.radial()
.projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
d3.select("body").append("div")
.attr("class", "wrapper")
var svg = d3.select(".wrapper").append("svg")
.attr("viewBox", "0 0 1500 1500")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr('class', "cluster")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")")
.style("float", 'left');
d3.json("https://api.myjson.com/bins/589z2", function(error, root) {
var nodes = tree.nodes(root),
links = tree.links(nodes);
var link = svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var titleBox = d3.select(".wrapper").append('div', ":first:child")
.attr('class', 'titleBox')
.text('Female Humans Amidst Fauna');
var tooltip = d3.select(".titleBox").append("div")
.attr('class', 'tooltip')
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
.on("mouseover", mouseover)
.on('mouseout', mouseout)
.on("click", function(d) {
tooltip.transition()
.ease('linear')
.duration(2500)
.style('opacity', 1)
.each(function() {
d3.selectAll('.div').transition()
.delay(4000)
.duration(2000)
.style('opacity', 0)
.remove();
})
var word = d.word
tooltip.html(d.beginContext + " " + "<span class='keyword'>" + word + "</span>" + " " + d.endContext);
//.remove();
});
node.append("circle")
.attr("r", 4.5);
node.append("text")
.attr("dy", ".31em")
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; })
.text(function(d) { return d.name; });
});
var chart = $(".cluster"),
aspect = chart.width() / chart.height(),
container = chart.parent();
$(window).on("resize", function() {
var targetWidth = container.width();
chart.attr("width", targetWidth);
chart.attr("height", Math.round(targetWidth / aspect));
}).trigger("resize");
function mouseover() { //makes the text size increase on mouseover
d3.select(this).select("text").transition()
.duration(750)
.style("font-size", "40px");
}
function mouseout() { //returns text to original size
d3.select(this).select("text").transition()
.duration(750)
.style("font-size", "15px");
}
And here's the CSS:
.wrapper {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: top;
overflow: hidden;
}
.node circle {
fill: #fff;
stroke: #41F9D0;
stroke-width: 1.5px;
}
.link {
fill: none;
stroke: #41F9D0;
stroke-width: 1.5px;
}
.keyword {
font-size: 3vw;
color: red;
}
.titleBox {
display: inline-block;
font-size: 5vw;
position: absolute;
width: 500px;
top: 50;
right: 0;
margin-top: 5vw;
float: left;
}
.tooltip {
position: absolute;
width: 400px;
font-family: serif;
opacity: 0;
font-size: 2vw;
margin-top: 50px;
}
.cluster {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
I’m still quite new to CSS/JS, so I appreciate any tips or pointers you might have!
Upvotes: 2
Views: 658
Reputation: 284
I edited your fiddle to adhere to your requests: http://jsfiddle.net/7tzrrpvr/. I hope that's what you wanted!
The reason your svg was overlaying the text is because of your use of absolute positioning. Be careful with this, as setting a div
to position: absolute
takes it out of the normal flow of the DOM and will effectively make it invisible to its neighbours. Additionally, your titleBox
was being dynamically created after the svg, which puts it in a lower position in the DOM. I moved this up in the javascript so that it will be created before the svg.
I added a media query in your css to achieve the responsive effect of stacking the columns for small viewports. Twitter Bootstrap (http://getbootstrap.com/) is a great library that uses media queries to do this for you automatically -- I recommend looking into that if you're planning to go further with responsive design in your app.
Upvotes: 3