Using images in D3 bubble charts (Part 2)
Using images in D3 bubble charts, Part 2 (SVG defs/images in d3)
Transcript
alright so we just used definitions in
d3 in order to figure out how to put
background images on SVG elements so 10
second review and we have this index
file here there's an SVG there's a
section called Dex deaths are
definitions of reusable components the
one that we're most interested in is a
pattern component that has an image
inside of it so this image points to
snow jpg which is an image of John Snow
and then we can apply this as a fill to
any object on the page by saying URL
pound symbol or hashtag John Snow so
this here matches with the ID of the
pattern so what we are going to do is
we're going to figure out how to apply
this to d3 so this is the code that we
are using we're reusing the code from a
couple tutorials ago where we made these
this bubble graph of different artists
album sales so we have a name and ID
sales decade and an image at so the
image path will be useful later but just
know that each one of these circles is a
different artist and it is sized
according to the millions of albums they
have sold over the course of their
career so we'll come back to this in a
bit so the first thing we're going to do
is we're going to figure out how to add
definitions to this page through d3 and
we're going to make every one turn into
John Snow so what we're going to do is
we are going to add definitions to the
page so we need to create a section that
is called deaths the best thing to do
would be to add this right under the SVG
but it seems to work no matter where we
add it so let's just add it the easiest
spot so let's take the code that we want
to steal so we're going to copy
from deaths to deaths and I'm just going
to put it in here in a comment but we
don't need the marker we don't need the
linear gradient we don't need the radial
gradient we don't need that comment we
don't need this this is the content here
that we would like to add into our page
so let's add it into the SVG so we want
to add a depth to this page so VAR
deaths equals SVG append def so it's
just going to add a def stag inside of
the SVG we're going to save that as a
variable because we're going to need to
use it later on but for now just know
when you make depth save it by
themselves inside of that depths we need
to add a pattern element so deaths dot
append pattern pretty simple right but
now comes the crazy part the part that I
hate about doing SVG depths in d3 and
that is translating all of these
attributes to something that is inside
of the SVG so we could just we can't
just type it all out what we need to do
is in the same way that for the circles
we do attr are attrs fill and that makes
this circle have a R and the circle has
a fill we need to do the same thing for
this pattern tag so attr ID the ID is
right here it's John Snow great now
height 100% great the next one with 100%
the next one pattern content units not
typing that out on the next one and then
it is a object bounding box
okay so now what we need to do is we've
made deaths we've made a pattern we can
just refresh to make sure that this is
working - so to refresh this page we go
divide each art look in the SVG and we
see there are some depths and we see yes
there is a pattern on that pattern is
currently empty we need to add inside of
that pattern this little image section
so we can just keep chaining this
together dot append image attr height is
1 and width is 1 height of 1 width of 1
preserve aspect ratio none XML namespace
X link
I think we might not need this one
because d3 does namespacing by itself
but just to be safe
we'll keep it and we'll say X link
Pietra slinky trap
Snow dot jpg Snow dot jpg alright so
what we just did then was we created a
definition section we added a single
pattern to it gave it an ID so we can
refer to it later
except the height width pattern content
units what does that do google it and
then we put an image inside of that so
save it refresh the page look an ID or
looking div SVG gee Dex pattern great so
it looks like this works we have a depth
section with a pattern and an image
inside of it now let's apply this
pattern to all of our circles so when we
were doing this let's still open guess
in order to make John Snow appear in
this circle or in this rectangle we had
to do URL hash tag the ID so John Snow
is the ID of the pattern so we just said
URL hash tag John Snow that we can do
the same thing here
so if we scroll down scroll down scroll
down to where we set the fill to be
light blue it is now going to be URL
hash and we look up then oh it's still
the same we call the John Snow so John
Snow
you just have to make sure that this
matches this so save and refresh and now
1 million John snows for our pleasure
now if we click these last time we made
it so that you can see what this is this
is Madonna Holland oats and eagles um
none of those musicians look like Jon
Snow so probably we should make those
images not reflect John snow but rather
reflect the artists themselves so there
is a folder that I have called images
and it has images of everyone in it
they've been cropped to be square and if
we look at our Excel spreadsheet there
is a column called image path so we know
where the image for Steely Dan is we
know where the image for Fetty WAP is so
we're going to be able to use these in
our code so all right back to our code
no we made one pattern for John Snow and
then we called it by saying URL John
Snow the problem is that to make a
pattern that has a Jon Snow Imogen in it
we needed to make one pattern with one
image in it if we want to make how many
of these do we have here if we want to
make 15 different patterns are we going
to manually do this 15 different times
no that would be crazy it would be it
would be nuts so this is where the magic
of d3 comes in so how many circles do we
have here oh we have 15 circles how did
we get these 15 separate circles to show
up well to make 15
different circles we just did that
select all data enter append and that
added 15 different circles into our SVG
we're going to end up doing the exact
same thing with patterns we need to add
15 extra patterns inside of our depths
and so we are just going to do deaths
and then the select all enter append so
that instead of making 15 different
circles we make 15 different patterns
one pattern for every single one of our
artists because we're going to give them
each a unique image so we don't need are
there so deafs dot select all now we
want to create pattern so you might
think to do pattern here but that's
actually going to interfere with the Jon
Snow pattern that we've already made so
let's give it a class we'll call it
artist pattern bind it to our data
points enter append pattern let's just
look at our page and see if this worked
so we're saying go into the definitions
find let's just set the class to we're
saying go into the deaths find all the
artist patterns whatever those are bind
them to our data points put a new
pattern in for every single one of our
data points and give it a class so
refresh open open open open so we now
have 15 blank patterns in here and what
we need to do is make our pattern in the
exact same way that we made this pattern
here so it means the same attributes
except the ID will be different and it
needs to have an image inside with a
different href so we can actually just
cut and paste copy everything that we
did to this pattern and then move it on
down here so every single pattern is
going to get
the exact same height with pattern
content units on height with preserve
expect ratio but also I D so let's let's
change these things real quick so
instead of the ID being John snow if we
look at our excel sheet there is an ID
there is a name
those are both unique let's displease
name for now so return d dot name so now
the name instead of being always John -
snow it will be say Madonna or the
Eagles and if you think oh no you're
doing something wrong we'll figure out
why I'm doing something wrong later and
additionally instead of always using
snow jpg we want to look at our data
point and then find the correct image
URL in image path so let's return d dot
image path let's refresh this look
inside and sure we sure enough have a
pattern with the idea of Madonna and
then it is going for Madonna dot PNG
wonderful so instead of always using
John Snow so these are circles actually
let's move this before our circles just
to think about the fact that we are
creating our definitions or actually
drawing our circles
so we have our circles here we're
binding our data blah blah blah I'm you
setting our fill and the fill is always
going to eat URL John Snow so let's
change this
let's just save it like this and refresh
to make sure it still works as John Snow
yes now we need to change this so
instead of John Snow it will do
something like Madonna so what we need
to do is just change it so that we're
using D dot name here because in the
same way that we set the ID according to
the name we're now going to refer to it
by the name when we're using URL
fill we refresh and some of them work
and some of them don't work so if we
look at this we see that yes it's saying
URL Madonna and it's successfully
grabbing Madonna on URL Kesha and it's
SS successfully grabbing Kesha but let's
say over here but Nicki Minaj is not
working and why is that well it's this
friend right here the space anytime you
are giving something an ID or a class
you don't want to put spaces in it if
you put spaces in a class it means
you're assigning multiple classes if you
put spaces in an ID it's just going to
break so we're going to fix this and the
first way we're going to fix it is going
to be wrong and then we're going to fix
it in the right way a few seconds later
so let us go first up here to where we
set the ID now the problem is this space
so let's just replace the space with a
dash that seems pretty reasonable we
could also do to lowercase just - things
look better when they're lowercase I
think and we want to make sure that we
use the same code here and down here so
instead of D name we're now going to
look for let's say a URL a Nicki Minaj
alpha coming up here and it's now going
to be the - equals
so anything we do to ID here we have to
also do to fill here because this URL
has to match that ID this is the pattern
this is the circle film refresh great
they're mostly working except one over
here isn't working
Hall and Oates is not working so let's
look at Nicki Minaj real quick and we
see that she does successfully have a
dash there but if we look over here at
Holland Oats there's Hall - and space
oats now a weird thing with replace in
JavaScript is it only replaces the very
first instance so only the first space
is going to be replaced by that - by
that - except that you think there's
like a do it globally replace all but
there's not we need to actually use a
regular expression and we need to make
it a global regular expression and
you're probably sobbing you're sweating
a little bit right now but really all
you need to do is this this means space
replace it globally you could make this
a little bit fancier you could say
replace anything that is not a through z
one through zero zero through nine I
guess anything that's not a normal ASCII
character for example Kesha is on here
and if used a dollar sign it would break
some things but to clean that up for us
so we are just going to do this guy here
and this guy here because again these do
you have to match so replace every
single space with the - and you are good
to go now so what we did was we figured
out how to make a separate depth for
every single one of our artists so that
they each have their specific background
image in their own specific pattern and
so one pattern per person one image per
person and then we applied those
patterns
to the circles so they're going to be to
select all enter pens one for a pattern
and one for the circles all right in the
next video we're going to figure out how
to manipulate our forces to make them
split according to whether they are in
the pre 2004 post 2000 group
d3 in order to figure out how to put
background images on SVG elements so 10
second review and we have this index
file here there's an SVG there's a
section called Dex deaths are
definitions of reusable components the
one that we're most interested in is a
pattern component that has an image
inside of it so this image points to
snow jpg which is an image of John Snow
and then we can apply this as a fill to
any object on the page by saying URL
pound symbol or hashtag John Snow so
this here matches with the ID of the
pattern so what we are going to do is
we're going to figure out how to apply
this to d3 so this is the code that we
are using we're reusing the code from a
couple tutorials ago where we made these
this bubble graph of different artists
album sales so we have a name and ID
sales decade and an image at so the
image path will be useful later but just
know that each one of these circles is a
different artist and it is sized
according to the millions of albums they
have sold over the course of their
career so we'll come back to this in a
bit so the first thing we're going to do
is we're going to figure out how to add
definitions to this page through d3 and
we're going to make every one turn into
John Snow so what we're going to do is
we are going to add definitions to the
page so we need to create a section that
is called deaths the best thing to do
would be to add this right under the SVG
but it seems to work no matter where we
add it so let's just add it the easiest
spot so let's take the code that we want
to steal so we're going to copy
from deaths to deaths and I'm just going
to put it in here in a comment but we
don't need the marker we don't need the
linear gradient we don't need the radial
gradient we don't need that comment we
don't need this this is the content here
that we would like to add into our page
so let's add it into the SVG so we want
to add a depth to this page so VAR
deaths equals SVG append def so it's
just going to add a def stag inside of
the SVG we're going to save that as a
variable because we're going to need to
use it later on but for now just know
when you make depth save it by
themselves inside of that depths we need
to add a pattern element so deaths dot
append pattern pretty simple right but
now comes the crazy part the part that I
hate about doing SVG depths in d3 and
that is translating all of these
attributes to something that is inside
of the SVG so we could just we can't
just type it all out what we need to do
is in the same way that for the circles
we do attr are attrs fill and that makes
this circle have a R and the circle has
a fill we need to do the same thing for
this pattern tag so attr ID the ID is
right here it's John Snow great now
height 100% great the next one with 100%
the next one pattern content units not
typing that out on the next one and then
it is a object bounding box
okay so now what we need to do is we've
made deaths we've made a pattern we can
just refresh to make sure that this is
working - so to refresh this page we go
divide each art look in the SVG and we
see there are some depths and we see yes
there is a pattern on that pattern is
currently empty we need to add inside of
that pattern this little image section
so we can just keep chaining this
together dot append image attr height is
1 and width is 1 height of 1 width of 1
preserve aspect ratio none XML namespace
X link
I think we might not need this one
because d3 does namespacing by itself
but just to be safe
we'll keep it and we'll say X link
Pietra slinky trap
Snow dot jpg Snow dot jpg alright so
what we just did then was we created a
definition section we added a single
pattern to it gave it an ID so we can
refer to it later
except the height width pattern content
units what does that do google it and
then we put an image inside of that so
save it refresh the page look an ID or
looking div SVG gee Dex pattern great so
it looks like this works we have a depth
section with a pattern and an image
inside of it now let's apply this
pattern to all of our circles so when we
were doing this let's still open guess
in order to make John Snow appear in
this circle or in this rectangle we had
to do URL hash tag the ID so John Snow
is the ID of the pattern so we just said
URL hash tag John Snow that we can do
the same thing here
so if we scroll down scroll down scroll
down to where we set the fill to be
light blue it is now going to be URL
hash and we look up then oh it's still
the same we call the John Snow so John
Snow
you just have to make sure that this
matches this so save and refresh and now
1 million John snows for our pleasure
now if we click these last time we made
it so that you can see what this is this
is Madonna Holland oats and eagles um
none of those musicians look like Jon
Snow so probably we should make those
images not reflect John snow but rather
reflect the artists themselves so there
is a folder that I have called images
and it has images of everyone in it
they've been cropped to be square and if
we look at our Excel spreadsheet there
is a column called image path so we know
where the image for Steely Dan is we
know where the image for Fetty WAP is so
we're going to be able to use these in
our code so all right back to our code
no we made one pattern for John Snow and
then we called it by saying URL John
Snow the problem is that to make a
pattern that has a Jon Snow Imogen in it
we needed to make one pattern with one
image in it if we want to make how many
of these do we have here if we want to
make 15 different patterns are we going
to manually do this 15 different times
no that would be crazy it would be it
would be nuts so this is where the magic
of d3 comes in so how many circles do we
have here oh we have 15 circles how did
we get these 15 separate circles to show
up well to make 15
different circles we just did that
select all data enter append and that
added 15 different circles into our SVG
we're going to end up doing the exact
same thing with patterns we need to add
15 extra patterns inside of our depths
and so we are just going to do deaths
and then the select all enter append so
that instead of making 15 different
circles we make 15 different patterns
one pattern for every single one of our
artists because we're going to give them
each a unique image so we don't need are
there so deafs dot select all now we
want to create pattern so you might
think to do pattern here but that's
actually going to interfere with the Jon
Snow pattern that we've already made so
let's give it a class we'll call it
artist pattern bind it to our data
points enter append pattern let's just
look at our page and see if this worked
so we're saying go into the definitions
find let's just set the class to we're
saying go into the deaths find all the
artist patterns whatever those are bind
them to our data points put a new
pattern in for every single one of our
data points and give it a class so
refresh open open open open so we now
have 15 blank patterns in here and what
we need to do is make our pattern in the
exact same way that we made this pattern
here so it means the same attributes
except the ID will be different and it
needs to have an image inside with a
different href so we can actually just
cut and paste copy everything that we
did to this pattern and then move it on
down here so every single pattern is
going to get
the exact same height with pattern
content units on height with preserve
expect ratio but also I D so let's let's
change these things real quick so
instead of the ID being John snow if we
look at our excel sheet there is an ID
there is a name
those are both unique let's displease
name for now so return d dot name so now
the name instead of being always John -
snow it will be say Madonna or the
Eagles and if you think oh no you're
doing something wrong we'll figure out
why I'm doing something wrong later and
additionally instead of always using
snow jpg we want to look at our data
point and then find the correct image
URL in image path so let's return d dot
image path let's refresh this look
inside and sure we sure enough have a
pattern with the idea of Madonna and
then it is going for Madonna dot PNG
wonderful so instead of always using
John Snow so these are circles actually
let's move this before our circles just
to think about the fact that we are
creating our definitions or actually
drawing our circles
so we have our circles here we're
binding our data blah blah blah I'm you
setting our fill and the fill is always
going to eat URL John Snow so let's
change this
let's just save it like this and refresh
to make sure it still works as John Snow
yes now we need to change this so
instead of John Snow it will do
something like Madonna so what we need
to do is just change it so that we're
using D dot name here because in the
same way that we set the ID according to
the name we're now going to refer to it
by the name when we're using URL
fill we refresh and some of them work
and some of them don't work so if we
look at this we see that yes it's saying
URL Madonna and it's successfully
grabbing Madonna on URL Kesha and it's
SS successfully grabbing Kesha but let's
say over here but Nicki Minaj is not
working and why is that well it's this
friend right here the space anytime you
are giving something an ID or a class
you don't want to put spaces in it if
you put spaces in a class it means
you're assigning multiple classes if you
put spaces in an ID it's just going to
break so we're going to fix this and the
first way we're going to fix it is going
to be wrong and then we're going to fix
it in the right way a few seconds later
so let us go first up here to where we
set the ID now the problem is this space
so let's just replace the space with a
dash that seems pretty reasonable we
could also do to lowercase just - things
look better when they're lowercase I
think and we want to make sure that we
use the same code here and down here so
instead of D name we're now going to
look for let's say a URL a Nicki Minaj
alpha coming up here and it's now going
to be the - equals
so anything we do to ID here we have to
also do to fill here because this URL
has to match that ID this is the pattern
this is the circle film refresh great
they're mostly working except one over
here isn't working
Hall and Oates is not working so let's
look at Nicki Minaj real quick and we
see that she does successfully have a
dash there but if we look over here at
Holland Oats there's Hall - and space
oats now a weird thing with replace in
JavaScript is it only replaces the very
first instance so only the first space
is going to be replaced by that - by
that - except that you think there's
like a do it globally replace all but
there's not we need to actually use a
regular expression and we need to make
it a global regular expression and
you're probably sobbing you're sweating
a little bit right now but really all
you need to do is this this means space
replace it globally you could make this
a little bit fancier you could say
replace anything that is not a through z
one through zero zero through nine I
guess anything that's not a normal ASCII
character for example Kesha is on here
and if used a dollar sign it would break
some things but to clean that up for us
so we are just going to do this guy here
and this guy here because again these do
you have to match so replace every
single space with the - and you are good
to go now so what we did was we figured
out how to make a separate depth for
every single one of our artists so that
they each have their specific background
image in their own specific pattern and
so one pattern per person one image per
person and then we applied those
patterns
to the circles so they're going to be to
select all enter pens one for a pattern
and one for the circles all right in the
next video we're going to figure out how
to manipulate our forces to make them
split according to whether they are in
the pre 2004 post 2000 group