Draw a dynamic U curve line (3 points) between two dots

Hi,

I found some example to draw lines between dot, but before reinventing the wheel, i want to ask.
Is there an helping function to compute curved line between two x,y points ?

For example on this graph, i have colored dots on tops of each rectangle of the stackbar : https://observablehq.com/@reyman/covid

The color correspond to the number of days between this date and another date (2020-03-19 sent to 2020-03-21) , so i’m interested to dynamically draw a not-so-simple U curve between two dots / date when user mouse-hover any dots.

Screenshot_2020-04-21 Covid

I found this tutorial very helpful: https://www.d3-graph-gallery.com/graph/arc_basic.html
Here is my implementation (with animations and interactions) in Observable: https://observablehq.com/@i247sp20/lab-11-d3-tutorial-2-creating-an-arc-diagram-with-animated-tr

1 Like

Thanks for the help/link @mahviz , i’m going to adapt your implementation and i go back here later to close issue !

Ok, i have only arc with 1 target, so it’s more simple.

I draw without too much problem the arcs corresponding to my data.


Now i have some problem to highlight on mouse enter on the nodes, perhaps @mahviz you have an idea ?

The code to build arc :

  svg.append("g")
     .selectAll("arcs")
     .data(dataforCircle)
    . join('path')
     .style("fill", "none")
     .attr("stroke", "black")
     .attr("d", d => buildArc(d));

the code for circles / nodes :

 svg.append("g")
  .selectAll('circle')
  .data(dataforCircle)
  .join('circle')
  .attr('cx', d=> x(d3.isoParse(d.dateRep)) )
  .attr('cy', d => y(d.ymax) - 8)
  .attr('r', 4)
  .style('fill', d => dotcolor(d.XDelta))
  .on("mouseenter", function(d) {
    d3.select(this)
      .raise() // bring to front
      .attr('r', 6);
      
    //Select the good arc ? return 0, don't understand why ...
    console.log(d3.selectAll("arcs").size());
    
    d3.selectAll("arcs")
    .style('stroke', function (arcd) { 
          console.log("arcd.dateRep = " + arcd.dateRep);
          return  arcd.dateRep === d.dateRep  ? 'firebrick' : 'black';})
     })

My selection to “arc” (the console.log) is equal to zero, don’t understand why, because that exist.

I just looked at your notebook and it looks like it’s working as far as I can tell. Can you clarify what you would like it to do differently?

I think that you mean to select .arcs everywhere in your code that you currently select arcs, to select elements with that class. Selecting arcs will attempt to select elements whose tag name is arcs.

Yes if finally found what happen, i need to define a class named .arc if i want to selectAll('arcs') later in my code (for highlight on nodes mouve hover by example)

  svg.append("g")
     .selectAll("arcs")
     .data(dataforCircle)
    . join('path')
     .style("fill", "none")
     .attr("stroke", "none")
     .attr("stroke-width", 3)
     .attr("class","arcs")
     .attr("d", d => buildArc(d));

What i don’t understand now @mahviz is why you don’t define this class .arcs in your tutorial ( https://observablehq.com/@i247sp20/lab-11-d3-tutorial-2-creating-an-arc-diagram-with-animated-tr ), and why this work for you and not for me -without defining this arcs classe- ?

In my code I defined a variable called arcs that held the selection to all of the arcs, and reused this throughout whenever I needed to access the arcs. I agree that it is a good idea to assign them all a class as you did here.

1 Like