Gio Bact
Gio Bact

Reputation: 541

Create a line passing through some points with d3.js

I have a situation very similar to the one in this JSFiddle with some points representing a team (in particular its final rank in a football season).

I would like to substitute the points with a line passing exactly in these points so that the final result shows the temporal evolution of each team in terms of final ranking position.

I know how to create a line by setting the X1,X2,Y1,Y2 coordinates but I don't understand how to set this coordinates to the exact value (e.g. if the line is between season 2006-2007 and season 2007-2008 I will have to set X1 and Y1 with value from the first season as d[0] and d[1] but for X2 and Y2 I need values from the next element in the array.

I'm very new with D3.js so any advice and solution is very welcome. Thanks

Upvotes: 1

Views: 637

Answers (2)

Gerardo Furtado
Gerardo Furtado

Reputation: 102219

Based on that fiddle, this is what I'd do:

First, I'd set a class to each team's circles (team1, team2 and so on...). So, I could later retrieve the circles' values for each team.

For retrieving the circles values, I'd use a for loop:

for(var j = 1; j < 4; j++){//this loops from "Team1" to "Team3"
var team = d3.selectAll("circle.Team" + j)[0];//selects the team by class
    for(var i = 0; i < team.length; i++){//this loops through the circles
        if(team[i+1]){//if the next circle exists
            svg.append("line")
                .attr("x1", d3.select(team[i]).attr("cx"))//this circle
                .attr("y1", d3.select(team[i]).attr("cy"))//this circle
                .attr("x2", d3.select(team[i+1]).attr("cx"))//the next circle
                .attr("y2", d3.select(team[i+1]).attr("cy"))//the next circle
                .attr("stroke", function(){
                    return _TEAM_COLORS_["Team" + j]
                });//sets the colours based on your object
        }
    }
};

Here is that fiddle, updated: https://jsfiddle.net/gerardofurtado/6cc0ehz2/18/

Upvotes: 0

Nikolai
Nikolai

Reputation: 318

Assuming you have already declared some data for your lines drawing the actual lines based on that data is as simple as this:

  1. create the X and Y scales:

    var xScale = d3.scale.linear().domain([dataRange.x1, dataRange.x2]).range([plotRange.x1, plotRange.x2]);
    var yScale = d3.scale.linear().domain([dataRange.y1, dataRange.y2]).range([plotRange.y1, plotRange.y2]);
    
  2. declare the line function:

    var valueLine = d3.svg.line()
    .x(function (dataItem, arrayIndex) {
        return xScale(dataItem);
    })
    .y(function (dataItem, arrayIndex) {
        return yScale(dataItem)
    });
    
  3. and finally create the path:

    g.append("path")
        .style("stroke", someColour)
        .attr("d", valueLine(myData))
        .attr("class", "someClass");
    

Refer to more documentation here: https://www.dashingd3js.com/

Upvotes: 1

Related Questions