Highcharts and Ajax

  
Hi all,

Does anybody with experience using Highcharts (the charts that come with the system components 8.0) has had any problems using Ajax Refresh on them?
I have a chart inside a container (it's working fine), but when I "Ajax Refresh" the container due to some user selections on the screen, the chart isn't redrawn.

Can anyone help?

regards
Hi Gonçalo,

Did you refresh the data that is binded to the chart? If possible show us how you configured the chart, what are the values for the input parameters.

Cheers
Hi André,

Yes I'm refreshing the data.
The thing is, I'm not using the Outsystems Charts, but another oml that uses the Highcharts. I'm using another oml because the Outsystems Charts doesn't provide all the charts functionalities that I need to format the chart.

I'm guessing that the problem resides in my initialization of the chart, that must be different (somehow) from your. I asked the support if they can give me a editable version of the charts oml so I can see where my problem is.

But thanks anyway for your input.
Hi-
I am having a similar issue with the default RichWidget, so I will post my experience and hopefully this is helpful.

I am trying to build a simple prototype screen as shown.  I have verified that I can build a functional chart with data if it is based on a full page refresh (e.g. building off the Preparation query).  And in the page entry screen shot I am just building an 'empty' chart by referencing a page variable named ChartList that is a RecordList of DataPoint objects.

When the user selects the inputs shown, the 'Create Chart' button calls an Action step that does some data munging (to convert the boolean to a value SQL Server will accept, simple stuff) and I have run it through Test SQL and through the debugger to show that the ChartList variable is properly updated with the list of values I want from the custom select.

When I get to the AjaxRefresh step in the Action, then the entire chart is blanked out (no axes or data at all).  I tried updating both my named Chart object and the named Container object I wrap the chart section in, but neither approach seems to work.

Appreciate any thoughts-- thanks!
Steve
Hi there. I developed several pages with charts updated upon ajax with no problems. Can you post an example oml? I can only think of one thing: your first chart is empty, maybe something isn t loaded. What if you put some data at first and then refresh with different data, does it work? What if you put tge chart in a webblock and refresh the whole webblock?

Hi Pedro--  Thanks much for the feedback.  This has puzzled me as I can get a normal chart to work fine, it is only when trying to use the Ajax Refresh that it's not working.  I was deliberately creating an empty chart at first since the user has not selected any of the inputs, but that single point 'default' chart does render okay on the Page Prep action. 

I agree that creating the empty chart at first may be creating some issue and I'll look at populating some default values or something to give it a good initial data set.  I did try your suggestion and separated the chart object into a Web Block -- it did not behave any differently.  It is interesting that I do get the selected animation action with the Ajax refresh, but the chart block is rendered completely empty (not even axes, etc.).  I posted the completely blank output as another attachment.  I may need to clean some of the source data in the .oml before I can post it.

The only difference here from my working chart example is that I am using a Local Variable of RecordList/ DataPoint type instead of referencing an Advanced Query to a DataPoint structure as with the working example.  But I have painstakingly compared the debugger structure values of the List Variable that is produced in the non-working example, and the Advanced SQL Query from the static page example, and they are identical.

A specific question, as I am still new to Outsystems -- when you are refreshing your forms, do you run the design the Screen Action from the parent page (e.g. where I have the 'Create Chart' button) to include the data refresh steps & then trigger the Ajax Refresh of just the chart?  Or do you put the data process in with the Web Block as an embedded screen action there as a Prep Action, and that is triggered with each Ajax Refresh.  Sorry if my question is difficult to explain.  Maybe the below is easier:

Is it more like (A):
-Click 'Create Chart' button on main page
-Calls Main Page Screen Action...
-     Action recalculates data from other input fields on main page
-     Action populates RecordList variable of DataPoints
-     Action triggers Ajax Refresh of Chart Web Block, which references the RecordList Variable

Or is it more like (B):
- Click 'Create Chart' button on main page
-    This action triggers Ajax Refresh of just the Web Block

- Web Block Prep Action executes the data refresh & etc etc
- My confusion with this design would be the plumbing for how the Web Block could 'see' the fields on the parent form to use in the data refresh.

I appreciate your help with my puzzlement.  I really enjoy the Outsystems platform and I assume this will end up being something so basic that I laugh about it when it becomes evident.

Steve
Hello Steve, any of the options will work. In option B, you will have to create input parameters on your webblock with everything it needs to know to be able to refresh the data itself. For instance, start date, end date, color, ... all would have to be parameters to your webblock with the chart, I assume.

Without the oml, it is difficult to check what the problem is! ;-)

