Jesús Estévez
Just another simple developer
by @jecaestevez
Let's play in a online editor CodePen
Absolute positioning; the origin ⟨0,0⟩ is the top-left corner!
let's try apply simple colors
Cascade Style Sheet is a declarative language for assigning styles to elements.
CSS assigns style rules via selectors.
Simple selectors identify elements by one facet
// element with ID myId
#myId // <any id="myId">
// all DIV tags
div // <div>
foo // <foo>
// all elements with CLASS “box”
.myClass // <any class="myClass">
[name=customName] // <any name="customName">
[foo=bar] // <any foo="bar">
// all SPAN tags inside DIVs
div span // <div><span/></div>
foo bar // <foo><bar/></foo>
//all DIV tags and all SPAN tags
div, span // <div/><span/><div><span/><div>
foo, bar // <foo/><bar/><foo><bar/><foo>
//all div tags with CLASS "myClass"
div.myClass // <div class="myClass">
foo.bar // <foo class="bar">
//idiv tag with ID myId
div#myId // <div id="myId">
foo#bar // <foo id="bar">
//<span> with parent <div>
div > span //<div><span/><div>
Open browser console run:
document.querySelectorAll("#myId")
// element with ID myId
#myId // <any id="myId">
// all DIV tags
div // <div>
foo // <foo>
// all elements with CLASS “box”
.myClass // <any class="myClass">
[name=customName] // <any name="customName">
[foo=bar] // <any foo="bar">
// all SPAN tags inside DIVs
div span // <div><span/></div>
foo bar // <foo><bar/></foo>
//all DIV tags and all SPAN tags
div, span // <div/><span/><div><span/><div>
foo, bar // <foo/><bar/><foo><bar/><foo>
//all div tags with CLASS "myClass"
div.myClass // <div class="myClass">
foo.bar // <foo class="bar">
//idiv tag with ID myId
div#myId // <div id="myId">
foo#bar // <foo id="bar">
//<span> with parent <div>
div > span //<div><span/><div>
Let's play in a online editor CodePen
https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js
Returns the element found
d3.select('#myId')
Returns all found elements
d3.selectAll('.myClass')
// element with ID myId
#myId // <any id="myId">
// all DIV tags
div // <div>
foo // <foo>
// all elements with CLASS “box”
.myClass // <any class="myClass">
[name='customName'] // <any name="customName">
[foo=bar] // <any foo="bar">
// all SPAN tags inside DIVs
div span // <div><span/></div>
foo bar // <foo><bar/></foo>
//all DIV tags and all SPAN tags
div, span // <div/><span/><div><span/><div>
foo, bar // <foo/><bar/><foo><bar/><foo>
//all div tags with CLASS "myClass"
div.myClass // <div class="myClass">
foo.bar // <foo class="bar">
//idiv tag with ID myId
div#myId // <div id="myId">
foo#bar // <foo id="bar">
//<span> with parent <div>
div > span //<div><span/><div>
Let's practice Selecting and show in console:
// select the <body> element
var body = d3.select("body");
// add an <h1> element
var h1 = myBody.append("h1");
h1.text("H1 append to the body!");
// select all <section> elements
var allDivs= d3.selectAll("div");
// add an <h1> element to each
var h1 = allDivs.append("h1");
h1.text("Hello!");
many elements selected, adds one element to each.
one element selected, adds one element
// select the <body> element
var body = d3.select("h1");
// remove an <h1> element
var h1 = body.remove("h1");
// select all <section> elements
var allDivs= d3.selectAll("div");
// Remove All <div> element to each
var h1 = section.remove("h1");
many elements selected, remove one element to each.
one element selected, remove one element
d3.select("p")
.style("color","red");
d3.select("div")
.classed("myClass",true);
d3.select("h1")
.attr("title","my description");
From this using
To do this
Data Array
.Enter( )
Elements Rendered
var dataset= [5,15,40,20];
d3.select("body")
.selectAll('div')
.data(dataset)
.enter()
.append("div")
.text(function(data,i){return data});
5
15
40
20
<body>
</body>
var dataset= [5,15,40,20];
d3.select("body");
<body>
<!--
<div></div>
<div></div>
<div></div>
<div></div>
-->
</body>
<body>
<!--
empty
selection
-->
</body>
var dataset= [5,15,40,20];
d3.select("body")
.selectAll('div');
var dataset= [5,15,40,20];
d3.select("body")
.selectAll('div')
.data(dataset);
var dataset= [5,15,40,20];
d3.select("body")
.selectAll('div')
.data(dataset)
.enter();
var dataset= [5,15,40,20];
d3.select("body")
.selectAll('div')
.data(dataset)
.enter()
.append("div");
<body>
<div>5</div>
<div>15</div>
<div>40</div>
<div>20</div>
</body>
<body>
<div></div>
<div></div>
<div></div>
<div></div>
</body>
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d);
Solution:
var dataset= [5,15,40,20];
var mySvg = d3.select("svg");
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("y", 40)
;
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x",(d,i) =>i*100)
.attr("y", 40)
;
<html>
<body>
<svg></svg>
</body>
</html>
svg{
width:500px;
height:100px;
border: 1px solid black;
}
TO DO THIS Started point : bit.ly/d3jsBlankSvg
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("fill", "red")
.attr("x",(d,i) =>i*100 +50)
.attr("y", 40)
;
mySvg.selectAll('circle')
.data(dataset)
.enter()
.append("circle")
.attr("cx",(d,i) =>i*100 +50)
.attr("cy", 40)
.attr("r", (d) =>d)
;
var dataset= [5,15,40,20];
var mySvg = d3.select("svg");
started point to do this
Data Array
Update
Elements Rendered
Solution with circles:
bit.ly/d3jsDataUpdateTextCircleSvg
Solution:
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x",(d,i) =>i*100)
.attr("y", 40)
;
var dataset= [5,15,40,20];
var mySvg = d3.select("svg");
function update(){
dataset = [40,20,10,50];
//Update Data - NOT using Enter()
mySvg.selectAll("text")
.data(dataset)
.text((d) => d)
.attr("x",(d,i) =>i*100)
.attr("y", 40)
;
}
<button onclick="update();">Update</button>
Trigger
Update
Data
Started point:
bit.ly/d3jsStartedPoint
Data Array
.EXIT( )
Elements Rendered
Solution with Circle:
Solution:
bit.ly/d3jsExitTextSvg
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("fill", "red")
.attr("x",(d,i) =>i*100 +50)
.attr("y", 40)
;
var dataset= [5,15,40,20];
var mySvg = d3.select("svg");
function exit(){
dataset =[];
dataset = [5,15,40];
//Update Data
mySvg.selectAll("text")
.data(dataset)
.exit()
.remove()
;
}
<button onclick="exit();">Delete</button>
Started Point:
bit.ly/d3jsStartedPoint
Remove
value
"20"
Data Array
Update
Elements Rendered
.EXIT( )
.ENTER( )
Solution:
bit.ly/d3jsDataObjectEnterTextSvg
var dataset= [
{name: "Daniel", score: 5, colour:"red"},
{name: "Fer", score: 15, colour:"orange"},
{name: "Marc", score: 40, colour:"black"},
{name: "Enric", score: 20, colour:"blue"}
];
var mySvg = d3.select("svg");
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) =>d.score)
.attr("fill", (d)=>d.colour)
.attr("x",(d,i) =>i*100)
.attr("y", 40)
;
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("fill", "red")
.attr("x",(d,i) =>i*100)
.attr("y", 40)
;
Started point to do this
bit.ly/d3jsStartedPoint2
var dataset= [
{name: "Daniel", score: 5, colour:"red"},
{name: "Fer", score: 15, colour:"orange"},
{name: "Marc", score: 40, colour:"balck"},
{name: "Enric", score: 20, colour:"blue"}
];
var mySvg = d3.select("svg");
function getScore(d,i) { return i * 100; }
function getColour(d) { return d.colour; }
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => getScore(d))
.attr("fill", (d)=>getColour(d))
.attr("x",(d,i) =>getScore(d,i) )
.attr("y", 40)
;
Instead to bind to values use functions
mySvg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) =>d.score)
.attr("fill", (d)=>d.colour)
.attr("x",(d,i) =>i*100)
.attr("y", 40)
;
Use functions instead to use directly the values
started point
In other session will see this in details
//Load in GeoJSON data
d3.json("https://codepen.io/jecaestevez/pen/eyNwME.js", function(json) {
//Bind data and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill","#666666");
});
var svgWidth = 800;
var svgHeight = 800;
//Create SVG element
var svg = d3.select("body").append("svg")
.attr({width:svgWidth, height: svgHeight});
//Define path generator
var path = d3.geo.path();
//Load in GeoJSON data
d3.json("https://codepen.io/jecaestevez/pen/eyNwME.js", function(json) {
});
By Jesús Estévez