2013-08-20 137 views
2

当我将Extjs和D3结合在一起时,我正在深入研究一些非常有趣的内容。Extjs + D3:渲染冲突

一般来说,ExtJS呈现整个页面的主框架,D3呈现该框架中某个div的动态图形。

由于Extjs中的渲染逻辑非常复杂,我放置D3渲染逻辑的地方似乎非常重要。

在这里,我尝试了两种:

1)投入“initComponent”

[ExtJS] 
Ext.define('EDS.view.selector.Container', { 
extend: 'Ext.panel.Panel', 
alias : 'widget.selectorcontainer', 

    initComponent: function(){ 
     renderSelectorOrgView(); 
    } 
} 

[D3] 
function renderSelectorOrgView(divId, divHeight, divWidth) { 
    var svg = d3.select("#" + divId).append("svg"); 
    .... 
} 

的问题是,它只是没有因为“initComponent”期间的工作,股利是不完全产生。

2)投入全球Ext.onReady()

事实证明,这是D3只能选择空的结果。我想原因是类似于1)

3)投入的OnRender()

按道理这应该工作正常的。事实上D3可以完美地获得div和它的属性。但问题是,ExtJS渲染过程完全被这段代码破坏了。整个布局已损坏。所以我错过了onRender()中的任何重要内容?

Ext.define('EDS.view.selector.Container', { 
extend: 'Ext.panel.Panel', 
alias : 'widget.selectorcontainer', 

layout: 'fit', 
onRender: function(){ 

    //// Render D3 
    // Selector 
    console.log("onRender"); 
    console.log(this.height); 
    console.log(this.width); 

    var divId = Ext.getCmp('selector-organization').id; 
    var divHeight = Ext.get(divId).getHeight(); 
    var divWidth = Ext.get(divId).getWidth(); 
    console.log(divHeight); 
    console.log(divWidth); 
    renderSelectorOrgView(divId, divHeight, divWidth); 

}, 
} 

回答

1

如果可以将D3对象呈现为HTML标记的字符串,则可以在面板模板中包含该字符串。另一种方法是让Ext JS组件像往常一样渲染自己,然后在boxready事件处理程序中注入新的标记。无论哪种方式都可以避免渲染冲突。

+0

在DOM元素完全呈现后'boxready'被触发,并且在稍后的渲染中不会更改? – SolessChong

+0

Ext JS组件首先被渲染到DOM中,然后进行布局(分配的尺寸)。 'boxready'事件在第一个布局之后触发,并且只触发一次。之后,组件的布局(尺寸)可以更改,但其DOM标记通常不会。 –

1

您必须在onRender添加this.callParent(arguments);。在这里,你完全取代了Panel自己的渲染逻辑,这就是为什么它最终破裂。

您也可以参见thisthis其中讨论类似主题的问题。

3

使您的d3代码与extjs一起工作的最佳方式是将d3代码保存在不同的html中。然后在你的extjs面板中使用autoLoad配置并给出html的url。

{ 
    xtype : 'panel', 
    title : 'd3Graph', 
    autoLoad : { url : 'd3code.html', scripts : true} // your HTML file containing d3 code. 
} 

我试过这个,它适用于我,没有任何错误。

另一种方法是使用contentEl配置并在渲染d3可视化的配置中给出div的名称。