我使用D3 js创建堆积面积图。这是我的代码的链接:
https://jsfiddle.net/6um7xans/
我的JS:
var sum_height_2009=0;
var sum_height_2013=0;
var count;
//console.log(trend_obj);
var marginTop = 10;
var marginBottom = 20;
var marginRight = 15;
var marginLeft = 30;
var height = 480 - marginTop - marginBottom;
var width = 627 - marginLeft - marginRight;
var svgSelection = d3.select('#chart1')
.append("svg")
.attr("width", width + marginLeft + marginRight)
.attr("height", height + marginTop + marginBottom);
var baseGroup = svgSelection
.append("g")
.attr("transform", "translate("+marginLeft+","+marginTop+")");
var yScale = d3.scale.linear()
.range([height,0])
.domain([0,100]);
var xScale = d3.time.scale()
.range([0, width])
//assign colores for segments
var colorScale = d3.scale.ordinal()
.range(["url(#gradient)", "url(#gradient2)", "url(#gradient3)", "url(#gradient4)","url(#gradient5)","url(#gradient6)","url(#gradient7)","url(#gradient8)","url(#gradient9)","url(#gradient10)"]);
var hoverLabel = d3.scale.ordinal()
.range("age1", "age2", "age3", "age4","age5");
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(10)
.tickFormat(function(d){if(d==100){return "$"+(d) ;}else{return "$"+(d)}})
.orient("left");
var format = d3.time.format("%Y");
var xAxis = d3.svg.axis()
.scale(xScale)
var dataset = [
{ year: "2009", age1: 10, age2: 0, age3: 12, age4: 17, age5: 16, age6: 11, age7: 10, age8: 12, age9: 17, age10: 15},
{ year: "2010", age1: 12, age2: 12, age3: 10, age4: 18, age5: 20, age6: 12, age7: 12, age8: 10, age9: 21, age10: 14},
{ year: "2011", age1: 14, age2: 16, age3: 12, age4: 20, age5: 20, age6: 14, age7: 12, age8: 10, age9: 21, age10: 12},
{ year: "2012", age1: 16, age2: 18, age3: 15, age4: 20, age5: 20, age6: 16, age7: 14, age8: 15, age9: 21, age10: 11},
{ year: "2013", age1: 18, age2: 20, age3: 18, age4: 22, age5: 20, age6: 18, age7: 12, age8: 12, age9: 21, age10: 20}
];
var parseDate = d3.time.format("%Y");
dataset.forEach(function(d) {
d.year = d.year;
});
// each key (age), uses a map to create all the objects for that age
// i in the anonymous function passed to map is the index of the dataset array, so can be used as the ID
var newDataset = ["age1", "age2", "age3", "age4","age5"].map(function(n){
return dataset.map(function(d, i){
return { x: d.year, y: d[n], y0: 0 };
});
});
d3.layout.stack()(newDataset);
xScale.domain(d3.extent(dataset, function(d) {
return d.year
}))
var x_axis_height = height+1;
baseGroup.append("g")
.attr("class", "x axis")
.attr("transform", "translate(-1," + x_axis_height + ")")
.style("z-index", 9999)
.call(xAxis);
baseGroup.append("g")
.attr("class", "y axis")
.attr("transform", "translate(-1,1)")
.style("z-index", 9999)
.call(yAxis);
var area = d3.svg.area()
.x(function(d) { return xScale(d.x); })
.y0(function(d) { return yScale(d.y0); })
.y1(function(d) { return yScale(d.y + d.y0); });
var ageGroup = baseGroup.selectAll(".valgroup")
.data(newDataset)
.enter()
.append("g")
.attr("class", "valgroup")
.style("border-right", "2px solid gray")
.style("z-index", -1)
.style("fill", function(d, i) { return colorScale(i); })
.attr("class", function(d, i) { return hoverLabel(i); });
ageGroup.append("path")
.style("shape-rendering", "auto")
.attr("d", function(d) { return area(d); })
.attr("class", function(d, i) { return hoverLabel(i); })
//code to display text in front of graph layers
svg=d3.select('svg');
function getMyCentroid(element) {
var bbox = element.getBBox();
return [bbox.x + bbox.width / 2, bbox.y + bbox.height / 1.5];
}
d3.selectAll("path")[0].forEach(function(d,i) {
var centroid = getMyCentroid(d);
count=i;
})
/* gradient colors */
//gradient
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "20%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "40%")
.attr("stop-color", "#699CD4")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#95B9EA")
.attr("stop-opacity", 1);
//gradient2
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient2")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "30%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#D66A64")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#EC9591")
.attr("stop-opacity", 1);
//gradient2
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient3")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "20%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#A9C767")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#C6E195")
.attr("stop-opacity", 1);
//gradient2
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient4")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "30%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#8B6EAE")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#BCAAD6")
.attr("stop-opacity", 1);
//gradient5
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient5")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "30%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#43B4CF")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#93DBF3")
.attr("stop-opacity", 1);
当我尝试向右侧添加阴影时,它会添加到整个图形中。有没有办法让它看起来像:
如何仅在右侧添加阴影?
答案 0 :(得分:1)
我的解决方案:创建另一组路径,用lightgray
填充它们,并将它们向右/向下翻译一下:
var shadow = baseGroup.selectAll(".shadow")
.data(newDataset)
.enter()
.append("g")
.append("path")
.style("fill", "lightgray")
.attr("d", function(d) {
return area(d);
})
.attr("transform", "translate(6,3)");
以下是演示:
var sum_height_2009=0;
var sum_height_2013=0;
var count;
//console.log(trend_obj);
var marginTop = 10;
var marginBottom = 20;
var marginRight = 15;
var marginLeft = 30;
var height = 480 - marginTop - marginBottom;
var width = 627 - marginLeft - marginRight;
var svgSelection = d3.select('#chart1')
.append("svg")
.attr("width", width + marginLeft + marginRight)
.attr("height", height + marginTop + marginBottom);
var baseGroup = svgSelection
.append("g")
.attr("transform", "translate("+marginLeft+","+marginTop+")");
var yScale = d3.scale.linear()
.range([height,0])
.domain([0,100]);
var xScale = d3.time.scale()
.range([0, width])
//assign colores for segments
var colorScale = d3.scale.ordinal()
.range(["url(#gradient)", "url(#gradient2)", "url(#gradient3)", "url(#gradient4)","url(#gradient5)","url(#gradient6)","url(#gradient7)","url(#gradient8)","url(#gradient9)","url(#gradient10)"]);
var hoverLabel = d3.scale.ordinal()
.range("age1", "age2", "age3", "age4","age5");
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(10)
.tickFormat(function(d){if(d==100){return "$"+(d) ;}else{return "$"+(d)}})
.orient("left");
var format = d3.time.format("%Y");
var xAxis = d3.svg.axis()
.scale(xScale)
var dataset = [
{ year: "2009", age1: 10, age2: 0, age3: 12, age4: 17, age5: 16, age6: 11, age7: 10, age8: 12, age9: 17, age10: 15},
{ year: "2010", age1: 12, age2: 12, age3: 10, age4: 18, age5: 20, age6: 12, age7: 12, age8: 10, age9: 21, age10: 14},
{ year: "2011", age1: 14, age2: 16, age3: 12, age4: 20, age5: 20, age6: 14, age7: 12, age8: 10, age9: 21, age10: 12},
{ year: "2012", age1: 16, age2: 18, age3: 15, age4: 20, age5: 20, age6: 16, age7: 14, age8: 15, age9: 21, age10: 11},
{ year: "2013", age1: 18, age2: 20, age3: 18, age4: 22, age5: 20, age6: 18, age7: 12, age8: 12, age9: 21, age10: 20}
];
var parseDate = d3.time.format("%Y");
dataset.forEach(function(d) {
d.year = d.year;
});
// each key (age), uses a map to create all the objects for that age
// i in the anonymous function passed to map is the index of the dataset array, so can be used as the ID
var newDataset = ["age1", "age2", "age3", "age4","age5"].map(function(n){
return dataset.map(function(d, i){
return { x: d.year, y: d[n], y0: 0 };
});
});
d3.layout.stack()(newDataset);
xScale.domain(d3.extent(dataset, function(d) {
return d.year
}))
var x_axis_height = height+1;
var area = d3.svg.area()
.x(function(d) { return xScale(d.x); })
.y0(function(d) { return yScale(d.y0); })
.y1(function(d) { return yScale(d.y + d.y0); });
var shadow = baseGroup.selectAll(".shadow")
.data(newDataset)
.enter()
.append("g")
.append("path")
.style("fill", "lightgray")
.attr("d", function(d) { return area(d); })
.attr("transform", "translate(6,3)");
var ageGroup = baseGroup.selectAll(".valgroup")
.data(newDataset)
.enter()
.append("g")
.attr("class", "valgroup")
.style("border-right", "2px solid gray")
.style("z-index", -1)
.style("fill", function(d, i) { return colorScale(i); })
.attr("class", function(d, i) { return hoverLabel(i); });
ageGroup.append("path")
.style("shape-rendering", "auto")
.attr("d", function(d) { return area(d); })
.attr("class", function(d, i) { return hoverLabel(i); })
baseGroup.append("g")
.attr("class", "x axis")
.attr("transform", "translate(-1," + x_axis_height + ")")
.style("z-index", 9999)
.call(xAxis);
baseGroup.append("g")
.attr("class", "y axis")
.attr("transform", "translate(-1,1)")
.style("z-index", 9999)
.call(yAxis);
//code to display text in front of graph layers
svg=d3.select('svg');
function getMyCentroid(element) {
var bbox = element.getBBox();
return [bbox.x + bbox.width / 2, bbox.y + bbox.height / 1.5];
}
d3.selectAll("path")[0].forEach(function(d,i) {
var centroid = getMyCentroid(d);
count=i;
})
/* gradient colors */
//gradient
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "20%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "40%")
.attr("stop-color", "#699CD4")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#95B9EA")
.attr("stop-opacity", 1);
//gradient2
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient2")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "30%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#D66A64")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#EC9591")
.attr("stop-opacity", 1);
//gradient2
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient3")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "20%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#A9C767")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#C6E195")
.attr("stop-opacity", 1);
//gradient2
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient4")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "30%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#8B6EAE")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#BCAAD6")
.attr("stop-opacity", 1);
//gradient5
svg=d3.select('svg');
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient5")
.attr("x1", "0%")
.attr("y1", "80%")
.attr("x2", "30%")
.attr("y2", "22%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "20%")
.attr("stop-color", "#43B4CF")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#93DBF3")
.attr("stop-opacity", 1);

body {
font-family: Helvetica;
font-size: 12px;
color:#9DA0A4;
}
.axis path,
.axis line {
fill: none;
stroke: #5c6067;
stroke-width:2px;
shape-rendering: auto;
}
.browser text {
text-anchor: end;
}
#chart1{
margin-top: 10px;
margin-left: 67px;
}
svg{
overflow: visible;
}
.cost_in_B{
position: absolute;
font-weight: bold;
color: #5c6067;
left:3%;
top:0%;
}
.year-bottom{
position: absolute;
font-weight: bold;
color: #5c6067;
left:6%;
bottom:35%;
}
.cagr-head{
position: absolute;
color: black;
font-weight: bold;
font-size: 15px;
left:40%;
top:0%;
}
.cagr-percent{
color: #5c6067;
}
.segment-div{
position:absolute;
left:60%;
//top:10%;
}
.seg-label{
display: inline-block;
}
.seg-rect{
display:inline-block;
height:16px;
//background:#638EC6;
width: 30px;
}
.seg-rect{
position:absolute;
left:60%;
//top:10%;
}
.seg-label{
position:absolute;
left:65%;
font-family: Helvetica;
color: #5c6067;
font-weight: bold;
}

<script src="https://d3js.org/d3.v3.js"></script>
<div id="chart1"></div>
&#13;
请记住,在我的解决方案中,如果您将阴影路径向下转换为很多,它们将显示在x轴下。
PS:删除所有&#34; z-index&#34;样式。它们对SVG没有影响。