2017-07-20 86 views
1

你能幫我解釋爲什麼這樣不能正常工作嗎?D3.js onclick切換其他線色

這是一個物理演示,它的概念是,我可以改變線的顏色,如果我點擊它,當我點擊一個矩形我想改變所有的邊(線周圍)顏色,並總是改變爲其他顏色。所以線條是白色或紅色,只有線條顏色改變,我可以點擊線條或矩形。這段代碼幾乎效果不錯。

兩個問題留給:

  1. 如果點擊矩形兩側改變顏色爲紅色,但不回來,如果前

  2. 1線是紅色的它不會更改爲白色

我希望我是清楚的,這裏是我堅持:

// grid basic variables 
 
var dimension = 10, 
 
\t width = 50, 
 
\t height = 50; 
 

 
function gridData() { 
 
\t var data = new Array(); 
 

 
\t // rectangle variables 
 
\t var rectXpos = 0, 
 
\t \t rectYpos = 0, 
 
\t \t rectWidth = width, 
 
\t \t rectHeight = height; 
 
\t \t click = 0; 
 

 
\t // iterate for rows 
 
\t for (var row = 0; row < dimension; row++) { 
 

 
\t \t // iterate for cells/columns inside rows 
 
\t \t for (var column = 0; column < dimension; column++) { 
 
\t \t \t // rectClass = "rect" + rectXpos.toString() + rectYpos.toString(); 
 
\t \t \t data.push({ 
 
\t \t \t \t x: rectXpos, 
 
\t \t \t \t y: rectYpos, 
 
\t \t \t \t width: rectWidth, 
 
\t \t \t \t height: rectHeight, 
 
\t \t \t \t // class: rectClass, 
 
\t \t \t \t click: click 
 
\t \t \t }); 
 

 
\t \t \t // increment the x position. I.e. move it over by 50 (width variable) 
 
\t \t \t rectXpos += rectWidth; 
 
\t \t } 
 
\t \t // reset the x position after a row is complete 
 
\t \t rectXpos = 0; 
 
\t \t // increment the y position for the next row. Move it down 50 (height variable) 
 
\t \t rectYpos += rectHeight; 
 
\t } 
 
\t return data; 
 
} 
 

 
var gridData = gridData(); 
 
// I like to log the data to the console for quick debugging 
 
console.log(gridData); 
 

 
var grid = d3.select("#grid") 
 
\t .append("svg") 
 
\t .attr("width", width*dimension) 
 
\t .attr("height",height*dimension); 
 

 
var rect = grid.selectAll(".square") 
 
\t .data(gridData) 
 
\t .enter().append("rect") 
 
\t .attr("class","rect") 
 
\t .attr("x", function(d) { return d.x; }) 
 
\t .attr("y", function(d) { return d.y; }) 
 
\t .attr("width", function(d) { return d.width; }) 
 
\t .attr("height", function(d) { return d.height; }) 
 
\t .style("fill", "#f2f2f2") 
 
\t .style("stroke", "#fff") 
 
\t .on("click", function(d){ 
 
\t \t d.click ++; 
 
\t \t var nextColor = (this.style.stroke == "red") ? "white" : "red"; 
 
\t \t d3.select(".vline" + d.x.toString() + d.y.toString() + (d.x + 50).toString() + d.y.toString()).style("stroke", nextColor); 
 
\t \t d3.select(".vline" + d.x.toString() + (d.y + 50).toString() + (d.x + 50).toString() + (d.y + 50).toString()).style("stroke", nextColor); 
 
\t \t d3.select(".hline" + d.x.toString() + d.y.toString() + d.x.toString() + (d.y + 50).toString()).style("stroke", nextColor); 
 
\t \t d3.select(".hline" + (d.x + 50).toString() + d.y.toString() + (d.x + 50).toString() + (d.y + 50).toString()).style("stroke", nextColor); 
 
\t }); 
 

 
function hlinegriddata() { 
 
\t var data = new Array(); 
 

 
\t // line variables 
 
\t var hlineX1 = 0, 
 
\t \t hlineY1 = 0, 
 
\t \t hlineX2 = 0, 
 
\t \t hlineY2 = 50, 
 
\t \t click = 0; 
 

 
\t var lineLength = width; 
 

 
\t for (var row = 0; row < dimension; row++) { 
 

 
\t \t // iterate for cells/columns inside rows 
 
\t \t for (var column = 0; column < dimension + 1; column++) { 
 
\t \t \t hlineClass = "hline" + hlineX1.toString() + hlineY1.toString() + hlineX2.toString() + hlineY2.toString(); 
 
\t \t \t data.push({ 
 
\t \t \t \t x1: hlineX1, 
 
\t \t \t \t y1: hlineY1, 
 
\t \t \t \t x2: hlineX2, 
 
\t \t \t \t y2: hlineY2, 
 
\t \t \t \t class: hlineClass, 
 
\t \t \t \t click: click 
 
\t \t \t }); 
 

 
\t \t  // increment the x position for the next line 
 
\t \t  hlineX1 += lineLength; 
 
\t \t  hlineX2 += lineLength; 
 
\t \t } 
 

 
\t \t // reset the x position after a row is complete 
 
\t \t hlineX1 = 0; 
 
\t \t hlineX2 = 0; 
 

 
\t \t // increment the y position for the next row. Move it down 50 (height variable) 
 
\t \t hlineY1 += lineLength; 
 
\t \t hlineY2 += lineLength; 
 
\t } 
 
\t return data; 
 
} 
 

 
var hlinegriddata = hlinegriddata(); 
 
