D3.js雷达图线图

D3.js Radar chart line drawing

我正在尝试创建类似于 link 的雷达图( http://www.larsko.org/v/euc/).

我能够创建坐标轴 (my work so far),但我在其中画线时遇到问题。

例如,如果我有如下所示的值列表,我如何在雷达图中画一条线?

var tempData = [56784, 5.898, 3417, 0, 0, 0]

编辑: 我已经包含了代码。我在查找 XY 坐标时遇到问题,我认为 XY 值必须来自 "scales".

var width = 1000,
  height = 960,
  r = (960 / 2) - 160;

var svg = d3.select("#radar")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + ", " + height / 2 + ")");

d3.csv("data/results.csv", function(data) {
      var headerNames = d3.keys(data[0]);
      headerNames.splice(0, 1); //Remove 'scenario'

      var minList = $.map(headerNames, function(h) {
          return d3.min($.map(data, function(d) {
            return d[h];
          }));
        }),

        maxList = $.map(headerNames, function(h) {
          return d3.max($.map(data, function(d) {
            return d[h];
          }));
        }),

        scales = $.map(headerNames, function(h, i) {
          return d3.scale.linear()
            .domain([minList[i], maxList[i]])
            .range([50, r]);
        }),

        axes = $.map(headerNames, function(h, i) {
          return d3.svg.axis()
            .scale(scales[i])
            .tickSize(4);
        });

      function angle(i) {
        return i * (2 * Math.PI / headerNames.length) + Math.PI / headerNames.length;
      }

      var line = d3.svg.line()
        .interpolate("cardinal-closed")
        /* computing X and Y: I am having a problem here 
        .x(function(d){ return scales(d); })
        .y(function(d){ return scales(d); }); */


      $.each(axes, function(i, a) {
          svg.append("g")
            .attr("transform", "rotate(" + Math.round(angle(i) * (180 / Math.PI)) + ")")
            .call(a)
            .selectAll("text")
            .attr("text-anchor", "middle")
            .attr("transform", function(d) {
              return "rotate(" + -angle(i) * (180 / Math.PI) + ")";
            })

          //Drawing line
          svg.selectAll(".layer")
            .data(data)
            .enter()
            .append("path")
            .attr("class", "layer")
            .attr("d", function(d) {
              return line(d);
            })

        }) // End CSV

示例results.csv 情景,n_dead_oaks,percent_dead_oaks,infected_area_ha,money_spent,area_treated_ha,price_per_oak 基线,56784,5.898,3417,0,0,0 scen2,52725,5.477,3294,382036,35,94.12071939 RS_1,58037,6.028,3407,796705,59,-635.8379888 RS_2,33571,3.487,2555,1841047,104,79.31103261 RS_3,46111,4.79,2762,1176461,61,110.227771

正如 Squeegy 所建议的那样,您应该分享一些代码来显示您当前的进度以及您如何创建坐标区。

无论如何,这就是我的处理方式:

  1. 对于要表示为一条线的给定值列表,找到该线每个点的 [x,y] 坐标,即将数据点放在每个轴上。如果你已经有一个比例系统来绘制你的轴,这应该不会太难。

  2. 使用d3.svg.line画一条通过所有这些点的线。

代码最终看起来像这样:

var tempData = [56784, 5.898, 3417, 0, 0, 0];

/** compute tempPoints from tempData **/

var tempPoints = [[123, 30], [12, 123], [123, 123], [0,0], [0,0], [0,0]];
var line = d3.svg.line();
d3.select('svg').append('path').attr('d', line(tempPoints) + 'Z'); // the trailing Z closes the path

我想我现在有一个解决方案,非常感谢您的所有回复!这是我当前发布的解决方案。

function getRowValues(data) {
  return $.map(data, function(d, i) {
    if (i != "scenario") {
      return d;
    }
  });
}

function getCoor(data) {
  console.log(data);
  var row = getRowValues(data),
    x,
    y,
    coor = [];
  for (var i = 0; i < row.length; i++) {
    x = Math.round(Math.cos(angle(i)) * scales[i](row[i]));
    y = Math.round(Math.sin(angle(i)) * scales[i](row[i]));
    coor.push([x, y]);
  }
  return coor;
}

var line = d3.svg.line()
  .interpolate("cardinal-closed")
  .tension(0.85);

svg.selectAll(".layer")
  .data(data)
  .enter()
  .append("path")
  .attr("class", "layer")
  .attr("d", function(d) { return line(getCoor(d)) + "Z"; })
  .style("stroke", function(d, i){ return colors[i]; })
  .style("fill", "none");