简体   繁体   中英

How to color lines in parallel coordinate plot in d3?

My problem is that I can't color lines in this d3 chart. I tried some things but didn't work.

I also tried to add this:

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

and then I added this:

 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); }); 

This is the code in jsfiddle , where I have a parallel coordinate plot with hovering over the lines, but now I want to color the lines for each car differently. This is how the code looks like:

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);

The output should be that I add colors to lines for each car ex.:

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

or in another way maybe, what am I doing wrong?

Your code is correct. The problem is just that you're using attr ...

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

... while you have a CSS rule for the paths:

.foreground path {
    stroke: steelblue;
}

Because of that, the value set in the attr is overridden.

The solution is just using style (or removing the CSS):

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

Here is your code with that change:

 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM