...
{
"Name": "MyDisplay",
"PanelType": "Canvas",
"DisplayMode": "Page",
"Size": "1366 x 728720",
"Elements": [
{
"Type": "Rectangle",
"Left": 100, "Top": 100, "Width": 200, "Height": 150
}
]
}
...
Before writing ANY element, mentally divide the 1366×728 1366×720 canvas into rectangular zones. Each zone represents a process area, equipment group, or information panel.
Standard zone layout for a process overview (1366×7281366×720):
PAGE TITLE (x:0, y:0, w:1366, h:50) ACTION BTNs | ||||||
|---|---|---|---|---|---|---|
| Zone 2 | Zone 2 | Zone 2 | Zone 2 | Zone 2 | Zone 2 |
BOTTOM PANEL: Trend, Alarms, KPIs, or ML Status (h:300+) | ||||||
...
For N process stages on a 1366×728 1366×720 canvas:
Available width = 1366 - 4020 (left/right margin 20px10px each) = 13261346
Available height = 728720 - 50 (title) - 2010 (top margin) = 658760
Zone width = (Available width - (N-1) × 15) / N
Zone height = 320 (for process row)
Zone startY = 60 (below title)
Zone[i].Left = 20 + i × (zoneWidth + 15)
Zone[i].Top = 60
Zone[i].Width = zoneWidth
Zone[i].Height = 320
Bottom panel:
Left = 20, Top = 400, Width = 1326, Height = 658 - 320 - 20 = 318
...
| Panel | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
|
...
{
"table_type": "DisplaysList",
"data": [{
"Name": "ProcessOverview",
"PanelType": "Canvas",
"DisplayMode": "Page",
"Size": "1366 x 728720",
"Elements": [
{
"Type": "Rectangle",
"Left": 20, "Top": 60, "Width": 208, "Height": 320,
"FillTheme": "PanelBackground",
"Stroke": "#FF909090", "StrokeThickness": 1
},
{
"Type": "TextBlock",
"Text": "Process Overview",
"Left": 20, "Top": 10, "Width": 400, "Height": 35,
"FontSize": 20
}
]
}]
}
...
{
"table_type": "DisplaysList",
"data": [{
"Name": "ControlPage",
"PanelType": "Canvas",
"Size": "1366 x 728720",
"Contents": "CSharp\r\nvoid DisplayOpening()\r\n{\r\n // Initialize display state\r\n}\r\n\r\nvoid ButtonStart_Click(object sender, EventArgs e)\r\n{\r\n @Tag.Plant/Pump1/Command.Value = 1;\r\n}\r\n\r\nvoid ButtonStop_Click(object sender, EventArgs e)\r\n{\r\n @Tag.Plant/Pump1/Command.Value = 0;\r\n}",
"Elements": [
{
"Type": "Button",
"Text": "Start Pump",
"Left": 50, "Top": 100, "Width": 120, "Height": 40,
"ClickEvent": "ButtonStart_Click"
},
{
"Type": "Button",
"Text": "Stop Pump",
"Left": 200, "Top": 100, "Width": 120, "Height": 40,
"ClickEvent": "ButtonStop_Click"
},
{
"Type": "TextBlock",
"LinkedValue": "{@Tag.Plant/Pump1/Running.Value}",
"Left": 50, "Top": 160, "Width": 200, "Height": 25
}
]
}]
}
...
FillTheme: "PanelBackground""Flow: {@Tag.X} GPM")PanelBackground theme RectanglesName (not ObjectName)PanelType is set at top level (never inside JsonFormat)...