6 Replies Latest reply on Dec 15, 2011 1:14 AM by haukegulich

    Creating dynamic decision graphs in Richfaces

    haukegulich

      Hello everyone,

       

      is there a way to create a dynamic decision graph in richfaces?

      I looked at svg to create it by myself, but I didn't find any information on how to create a svg image dynamically and display that in jsf based on richfaces. The xml information of the svg image should be generated at the server side bean because only there I have all the information I need for the graph.

       

      Is there a other way to create something like that? rich:paint2d ?

       

      Thanks,
      Hauke

        • 1. Re: Creating dynamic decision graphs in Richfaces
          mcmurdosound

          Maybe creating an own component would be a nice approach.

           

          public class ChartComponent extends UIOutput {

            public static final String COMPONENT_TYPE = "uicomponents.ChartComponent";

            public static final String COMPONENT_FAMILY = "uicomponents.ChartComponentFamily";

            public static final String RENDERER_TYPE = "uicomponents.ChartComponentRenderer";

           

            @Override

            public String getFamily() {

              return COMPONENT_FAMILY;

            }

           

            @Override

            public String getRendererType() {

              return RENDERER_TYPE;

            }

           

          }

           

           

           

          Renderer:

          public class ChartComponentRenderer extends RendererBase {

           

            @Override

            protected Class<? extends UIComponent> getComponentClass() {

              return ChartComponent.class;

            }

           

            @Override

            protected void doEncodeBegin(ResponseWriter writer, FacesContext context,

                UIComponent component) throws IOException {

              writer.startElement("span", component);

              writer.writeAttribute("id", component.getClientId(context), "id");

           

          write your html / js / xml code here

           

           

           

           

          You'll need to add your component and renderer to the faces-config.xml and a taglib to become usable in a facelet.

           

          Like:

            <component>

              <component-type>uicomponents.ChartComponent</component-type>

              <component-class>XXXXX.ui.components.ChartComponent</component-class>

            </component>

           

          <render-kit>

          <renderer>

                <component-family>uicomponents.ChartComponentFamily</component-family>

                <renderer-type>uicomponents.ChartComponentRenderer</renderer-type>

                <renderer-class>XXXXX.platform.ui.components.ChartComponentRenderer</renderer-class>

              </renderer>

           

          taglib:

           

            <tag>

              <tag-name>chart</tag-name>

              <component>

                <component-type>uicomponents.ChartComponent</component-type>

                <renderer-type>uicomponents.ChartComponentRenderer</renderer-type>

              </component>

            </tag>

           

           

          You can even rerender this component to update the svg image etc.

          1 of 1 people found this helpful
          • 2. Re: Creating dynamic decision graphs in Richfaces
            haukegulich

            Hi Christian,

             

            thanks for your reply and your help. I never created an own component before, so I have no idea where to put the <tag> tag. Does is belong to the faces-config.xml file? Eclipse tells me that this is not allowed there.

             

            I also read something about create own components, but I couldn't find the information with the <tag> thing.

             

            Will ne new tag (chart) appear on eclipse as well? Which taglib does this component belongs to? Do I need to write <f:chart/> ?

             

            If I understand you right, the <f:chart/> will create html output which I can dynamically generate? That would solve my problem :-)

             

             

            Thanks a lot,

            Hauke

            • 3. Re: Creating dynamic decision graphs in Richfaces
              mcmurdosound

              I had to create a taglib first:

              my.taglib.xml:

               

              <?xml version="1.0"?>

              <!DOCTYPE facelet-taglib PUBLIC

                "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"

                "facelet-taglib_1_0.dtd">

              <facelet-taglib>

                <namespace>http://www.XXXXX.de/mytags/jsf</namespace>

              <tag>

                  <tag-name>chart</tag-name>

                  <component>

                    <component-type>uicomponents.ChartComponent</component-type>

                    <renderer-type>uicomponents.ChartComponentRenderer</renderer-type>

                  </component>

                </tag>

              </facelet-taglib>

               

               

               

              and register it it the web.xml:

               

                <context-param>

                  <param-name>facelets.LIBRARIES</param-name>

                  <param-value>

                    /WEB-INF/facelets/tags/my.taglib.xml;

                  </param-value>

                </context-param>

               

               

              usage in facelets:

              <ui:composition xmlns="http://www.w3.org/1999/xhtml"

                xmlns:ui="http://java.sun.com/jsf/facelets"

                xmlns:f="http://java.sun.com/jsf/core"

                xmlns:h="http://java.sun.com/jsf/html"

              ...

                xmlns:my="http://www.XXXXX.de/mytags/jsf"

              ...

               

               

              <my:chart />

              1 of 1 people found this helpful
              • 4. Re: Creating dynamic decision graphs in Richfaces
                haukegulich

                Hi Christian,

                 

                thanks again

                 

                I am getting closer, but now I need to go home because it was a long day with a lot of trying out :-)

                 

                In eclipse I get this error when I go on this line :

                xmlns:my="http://127.0.0.1:8080/mytags/jsf"

                 

                 

                NLS missing message: CANNOT_FIND_FACELET_TAGLIB in:

                org.eclipse.jst.jsf.core.validation.internal.facelet.messages

                 

                 

                is that right, that I need to put here my localhost machine? I think so, because we defined that in the web.xml file before.

                 

                The page doesn't print the span-tag, it prints <my:chart/>. I expected to see <span id="xxx" /> in my html code.

                 

                Do I need to do something special with the ResponseWriter at doEncodeBegin. The method is void so I can't pass the result somewhere else.

                 

                 

                Thanks a lot and I will continue trying tomorrow.

                 

                Many greetings,

                Hauke

                • 5. Re: Creating dynamic decision graphs in Richfaces
                  mcmurdosound

                  sorry, no:

                  xmlns:my="http://127.0.0.1:8080/mytags/jsf" this doesn't have to be the address of your server.

                   

                  Maybe this article could be useful: http://www.ibm.com/developerworks/java/library/j-facelets/ at about half down the page there is an example how to create an own taglib.

                   

                   

                  I've not yet used svg before, so there's no experience on my side. There might be much easier solutions.

                   

                  http://www.java-tips.org/java-ee-tips/javaserver-faces/using-ajax-with-non-markup-in-jsf-2.html

                  • 6. Re: Creating dynamic decision graphs in Richfaces
                    haukegulich

                    Hi Christian,

                     

                    I've got that working now. Here is what I did:

                     

                    I added this to web.xml

                    {code:xml}

                    <context-param>
                            <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
                           <param-value>/WEB-INF/custom-taglib.xml</param-value>

                       </context-param>

                    {code}

                     

                    Then I created this custom-taglib.xml file

                     

                     

                    {code:xml}

                     

                    <facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"

                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"

                        version="2.0">

                        <namespace>http://127.0.0.1:8080/custom-taglib</namespace>

                        <tag>

                            <tag-name>custom</tag-name>

                            <component>

                                <component-type>mycustom</component-type>

                            </component>

                        </tag>

                    </facelet-taglib>

                    {code}

                     

                    and I created the class MyCustom.java

                     


                    {code}

                    package de.hauke.client.playground;

                     

                    import java.io.IOException;

                     

                    import javax.faces.component.FacesComponent;

                    import javax.faces.component.UIComponentBase;

                    import javax.faces.context.FacesContext;

                    import javax.faces.context.ResponseWriter;

                     

                    import org.dom4j.Document;

                    import org.dom4j.DocumentHelper;

                    import org.dom4j.Element;

                     

                    @FacesComponent(value = "mycustom")

                    public class MyCustom extends UIComponentBase {

                     

                        @Override

                        public String getFamily() {

                            return "custom";

                        }

                     

                        @Override

                        public void encodeEnd(FacesContext context) throws IOException {

                     

                       

                                Document document = DocumentHelper.createDocument();

                                Element root = document.addElement("svg");

                                root.addAttribute("xmlns", "http://www.w3.org/2000/svg");

                                root.addAttribute("version", "1.1");

                               

                               

                                Element border = root.addElement("rect");

                                border.addAttribute("width", "700");

                                border.addAttribute("height", "550");

                                border.addAttribute("style", "fill:rgb(255,255,255);stroke-width:1;stroke:rgb(0,0,0)");

                               

                               

                                Element text = root.addElement("text");

                                text.addAttribute("x", "30");

                                text.addAttribute("y", "30");

                                text.addAttribute("fill", "black");

                                text.setText("Das ist der Text");

                               

                                Element rect = root.addElement("rect");

                                rect.addAttribute("x", "30");

                                rect.addAttribute("y", "30");

                                rect.addAttribute("rx", "10");

                                rect.addAttribute("ry", "10");

                                rect.addAttribute("width", "100");

                                rect.addAttribute("height", "30");

                                rect.addAttribute("style", "fill:red;stroke:black;stroke-width:2;opacity:0.5");

                               

                                Element polyline = root.addElement("polyline");

                                polyline.addAttribute("points", "0,40 40,40 40,80 80,80 80,120 120,120 120,160 160,160 160,200 200,200 200,240 240,240 240,280 280,280 280,320 320,320 320,360 360,360 360,400 400,400 400,440");

                                polyline.addAttribute("style", "fill:white;stroke:red;stroke-width:4");

                               

                           

                           

                            ResponseWriter responseWriter = context.getResponseWriter();

                            responseWriter.startElement("div", null);

                            responseWriter.write(document.asXML());

                            responseWriter.endElement("div");

                        }

                    }

                     

                    {code}

                     

                    where I anotated the name of the new component and extended UIComponentBase and overwrote encodeEnd method. There I created a dom4j document, put all the tags I needed for svg in, and passed that to the responsewriter.

                     

                    Finally I create a xhtml page like this:

                     

                     

                    {code:xml}

                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

                              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

                    <html xmlns="http://www.w3.org/1999/xhtml"

                    xmlns:f="http://java.sun.com/jsf/core"

                    xmlns:h="http://java.sun.com/jsf/html"

                    xmlns:ui="http://java.sun.com/jsf/facelets"

                    xmlns:a4j="http://richfaces.org/a4j"

                    xmlns:rich="http://richfaces.org/rich"

                    xmlns:cu="http://127.0.0.1:8080/custom-taglib">

                     

                     

                     

                    <h:outputText value="WEBCAM"></h:outputText>

                     

                    <cu:custom/>

                     

                     

                    </html>

                    {code}

                     

                    and that is working.

                     

                    But I still have a problem with displaying the svg because firefox cuts the graphic half way. IE displays it completly. But that is a different problem.

                     

                    Thanks so much for bringing me to the right track.

                     

                    Many greetings,

                    Hauke