// I like to log the data to the console for quick debugging 
 
console.log(hlinegriddata); 
 

 
var hline = grid.selectAll(".hline") 
 
\t .data(hlinegriddata) 
 
\t .enter().append("line") 
 
\t .attr("class", function(d) { return d.class; }) 
 
\t .attr("x1", function(d) { return d.x1; }) 
 
\t .attr("y1", function(d) { return d.y1; }) 
 
\t .attr("x2", function(d) { return d.x2; }) 
 
\t .attr("y2", function(d) { return d.y2; }) 
 
\t .style("stroke", "white") 
 
\t .style("stroke-width", "4") 
 
\t .style("cursor", "pointer") 
 
\t .on("click", function(){var nextColor = this.style.stroke == "white" ? "red" : "white"; 
 
      d3.select(this).style("stroke", nextColor); 
 
\t }); 
 
\t // .on('click', function(d) { 
 
\t // \t d.click ++; 
 
    // if ((d.click)%2 == 0) { d3.select(this).style("stroke","#fff"); } 
 
\t // if ((d.click)%2 == 1) { d3.select(this).style("stroke","red"); } 
 
    // }); 
 

 
function vlinegriddata() { 
 
\t var data = new Array(); 
 

 
\t // line variables 
 
\t var vlineX1 = 0, 
 
\t \t vlineY1 = 0, 
 
\t \t vlineX2 = 50, 
 
\t \t vlineY2 = 0, 
 
\t \t click = 0; 
 

 
\t var lineLength = width; 
 

 
\t // iterate for rows 
 
\t for (var row = 0; row < dimension; row++) { 
 

 
\t \t // iterate for cells/columns inside rows 
 
\t \t for (var column = 0; column < dimension + 1; column++) { 
 
\t \t \t vlineClass = "vline" + vlineX1.toString() + vlineY1.toString() + vlineX2.toString() + vlineY2.toString(); 
 
\t \t \t data.push({ 
 
\t \t \t \t x1: vlineX1, 
 
\t \t \t \t y1: vlineY1, 
 
\t \t \t \t x2: vlineX2, 
 
\t \t \t \t y2: vlineY2, 
 
\t \t \t \t class: vlineClass, 
 
\t \t \t \t click: click 
 
\t \t \t }); 
 

 
\t \t  // increment the x position for the next line 
 
\t \t  vlineY1 += lineLength; 
 
\t \t  vlineY2 += lineLength; 
 
\t \t } 
 

 
\t \t // reset the x position after a row is complete 
 
\t \t vlineY1 = 0; 
 
\t \t vlineY2 = 0; 
 
\t \t // increment the y position for the next row. Move it down 50 (height variable) 
 
\t \t vlineX1 += lineLength; 
 
\t \t vlineX2 += lineLength; 
 
\t } 
 
\t return data; 
 
} 
 

 
var vlinegriddata = vlinegriddata(); 
 
// I like to log the data to the console for quick debugging 
 
console.log(vlinegriddata); 
 

 
var vline = grid.selectAll(".vline") 
 
