如何访问数组中的数据

时间:2017-02-26 20:24:55

标签: javascript d3.js multidimensional-array

如何在d3.js中访问多维数组中的数据?

我使用一维数组创建了这个迷你图。 但是当我想用多维数组创建更多的迷你图时呢。

我有这个效果

    var canvasWidth  = 200,
    canvasHeight = 150;

var pathData = [
  { "x": 0,   "y": 50}, 
  { "x": 20,  "y": 20},
  { "x": 60,  "y": 40}, 
  { "x": 80,  "y": 30}, 
  { "x": 120, "y": 90},
  { "x": 150, "y": 70}, 
  { "x": 180, "y": 30},
  { "x": 190, "y": 90},
];

var widthScale = d3.scaleLinear()
  .domain([0, 190])
  .range([0, canvasWidth - 30]);

var heightScale = d3.scaleLinear()
  .domain([0, 90])
  .range([0, canvasHeight - 10]);

// Canvas
var canvas = d3.select("body")
  .append("svg")
  .attr("width", canvasWidth)
  .attr("height", canvasHeight)
    .append("g")
    .attr("transform","translate(20)");

// _+_+_+_+_+_+_+_+ Basic of Data --> SVG Path _+_+_+_+_+_+_+_+ //

// Create accessor function
var pathFunction = d3.line()
  .x(function(d) { return widthScale(d.x); })
  .y(function(d) { return heightScale(d.y); })
  .curve(d3.curveCatmullRom);

// Create <path> and append accessor function
var path = canvas.append("path")
  .attr("d", pathFunction(pathData))
  .attr("stroke", "red")
  .attr("stroke-width", 2)
  .attr("fill", "none");

// Add data points 
var circles = canvas.selectAll("circle")
  .data(pathData)
  .enter()
  .append("circle")
    .attr("cx", function(d) { return widthScale(d.x) })
    .attr("cy", function(d) { return heightScale(d.y) })
    .attr("fill", "black")
    .attr("r", 4);

这是因为我不能在每个迷你图中添加圆圈而被卡住了 - “

var canvasWidth  = 200,
    canvasHeight = 150;

    var pathData = [
        [
            { "x": 0,   "y": 50}, { "x": 20,  "y": 20}, 
            { "x": 60,  "y": 40}, { "x": 80,  "y": 30},
            { "x": 120, "y": 90}, { "x": 150, "y": 70}, 
            { "x": 180, "y": 30}, { "x": 190, "y": 90},
        ],
        [    
            { "x": 0,   "y": 90}, { "x": 20,  "y": 20}, 
            { "x": 30,  "y": 80}, { "x": 80,  "y": 30},
            { "x": 120, "y": 90}, { "x": 150, "y": 70}, 
            { "x": 180, "y": 30}, { "x": 190, "y": 90},
        ],
        [    
            { "x": 0,   "y": 40}, { "x": 20,  "y": 20}, 
            { "x": 30,  "y": 80}, { "x": 80,  "y": 30},
            { "x": 120, "y": 90}, { "x": 150, "y": 70}, 
            { "x": 180, "y": 30}, { "x": 190, "y": 90},
        ]
    ];

    var widthScale = d3.scaleLinear()
      .domain([0, 190])
      .range([0, canvasWidth - 30]);

    var heightScale = d3.scaleLinear()
      .domain([0, 90])
      .range([0, canvasHeight - 10]);

    // Canvas
    var container = d3.select(".main-container")


    // Create accessor function
    var pathFunction = d3.line()
      .x(function(d) { return widthScale(d.x); })
      .y(function(d) { return heightScale(d.y); })
      .curve(d3.curveCatmullRom);


    var canvas = container.selectAll("svg")
        .data(pathData)
        .enter()
            .append("svg")
            .attr("width", canvasWidth)
            .attr("height", canvasHeight)
            .append("g")
            .attr("transform","translate(20)");

    var sparklines = canvas.append("path")
        .attr("d", pathFunction)
        .attr("stroke", "#19ff9f")
        .attr("stroke-width", 2)
        .attr("fill","none");


    var circles = canvas.selectAll("circle")
        .data(pathData)
        .enter()        
            .append("circle")
            .attr("cx", function(d,i) { return widthScale(d.x); })
            .attr("cy", function(d,i) { return widthScale(d.y); })
            .attr("fill", "black")
            .attr("r", 3);