But here are some things I would do to debug it:
- Ajax refresh, as I understood, works the following way: an ajax request is made to the server which returns an XML with a set of parameters indicating what parts of the screen will be refreshed, and the data to refresh it (I think it also returns actual HTML code to replace the existing one). Then, some javascript on the client side will do the refresh. Try using a tool like Fiddler to check what is being returned by the Ajax request. You should see something like "OsJSONUpdate(...)".
- Look for somehting like "var json = { ... " or "chart", see if you can find the data that you would expect for your chart.
- If nothing like this is returned, then the problem is some error in the server.
- If you can see your chart data being returned, then use dev tools on your browser (F12) to inspect the html before and after the refresh: check the element SVG (main element of the chart). Is it still there after the refresh? Does it have any content?
- Long shot: check if you are returning any "strange" characters, like ~ or < or >.

Let me know what you found.

Best regards,
Pedro Vieira

I am using the HighCharts of Sustem comoponents too, and refreshing with Ajax. No problem...
Pedro--
Thanks very much for your feedback, and by using the developer tools in the browser I can see what I think is causing the problem... I am not sure how this issue is being created though.
1) As I noted above, I have created one version of the chart page that does work, but it is a static page (i.e. the query is run once at Prep and it is not interactive).  That chart renders fine and I notice that the svg header has a setting like <svg width="940" height= "300" version="1.1"> 
2) In the chart that does not render properly, it appears the width setting is being set to 0 somehow??  It looks like this:  <svg width="0" height="300" version="1.1">  In drilling into the returned detail for the page it does appear the data is present, but this width property appears to be the issue.

I am guessing a chart with width = 0 does not display (ha).

Any ideas how this is happening inside the process?  I am never setting a width property for the object in any of my configuration items.

Thanks again for all your help--

Steve
Apologies for a second post so quickly, but one other interesting item I noted was that the style does appear different as well.

In the chart that works, on the right side of the debugger page it says "Inherited from div#highcharts-0"

In the chart that does not render properly, the same block reads "Inherited from div#highcharts-2"

I am not very strong on understanding the details of css at this level-- any ideas if this is contributing somehow?  How is this set when I am building the page template in Outsystems?

It also seems odd because the default chart block that renders (the "empty chart" I create before the user selects any objects to plot) does display properly.  It is only becoming corrupted during the Ajax refresh action somehow.

Thank you again!

Steve
Having some time to work on this today, I now see the issue appears not with Ajax!

My chart is a time-based plot, and I know that Highcharts is very sensitive to the data presentation of a date when used on the x-axis.

For the static chart that renders properly, I connect the chart input directly to an advanced SQL query output (using a Datapoints structure) where my SQL output of the SQL DateTime field generates data points on the chart that look like this:  d="M 8.96078 38.4214 L 9.05017 38.7826 L" (... and etc).  When connected directly to the SQL output, it appears to convert the DateTime data properly into a linear X-axis value the chart can read (in other words the 8.96078 is really a date sometime in 1987).

For the chart that does not work, I am populating the chart using a Local Variable, of RecordList type, of structure Datapoints.  I then run my Advanced SQL to a DataPoints output, and use an Assign step to fill the local variable.  I use a single assignment step that looks like  ChartPoints (variable) = FillChart.List  (where FillChart is the SQL Query).

When that renders, it generates data points like this:   d="M 0 38.4214 L 0 38.7826 L" ... and etc.  So all the x-axis values are 0!  Both queries output the same DateTime data field, so is the issue in how the Local Variable using a RecordList type would pass data to the chart differently than how a direct SQL connection would do it?

The DataPoint structure uses a 'text' datatype for the Label field (the x-axis) -- and I have checked the debugger and found the outputs there to be *identical* in both cases -- so it must be happening upstream somewhere?

