2015-11-22 68 views
1

我试图在基于使用D3的那些单元格中的值的表格中的单元格附加SVG圆圈。使用D3.js将SVG元素附加到HTML表格单元格

这里就是我试图让:

 .canvasBackground { 
 
      background-color: white 
 
     } 
 
     
 
     .table { 
 
      border-collapse: collapse; 
 
      border: #d0d4d5 solid 1px; 
 
      border-spacing: 0px; 
 
      font: normal 11px Georgia, 'Times New Roman', Times, serif; 
 
      letter-spacing: 1px; 
 
      line-height: 14px; 
 
      padding: 5px; 
 
      width: 100% 
 
     } 
 
     
 
     .headerStyle { 
 
      vertical-align: middle; 
 
     } 
 
     
 
     .headerRowStyle { 
 
      background-color: #fff; 
 
      border-bottom: 3px solid #ccc; 
 
      color: #4078a9; 
 
      font-size: 14px; 
 
      height: 48px; 
 
      line-height: 14px; 
 
      padding: 10px 5px 5px 5px 
 
     } 
 
     
 
     .headerCellStyle { 
 
      border-left: 1px solid #d0d4d5; 
 

 
     } 
 

 
     .tableBodyStyle { 
 
      text-align: left; 
 
      vertical-align: middle 
 
     } 
 
     
 
     .tableRowStyle { 
 
      background-color: #fff; 
 
      border-bottom: 1px solid #d0d4d5; 
 
      color: #565656; 
 
      padding: 5px 5px 
 
     } 
 
     
 
     .tableCellStyle { 
 
      border: 1px solid #d0d4d5; 
 
      
 
     }   
 
    
<body> 
 
    <div class="canvasBackground"> 
 
    <div class="tables"> 
 
    <table id="sample" class="table display"> 
 
     <thead class="headerStyle"> 
 
      <tr class="headerRowStyle"> 
 
       <th>Title</th> 
 
       <th>ID</th> 
 
       <th>Name</th> 
 
       <th>Color 1</th> 
 
       <th>Color 2</th> 
 
      </tr> 
 
     </thead> 
 
     <tbody class="tableBodyStyle"> 
 
      <tr class="tableRowStyle"> 
 
       <td class="tableCellStyle">Title 1</td> 
 
       <td class="tableCellStyle">00001</td> 
 
       <td class="tableCellStyle">Rena</td> 
 
       <td class="tableCellStyle"> 
 
        <svg width="50" height="50"> 
 
         <g> 
 
          <circle cx="28" cy="25" r="20" style="fill: rgb(244, 248, 94);"></circle> 
 
          <text dy="30" dx="24" style="fill: rgb(86, 86, 86);">Y</text> 
 
         </g> 
 
        </svg> 
 
       </td> 
 
       <td class="tableCellStyle"> 
 
        <svg width="50" height="50"> 
 
         <g> 
 
          <circle cx="28" cy="25" r="20" style="fill: rgb(122, 162, 92);"></circle> 
 
          <text dy="30" dx="24" style="fill: rgb(255, 255, 255);">G</text> 
 
         </g> 
 
        </svg> 
 
       </td> 
 
      </tr> 
 
      <tr class="tableRowStyle"> 
 
       <td class="tableCellStyle">Title 2</td> 
 
       <td class="tableCellStyle">00002</td> 
 
       <td class="tableCellStyle">Elsa</td> 
 
       <td class="tableCellStyle"> 
 
        <svg width="50" height="50"> 
 
         <g> 
 
          <circle cx="28" cy="25" r="20" style="fill: rgb(122, 162, 92);"></circle> 
 
          <text dy="30" dx="24" style="fill: rgb(255, 255, 255);">G</text> 
 
         </g> 
 
        </svg> 
 
       </td> 
 
       <td class="tableCellStyle"> 
 
        <svg width="50" height="50"> 
 
         <g> 
 
          <circle cx="28" cy="25" r="20" style="fill: rgb(216, 75, 42);"></circle> 
 
          <text dy="30" dx="24" style="fill: rgb(255, 255, 255);">R</text> 
 
         </g> 
 
        </svg> 
 
       </td> 
 
      </tr> 
 
     </tbody> 
 
    </table> 
 
</div> 
 
    </div> 
 
</body>

这是我到目前为止有:

