javascript - 如何在d3中的平行坐标图中为线条着色?

标签 javascript css d3.js

我的问题是我无法在这个 d3 图表中为线条着色。我尝试了一些东西但没有用。

我也尝试添加这个:

 var color = d3.scale.ordinal()
  .domain([1,2,3])
  .range(['red','green','blue']); 

然后我添加了这个:

 foreground = svg.append('svg:g')
  .attr('class', 'foreground')
  .selectAll('path')
  .data(data)
  .enter().append('svg:path')
  .attr('d', path)
  .attr('stroke', function(d) { return color(d.label); }); 

这是jsfiddle中的代码,我有一个平行坐标图,将鼠标悬停在线条上,但现在我想为每辆车的线条涂上不同的颜色。 代码如下所示:

var margin = {top: 30, right: 40, bottom: 20, left: 200},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var dimensions = [
  {
    name: "name",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: "string"
  },
  {
    name: "economy (mpg)",
    scale: d3.scale.linear().range([0, height]),
    type: "number"
  },
  {
    name: "cylinders",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "displacement (cc)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "power (hp)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "weight (lb)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "0-60 mph (s)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "year",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
];

var x = d3.scale.ordinal()
    .domain(dimensions.map(function(d) { return d.name; }))
    .rangePoints([0, width]);

var line = d3.svg.line()
    .defined(function(d) { return !isNaN(d[1]); });

// CREATE A COLOR SCALE
var color = d3.scale.ordinal()
  .domain(['Buick','Chevrolet','Dodge'])
  .range(['red','blue','green'])    

var yAxis = d3.svg.axis()
    .orient("left");

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var dimension = svg.selectAll(".dimension")
    .data(dimensions)
  .enter().append("g")
    .attr("class", "dimension")
    .attr("transform", function(d) { return "translate(" + x(d.name) + ")"; });

function parallelchart(data) {
  dimensions.forEach(function(dimension) {
    dimension.scale.domain(dimension.type === "number"
        ? d3.extent(data, function(d) { return +d[dimension.name]; })
        : data.map(function(d) { return d[dimension.name]; }).sort());
  });

  svg.append("g")
      .attr("class", "background")
    .selectAll("path")
      .data(data)
    .enter().append("path")
      .attr("d", draw);

/*   svg.append("g")
      .attr("class", "foreground")
    .selectAll("path")
      .data(data)
    .enter().append("path")
      .attr("d", draw); */

  // USE THE COLOR SCALE TO SET THE STROKE BASED ON THE DATA
  foreground = svg.append("g")
      .attr("class", "foreground")
    .selectAll("path")
      .data(data)
    .enter().append("path")
      .attr("d", path)
      .attr("stroke", function(d) {
        var company = d.name.slice(0,d.name.indexOf(' '));
        return color(company);
      })


  dimension.append("g")
      .attr("class", "axis")
      .each(function(d) { d3.select(this).call(yAxis.scale(d.scale)); })
    .append("text")
      .attr("class", "title")
      .attr("text-anchor", "middle")
      .attr("y", -9)
      .text(function(d) { return d.name; });

  var ordinal_labels = svg.selectAll(".axis text")
      .on("mouseover", mouseover)
      .on("mouseout", mouseout);

  var projection = svg.selectAll(".background path,.foreground path")
      .on("mouseover", mouseover)
      .on("mouseout", mouseout);

  function mouseover(d) {
    svg.classed("active", true);

    // this could be more elegant
    if (typeof d === "string") {
      projection.classed("inactive", function(p) { return p.name !== d; });
      projection.filter(function(p) { return p.name === d; }).each(moveToFront);
      ordinal_labels.classed("inactive", function(p) { return p !== d; });
      ordinal_labels.filter(function(p) { return p === d; }).each(moveToFront);
    } else {
      projection.classed("inactive", function(p) { return p !== d; });
      projection.filter(function(p) { return p === d; }).each(moveToFront);
      ordinal_labels.classed("inactive", function(p) { return p !== d.name; });
      ordinal_labels.filter(function(p) { return p === d.name; }).each(moveToFront);
    }
  }

  function mouseout(d) {
    svg.classed("active", false);
    projection.classed("inactive", false);
    ordinal_labels.classed("inactive", false);
  }

  function moveToFront() {
    this.parentNode.appendChild(this);
  }
}

function draw(d) {
  return line(dimensions.map(function(dimension) {
    return [x(dimension.name), dimension.scale(d[dimension.name])];
  }));
}

parallelchart(data);

输出应该是我为每辆车的线条添加颜色,例如:

 var color = d3.scale.ordinal()
  .domain(['BMW', Buick, 'Chevrolet'])
  .range(['red','green','blue']); 

或者换句话说,我做错了什么?

最佳答案

您的代码是正确的。问题在于您正在使用 attr...

.attr("stroke", function(d) {
    var company = d.name.slice(0, d.name.indexOf(' '));
    return color(company);
})

...当您有路径的 CSS 规则时:

.foreground path {
    stroke: steelblue;
}

因此,attr 中设置的值被覆盖。

解决方案是使用 style(或删除 CSS):

.style("stroke", function(d) {
  var company = d.name.slice(0, d.name.indexOf(' '));
  return color(company);
}) 

这里是你的代码有那个变化:

var data = [{
    "name": "AMC Ambassador Brougham",
    "economy (mpg)": 13,
    "cylinders": 8,
    "displacement (cc)": 360,
    "power (hp)": 175,
    "weight (lb)": 3821,
    "0-60 mph (s)": 11,
    "year": 73
  },
  {
    "name": "AMC Ambassador DPL",
    "economy (mpg)": 15,
    "cylinders": 8,
    "displacement (cc)": 390,
    "power (hp)": 190,
    "weight (lb)": 3850,
    "0-60 mph (s)": 8.5,
    "year": 70
  },
  {
    "name": "AMC Ambassador SST",
    "economy (mpg)": 17,
    "cylinders": 8,
    "displacement (cc)": 304,
    "power (hp)": 150,
    "weight (lb)": 3672,
    "0-60 mph (s)": 11.5,
    "year": 72
  },
  {
    "name": "AMC Concord DL 6",
    "economy (mpg)": 20.2,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 90,
    "weight (lb)": 3265,
    "0-60 mph (s)": 18.2,
    "year": 79
  },
  {
    "name": "AMC Concord DL",
    "economy (mpg)": 18.1,
    "cylinders": 6,
    "displacement (cc)": 258,
    "power (hp)": 120,
    "weight (lb)": 3410,
    "0-60 mph (s)": 15.1,
    "year": 78
  },
  {
    "name": "AMC Concord DL",
    "economy (mpg)": 23,
    "cylinders": 4,
    "displacement (cc)": 151,
    "power (hp)": "",
    "weight (lb)": 3035,
    "0-60 mph (s)": 20.5,
    "year": 82
  },
  {
    "name": "AMC Concord",
    "economy (mpg)": 19.4,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 90,
    "weight (lb)": 3210,
    "0-60 mph (s)": 17.2,
    "year": 78
  },
  {
    "name": "AMC Concord",
    "economy (mpg)": 24.3,
    "cylinders": 4,
    "displacement (cc)": 151,
    "power (hp)": 90,
    "weight (lb)": 3003,
    "0-60 mph (s)": 20.1,
    "year": 80
  },
  {
    "name": "AMC Gremlin",
    "economy (mpg)": 18,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 100,
    "weight (lb)": 2789,
    "0-60 mph (s)": 15,
    "year": 73
  },
  {
    "name": "AMC Gremlin",
    "economy (mpg)": 19,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 100,
    "weight (lb)": 2634,
    "0-60 mph (s)": 13,
    "year": 71
  },
  {
    "name": "AMC Gremlin",
    "economy (mpg)": 20,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 100,
    "weight (lb)": 2914,
    "0-60 mph (s)": 16,
    "year": 75
  },
  {
    "name": "AMC Gremlin",
    "economy (mpg)": 21,
    "cylinders": 6,
    "displacement (cc)": 199,
    "power (hp)": 90,
    "weight (lb)": 2648,
    "0-60 mph (s)": 15,
    "year": 70
  },
  {
    "name": "AMC Hornet Sportabout (Wagon)",
    "economy (mpg)": 18,
    "cylinders": 6,
    "displacement (cc)": 258,
    "power (hp)": 110,
    "weight (lb)": 2962,
    "0-60 mph (s)": 13.5,
    "year": 71
  },
  {
    "name": "AMC Hornet",
    "economy (mpg)": 18,
    "cylinders": 6,
    "displacement (cc)": 199,
    "power (hp)": 97,
    "weight (lb)": 2774,
    "0-60 mph (s)": 15.5,
    "year": 70
  },
  {
    "name": "AMC Hornet",
    "economy (mpg)": 18,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 100,
    "weight (lb)": 2945,
    "0-60 mph (s)": 16,
    "year": 73
  },
  {
    "name": "AMC Hornet",
    "economy (mpg)": 19,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 100,
    "weight (lb)": 2901,
    "0-60 mph (s)": 16,
    "year": 74
  },
  {
    "name": "AMC Hornet",
    "economy (mpg)": 22.5,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 90,
    "weight (lb)": 3085,
    "0-60 mph (s)": 17.6,
    "year": 76
  },
  {
    "name": "AMC Matador (Wagon)",
    "economy (mpg)": 14,
    "cylinders": 8,
    "displacement (cc)": 304,
    "power (hp)": 150,
    "weight (lb)": 4257,
    "0-60 mph (s)": 15.5,
    "year": 74
  },
  {
    "name": "AMC Matador (Wagon)",
    "economy (mpg)": 15,
    "cylinders": 8,
    "displacement (cc)": 304,
    "power (hp)": 150,
    "weight (lb)": 3892,
    "0-60 mph (s)": 12.5,
    "year": 72
  },
  {
    "name": "AMC Matador",
    "economy (mpg)": 14,
    "cylinders": 8,
    "displacement (cc)": 304,
    "power (hp)": 150,
    "weight (lb)": 3672,
    "0-60 mph (s)": 11.5,
    "year": 73
  },
  {
    "name": "AMC Matador",
    "economy (mpg)": 15,
    "cylinders": 6,
    "displacement (cc)": 258,
    "power (hp)": 110,
    "weight (lb)": 3730,
    "0-60 mph (s)": 19,
    "year": 75
  },
  {
    "name": "AMC Matador",
    "economy (mpg)": 15.5,
    "cylinders": 8,
    "displacement (cc)": 304,
    "power (hp)": 120,
    "weight (lb)": 3962,
    "0-60 mph (s)": 13.9,
    "year": 76
  },
  {
    "name": "AMC Matador",
    "economy (mpg)": 16,
    "cylinders": 6,
    "displacement (cc)": 258,
    "power (hp)": 110,
    "weight (lb)": 3632,
    "0-60 mph (s)": 18,
    "year": 74
  },
  {
    "name": "AMC Matador",
    "economy (mpg)": 18,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 100,
    "weight (lb)": 3288,
    "0-60 mph (s)": 15.5,
    "year": 71
  },
  {
    "name": "AMC Pacer D/L",
    "economy (mpg)": 17.5,
    "cylinders": 6,
    "displacement (cc)": 258,
    "power (hp)": 95,
    "weight (lb)": 3193,
    "0-60 mph (s)": 17.8,
    "year": 76
  },
  {
    "name": "AMC Pacer",
    "economy (mpg)": 19,
    "cylinders": 6,
    "displacement (cc)": 232,
    "power (hp)": 90,
    "weight (lb)": 3211,
    "0-60 mph (s)": 17,
    "year": 75
  },
  {
    "name": "AMC Rebel SST (Wagon)",
    "economy (mpg)": "",
    "cylinders": 8,
    "displacement (cc)": 360,
    "power (hp)": 175,
    "weight (lb)": 3850,
    "0-60 mph (s)": 11,
    "year": 70
  },
  {
    "name": "AMC Rebel SST",
    "economy (mpg)": 16,
    "cylinders": 8,
    "displacement (cc)": 304,
    "power (hp)": 150,
    "weight (lb)": 3433,
    "0-60 mph (s)": 12,
    "year": 70
  },
  {
    "name": "AMC Spirit DL",
    "economy (mpg)": 27.4,
    "cylinders": 4,
    "displacement (cc)": 121,
    "power (hp)": 80,
    "weight (lb)": 2670,
    "0-60 mph (s)": 15,
    "year": 79
  },
  {
    "name": "Audi 100 LS",
    "economy (mpg)": 20,
    "cylinders": 4,
    "displacement (cc)": 114,
    "power (hp)": 91,
    "weight (lb)": 2582,
    "0-60 mph (s)": 14,
    "year": 73
  },
  {
    "name": "Audi 100 LS",
    "economy (mpg)": 23,
    "cylinders": 4,
    "displacement (cc)": 115,
    "power (hp)": 95,
    "weight (lb)": 2694,
    "0-60 mph (s)": 15,
    "year": 75
  },
  {
    "name": "Audi 100 LS",
    "economy (mpg)": 24,
    "cylinders": 4,
    "displacement (cc)": 107,
    "power (hp)": 90,
    "weight (lb)": 2430,
    "0-60 mph (s)": 14.5,
    "year": 70
  },
  {
    "name": "Audi 4000",
    "economy (mpg)": 34.3,
    "cylinders": 4,
    "displacement (cc)": 97,
    "power (hp)": 78,
    "weight (lb)": 2188,
    "0-60 mph (s)": 15.8,
    "year": 80
  },
  {
    "name": "Audi 5000",
    "economy (mpg)": 20.3,
    "cylinders": 5,
    "displacement (cc)": 131,
    "power (hp)": 103,
    "weight (lb)": 2830,
    "0-60 mph (s)": 15.9,
    "year": 78
  },
  {
    "name": "Audi 5000S (Diesel)",
    "economy (mpg)": 36.4,
    "cylinders": 5,
    "displacement (cc)": 121,
    "power (hp)": 67,
    "weight (lb)": 2950,
    "0-60 mph (s)": 19.9,
    "year": 80
  },
  {
    "name": "Audi Fox",
    "economy (mpg)": 29,
    "cylinders": 4,
    "displacement (cc)": 98,
    "power (hp)": 83,
    "weight (lb)": 2219,
    "0-60 mph (s)": 16.5,
    "year": 74
  },
  {
    "name": "BMW 2002",
    "economy (mpg)": 26,
    "cylinders": 4,
    "displacement (cc)": 121,
    "power (hp)": 113,
    "weight (lb)": 2234,
    "0-60 mph (s)": 12.5,
    "year": 70
  },
  {
    "name": "BMW 320i",
    "economy (mpg)": 21.5,
    "cylinders": 4,
    "displacement (cc)": 121,
    "power (hp)": 110,
    "weight (lb)": 2600,
    "0-60 mph (s)": 12.8,
    "year": 77
  },
  {
    "name": "Buick Century 350",
    "economy (mpg)": 13,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 175,
    "weight (lb)": 4100,
    "0-60 mph (s)": 13,
    "year": 73
  },
  {
    "name": "Buick Century Limited",
    "economy (mpg)": 25,
    "cylinders": 6,
    "displacement (cc)": 181,
    "power (hp)": 110,
    "weight (lb)": 2945,
    "0-60 mph (s)": 16.4,
    "year": 82
  },
  {
    "name": "Buick Century Luxus (Wagon)",
    "economy (mpg)": 13,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 150,
    "weight (lb)": 4699,
    "0-60 mph (s)": 14.5,
    "year": 74
  },
  {
    "name": "Buick Century Special",
    "economy (mpg)": 20.6,
    "cylinders": 6,
    "displacement (cc)": 231,
    "power (hp)": 105,
    "weight (lb)": 3380,
    "0-60 mph (s)": 15.8,
    "year": 78
  },
  {
    "name": "Buick Century",
    "economy (mpg)": 17,
    "cylinders": 6,
    "displacement (cc)": 231,
    "power (hp)": 110,
    "weight (lb)": 3907,
    "0-60 mph (s)": 21,
    "year": 75
  },
  {
    "name": "Buick Century",
    "economy (mpg)": 22.4,
    "cylinders": 6,
    "displacement (cc)": 231,
    "power (hp)": 110,
    "weight (lb)": 3415,
    "0-60 mph (s)": 15.8,
    "year": 81
  },
  {
    "name": "Buick Electra 225 Custom",
    "economy (mpg)": 12,
    "cylinders": 8,
    "displacement (cc)": 455,
    "power (hp)": 225,
    "weight (lb)": 4951,
    "0-60 mph (s)": 11,
    "year": 73
  },
  {
    "name": "Buick Estate Wagon (Wagon)",
    "economy (mpg)": 14,
    "cylinders": 8,
    "displacement (cc)": 455,
    "power (hp)": 225,
    "weight (lb)": 3086,
    "0-60 mph (s)": 10,
    "year": 70
  },
  {
    "name": "Buick Estate Wagon (Wagon)",
    "economy (mpg)": 16.9,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 155,
    "weight (lb)": 4360,
    "0-60 mph (s)": 14.9,
    "year": 79
  },
  {
    "name": "Buick Lesabre Custom",
    "economy (mpg)": 13,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 155,
    "weight (lb)": 4502,
    "0-60 mph (s)": 13.5,
    "year": 72
  },
  {
    "name": "Buick Opel Isuzu Deluxe",
    "economy (mpg)": 30,
    "cylinders": 4,
    "displacement (cc)": 111,
    "power (hp)": 80,
    "weight (lb)": 2155,
    "0-60 mph (s)": 14.8,
    "year": 77
  },
  {
    "name": "Buick Regal Sport Coupe (Turbo)",
    "economy (mpg)": 17.7,
    "cylinders": 6,
    "displacement (cc)": 231,
    "power (hp)": 165,
    "weight (lb)": 3445,
    "0-60 mph (s)": 13.4,
    "year": 78
  },
  {
    "name": "Buick Skyhawk",
    "economy (mpg)": 21,
    "cylinders": 6,
    "displacement (cc)": 231,
    "power (hp)": 110,
    "weight (lb)": 3039,
    "0-60 mph (s)": 15,
    "year": 75
  },
  {
    "name": "Buick Skylark 320",
    "economy (mpg)": 15,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 165,
    "weight (lb)": 3693,
    "0-60 mph (s)": 11.5,
    "year": 70
  },
  {
    "name": "Buick Skylark Limited",
    "economy (mpg)": 28.4,
    "cylinders": 4,
    "displacement (cc)": 151,
    "power (hp)": 90,
    "weight (lb)": 2670,
    "0-60 mph (s)": 16,
    "year": 79
  },
  {
    "name": "Buick Skylark",
    "economy (mpg)": 20.5,
    "cylinders": 6,
    "displacement (cc)": 231,
    "power (hp)": 105,
    "weight (lb)": 3425,
    "0-60 mph (s)": 16.9,
    "year": 77
  },
  {
    "name": "Buick Skylark",
    "economy (mpg)": 26.6,
    "cylinders": 4,
    "displacement (cc)": 151,
    "power (hp)": 84,
    "weight (lb)": 2635,
    "0-60 mph (s)": 16.4,
    "year": 81
  },
  {
    "name": "Cadillac Eldorado",
    "economy (mpg)": 23,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 125,
    "weight (lb)": 3900,
    "0-60 mph (s)": 17.4,
    "year": 79
  },
  {
    "name": "Cadillac Seville",
    "economy (mpg)": 16.5,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 180,
    "weight (lb)": 4380,
    "0-60 mph (s)": 12.1,
    "year": 76
  },
  {
    "name": "Chevroelt Chevelle Malibu",
    "economy (mpg)": 16,
    "cylinders": 6,
    "displacement (cc)": 250,
    "power (hp)": 105,
    "weight (lb)": 3897,
    "0-60 mph (s)": 18.5,
    "year": 75
  },
  {
    "name": "Chevrolet Bel Air",
    "economy (mpg)": 15,
    "cylinders": 8,
    "displacement (cc)": 350,
    "power (hp)": 145,
    "weight (lb)": 4440,
    "0-60 mph (s)": 14,
    "year": 75
  },
  {
    "name": "Chevrolet Camaro",
    "economy (mpg)": 27,
    "cylinders": 4,
    "displacement (cc)": 151,
    "power (hp)": 90,
    "weight (lb)": 2950,
    "0-60 mph (s)": 17.3,
    "year": 82
  },
  {
    "name": "Chevrolet Caprice Classic",
    "economy (mpg)": 13,
    "cylinders": 8,
    "displacement (cc)": 400,
    "power (hp)": 150,
    "weight (lb)": 4464,
    "0-60 mph (s)": 12,
    "year": 73
  },
  {
    "name": "Chevrolet Caprice Classic",
    "economy (mpg)": 17,
    "cylinders": 8,
    "displacement (cc)": 305,
    "power (hp)": 130,
    "weight (lb)": 3840,
    "0-60 mph (s)": 15.4,
    "year": 79
  },
  {
    "name": "Chevrolet Caprice Classic",
    "economy (mpg)": 17.5,
    "cylinders": 8,
    "displacement (cc)": 305,
    "power (hp)": 145,
    "weight (lb)": 3880,
    "0-60 mph (s)": 12.5,
    "year": 77
  }
]


var margin = {
    top: 30,
    right: 40,
    bottom: 20,
    left: 200
  },
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

var dimensions = [{
    name: "name",
    scale: d3.scale.ordinal().rangePoints([0, height]),
    type: "string"
  },
  {
    name: "economy (mpg)",
    scale: d3.scale.linear().range([0, height]),
    type: "number"
  },
  {
    name: "cylinders",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "displacement (cc)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "power (hp)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "weight (lb)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "0-60 mph (s)",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
  {
    name: "year",
    scale: d3.scale.linear().range([height, 0]),
    type: "number"
  },
];

var x = d3.scale.ordinal()
  .domain(dimensions.map(function(d) {
    return d.name;
  }))
  .rangePoints([0, width]);

var line = d3.svg.line()
  .defined(function(d) {
    return !isNaN(d[1]);
  });

// CREATE A COLOR SCALE
var color = d3.scale.ordinal()
  .domain(['Buick', 'Chevrolet', 'Dodge'])
  .range(['red', 'blue', 'green'])

var yAxis = d3.svg.axis()
  .orient("left");

var svg = d3.select("body").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var dimension = svg.selectAll(".dimension")
  .data(dimensions)
  .enter().append("g")
  .attr("class", "dimension")
  .attr("transform", function(d) {
    return "translate(" + x(d.name) + ")";
  });

function parallelchart(data) {
  dimensions.forEach(function(dimension) {
    dimension.scale.domain(dimension.type === "number" ?
      d3.extent(data, function(d) {
        return +d[dimension.name];
      }) :
      data.map(function(d) {
        return d[dimension.name];
      }).sort());
  });

  svg.append("g")
    .attr("class", "background")
    .selectAll("path")
    .data(data)
    .enter().append("path")
    .attr("d", draw);

  /*   svg.append("g")
        .attr("class", "foreground")
      .selectAll("path")
        .data(data)
      .enter().append("path")
        .attr("d", draw); */

  // USE THE COLOR SCALE TO SET THE STROKE BASED ON THE DATA
  foreground = svg.append("g")
    .attr("class", "foreground")
    .selectAll("path")
    .data(data)
    .enter().append("path")
    .attr("d", draw)
    .style("stroke", function(d) {
      var company = d.name.slice(0, d.name.indexOf(' '));
      return color(company);
    })


  dimension.append("g")
    .attr("class", "axis")
    .each(function(d) {
      d3.select(this).call(yAxis.scale(d.scale));
    })
    .append("text")
    .attr("class", "title")
    .attr("text-anchor", "middle")
    .attr("y", -9)
    .text(function(d) {
      return d.name;
    });

  var ordinal_labels = svg.selectAll(".axis text")
    .on("mouseover", mouseover)
    .on("mouseout", mouseout);

  var projection = svg.selectAll(".background path,.foreground path")
    .on("mouseover", mouseover)
    .on("mouseout", mouseout);

  function mouseover(d) {
    svg.classed("active", true);

    // this could be more elegant
    if (typeof d === "string") {
      projection.classed("inactive", function(p) {
        return p.name !== d;
      });
      projection.filter(function(p) {
        return p.name === d;
      }).each(moveToFront);
      ordinal_labels.classed("inactive", function(p) {
        return p !== d;
      });
      ordinal_labels.filter(function(p) {
        return p === d;
      }).each(moveToFront);
    } else {
      projection.classed("inactive", function(p) {
        return p !== d;
      });
      projection.filter(function(p) {
        return p === d;
      }).each(moveToFront);
      ordinal_labels.classed("inactive", function(p) {
        return p !== d.name;
      });
      ordinal_labels.filter(function(p) {
        return p === d.name;
      }).each(moveToFront);
    }
  }

  function mouseout(d) {
    svg.classed("active", false);
    projection.classed("inactive", false);
    ordinal_labels.classed("inactive", false);
  }

  function moveToFront() {
    this.parentNode.appendChild(this);
  }
}

function draw(d) {
  return line(dimensions.map(function(dimension) {
    return [x(dimension.name), dimension.scale(d[dimension.name])];
  }));
}

parallelchart(data);
svg {
  font: 12px sans-serif;
}

.background path {
  fill: none;
  stroke: none;
  stroke-width: 20px;
  pointer-events: stroke;
}

.foreground path {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}

.axis .title {
  font-size: 11px;
  font-weight: bold;
  text-transform: uppercase;
}

.axis line,
.axis path {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.axis.string {
  font-size: 6px;
}

.label {
  -webkit-transition: fill 125ms linear;
}

.active .label:not(.inactive) {
  font-weight: bold;
  font-size: 11px;
}

.label.inactive {
  fill: #ccc;
}

.foreground path.inactive {
  stroke: #ccc;
  stroke-opacity: .5;
  stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

关于javascript - 如何在d3中的平行坐标图中为线条着色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58294140/

相关文章:

JavaScript: boolean 对象可以用作回调函数吗?

javascript - 使用 jquery 获取 .html() 除了子元素的内容

html - 简单的 2 block 移动导航

css - 嵌套的 Bootstrap 工具提示 divs 切换父 div 的工具提示

css - 使用 CSS3 转换延迟鼠标移开/悬停

Javascript 在将数字相加时删除小数

javascript - 单击reactjs中的按钮时不显示任何文本

javascript - 为 D3 JS 中的给定数据点附加随机选择的多边形

d3.js - d3-drag - 在 d3v5 中拖动重新调整 y 轴

javascript - 如何使用 d3.js 创建像 StackOverflow 信誉图这样的图表?