d3 (or JavaScript): use local variable in another

2019-08-02 13:17发布

I'm stuck in d3.js.

I'm drawing multiple SVG canvas with lines, where the length of the lines is determined by data. Each row of the data is mapped to its own SVG.

What's not working properly is to draw a line at the end of another line. My code worked before I entered the data. But now as soon as I add a data value (e.g. d.uni), the second line is always drawn at the same position, namely at the last position determined by JS.

Here is the code:

var w = 300;
var h = 250;
var stemL = 100;
var catX1 = 0;
var catY1 = 0;
var catX2 = 0;
var catY2 = 0;
var subCatX1 = 0;
var subCatY1 = 0;
var length1 = 80;
var length2 = 40;
var angle1 = -1.2;
var angleF = 0.7;

d3.csv("data_test.csv", function(data) {

//Create SVG element
var svg = d3.select("body")
.selectAll("svg")
.data(data)
.enter()
.append("svg")
.attr("width", w)
.attr("height", h)
.append("g")  

// Cat 1          
svg.append("line")
   .attr("x1", function() {catX1 = w/2; return catX1})
   .attr("y1", function() {catY1 = h - stemL; return catY1})
   .attr("x2", function(d) {catX2 = catX1 + length1 * d.uni * Math.sin(angle1); return catX2})
   .attr("y2", function(d) {catY2 = catY1 - length1 * d.uni * Math.cos(angle1); return catY2})
   .style("stroke", "steelblue")
   .style("stroke-width", 5);

// Cat 1 - uni Acc    
svg.append("line")
   .attr("x1", catX2)
   .attr("y1", catY2)
   .attr("x2", function(d) {subCatX2 = catX2 + length2 * d.uniAcc * Math.sin(angle1 - angleF); return subCatX2;})
   .attr("y2", function(d) {subCatY2 = catY2 - length2 * d.uniAcc * Math.cos(angle1 - angleF); return subCatY2;})
   .style("stroke", "steelblue")
   .style("stroke-width", 3);           

});

So, is this a problem of local vs. global variables or does it have to do with the fact that I'm drawing multiple SVG?

This is how it should look like: Two lines per SVG (but with varying lengths of the first line).

How can I achieve this?

Your help is very much appreciated!

Thanks Ewa

Here is the "data_test.csv":

country,uni,uniAcc
Sweden,1.6,1.1
Germany,1,1.5
Poland,0.7,1

1条回答
Emotional °昔
2楼-- · 2019-08-02 14:14

It can be done this way:

var w = 300;
var h = 250;
var stemL = 100;
var catX1 = 0;
var catY1 = 0;
var catX2 = 0;
var catY2 = 0;
var subCatX1 = 0;
var subCatY1 = 0;
var length1 = 80;
var length2 = 40;
var angle1 = -1.2;
var angleF = 0.7;

catX1 = w/2;
catY1 = h - stemL;



d3.csv("data_test.csv", function(data) {

var lineFunction = d3.svg.line()
            .x(function(d) { return d.x; })
            .y(function(d) { return d.y; });


//Create SVG element
var svg = d3.select("body")
          .selectAll("svg")
          .data(data)
          .enter()
          .append("svg")
          .attr("width", w)
          .attr("height", h)
          .append("g");



svg.append("path").attr("d", function(d){



var lineData = [ { "x": catX1,   
                   "y": catY1 }, 

                { "x": function() {catX2 = catX1 + length1 * d.uni * Math.sin(angle1); return catX2}(),  
                  "y": function() {catY2 = catY1 - length1 * d.uni * Math.cos(angle1); return catY2}() }, 

                { "x": function() {catX2 = catX1 + length1 * d.uni * Math.sin(angle1); return catX2}(),  
                  "y": function() {catY2 = catY1 - length1 * d.uni * Math.cos(angle1); return catY2}() },

                { "x": function() {subCatX2 = catX2 + length2 * d.uniAcc * Math.sin(angle1 - angleF); return subCatX2;}(),  
                  "y": function() {subCatY2 = catY2 - length2 * d.uniAcc * Math.cos(angle1 - angleF); return subCatY2;}() }
                ];  

                return lineFunction(lineData);
})
 .style("stroke", "steelblue")
 .style("stroke-width", 3)
 .attr("fill", "none");   



});

Here is working version - http://lunobus.com/threelines2/

查看更多
登录 后发表回答