function evalColor(d) { 
 
    if (d == "Green" | d == "Yellow" | d == "Red") { 
 
     return createSVG(d); 
 
    } 
 
    if (d != "Green" | d != "Yellow" | d != "Red") { 
 
     return d; 
 
    } 
 
} 
 

 
function evalText(d) { 
 
    if (d == "Green" | d == "Yellow" | d == "Red") { 
 
     console.log(d); 
 
    } 
 
    else if (d != "Green" | d != "Yellow" | d != "Red") { 
 
     return d; 
 
    } 
 
} 
 

 
function createTable() { 
 
    var dataSet = [{ 
 
     "Title": "Title 1", 
 
     "ID": "00001", 
 
     "Name": "Rena", 
 
     "Color 1": "Yellow", 
 
     "Color 2": "Green" 
 
    }, { 
 
     "Title": "Title 2", 
 
     "ID": "00002", 
 
     "Name": "Elsa", 
 
     "Color 1": "Green", 
 
     "Color 2": "Red" 
 
    }, ]; 
 

 
    var div = d3.select('.tables'); 
 

 
    // append a table to the div 
 
    var table = div.append("table") 
 
     .attr({ 
 
      id: "sample", 
 
      class: 'table' 
 
     }) 
 
     .classed("display", true); 
 

 
    // append a header to the table 
 
    var thead = table.append("thead") 
 
     .attr({ 
 
      class: 'headerStyle' 
 
     }); 
 

 
    // append a body to the table 
 
    var tbody = table.append("tbody") 
 
     .attr({ 
 
      class: 'tableBodyStyle' 
 
     }); 
 

 
    // append a row to the header 
 
    var theadRow = thead.append("tr") 
 
     .attr({ 
 
      class: 'headerRowStyle' 
 
     }); 
 

 
    // return a selection of cell elements in the header row 
 
    // attribute (join) data to the selection 
 
    // update (enter) the selection with nodes that have data 
 
    // append the cell elements to the header row 
 
    // return the text string for each item in the data array 
 
    theadRow.selectAll("th") 
 
     .data(d3.keys(dataSet[0])) 
 
     .enter() 
 
     .append("th") 
 
     .text(function(d) { 
 
      return d; 
 
     }); 
 

 
    // table body rows 
 
    var tableBodyRows = tbody.selectAll("tr") 
 
     .data(dataSet) 
 
     .enter() 
 
     .append("tr") 
 
     .attr({ 
 
      class: 'tableRowStyle' 
 
     }); 
 

 
    //table body row cells 
 
    tableBodyRows.selectAll("td") 
 
     .data(function(d) { 
 
      return d3.values(d); 
 
     }) 
 
     .enter() 
 
     .append("td") 
 
     .append(function(d) { 
 
      return createSVG(d); 
 
     }) 
 
     .text(function(d) { 
 
      return evalText(d); 
 
     }); 
 
} 
 

 
function createSVG(d) { 
 

 
    function colorPicker(value) { 
 
     if (value == "Green") { 
 
      return "#7aa25c"; 
 
     } 
 
     else if (value == "Yellow") { 
 
      return "#f4f85e"; 
 
     } 
 
     else if (value == "Red") { 
 
      return "#d84b2a"; 
 
     } 
 
    } 
 

 
    function colorFill(value) { 
 
     if (value == "Green") { 
 
      return "#fff"; 
 
     } 
 
     else if (value == "Yellow") { 
 
      return "#565656"; 
 
     } 
 
     else if (value == "Red") { 
 
      return "#fff"; 
 
     } 
 
    } 
 

 
    function letterChoice(value) { 
 
     if (value == "Green") { 
 
      return "G"; 
 
     } 
 
     else if (value == "Yellow") { 
 
      return "Y"; 
 
     } 
 
     else if (value == "Red") { 
 
      return "R"; 
 
     } 
 
    } 
 

 
    var w = 50; 
 
    var h = 50; 
 

 
    var kpi = document.createElement("div"); 
 

 
    var svg = d3.select(kpi).append("svg") 
 
     .attr({ 
 
      width: w, 
 
      height: h 
 
     }); 
 

 

 
    var elem = svg.selectAll("div") 
 
     .data([d]); 
 

 
    var elemEnter = elem.enter() 
 
     .append("g"); 
 

 
    elemEnter.append("circle") 
 
     .attr({ 
 
      cx: 28, 
 
      cy: 25, 
 
      r: 20 
 
     }) 
 
     .style("fill", function(d) { 
 
      return colorPicker(d); 
 
     }); 
 

 
    elemEnter.append("text") 
 
     .style("fill", function(d) { 
 
      return colorFill(d); 
 
     }) 
 
     .attr("dy", 55) 
 
     .attr("dx", 45) 
 
     .text(function(d) { 
 
      return letterChoice(d); 
 
     }); 
 

 
    return kpi; 
 
} 
 

 
createTable();
 .canvasBackground { 
 
      background-color: white 
 
     } 
 
     
 
     .table { 
 
      border-collapse: collapse; 
 
      border: #d0d4d5 solid 1px; 
 
      border-spacing: 0px; 
 
      font: normal 11px Georgia, 'Times New Roman', Times, serif; 
 
      letter-spacing: 1px; 
 
      line-height: 14px; 
 
      padding: 5px; 
 
      width: 100% 
 
     } 
 
     
 
     .headerStyle { 
 
      vertical-align: middle; 
 
     } 
 
     
 
     .headerRowStyle { 
 
      background-color: #fff; 
 
      border-bottom: 3px solid #ccc; 
 
      color: #4078a9; 
 
      font-size: 14px; 
 
      height: 48px; 
 
      line-height: 14px; 
 
      padding: 10px 5px 5px 5px 
 
     } 
 
     
 
     .headerCellStyle { 
 
      border-left: 1px solid #d0d4d5; 
 

 
     } 
 

 
     .tableBodyStyle { 
 
      text-align: left; 
 
      vertical-align: middle 
 
     } 
 
     
 
     .tableRowStyle { 
 
      background-color: #fff; 
 
      border-bottom: 1px solid #d0d4d5; 
 
      color: #565656; 
 
      padding: 5px 5px 
 
     } 
 
     
 
     .tableCellStyle { 
 
      border: 1px solid #d0d4d5; 
 
      
 
     }   
 
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<body> 
 
    <div class="canvasBackground"> 
 
