简体   繁体   中英

Issue implementing sample line chart from Chartis.js using GWT JSNI native method

I'm currently trying to recreate a sample line chart code from Chartist.js using the below Javascript code and convert to GWT JSNI native method. When I tried executing the JSNI method, the output returns unexpected result as shown in first screen shot. However when i tried to execute the Javascript code in IE's developer console, it produces the right output as shown in the last screen.

What went wrong with JSNI GWT method code below? Thanks.

Javascript code

var data = {
    labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
    series: [[5, 2, 4, 2, 0]]};

var options = {
    width: '300px',
     height: '200px'
};

new Chartist.Line('#chartTest', data, options);

JSNI GWT method

public native void createChart() /*-{
        var data = {
        labels: ["Mon", "Tue", "Wed", "Thu", "Fri"],
        series: [[5, 2, 4, 2, 0]]};
        var options = {
          width: "300px",
          height: "200px"
        };
        new $wnd.Chartist.Line("#chartTest", $wnd.data, $wnd.options);
    }-*/;

JSNI GWT Native method output

Javascript code

Too many $wnd s in your code. Only put them where you are referencing some global object, not for local variables. When you construct the new Line , (in the namespace Chartist which is global), you need the $wnd prefix for Chartist but not for your local variables data and options :

public native void createChart() /*-{
    var data = {
    labels: ["Mon", "Tue", "Wed", "Thu", "Fri"],
    series: [[5, 2, 4, 2, 0]]};
    var options = {
      width: "300px",
      height: "200px"
    };
    new $wnd.Chartist.Line("#chartTest", data, options);
}-*/;

Edit: Okay, I think I figured it out. There is a "bug" in Chartist that prevents it from understanding your data ( https://github.com/gionkunz/chartist-js/blob/master/dist/chartist.js#L460 ):

} else if(value instanceof Array) {

This line of JS checks if your series values is an array, but not in the way you think - unlike Java, it doesn't check to see if the reference points to an array, but if the constructor that creates that object is the same object as Array is - and in your case, they are not the same - arrays are not always Arrays. In GWT, this is specifically because all GWT code is run in an iframe to avoid accidentally interfering with the page's own JS.

The library should be checking with Array.isArray(value) , but in lieu of that, you can change how you create the array to use the expected constructor for the main page, via Array.from , Array.of , or new Array . Here's a quick example of doing it with Array.of :

public native void createChart() /*-{
    var data = {
      labels: Array.of("Mon", "Tue", "Wed", "Thu", "Fri"),
      series: Array.of(Array.of(5, 2, 4, 2, 0))
    };
    var options = {
      width: "300px",
      height: "200px"
    };
    new $wnd.Chartist.Line("#chartTest", data, options);
}-*/;

It is possible that the same sort of problem will happen in the literal object creation too, but I'd need a full working sample or more error messages to verify this...

this works for me

private static native void run (Element element) /*-{
var data = {
    labels : $wnd.Array("Mon", "Tue", "Wed", "Thu", "Fri"),
    series : $wnd.Array($wnd.Array(5, 2, 4, 2, 0))
};
var options = {
    width : "300px",
    height : "200px"
};
new $wnd.Chartist.Line(element, data, options);
}-*/;

Edit: this will also work

var data = $wnd.JSON.parse('{"labels" : ["Mon", "Tue", "Wed", "Thu", "Fri"],"series" : [[5, 2, 4, 2, 0]]}');

where as this does not

var data = JSON.parse('{"labels" : ["Mon", "Tue", "Wed", "Thu", "Fri"],"series" : [[5, 2, 4, 2, 0]]}');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM