Ryan Baxter-King Ryan Baxter-King - 2 months ago 13
jQuery Question

D3 updating barchart using jquery $(this) selector

I am creating a barchart using D3 and am using jquery to select the bars. I have run into an issue I don't understand where I think I have selected a bar (rectangle) using $(this) and a console.log() statement seems to confirm this. However, I have issues getting certain functions (e.g. transition, style) to work -- the error message says they are not a function.

I have constructed a small example of the issues I am encountering below. Instead of a barchart, there are just two rectangles. I successfully change the width but cannot use transition to smooth this change and also cannot change the fill color using $(this).style.

Thanks for any help! Here is my code.

P.S. This is my first StackOverflow question so please let me know if I should have asked this question differently and/or if there is some convention I did not follow. I did a fairly exhaustive search over a couple of days regarding this issue and have really hit a wall. Thanks again!

<body>
<svg width="1000" height="1000" id="this_svg">
<rect x="0" y="0" width="100" height="100" fill="blue" data-color="red"> </rect>
<rect x="0" y="100" width="100" height="100" fill="green" data-color="purple"></rect>
</svg>

<script>
$ (document ).ready(function() {
$svg = $("#this_svg")
rcts = $svg.find("rect")
// This Works Fine
rcts.each(function() {
$(this).attr("width", "500")
});
// This breaks (see error message):
// Uncaught TypeError: $(...).transition is not a function
rcts.each(function() {
$(this).transition().duration(500).attr("width", "500")
});
//... and if this hadn't already broken, this next part would
// break instead (see error message):
// Uncaught TypError: $(...).style is not a function
rcts.each(
$(this).style("fill", function() {
return $(this).attr("data-color")
}));
});
</script>
</body>

Answer

d3 !== jquery, you can't call methods of d3 selectors on jquery selectors. Note, there is some overlap in method names (for instance they both have a attr method), but they are still not the same.

The easy fix to your troubles is to use a d3 transition do:

 d3.select(this).transition().duration(500).attr("width", "500");

but it sounds like you need to read up to get a better understanding of the use cases for both libraries. In my mind, when coding up anything to d3, don't even load jquery. You don't need that jquery crutch, do it the d3 way instead and you'll be less confused in the long run.