2017-08-24 5 views
0

D3.jsを使用して積み上げ領域チャートを作成しています。私はsvgにラインパスを追加すると、複数のラインパスの代わりにただ一つのパスに分かりました。私のデータ構造は他の例とは異なります。私はこの積み上げられたエリアチャートに複数のラインパスを描く方法を知りましたか?スタック領域チャートに線を追加するD3

Here is the link

ここでcsvファイルのないコードです:複数のパスを追加するための

var formatDate = d3.time.format("%Y"); 
 

 
var fullwidth = 500, 
 
    fullheight = 380; 
 

 
var margin = {top: 80, right: 30, bottom: 80, left: 40}, 
 
    width = fullwidth - margin.left - margin.right, 
 
    height = fullheight - margin.top - margin.bottom; 
 

 
var xScale = d3.time.scale() 
 
.domain([2014,2021]) 
 
    .range([0, width]); 
 

 
var yScale = d3.scale.linear() 
 
    .range([height, 0]); 
 

 
var newyScale = d3.scale.linear() 
 
    .range([height, 0]); 
 

 
var colorScale = d3.scale.ordinal() 
 
\t \t \t \t .domain(["Not meet","Nearly meet","Standard","Exceed"]) 
 
\t \t \t \t .range(["#F2F094","#CCE19A","#8DBF79","#467E43"]); 
 

 
var ordinal = d3.scale.ordinal() 
 
     .domain(["Not meet","Nearly meet","Standard","Exceed"]) 
 
     .range(["#F2F094","#CCE19A","#8DBF79","#467E43"]); 
 

 
// var linecolor = d3.scale.ordinal() 
 
//   .domain(["Not meet","Nearly meet","Standard","Exceed"]) 
 
//   .range(["#BBB84B","#789952","#50DB51","#2D602A"]); 
 

 

 

 

 
var xAxis = d3.svg.axis() 
 
    .scale(xScale) 
 
    .orient("bottom") 
 
    .outerTickSize(0); 
 
    
 
    
 
var yAxis = d3.svg.axis() 
 
    .scale(yScale) 
 
    .orient("right") 
 
    .tickSize(width) 
 
    .tickFormat(function(d){return d + "%";}) 
 
    .ticks(6); 
 

 
var stack = d3.layout.stack() 
 
    .offset("zero") // try "silhouette" next, that's a streamgraph! 
 
    //.order("inside-out") // try this and see what you think 
 
    .values(function(d) { return d.values; }) 
 
    .x(function(d) { return formatDate.parse(d.Year);}) 
 
    .y(function(d) { return +d.Pct; }); 
 

 
// use the result of the stack to draw the shapes using area 
 
var area = d3.svg.area() 
 
    .interpolate("cardinal") 
 
    .defined(function (d) { 
 
     // console.log(d); 
 
     return d.Pct !== "null"; 
 
    }) 
 
    .x(function(d) { return xScale(formatDate.parse(d.Year)); }) 
 
    .y0(function(d) { return yScale(d.y0); }) 
 
    .y1(function(d) { return yScale(d.y0 + d.y); }); 
 

 
//define the line 
 
    var line = d3.svg.line() 
 
    .defined(function (d) { 
 
     // console.log(d); 
 
     return d.Pct !== "null"; 
 
    }) 
 
    .x(function(d) {return xScale(formatDate.parse(d.Year));}) 
 
    .y(function(d) { return yScale(+d.New);}); 
 

 
var svg = d3.select("#chart").append("svg") 
 
    .attr("width", fullwidth) 
 
    .attr("height", fullheight) 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
d3.csv("test.csv", function(error, data) { 
 
\t if(error){console.log(error);}; 
 

 
console.log(data); 
 

 
\t var priorities = ["Exceed","Standard","Nearly meet","Not meet"]; 
 

 
\t var dataset = d3.nest() 
 
    .key(function(d) { 
 
     return d.Level; 
 
    }) 
 
    .sortKeys(function(a,b) { 
 
    return priorities.indexOf(b) - priorities.indexOf(a);}) // customize order 
 
    .sortValues(function (a, b) { return formatDate.parse(a.Year) - formatDate.parse(b.Year)}) 
 
    .entries(data); 
 

 
    // console.log(dataset); 
 

 
var layers = stack(dataset); 
 
// console.log("layers", layers); // it adds a y and y0 to the data values. 
 

 
// reset these after doing the layer stacking. 
 
    xScale.domain(d3.extent(data, function(d) { return formatDate.parse(d.Year); })); 
 
    yScale.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]); // highest combo 
 

 

 

 
