function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Johannes SchausbergerJohannes Schausberger 

Rerender is not called in Lightning component

Hello,

I have a lightning component containing a <div id="myChart"/> tag.

The task is to render a custom graph into that div tag. For that i need to use a charting library (d3funnel.js, based on d3.js) which puts <svg> into the div tag. Then i need to add my own svg elements (circle, path...) into that <svg> tree.

 

what i did: i inserted my library chart and my custom svg elements in doneRendering() event, because i need correct results from element.getBoundingClientRect(). and i only get the boundingrect if the dom is rendered.

the problem: the library chart renders fine. but when i try to insert my custom svg tags, the chart gets repainted instantly, somehow. then, only the chart is present, but my custom tags are gone.

The documentation says that i need to modify the dom in the custom renderer. 
i cant use render() and afterRender(), because the chart gets inserted in doneRendering.

When i try to use rerender() to insert , the function doesnt get called. I changed an attributes, fired events from the client controller, changed labels from ui elements, but no effect.

what am i doing wrong?

code snippets:

doneRendering : function(component, event, helper){
        //Polling: We need to wait for scripts and serverdata to be loaded
        //before we can draw the chart. so we periodically check if data is here
        var timesToCheck = 50;
        var poll = function (helper) {
            setTimeout(function () {
                timesToCheck--;
                //everything is loaded?
                if (helper.isScriptsLoaded() && helper.isSectionsLoaded() && helper.isDataPointsLoaded()) {
                    helper.render();
                } else if (timesToCheck > 0) {
                    poll(helper);
                } else {
                    window.alert("Unable to load data from server!");
                }
            }, 100);
        };

(helper.render first draws the chart using the js library, then immediately draws my custom svg elements, then finishes.)

renderer:

({
    render : function(cmp, helper) {
    	var ret = this.superRender();
        window.alert("I get called");
    	return ret;
	},
    rerender : function(cmp, helper){
    	this.superRerender();
        window.alert("I do not get called :(");
        helper.paintCustomSvg();
	},
})

clientcontroller:

causeRerender : function(cmp, event, helper){
        var button = cmp.find("refreshElement");
        button.set("v.label","Hello");
        cmp.set("v.refresh", "123"); //change some attribute
    }

component:

<aura:component controller="SalesFunnelController">
    <ltng:require styles="{!$Resource.bootstrap}"/>
    <ltng:require scripts="{!$Resource.d3library}"/>
    <ltng:require scripts="{!$Resource.d3funnel}"
    afterScriptsLoaded="{!c.afterScriptsLoaded}" />
    
    <aura:handler event="aura:doneRendering" action="{!c.doneRendering}"/>
    
    <ui:button aura:id="refreshElement" label="refresh button hidden" press="{!c.causeRerender}"/>
    <aura:attribute name="refresh" type="String" description="some attribute" />
  
    <div id="funnel">LOADING FUNNEL DATA...</div>
</aura:component>