Blog

Dojox Charting Update – Part One

  |   Blog   |   8 Comments

It’s over three years since my last blog post on the charting options available with Dojo. At that time the version of Dojo in XPages would have been later than 1.6, when a major overhaul of Dojo for AMD processing had taken place. But then and afterwards I didn’t revisit the code to load Dojo charts. This week I needed to create some charts again, so took a step back and looked at the documentation on the Dojo site (there’s also the reference guide). Although a lot of the functionality has been around since my first blog post tutorials in 2009, there are some useful additions as well as changes that make setting up the charts – particularly in an XPages context – much easier.

To re-cap on the basics, the original process involved a number of steps:

  • Adding the relevant Dojo modules to the XPage / Custom Control
  • Adding divs to hold elements, typically as standard HTML divs (so the IDs are easier to reference). If you want to include multiple instances on a page, my typical approach is to create a custom property on the Custom Control (e.g. chartKey), into which I pass a unique reference, and then set the div ID to #{compositeData.chartKey}chart.
  • Add Computed Field controls to write the data for the chart onto the XPage as inline JavaScript. Typically the data was created via a loop in SSJS, manually generating the JSON string.
  • Add an Output Script control into which the JavaScript function to generate the chart is added and subsequently called via XSP.addOnLoad().

As my XPages and Java experience has developed, that now feels awkward and a little prone to error. Dojo modules may get missed off or new modules not added when amending the function. Generating JSON manually is cumbersome and far from preferable after using JsonJavaObject and JsonJavaArray. Writing inline JavaScript on the XPage in a Computed Field seems a bit of a hack and, although it allows you to see the output, debugging can also give you that. And calling XSP.addOnLoad has some limitations.

The newer Dojo code allows modules to be loaded inline and it allows for use of dojo/domReady! to wait and only render the chart when Dojo has finished loading. That’s two steps overcome. Using Java and IBM’s JsonJavaObject or JsonJavaArray allows creation of JSON data on-the-fly for the chart, and that can then be passed into the Output Script control that contains everything else. So now there are just two components on the page – the div and the Output Script control. That makes this much neater, cleaner and less error prone. In the next part I’ll take a couple of the original examples I used back in 2009 and update them to the new code. Of course those not yet comfortable with Java will be able to mix the Computed Fields of the original examples with the Output Script control of the new. But those getting into Java will be able to see the conversion from SSJS and Computed Fields to a Java method that outputs the same kind of thing.

AUTHOR - Paul Withers

Paul Withers has been an IBM Champion since 2011, has been an OpenNTF Board Member since 2013, has worked with XPages since 2009, co-authored XPages Extension Library and was technical editor for Mastering XPages 2nd Edition. He is one of the developers on OpenNTF Domino API as well as contributor to a variety of other OpenNTF projects.

8 Comments
  • Richard Moy | Jul 20, 2017 at 4:46 pm

    Paul,

    I find the dojox/Chart heavy and slow. I would recommend using Chartjs 2.0 It is much lighter and easier to use. I use this with Dojo 1.11 currently.

    • Paul Withers | Jul 26, 2017 at 8:42 am

      That looks very useful and 2.0 seems to cover all scenarios I’ve typically required (clickable legend, drill-down, combination charts). How does it work alongside the AMD loading of Dojo? I’ve hit complications with other JS libraries that conflict with AMD loading. It’s possible a Chart component could be extended to use Chart.js instead of Dojo. Some properties might need amending, but overall it may just need a different renderer.

  • Cameron Gregor | Jul 20, 2017 at 8:30 pm

    do you think these would be suitable for a new set of extlib dojo chart controls?

    • Paul Withers | Jul 26, 2017 at 8:15 am

      I’ve always thought it couldn’t work because of the variety of options. But I realise that’s because I’ve considered them as “Line chart” component, “Bar chart” component etc. Now I think about it again, and with deeper understanding of creating components, complex types etc, it may be feasible to have a Chart component, requiring one or more plot complex types (element 0 would be default), each plot taking one or more series complex types; the Chart would also allow one or more animations and Legend / Selectable Legend. With a single component, the HTML divs could easily be generated by the renderer and the JS generated. Although I’ve come to learn that writing JS in Java is what Stephan Wissel rightly bemoans as “frankencode” – it’s a challenge to get the right output! The whole thing would not be straightforward, but I now think it is achievable.

      • Cameron Gregor | Aug 10, 2017 at 1:24 pm

        i was wondering if there might be a way to standardize some categorized view designs to use as series data. e.g. a bar chart control, point it at a view, specify some data range and the control does the rest
        i hope to look into it one day when i get a chance!

        could mean making charts is as easy as designing the views

        • Paul Withers | Aug 10, 2017 at 1:59 pm

          Possibly, a dominoViewSeries object that takes viewName, categoryName, columnNumber / columnName. With FP9 out at the end of the month I think my priority needs to be a new FP8 ODA release and an FP9 ODA release (if no new APIs are added, the FP9 one won’t be hard).

  • Sean Ding | Aug 6, 2017 at 8:38 am

    Hi Paul:
    thanks for your article first, but can i ask something other than the problem? fact, I’m just doing a project to create chart on xpages, I need to read data from SQL(user want me to show every database’s size monthly online), for me now, I’m wonder which method I can use to create chart now, I mean, the dojox things you write it’s a little complicated to me, and I found google chart api is enough for me, actually I find some article about how to use it: http://www-10.lotus.com/ldd/xpagesforum.nsf/xpTopicThread.xsp?documentId=23CFCCB2F21E437585257DE300176578 , the question it’s how to get the array data? I’m not sure you read it before or not, I mean in this example, the data is fixed in csv which lays in webcontent folder, and have to “place” the webcontent folder, but I need to show dynamic data, then I just lost my way, I have to create this chart on client-side in the onclientload event, then is that possible to get array data with viewscope or something like that? now you see, I’m completely new on xpages….

    would you like to give me some advice? thanks~should I use the google chart or need to study the dojo method?

    • Paul Withers | Aug 7, 2017 at 7:29 am

      As Richard’s comment showed, there are a variety of options for charting. The key to which to choose comes down to a few things. Documentation and ease of use should be a major one. Functionality should be another – why spend ages working with charting framework A, when your app then needs a type of chart or functionality that’s not available in that framework. Performance is another, but the topic of performance is a whole separate blog post (and a long one too). In most case, the data needs to be JavaScript. So you need some server-side code to generate that. In terms of SQL, I don’t have much experience of calling SQL. But Extension Library gives SSJS functions for getting SQL data, so that would be my recommended starting point. You’ll then need to iterate over the result of your SQL query, to create the array data ready for the XPage. The sample will show you the format required. Creating that as a text string is the most basic option, because it needs to be inserted into JavaScript, which is text written on the web page. I’d recommend breaking it into those steps – get the data from SQL; then put it into the text string in a field on the page and have a version you can use to debug if there are errors (that’s a key part of what I originally did); then insert that content into the JavaScript code in an Output Script block (you need to use the “Other…” option in controls palette to get that). onclientload event is just writing a string of text to the browser, and that text gets evaluated as JavaScript by the browser. #{id:myField} gets the ID of a field, and standard JavaScript can get the value for a field or inner HTML of a span once it knows the ID.

Post A Comment