Why Does Perspective Table Width Auto Truncate Totalizers?

David Krause9 min read
HMI / SCADAOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

How the Perspective Table Sizes Columns

An Ignition Perspective table does not measure cell contents to size its columns. Each column's width is a number. The table uses that number as the column's base size in pixels, then applies strictWidth:

  • strictWidth = true: the column is exactly width pixels, regardless of container size.
  • strictWidth = false: width is a starting size, and the column stretches or shrinks with the others to fill the table. The column widths therefore behave as relative proportions. A column at 2 ends up about twice as wide as a column at 1. The values are not literal pixels in this mode.

The table renders rows lazily. It never scans every value to find the widest one. This means a column cannot auto-fit its data the way a spreadsheet column does. The term auto here has no layout meaning. A string such as "auto" in a numeric width field is not a recognized value, so the column falls back to a default share of the table width.

This also answers the load-order question. Column width is never computed from data, so the table rendering before the script updates the data does not cause truncation. A script that writes the columns object with width: "auto" produces the same layout whether the data arrives first or last. Stop investigating timing and move to the checks below.

Symptom-to-Cause Map

Symptom Likely cause Go to
All columns equal width, large numbers clipped or ellipsized width is non-numeric ("auto") or equal defaults on every column Check 1
Numeric widths set, but columns ignore them strictWidth false, and the container is wider or narrower than the sum of widths Check 2
Horizontal scrollbar appears, yet a numeric column still clips Column too narrow for its own content; padding and font consume the space Check 3, Check 4
Same view renders fine on one gateway and clips on another at the same resolution Different font size or theme CSS (cell padding) between gateways Check 3
Text off-center after a padding change Padding removed on one side only Check 3
Totalizer shows many digits with odd fractional steps (.25, .5) 32-bit float storage with too many displayed digits Check 5

Check 1: Width Value Type in the Columns Object

Open the table's columns property in the Property Editor. If a binding or script generates it, read the bound output rather than the design-time default. Inspect the width on each column.

  • Reading: string "auto" or any non-numeric value. This is invalid. Change the script to emit a number for every column. Go to Check 2.
  • Reading: numeric on every column. The type is correct. Go to Check 2.

When a script builds the columns list, set width as an integer, not a quoted string. A quoted "120" is a common cause of "width does nothing". JSON-typed properties do not always coerce strings to numbers.

Check 2: strictWidth Mode Against the Container

Decide which sizing model you want before picking numbers.

  • Relative weights (strictWidth false on all columns). Use small integers (1, 2, 3) as proportions. The table fills its container, and the totalizer column receives its weighted share. This works when the container is wide enough that the share covers the longest value. The view designer's manual describes width in pixels, and that remains true as the base size. Relative behavior appears only because non-strict columns flex to fill the space. If you mix strict and non-strict columns, the strict ones take their pixels first. The flexible columns then split what remains, which can make weights look ineffective.
  • Fixed pixels (strictWidth true). The column is exactly the stated width. Use this only when you have sized it for the largest future value (Check 4).
  • Percentage of table width. Some engineers define column widths as percentages through styling instead of the numeric width field. This approach keeps proportions stable across screen widths. It still does not measure content.

Next, look at the running session at full width.

  • Horizontal scrollbar present, table overflows the container. The sum of column widths exceeds the container, so the columns are not being squashed. If the totalizer column still clips, that column is too narrow for its own content. Go to Check 3.
  • No scrollbar, columns compressed. The container is too narrow for the proportions. Widen the container, reduce column count, or raise the totalizer's weight. Then go to Check 4.

Check 3: Font Size and Cell Padding Between Gateways

A view can render correctly on a Standard Ignition gateway and clip on Ignition Edge at the same 1920x1080 resolution. In that case, the layout inputs differ, not the table logic. In the observed case, everything was identical except font size. Font size sets the pixel advance of every digit. A few pixels per character, multiplied across 12 characters, is enough to push a value past the column edge.

  1. Open the session in a browser on each gateway and launch developer tools.
  2. Inspect a totalizer cell. The cell element carries the class tc ia_table__Cell.
  3. In the computed styles, record font-size, padding-left, and padding-right for both gateways.
  4. Compare the rendered cell width against the text width. The text width is the content box plus both paddings.
  • Font size differs. Set the font size explicitly in the column or table style so both gateways render the same. Re-check.
  • Padding consumes the space. Reduce it in a custom theme CSS file. On an Edge gateway running on a controller platform, such as an Opto22 Edge device, this can mean copying the stylesheet to the device over SSH (for example with PuTTY) into the gateway's theme location.