\t .data(vlinegriddata) 
 
\t .enter().append("line") 
 
\t .attr("class", function(d) { return d.class; }) 
 
\t .attr("x1", function(d) { return d.x1; }) 
 
\t .attr("y1", function(d) { return d.y1; }) 
 
\t .attr("x2", function(d) { return d.x2; }) 
 
\t .attr("y2", function(d) { return d.y2; }) 
 
\t .attr("click", function(d) { return d.click; }) 
 
\t .style("stroke", "white") 
 
\t .style("stroke-width", "4") 
 
\t .style("cursor", "pointer") 
 
\t .on("click", function(){var nextColor = this.style.stroke == "white" ? "red" : "white"; 
 
      d3.select(this).style("stroke", nextColor); 
 
\t }); 
 
\t // .on('click', function(d) { 
 
    // d.click ++; 
 
    // if ((d.click)%2 == 0) { d3.select(this).style("stroke","#fff"); } 
 
\t // if ((d.click)%2 == 1) { d3.select(this).style("stroke","red"); } 
 
    // });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
<div id="grid"></div>

回答

0

行添加selected.each()

hline 
    .each(function(d){ 
     d.switch = 0; 
    }) 
vline 
    .each(function(d){ 
     d.switch = 0; 
    }) 

線變化。對( 「點擊」)

hline 
    .on("click",function(d){ 
     var Color = ["white","red"]; 
     //switch ===> 0 or 1 
     d.switch = d.switch^1; 
     //color ===> "white" or "red" 
     var nextColor = Color[d.switch]; 
     d3.select(this).style("stroke", nextColor); 
    }) 

vline 
    .on("click",function(d){ 
     var Color = ["white","red"]; 
     //switch ===> 0 or 1 
     d.switch = d.switch^1; 
     //color ===> "white" or "red" 
     var nextColor = Color[d.switch]; 
     d3.select(this).style("stroke", nextColor); 
    }) 

RECT變化:

rect 
.on("click", function(d){ 
    var Color = ["white" , "red"]; 
    d3.select(".vline" + d.x.toString() + d.y.toString() + (d.x + 50).toString() + d.y.toString()).style("stroke", Next_Color); 
    d3.select(".vline" + d.x.toString() + (d.y + 50).toString() + (d.x + 50).toString() + (d.y + 50).toString()).style("stroke", Next_Color); 
    d3.select(".hline" + d.x.toString() + d.y.toString() + d.x.toString() + (d.y + 50).toString()).style("stroke", Next_Color); 
    d3.select(".hline" + (d.x + 50).toString() + d.y.toString() + (d.x + 50).toString() + (d.y + 50).toString()).style("stroke", Next_Color); 
    function Next_Color(d){ 
     var Color = ["white","red"]; 
     d.switch = d.switch^1; 
     var next_Color = Color[d.switch]; 
     return next_Color; 
    } 
}); 

實施例

// grid basic variables 
 
var dimension = 10, 
 
\t width = 50, 
 
\t height = 50; 
 

 
function gridData() { 
 
\t var data = new Array(); 
 

 
\t // rectangle variables 
 
\t var rectXpos = 0, 
 
\t \t rectYpos = 0, 
 
\t \t rectWidth = width, 
 
\t \t rectHeight = height; 
 
\t \t click = 0; 
 

 
\t // iterate for rows 
 
\t for (var row = 0; row < dimension; row++) { 
 

 
\t \t // iterate for cells/columns inside rows 
 
\t \t for (var column = 0; column < dimension; column++) { 
 
\t \t \t // rectClass = "rect" + rectXpos.toString() + rectYpos.toString(); 
 
\t \t \t data.push({ 
 
\t \t \t \t x: rectXpos, 
 
\t \t \t \t y: rectYpos, 
 
\t \t \t \t width: rectWidth, 
 
\t \t \t \t height: rectHeight, 
 
\t \t \t \t // class: rectClass, 
 
\t \t \t \t click: click 
 
\t \t \t }); 
 

 
\t \t \t // increment the x position. I.e. move it over by 50 (width variable) 
 
\t \t \t rectXpos += rectWidth; 
 
\t \t } 
 
\t \t // reset the x position after a row is complete 
 
\t \t rectXpos = 0; 
 
\t \t // increment the y position for the next row. Move it down 50 (height variable) 
 
\t \t rectYpos += rectHeight; 
 
\t } 
 
\t return data; 
 
} 
 

 
var gridData = gridData(); 
 
