2
votes

I'm using the nvd3.js line with focus chart ( view finder ) model for a project. There are customizations that i need to add to this example -- such as different types of annotation overlays on top of the graph.

spec

There's a couple ways i can see tackling this:

1. I could extend the nvd3 chart models to create one that does what i need ( that seems like a lot of work at the moment )

2. I can find the right interfaces in the existing nvd3 chart models and write my own d3 stuff to create annotations ( this seemed easier, and so i went down this route )

I've figured out most of what i need except how to get the chart's svg screen position for a value from my xScale ( d3.linear.scale() ). Once i have the correct screen position within the nvd3 chart i can make my annotation overlay in the correct spots.

Question: Does anyone know if there's an interface in nvd3 charts to calculate the chart's screen position from an xScale value? If there's no easy interface, how could i solve this problem?

Thanks

UPDATE: It looks like i had all the correct information to begin with thanks to Lars' comment. But it wasn't making sense since there seems to be a bug when setting xAxis with dates like this:

 chart.xAxis
  .tickFormat(function(d) { return d3.time.format('%Y-%m-%d')(new Date(d)); });

When you try to get the xAxis.scale(), you get a date back instead of the scale function. So it wasn't obvious.

2
You should be able to access the scale through xAxis.scale().Lars Kotthoff
@LarsKotthoff: yep, you are right. Though a subtle bug in nvd3.js seems to have kept that conclusion from me for some time. See my update abovesudobangbang
Yeah, NVD3 does some attribute wrapping of its own that can be confusing at times. I'll add that as an answer anyway for reference.Lars Kotthoff

2 Answers

0
votes

You should be able to access the scale through xAxis.scale(). You should run this code after the graph has been drawn to make sure that the scale is set up properly.

0
votes

To add some context to the solution by Lars:

My xAxis is setup like:

chart.xAxis
  .tickValues([
    Date.parse('08/24/14'),
    Date.parse('08/30/14'),
    // parsed dates..
  ])
  .tickFormat(function(d) {
    return d3.time.format('%x')(new Date(d))
  });

Then, after the chart has been rendered (in the callback), I can then get the x position for a certain date value by doing:

chart.xScale()(chart.x()({ x: Date.parse('11/01/14') }))

Hope this helps someone. Cheers.