I have created, together with a "intern", a simple mobile app to introduce him into the wondrous world of application development. The app is a simple game statistics thingy in which you can input the datetime played and the rank you reached. 

In this app we also made a dashboard in which you can see a small overview of your statistics, times played, number of time won and a chart with the result of the last 50 matches.

The chart is causing us some issue. We want to use a line chart and the input struct is real simple. A record with a property called "Label" of type Text and a property called "Position" of type Integer.

The list has  5 records.

When we plot the chart it looks like this: 

When we change the line chart with a column chart it looks like this:

Mind you that the input is exactly the same. And we are sure we didn't change any inputs because we used the pulldown menu of the component to change its type. So the input is 100% the same in both cases.

The input looks like the following on both charts;


I read a thread about that a line chart can't have the same label in every column so I checked this with the debugchart to retrieve the underlying json and noticed some differences;

In the line chart there is an X property in the data series that is not in the column json.
In the column chart there is a listing of categories in the xAxis section that is not in the line chart.
Adding or removing these in the line chart json doesn't seem to do anything. 

Am I doing anything wrong here? I presumed this would be a simple action and the tutorial available is suggestion that but for some reason it doesn't seem to work this way.

The line chart JSON

{   chart\: {      plotShadow\: false,      type\: "line",      renderTo\: "b8-b1-chartcontainer",      height\: 300,      animation\: true,      backgroundColor\: "rgba(255, 255, 255, 0)"   },   title\: {      text\: ""   },   tooltip\: {      formatter\: function () { var date = new Date(this.x); return this.point.xTooltip ? this.point.xTooltip :  (chartdata.series.length>1 ? this.series.name + ', ' : '') + date.getFullYear() + '-' + ((date.getMonth()+1) < 10 ? '0' \: '') + (date.getMonth()+1) + '-' + (date.getUTCDate() < 10 ? '0' \: '') +date.getUTCDate() +'\:  <b>' + this.y +'</b>'; }   },   plotOptions\: {      pie\: {               },      series\: {         cursor\: "",         point\: {            events\: {                           }         },         dataLabels\: {            enabled\: false,            format\: ""         },         borderRadius\: 1,         borderWidth\: 0      },      line\: {         allowPointSelect\: false,         cursor\: "pointer",         dataLabels\: {            enabled\: false,            format\: ""         },         point\: {            events\: {                           }         },         marker\: {            enabled\: false         },         animation\: true      },      column\: {               },      area\: {               },      bar\: {               }   },   series\: [{         name\: "",         data\: [{               x\: 1558044000000,               marker\: {                  fillColor\: undefined               },               y\: 10,               color\: undefined,               xTooltip\: undefined            },{               x\: 1558044000000,               marker\: {                  fillColor\: undefined               },               y\: 7,               color\: undefined,               xTooltip\: undefined            },{               x\: 1558044000000,               marker\: {                  fillColor\: undefined               },               y\: 1,               color\: undefined,               xTooltip\: undefined            },{               x\: 1558044000000,               marker\: {                  fillColor\: undefined               },               y\: 34,               color\: undefined,               xTooltip\: undefined            },{               x\: 1558044000000,               marker\: {                  fillColor\: undefined               },               y\: 34,               color\: undefined,               xTooltip\: undefined            }],         point\: {            events\: {                           }         }      }],   legend\: {      enabled\: true,      floating\: false,      itemMarginBottom\: 10   },   xAxis\: {      type\: "datetime",      labels\: {         enabled\: false      },      title\: {         text\: ""      },      tickInterval\: 0,      min\: 1558044000000,      max\: 1558044000000   },   yAxis\: {      title\: {         text\: ""      },      reversedStacks\: true,      stackLabels\: {         enabled\: false      }   },   credits\: {      enabled\: false   }}

The column chart json: 

