Perspective: Designing a "table" for mobile and PC

I have a Flex repeater that I’m using to repeat a View to create a table of sorts.

I’m wondering how others would make this responsive so that it will work with mobile screens?

I have tried using a column container instead of a flex (as in screenshot), but I just couldn’t get it to display nicely. I want to display as many rows as possible on the page (without it looking terrible).

Should I just use a Breakpoint View and display the above for PC (within a flex container) and create another Flex View for mobile version that displays it nicely? I was hoping there was a nice way without having to duplicate work :thinking:

I always seem to have a hard time creating “Dynamic heights” between two different form factors like this.

Its really easy to put that first item in a breakpoint, but then you need it to be taller when smaller, so now do you just pick a comfortable height in the middle or what?

I would probably nest things this way:

-Breakpoint Container
------Flex repeater with wide view
------Flex repeater with tall view

Then create a custom property on the view itself for your data, bind both of the flex repeaters to that dataset, and manage any script interactions through messageHandlers on the breakpoint container.

That way you dont have to worry about replicating functionality.

This seems like a time when a Flex Repeater with an instanced View made from a Column Container would be ideal, as long as you want all of the same info conveyed in both the Desktop and Mobile device.

How would you get around the height issue, as @kgamble pointed out? You can’t set the height differently between different breakpoints, and I would need multiple lines to show on mobile if I was to use the column container

When you lay-out the breakpoint for the “smaller” sizes, move the components onto multiple lines (which it looks like you’ve done). In your case, it looks like you want three separate rows at the small breakpoint. You should also make sure that you set the default height of the Column View to something like… 40px? and make sure that the Flex Repeater has useDefaultHeight set to true. It looks like your “mobile” view is really just suffering from using extra blank space because you’re not limiting the space allocated to each instanced View.

I just tried this out and it doesnt seem to dynamically adjust the height

Here is my “Large” breakpoint for the column

My “Medium” height

Then my “Small” breakpoint

And as recommended (after taking those screenshots) I set the height to 40px

Then I create a flex repeater with the following properties

And this is the output

The desired output that we are looking for would automatically adjust the height of the repeated instances based off the breakpoint

Something like this (I manually changed the default height to visualize this)

In that case I think your best option is to use a value of “auto” for FlexRepeater.props.elementPosition.basis.

Unfortunately this seems to have resulted in no change

EDIT: I see below that @nminchin decided not to do this anyway, but I would still like to figure out how this works. As this has been something I have really struggled to figure out in Perspective

EDIT #2: Also here is a copy of what I am working with (12.9 KB)

I decided to not use the Column Container, as it just isn’t flexible enough to make the View look as I wanted it to. I went for the Breakpoint container with two separate Views:


Just working out the colours…


I was able to get a Column container View working perfectly fine (using @kgamble’s example):

The key to this is that I had to set the following properties:
FlexRepeater.props.elementPosition.basis: “auto”
FlexRepeater.props.elementPosition.grow: 0

1 Like

I got this working as well, I just also had to set FlexRepeater.props.elementPosition.shrink to 0

Here is an export that works for anyone that needs it!

Thanks @cmallonee! (14.2 KB)

1 Like

Hmm, so now I’ve run into memory issues with my flex repeater… and I’m only displaying 25 rows. I have 649 rows total I need to display. I thought by grouping them by displaying 100 at a time with the carousel container that I would be ok, but I can’t even get 25% of that before chrome crashes… We have the same information and more displayed in a similar table in Vision. It loads a little slow in Vision, takes maybe 5s-10s and that’s to load all 649 rows, but it never crashes! Is there anything else I can do, apart from reducing the number of rows further (making usability approach 0)

Just an untested thought, but how possible would it be for you to go the column container route where each is an embedded view in a table that props.virtualized is true?

Otherwise, are you generating all of your data and providing it to the view, or is each view collecting its own data? I have found often time that If I am able to read everything at once and then provide it to the view then I dont have near as many calls from my child views to slow things down.

To answer my own question, this definitely works and is unbelievably more efficient

I ran this with 10,000 instances with no issues. Granted my view is alot dumber than yours, but the virtualization premise should help yours out too. (14.4 KB)

1 Like