newyScale.domain([0, d3.max(data, function(d){return +d.New;})]); 
 

 

 

 

 
svg.append("g") 
 
     .attr("class", "x axis") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xAxis); 
 

 
    svg.append("g") 
 
     .attr("class", "y axis") 
 
     .call(customYAxis); 
 

 
svg.selectAll(".layer") 
 
     .data(layers) 
 
    .enter().append("path") 
 
     .attr("class", "layer") 
 
     .attr("d", function(d) { return area(d.values); }) 
 
     .on("mouseover", mouseover) 
 
     .on("mouseout", mouseout) 
 
     .style("fill", function(d, i) { return colorScale(i); }); 
 
     // .append("title") 
 
     // .text(function(d) { 
 
     // return d.key; // level is the key in the nest 
 
     // }); 
 

 
svg.append("path") 
 
    .data([data])//tricky part 
 
    .attr('class',"line") 
 
    .attr("d",line) 
 
    .style("stroke", "white"); 
 

 
svg.append("g") 
 
.attr("class","legendOrdinal") 
 
.attr("transform","translate(" +(20)+","+(-80)+")"); 
 

 
var legendOrdinal = d3.legend.color() 
 
     .shapeWidth(50) 
 
     .shapePadding(50) 
 
     .orient('horizontal') 
 
     .labels(["Standard Not meet","Standard Nearly meet","Standard","Exceed"]) 
 
     .scale(ordinal); 
 

 
svg.select(".legendOrdinal") 
 
     .call(legendOrdinal) 
 
     .selectAll(".label") 
 
     .call(wrap,50); 
 

 
//wrap the label 
 
function wrap(text, width) { 
 
    text.each(function() { 
 
    var text = d3.select(this), 
 
     words = text.text().split(/\s+/).reverse(), 
 
     word, 
 
     line = [], 
 
     lineNumber = 0, 
 
     lineHeight = 1.0, // ems 
 
     y = text.attr("y"), 
 
     dy = parseFloat(0), 
 
     tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); 
 
    while (word = words.pop()) { 
 
     line.push(word); 
 
     tspan.text(line.join(" ")); 
 
     if (tspan.node().getComputedTextLength() > width) { 
 
     line.pop(); 
 
     tspan.text(line.join(" ")); 
 
     line = [word]; 
 
     tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", "1em").text(word); 
 
     } 
 
    } 
 
    }); 
 
} 
 

 
//mouseover function 
 
function mouseover(){ 
 
\t d3.select(this).classed("highlight", true) 
 
}; 
 

 
function mouseout(){ 
 
d3.select(this).classed("highlight", false); 
 
}; 
 

 
// Axis style 
 
function customYAxis(svg) { 
 
svg.call(yAxis); 
 

 
    svg.select(".domain").remove(); 
 

 
    svg.selectAll(".tick:not(:first-of-type) line").attr("stroke-dasharray", "2,2"); 
 

 
    svg.selectAll(".tick text").attr("x", 0) 
 
    \t .attr("dy", -4) 
 
    \t .style("text-anchor", "end") 
 
    \t .attr("class","small"); 
 
}; 
 

 
// Manually add text to Axis 
 
