Search code examples
javagwtproxygxt

GXT-3 issue to load data for my Chart


My problem is annoying. My server side is generating 12 random numbers (double here).

My Client side received the correct data but nothing is displayed in my Chart. That worked fine with hardcoded data in the store but not with a REST call.

The transfer between my server and my client is that :

[{"key":"key0","value":0.47222548599297787},{"key":"key1","value":0.6009173797369691},{"key":"key2","value":0.13880104282435624},{"key":"key3","value":0.01804674319345545},{"key":"key4","value":0.5547733564202956},{"key":"key5","value":0.8229999661308851},{"key":"key6","value":0.8959346004391032},{"key":"key7","value":0.6848052288628435},{"key":"key8","value":0.10222856671111813},{"key":"key9","value":0.6931371931409103},{"key":"key10","value":0.2994297934549003},{"key":"key11","value":0.47566752196381334}]

Here my simple class used for my test. I am a newbie with GXT 3

public void onModuleLoad() {

    final ListStore<JSOModel> store;
    final ContentPanel panel  = new FramedPanel();
    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "/ws/DocumentService/v1/test");
    builder.setHeader("Accept", "application/json");

    HttpProxy proxy = new HttpProxy(builder);

    final Loader<ListLoadConfig, ListLoadResult<JSOModel>> loader = new ListLoader<ListLoadConfig, ListLoadResult<JSOModel>>(proxy, new DataReader<ListLoadResult<JSOModel>, String>() {
        @Override
        public ListLoadResult<JSOModel> read(Object loadConfig, String data) {
            List<JSOModel> jsoModels = new ArrayList<JSOModel>();
            JsArray<JSOModel> jsoModelJsArray = JSOModel.arrayFromJson(data);
            if(jsoModelJsArray != null) {
                for(int i = 0; i < jsoModelJsArray.length(); i++) {
                    jsoModels.add(jsoModelJsArray.get(i));
                }
            }

            return new ListLoadResultBean<JSOModel>(jsoModels);
        }
    });

    store = new ListStore<JSOModel>(new ModelKeyProvider<JSOModel>() {
        @Override
        public String getKey(JSOModel item) {
            return item.get("key");
        }
    });

    loader.addLoadHandler(new LoadResultListStoreBinding<ListLoadConfig, JSOModel, ListLoadResult<JSOModel>>(store) {
        @Override
        public void onLoad(LoadEvent<ListLoadConfig, ListLoadResult<JSOModel>> event) {
            ListLoadResult<JSOModel> loaded = event.getLoadResult();
            if(loaded.getData() == null) {
                store.replaceAll(new ArrayList<JSOModel>());
            } else {
                store.replaceAll(loaded.getData());
            }
        }
    });

    Chart<JSOModel> chart = new Chart<JSOModel>();
    chart.setStore(store);
    chart.setShadowChart(true);

    NumericAxis<JSOModel> axis = new NumericAxis<JSOModel>();
    axis.setPosition(Chart.Position.LEFT);
    axis.addField(new ValueProvider<JSOModel, Number>() {
        @Override
        public Number getValue(JSOModel JSOModel) {
            return JSOModel.getNumber("value");
        }

        @Override
        public void setValue(JSOModel JSOModel, Number number) {

        }

        @Override
        public String getPath() {
            return "key";
        }
    });
    axis.setTitleConfig(new TextSprite("Number of hits"));
    axis.setWidth(50);
    axis.setMinimum(0);
    axis.setMaximum(100);
    chart.addAxis(axis);

    PathSprite odd = new PathSprite();
    odd.setOpacity(1);
    odd.setFill(new Color("#dff"));
    odd.setStroke(new Color("#aaa"));
    odd.setStrokeWidth(0.5);
    axis.setGridOddConfig(odd);

    CategoryAxis<JSOModel, String> horizontalAxis = new CategoryAxis<JSOModel, String>();
    horizontalAxis.setPosition(Chart.Position.BOTTOM);
    horizontalAxis.setField(new ValueProvider<JSOModel, String>() {
        @Override
        public String getValue(JSOModel JSOModel) {
            return  JSOModel.get("key");
        }

        @Override
        public void setValue(JSOModel JSOModel, String s) {

        }

        @Override
        public String getPath() {
            return "key";
        }
    });
    horizontalAxis.setTitleConfig(new TextSprite("month of year"));
    chart.addAxis(horizontalAxis);

    LineSeries<JSOModel> column = new LineSeries<JSOModel>();
    column.setYAxisPosition(Chart.Position.LEFT);
    column.setStroke(new RGB(148,174,10));
    column.setHighlighting(true);
    chart.addSeries(column);

    axis.addField(column.getYField());
    chart.addSeries(column);

    chart.setHeight(100);
    chart.setWidth(100);

    Button b = new Button("ha");
    b.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent clickEvent) {
            loader.load();
        }
    });

    RootPanel.get().add(b);



    panel.setCollapsible(true);
    panel.setHeadingText("Column Chart");
    panel.setPixelSize(620, 500);
    panel.setBodyBorder(true);


    VerticalLayoutContainer layout = new VerticalLayoutContainer();
    panel.add(layout);

    chart.setLayoutData(new VerticalLayoutContainer.VerticalLayoutData(1,1));
    layout.add(chart);

    chart.setBackground(new Color("#dff"));
    RootPanel.get().add(panel);

Solution

  • There are two ways to wire the chart into a store. One is to simply specify that the chart is using a store via setStore, as you have done:

        chart.setStore(store);
    

    When you do this, you must also inform the chart when it must redraw everything - you must call:

        chart.redrawChart();
    

    This call must be made shortly after the load is completed - consider doing it at the end of onLoad.

    Why is this required? In some cases, developers want to make many changes to the store, one at a time, and if the chart automatically updated after each change, that would spawn many slow changes to the data model, and could end up looking strange. In a case like this, you would only call redrawChart() after all changes were complete.

    There is another option however - instead of calling setStore, you can call bindStore, and ask the Chart to automatically update whenever any change occurs to the chart:

        chart.bindStore(store);
    

    In your case, this is likely the correct answer.