Hi all, We have a lot of vertical orientated tables. An example is our questionnaire table. This contains all our questionnaire-types with their questions and user-answers. We ourselves, but also our users, would like to combines these in a pivot style way, but that was not possible with the current Sisense Pivot Table. And datamodelling became to cumbersome to do this for every questionnaire (we have around 300 types). The built-in Pivot only allows aggregations at a row × column intersection. That works for numbers, but not when the value you want to show is text. Our questionnaire data stored in a "text" format is the classic case: I wanted one row per form, one column per question and the actual answer in each cell. The workarounds I found meant either mapping answers to numeric codes with javascript or reshaping the data model every time a question was added. So I built a widget plugin instead with the new ComposeSDK. Setting it up The data panel has three slots: Rows: up to 3 fields, for example form ID and location Columns: 1 field, for example question Value: a text field, used as is with no aggregation When a cell has more than one value, you choose whether to join them (with your own separator), keep the first, or keep the last. Rows and columns have a default sort order (A→Z, Z→A, or order of appearance). You can also click any header to sort by that column, including by the answers in a question column and empty cells always end up at the bottom. Wide tables were the main usability problem, so the header row and the row-field columns stay frozen when you scroll sideways. Text wrapping and the width of the row columns are both settings. The row limit counts table rows (forms in this example), not the records underneath. Limiting raw records would cut forms off halfway, so the widget fetches complete forms only and shows a notice when there are more than the limit. The native PDF export only captures the part of a widget you can see, so I added export buttons for the whole table: CSV, Excel (.xlsx with a frozen header) and PDF (A4 landscape, with the header repeated on every page and extra pages sideways for very wide tables). Dashboard filters apply to it like any other widget. How it's built It's a Compose SDK widget plugin, created with the Plugin DevX toolchain ( npx @sisense/sdk-cli create-plugin , React and TypeScript) and uploaded to Sisense as a plugin. I tested it on Sisense 2026.3.2, Linux. The data comes from useExecuteQuery with ungroup: true , and the pivoting happens in the browser. For the row limit, the widget first counts the distinct column values, then fetches just enough rows, sorted by the row fields, to fill the requested number of complete table rows. Four things I ran into while building it If you build plugins yourself, these may save you some time. At runtime the plugin doesn't use the SDK version in your package.json . It runs on the host's copy ( window["@sisense/sdk-ui"] ), so check that every API you call exists in the version your instance ships. Sisense's own CSS also styles MUI class names. In my case it turned the design-panel labels white on a light background. Explicit colors on a wrapper with more specific selectors fixed it, plus !important for the labels. Dropdown menus render outside the widget, so they need their own styling via slotProps . Adding PDF export with jsPDF made the bundle balloon. The Sisense build is a single IIFE file, so jsPDF's optional dependencies (html2canvas, canvg) got inlined even though the plugin never uses them. A scoped npm overrides entry that points them at tiny local stubs brought the bundle back to about 860 KB. If your widget measures its container, for a canvas or a chart, attach the ResizeObserver through a callback ref. The widget renders its loading state first, so a useEffect(..., []) on a regular ref never sees the element and the size stays at zero. Getting it Download it here Limitations The pivoting runs in the browser, so it's meant for tens of thousands of underlying rows, not millions. With bigger sets, use filters or the row limit. There's one column field for now, with no nested column headers, and clicking a cell doesn't cross-filter other widgets yet. How do you handle text values in pivots today: a data-model change, a script on the native pivot, or something else? I'd also like to know whether there's a cleaner approach I missed and which feature you'd want added first. :) Hamza