1

I am trying to load a d3 graph having info based on the equipment I have selected in the previous page i.e dynamic loading based on the data. My current configuration is given below although its not working because as soon as the graphs loaded, it gives me d3.event as null exception.

my faces-config.xml has render kit as :

  <render-kit>
            <renderer>
              <display-name>ABCTopologyView</display-name>
              <component-family>javax.faces.ABCTopologyView</component-family>
              <renderer-type>com.jsf.component.ABCView</renderer-type>
              <renderer-class>com.jsf.component.ABCViewRenderer</renderer-class>
            </renderer>
        </render-kit>

How can I pass the json as string from ABCViewRenderer class to the view page in the ABC.js file which is a d3 script :

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:aui="http://liferay.com/faces/aui"
    xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html" xmlns:example-cc="http://java.sun.com/jsf/composite/example-cc"
    xmlns:ice="http://www.icesoft.com/icefaces/component" xmlns:icecore="http://www.icefaces.org/icefaces/core"
    xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ace="http://www.icefaces.org/icefaces/components">
    <icecore:config messagePersistence="false" />
    <aui:layout id="x">
        <aui:column id="y">
            <h:form id="z">
                <icecore:singleSubmit />
                <h:messages globalOnly="true" layout="table" />
                    <ice:panelGroup binding="#{myBean.view}"/>


                    <h:outputScript library="js" name="d3.min.js" type="text/javascript" target="head"/>
                    <h:outputScript library="js" name="ABC.js"  type="text/javascript" />
                </ice:panelGroup>
            </h:form>
        </aui:column>       
    </aui:layout>

</ui:composition>

ABC.js :

topology = {

        CreatePage: function(data) {

                    var svg = d3.select("#chart").append('svg');

                    svg.append("rect")
                            .attr("width", "100%")
                            .attr("height", "100%")
                            .attr("fill", "#F8F8F8");

                    // SVG Building
                    // Base D3 Properties
                    //

                    var margin = {top: -5, right: -5, bottom: -5, left: -5};
                    var width = 1300 - margin.left - margin.right;
                    var height = 500 - margin.top - margin.bottom;
                    var transform = d3.zoomIdentity;
                    var contextMenuOpenBool = false;
                    var edges;

                    // Setting Up data from Function call
                    // May need to be omitted/altered with actual code base
                    var formId = data.formId;
                    var nodes = data.nodes;
                    var links = data.edges;
})
                    };

ABCViewRenderer.java : the method encodeEnd parse data from object into JSON object and call the javascript function..

public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
            throws IOException {

        JsonElement dataElement = parseData(object);
        JsonObject options = dataElement.getAsJsonObject();

        JavascriptContext.addJavascriptCall(facesContext,
                String.format("topology.CreateHtml(%s);", options.toString()));
    }
1
  • JavascriptContext.addJavascriptCall is not something from plain JSF. (Most likely icefaces) and I don't think it should be used from a component but from a bean Commented Mar 19, 2018 at 11:48

1 Answer 1

1

You should write a JavaScript element to the response writer in your encodeEnd method:

ResponseWriter writer = context.getResponseWriter();
writer.startElement("script", this);
writer.writeText("alert('foo');", null);
writer.endElement("script");

Just replace alert('foo') with your JavaScript statement.

Sign up to request clarification or add additional context in comments.

5 Comments

should i give the path of my javascript file?
If you want to load a JavaScript file, add it using @ResourceDependency. See for example stackoverflow.com/questions/4302588/…
although i am able to get the json object in the d3 javascript, but d3.event is returning null
As can be seen in the source code of all JSF component frameworks like PrimeFaces, IceFaces etc
@user2617666 Maybe your JavaScript code can only be ran on document load?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.