// I like to log the data to the console for quick debugging 
 
console.log(gridData); 
 

 
var grid = d3.select("#grid") 
 
\t .append("svg") 
 
\t .attr("width", width*dimension) 
 
\t .attr("height",height*dimension); 
 

 
var rect = grid.selectAll(".square") 
 
\t .data(gridData) 
 
\t .enter().append("rect") 
 
\t .attr("class","rect") 
 
\t .attr("x", function(d) { return d.x; }) 
 
\t .attr("y", function(d) { return d.y; }) 
 
\t .attr("width", function(d) { return d.width; }) 
 
\t .attr("height", function(d) { return d.height; }) 
 
\t .style("fill", "#f2f2f2") 
 
\t .style("stroke", "#fff") 
 
\t .on("click", function(d){ 
 
\t \t var Color = ["white" , "red"]; 
 
\t \t d3.select(".vline" + d.x.toString() + d.y.toString() + (d.x + 50).toString() + d.y.toString()).style("stroke", Next_Color); 
 
\t \t d3.select(".vline" + d.x.toString() + (d.y + 50).toString() + (d.x + 50).toString() + (d.y + 50).toString()).style("stroke", Next_Color); 
 
\t \t d3.select(".hline" + d.x.toString() + d.y.toString() + d.x.toString() + (d.y + 50).toString()).style("stroke", Next_Color); 
 
\t \t d3.select(".hline" + (d.x + 50).toString() + d.y.toString() + (d.x + 50).toString() + (d.y + 50).toString()).style("stroke", Next_Color); 
 

 

 
     function Next_Color(d){ 
 
      var Color = ["white","red"]; 
 
      d.switch = d.switch^1; 
 
      var next_Color = Color[d.switch]; 
 
      return next_Color; 
 
     } 
 
\t }); 
 

 
function hlinegriddata() { 
 
\t var data = new Array(); 
 

 
\t // line variables 
 
\t var hlineX1 = 0, 
 
\t \t hlineY1 = 0, 
 
\t \t hlineX2 = 0, 
 
\t \t hlineY2 = 50, 
 
\t \t click = 0; 
 

 
\t var lineLength = width; 
 

 
\t for (var row = 0; row < dimension; row++) { 
 

 
\t \t // iterate for cells/columns inside rows 
 
\t \t for (var column = 0; column < dimension + 1; column++) { 
 
\t \t \t hlineClass = "hline" + hlineX1.toString() + hlineY1.toString() + hlineX2.toString() + hlineY2.toString(); 
 
\t \t \t data.push({ 
 
\t \t \t \t x1: hlineX1, 
 
\t \t \t \t y1: hlineY1, 
 
\t \t \t \t x2: hlineX2, 
 
\t \t \t \t y2: hlineY2, 
 
\t \t \t \t class: hlineClass, 
 
\t \t \t \t click: click 
 
\t \t \t }); 
 

 
\t \t  // increment the x position for the next line 
 
\t \t  hlineX1 += lineLength; 
 
\t \t  hlineX2 += lineLength; 
 
\t \t } 
 

 
\t \t // reset the x position after a row is complete 
 
\t \t hlineX1 = 0; 
 
\t \t hlineX2 = 0; 
 

 
\t \t // increment the y position for the next row. Move it down 50 (height variable) 
 
\t \t hlineY1 += lineLength; 
 
\t \t hlineY2 += lineLength; 
 
\t } 
 
\t return data; 
 
} 
 

 
var hlinegriddata = hlinegriddata(); 
 
// I like to log the data to the console for quick debugging 
 
console.log(hlinegriddata); 
 

 
var hline = grid.selectAll(".hline") 
 
\t .data(hlinegriddata) 
 
\t .enter().append("line") 
 
\t .attr("class", function(d) { return d.class; }) 
 
\t .attr("x1", function(d) { return d.x1; }) 
 
\t .attr("y1", function(d) { return d.y1; }) 
 
\t .attr("x2", function(d) { return d.x2; }) 
 
\t .attr("y2", function(d) { return d.y2; }) 
 
\t .style("stroke", "white") 
 
\t .style("stroke-width", "4") 
 
