Javascript D3面积图,带有指定的底部/地板

Javascript D3面积图,带有指定的底部/地板,javascript,d3.js,svg,graph,line-plot,Javascript,D3.js,Svg,Graph,Line Plot,是否可以在D3中制作一个面积图,在这里我可以指定面积图的楼层(作为另一个图) 大概是这样的: var area = d3.svg.area() .x(function(d) { return x(d.xValue); }) .y0(function(d){ return y(d.xValue/2);}) //FUNCTION FOR BASE-Y .y1(function(d) { return y(d.xValue^3); }); //FUNCTION FOR TOP-Y 因此,它实际上是

是否可以在D3中制作一个面积图,在这里我可以指定面积图的楼层(作为另一个图)

大概是这样的:

var area = d3.svg.area()
.x(function(d) { return x(d.xValue); })
.y0(function(d){ return y(d.xValue/2);}) //FUNCTION FOR BASE-Y
.y1(function(d) { return y(d.xValue^3); }); //FUNCTION FOR TOP-Y

因此,它实际上是一个从Y=1.03^X导出的曲线图,而不是楼层始终为Y=0

这是我的代码:

var NSW = "NSW";
var QLD = "QLD";

var width = 600;
var height = 400;
var years = [];

var getStat = function(year, volatility, basis) {
    // volatility = 0.04;
    // basis = 1.11;

    return {
        d: year,
        x: basis,
        vol: volatility,
        value: 45 * Math.pow(basis, year),
        high: 45 * Math.pow(basis+volatility, year),
        low: 45 * Math.pow(basis-volatility, year),
    }
}

for(i = 0; i < 25; i++) {
    years.push(i);
}

var data = years.map(function(year){ return [getStat(year, 0.04, 1.11),getStat(year, 0.02, 1.07)]; });   // generate bogus data
var nsw = data.map(function(d) { return d[0].value;}); // extract new south wales data
var qld = data.map(function(d) { return d[1].value;}); // extract queensland data

var chart = d3.select("#chart").attr("width", width).attr("height", height).append("g");
var x = d3.scale.linear().domain([0, years.length]).range([0, width]);
var y = d3.scale.linear().domain([0, d3.max(data, function(d){ return Math.max(d[0].high, d[1].high); })]).range([height,0]);
var area = d3.svg.area().x(function(d,i) { return x(i); }).y0(height).y1(function(d, i) { return y(d); })

console.log([nsw,qld])

chart
.selectAll("path.area")
.data([nsw,qld])          // !!! here i can pass both arrays in.
.enter()
.append("path")
.attr("fill", "rgba(0,0,0,0.5)")
.attr("class", function(d,i) { return [NSW,QLD][i]; })
.attr("d", area);
var NSW=“NSW”;
var QLD=“QLD”;
var宽度=600;
var高度=400;
风险值年数=[];
var getStat=函数(年、波动率、基础){
//波动率=0.04;
//基准=1.11;
返回{
d:一年,
十:基础,,
卷:波动性,
值:45*Math.pow(基数,年份),
高:45*Math.pow(基差+波动率,年份),
低:45*Math.pow(基准波动率,年份),
}
}
对于(i=0;i<25;i++){
年。推(一);
}
var data=years.map(函数(年){return[getStat(年,0.04,1.11),getStat(年,0.02,1.07)];})生成虚假数据
var nsw=data.map(函数(d){返回d[0].value;});//提取新南威尔士州数据
var qld=data.map(函数(d){返回d[1].value;});//提取昆士兰数据
var chart=d3。选择(“图表”).attr(“宽度”,宽度)。attr(“高度”,高度)。追加(“g”);
var x=d3.scale.linear().domain([0,years.length]).range([0,width]);
var y=d3.scale.linear().domain([0,d3.max(数据,函数(d){return Math.max(d[0].high,d[1].high);})]).range([height,0]);
var area=d3.svg.area().x(函数(d,i){return x(i);}).y0(height).y1(函数(d,i){return y(d);})
console.log([nsw,qld])
图表
.selectAll(“路径区域”)
.数据([nsw,qld])/!!!在这里,我可以传入两个数组。
.输入()
.append(“路径”)
.attr(“填充”、“rgba(0,0,0,0.5)”)
.attr(“类”,函数(d,i){return[NSW,QLD][i];})
.attr(“d”,区域);
和我的HTML:

<svg id="chart"></svg>

以下是一个有助于您理解上下文的示例

var area = d3.svg.area()
.x(function(d) { return x(d.xValue); })
.y0(height)
.y1(function(d) { return y(d.xValue^3); });
现在,当你这样做的时候,基础y0被固定在全高上,这是你现在图表的基础。但从根本上讲,y0和y1都是访问器函数。因此,基本上,对于每个数据值,每次都将height传递给y0。现在,如果你把它改成这样:

var area = d3.svg.area()
.x(function(d) { return x(d.xValue); })
.y0(function(d){ return y(d.xValue/2);}) //FUNCTION FOR BASE-Y
.y1(function(d) { return y(d.xValue^3); }); //FUNCTION FOR TOP-Y
现在理想情况下,你的面积图的底部会相应地变化。我希望这能帮助你实现你正在尝试的目标。如果解决方案没有按预期效果,请告诉我。如果需要的话,我会做一把小提琴

编辑:为了响应问题中的更改,要绘制的每个区域都必须有自己的功能。现在,这将需要您编写多个面积函数,这些函数仅适用于一个或两个面积。然而,如果你打算用多种颜色的区域填充整个图表,我相信你需要先使用这个

在概念中,堆栈布局重新排列您的数据,以便返回的布局对象基本上包含多个数组(我说数组是因为它使您在编写映射函数时更容易理解实际结构)。现在,您需要一个单一的区域函数,可以在返回的布局中对每个实例进行迭代调用。对于每个实例,我指的是不同的数组,当传递到area函数时,这些数组会产生不同的区域。我希望我的解释能有所帮助,但我自己对该主题还是比较陌生的,因此下面的示例将有所帮助:

这是实现这一点的理想方法,如果你不介意一个简单的解决方法,那么这就是我目前正在做的:说现在,而不仅仅是[nsw,qld],你想为[nsw1,qld1],[nsw2,qld2],……绘制区域

iterationData = [[nsw,qld],[nsw1,qld1],[nsw2,qld2],........];
for(i in iterationData){
    chart
    .data(iterationData[i])
    .append("path")
    .attr("fill", "fixed_color_value/color_scale(category10/category20)")
    .attr("class", function(d,i) { return [NSW,QLD][i]; })
    .attr("d", area);
}

希望这能彻底回答您的问题。

只需先绘制原始图表,然后在上面绘制一个白色背景色的图表,就可以在视觉上获得相同的外观。@SpencerWieczorek我计划在彼此的顶部进行多个重叠,因此最好将地板标记抬高。太棒了!我想这是可行的。我如何调整y0和y1以适应多个绘图?我已经修改了我的问题,以显示我正在使用的确切代码。它可以很好地处理单个绘图。我只是对我会如何对待别人感到困惑。@Akshat为了回应你的编辑,我已经尽我所能详细回答了。希望这是有帮助的。