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.