[Feedback] NEW Perspective Dashboard

Thanks, you gave me an idea. I manage to get it to work.

Made a bi-directional parameter on the widget view that is binded to the textinput text. I then keep a list that of the tagPath of the udt and index of the widget. I can then marry the two lists using the tagPath and then use the Index in the list to write to the title of a specific widget.

1 Like

I am having issues saving the widget properties json array to the DB. Do you have some sample code on how you manage to do the convert the array/list to a string and the other way around.

at the moment there is no straight forward way to do this, as i understood it.
I asked the same question as you, See this post:

I like how you got it to work. I have also been asking myself how to implement this.

I do wish that header each widget will be bound to a widget parameter like the “configuring” tag. Anything else feels like a quickfix.

Developers please :slight_smile:

Its fairly simple to do once you can convert the wrapper objects. Below is the majority of my code to accomplish this. Your path to the dashboard might change, but save jsonObjectFull to a table and then I use a non-polling query binding on the property to pull it back on load. So far it seems to work fine.

   	from com.inductiveautomation.ignition.common import TypeUtilities
    User = self.session.props.auth.user.userName
	layoutFull = self.parent.parent.getChild("BreakpointContainer").getChild("Dashboard").props.widgets
	jsonObjectFull = TypeUtilities.pyToGson(layoutFull)
3 Likes

Or it can be directly editable when the widget goes into configuration mode?

Absolutely love this feature and the possibilities that come with it! I do have a feature request. While I do like the auto-rearrange feature when adding and moving widgets, it can be very frustrating at times. When trying to get a layout just right, the auto-rearrange feature continues to ‘undo’ the layout that I am trying to create. I have tried making the widgets different sizes and arranging the widgets in a different order but it always seem to “fill” to the top of the dashboard when dragging the widgets around. Maybe next to the edit and delete icons there could be a lock icon that toggles the ability to move the widget.

3 Likes

Hi,
So I seem to be having trouble ‘marrying’ viewParams to a specific widget.

I created an iframe View where a user can input into a text field a url, and I made this view an availableWidget.

I added two viewParams to the availbaleWidget: configuring and src. I want the src to populate once a user enters the url. I tried doing this by binding the src entered in the View text field to a global View parameter I called src, which should automatically populate the widget because it has the same parameter name. However, it doesn’t physically populate it (I can’t see any change to the src parameter in the widget). I DO however see the url in the iframe, so there is some sort of connection being made.

Even more strange is what happens when I try to delete the widgets. If I add widget A with src a and then widget B with src b, and then I try to delete widget A, what happens is that src b gets populated with src a due to some indexing issue.

I’ve made a couple attempts to work around this but I am having trouble finding information about this relatively new component. What I need is the ability to find out which widget is currently being edited. How can this be done?

Cheers,

Yoni

Hi,

Glad you like it. It’s still a little rough and we do have plans to improve it. Specifically the bin packing algorithm that is used to reposition widgets in available space. Currently is does repack to the top left corner, but we are hoping to refine this so that it is more natural to the user. Keep in mind, widgets do not save their new position unless a widget is dropped in a position where one or many widgets might be already placed. It might look like they are getting repositioned while you move a widget, but that is more for feedback to let you know where they might move in case the widget was dropped in its present position. Widgets will return to their original positions if their original position exists.

I hope that helps clarify things.

-Y

Hi.

I still cant save it.

Sorry, but I can’t load the .props.widgets from the database.

Can you guys help me?

@grietveld
to save i do:

from com.inductiveautomation.ignition.common import TypeUtilities
	User = self.session.props.auth.user.userName
	layoutFull = self.getSibling("Dashboard").props.widgets
	jsonObjectFull = TypeUtilities.pyToGson(layoutFull)
	#system.perspective.print(jsonObjectFull)
	vars = {"User": User,"JSON": jsonObjectFull}
	system.db.runNamedQuery("Baseline","SaveDashBoard",vars)

NamedQuery is:

REPLACE INTO dashusersetting (
  dashusersetting.user,
  dashusersetting.dashsetting
)
VALUE
( :User, :JSON) 