`

CX和CY位置是NaN。而且只有3个圆圈,而不是8个数组长度(http://prntscr.com/edp7hq

2 个答案:

答案 0 :(得分:1)

您只需要进行一次修改:

由于您有3个内部数组,因此每个SVG都有一个绑定为数据的数组。所以,当谈到附加圈子时,而不是......

var circles = canvas.selectAll("circle")
    .data(pathData)
    .enter()        
    .append("circle")

...,它指向整个数据数组,它应该是......

var circles = canvas.selectAll("circle")
    .data(d => d)
    .enter()        
    .append("circle")

...使内部数组(即绑定到每个SVG的数据)成为每组圆的数据数组。

以下是仅使用该修改的工作代码(同样,您在heightScale上输入错误信息):

var canvasWidth  = 200,
    canvasHeight = 150;

    var pathData = [
        [
            { "x": 0,   "y": 50}, { "x": 20,  "y": 20}, 
            { "x": 60,  "y": 40}, { "x": 80,  "y": 30},
            { "x": 120, "y": 90}, { "x": 150, "y": 70}, 
            { "x": 180, "y": 30}, { "x": 190, "y": 90},
        ],
        [    
            { "x": 0,   "y": 90}, { "x": 20,  "y": 20}, 
            { "x": 30,  "y": 80}, { "x": 80,  "y": 30},
            { "x": 120, "y": 90}, { "x": 150, "y": 70}, 
            { "x": 180, "y": 30}, { "x": 190, "y": 90},
        ],
        [    
            { "x": 0,   "y": 40}, { "x": 20,  "y": 20}, 
            { "x": 30,  "y": 80}, { "x": 80,  "y": 30},
            { "x": 120, "y": 90}, { "x": 150, "y": 70}, 
            { "x": 180, "y": 30}, { "x": 190, "y": 90},
        ]
    ];

    var widthScale = d3.scaleLinear()
      .domain([0, 190])
      .range([0, canvasWidth - 30]);

    var heightScale = d3.scaleLinear()
      .domain([0, 90])
      .range([0, canvasHeight - 10]);

    // Canvas
    var container = d3.select("body")


    // Create accessor function
    var pathFunction = d3.line()
      .x(function(d) { return widthScale(d.x); })
      .y(function(d) { return heightScale(d.y); })
      .curve(d3.curveCatmullRom);


    var canvas = container.selectAll("svg")
        .data(pathData)
        .enter()
            .append("svg")
            .attr("width", canvasWidth)
            .attr("height", canvasHeight)
            .append("g")
            .attr("transform","translate(20)");

    var sparklines = canvas.append("path")
        .attr("d", pathFunction)
        .attr("stroke", "#19ff9f")
        .attr("stroke-width", 2)
        .attr("fill","none");


    var circles = canvas.selectAll("circle")
        .data(d=>d)
        .enter()        
            .append("circle")
            .attr("cx", function(d,i) { return widthScale(d.x); })
            .attr("cy", function(d,i) { return heightScale(d.y); })
            .attr("fill", "black")
            .attr("r", 3);
<script src="https://d3js.org/d3.v4.min.js"></script>

答案 1 :(得分:0)

我发现检查此类问题的一种有用方法是将“d”值记录到控制台:

.attr("cx", function(d,i) { console.log(d); return widthScale(d.x) })

这可能会突出显示,因为您现在使用的是多维数组,绑定到您的圆元素的数据不再能让您立即访问数据点。以下内容可能会起作用:

.attr("cx", function(d,i) { return widthScale(d[i].x) })