{    chart\: {       plotShadow\: false,       type\: "column",       renderTo\: "b6-b1-chartcontainer",       height\: 300,       animation\: true,       backgroundColor\: "rgba(255, 255, 255, 0)"    },    title\: {       text\: ""    },    tooltip\: {       formatter\: function () { return this.point.xTooltip ? this.point.xTooltip : (chartdata.series.length >1 ? this.series.name + ', ' : '') + this.x +'\:  <b>' + this.y +'</b>'; }    },    plotOptions\: {       pie\: {                 },       series\: {          cursor\: "",          point\: {             events\: {                             }          },          dataLabels\: {             enabled\: true,             format\: ""          },          borderRadius\: 1,          borderWidth\: 0       },       line\: {                 },       column\: {          allowPointSelect\: false,          cursor\: "pointer",          dataLabels\: {             enabled\: false,             format\: ""          },          point\: {             events\: {                             }          },          marker\: {             enabled\: false          },          animation\: true       },       area\: {                 },       bar\: {                 }    },    series\: [{          name\: "Last 50 matches",          data\: [{                y\: 10,                color\: undefined,                xTooltip\: undefined             },{                y\: 7,                color\: undefined,                xTooltip\: undefined             },{                y\: 1,                color\: undefined,                xTooltip\: undefined             },{                y\: 34,                color\: undefined,                xTooltip\: undefined             },{                y\: 34,                color\: undefined,                xTooltip\: undefined             }],          point\: {             events\: {                             }          }       }],    legend\: {       enabled\: true,       floating\: false,       itemMarginBottom\: 10    },    xAxis\: {       categories\: ["2019-05-17 01:21:09","2019-05-17 02:21:00","2019-05-17 02:34:00","2019-05-17 02:44:00","2019-05-17 02:54:00"],       type\: "datetime",       labels\: {          enabled\: false       },       title\: {          text\: ""       }    },    yAxis\: {       title\: {          text\: ""       },       reversedStacks\: true,       stackLabels\: {          enabled\: false       }    },    credits\: {       enabled\: false    } }

A small after weekend bump hoping that someone knows the solution :) 

Hi Vincent,

I didn't look in detail to the JSON, but the problem is likely your X-value is the same for all datapoints.

Hi Kilian,

I know that the labels are the same in the json output. It is not in the same in the input object. And since all other chart types work I suspect a bug in the linechart and I'm now looking for confirmation that I either did something wrong or there is indeed a bug. 

Note that I don't generate the JSON, that is Outsystems doing. 

Hi Vincent,

The bar chart works because out desks with the input differently, but as you can see it doesn't have labels on the x-axis, which it should have if the data were correctly supplied. So instead of blaming OutSystems, I would advise you to check your code, since it has a bug in it, not setting the right data. Debugging is the magic word!

Hi Kilian,

I should have mentioned that I hid the x-axis. The label is to long for a nice display (a date time). If I plot the label it shows the correct text (a datetime) in the column chart but a null date in the line chart. A null date isn't even in the input variable so this is part of the same puzzle.

And I'm not blaming OutSystems, I'm trying to understand what it happening since even after debugging I can't figure it out and the documentation is not helping me any further. Note that I was always open minded in this thread, that I could be the problem but that I suspect an issue with the platform due to the results of my debugging. I suspect that the widget is not picking up my, all unique, labels. And that even when I supply a JSON that has unique labels (since in the json the labels are not unique) the chart is still not plotting correctly. 

So again I'm hoping that someone is able to point me into the right direction :) 

In that case, could you post an example module that shows this behaviour?

Sure. This is the app in question. You first need to add some data to the database via the "New" bottom bar button. Then you can view the data via the Dashboard. 

Note that the line chart is a copy of the column chart and only the source block property has been changed.

Don't mind the strange thing I did with the input object (a conversion of datetime to string), this was to make sure that a datetime input was not the problem.

Solution

Some observations, not necissarily related to your problem:

  • Instead of using a For Each with a ListAppend, just assign Last50Matches.List to LineChartStruc, using the same mapping. This is slighlty faster.
  • Also, why do you use your own structure instead of DataPoint? Now you need to covert again when assigining the local variable to the chart.
  • Since you refresh the TotalMatches, TotalWon and Last50Matches in the GetModusOnAfterFetch, those queries will run twice, and so will their OnAfterFetches. Why are you refreshing those queries? (I understand you're setting ModeId, but that could be handled differently (like setting a Default Value). Also, there's no Sorting, so you get a semi-random mode.)

That said, I found the bug. It's a weird one, in that the same in a Web App does work I think. Also, if you had debugged, you would've found it! Always debug properly :). The problem lies in the ListAppend in Last50MatchesOnAfterFetch: in the mapping, you use "Last50Matches.List.Current.Statistic.DateTime". Instead, you should use "Statistic.DateTime". Apparently, the List.Current always points to the first element (as opposed to Web, where, iirc, it doesn't matter if you explicitly use the List.Current). When debugging, I found that the LineChartStrucs list contained the same date for each element. Removing the "Last50Matches.List.Current" made it work.

EDIT: Included the version I came up with.

Solution

Hi Kilian,

Thanks for all the tips. I'll be sure to pass them on.

I'll will try your fix and check the internal variables after doing so. I'm almost sure I did that and that the labels where unique (since the same labels are also shown in the bar chart). Always good to learn new things :)

Thank you very much for your help!

You're most welcome. Happy coding!