Reputation: 151
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()));
}
Upvotes: 1
Views: 476
Reputation: 20253
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.
Upvotes: 1