So I have a .js file that contains a simple SVG that creates a square. Code below:
function load(){
var xmlns = "http://www.w3.org/2000/svg";
var foo = document.getElementById("printSquare");
var bar = document.createElementNS(xmlns, "svg");
var svgSquare = d3.select("div.output svg")
s.appendChild(svgSquare)
foo.appendChild(bar);
var square = svg.select("rect")
square.attr("width", 200)
square.attr("height", 200)
}
window.onload = load;
I want to append this square to an html file so I can open it in a browser and see the square. My HTML code as of right now:
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="drawSquare.js"></script>
</head>
<body>
<div id="printSquare"></div>
</body>
</html>
Check out this fiddle - https://jsfiddle.net/s8capLx3/2/
If you want to just create a square and nothing else, there are 2 ways to go about it...
Use d3 symbols or 2. Use a rect (like you tried)
var data = [0];
var svg = d3.select('#printSquare').append('svg').attr('width',400).attr('height',200);
//symbols approach
svg.selectAll('.symbol')
.data(data)
.enter()
.append('path')
.attr('transform',function(d,i) { return 'translate('+(i*20+20 )+','+30+')';})
.attr('d', d3.symbol().type( function(d,i) { return d 3.symbols[3];}).size("200"));
//rect approach
svg.append("rect")
.attr("x", "200")
.attr("y", "10")
.attr("width", "75")
.attr("height", "75")
.attr("fill", "black");
Related
I am trying to put a text so that it is located in the center of my element as in the following image:
I would like this to be done dynamically depending on the size of my image.
How can I do it?
<body>
<script type="text/javascript">
const svg = d3.select("body").append("svg").attr("width",1000).attr("height",1000);
var widthMarker=50;
var img = svg.append("svg:image")
.attr("xlink:href", "marker.svg")
.attr("width", widthMarker)
.attr("height", widthMarker)
.attr("x", 228)
.attr("y",53);
svg.append("text").attr("width",100).attr("height",100).text("hello world");
</script>
</body>
http://plnkr.co/edit/39zEvnjOmotZXYF2GFwq?p=preview
You can simply put the image and text in a group container and adjust the text position relatively as shown below.
Plunker
const svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 1000);
var widthMarker = 50;
var imgContainer = svg.append("g")
.attr("transform", "translate(228,53)");
var img = imgContainer.append("svg:image")
.attr("xlink:href", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQgfLDf_0gBVxWp_7ec2UR3Dro5rBXquElgRdSH6K8LQQ7QanSQ")
.attr("width", widthMarker)
.attr("height", widthMarker);
var text = imgContainer.append("svg:text")
.attr("dy", widthMarker/2)
.text("hello world");
text.attr("dx", (widthMarker - text.node().getComputedTextLength()) / 2);
<script src="https://d3js.org/d3.v3.min.js"></script>
I am not succeding in appending a path on a simple svg container.
It considers my "path" element as a text instead.
Here is my code:
// Create the SVG
var tracer = {};
tracer.$container = document.getElementById('container');
tracer.$svg = $('<svg class="svg-d3-table" style="width:100%; height:100%">');
tracer.$container.append(tracer.$svg);
// Specify the path points
var pathInfo = [{x:0, y:60},
{x:50, y:110},
{x:90, y:70},
{x:140, y:100}];
// Specify the function for generating path data
var pathLine = d3.line()
.x(function(d){return d.x;})
.y(function(d){return d.y;})
.curve(d3.curveBasis);
// Append path
tracer.$svg.append("path")
.attr("d", pathLine(pathInfo))
.attr("stroke", "white")
.attr("stroke-width", 8)
.attr("fill", "none");
Instead of having a new path element as
<path d="M314,352L314,352C314,352,314,352,..."></path>
It comes with the following:
<svg class="svg-d3-table" style="..." d="M0,60L8.3,68.3.7,...">path</svg>
What am I missing?
PS: Sorry, I come from c++ and can be struggled with some very basic js operations.
Thank you very much.
Kind Regards.
As others have pointed out in the comments, avoid mixing jquery and d3.
The root of your problems though is that your tracer.$svg is a jquery selector but you are treating it as a d3 selector. While both of them have an append method, they are two wholly different beasts (and as #altocumulus points out, jquery don't play so nice manipulatively SVG).
Here's your code as I would write it with just d3:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="container" style="background-color: steelblue"></div>
<script>
// Create the SVG
var tracer = {};
tracer.$container = d3.select('#container');
tracer.$svg = tracer.$container.append("svg")
.attr("class", "svg-d3-table")
.style("width", "100%")
.style("height", "100%");
// Specify the path points
var pathInfo = [{
x: 0,
y: 60
}, {
x: 50,
y: 110
}, {
x: 90,
y: 70
}, {
x: 140,
y: 100
}];
// Specify the function for generating path data
var pathLine = d3.line()
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
})
.curve(d3.curveBasis);
// Append path
tracer.$svg.append("path")
.attr("d", pathLine(pathInfo))
.attr("stroke", "white") //<-- need a color?
.attr("stroke-width", 8)
.attr("fill", "none");
</script>
</body>
</html>
Thanks to altocumulus:
jquery's append not working with svg element?
Is exactly the kind of information I was looking for better understanding of manipulating DOM (but still shows me how much front-end development can be akward).
Thank to Gerardo Furtado:
Indeed the need of different lib leads easily to confusing behavior and makes JS hard to handle when working on an existing project (how to determine namespace by reading code, avoid collision...)
I handled my problem by only managing my svg using D3 as you adviced:
tracer.$svg = tracer.capsule.$svg = d3.select("#" + tracer.defaultName)
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("id", tracer.defaultName + "-svg")
.attr("class", "svg-d3-table")
.attr("xmlns", "http://www.w3.org/2000/svg");
Thank you for your comments.
I get a blank screen when the browser tries to render the following code and its json file. happens both Safari and Chrome. Seems like it renders the SVG in the canvas but not the rest. Am I missing something in the structure? Or should it be run on a server ?
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<script>
// load the external data from built-in method in D3
d3.json("datastuff.json", function(data) {
// after data load then...
var canvas = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) { return d.age * 10; })
.attr("height", 50)
.attr("y", function (d,i) {return i * 50; })
.attr("fill", "blue")
})
</script>
</body>
</html>
Here is its associated external datastuff.json file.
[
{“name”:”Maria”,”age”:30},
{“name”:”Fred”,”age”:50},
{“name”:”Francis”,”age”:12}
]
All:
For example I have array of string:
["string1","string2","string3","string4","string5"]
I want to add all of them into a div with separate them like:
<div>
string1<br>
string2<br>
string3<br>
string4<br>
string5
</div>
I wonder how to do it with D3? I am thinking use selectAll()...data()...enter().append(), but I do not know how to append this.
Thanks
Data binding in d3 is about appending an element to the dom for each item in your data. What you are asking for, though, is how do I get one element with my strings separated by a <br/>:
var arr = ["string1","string2","string3","string4","string5"];
d3.select('body')
.append('div')
.html(arr.join('<br/>'));
A more d3ish way to get the same appearance is (but this gives you a div per string):
var arr = ["string1","string2","string3","string4","string5"];
d3.select('body')
.selectAll('div')
.data(arr)
.enter()
.append('div')
.text(function(d){
return d;
});
A third approach is to use <span>s:
d3.select('body')
.selectAll('span')
.data(arr)
.enter()
.append('span')
.text(function(d){
return d;
})
.append('br');
Here's an example with both approaches:
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<script>
var arr = ["string1","string2","string3","string4","string5"];
d3.select('body')
.selectAll('div')
.data(arr)
.enter()
.append('div')
.text(function(d){
return d;
});
d3.select('body')
.append('div')
.html(arr.join('<br/>'))
d3.select('body')
.selectAll('span')
.data(arr)
.enter()
.append('span')
.text(function(d){
return d;
})
.append('br');
</script>
</body>
</html>
you should appendChild to the div;
try something like this(this is pure js !!!):
var myArray=["string1","string2","string3","string4","string5"];
var test = document.querySelector(".test")
myArray.forEach(function(x){
var textnode = document.createTextNode(x);
test.appendChild(textnode )
})
https://jsfiddle.net/maio/m3sqjjb3/
I have to plot a custom polar chart in which the radius of the circles vary and the grid lines are created at 30 degrees separation.Below is my code which plots the circle. The problem is that I am not able to plot the gridlines on the svg. The gridlines takes values from the list grid and it has values in x1,y1,x2,y2 format. Any idea why is it not plotting the gridline?
The image shows that it is taking only a single value from the list and appending it in the variables x1,y1,x2,y2
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
</head>
<body>
<div id="circles"></div>
<script type="text/javascript">
var circleRadii = [100,90,80,70,60,50,40,30,20];
var min_radii = d3.min(circleRadii);
var max_radii = d3.max(circleRadii);
var theta_range = d3.range(0,360,30);
document.write(theta_range);
//set the svg container size
width = 750;
height = 750;
grid = [395,375,392.32,385,385,392.32,375,395,365,392.32,357.68,385,355,375,357.68,365,365,357.68,375,355,385,357.68,392.32,365,395,375]
var svgContainer = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
var circles = svgContainer.selectAll("circle")
.data(circleRadii)
.enter()
.append("circle")
var circleAttributes = circles
.attr("cx",width/2)
.attr("cy",height/2)
.attr("r", function (d) { return d; })
.style("stroke","gray")
.style("fill","white");
var gridlines = svgContainer.append("gridline")
.data(grid)
.enter().append("gridline")
.attr("x1",function(d){return d;})
.attr("y1",function(d){return d;})
.attr("x2",function(d){return d;})
.attr("y2",function(d){return d;})
.attr("stroke", "black")
.attr("stroke-width", 2);
console.log(gridlines);
</script>
</body>
</html>