2017-03-31 145 views
2

我正在研究聚合物(v1)項目,並且我的一個自定義聚合物元素需要包含D3(v4)圖表。 D3似乎在附加到DOM上時操作非常繁重。不幸的是,Polymer似乎對DOM操作的執行方式非常嚴格。將D3.js元素附加到聚合物元素的陰影DOM中

我創建了D3圖表我想要實現的一個非常簡單的版本:

的index.html

<!DOCTYPE html> 
<html> 
<head> 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
    <style> 
     .bar { 
      fill: #0198E1; 
     } 
    </style> 
</head> 
<body> 

<svg></svg> 

<script> 
var data = [100, 120, 130, 110, 150, 90]; 

const CHART_WIDTH = 126; 
const CHART_HEIGHT = 160; 

svg = d3.select('svg') 
    .attr("width", CHART_WIDTH) 
    .attr("height", CHART_HEIGHT); 

svg.selectAll('rect') 
    .data(data).enter().append('rect') 
     .attr("x", function(d, i) {return i * 21}) 
     .attr("y", function(d) {return CHART_HEIGHT - d}) 
     .attr("height", function(d) {return d}) 
     .attr("width", 20) 
     .attr("class", "bar"); 
</script> 
</body> 
</html> 

我試圖用下列文件兩種解決方案。

的index.html

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="import" href="../bower_components/polymer/polymer.html"> 
    <link rel="import" href="./d3-chart.html"> 
</head> 
<body> 
    <d3-chart></d3-chart> 
</body> 
</html> 

D3-lib.html

<script src="https://d3js.org/d3.v4.min.js"></script> 

嘗試的解決方案1 ​​

使用D3與聚合物的組合選擇目標svg元素,然後執行d3追加。

D3-chart.html

<link rel="import" href="../bower_components/polymer/polymer.html"> 
<link rel="import" href="./d3-lib.html"> 

<dom-module id="d3-chart"> 
    <template> 
     <style> 
      .bar { 
       fill: #0198E1; 
      } 
     </style> 

     <svg id="svg"></svg> 
    </template> 

    <script> 
     Polymer({ 
      is: 'd3-chart', 
      properties: { 
       data: { 
        Type: Array, 
        value: [100, 120, 130, 110, 150, 90] 
       } 
      }, 
      ready: function() { 
       const CHART_WIDTH = 126; 
       const CHART_HEIGHT = 160; 

       var svg = d3.select(this.$.svg) 
        .attr("width", CHART_WIDTH) 
        .attr("height", CHART_HEIGHT); 

       svg.selectAll('rect') 
        .data(this.data).enter().append('rect') 
         .attr("x", function(d, i) {return i * 21}) 
         .attr("y", function(d) {return CHART_HEIGHT - d}) 
         .attr("height", function(d) {return d}) 
         .attr("width", 20) 
         .attr("class", "bar"); 
      } 
     }); 
    </script> 
</dom-module> 

這成功地顯示圖表,但CSS樣式不適用。我認爲這是因爲Polymer不知道已添加的新元素。

嘗試的解決方案2

使用D3選擇(未在DOM)的新SVG元素,執行D3在元件上追加,並用聚合物將其追加到DOM。

D3-chart.html

<link rel="import" href="../bower_components/polymer/polymer.html"> 
<link rel="import" href="./d3-lib.html"> 

<dom-module id="d3-chart"> 
    <template> 
     <style> 
      .bar { 
       fill: #0198E1; 
      } 
     </style> 

    </template> 

    <script> 
     Polymer({ 
      is: 'd3-chart', 
      properties: { 
       data: { 
        Type: Array, 
        value: [100, 120, 130, 110, 150, 90] 
       } 
      }, 
      ready: function() { 
       const CHART_WIDTH = 126; 
       const CHART_HEIGHT = 160; 

       var newSvgElement = document.createElement("svg"); 

       var svg = d3.select(newSvgElement) 
        .attr("width", CHART_WIDTH) 
        .attr("height", CHART_HEIGHT); 

       svg.selectAll('rect') 
        .data(this.data).enter().append('rect') 
         .attr("x", function(d, i) {return i * 21}) 
         .attr("y", function(d) {return CHART_HEIGHT - d}) 
         .attr("height", function(d) {return d}) 
         .attr("width", 20) 
         .attr("class", "bar"); 

       Polymer.dom(this.root).appendChild(newSvgElement); 
      } 
     }); 
    </script> 
</dom-module> 

此代碼成功地追加到DOM的所有元素,但不顯示任何內容。

將聚合物與D3集成的正確方法是什麼?

回答