\t <div class="tables"></div> 
 
</body>

从本质上讲,我想使用.append方法如果文本不包含颜色,例如“红色”,“黄色”或“绿色”,则在文本中附加<td>元素。如果文本包含这些颜色,我想使用相同的.append方法来追加一个子svg cirlce元素。但是当我使用.text方法时,我的svg元素消失了。

任何想法?

回答

0

反转调用的顺序,并在那里扔一个过滤器:

//table body row cells 
    tableBodyRows.selectAll("td") 
    .data(function(d) { 
     return d3.values(d); 
    }) 
    .enter() 
    .append("td") 
    .text(function(d) { 
     return evalText(d); 
    }) 
    // only make the SVG for those text that have a color 
    .filter(function(d){ 
     return (d === "Green" || 
     d === "Yellow" || 
     d === "Red"); 
    }) 
    .append(function(d) { 
     return createSVG(d); 
    }); 

工作代码:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> 
 
    <style> 
 
    .canvasBackground { 
 
     background-color: white 
 
    } 
 
    
 
    .table { 
 
     border-collapse: collapse; 
 
     border: #d0d4d5 solid 1px; 
 
     border-spacing: 0px; 
 
     font: normal 11px Georgia, 'Times New Roman', Times, serif; 
 
     letter-spacing: 1px; 
 
     line-height: 14px; 
 
     padding: 5px; 
 
     width: 100% 
 
    } 
 
    
 
    .headerStyle { 
 
     vertical-align: middle; 
 
    } 
 
    
 
    .headerRowStyle { 
 
     background-color: #fff; 
 
     border-bottom: 3px solid #ccc; 
 
     color: #4078a9; 
 
     font-size: 14px; 
 
     height: 48px; 
 
     line-height: 14px; 
 
     padding: 10px 5px 5px 5px 
 
    } 
 
    
 
    .headerCellStyle { 
 
     border-left: 1px solid #d0d4d5; 
 
    } 
 
    
 
    .tableBodyStyle { 
 
     text-align: left; 
 
     vertical-align: middle 
 
    } 
 
    
 
    .tableRowStyle { 
 
     background-color: #fff; 
 
     border-bottom: 1px solid #d0d4d5; 
 
     color: #565656; 
 
     padding: 5px 5px 
 
    } 
 
    
 
    .tableCellStyle { 
 
     border: 1px solid #d0d4d5; 
 
    } 
 
    </style> 
 
