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/
Related
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");
I'm trying to load a csv file with x and y coordinates and create circles with that coordinates. I've understood how to load a csv file and i can log coordinates in the console but I don't understand why the log function return Not_a_number when i try to create circles. Is there a problem with mine data.map function? Thanks
Here the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="d3/d3.v3.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 900;
var h = 500;
var padding = 20;
var dataset = [];
d3.csv("dataset.csv", function(data) {
dataset = data.map(function(d,i) {
//THIS WORKS
console.log(d);
console.log(i);
return [ +d["x-coordinate"], +d["y-coordinate"]
]; });
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
//THIS DOESNT WORK
console.log(d);
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", function(d) {
return d[1];
})
});
</script>
</body>
</html>
You can only access the dataset after it has been asynchronously loaded inside d3.csv.
The code inside d3.csv is executed asynchronously, meaning it would run only after the file has been loaded, it is not guaranteed to run before the code below it.
d3.csv("dataset.csv", function(data) {
dataset = data.map(function(d,i) {
//THIS WORKS
console.log(d);
console.log(i);
return [ +d["x-coordinate"], +d["y-coordinate"]
]; });
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
//THIS DOESNT WORK
console.log(d);
return d[0];
})
.attr("cy", function(d) {
return d[1];
})
.attr("r", function(d) {
return d[1];
})
.text("hello world");
});
Alternatively, create a method and pass dataset into that method inside d3.csv.
The following is my code. Yet when I run it I get a blank page. Why is this the case ? Also how can I use data from hundreds of columns to make a simple interactive visual using d3 ? I would like to add that the following csv file "LoanStats3a.csv" is in the same folder.
<html>
<title>Loans</title>
<link href="../css/jquery-ui.css" rel="stylesheet" />
<script src="../Scripts/jquery-1.12.4"></script>
<script src="../Scripts/jquery-1.12.4.js"></script>
<script src="../Scripts/jquery-ui.js"></script>
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
<style>
#LoanStats3a{
color: blueviolet;
}
</style>
<body>
<script>
d3.csv("LoanStats3a", function (file1){
var bg = d3.select("body").append("svg")
.attr("width", 5000)
.attr("height", 5000);
bg.selectAll("rect")
.data(file1)
.enter()
.attr("width", function(d){return d.loan_amnt / 100;})
.attr("height", function(d) {return d.term;})
.attr("y", function (d,i) {return i *50;})
.attr("fill", function (d){"red","blue";});
}
</script>
</body>
This is because after binding the data to your empty selection, you have to append a rect element for each data.
Also, your attribute "fill" is incorrect.
bg.selectAll("rect")
.data(file1)
.enter()
.append("rect") // <= You need to create a rect for each data
.attr("width", function(d){return d.loan_amnt / 100;})
.attr("height", function(d) {return d.term;})
.attr("y", function (d,i) {return i *50;})
.attr("fill", "blue");
If you want to change the color depending on the data, create a function and return something.
// For example
.attr("fill", function(d){return d.loan_amnt > 25000 ? "blue" : "red"});
Here's a JsFiddle with random data : DEMO
EDIT : If it's still not working, it's probably a problem with your data because the only thing different between our code is that I used custom data in the JsFiddle.
I notice that your csv file doesn't have the extension .csv, it's just LoanStats3a ?
You should do a console.log(file1), to check if your data are correct.
Take a look at D3 CSV for how to load a csv file.
You are missing a closing ) at the end:
.attr("fill", function (d){"red","blue";});
}
// ^ Here should be a )
</script>
It helps if you have proper indent:
<script>
d3.csv("LoanStats3a", function(file1) {
var bg = d3.select("body").append("svg")
.attr("width", 5000)
.attr("height", 5000);
bg.selectAll("rect")
.data(file1)
.enter()
.attr("width", function(d) {
return d.loan_amnt / 100;
})
.attr("height", function(d) {
return d.term;
})
.attr("y", function(d, i) {
return i * 50;
})
.attr("fill", function(d) {
"red", "blue"; // What is going on here?
// Did you for to return?
// return "blue";
});
});
</script>
I am trying to draw a circle using d3.js with text inside it.
Here is my code:
<script src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>
<div class="circles"></div>
<script>
$(document).ready(function () {
circles();
$(".circles").show();
function circles() {
var svg = d3.select(".circles");
var groups = svg.selectAll("div")
.data("DEMO")
.enter()
.append("div");
groups.attr("transform","translate(" +100+ "," +100+ ")");
var circles = groups.append("circle")
.attr("cx", "100")
.attr("cy","100")
.attr("r", "100")
.attr("fill", "red")
.attr("stroke-width","2.4192")
.attr("stroke","#00ffff");
var label = groups.append("text")
.text(function(d){
return d;
})
.attr({
"alignment-baseline": "middle",
"text-anchor": "middle",
"font-family":"Arial",
"font-size":"30",
"fill":"white"
});
}
});
</script>
But it displays only the text and the circle is not being displayed.
I am unable to fix it.
Can anyone please point out my mistake and help me fix it.
You're appending a <circle> element in HTML, not SVG. It doesn't have any meaning there, so it doesn't get rendered. You need to append an svg element, then append your circle and text nodes to that.
Fill, stroke-width, and stroke should also be applied with .style instead of .attr.
Some relevant code changes are:
var svg = d3.select('.circles').append('svg') // added .append('svg')
.attr('height', /* set the height */)
.attr('width', /* set the width */);
var groups = svg.selectAll('g') // 'g' instead of 'div'
.data('DEMO')
.enter().append('g');
I tried to show my two Line Chart using D3.js,
I can display the first chart "blob",
But it doesn't work with "blub"!!
How can I fix it and how to simplify the for loop?
var canvas=d3.select("body")
.append("svg")
.attr("width",500).attr("height",300);
var donnees= {
blob:[
{x:10,y:20},{x:20,y:60}, {x:30,y:70},
{x:40,y:202},{x:50,y:260}, {x:60,y:70},
{x:70,y:75},{x:80,y:70}, {x:90,y:0}
],
blub:[
{x:100,y:20},{x:110,y:20},{x:120,y:60}, {x:130,y:70},
{x:140,y:32},{x:150,y:60}, {x:160,y:90},
{x:170,y:75},{x:180,y:100}, {x:190,y:20}
]
};
var groupe= canvas.append("g")
.attr("transform", "translate(20,20)");
var line= d3.svg.line()
.x (function(d){return d.x})
.y (function(d){return d.y});
var colors = d3.scale.category20();
var index = 0;
for (var i in donnees) {
groupe.selectAll("path")
.data([donnees[i]])
.enter()
.append("path")
.attr("d",line)
.attr("fill", "none")
.attr("stroke", colors(index))
.attr("stroke-width","1");
index++
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
First off, you don't need a loop here (you almost never do in D3), but you can use nested selections:
groupe.selectAll("g")
.data(d3.values(donnees))
.enter()
.append("g")
.selectAll("path")
.data(function(d) { return [d]; })
.enter()
.append("path")
...
The problem you're seeing specifically is because you're selecting path elements, which, after the first iteration of the loop, will be there already. That is, the data you provide in .data() is matched by the existing path element and hence the .enter() selection is empty, adding nothing. You can work around this e.g. by assigning a class to each path that allows you to distinguish them, but a better solution is to use nested selection as I've outlined above.
Complete demo here.
See this tutorial for more details on how selections work.
Instead of using data() and enter(), i directly appended the path tag to g tag which worked for me.
var canvas=d3.select("body")
.append("svg")
.attr("width",500).attr("height",300);
var donnees= {
blob:[
{x:10,y:20},{x:20,y:60}, {x:30,y:70},
{x:40,y:202},{x:50,y:260}, {x:60,y:70},
{x:70,y:75},{x:80,y:70}, {x:90,y:0}
],
blub:[
{x:100,y:20},{x:110,y:20},{x:120,y:60}, {x:130,y:70},
{x:140,y:32},{x:150,y:60}, {x:160,y:90},
{x:170,y:75},{x:180,y:100}, {x:190,y:20}
]
};
var groupe= canvas.append("g")
.attr("transform", "translate(20,20)");
var line= d3.svg.line()
.x (function(d){ return d.x})
.y (function(d){return d.y});
var colors = d3.scale.category20();
var index = 0;
for (var i in donnees) {
groupe
.append("path")
.attr("d", line(donnees[i]))
.attr("fill", "none")
.attr("stroke", colors(index))
.attr("stroke-width", 1);
index++
}