I’ll have to have a look at it tomorrow, it’s pretty late down under! Sounds interesting though.
Previously, I was creating the instances array for the flex repeater via a script on change of a session prop, but 649 rows killed the browser. So then I put the flex repeater into its own view and used that in a carousel, when again, I created the views property via script and used an items per page to split it up. The params I pass into the flex repeater views are just elements which make up the tag path to the device (tank) displayed in the rows. The components in the flex repeater views then use that base path to read their tags.
I thought that maybe instead of having the data live, I could just read all the values and return a json document with tag values to then display. These fields don’t technically need to be second-live, I could give them a refresh button. Last resort…

Couple of comments that may help:

When you are in the table you should probably use a dataset. I find that using a dataset instead of a json perspective seems to pass it around more efficiently. Though this may also just be in the designer as it tries to render a massive json array in the properties list.

Could be that once its virtualized in a table, it only tries to “read” the tags that are currently rendered on screen. This would probably allow you to make it real time.

Worst case scenario I would make them at least refresh themselves, put a ticker property on the embedded view that at now(5000) refreshes the data.

I’ve done some testing. I tested the following row View scenarios, all using the carousel container to house my flex repeater View which repeats the row View. Not sure if this image helps to visualise it. Ignore the dodgy grey area and the Sahara of empty space… Also, the embedded Views in the Row Views in the screenshot aren’t actually embedded views as they’re from (3) below, however these would be in (1) and (2):

  1. Row View contains embedded Views for displaying tag values, given a tag path. This was the original View I was using in the above posts. This has the most issues with performance and I cannot display more than 20-25 rows before it starts to crash the browser. It’s also super slow to load the tag values in.

  2. Row View contains embedded Views for displaying values given to it via params. i.e. you supply a value “32” and it will display “32”. These Views do not use tag indirection to read tag values. I populated the values in these by first collating a list of all the tags to display for all of the rows to display them for and then bulk-read the values in a script function and wrote them directly into the params passed into the flex repeater rows. This can handle a few more rows than (1) and load time is a little faster, but still can’t get past around 40-50 rows before it crashes.

  3. Same as (2) except removed all embedded views from the row View and instead just used basic components (Labels and Flex Containers). Using this approach, I could display more than 250 rows, but less than 500. I didn’t test where the cutoff was.

This leads me to believe that embedded Views cause performance issues and should therefore be avoided. However, this is counter-intuitive, as these are equivalent to Templates in Vision which are its lifeblood. Is it possible to improve this?

The last thing I need to try is (3) with tag bindings.

This leads me to believe that we have something configured differently at a high level. I was able to display over 10,000 of my embedded in the table with no issue

I guess I have a few questions:
A. Do you need the carousel in this case? Or was that just an attempt to optimize things
B. For the table is ‘props.virtualized’ True? This is a fundamental necessity here, as it only triggers the screen into rendering the rows you can see, not all of the data in total.
C. If you are virtualized then are you passing the table a dataset with your parameters in it, or a json? The designer hates loading large json arrays
D. Is there a reason that each of those labels is an embedded view? At a high level, not knowing your end goal, this feels unnecessary?
E. Is this on something like a raspberry pi, or a device with a really slow network connection? Or a regular server grade device?

I can wire mine up to some more data and see what happens as well

Sorry I must have missed mentioning it, but this was using a flex repeater view, not the column view. I couldn’t get it to display how I wanted with the column view as I need some components to change text alignment and to span multiple rows… Hang on, I don’t think that is relevant…

I think the penny just dropped. I’m using a flex repeater, you’re using a table. I just read the user manual, and I didn’t realise you can give an embedded view into the table component. I’ll give that a go, awesome!

Re why I’m using embedded views for the value displays. I have some for displaying analogue values which I’ve setup to have the value a particular style and margin with the eng units beside it, also with the correct flex container position property values. I also have one that has a sparkline chart beside it, one that has a percentage beside it as well for things like tank levels, and one for setpoints that includes the eng units. The analogue templates pull the eng unit and format string from the tag. The view for the string values was just to keep it consistent mainly, but it also defines in it the style of the string. Otherwise I have to do this all manually every time (or copy and paste) and if I ever need to change it for some reason, it’s one or a few places, not hundreds. I can also configure specific bindings on the components in the views as well of I need. I do the same thing for Vision projects

Definitely, the ability to virtualize the table will heavily impact the performance. Hopefully that works for you!

1 Like