I have not seen any guidance on Outsystems for using Dates inside charts re: populating the charts -- any ideas are welcome.  I'll see if I can rewrite the page to use a SQL query consistently that I can just execute a RefreshQuery action on.  I had been concerned this would not work properly for my design.

Thanks!!

Steve
OK, I had hoped to resolve this myself without uploading the big OML file, but I've hit my endpoint of confusion. 

I changed the chart to use a query object instead of the RecordList variable.  It renders fine on the Preparation step.  In the Chart Update action triggered by the button, when I trace in the debugger the data set output looks identical.  But when I look at the detailed output to the browser, the points get corrupted somehow during the refresh.  I don't understand why the style changes from 'highcharts-0' to 'highcharts-2' during the refresh, or why else the chart width is getting set to 0.

Is there a size limit to the OML that can be uploaded?  Mine is 17Mb but every time I try to choose it as an attachment it seems the page will not allow the upload.

Any help is much appreciated.

Thanks,

Steve
Hello Steve,
 
I digged a little bit, and I believe the values "M xxx yyy L zzz aaa bbb ..." define graphical dimensions of the graphical elements in the graph and not the dates. It seems that the values we pass in to highcharts are converted in graphical values and loose their original meaning, at least in the HTML.
 
You can check the javascript object to see the original values: on the developer tools console, write:

Highcharts.charts[0].series[0].data
(returns the array of points, where you can check x and y values)

or just use
 
Highcharts.charts[0].series[0].data[0].x
Highcharts.charts[0].series[0].data[0].y
Highcharts.charts[0].series[0].data[1].x
Highcharts.charts[0].series[0].data[1].y
...


If you think the problem is in the data convertion (which probably is), check your xAxis type: set your xAxisFormat attribute of the chart to a XAxisFormat structure, where you set ValueType to Auto. If this doesn't work, you can try to set the xAxisFormat to 'datetime'. Unfortunately outsystems doesn't have this option, so you have to use an advanced format. Set the chart AdvancedFormat attribute to an AdvancedFormat structure, and set the HighchartsJSON to the following text:
{
   xAxis: {
    type: 'datetime'
   }
}
You can use the HighchartsJSON to set any options Highcharts allows. If you have the opportunity, check http://api.highcharts.com/ for the full API, and http://www.highcharts.com/demo for many demo's.
 
Keep posting your updates, and try to upload that OML if still necessary... ;-)


Pedro - Thanks again, this is definitely showing progress.  Still not all the way there, but tantalizingly close?
I set the AdvancedFormat structure as per your guidance above, and interestingly...
1) The chart renders on Preparation exactly as expected (same behavior as before)
2) Upon a refresh, the chart area goes blank (as before)... BUT now when I select F12 to enable the developer tools... the new chart now appears!  This did not happen before.  (And behaves the same in IE and Chrome, no chart until selecting F12)

So now there is at least a way to get the chart to show itself... but what does the F12 invoke that the regular AjaxRefresh does not?

Andre gave me some guidance about removing the large Excel bootstrap files from the OML to bring the size down so that I can post it.  But if I do so won't that prevent you from being able to see the data I am working with?  Do you know what the OML file size limit is for an attachment?  I will try to strip down the sample data to just two examples or something.

Thank you again for your patient assistance and instruction.  The Highcharts capability is the primary object set I will want to work with for my Outsystems project, so I am very happy to be getting close!

Steve
Wow, entering the twilight zone, I see...
I once saw something similar: webpage behaviour was different when using F12 developer tools. I think it's because the browser adds something to the page when you press F12, or encapsulates it in some sort of container (div? frame? don't know), which makes it behave differently in some special situations: looks like you found one of those special situations. Don't know what is causing your problem, but will sure be nice to see the conclusion on this issue.

