[英]How do i change the styling of a nodes CSS through javascript(d3)
這是我的CSS
.node.selectedNode {
width:50px;
height:50px;
stroke-width: 3px;
stroke: #f00;
}
.node.unselectedNode {
width:35px;
height:35px;
stroke-width: 3px;
stroke: #000;
}
我想單擊一個使其選定的節點(為它提供選定的屬性),再次單擊並使其未選定。 這是一段代碼,我在其中檢查節點的id是否在數組中,如果不是,它也會添加它,這使我能夠輕松打印出選定的節點。
if(selectedNodesArray.indexOf(d.coreId)==-1){
selectedNodesArray.push(d.coreId);
d.selectedNode = true; //change style
d.unselectedNode = false;
d3.select(this).classed("selectedNode", true);
console.log("clicked");
}else{
selectedNodesArray.pop(d.coreId);
d.unselectedNode = true;
d.selectedNode = false;
d3.select(this).classed("unselectedNode", true);
console.log("pulled");
}
您可能會注意到,我嘗試更改樣式。 現在,它可以工作兩次; 當我選擇它和當我取消選擇它時。 在那之后它不再起作用。 有任何想法嗎 ?
另外,我創建了一個按鈕,以便清除所有突出顯示的節點。 就像我在這里一樣,當我單擊節點時,它將其屬性更改為固定
function dragstart(d) {
d.fixed = true;
d3.select(this).classed("fixed", true);
我想在單擊按鈕時執行此操作,因此它會更改節點的css屬性。 我不知道如何挑選所有節點並將它們賦予相同的css屬性,而不是通過D3並以這種方式更改.style。
抱歉,我的論文長篇大論,我只想為您提供盡可能多的細節,使每個人都更容易。
看來您做得差不多。 問題是您的代碼假定未在節點上調用.classed("selectedNode", true)
導致該節點.selectedNode
應用.selectedNode
類。 但是實際上(您將可以在瀏覽器開發人員工具的“元素”面板中看到此內容),如果取消選擇節點,則該節點將具有.unselectedNode
但也具有.selectedNode
,因為不會刪除.selectedNode
類。 而且,任何后續的選擇/取消選擇操作都不會再修改內容,因為該節點已經具有兩個類。
因此,您需要在每次發生交互時通過調用以下方法刪除不適用的類:
d3.select(this).classed("selectedNode", false);
和
d3.select(this).classed("unselectedNode", false);
在適當的地方。 這樣就可以了。
但是現在您有機會重構某些東西。
首先,我的建議是完全忘記unselectedNode
類,而僅使用類.node
設置取消選中狀態的樣式。 這樣,您將只有一個selectedNode
類,該類是默認樣式的修飾符,並且您的代碼將更簡單。
最后,我猜您正在使用力布局,因此您已經有了tick()
函數或類似的東西,每秒可以更新所有節點很多次。 因此,將所有內容放在一起,就可以在該方法中執行以下操作:
var selectedNodesArray = [];
function tick() {
var nodes = d3.selectAll('.node').data(force.nodes);
// ENTER
nodes.enter()
.append('circle')// or 'rect' or whatever
.attr('class', 'node')
.on('click', function(d) {
// here you set the selected-ness, but not the visual representation
d.selectedNode = !d.selectedNode; // flip the selected-ness from true->false or vice versa
console.log(d.selectedNode ? "clicked" : "pulled");
// here you manage the array
if(!d.selectedNode) {
// note that pop() is actually unsafe here, bc it
// removes the last-selected node, but what if you
// deselect something from 2 clicks ago?
selectedNodesArray.pop();
}
else {
// Here I recommend pushing d, instead of its d.coreId, because
// then you can use this array to get the actual datums of the
// selectedNodes, rather than just their id
selectedNodesArray.push(d);
}
})
...// do whatever else you need to do to the entering nodes
// UPDATE
nodes
// Here you take care of the representation of selected-ness
.classed('selectedNode', function(d) {
return d.selectedNode
// or: return selectedNodesArray.indexOf(d)==-1
})
// do whatever else you need to do to the updating nodes (position, etc)
}
關於您的第二個問題:我不確定您到底在問什么,但是我認為,如果您將tick()
方法視為基於僅數據模型或狀態(例如, selectedNodesArray
更新表示形式的東西,或d.selectedNode
),那么任何交互都可以修改該狀態,並讓tick()
加快表示速度。 例如,這是一種取消選擇所有內容的批量方法:
// loop through the array and set selected to `false`
selectedNodesArray.forEach(function(d) {
d.selectedNode = false;
})
selectedNodesArray = [];// clear the array
tick();// To update the visuals
最后一件事:在兩個位置( selectedNodesArray
和d.selectedNode
)維護有關selectedness的信息d.selectedNode
。 如果您可以選擇並使用這兩種方式中的一種來表示選定狀態,則前進的時間會更容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.