Set div width using D3 - javascript

I created a div in my html,
<div id="search"></div>
I want to set its width to 15% of my window width in my Javascript. I'm attempting to use D3 to do this:
var width = 0.15 * window.innerWidth,
height = 0.95 * window.innerHeight;
var searchcolumn = d3.select("#search")
.attr("width", width)
.attr("height", height);
I can see in the DOM, the width and height of my div has been changed:
However, in the rendered html the div is just 10px x 10px.
Why does this happen? I do not have any CSS that overwrites the size of the div. How do I set my div to my desired width?

This is an old post but for anyone else wanting to solve this, the following will work :
var width = 0.15 * window.innerWidth,
height = 0.95 * window.innerHeight;
var searchcolumn = d3.select("#search")
.style("width", width + 'px')
.style("height", height + 'px');
I have added is + 'px'; and also changed .attr to .style as it's the CSS you are working with here.
Working code :
var data = [10,12,6,8,15];
var svg = d3.select('body')
//.append('svg')
.attr('width', 500).attr('height', 500);
var width = 0.15 * window.innerWidth,
height = 0.95 * window.innerHeight;
svg.selectAll('div')
.data(data)
.enter().append('div')
.attr('class','divs')
.attr('x', function(d,i) { d.clicked=false; return 100+100*i; })
.attr('y', function(d,i) { return 0; })
.style('width', width + 'px')
.style('height',height +'px')
.attr('background-color', function() { return 'red'; })
.text(function(d){ return d;})
.divs {
background: blue;
display:inline-block;
float:left;
margin:5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Try:
d3.select("#search")
.style("height", height)
.style("width", width);

You can simply do the following when you want to set multiple style attributes instead of repeating style(" ", " ") n times:
d3.select("#search").style({
'height': height+'px',
'width': width+'px'
});
Hope that helps.

Related

Why Tooltip is not moving with mouse?

This is a code for making pie chart.
I have added 2 functionalities to pie chart. First one is to increase the arc size when mouse hovers on it.
Second is that when i hover, tooltip displays y position of mouse and this tooltip moves with mouse.
But problem with me is that. Tooltip Text is not moving with movement of mouse.
I have seen various stack overflow links for this but i am unable to find solution. Below i have also attached links that so that the question is not marked duplicate.
Please do not give me a new code for tooltip. Correct this one.
Below are the links that i have already visited
Why is my D3.js tooltip not working
D3 - Positioning tooltip on SVG element not working
Tooltips not showing on mouse move and mouse over
Link of jsfiddle :- https://jsfiddle.net/uoh1bsrp/
Thanks,
Shubham Sharma
width = 600
height = 600
svg = d3.select('body').append('svg').attr('width',width).attr('height',height).append('g').attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')');
a = [2,5,7]
pie = d3.pie()
radius = 150
arc = d3.arc().innerRadius(0)
.outerRadius(radius);
arcs = svg.selectAll('arc').data(pie(a)).enter().append('g')
arcs.append("path").attr('d',function(d){return arc(d)})
tooltip = svg.append('text')
color = ['red','green','blue']
path = d3.selectAll('path').style('fill',function(d,i){return color[i]})
path.on('mouseover',handlemouseover)
path.on('mouseout',handlemouseout)
path.on('mousemove',handlemousemove)
function handlemouseover(){
d3.select(this).attr('d',function(d){return d3.arc().innerRadius(0)
.outerRadius(180)(d)});
}
function handlemousemove(){
// svg.append('text').text(function(){return 'shubham'}).style('top',(d3.event.layerY + 10)+'px').style('left',(d3.event.layerX + 10) + 'px')
tooltip.text(function(){return d3.event.layerX}).style('top',(d3.event.layerY + 10)+'px').style('left',(d3.event.layerX + 10) + 'px').style('display','block');
}
function handlemouseout(){
d3.select(this).attr('d',function(d){return d3.arc().innerRadius(0).outerRadius(radius)(d)});
tooltip.style('display', 'none');
}
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-path.v1.min.js"></script>
<script src="https://d3js.org/d3-shape.v1.min.js"></script>
</head>
That's because you are trying to increase top property of text tag in SVG. This porperty just doesn't work. You can use translate instead of it or just use tags like div or span.
Check the fiddle https://jsfiddle.net/fr71t0o3/3/:
function handlemousemove() {
// svg.append('text').text(function(){return 'shubham'}).style('top',(d3.event.layerY + 10)+'px').style('left',(d3.event.layerX + 10) + 'px')
tooltip
.text(function() {
return d3.event.layerX;
})
.style('transform', `translate(${d3.event.layerX - 300}px, ${d3.event.layerY - 300}px)`)
.style('display', 'block').style('color','red');
}
I'm not sure about offset of tooltip, if you want it moving with the mouse move you can use mouse coordinates.
Instead of .style('left', /*[...]*/) and .style('top', /*[...]*/) you can use .attr('x', [...]) and .attr('y', [...])
Also, you have to substract height/2 from y and width/2 from x, as the x and y attributes move text relative to its parent:
width = 600
height = 600
svg = d3.select('body').append('svg').attr('width',width).attr('height',height).append('g').attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')');
a = [2,5,7]
pie = d3.pie()
radius = 150
arc = d3.arc().innerRadius(0)
.outerRadius(radius);
arcs = svg.selectAll('arc').data(pie(a)).enter().append('g')
arcs.append("path").attr('d',function(d){return arc(d)})
tooltip = svg.append('text')
color = ['red','green','blue']
path = d3.selectAll('path').style('fill',function(d,i){return color[i]})
path.on('mouseover',handlemouseover)
path.on('mouseout',handlemouseout)
path.on('mousemove',handlemousemove)
function handlemouseover(){
d3.select(this).attr('d',function(d){return d3.arc().innerRadius(0)
.outerRadius(180)(d)});
}
function handlemousemove(){
// svg.append('text').text(function(){return 'shubham'}).style('top',(d3.event.layerY + 10)+'px').style('left',(d3.event.layerX + 10) + 'px')
tooltip.text(function(){return d3.event.layerX}).attr('y',(d3.event.layerY - height/2 + 10)+'px').attr('x',(d3.event.layerX - width/2 + 10) + 'px').style('display','block');
}
function handlemouseout(){
d3.select(this).attr('d',function(d){return d3.arc().innerRadius(0).outerRadius(radius)(d)});
tooltip.style('display', 'none');
}
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-path.v1.min.js"></script>
<script src="https://d3js.org/d3-shape.v1.min.js"></script>
</head>
You have to append a div and add css styles to it.
Working jsfiddle: https://jsfiddle.net/amp42fjn/
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
path.on("mouseover",handlemouseover)
path.on("mousemove", handlemousemove)
path.on("mouseout", handlemouseout);
function handlemouseover(){
d3.select(this).attr('d',function(d){return d3.arc().innerRadius(0)
.outerRadius(180)(d)});
tooltip.style("visibility", "visible");
}
function handlemousemove(){
tooltip.text(function(){return d3.event.layerX}).style('top',(d3.event.layerY + 10)+'px').style("top",
(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");
}
function handlemouseout(){
d3.select(this).attr('d',function(d){return d3.arc().innerRadius(0).outerRadius(radius)(d)});
tooltip.style("visibility", "hidden");
}

How to resize d3 map

I have this map in d3 consisting of a chart and map:
I define a few global variables:
var chartWidth = window.innerWidth * 0.425,
chartHeight = 473,
leftPadding = 35,
rightPadding = 2,
topBottomPadding = 5,
innerWidth = chartWidth - leftPadding - rightPadding,
innerHeight = chartHeight - topBottomPadding * 2,
translate = "translate(" + leftPadding + "," + topBottomPadding + ")";
Here's the map:
//set up the map
function setMap(){
var width = window.innerWidth * 0.55, //dimensions
height = 580; //dimensions
//create new svg container for the map
var map = d3.select("body")
.append("svg")
.attr("class", "map")
.attr("width", width)
.attr("height", height);
And a linked chart:
function setChart(csvData, colorScale, attribute){
var expressed = attribute
//create a second svg element to hold the bar chart
var chart = d3.select("body")
.append("svg")
.attr("width", chartWidth)
.attr("height", chartHeight)
//assign class
.attr("class", "chart");
//create a rectangle for chart background fill
var chartBackground = chart.append("rect")
.attr("class", "chartBackground")
.attr("width", innerWidth)
.attr("height", innerHeight)
.attr("transform", translate);
}
I'm trying to make the map (the map itself and the associated chart, both are appended to 'map' canvas) responsive, so it will resize when window is resized. I've inserted the following code in the setMap function with no luck, hoping to re-class the 'map' on re-size:
d3.select("map")
.append("div")
.classed("svg-container", true) //container class to make it responsive
.append("svg")
//responsive SVG needs these 2 attributes and no width and height attr
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 " + width + " " + height)
//class to make it responsive
.classed("svg-content-responsive", true);
What can I try to achieve this?

Internet Explorer Scaling not working properly

I have a map created with d3. I set it to have the width of the parent div (with id map) and height with a ratio of 5/9 to to the width. The viewBox has been set to "0 0 width height".
Here is the setup:
var width = $("#map").width(),
height = width * 500 / 900,
active = d3.select(null);
var projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
path = d3.geo.path()
.projection(projection);
svg = d3.select("#map").append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("viewBox", "0 0 " + width + " " + height)
g = svg.append("g");
Here is how it looks like in Chrome:
But it looks like this in IE:
The scaling is completely messed up. I believe it has to do with the viewBox. Could someone explain how to solve this issue?
Thanks!
The problem you are having is that height: "100%" is handled differently by Chrome and IE. You have smartly set your height variable to be based on your width and aspect ratio, but to take advantage of this, you'll need to use these values when setting the dimensions of your svg as well as the viewBox:
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", "0 0 " + width + " " + height);

Strange behavior of Bootstrap Accordion Expand Height with D3 Graph

I have a circle packing layout of D3 within a bootstrap accordion (where all the tabs are expanded on load). I have tried to allow for a responsive layout by using the following:
var vis = d3.select("#Vis_container").insert("svg:svg", "h2")
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox', '0 0 ' + w + ' ' + h)
.attr('preserveAspectRatio', 'xMinYMin')
.append("svg:g")
.attr("transform", "translate(" + 0 + "," + 0 + ")");
If you collapse the tab that contains the D3 layout and expand it again, the svg's height is fine, but the container it is in does not resize correctly i.e. not enough height is provided for the entire layout to show.
Note: I used the container's width as its height as well, due to the height not being available on load.
var w = $('#Vis_container').width(),
h = $('#Vis_container').width()
Can anyone help me to correct the height of the container / accordion when the tab is expanded again?
See the fiddle here: http://jsfiddle.net/Sim1/sLMC2/7/
I am offering this as an alternative. Here is the FIDDLE.
Basically, I gave an initial (and hopefully reasonable) value for width and height, and then added code to re-size after that, if desired. May this will help.
var vis = d3.select("#Vis_container")
.insert("svg:svg", "h2")
.attr("width", h)
.attr("height", w)
...
var chart = $("#Vis_container>svg"),
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");

d3.js scale donut chart in resize event

I drew my chart with two dimensions to the width of the window:
var width = (window.innerWidth < 1280) ? 400 : 600,
height = (window.innerWidth < 1280) ? 400 : 500,
radius = Math.min(width, height) / 2;
var arc = d3.svg.arc().innerRadius(radius).outerRadius(radius - 10),
arcFinal = d3.svg.arc().innerRadius(radius - 100).outerRadius(radius - 10),
arcHover = d3.svg.arc().innerRadius(radius - 100).outerRadius(radius);
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("id", "pie")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");}
What is the best way to update this function in resize event?
Ok, I fixed by adding:
...
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", "0, 0, " + width + ", " + height)
.attr("preserveAspectRatio", "xMinYMin")
...
Then I updated the width and height on resize event

Categories