\t .style("cursor", "pointer") 
 
    .each(function(d){ 
 
     d.switch = 0; 
 
    }) 
 
\t .on("click", function(d){ 
 
     var Color = ["white","red"]; 
 
     d.switch = d.switch^1; 
 
     var nextColor = Color[d.switch]; 
 
     d3.select(this).style("stroke", nextColor); 
 
\t }); 
 
\t // .on('click', function(d) { 
 
\t // \t d.click ++; 
 
    // if ((d.click)%2 == 0) { d3.select(this).style("stroke","#fff"); } 
 
\t // if ((d.click)%2 == 1) { d3.select(this).style("stroke","red"); } 
 
    // }); 
 

 
function vlinegriddata() { 
 
\t var data = new Array(); 
 

 
\t // line variables 
 
\t var vlineX1 = 0, 
 
\t \t vlineY1 = 0, 
 
\t \t vlineX2 = 50, 
 
\t \t vlineY2 = 0, 
 
\t \t click = 0; 
 

 
\t var lineLength = width; 
 

 
\t // iterate for rows 
 
\t for (var row = 0; row < dimension; row++) { 
 

 
\t \t // iterate for cells/columns inside rows 
 
\t \t for (var column = 0; column < dimension + 1; column++) { 
 
\t \t \t vlineClass = "vline" + vlineX1.toString() + vlineY1.toString() + vlineX2.toString() + vlineY2.toString(); 
 
\t \t \t data.push({ 
 
\t \t \t \t x1: vlineX1, 
 
\t \t \t \t y1: vlineY1, 
 
\t \t \t \t x2: vlineX2, 
 
\t \t \t \t y2: vlineY2, 
 
\t \t \t \t class: vlineClass, 
 
\t \t \t \t click: click 
 
\t \t \t }); 
 

 
\t \t  // increment the x position for the next line 
 
\t \t  vlineY1 += lineLength; 
 
\t \t  vlineY2 += lineLength; 
 
\t \t } 
 

 
\t \t // reset the x position after a row is complete 
 
\t \t vlineY1 = 0; 
 
\t \t vlineY2 = 0; 
 
\t \t // increment the y position for the next row. Move it down 50 (height variable) 
 
\t \t vlineX1 += lineLength; 
 
\t \t vlineX2 += lineLength; 
 
\t } 
 
\t return data; 
 
} 
 

 
var vlinegriddata = vlinegriddata(); 
 
// I like to log the data to the console for quick debugging 
 
console.log(vlinegriddata); 
 

 
var vline = grid.selectAll(".vline") 
 
\t .data(vlinegriddata) 
 
\t .enter().append("line") 
 
\t .attr("class", function(d) { return d.class; }) 
 
\t .attr("x1", function(d) { return d.x1; }) 
 
\t .attr("y1", function(d) { return d.y1; }) 
 
\t .attr("x2", function(d) { return d.x2; }) 
 
\t .attr("y2", function(d) { return d.y2; }) 
 
\t .attr("click", function(d) { return d.click; }) 
 
\t .style("stroke", "white") 
 
\t .style("stroke-width", "4") 
 
\t .style("cursor", "pointer") 
 
    .each(function(d){ 
 
     d.switch = 0; 
 
    }) 
 
\t .on("click", function(d){ 
 
     var Color = ["white","red"]; 
 
     d.switch = d.switch^1; 
 
     var nextColor = Color[d.switch]; 
 
     d3.select(this).style("stroke", nextColor); 
 
     //var nextColor = this.style.stroke == "white" ? "red" : "white"; 
 
     //d3.select(this).style("stroke", nextColor); 
 
\t }); 
 
\t // .on('click', function(d) { 
 
    // d.click ++; 
 
    // if ((d.click)%2 == 0) { d3.select(this).style("stroke","#fff"); } 
 
\t // if ((d.click)%2 == 1) { d3.select(this).style("stroke","red"); } 
 
    // });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
<div id="grid"></div>

+0

謝謝,這是完美的:) – khlan

+0

@khlan我覺得這個想法是偉大的!我想知道在哪裏可以使用它嗎? – Han

+0

感謝您的關注。基於這篇文章(https://journals.aps.org/prx/pdf/10.1103/PhysRevX.7.021029),我爲這個概念中的基本轉換做了演示。所以基本上我需要這個,因爲量子比特。 – khlan