我是 javascript 和 D3 的新手。
我正在尝试创建一个堆叠面积图,在以绝对比例和百分比比例显示数据之间切换。我意识到这涉及玩弄
d3.layout.stack().offset("zero") 和 d3.layout.stack().offset("expand")。
我已经成功地让图表做我想做的事:
...但我并不为我的方法感到自豪,并且确信有更好的方法来做到这一点。有任何想法吗?有没有你可能知道的简单例子?
我对我的代码不满意,因为在设置 if/else 语句时,我只是重新声明了之前编写的所有内容,只更改了偏移变量。这似乎是一种笨拙的方法。另外,我认为这不会让我设置过渡。
data = [{"type": "Group1",
"values": [
{"x":0, "y": 2.5},
{"x":1, "y": 2.4},
{"x":2, "y": 0.3}]},
{"type": "Group2",
"values": [
{"x":0, "y": 1.5},
{"x":1, "y": 1.3},
{"x":2, "y": 1.1}]}
];
var stackZero = d3.layout.stack()
.values(function(d){return d.values;})
.offset("zero");
stackZero(data);
var xScale = d3.scale.linear()
.domain([0,2])
.range([0, width]);
var yScale = d3.scale.linear()
.range([height,0])
.domain([0, d3.max(data, function(d){return d3.max(d.values, function(d){return d.y0 + d.y;});})]);
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.y0 + d.y);});
var svg = d3.selectAll("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 +")");
svg.selectAll(".layers")
.data(data)
.enter()
.append("path")
.attr("class", "layer")
.attr("d", function(d){return area(d.values);})
.style("fill", function (d,i){return colors(i)});
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(yAxis);
d3.select("p") //now we start to interact with the chart
.on("click", function() {
console.log("entering variable is " + stackType);
svg.selectAll("path").data([]).exit().remove();
svg.selectAll(".y.axis").data([]).exit().remove();
if(stackType){ //enter true, or expanded data
var stackExpand = d3.layout.stack()
.values(function(d){return d.values;})
.offset("expand");
stackExpand(data);
console.log(data);
var yScale = d3.scale.linear()
.range([height,0])
.domain([0, d3.max(data, function(d){return d3.max(d.values, function(d){return d.y0 + d.y;});})]);
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.y0 + d.y);});
svg.selectAll(".layers")
//.data(stackZero(data))
.data(stackExpand(data))
.enter()
.append("path")
.attr("class", "layer")
.attr("d", function(d){return area(d.values);})
.style("fill", function (d,i){return colors(i)});
formatter = d3.format(".0%");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.tickFormat(formatter);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(yAxis);
stackType = false;
console.log("exiting variable is " + stackType);
} else { //enter false, or zero data
data = [{"type": "Group1",
"values": [
{"x":0, "y": 2.5},
{"x":1, "y": 2.4},
{"x":2, "y": 0.3}]},
{"type": "Group2",
"values": [
{"x":0, "y": 1.5},
{"x":1, "y": 1.3},
{"x":2, "y": 1.1}]}
];
var stackZero = d3.layout.stack()
.values(function(d){return d.values;})
.offset("zero");
stackZero(data);
console.log(data);
var yScale = d3.scale.linear()
.range([height,0])
.domain([0, d3.max(data, function(d){return d3.max(d.values, function(d){return d.y0 + d.y;});})]);
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.y0 + d.y);});
svg.selectAll(".layers")
.data(stackZero(data))
//.data(stackExpand(data))
.enter()
.append("path")
.attr("class", "layer")
.attr("d", function(d){return area(d.values);})
.style("fill", function (d,i){return colors(i)});
stackType = true;
console.log("exiting variable is" + stackType);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(yAxis);
};
});
</script>