Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

How do you restyle the trend widget in WinCC OA?

WinCC OA 3.21 License: MIT

Four visual themes for the WinCC OA trend widget, two light and two dark, in one panel and one CTRL library.

The widget is a composite. Its container, its legend and its splitter handle are ordinary Qt widgets and take a Qt style sheet; its plot area, grid, scales and curves are drawn by WinCC OA and follow the widget's own attributes. A theme writes both halves.

Four themes on one WinCC OA trend widget

Themes

Theme Mode Intended use
Paper light An editorial figure for a printed report. Warm paper, one hairline of ink, a comparison run in pale grey, the legend as a caption.
Blueprint light An engineering sheet. Cold graph paper, a hatched area under the flow, a stepped digital signal on a fixed -1..3 scale, monospaced numbers, an HTML title block in the corner of the plot.
Console dark The control room at night. Near black, colour-blind safe pens, thick strokes, a translucent fill on the lead variable, alarm limits on the chart, one value scale.
Slate dark Classic dark mode for a plant dashboard. Cool slate greys, one indigo accent, a rounded card with air around the plot, a two-level grid, a soft wash under the lead series, the value axis on the right.

Requirements

  • WinCC OA 3.21
  • Nothing else. No datapoints, no archive, no driver and no peripherals: the demo series are generated in CTRL and written into the curves with curveVals, so the panel draws the same thing on a clean installation as it does on a live plant.

Installation

  1. Copy panels/trendStyles.xml into <project>/panels/.

  2. Copy scripts/libs/trendStyles.ctl into <project>/scripts/libs/.

  3. Add two entries to the [ui] section of <project>/config/config:

    [ui]
    # Value scale numbers horizontal instead of rotated ninety degrees.
    trendHorizontalScaleText = 1
    # Legend shows a coloured curve sample next to the series name.
    trendLegendStyle = 0
  4. Open the panel: WCCOAui -p trendStyles.xml, or from GEDI.

Usage

One call per trend shape, from the Initialize of the panel that owns it:

#uses "trendStyles.ctl"

main()
{
  TS_Paper(getShape("trPaper"));
  TS_Blueprint(getShape("trBlueprint"));
  TS_Console(getShape("trConsole"));
  TS_Slate(getShape("trSlate"));
}

Each theme is five steps: the look, the addCurve calls, the per-curve style, the data, and the scales.

The demo generator is seeded with a fixed constant, so the same screenshot comes out of every machine and every run: a visual difference means a real change of style, not a different random walk.

How it works

The Qt half

The style sheet is built from small named strings, so each rule can carry the reason it exists:

string TS_QssConsole()
{
  // A raised card on a darker desk. The rounded corner alone carries it:
  // a hairline border at this contrast reads as a scratch on the screen.
  string frame = "TrendQT {"
               + "  background-color: #16181D;"
               + "  border: none;"
               + "  border-radius: 6px;"
               + "  padding: 10px 12px 6px 6px;"
               + "}";

  // A wide transparent handle instead of a grey bar: the gap between chart
  // and readout becomes air, which is what separates them in the design.
  string handle = "QSplitter::handle {"
                + "  background: transparent;"
                + "  height: 10px;"
                + "}";

  // legend, label and box, the same way: the readout card, the series
  // names and the check boxes.

  return frame + handle + legend + label + box;
}

The WinCC OA half

Plain attribute writing, in one pass, because every write can trigger a redraw of the whole widget:

setMultiValue(
  shp, "styleSheet", TS_QssConsole(),
  shp, "manageCommands", FALSE,                 // hide the built-in command bar
  shp, "backCol",     "{22,24,29}",             // the plot
  shp, "legendColor", "{31,36,44}",             // and the legend, separately
  shp, "foreCol",     "{124,133,148}",          // time axis and plot frame
  shp, "gridColor",   "{38,43,52}",             // value grid
  shp, "gridColorX",  "{38,43,52}",             // time grid, separately again
  shp, "gridLineType", "[dashed,oneColor,JoinMiter,CapButt,1]",
  shp, "areaMargins", 0, 10, 6, 24, 2,
  shp, "timeFormat", 0, TRUE, "%H:%M", "%d/%m");

What a style sheet reaches