Are you sure you are not changing anything else when you refresh the page?
On situation 2) do you still start with an empty chart? Could it be that the div element containing the chart has width = 0?
Could you try with an empty page that only contains the chart, and nothing else?
Pedro-- Thanks for the continuing support.  Yes, this does feel very odd. 
There is no difference in the page design between steps 1 & 2 - it is the same page object and with step 2 I am merely clicking a button that refreshes the underlying chart query object for the user-selected input and then executing the AjaxRefresh for the chart widget.  I've debugged and looked at the query output for both the Prep and the Refresh steps, and the output is identical (I can even trigger the behavior by merely refreshing the 'default' settings executed when the Prep loads, i.e. it is literally and exactly the same set of data points in the Prep as in the Refresh- the Prep chart renders, the Refresh gives this odd behavior).
I will take the extra steps to build a simpler OML and take out all but this page with a minimal amount of data so I can post it.  I would really appreciate knowing what is going on - not so much that this specific example must be fixed, but this is a generic process I want to replicate across my application so it is important that I can refresh charts based on user-selected inputs on a page.

Thanks again for your assistance - most helpful to know I am not fighting this alone!
Steve
Pedro-- OK -- is fixed!  For whatever reason the page did not like the 'Vertical Slide' transition effect that I had selected for the refresh action.  When I removed the transition effect the chart  now refreshes and renders properly!  I did not require the transition effect, it is the chart refresh that was the big concern.

Thanks for the support-- I had checked that previously and removing it did not fix the issue, so the clue about specifying the axis 'datetime' property type was definitely a contribution to the solution.

I am excited to be past this odd issue and really appreciate the ideas and contributions!

Steve
Great! Mistery solved... it had to be something weird ;-)
I've had an issue related with this.

I had an client side accordion component that contains a chart. This accordion should start collapsed (with display: none;)

The problem is, when the accordion is expanded, the graph does not show up.

Together with R&D I've found a workaround forcing the chart to redraw.

All I had to do was executing a piece of javascript after expanding the accordion:

<script type=""text/javascript"">
<!--
var arrayLength = Highcharts.charts.length;
for (var i = 0; i < arrayLength; i++) {
    Highcharts.charts[i].callback(Highcharts.charts[i]);
}
//-->
</script>
this forces every chart to be redrawn after the accordion is expanded.

let me know if it helps on your scenario.
Thanks for posting.  I have the same problem with charts inside a clientside tab not rendering.  I finally ended up removing the tabs to get the chart to render.  I will now be able go back to the tab approach with your solution.
ok let me know the outcome of reintroducing the client side tabs ;)
João Melo wrote:
I am using the HighCharts of Sustem comoponents too, and refreshing with Ajax. No problem...
 Hi,
Can you suggest me how to work with Highcharts or how can I create Staked Column chart?

Its very urgent..

Regards,
Venkat Gude.
 

Hello,
You can use the AdvancedFormat_Init action to set the chart advanced format in JSON Format, and then use its output in the AdvancedFormat property of the chart.

You can find many examples of configurations you can do with Highcharts in the highcharts demo site, take a look at www.highcharts.com/demo/bar-stacked . Press 'Edit in Jsfiddle' to see the source. In this case, I believe you only have to set your advanced format to:
{
    plotOptions: {
            series: {
                stacking: 'normal'
            }
        }
}


Even I am also looked into it but I am not sure how can I use that code in Outsystems. Can you suggest any smart way to achieve this

Thanks,
Venkat.


Add a barchart to a page, and on the Preparation call de AdvancedFormat_Init action, and set the HighchartsJSON input parameter to the code below:

{
    plotOptions: {
            series: {
                stacking: 'normal'
            }
        }
}


Then you have to fill in the data points of the chart. You have to create a RecordList of datapoints, and add one datapoint for each "slice" of a bar in your chart. (See the record DataPoint of the Charts eSpace). The label will set the bar (in the example above, labels will be Apples, Oranges, Pears, ...). The DataSeriesName will set the series (in the example above, series will be Joe, Jane and John). And the value, of course it's the numeric value that sets the size of the slice.

Add all the records you want to the a Datapoint RecordList variable, than set the chart property SourceDataPointList to that variable, and set the AdvancedFormat to AdvancedFormat_Init.AdvancedFormat.

I did not test this, but I think it will work.

Let me know how this goes...
Hi All,

When using the chart Im noticing that all other buttons with a method of ajax submit are deactivated? How is this possible? Any advice on a fix?

Julius

Strange, that always worked on my pages...