Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Google Visualization API and nested smartGWT layout containers

    HI,

    I would like to add visualization support via the Google Visualization API to an existing GWT (2.1.1) and smartGWT (2.4) application.

    I would like the "chart" to appear in a nested smartGWT layout container (e.g. a HLayout or a VLayout).

    I followed the approach described in this post -> http://forums.smartclient.com/showpost.php?p=37754&postcount=2 and the Visualization Getting Started guide-> http://code.google.com/p/gwt-google-apis/wiki/VisualizationGettingStarted

    Code:
      @SuppressWarnings("deprecation")
      public void loadVisualizationApi() {
        
        // Create a callback to be called when the visualization API 
        // has been loaded.
        Runnable onLoadCallback = new Runnable() {
          public void run() {
     
            // Create a pie chart visualization.
            PieChart pie = new PieChart(createTable(), createOptions());   
    
            // RootPanel.get().add(pie);
            panel.addMember(pie);
          }
        };
    
        // Load the visualization api, passing the onLoadCallback 
        // to be called when loading is complete.
        VisualizationUtils.loadVisualizationApi(onLoadCallback, PieChart.PACKAGE);
      }  
    
      // The code for createTable() and createOptions()) is as per 
      // the post mentioned above.
    However, this results in the following [FATAL] Uncaught Exception:

    Code:
    java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
        at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:136)
        at com.google.gwt.user.client.ui.RootPanel.get(RootPanel.java:211)
        at com.smartgwt.client.widgets.WidgetCanvas.onDraw(WidgetCanvas.java:39)
        at com.smartgwt.client.widgets.BaseWidget.rendered(BaseWidget.java:242)
        at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:326)
        at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:207)
        at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:126)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:289)
        at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:107)
        at com.smartgwt.client.widgets.layout.Layout.addMemberPostCreate(Layout.java)
        at com.smartgwt.client.widgets.layout.Layout.addMember(Layout.java:1089)
        at com.smartgwt.client.widgets.layout.Layout.addMember(Layout.java:1076)
        at au.com.uptick.serendipity.client.sales.view.DashboardsView$1.run(DashboardsView.java:76)
        at com.google.gwt.ajaxloader.client.ExceptionHelper.runProtected(ExceptionHelper.java:36)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:281)
        at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:531)
        at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:352)
        at java.lang.Thread.run(Thread.java:619)
    If I comment out the call to "panel.addMember(pie)" and replace it with "RootPanel.get().add(pie)" no exception is thrown and the "chart" is rendered correctly (you can see it momentarily if you re-size the browser window) but as a child of the root panel. Which means it is hidden by the the other nested layout containers (e.g. North, West, East and South).

    I would like to be able both size and position the "chart" using nested smartGWT layout containers if possible?

    N.B. I also tried using the latest nightly build (e.g. smartGWT 2.5) as per this post -> http://code.google.com/p/smartgwt/issues/detail?id=405

    Cheers
    Rob

    #2
    Hi,

    Some more information (Java 1.6, FF3):

    With GWT (2.1.1), smartGWT (2.4) and Google Visualization API (1.1) I receive the following error: (NativeMethodAccessorImpl.java:-2) 2011-05-09 10:26:21,613 [FATAL] Uncaught JavaScript exception [Script error.] in , line 0

    With GWT (2.1.1), smartGWT LGPL (2.5 nightly build) and Google Visualization API (1.1) I receive the following error: java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:136)

    I found the following example:

    Code:
       ...
    
    1. Call a method that retrieves your data and initializes your
    barchart (setServices in my code)
    2. Also create a timer that will update the data for your barchart
         t = new Timer() {
            public void run() {
                    retrieveGaugeData();
                    if(gauge != null) {
                            gauge.draw(createGaugeData(), createGaugeOptions());
                    }
            }
         };
         t.scheduleRepeating(5000);
    
    Method setServices (retrieves data initially and initializes my
    visualization)
    1. Retrieves your data, I use an RPC call to pull this data from the
    server which in turn pulls it from MySQL and returns it
    2. Create your barchart (in my case a Gauge), note I'm also using
    SmartGWT so adding it to the canvas may be a little different.
         Runnable onLoadCallback = new Runnable() {
            public void run() {
                    gauge = new Gauge(createGaugeData(), createGaugeOptions());
                    gauge.setWidth("80%");
                    Canvas c = new Canvas();
                    c.setID("sys_gauge_canvas");
                    c.setWidth100();
                    c.setHeight("30%");
                    c.addChild(gauge);
                    addMember(c, 0);
            }
         };
    
         VisualizationUtils.loadVisualizationApi("1.1", onLoadCallback,
    Gauge.PACKAGE); 
    
     ...
    in this post -> http://groups.google.com/group/google-visualization-api/browse_thread/thread/ff89e49ecf52fd4/69b7bfd3d4042526?lnk=gst&q=smartGWT#69b7bfd3d4042526 in the Google Visualization API group.

    And, modified my code as per the sample:

    Code:
      public void loadVisualizationApi() {
        
        Log.debug("loadVisualizationApi()");
        
        // Create a callback to be called when the visualization API  
        // has been loaded.
        Runnable onLoadCallback = new Runnable() {
          public void run() {
            
            Log.debug("onLoadCallback()");
            
            // Create a pie chart visualization.
            pie = new PieChart(createTable(), createOptions());
            pie.setWidth("80%");
    		
            Canvas canvas = new Canvas();
            canvas.setID("sys_pie_canvas");
            canvas.setWidth100();
            canvas.setHeight("50%");
            canvas.addChild(pie);
            
            panel.addMember(canvas, 0); 
            
            Log.debug("panel.addMember(canvas, 0)");
          }
        };
    
        // Load the visualization api, passing the onLoadCallback 
        // to be called when loading is complete.
        VisualizationUtils.loadVisualizationApi("1.1", onLoadCallback,
            PieChart.PACKAGE);
      }
    However, this still results in the following error: java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:136) when using GWT (2.1.1), smartGWT LGPL (2.5 nightly build) and Google Visualization API (1.1).

    As before, if I comment out the call to "panel.addMember(pie)" and replace it with "RootPanel.get().add(pie)" no exception is thrown and the "chart" is rendered correctly (you can see it momentarily if you re-size the browser window) but as a child of the root panel. Which means it is hidden by the the other nested layout containers (e.g. North, West, East and South).

    I would like to be able to place the "chart" in a nested layout container if possible?

    Cheers
    Rob

    Comment


      #3
      Hi,

      Some more information:

      See attached screen shot of (gwt-google-apis/visualization -> http://code.google.com/p/gwt-google-apis and smartGWT) issue.

      Added div to host file:

      Code:
      <html>
        <body>
      
          ...
          
          <div id="sys_pie_canvas"></div>
      
        </body>
      </html>
      And, updated the call to -> RootPanel.get("sys_pie_canvas").add(pie)

      Code:
        public void loadVisualizationApi() {
          
          Log.debug("loadVisualizationApi()");
          
          // Create a callback to be called when the visualization API  
          // has been loaded.
          Runnable onLoadCallback = new Runnable() {
            public void run() {
              
              Log.debug("onLoadCallback()");
              
              // Create a pie chart visualization.
              pie = new PieChart(createTable(), createOptions());
              // pie.setWidth("80%");
              
              // Canvas canvas = new Canvas();
              // canvas.setID("sys_pie_canvas");
              // canvas.setWidth100();
              // canvas.setHeight("50%");
              // canvas.addChild(pie);
              
              // panel.addMember(canvas, 0); 
              // Log.debug("panel.addMember(canvas, 0)");
              
              RootPanel.get("sys_pie_canvas").add(pie);
            }
          };
      
          // Load the visualization api, passing the onLoadCallback 
          // to be called when loading is complete.
          VisualizationUtils.loadVisualizationApi("1.1", onLoadCallback,
              PieChart.PACKAGE);
        }
      I would like to be able to place the "chart" in a nested layout container (e.g. east) if possible?

      Cheers
      Rob
      Attached Files

      Comment


        #4
        Hi,

        After a bit more investigation I found this post (GWT layout gotcha) -> http://turbomanage.wordpress.com/2010/01/12/gwt-layout-gotcha/ on David Chandler's blog.

        Which states "One gotcha I’ve found is that you must be careful not to attach a widget to a DIV nested inside a DIV that is attached to a widget."

        Code:
        public class DashboardsView extends ViewWithUiHandlers<DashboardsUiHandlers> implements
          DashboardsPresenter.MyView {
        
          private static final String CONTEXT_AREA_WIDTH = "*";
          private static String html = "<div id=\"chart_nested_div\"> </div>\n"; 
          
          private VLayout panel;
          private HTMLFlow htmlFlow; 
        
          private PieChart pie;
        
          public DashboardsView() {
        
            panel = new VLayout();
            panel.setWidth(CONTEXT_AREA_WIDTH);
            
            htmlFlow = new HTMLFlow(html); 
            
            panel.addMember(htmlFlow);    
            
            loadVisualizationApi();    
          }
          
          @Override
          public Widget asWidget() {
            return panel;
          } 
        
          public void loadVisualizationApi() {
            
            Log.debug("loadVisualizationApi()");
            
            // Create a callback to be called when the visualization API has been loaded.
            Runnable onLoadCallback = new Runnable() {
              public void run() {
                
                Log.debug("onLoadCallback()");
        
                pie = new PieChart(createTable(), createOptions());
        
                RootPanel.get("chart_sibling_div").add(pie);
                // RootPanel.get("chart_nested_div").add(pie);
              }
            };
        
            // Load the visualization api, passing the onLoadCallback to be called when loading is complete.
            VisualizationUtils.loadVisualizationApi("1.1", onLoadCallback, PieChart.PACKAGE);
          }
        Host file:

        Code:
          <body>
        
            <div id="loading" style="display: block;position: absolute;top: 50%;left: 50%;
                 text-align: center;font-family: Tahoma, Verdana, sans-serif;font-size: 11px;">
              Loading
              <img src="images/loading.gif" />
            </div>
        
            <!-- OPTIONAL: include this if you want history support -->
            <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
                    style="position: absolute; width: 0; height: 0; border: 0"> 
            </iframe>
            
            <div id="chart_sibling_div"> </div>
        
          </body>
        The call to RootPanel.get("chart_sibling_div").add(pie) works as expected (albeit the chart isn't where I'd like it to be). However, the same call (using a nested div) "RootPanel.get("chart_nested_div").add(pie)" fails as per David's post.

        Code:
         
        
        [ERROR] Uncaught exception escaped
        java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
        at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:122)
        See also -> http://code.google.com/p/google-web-toolkit/issues/detail?id=3511

        Any suggestions much appreciated :-)

        Cheers
        Rob

        Comment


          #5
          Hi Rob,
          Please file an issue for this in tracker with a link to this thread. Also a minimal standalone testcase with an EntryPoint would help.

          Thanks,
          Sanjiv

          Comment


            #6
            Hi,

            Raised issue 584-> http://code.google.com/p/smartgwt/issues/detail?id=584

            And uploaded a minimal test case + screen shot.

            Cheers
            Rob

            Comment


              #7
              Hi,

              Some more feedback:

              The following will display the chart (in Chrome) in a nested layout container (see attached screen shot) but the image is hidden if you re-size the browser window.

              In FF3 the chart is not shown but if you re-size the browser window you can see it momentarily.

              Code:
              public class ContextArea extends VLayout {
                
                private static final String CONTEXT_AREA_WIDTH = "*";
                private static String html = "<div id=\"chart_nested_div\" style=\"position: absolute; z-index: 1000000\"> </div>\n"; 
              
                private HTMLFlow htmlFlow; 
              
                private PieChart pie;
              	
                public ContextArea() {
                  super();
                  
                  Log.debug("init Context Area()...");
              
                  this.setWidth(CONTEXT_AREA_WIDTH);
                  this.setBackgroundColor("#EEEEEE");
                  
                  htmlFlow = new HTMLFlow(html); 
                  this.addMember(htmlFlow);    
              
                  loadVisualizationApi();       
                }	
                
                public void loadVisualizationApi() {
                  
                  Log.debug("loadVisualizationApi()");
                  
                  // Create a callback to be called when the visualization API has been loaded.
                  Runnable onLoadCallback = new Runnable() {
                    public void run() {
                      
                      Log.debug("onLoadCallback()");
              
                      // pie = new PieChart(createTable(), createOptions());
                      // RootPanel.get("chart_sibling_div").add(pie);
                      // RootPanel.get("chart_nested_div").add(pie);
                      
                      drawChart();
                    }
                  };
              
                  // Load the visualization api, passing the onLoadCallback to be called when loading is complete.
                  VisualizationUtils.loadVisualizationApi("1.1", onLoadCallback, PieChart.PACKAGE);
                }  
                
                private native void drawChart() /*-{
                
                  // Create our data table.
                  var dataTable = new $wnd.google.visualization.DataTable();
                  
                  dataTable.addColumn('string', 'Task');
                  dataTable.addColumn('number', 'Hours per Day');
                  dataTable.addRows(5);
                  dataTable.setValue(0, 0, "Work");
                  dataTable.setValue(0, 1, 11);
                  dataTable.setValue(1, 0, "Eat");
                  dataTable.setValue(1, 1, 2);
                  dataTable.setValue(2, 0, "Commute");
                  dataTable.setValue(2, 1, 2);
                  dataTable.setValue(3, 0, "Watch TV");
                  dataTable.setValue(3, 1, 2);
                  dataTable.setValue(4, 0, "Sleep");
                  dataTable.setValue(4, 1, 7);
                  
                  // Instantiate and draw our chart, passing in some options.
                  // var chart = new $wnd.google.visualization.PieChart($doc.getElementById('chart_sibling_div'));
                  var chart = new $wnd.google.visualization.PieChart($doc.getElementById('chart_nested_div'));
                  chart.draw(dataTable, {width: 400, height: 240});
              
                }-*/;  
              
                ...
              
              }
              Any suggestions?

              Cheers
              Rob
              Attached Files

              Comment


                #8
                Hi,

                A similar problem occurs when using FusionCharts:

                The following will display a FusionChart chart (in Chrome) in a nested layout container (see attached screen shot) but the image is hidden if you re-size the browser window.

                In FF3 the chart is not shown but if you re-size the browser window you can see it momentarily.

                Code:
                public class ContextArea extends VLayout {
                  
                  private static final String CONTEXT_AREA_WIDTH = "*";
                  private static String html = "<div id=\"chart_nested_div\"> </div>\n"; 
                  // private static String html = "<div id=\"chart_nested_div\" style=\"position: absolute; z-index: 1000000\"> </div>\n"; 
                
                  private HTMLFlow htmlFlow; 
                  private PieChart pie;
                	
                  public ContextArea() {
                    super();
                    
                    Log.debug("init Context Area()...");
                
                    this.setWidth(CONTEXT_AREA_WIDTH);
                    this.setBackgroundColor("#EEEEEE");
                    
                    htmlFlow = new HTMLFlow(html); 
                    
                    this.addMember(htmlFlow);    
                
                    // loadVisualizationApi(); 
                    
                    loadFusionChart();
                
                  }	
                  
                  public void loadFusionChart() {
                	  
                	Timer t = new Timer() {
                	  public void run() {
                	        	
                	    Log.debug("run()");
                	      
                	    Element div = DOM.getElementById("chart_nested_div");
                	      
                	    if (div != null) {
                	      Log.debug("DOM.getElementById(\"chart_nested_div\") - " + div.getId());
                	    }        
                
                	    drawFusionChart();
                	  }
                	};
                
                	// Schedule the timer to run once in 2 seconds
                	t.schedule(2000);	  
                  }
                  
                  public void loadVisualizationApi() {
                    
                    Log.debug("loadVisualizationApi()");
                    
                    // Create a callback to be called when the visualization API has been loaded.
                    Runnable onLoadCallback = new Runnable() {
                      public void run() {
                        
                        Log.debug("onLoadCallback()");
                
                        // pie = new PieChart(createTable(), createOptions());
                        // RootPanel.get("chart_sibling_div").add(pie);
                        // RootPanel.get("chart_nested_div").add(pie);
                        
                        Element div = DOM.getElementById("chart_nested_div");
                        
                        if (div != null) {
                          Log.debug("DOM.getElementById(\"chart_nested_div\") - " + div.getId());
                        }        
                        
                        // drawGoogleVisualizationChart();
                      }
                    };
                
                    // Load the visualization api, passing the onLoadCallback to be called when loading is complete.
                    VisualizationUtils.loadVisualizationApi("1.1", onLoadCallback, PieChart.PACKAGE);
                  }  
                
                  private native void drawFusionChart() /*-{
                    var fusionChart = new $wnd.FusionCharts("charts/fusioncharts/FCF_Column3D.swf", "chart_nested_div", "400", "300", "0", "1");           
                    fusionChart.setDataXML("<graph><set name='A' value='10' color='D64646' /><set name='B' value='11' color='AFD8F8' /></graph>");
                    fusionChart.render("chart_nested_div");
                  }-*/;  
                  
                  private native void drawGoogleVisualizationChart() /*-{
                  
                    // Create our data table.
                    var dataTable = new $wnd.google.visualization.DataTable();
                    
                    dataTable.addColumn('string', 'Task');
                    dataTable.addColumn('number', 'Hours per Day');
                    dataTable.addRows(5);
                    dataTable.setValue(0, 0, "Work");
                    dataTable.setValue(0, 1, 11);
                    dataTable.setValue(1, 0, "Eat");
                    dataTable.setValue(1, 1, 2);
                    dataTable.setValue(2, 0, "Commute");
                    dataTable.setValue(2, 1, 2);
                    dataTable.setValue(3, 0, "Watch TV");
                    dataTable.setValue(3, 1, 2);
                    dataTable.setValue(4, 0, "Sleep");
                    dataTable.setValue(4, 1, 7);
                    
                    // Instantiate and draw our chart, passing in some options.
                    // var chart = new $wnd.google.visualization.PieChart($doc.getElementById('chart_sibling_div'));
                    var googleChart = new $wnd.google.visualization.PieChart($doc.getElementById('chart_nested_div'));
                    googleChart.draw(dataTable, {width: 400, height: 240});
                
                  }-*/;  
                
                  ...
                
                }
                Cheers
                Rob
                Attached Files

                Comment


                  #9
                  Hi Rob,

                  GChart is not as sexy as the Google Viz, but perhaps the following code will be of some use/give you some ideas (see the code on resizing and removing/re-adding elements to the layout)

                  I know there was an issue with the new Google Viz tools, but I think it was fixed. In the past, I was able to get the older version of Google Viz working, but I have not had time to look at it since.

                  Code:
                  import com.googlecode.gchart.client.GChart;
                  import com.smartgwt.client.widgets.Canvas;
                  import com.smartgwt.client.widgets.events.DrawEvent;
                  import com.smartgwt.client.widgets.events.DrawHandler;
                  import com.smartgwt.client.widgets.events.ResizedEvent;
                  import com.smartgwt.client.widgets.events.ResizedHandler;
                  import com.smartgwt.client.widgets.events.VisibilityChangedEvent;
                  import com.smartgwt.client.widgets.events.VisibilityChangedHandler;
                  import com.smartgwt.client.widgets.layout.VLayout;
                  
                  public class GChartSmartGWT extends VLayout {
                  
                  	public GChartSmartGWT(final GChart gchart) {
                  		final Canvas canvas = new Canvas();
                  		canvas.addChild(gchart);
                  		canvas.setWidth100();
                  		canvas.setHeight100();
                  		addDrawHandler(new DrawHandler() {
                  			@Override
                  			public void onDraw(DrawEvent event) {
                  				updateSize(gchart, canvas);
                  			}
                  		});
                  		addVisibilityChangedHandler(new VisibilityChangedHandler() {
                  			@Override
                  			public void onVisibilityChanged(VisibilityChangedEvent event) {
                  				gchart.setVisible(event.getIsVisible());
                  			}
                  		});
                  		addResizedHandler(new ResizedHandler() {
                  			@Override
                  			public void onResized(ResizedEvent event) {
                  				updateSize(gchart, canvas);
                  			}
                  		});
                  	}
                  
                  	private void updateSize(final GChart gchart, final Canvas canvas) {
                  		int innerWidth = canvas.getInnerWidth();
                  		int innerHeight = canvas.getInnerHeight();
                  		int decoratedWidthOffset = gchart.getXChartSizeDecorated()
                  				- gchart.getXChartSize();
                  		int decoratedHeightOffset = gchart.getYChartSizeDecorated()
                  				- gchart.getYChartSize();
                  		int width = Math.max(0, innerWidth - decoratedWidthOffset);
                  		int height = Math.max(0,innerHeight - decoratedHeightOffset);
                  		gchart.setChartSize(width, height);
                  		gchart.update();
                  		if (hasMember(canvas))
                  			removeMember(canvas);
                  		addMember(canvas);
                  	}
                  
                  }

                  Comment


                    #10
                    We don't have this problem with the built-in FusionChart component or generally with Flashlet (not sure why Flashlet is not being used here).

                    However as far the problems you're seeing, also check the Watch tab to see component sizes. It's possible that the FusionChart and/or Google Visualization is registering as zero size or the wrong size. If this is timing-related, a call to canvas.adjustForContent() may fix it. Alternatively, if the embedded content is persistently being reported in the DOM as zero size, you can add another piece of content (like a big <img> tag) with size matching the intended size of the FusionChart in order to get it's intended size recognized.

                    Comment


                      #11
                      Hi,

                      I took a look at http://code.google.com/p/ofc4sgwt/ which extends smartGWT Flashlet.

                      And, it works as advertised:

                      Code:
                        ...
                      
                        public ContextArea() {
                          super();
                      
                          Log.debug("init Context Area()...");
                      
                          this.setWidth(CONTEXT_AREA_WIDTH);
                          this.setBackgroundColor("#EEEEEE");
                      
                          drawOfcChart(panel);
                        }
                      
                        private void drawOfcChart(VLayout panel) {
                          ChartWidget chartWidget = new ChartWidget();
                          chartWidget.setChartData(getSketchChartData());
                          chartWidget.setSize("400", "300");
                          panel.addChild(chartWidget);
                        }
                      
                        private ChartData getSketchChartData() {
                          ChartData cd2 = new ChartData("How many pies were eaten?", "font-size: 14px; font-family: Verdana; text-align: center;");
                          cd2.setBackgroundColour("#ffffff");
                          XAxis xa = new XAxis();
                          xa.setLabels("John", "Frank", "Mary", "Andy", "Mike", "James");
                          // xa.setMax(6);
                          cd2.setXAxis(xa);
                          SketchBarChart sketch = new SketchBarChart("#00aa00", "#009900", 6);
                          sketch.setTooltip("#val# pies");
                          sketch.addValues(Random.nextInt(6) + 1, Random.nextInt(5) + 1, Random.nextInt(3) + 1);
                          SketchBarChart.SketchBar skb = new SketchBarChart.SketchBar(Random.nextInt(5) + 5);
                          skb.setColour("#6666ff");
                          skb.setTooltip("Winner!<br>#val# pies");
                          sketch.addBars(skb);
                          sketch.addValues(Random.nextInt(5) + 1, Random.nextInt(5) + 1);
                          cd2.addElements(sketch);
                          return cd2;
                        }
                        
                        ...
                      And if you use a smartGWT Flashlet then FusionCharts will work with nested smartGWT layout containers.

                      Code:
                        ...
                      
                        <inherits name="com.smartgwt.SmartGwtPluginBridges" />
                        <script src="../charts/javascripts/FusionCharts.js"></script>
                      
                        ...
                      and

                      Code:
                        public ContextArea() {
                          super();
                      
                          ...
                      
                          loadFusionChart();
                        }
                      
                        public void loadFusionChart() {
                          Log.debug("loadFusionChart()");
                          
                          Timer t = new Timer() {
                            public void run() {
                      
                              drawFusionChart(panel);
                            }
                          };
                      
                          // Schedule the timer to run once in 2 seconds
                          t.schedule(2000);   
                        }  
                      
                        private void drawFusionChart(VLayout panel) {
                      
                          Flashlet fusionChart = new Flashlet();
                          fusionChart.setID("chart_nested_div");
                          fusionChart.setWidth(400);
                          fusionChart.setHeight(300);
                          fusionChart.setSrc("charts/fusioncharts/FCF_Column3D.swf");
                          fusionChart.setCodeBase("http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0");
                          fusionChart.setClassID("clsid:d27cdb6e-ae6d-11cf-96b8-444553540000");
                          fusionChart.setPluginsPage("http://www.macromedia.com/go/getflashplayer");
                      
                          Map<String, String> params = new HashMap<String, String>();
                          params.put("movie", "charts/fusioncharts/FCF_Column3D.swf");
                          params.put("flashvars", "&chartWidth=400&chartHeight=300&DOMId=chart_nested_div&registerWithJS=1&debugMode=0&dataURL=data.xml" );
                          
                          params.put("quality", "high");
                          fusionChart.setParams(params);
                          
                          panel.addMember(fusionChart);
                        }
                      No luck yet with nested smartGWT layout containers and the Google Visualization API (1.1).

                      Cheers
                      Rob
                      Last edited by robferguson; 13 May 2011, 19:55.

                      Comment


                        #12
                        There are any news regarding this issue?
                        No workarounds found to add a Google Visualization API component in a smartGWT layout?
                        Im currently having the same AssertionError: A widget that has an existing parent widget may not be added to the detach list.

                        Thanks.

                        Comment


                          #13
                          Hi,

                          No luck yet with nested smartGWT layout containers and the Google Visualization API (1.1).

                          However, you might find this post helpful -> http://uptick.com.au/content/smartgwt-and-fusioncharts

                          Cheers
                          Rob

                          Comment


                            #14
                            This worked for me.

                            Code:
                            package com.test.client;
                            
                            import com.google.gwt.core.client.EntryPoint;
                            import com.google.gwt.core.client.JsArray;
                            import com.google.gwt.user.client.Window;
                            import com.google.gwt.user.client.ui.HTMLPanel;
                            import com.google.gwt.user.client.ui.Panel;
                            import com.google.gwt.user.client.ui.RootPanel;
                            import com.google.gwt.visualization.client.AbstractDataTable;
                            import com.google.gwt.visualization.client.VisualizationUtils;
                            import com.google.gwt.visualization.client.DataTable;
                            import com.google.gwt.visualization.client.Selection;
                            import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
                            import com.google.gwt.visualization.client.events.SelectHandler;
                            import com.google.gwt.visualization.client.visualizations.PieChart;
                            import com.google.gwt.visualization.client.visualizations.PieChart.Options;
                            import com.smartgwt.client.widgets.HTMLPane;
                            import com.smartgwt.client.widgets.Label;
                            import com.smartgwt.client.widgets.events.DrawEvent;
                            import com.smartgwt.client.widgets.events.DrawHandler;
                            import com.smartgwt.client.widgets.layout.VLayout;
                            
                            public class GoogleVizTest implements EntryPoint {
                            	public void onModuleLoad() {
                            		// Create a callback to be called when the visualization API
                            		// has been loaded.
                            
                            		Runnable onLoadCallback = new Runnable() {
                            			public void run() {
                            
                            				final VLayout layout = new VLayout();
                            				layout.setWidth100();
                            				layout.setHeight100();
                            
                            				// HTMLPane pane = new HTMLPane();
                            				final Panel panel = new HTMLPanel("");
                            //				panel.setSize("100%", "100%");
                            
                            				// Create a pie chart visualization.
                            				PieChart pie = new PieChart(createTable(), createOptions());
                            
                            				pie.addSelectHandler(createSelectHandler(pie));
                            				panel.add(pie);
                            
                            				layout.addMember(panel);
                            				layout.draw();
                            			}
                            		};
                            
                            		// Load the visualization api, passing the onLoadCallback to be called
                            		// when loading is done.
                            		VisualizationUtils.loadVisualizationApi(onLoadCallback,
                            				PieChart.PACKAGE);
                            	}
                            
                            	private Options createOptions() {
                            		Options options = Options.create();
                            		options.setWidth(400);
                            		options.setHeight(240);
                            		options.set3D(true);
                            		options.setTitle("My Daily Activities");
                            		return options;
                            	}
                            
                            	private SelectHandler createSelectHandler(final PieChart chart) {
                            		return new SelectHandler() {
                            			@Override
                            			public void onSelect(SelectEvent event) {
                            				String message = "";
                            
                            				// May be multiple selections.
                            				JsArray<Selection> selections = chart.getSelections();
                            
                            				for (int i = 0; i < selections.length(); i++) {
                            					// add a new line for each selection
                            					message += i == 0 ? "" : "\n";
                            
                            					Selection selection = selections.get(i);
                            
                            					if (selection.isCell()) {
                            						// isCell() returns true if a cell has been selected.
                            
                            						// getRow() returns the row number of the selected cell.
                            						int row = selection.getRow();
                            						// getColumn() returns the column number of the selected
                            						// cell.
                            						int column = selection.getColumn();
                            						message += "cell " + row + ":" + column + " selected";
                            					} else if (selection.isRow()) {
                            						// isRow() returns true if an entire row has been
                            						// selected.
                            
                            						// getRow() returns the row number of the selected row.
                            						int row = selection.getRow();
                            						message += "row " + row + " selected";
                            					} else {
                            						// unreachable
                            						message += "Pie chart selections should be either row selections or cell selections.";
                            						message += "  Other visualizations support column selections as well.";
                            					}
                            				}
                            
                            				Window.alert(message);
                            			}
                            		};
                            	}
                            
                            	private AbstractDataTable createTable() {
                            		DataTable data = DataTable.create();
                            		data.addColumn(ColumnType.STRING, "Task");
                            		data.addColumn(ColumnType.NUMBER, "Hours per Day");
                            		data.addRows(2);
                            		data.setValue(0, 0, "Work");
                            		data.setValue(0, 1, 14);
                            		data.setValue(1, 0, "Sleep");
                            		data.setValue(1, 1, 10);
                            		return data;
                            	}
                            }

                            Comment


                              #15
                              Hi,

                              -> This worked for me.

                              Yes for me too, however, it does NOT work with nested (e.g. in cases where you don't call RootPanel.add or layout.draw directly) smartGWT layout containers.

                              Take a look at this post -> http://uptick.com.au/content/smartgwt-and-fusioncharts

                              which shows FusionCharts working with nested smartGWT layout containers.

                              See also Issue 584: Google Visualization API (gwt-google-apis) and nested smartGWT layout containers

                              Cheers
                              Rob

                              Comment

                              Working...
                              X