I'm digging into something really interesting when combining Extjs and D3.
In general, ExtJS renders the main frame for the whole page and D3 to render a dynamic graph in certain div in that frame.
As the rendering logic in Extjs is quite complicated, the place where I put the D3 render logic seems crucial.
Here I've tried two:
1) put into '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");
....
}
The problem is that it just doesn't work since during "initComponent", the div is not completely generated.
2) put into global Ext.onReady()
This turned out that D3 can only select empty result. I think the reason is similar to 1)
3) put into onRender()
Logically this should work alright. And in fact D3 can get the div and its attr perfectly. However the problem is, the ExtJS render process is totally ruined by this code. The whole layout is corrupted. So am I missing anything important in 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);
},
}
If it is possible to render D3 object as a string of HTML markup, you can include that string in the Panel template. Another way is to let Ext JS components render themselves as usual, and then inject new markup in boxready
event handler. Either way will avoid rendering conflicts.