Description of requirement:
I am using d3 to parse a .csv file for data and then populate various items on a page dynamically. One section is shown below:
My Code progression:
I started out by housing each dynamically retrieved number within its own div tag and setting the background image for each dynamically. Here is the d3 JavaScript code:
careerstage_td.append("div")
.text(function(d){ return d.count })
.attr("class", "career-count")
.style("color", function(d){return d.color;})
.style("background-image", function(d){return "url('images/" + d.icon + "')";})
.style("background-repeat", "no-repeat")
.style("background-position", "center center");
(Notice that I am using a function to dynamically populate the number as well as to figure out which image to overlay)
This gave me the following expected result, where the images were behind the text:
The next step was to figure out how to overlay that background image on top of the text. For this I started digging around on google and found this question on SO: How to overlay images. Over here I identified two different solutions:
Solution 1: (from the top answer on that page) add a span in the div with the number, then position the span absolutely in the center using css, like so
div.career-count span.stickperson
{
position:absolute;
left:45%;
top: 34%;
}
Solution 2: (from another answer on that page) Add the following css that extends the class of the div with the dynamic text, like so
.career-count:after
{
content: url(/images/person_assoc.gif);
position: absolute;
left:45%;
top: 34%;
}
Both solutions work, but Solution 1 only works in Chrome, and Solution 2 doesn't allow me to set the images dynamically since it is all done in css and the 'after' contruct cannot be used in-line.
I would appreciate help in figuring out a solution that allows me to set the image dynamically and also works in Chrome, Firefox 25 and IE 11.
EDIT: Thanks for the up-votes, folks. I added images now :)
Actually I think the best solution is not to add a background-image to the div
elements in which you put your text, but rather to create a child div
for each div
you created, and work with the image inside the child.
careerstage_td.selectAll('div')
.data(dataset)
.enter().append('div')
.attr("class", "career-count")
.text(function(d){return d;})
.style("color", function(d){return d.color;})
.append('div')
.attr("class", "childClass")
.style("background-image", function(d){return "url('images/" + d.icon + "')";})
.style("background-repeat", "no-repeat")
.style("background-position", "center center");
In the given code, I generate my divs thanks to the data, and for each div
I append a new div
(classnames "childClass"). Now I can play on this childClass.
See the jsfiddle for an example. (note that I used a simplified dataset so I pushed always the image as a background, and the same text color).
The trick to ensure that the icon displays in the middle of the parent node is to define the parent as position:relative
and the children as absolute
with a width and height of 100%. Centering the background both on x and y does the job.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With