when is try to load query as json to the props.widgets binding :

SELECT 
  dashusersetting.dashsetting
FROM dashusersetting
where dashusersetting.user = :User

it give me this

What I am doing wrong ?

I found out

Added transform script to props.widgets binding then it worked

return system.util.jsonDecode(value)
1 Like

Please allow us to disable the auto-arrange feature so we can just put widget where we want them. It can be extremely frustrating at times. Its almost impossible to fill the screen the way you want it.

Otherwise, I absolutely love this component. It is my favorite feature in Perspective.

I just use small size for grid so it is much easier to position widget.

Hi Tony, I created a request in the feedback, features and ideas here: https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/dashboard-component-bin-packing-algorithm

Please upvote to try and move it up the priority list.

I’m testing a workaround today by exposing the position properties of the widget in runtime, allowing the user to manually position the widget without using the drag-and-drop method. Hopefully the algorithm will not effect this.

[Edit]
Editing the widget’s position property in runtime works well, and doesn’t trigger the bin packing algorithm. It also allows for widgets to overlap [if this is ever needed]. This will be my preferred solution until the algorithm gets optimised.

1 Like

@tony.upton, @matthew.ayre. Sure. Sounds reasonable to me. If that’s what you guys want. We’ll see what we can do. I actually think we might already have it in queue. Thanks for the feedback.

2 Likes

First... Thanks to @Bojacobsen and @grietveld for providing the information they have provided thus far. Without it, I would still be scratching my head. Now to the problem.

I have taken in what has been provided as sample code to save the props.widgets object of a dashboard component to a database table and gotten mostly there. Where I continue to get tripped up is converting the objects to get them stuffed into a table then getting it back to something useful. I would like to share what I have done so far and open up for comment. I feel like I'm making it more complex than it needs to be. I should also point out that I lack some fundamental knowledge about all of the different data types, "wrapping" and "unwrapping", etc. I tend to read trough these forums, do a lot of googling, and hack away.

System Information
Ignition Maker 8.0.15
Database: Postgres

############ My Code ###################

## Property Change script tied to props.widgets

from com.inductiveautomation.ignition.common import TypeUtilities
User = self.session.props.auth.user.userName
dashboardWidgets = self.props.widgets
jsonObjectFull = str(TypeUtilities.pyToGson(dashboardWidgets))
vars = {"user": User,"widgets": jsonObjectFull}
system.db.runNamedQuery("DashboardUpdate",vars)

## DashboardUpdate (Named Query)

  • I have two parameters setup for this named query. :user and :widgets. Both of them are strings.

INSERT INTO dashboards (dashboardid , username, widgets)
VALUES ( DEFAULT, :user , :widgets )
ON CONFLICT (username) DO UPDATE SET widgets = EXCLUDED.widgets;

## I have started a query Binding... (See below)
NOTE: I was testing against user "jtunell" for testing purposes. I would eventually change the parameter value to a script to read active user.

----- Questions: ------

  1. I had to convert the wrapper object per @grietveld instruction. I then converted that to string because that is the only way I was able to get it passed to the Named Query parameter. I'm able to successfully write it to the database. But... How to undue the str()?? Did I really need to convert to string? I couldnt find another way to pass json to the named query parameter.

  2. I see @Bojacobsen added a transform script to the props.widgets binding but this doesnt solve my issue.

  3. Looking for pointers on how to come up to speed faster on manipulating the data and the various data types within the Ignition software. I know its a weird question. I not really sure what the right questions is I just know I'm feeling a bit lost.

Ok… I think I may have stumbled upon the solution! The transform below works. Maybe I just needed to get away from it.

1 Like

Thank you for all of your help (If i could tell the entire chain I would). To anyone that finds this in the future, you need to use the TypeUtilites.pyToGson to do the conversion to JSON, but then you need to use system.util.jsonDecode to get it back. Hopefully they fix jsonEncode soon.

The JSON issues are supposed to be fixed in 8.1, but I haven’t checked myself yet. I was having a similar issue.