xh / hoist-react

🏗️ ⚛️ The XH Hoist toolkit for React
https://xh.io
Apache License 2.0
24 stars 9 forks source link

`ZoneGrid` should prioritize showing start of metric when space constraints will clip #3644

Closed amcclain closed 5 months ago

amcclain commented 5 months ago

The ZoneGrid component is designed to show data in a very flexible / user-driven way, which can be at odds with managing column sizes to avoid clipping of data.

Given that cells have an complex internal layout, we don't auto-size between the grid's two managed columns, and we don't have horizontal scrolling as an option.

That means that if you have two values you wish to show in the top two left/right slots in the grid, if they are sufficiently long they will need to clip. The issue currently is that if you have a numeric metric in the top-right (primary expected use case), if it overflows and clips it will clip the left (i.e. starting) edge of the value, which can if perfectly (mis)aligned can lead to very misleading output.

Below is an (admittedly contrived) modification of the Toolbox mobile example that demonstrates the issue - all numbers are larger than they appear. Negative numbers have the easy-to-miss hint of the missing left ( but positive numbers show no indication.

Screenshot 2024-04-30 at 2 18 30 PM
amcclain commented 5 months ago

Created the above with this mod to mobile ZoneGridPageModel in toolbox:

zoneGridModel: ZoneGridModel = new ZoneGridModel({
        persistWith: {localStorageKey: 'toolboxSampleZoneGrid'},
        sortBy: 'profit_loss|desc|abs',
        zoneMapperModel: true,
        onRowClicked: ({data: record}) => {
            const {id} = record;
            XH.appendRoute('gridDetail', {id});
        },
        store: {
            processRawData: r => {
                r.profit_loss = r.profit_loss * 100;
                const pnl = r.profit_loss;
                return {
                    winLose: pnl > 0 ? 'Winner' : pnl < 0 ? 'Loser' : 'Flat',
                    ...r
                };
            }
        },
        rightColumnSpec: {width: 100, flex: null},
        columns: [
            companyCol,
            winLoseCol,
            cityCol,
            profitLossCol,
            {...tradeVolumeCol, headerName: 'Vol'},
            tradeDateCol,
            activeCol
        ],
        mappings: {
            tl: 'company',
            tr: 'profit_loss',
            bl: ['city', 'trade_date'],
            br: {field: 'trade_volume', showLabel: true}
        },
        limits: {
            tl: {min: 1, max: 1, only: ['company', 'city']},
            tr: {max: 1},
            bl: {max: 4},
            br: {max: 1}
        }
    });