更新形状属性时的对象一致性
Object Consistency when updating shape attributes
我是D3和Javascript的新手,所以如果我的代码看起来有点丑或组织不好,请原谅我。
我一直在研究一个利用3个指标的绘图:x轴和y轴,以及圆的半径作为绘图的数据指标。我正在读取的数据是一个二维数组,每一行是一个不同的度量,每一列是一个新的数据点。我已经成功地实现了一种方法,通过从下拉框中选择不同的度量来动态地改变圆的半径,但这是在与一个非常特殊的问题进行无休止的斗争之后-我的数据被分配到错误的圆!
当我最初创建我的圆圈时,我首先使用sort()从默认半径度量(在我的代码中,它的"impactcpu")降序排序圆圈。这样做是为了解决一个问题,即在较小的圆圈之后绘制较大的圆圈会阻碍较小的圆圈,所以我想先"绘制"最大的圆圈。
我能够解决这个问题,首先排序我的计算数据数组,然后将其分配给圆圈,这保留了默认的顺序。然而,我现在尝试对X轴和Y轴做类似的事情。虽然我的下拉菜单是正确分配公制值的圆圈,它是这样做的错误的圆圈。我还没有找到解决这个问题的方法,因为在分配之前重新排序数组就像我为半径做的那样不起作用(这是我所期望的)。有什么建议,我如何才能确保正确的数据点分配到正确的圆?最好是一个不需要修改我其余代码的代码:)
请查看我的jsfiddle,以了解我的上述情况:
http://jsfiddle.net/kingernest/YDQR4/3/创建圆圈的例子:
var circles = svg.selectAll("circle")
.data(dataset, function(d) { return d.id })
.enter()
.append("circle")
.sort(function(a, b){ //Sort by radius size, helps reduce obstruction of circles
return d3.descending(a[14], b[14]);
})
.attr("cx", function(d){ //x axis is Req IO, col index 9
return xScale(d[9]);
})
.attr("cy", function(d){ //y axis is Req CPU, col index 8
return yScale(d[8]);
})
.attr("r", function(d){ //radius is based off Impact CPU, col 14
console.log("Rad: " + d[14])
return d[14] * 1.5;
})
.attr("class", "dataCircle")
等我当前如何改变我的半径:
function changeRad() {
console.log(this.value);
var myRadData = [];
var index = metricHash[this.value];
var weight; //to adjust data to fit appropriately in graph
switch(this.value)
{
case "impactcpu":
weight = 1.5;
break;
case "spool":
weight = .0000001; //spool is normally a very large value
break;
case "pji":
weight = 8;
break;
case "unnecio":
weight = 12;
break;
case "duration":
weight = .0002;
break;
default: alert("Invalid value: " + this.value);
break;
}
for(var i=0; i < dataset.length; i++)
{
console.log(dataset[i][index]);
myRadData.push(dataset[i][index] * weight);
}
myRadData.sort(function(a,b){return b-a});
d3.selectAll("circle")
.data(myRadData)
.transition().duration(500)
.attr("r", function(d){
return d;
});
circles.data(dataset); //reassign old data set (with all data values)
}
我在你的代码中看到了两件事:
-
数据绑定上不一致的键函数-您在初始创建圆圈(
.data(dataset, function(d) { return d.id })
)时正确使用它,但在更新它们时不要引用它,在更新上添加相同的键将确保您更新相同的元素。 -
DOM排序-选择的使用。排序时,最初创建您的圈子似乎合乎逻辑和适当的(
.sort(function(a, b){ return d3.descending(a[14], b[14]); })
),我建议将此扩展到您的更新功能,而不是重新绑定数据。
我已经对你的代码进行了这些快速更新,它似乎解决了你的问题:http://jsfiddle.net/AbHfk/3/
我不确定我是否掌握了您的整个代码(它相当长),但我认为解决方案是沿着这些行:
1 -当您最初创建圆圈时,使用keys函数。很好,你在这样做:
.data(dataset, function(d) { return d.id; })
2 -使用相同的函数给圆圈一个ID属性:
.attr("ID", function(d) { return d.id; })
3 -然后当你需要单独修改一个特定的圆时,你可以像这样选择它:
svg.select('#' + myCircleID).attr('blahblah', somevalue)
我还注意到,在构建myRadData数组时丢失了ID属性。这将阻止代码将它们连接到正确的圆圈上。由于一开始就有一个ID属性,因此最好始终使用keys函数,而不是尝试使用排序来使内容排列。
如果你想要一个更具体的答案,我认为你需要把这个例子浓缩成尽可能简单的形式来再现这个问题。
- 引用对象中的通用值
- jQuery匹配JSON对象的部分文本
- 节点导出返回一个空对象
- 如何在Javascript中将JSon对象转换为数组
- 我可以在json对象中添加一个函数吗
- 使用JS将数组转换为json对象
- 全局变量和全局对象的属性之间有什么区别吗
- 比较从函数和生成的日期对象
- Javascript,访问一个主要对象模块模式中的每个对象
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- 调整窗口大小时,可拖动的对象会出现在容器外部
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何使用json将对象列表从java转换为javascript
- 序列化数据属性中对象的最可靠方法
- 如何访问声音管理器2创建的声音对象
- FabricJs-限制主对象内添加对象的移动区域
- Javascript(Angular)从一个对象数组到第二个数组查找值
- 值对象在某个变量发生更改后发生更改
- 如何为json对象中的段发送array[]
- 更新形状属性时的对象一致性