user1253952 user1253952 - 9 months ago 17
Javascript Question

How to access svg defined in another function?

I am attempting to highlight a point in a d3 line chart. This needs to be done in a function call after the line chart is created and drawn in another function.

The drawing of the line chart (and creation of the svg object) occurs in an update_graph function. I'm trying to figure out the best way to access the svg object to use in the highlight_point function call.

I created a jsfiddle here: https://jsfiddle.net/pxc0gpc6/4/ When the code inside update_graph is not wrapped in a function call, the highlight_point code works as expected. But when I do have the code inside the update_graph function, I no longer know how to access the svg object.

I've tried giving the svg an id so that I can access it again, however the highlighted point does not end up being drawn on the line chart area. I've also tried to make the svg globally accessible by creating a this.svg variable at the end of the update_graph function, but that also does not work:

this.svg = svg;

Answer Source

Problem 1:

How to get the SVG instance in update_graph function.

Make an ID and assign it to the group like this:

  var svg = d3.select("body").append("svg")

    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("id", "myGroup")//assign id to  group

Inside your function access group like this:

function highlight_point() {
  var svg = d3.select("#myGroup")

Problem 2:

How to access the line data in order to make circles for the point in update_graph function.

  var data = d3.selectAll(".line").data();//get the line data
  data.forEach(function(d) {//for each line
    d.values.forEach(function(v) { //get each line's data points
      //iterate over the points
      var focus_red = svg.append("g")
        .attr("class", "focus")
        .style("stroke", "#ff0000")
        .style("display", null);

      focus_red.append("circle")
        .style("fill", "#ff0000")
        .style("stroke", "#ff0000")
        .attr("r", 4.5);
      //the x of the center defined by date
      //the y of the center defined by temperature
      focus_red.attr("transform", "translate(" + x(v.date) + "," + y(v.temperature) + ")");

    });

working code here

EDIT

Highlight second point.

Use filter like this:

data.forEach(function(d) {
    d.values.filter(function(k, i) {
      return i == 2; //select the second data form each line.
    }).forEach(function(v) {
      //make circle

working code here