Removing only padding-left shifts text left of center, which was the result seen here. If you trim padding, trim both sides equally, or change the justification. For numeric columns, right-justify the cell. Digits then align by place value, and growth extends leftward into the column instead of pushing past the right edge. Centered numbers of varying length never line up, and they look off-center as soon as the magnitude changes.

Check 4: Width Needed for the Largest Totalizer Value

A totalizer grows. Size the column for the largest value it will show over its service life, not today's reading. Required width is:

W_required (px) = N_chars x char_advance (px) + padding_left + padding_right
  • N_chars: characters in the longest formatted value, including thousands separators, decimal point, and sign. 3,350,652.25 is 12 characters. One more integer digit adds one character, and the next thousands group adds a separator as well.
  • char_advance: measure it. In dev tools, read the rendered width of the current value and divide by its character count. Tabular (fixed-width) digits make this constant across values.
  • Paddings: take them from the computed style in Check 3.

With strictWidth true, set width to at least W_required. With relative weights, confirm that the column's rendered width at the smallest supported container size still meets W_required. A column that fits at 1920 px wide can clip on a narrower client.

Check 5: Totalizer Representation and Displayed Precision

Before fighting the layout for nine or ten significant digits, confirm those digits carry information.

Its resolution shrinks as the value grows. The value3,350,652.25 lies between 2^21 (2,097,152) and 2^22 (4,194,304). There, the smallest representable step is 2^(21-23) = 0.25. The trailing .25 is therefore a quantization artifact, not a measured quarter-unit. Above 2^24 (16,777,216), the step becomes 2, and small increments stop registering at all. A float32 totalizer then stalls or advances in jumps.

  • Tag or controller register is float32. Drop the decimals from the display. Better, accumulate in a 64-bit double or an integer count in the controller, and scale for display.
  • Display scaling. Divide by 1,000 or 1,000,000 and label the engineering unit, for example thousands or millions of units. 3,350,652.25 becomes 3,350 (x1000) or 3.350 (x10^6). This cuts N_chars in Check 4 by 4-7 characters and removes the width problem at its source.

Resolving Procedure and Verification

  1. Edit the script that builds the columns object. Replace width: "auto" with numeric values for every column. Choose one model: relative weights (strictWidth false everywhere) or fixed pixels (strictWidth true) for columns with known maximum content.
  2. Set the totalizer column's format to the precision the data supports, and apply display scaling if the magnitude warrants it.
  3. Set the numeric column's justification to right.
  4. Set an explicit font size in the table or column style so every gateway renders identically.
  5. If padding still clips the value, reduce it symmetrically in a custom theme CSS file. Deploy the file to every gateway that serves the view, including Edge devices.
  6. Compute W_required for the largest expected value, and set or verify the column width against it.

Verification:

  1. Check 1: read the bound columns output. Expect a numeric width on every column and no string values.
  2. Check 2: resize the browser from full width down to the smallest supported client width. Expect the totalizer column to stay at or above W_required, with no ellipsis.
  3. Check 3: inspect ia_table__Cell on both the Standard and Edge gateways. Expect identical computed font-size and equal left and right padding.
  4. Check 4: write a test value with the maximum digit count the totalizer will reach (in a simulated or memory tag, not the live accumulator). Expect the full value to display, right-aligned, with no clipping.
  5. Check 5: step the test value by the smallest real increment. Expect the display to change by that increment. If it does not, the storage type lacks resolution at that magnitude.

FAQ

Why does setting a Perspective table column width to auto do nothing?

The column width expects a number. The table never measures cell content, so "auto" is ignored and the column falls back to a default share. Use numeric values, either as relative weights with strictWidth false or as pixels with strictWidth true.

Why does my Perspective table column width not behave like pixels?

With strictWidth false, width is only a base size. Columns stretch or shrink to fill the table, so the values act as proportions. Set strictWidth true on a column to lock it to exact pixels.

Why does the same Perspective table clip on Ignition Edge but not on Standard?

At the same resolution, the difference comes from rendering inputs, usually font size and theme cell padding. Inspect the tc ia_table__Cell element on both gateways and compare the computed font-size and padding. Then set the font explicitly and deploy any theme CSS change to both gateways.

Why is my numeric table text off-center after removing padding?

Removing only padding-left leaves the right padding in place, which shifts the text left. Trim both sides equally, or right-justify numeric columns so digits align by place value as the totalizer grows.

Why does my float totalizer show .25 steps or stop incrementing?

A 32-bit float holds about 6-7 significant digits. Between 2,097,152 and 4,194,304, its resolution is 0.25, and above 16,777,216 it is 2. Accumulate in a 64-bit double or an integer, and display scaled values such as thousands or millions.

Back to blog