svg.append("text") 
 
    .attr("transform", "translate(" + (width/7) + " ," + (height + margin.top/3)+")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blueT") 
 
    .text("2015"); 
 

 
    svg.append("text") 
 
    .attr("transform", "translate(" + (2 * width/7) + " ," + (height+margin.top/3) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blueT") 
 
    .text("2016"); 
 

 
    svg.append("text") 
 
    .attr("transform", "translate(" + (3 * width/7) + " ," + (height+margin.top/3) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blueT") 
 
    .text("2017"); 
 

 
    svg.append("text") 
 
    .attr("transform", "translate(" + (5 * width/7) + " ," + (height+margin.top/3) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blueT") 
 
    .text("2015"); 
 

 
    \t svg.append("text") 
 
    .attr("transform", "translate(" + (6 * width/7) + " ," + (height+margin.top/3) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blueT") 
 
    .text("2016"); 
 

 
    svg.append("text") 
 
    .attr("transform", "translate(" + width + " ," + (height+margin.top/3) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blueT") 
 
    .text("2017"); 
 

 
svg.append("text") 
 
    .attr("transform", "translate(" + (width/3.5) + " ," + (height + margin.bottom - 5) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blackT") 
 
    .text("Math"); 
 

 
svg.append("text") 
 
    .attr("transform", "translate(" + (3*width/3.5) + " ," + (height + margin.bottom - 5) +")") 
 
    .style("text-anchor", "middle") 
 
    .attr("class","blackT") 
 
    .text("English"); 
 

 

 
});
body { 
 
    font-family: 'Proxima Nova', Georgia, sans-serif; 
 
} 
 

 
text.label{ 
 

 
fill:#4A4A4A; 
 
font-size:12px; 
 

 
} 
 

 
.highlight{ 
 
fill:#F7E50A!important; 
 
} 
 

 
.blueT{ 
 
\t fill:#407DC6; 
 
\t font-size:16px; 
 
} 
 

 
.blackT{ 
 
\t fill:#4A4A4A; 
 
\t font-size:23px; 
 
} 
 

 
.small{ 
 
\t fill:#4A4A4A; 
 
\t font-size: 14px; 
 
} 
 

 
.x.axis text{ 
 
\t display: none; 
 
} 
 

 
.x.axis tick{ 
 
\t display: none; 
 
} 
 

 
.path:hover{ 
 
fill:#407DC6; 
 
} 
 

 
.axis path, 
 
.axis line { 
 
    fill: none; 
 
    stroke: #B9B7B7; 
 
    shape-rendering: crispEdges; 
 
}
<div id="chart"></div> 
 

 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> 
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.13.0/d3-legend.min.js"></script>

答えて

1

は、あなたのコードの中で、私が見る、SVGに別々にそれらを追加する必要があります1つのパスだけがsvgに追加されます。私はこのコードを使用して複数の折れ線グラフを作成しました。これはsvgに複数のパスを追加したコードです。

var chartWidth = 748, 
chartHeight = 580 ; 


var svg = d3.select("#chart").append('svg') 
.attr('width', chartWidth) 
.attr('height', chartHeight) 
.attr('id', "d3Chart"); 


var margin = {top: 20, right: 40, bottom: 150, left: 70}, 
    width = +svg.attr("width") - margin.left - margin.right, 
    height = +svg.attr("height") - margin.top - margin.bottom, 


var focus = svg.append("g") 
    .attr("class", "focus") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

//I have multiple y axis in my chart, two on the left and one on the right 
//if you don't need multiple y axis then use just one. Also in path 
//generator use the same variable for converting the data into coordinates. 

var x = d3.scaleTime().range([0, width]), //time scale with range  
    y = d3.scaleLinear().range([height, 0]), //for y axis on the right 
    y2 = d3.scaleLinear().range([height, 0]), //for 2nd y axis main chart 
    y3 = d3.scaleLinear().range([height, 0]); //for 3rd y axis main chart 


//path generator for data 
var pathGeneratorVergleich1 = d3.line() 
       .x(function(d) { return x(d.date); }) //return the x axis value to be ploted on chart 
       .y(function(d) { return y2(d.varVergleich1); });//returns the y axis value to be ploted on chart 

var pathGeneratorVergleich2 = d3.line() 
       .x(function(d) { return x(d.date); }) 
       .y(function(d) { return y3(d.varVergleich2); }); 


focus.append("path") 
     .attr("id", "path1") 
     .style('fill', 'none') 
     .style('stroke', '#6FFF00') /*fancy green*/ 
     .style('stroke-width', '2px') 
     .data([dataX]) 
     .attr('d', pathGeneratorVergleich1); 

focus.append("path") 
     .attr("id", "path2") 
     .style('fill', 'none') 
     .style('stroke', '#FFFF41') /*fancy yellow*/ 
     .style('stroke-width', '2px') 
     .data([dataX]) 
     .attr('d', pathGeneratorVergleich2); 

と私DATAXは、次のようにloks:私はそれを行うために別のCSVファイルを使用しようとするかもしれないと思い

[{date: Thu Aug 24 2017 13:44:22 GMT+0200 (Mitteleuropäische Sommerzeit), varKurve: 0.564 , varVergleich1: 0.356, varVergleich2: 0}, 
{date: Thu Aug 24 2017 13:36:22 GMT+0200 (Mitteleuropäische Sommerzeit), varKurve: 0.640, varVergleich1: 0.355, varVergleich2: 0}, 
{date: Thu Aug 24 2017 13:28:22 GMT+0200 (Mitteleuropäische Sommerzeit), varKurve: 0.764, varVergleich1: 0.357, varVergleich2: 0}, 
{date: Thu Aug 24 2017 13:20:22 GMT+0200 (Mitteleuropäische Sommerzeit), varKurve: 0.760, varVergleich1: 0.355, varVergleich2: 0}, 
{date: Thu Aug 24 2017 13:12:22 GMT+0200 (Mitteleuropäische Sommerzeit), varKurve: 0.564, varVergleich1: 0.35, varVergleich2: 0}, 
{date: Thu Aug 24 2017 13:04:22 GMT+0200 (Mitteleuropäische Sommerzeit), varKurve: 0.164, varVergleich1: 0.351, varVergleich2: 0}] 
+0

。ありがとう –

関連する問題