3

I feel like I'm going crazy here. I've been staring and staring and must be missing something obvious.

See this example on jsbin

I would like the curved path to be blue and the straight path underlying the word to be red.

I noticed that I'm always setting stroke-width, stroke, and fill so I made a helper method

lineColor = (color, node) ->
  node
    .attr 'stroke', color
    .attr 'stroke-width', 2
    .attr 'fill', 'none'

And draw the paths like this

#curvy
lineColor 'blue', svg
  .append 'path'
  .attr 'd', line indentations

and like this

#underline
lineColor 'red', svg
  .append 'path'
  .attr 'd', usageLine usageCol

you would think the first line would be blue and the second red, but they both come out red (or whatever color is used last)!

I don't get it, there's no delayed execution going on here, and if I put the stroke command on each node outside the function it works.

What am I missing?

Edit: Here's the same thing without the helper function - everything's working great.

George Mauer
  • 117,483
  • 131
  • 382
  • 612
  • @muistooshort thats what I thought too, but the color variable will bind at the time it's invoked. that's just javascript. I'm not certain but I think d3 writes elements as `append` is called and relies on browser optimizations to not thrash layouts – George Mauer Nov 07 '14 at 04:32

2 Answers2

3

if I put the stroke command on each node outside the function it works.

I'm not seeing that happening: http://jsbin.com/woxehetobe/2/edit

It makes sense to me that changing an attribute on your reference to svg changes them all, as it must retain a reference of all the ones you've attached and thus changes all their attributes to the blue color.

If you have a second reference, you can get both to be different colors. I am sure there's a better way to clone that's more "d3," but I don't have a lot of experience with that.

Working example: http://jsbin.com/woxehetobe/3/edit

CWSpear
  • 3,230
  • 1
  • 28
  • 34
  • You rewrote it to have multiple svgs and were setting color on thg svg though. I'm setting colors on the paths. [Here is the same thing but without the helper function (and it's working!)](http://jsbin.com/raseg/1/) – George Mauer Nov 07 '14 at 04:30
  • This example is not the same as your original. In the first, you change the color of the node and *then* append. In the 2nd example, you append and *then* change the color. Indeed, change the order in the 2nd one to match what's happening in the 1st one and you get the double red again. Which again validates my answer. – CWSpear Nov 07 '14 at 04:34
  • Oh holy crap, you're right. Foiled by my own clever coffeescript indentation. I meant to invoke `lineColor` on the result of the chain – George Mauer Nov 07 '14 at 04:36
  • Do not blame coffeescript, I take full responsibility for my stupid stupid head – George Mauer Nov 07 '14 at 04:39
0

It won't let me add a comment so here's an attempted answer: I think the issue is that you pass in the whole SVG element in your lineColor function which sets the stroke color globally, i.e. for all lines on the SVG. Append a "g" element to the SVG for each of the lines and pass that in to the lineColor function instead. That should solve your issue!

Sorry for the lack of code example, I am not familiar with CoffeeScript...

srbdev
  • 46
  • 6