</head> 
 

 
<body> 
 
    <div class="canvasBackground"> 
 
    <div class="tables"></div> 
 
    </div> 
 

 
    <script> 
 
    function evalColor(d) { 
 
     if (d == "Green" | d == "Yellow" | d == "Red") { 
 
     return createSVG(d); 
 
     } 
 
     if (d != "Green" | d != "Yellow" | d != "Red") { 
 
     return d; 
 
     } 
 
    } 
 

 
    function evalText(d) { 
 
     if (d == "Green" | d == "Yellow" | d == "Red") { 
 
     console.log(d); 
 
     } else if (d != "Green" | d != "Yellow" | d != "Red") { 
 
     return d; 
 
     } 
 
    } 
 

 
    function createTable() { 
 
     var dataSet = [{ 
 
     "Title": "Title 1", 
 
     "ID": "00001", 
 
     "Name": "Rena", 
 
     "Color 1": "Yellow", 
 
     "Color 2": "Green" 
 
     }, { 
 
     "Title": "Title 2", 
 
     "ID": "00002", 
 
     "Name": "Elsa", 
 
     "Color 1": "Green", 
 
     "Color 2": "Red" 
 
     }, ]; 
 

 
     var div = d3.select('.tables'); 
 

 
     // append a table to the div 
 
     var table = div.append("table") 
 
     .attr({ 
 
      id: "sample", 
 
      class: 'table' 
 
     }) 
 
     .classed("display", true); 
 

 
     // append a header to the table 
 
     var thead = table.append("thead") 
 
     .attr({ 
 
      class: 'headerStyle' 
 
     }); 
 

 
     // append a body to the table 
 
     var tbody = table.append("tbody") 
 
     .attr({ 
 
      class: 'tableBodyStyle' 
 
     }); 
 

 
     // append a row to the header 
 
     var theadRow = thead.append("tr") 
 
     .attr({ 
 
      class: 'headerRowStyle' 
 
     }); 
 

 
     // return a selection of cell elements in the header row 
 
     // attribute (join) data to the selection 
 
     // update (enter) the selection with nodes that have data 
 
     // append the cell elements to the header row 
 
     // return the text string for each item in the data array 
 
     theadRow.selectAll("th") 
 
     .data(d3.keys(dataSet[0])) 
 
     .enter() 
 
     .append("th") 
 
     .text(function(d) { 
 
      return d; 
 
     }); 
 

 
     // table body rows 
 
     var tableBodyRows = tbody.selectAll("tr") 
 
     .data(dataSet) 
 
     .enter() 
 
     .append("tr") 
 
     .attr({ 
 
      class: 'tableRowStyle' 
 
     }); 
 

 
     //table body row cells 
 
     tableBodyRows.selectAll("td") 
 
     .data(function(d) { 
 
      return d3.values(d); 
 
     }) 
 
     .enter() 
 
     .append("td") 
 
     .text(function(d) { 
 
      return evalText(d); 
 
     }) 
 
     .filter(function(d){ 
 
      return (d === "Green" || 
 
      d === "Yellow" || 
 
      d === "Red"); 
 
     }) 
 
     .append(function(d) { 
 
      return createSVG(d); 
 
     }); 
 
     
 
    } 
 

 
    function createSVG(d) { 
 
     
 
     function colorPicker(value) { 
 
     if (value == "Green") { 
 
      return "#7aa25c"; 
 
     } else if (value == "Yellow") { 
 
      return "#f4f85e"; 
 
     } else if (value == "Red") { 
 
      return "#d84b2a"; 
 
     } 
 
     } 
 

 
     function colorFill(value) { 
 
     if (value == "Green") { 
 
      return "#fff"; 
 
     } else if (value == "Yellow") { 
 
      return "#565656"; 
 
     } else if (value == "Red") { 
 
      return "#fff"; 
 
     } 
 
     } 
 

 
     function letterChoice(value) { 
 
     if (value == "Green") { 
 
      return "G"; 
 
     } else if (value == "Yellow") { 
 
      return "Y"; 
 
     } else if (value == "Red") { 
 
      return "R"; 
 
     } 
 
     } 
 

 
     var w = 50; 
 
     var h = 50; 
 

 
     var kpi = document.createElement("div"); 
 

 
     var svg = d3.select(kpi).append("svg") 
 
     .attr({ 
 
      width: w, 
 
      height: h 
 
     }); 
 
     
 
     var elem = svg.selectAll("div") 
 
     .data([d]); 
 

 
     var elemEnter = elem.enter() 
 
     .append("g"); 
 

 
     elemEnter.append("circle") 
 
     .attr({ 
 
      cx: 28, 
 
      cy: 25, 
 
      r: 20 
 
     }) 
 
     .style("fill", colorPicker); 
 

 
     elemEnter.append("text") 
 
     .style("fill", colorFill) 
 
     .attr("dy", 30) 
 
     .attr("dx", 25) 
 
     .text(letterChoice); 
 

 
     return kpi; 
 
    } 
 

 
    createTable(); 
 
    </script> 
 
</body> 
 

 
</html>

+1

中超,@马克。谢谢!我不知道.filter方法。另外,感谢您清理代码。 – Tony

+0

.filter超级有用,并且不限于d3! – danimal