For a Perspective page- I want to put up a watermarked indicator over the entire window or just some components when a SQL query/data processing script is currently running, so that the user knows the data is still loading.
I vaguely recall an “IsLoading” property on some Vision components. Is there a similar mechanism in Perspective? If not, has anyone achieved this by alternative means?
Any update on this? I would also like to know if there is any kind of “isLoading” property for tables and graphs with lots of data. There can be a significant lag with no user feedback while they wait.
There are really two things that might come into play here:
1. Loading indicator for bindings.
Bindings produce values in an async way. Imagine you have a polling-off query binding. The view will start up, your property value will initially be whatever default it was set to in the designer or simply missing if set to non-persistent as the query executes. The query may take some significant amount of time to produce a result. During this time, the view and component are loaded and visible, but the binding is “loading”, and this is useful information that you might want to act upon. This is something we will be adding, and it is easy for us to do. It will be in the form of a new property on component meta like meta.loading which will be a count of bindings that are currently loading. You could use this to come up with some sort of “please be patient” UI of your own.
2. Loading UI indication for the loading of views, including embedded sub-views.
Imagine you navigate to a page configuration, and that it has some embedded sub-views. Then, those sub-views have more sub-views embedded in them, and on down the line. There could easily be hundreds of sub-views that get loaded in the process of loading that page configuration. Currently, each individual view gets its own, independent loading UI. This can look busy / messy for highly complex nested view configurations as all the views pop into place. It also causes some browser layout thrash along the way as the layout needs to be recomputed often as views load and learn of their true size. To make matters even more complicated, some embedded view configurations like view repeaters typically only know what sub-views will be in them when their bindings (which are async, remember) provide their data.
We’re working on some solutions to improve the look of this sort of loading scenario so that the whole page has a more pleasant / less thrash-ey “page is loading” look. This one is proving tricky to solve, however, because of the async/unknown nature of exactly how many views are going to be loaded before a page is considered “finished” loading.
We’re also working to simple improve the time it takes to load views, and we have made significant progress on this front steadily since 8.0.13, but there is still room to improve.
So I should be expecting to see a new component property called “meta.Loading” in a future release, but not a general view-level property for loading, correct?
Is the meta.loading feature available yet? If so, in what version?
I could really use this; I have a very large query that returns JSON to a table. I use a “Searching…” popup when the query is actually running, but I have to close the popup before the data is actually returned to the table. The query will finish running, close the popup, and then the table is empty for several seconds after the “Searching…” popup closes.
We use a binding and a transform script on the data prop. We call the “loading” indicator at the start of the transform, and the last thing before returning the data is to close the loading. Its seamless and there is no gap between the table populating and the loading indicator closing.
Obviously, the meta.loading will be better in the long run, but you should be able to simulate similar behavior now.
Thanks @ryanjmclaughlin. We are basically doing the same thing, but our issue is that the dataset is so large that there is a significant delay after returning the data in the transform statement. We have the “loading” animation when the query is actually running, but there are still several seconds between when the “loading” animation closes and when the table on the view actually displays the records.
For now, I have fixed this by only showing the first 500 records on the table as a “Preview” of the dataset. The main goal for this particular view is to export the data to Excel. I don’t have the problem with the loading animation when producing the Excel file because I can call the system.dataset.toExcel function before I close the loading animation. In fact, after we retrieve the data from the query, I update my “loading” animation with the number of records found while Ignition continues to generate the Excel file in the background.
I do pretty much exactly what @ryanjmclaughlin stated, but depending on what version of Ignition you’re running, the table may have an emptyMessage property. I don’t know the exact version this property was added, but I’m running 8.1.4 and it’s present on the table component. I just write "loading . . . " to the table’s props.emptyMessage.noData.text. It has the added benefit of letting you check the length of your list of json objects being written to the data property after your script has run and if it’s 0 you can write a nice no data message back to that same property so users aren’t left guessing whether the data has finished loading or not.
It’s marked as ‘incubating’ in our backlog, meaning we want to do it, but either we’re not sure how to do it, or we’re not sure in which way to do it, or we’re waiting on a major version to do it.
In this case it looks like ‘we’re not sure in which way to do it’.
Thought I'd share my workaround if anyone's still looking for a solution. Add a script transform after your query:
# show if no results were found
if type(value) == list and value == []:
self.props.emptyMessage.noData.text = "No Data"
elif str(type(value)) == "<type 'com.inductiveautomation.ignition.common.BasicDataset'>" and value.getRowCount() == 0:
self.props.emptyMessage.noData.text = "No Data"
else:
self.props.emptyMessage.noData.text = "Loading Results..."
return value
This will set noData.text so that if no results are found (for either a list or dataset value result) to "No Data", otherwise if results are loaded it'll set it to "Loading Results..." which won't display until next time the query runs with no data present in the table.
This fixes the issue with the significant delay after returning the data, regardless of if subsequent transforms are used. You can also adapt this to update the message between long running transforms such as changing the message to "Formatting Results" or something to let your users know things are still happening.