1

Hello I am using Vaadin 8 and Vaadin charts 4.0 and am trying to format one of the data axis of the chart to different date time formats depending on user format input and locale. I try to inject the moment.js library and get a reference exception saying that moment variable does not exist. I have tried 2 different approaches which I list below:

(1) Use the @JavaScript annotation to inject moment.js.

@JavaScript({"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js", "https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"})
@WebServlet(urlPatterns = "/*", name = "IeUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = IeUI.class, productionMode = true, heartbeatInterval = 500, closeIdleSessions = false, widgetset = "softcom.ievaadin.AppWidgetSet")

public static class IeUIServlet extends VaadinServlet implements SessionInitListener {//, SessionDestroyListener {

    @Override
    protected void servletInitialized() throws ServletException {
        super.servletInitialized();

        // Add any system level init here
        //Main.initSystem();

    }

    @Override
    public void destroy() {
        super.destroy(); //To change body of generated methods, choose Tools | Templates.

        Main.destroy();
    }

    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException {
        event.getSession().getSession().setMaxInactiveInterval(-1);
    }
}

And the one where set the formatter

YAxis ya = new YAxis();
String js = "function() {";
js += "try {"
                        + "var g = moment.tz(\"2014-06-01 12:00\", \"America/New_York\");"
                        + "alert(g);"
                        + "return g;}"
                        + "catch(e) {"
                        + "alert(e);}}";
ya.getLabels().setFormatter(js);

(2) I try to append the script tag at the head in the function itself.

String js = "attempt {"
                        + "var script = document.createElement('script');"
                        + "script.src = \"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js\";"
                        + "document.head.appendChild(script);"
                        + "} catch(e) {"
                        + "alert('first one'); }"
                        + "try {"
                        + "var b = moment().format();"
                        + "return b;"
                        + "} catch (e) {"
                        + "alert(e); }";

                JavaScript.getCurrent().execute(attempt);
String js = "function() {";
js += "try {"
                        + "var g = moment.tz(\"2014-06-01 12:00\", \"America/New_York\");"
                        + "alert(g);"
                        + "return g;}"
                        + "catch(e) {"
                        + "alert(e);}}";
ya.getLabels().setFormatter(js);

Any help would be appreciated.

ewolden
  • 5,722
  • 4
  • 19
  • 29
  • I'm not the Vaadin and Java expert, but as I know, Highcharts checks whether the `moment` is available on the browsers `window` object. Additionally, in order to use `tz()` function, you need to also inject the `moment-timezone` expansion. – daniel_s Aug 28 '18 at 07:33

2 Answers2

0

Some possible (pure Vaadin) approaches:

1) Customizing the labels: mychart.getConfiguration().getxAxis().setDateTimeLabelFormats(dateTimeLabelFormats);

2) Customizing the timezone & offset:

JavaScript.getCurrent().execute("Highcharts.setOptions({\n" +
" global: {\n" +
"  useUTC: true,\n" +
"  timezoneOffset: "+ timezoneOffsetInMinutes + "\n" + 
" }\n" +
"});");

3) Configuring the tooltip with a user-friendly datetime format:

DataSeriesItem dataSeriesItem;  
Date datetime = ...;
if (useUTC) {                                   
    dataSeriesItem = new DataSeriesItem(datetime.toInstant(), value);
} else {
    dataSeriesItem = new DataSeriesItem(datetime, value);
}   
dataSeriesItem.setId(xxxxx); // <= string with desired user/locale-dependant formatting of related datetime
TacheDeChoco
  • 3,683
  • 1
  • 14
  • 17
  • These approaches as you mentioned require me to do the formatting in vaadin, I want to use the formats provided to me moment.js because I have to do around 56 date time formats with locale support which they provide. But I might have to do it this way if I cannot include the file. – Ujjawal Tivari Aug 28 '18 at 18:42
0

You can inject the script tag in the head of the document by registering a BootstrapListener in your IeUIServlet:

        @Override
        protected void servletInitialized() {
         getService().addSessionInitListener(event -> {
          event.getSession().addBootstrapListener(new BootstrapListener() {
           @Override
           public void modifyBootstrapPage(BootstrapPageResponse response) {
            response.getDocument().head().append("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js\"></script>");
            response.getDocument().head().append("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js\"></script>");
           }

           @Override
           public void modifyBootstrapFragment(BootstrapFragmentResponse response) {

           }
          });
         });
        }

And preprend $wnd to moment in your javascript, like this:

var g = $wnd.moment.tz(\"2014-06-01 12:00\", \"America/New_York\");
Tulio
  • 432
  • 2
  • 4
  • I attempted this but the formatter gave the same reference exception for moment object. When I check the html that is generated by vaadin, I see the script reference for moment.js but it seems they are not seen by the js being executed in the setFormatter method of the axis. – Ujjawal Tivari Aug 29 '18 at 19:40
  • I tried it out and updated the answer. Check if it works now. – Tulio Aug 31 '18 at 07:55