Javascript SVG和d3:在数据坐标中绘制基本矩形?
我正在尝试学习d3来构建可视化;作为这个项目的一部分,我发现我需要画一些填充矩形。这在SVG坐标中应该很简单,但我想在数据坐标中绘制。我无法理解为什么会在画布之外绘制任何矩形,但我在这里的最小(非)工作示例中观察到了这一点: 粉色矩形实际上超出了SVG元素的边界,如果我正确设置了x和y映射,这就没有意义了。是否有我没有使用过的绘制数据坐标的技巧,或者比例配置不正确?我尝试过向上改变y比例参数(范围和域),但没有成功;以相同的方式设置的x比例似乎能按预期工作Javascript SVG和d3:在数据坐标中绘制基本矩形?,javascript,d3.js,svg,Javascript,D3.js,Svg,我正在尝试学习d3来构建可视化;作为这个项目的一部分,我发现我需要画一些填充矩形。这在SVG坐标中应该很简单,但我想在数据坐标中绘制。我无法理解为什么会在画布之外绘制任何矩形,但我在这里的最小(非)工作示例中观察到了这一点: 粉色矩形实际上超出了SVG元素的边界,如果我正确设置了x和y映射,这就没有意义了。是否有我没有使用过的绘制数据坐标的技巧,或者比例配置不正确?我尝试过向上改变y比例参数(范围和域),但没有成功;以相同的方式设置的x比例似乎能按预期工作 提前感谢您的帮助。请记住,svg坐标从
提前感谢您的帮助。请记住,svg坐标从顶部开始,高度向下延伸矩形。如果替换此行:
.attr("y", function(d) { return y(d.y0); })
与
你会得到一些看起来更合适的东西
以y坐标为y1:2和y0:0的矩形为例。此矩形用于填充svg的整个高度。使用您的秤:
var y = d3.scaleLinear().rangeRound([height, 0]).domain([0., 2.]);
var y = d3.scaleLinear().rangeRound([0, height]).domain([0., 2.]);
您的y位置:
.attr("y", function(d) { return y(d.y0); })
您将把这个矩形的顶部放在svg的底部。对于输入y值为0,标尺将返回一个等于高度的值。svg y坐标为高度的任何对象都位于svg的底部
矩形的高度也将等于高度
,因此矩形将向下延伸离开svg(部分矩形将可见,因为使用代码的边距)
相反,这个矩形应该出现在顶部,并一直向下延伸,为了做到这一点,从高度
中减去缩放值,矩形将出现在svg的顶部
如果希望输入y值为零显示在屏幕底部,而不是顶部(对于更典型的笛卡尔设置,取消SVG约定),则需要对比例进行一些更改:
var y = d3.scaleLinear().rangeRound([height, 0]).domain([0., 2.]);
var y = d3.scaleLinear().rangeRound([0, height]).domain([0., 2.]);
身高:
.attr("height", function(d) { return y(d.y1) - y(d.y0); })
并对其进行更改,以便将顶部坐标放置在矩形的顶部:
.attr("y", function(d) { return y(d.y1); })
在本回答中,我将不讨论坐标问题,该问题已在中介绍,但我将给您两个重要建议:
不要将jQuery和D3混用:这不仅是不必要的,而且有时还会破坏某些东西。只要去掉jQuery代码就行了
不要使用循环绑定数据:使用D3惯用数据绑定
关于第2点,由于您的数据是一个对象,data
方法不接受对象,所以让我们将其转换为一个数组
var dataArray = [];
for (var key in data) {
dataArray.push({
category: key,
y1: data[key][0].y1,
y0: data[key][0].y0,
x1: data[key][0].x1,
x0: data[key][0].x0,
})
}
。。。我们可以使用它以惯用方式绑定数据:
g.selectAll(null)
.data(dataArray)
.enter()
.append("rect")
以下是您的代码和这些更改:
风险值数据={
“第1类”:[{
“y1”:1.581699235490658,
“y0”:0.812416240209036,
“x0”:0.0003786444528587656,
“x1”:0.235138202529344
}],
“第二类”:[{
“y1”:1.438932516124979,
“y0”:0.7292493003174502,
“x0”:0.0003786444528587656,
“x1”:0.3029155622870125
}, {
“y1”:0.816326356719349,
“y0”:0.7577181178689592,
“x0”:0.471790988262022,
“x1”:1.0
}],
“第三类”:[{
“y1”:1.04308128481062,
“y0”:0.5216497481615152,
“x0”:0.0,
“x1”:0.3029155622870125
}, {
“y1”:1.27967372400311,
“y0”:0.544378022140943,
“x0”:0.471790988262022,
“x1”:1.0
}],
“第四类”:[{
“y1”:0.8577183187799378,
“y0”:0.550780327785857598,
“x0”:0.44377129875047333,
“x1”:0.4714123438091632
}],
“第五类”:[{
“y1”:1.411106314679798,
“y0”:0.6447611230842676,
“x0”:0.3032942067398713,
“x1”:0.4714123438091632
}],
“第六类”:[{
“y1”:0.9875866563383724,
“y0”:0.5832528539336078,
“x0”:0.2355168496781522,
“x1”:1.0
}],
“第七类”:[{
“y1”:1.2362146708036688,
“y0”:0.2743087520017313,
“x0”:0.3032942067398713,
“x1”:0.44339265429761454
}]
};
var dataArray=[];
for(var输入数据){
dataArray.push({
类别:重点,,
y1:数据[键][0]。y1,
y0:数据[键][0]。y0,
x1:数据[键][0].x1,
x0:数据[键][0].x0,
})
}
//定义图形窗格的尺寸
var保证金={
前30名,
右:30,,
底数:30,
左:30
};
变量宽度=400-margin.left-margin.right;
变量高度=200-margin.top-margin.bottom;
//定义比例
var x=d3.scaleLinear().rangeRound([0,width]).domain([0,1.]);
var y=d3.scaleLinear().rangeRound([0,height]).domain([0,2.]);
Varz=d3.scaleOrdinal(d3.schemeCategory10);
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部);
var g=svg.append(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
g、 选择全部(空)。数据(dataArray)。输入()
.append(“rect”)
.attr(“x”,函数(d){
返回x(d.x0);
})
.attr(“y”,函数(d){
返回y(d.y0);
})
.attr(“宽度”,函数(d){
返回x(d.x1)-x(d.x0);
})
.attr(“高度”,功能(d){
返回y(d.y1)-y(d.y0);
})
.attr(“填充”,功能(d){
返回z(d类);
});
一如既往,这是非常有用的信息。不必要的jquery和d3组合总是让我在里面有点畏缩,就像附加特性的循环一样。的确如此。每次有人将jQuery与D3混合时,熊猫就会死亡。