Part of the widget Qt class Style sheet
Container, padding, card background TrendQT (QSplitter) yes
Legend background, border, font, padding TrendLegend yes
Bar between legend and plot QSplitter::handle yes, and nothing else reaches it
Legend check boxes QCheckBox yes
Preview band (viewport) #viewport_leading, #viewport_window, #viewport_starthandle, #viewport_endhandle, #viewport_trailing - by object name, not by class yes, and nothing else reaches it
Plot area, grid, curves, scales TrendPlot, TrendScaleQT, TrendTimeScale, TrendValueScale selectors attach, but WinCC OA draws over them: use the attributes

Implementation notes

A selection of the behaviours that shaped this example the most. It is not the complete list, only the ones that come up first when you start styling the widget. All of them measured on WinCC OA 3.21.

border-radius works together with padding. The container is a Qt widget and rounds its own fill; the plot area inside it is drawn by WinCC OA as a plain rectangle, and with no padding that rectangle reaches the corners. The padding is what holds it back:

border-radius with padding, and the same theme with padding at zero

Outside the rounded corner the widget draws nothing, so the panel shows through. Put a WinCC OA RECTANGLE under the trend in the card colour, with its own CornerRadius if the card is rounded, and the two read as one object.

Attribute colours are colorDB names or {r,g,b} literals. Hexadecimal belongs to the style sheet: setValue(shp, "backCol", "#16181D") returns 0 and logs Reading color: Color '#16181D' does not exist. The two worlds meet at exactly that line.

Background and grid are two attributes each. backCol paints the plot and legendColor the legend; gridColor is the value grid and gridColorX the time grid. foreCol governs the time axis and the frame of the drawing area.

curveLineType is [shape,colorMode,join,cap,width], with solid and dashed as the line shapes. Width is in pixels, and 0 draws nothing.

curveFillType takes a WinCC OA fill string: [solid], [hatch,[parallel,6,left]], [hatch,[cross,10,left]]. A filled curve needs curveFilled, curveFillType and curveFillColor set together.

curveMinMax applies once autoscale is off. Write curveAutoscale to FALSE first.

A hand-fed curve needs its unit written. The widget reads _common over an open connection, so a static curve takes curveLegendUnit explicitly. Leave the unit out of the series name: the widget appends it itself, and you would get Feed [m3/h] [m3/h].

Number formats take a field width. curveLegendFormat and curveScaleFormat want %1.1f rather than %.1f; without a width they fall back to %g and six significant digits, so a legend with room for 63.8 shows 63.7819.

visibleTimeRange is enough to frame a static curve. trendStop marks the plot as recording-stopped, and a curve with no data source has nothing to update anyway.

Styling QCheckBox::indicator replaces the native tick. Qt hands the whole sub-control over, so ticked and unticked look the same unless the state is carried by the fill: hollow off, solid on.

A style sheet on the legend makes the series names one colour. WinCC OA can tint each name with the colour of its curve, and stops once a style sheet touches the legend. [ui] trendLegendStyle = 0 puts a coloured sample of the curve, with its real line type, next to the name instead.

Digital signals are stepped and sit on a fixed scale. curveType = 1 holds the value between two samples, because a pump was not half running in between. On a fixed -1..3 the trace stays in the lower quarter, reads as a status strip and leaves the top of the plot to the analogue values.

One value scale, not one per pen. Every visible curve draws its own axis, and three axes on a wide card stack numbers that belong to different units. Showing only the lead curve's scale leaves the plot to the data; the other values are read from the legend, where they carry their own units.

curveScalePosition shares one numbering across both orientations. On a horizontal trend 2 is left and 3 is right; 0 and 1 are bottom and top, and belong to a vertical trend. The Slate theme uses 3 on purpose: a right hand axis is what a web dashboard does.

Group the writes that can be grouped. curveVals, curveAutoscale and curveMinMax share one setMultiValue, applied in the order they are written, so autoscale goes off in time for the range. curveScaleVisibility goes in a later call, once the curve has values.

areaMargins is spacing, not reserved space. The widget makes its own room on the real width of each visible scale. The right margin is what keeps the last label of the time axis clear of the edge of the card.

Repository layout

panels/trendStyles.xml        the page: four trends, cards and headings
scripts/libs/trendStyles.ctl  the four themes and the demo generator
docs/                         screenshots

License

MIT - see LICENSE.

Credits

Built by Interial, WinCC OA specialists in Brescia, Italy. WinCC OA and Siemens are trademarks of Siemens AG. This project is not affiliated with, endorsed by, or sponsored by Siemens AG.

About

Four ready themes for the Siemens WinCC OA trend widget: Qt style sheets for the parts Qt paints, widget attributes for the parts WinCC OA paints, plus the undocumented behaviour behind both.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages