Designing better data tables (2017)
uxdesign.cc
uxdesign.cc
• First Click: Sort ASC
• Second Click: Sort DESC
• Third Click: Remove Column Sort
This allows me to go back to the initial state where the tables have been loaded. Currently, most data tables don't support "resetting" of column sorting and are implemented in this manner: • First Click: Sort ASC
• Second Click: Sort DESC
• Third Click: Sort ASCBy default, most tables that I have are sorted by "created_datetime" but this is the column that won't be shown to the end-user since most of the time it is redundant information for them. If we're implementing explicit sort, I need to add an additional column which would be useless to them.
Having the ability to easily reset back to default sort makes everything so much cleaner as an end-user (for me). I won't have to experience another "How the heck do I go back".
It may be seen as overengineering for an itunes user, but a full implementation should provide a way to do both sorts and to cancel view-sort if no longer needed.
Also, sorts may be not just column-based. Shop cart may be sorted by product group without having such column even in dataset, like rows.sort(“product.group.title”) or alike. In UI it can be done as right-clicking on a column/cell and sort->[natural, id, title, group->[natural, id, title, ...], ...] menu hierarchy.
* algorithms may depend on this ordering, so a user takes care to not change it accidentally
--
[0] - Even if it means including a DB id, though preferably, you'd resort the data by one of the columns intended for users.
Imagine a query like "select top 10 * from foo where bar = 1", when there is no index on the bar column. The database will need to scan through the foo table, the check the bar column for each item, then return the first 10 that it finds. So it could behave as you describe, just scanning from the top to the bottom in on-disk order, returning results in that order.
However, the database may maintain statistics of how often bar is set to 1, and if it is only sparsely set, it could recognise that a single-threaded top-to-bottom scan would be quite slow. In this case, it could be much faster to break the table up, one chunk per thread, scan each chunk, then return results as soon as enough are found. The final order of results (if there is no order by clause) could then depend on the order that the threads run in, but you'd only see that if there was a lot of data in the table to start with.
https://docs.microsoft.com/en-us/sql/t-sql/queries/top-trans...
This is why it is very common to see suggestions to always specify an explicit order when implementing pagination, as the order of results could change from one page to another if the sort order is left undefined, leading to missing or duplicated results from a user's perspective.
Now, one thing that is very important to me: The sort should be stable. So, for example, I should be able to sort by successively by track number, disk number, album, and artist, to get a view that is sorted by artist, album, disk, and track.
Unfortunately, some views (eg iTunes list view) don't obey that.
Personally, I like the idea of it being a way of viewing the data rather than a change to the data. It would even make sense to be able to sort by column A, and then click to sort column B to breaks ties, and column C to further break ties ect. (though there would need to be a visual describing the precedence of the sorts to the user). Then, you can undone any of these by clicking a column twice more.
But then, sort is not stable. For example, if I sort by song name, and then by genre, the songs within a genre are not sorted by song name, but (for some unfathomable reason) by artist. Very annoying. Bad iTunes, bad. (This is on macOS Mojave, haven't dared the jump to Catalina yet.)
However, insofar as most people desire the ability to sort by multiple columns, they'd likely also want a more intuitive UI than clicking the columns in the reverse order of priority. A few years ago I participated in developing a datagrid component where you could add columns to the sort order by shift-clicking.
For a music player, "index occurrence in release album" is thoroughly useless data in every situation other than playing albums in order. So it's more elegant to hide that information and specifically design the sorting features around the use case.
3rd mouse should be a shortcut to something that can already be done
Modals are also really really hard to make accessible, and are often confusing. If you MUST use modals, please use a well-vetted library instead of rolling your own.
There's a lot of things that look really cool but make life difficult for people that aren't you. We appreciate your consideration when you build your UX. <END OF PSA>
Of course, this will still not really help with touch devices.
This way, you can enable hover controls only if the user is not on a touch screen or a screen reader.
I think leaving this kind of functionality to web developers, leaving everyone to figure it out for themselves and also make it work on several platforms and browsers is just silly. I don't know why we do it this way.
Basically, it would be hugely complicated, require significant additions to the HTML of tables and would probably be no more successful than the built-in date-pickers of browsers, which always get replaced to get a nice look or behavior.
When I gave the first version to our testers, each and every one of them came with non-overlapping set of features. Some of these features are listed in this article and even more.
If you look into details, you will be amazed how many features there are in such common and simply-looking interface element. It took me (and the testing team) more than a couple of weeks to "kind-a finish" this work.
Yes! Reminds me of this recent tweet by Ryan Florence (a renowned JS lib author) on spending 3 hours w/ a friend creating a chart -- ie, a spec -- for "just" a dropdown button:
https://twitter.com/ryanflorence/status/1189728090575921152?...
The Adamn Lynch article that was on HN a few months ago was great, with code examples - https://adamlynch.com/flexible-data-tables-with-css-grid
- It’s focused entirely on tables (as opposed to being a more general widget framework).
- I believe it covers most of the functionality discussed in the article.
- It has a mobile vertical layout.
I have been using Sencha/ExtJS' grid for that purpose, which is very powerful and versatile, and recently I've been contemplating ag-grid, which seems very nice also.
Be forewarned though: if you're trying to use this from React with dynamic data that can be modified on the client, you're probably not going to have fun. Ag-grid is a vanilla JS library with a very thin React wrapper written around it, so even though on the surface it looks like it fits into the React model, most complex things you'll want to do end up meaning you have to use the imperative table API. I can't speak to how it fits in with other frameworks out there, but I would imagine it's going to be a similar situation.
That being said, if you're just going to drop some data into the table that's read-only, i.e. just for analysis etc., I think it's pretty solid and hard to find something with anywhere near a comparable level of features.
There are some gotchas with column widths when using horizontal scrolling with fixed header and fixed column(s), but it works.
I'd say this is common to a lot of our work as developers. On the face of it a task seems easy - but it typically involves adding lot of fine detail to make it excellent.
One thing they don't mention, is exporting. Anytime you're dealing with tabular data, you really need an "export to excel" button. You'll never be able to do all the slicing, filtering, and sorting that excel can do. By all means, add it into your app and hopefully over time your users won't need it, but at the start, it's vital.
I recently had to implement a js/jquery web application & datatables is golden : so many features, so many possibilities. Used for so long by so many => so few bugs left.
There is exactly zero open source and/or free component data tables for React that do everything in this article.
Not only that, but many are so full of bugs or so difficult to implement that they might as well not exist at all.
Serious opportunity to create a top leading project that would have a huge impact on the usability of the web if everyone adopted it.
Edit: Yes, I'd contribute to working on a project like this under a permissive MIT license, but I don't want to do it alone.
Pretty sad no? Spreadsheets have been around for 30 years and there is still no excellent solution for web apps?
Throughout my web-dev career, I did table or detailed-list views many times, but each time with different requirements. Aside from sheer size of code to implement all the features, you will have contradicting requirements and there is no one-size-fits-all solution.
Top concerns are: 1. is your data homogeneous (all columns in a row are presented equally) 2. can this data change? 3. is there a lot of data? (so you have to implement virtual list) 4. is data dynamically loaded? 5. do you need actions on data, and how to display them (inline / overlay / menu?) 6. some features are really simple on surface (resizing, drag-drop reorder of rows, auto-sizing on dbl-click is a hell of itself) but are pain in the ass to implement. 7. is filtering/sorting done on a client or you have a server to help you? 8. and many many more...
There are multiple implementations, but you have to investigate which one fits you need.
For any use cases not supported it is often easy enough to extend, and the library is MIT licensed so you could always add more features to it.
Size of data can be:
1. Small, so you can display it all at once and the user will have luxury to ctrl+f what he/she wants;
2. Big to display, but small enough to push to client: then you will need to create pagination or virtualized view. Ctrl+F will not work (at least without some tricks), but you can easily filter/search it yourself in JS;
3. Too big to transfer: the only way to search/filter is on the server and separate controls (of course Ctrl+F won't work).
I also wonder whether we shouldn't have new <table> tag, meant specifically for data tables. Say, <datatable>. It would have all sorts of sorting and filtering and pivot tables built-in, and it could exploit native code to ensure high performance. Case 3 could be handled by a well-defined API that translates table operations to JS calls, in case a full dataset can't be sent to the browser.
As another poster linked ag-grid this is how API surface should look like: https://www.ag-grid.com/javascript-grid-server-side-model/
Paging is an anti pattern. You need good search and filters, not paging. With paging all you do is overload the user with information, forcing them to scan mountains of irrelevant data over and over again until they find what they were looking for.
If you need paging, your UX design is wrong.
Sencha ExtJs is a paid front-end JS framework, which I find extremely comprehensive. I have worked on this framework quite extensively and find these features missing even in most, if not all, modern JS frameworks.
Examples:
For Desktop: https://examples.sencha.com/extjs/7.0.0/examples/kitchensink...
For Mobile: https://examples.sencha.com/extjs/7.0.0/examples/kitchensink...
Hmm:
Loading failed for the <script> with source “https://cdn.optimizely.com/js/16180790160.js”. design-better-data-tables-4ecc99d23356:8:1
-+++++= .+++++=
.+@@@@@+ #@@@@*:
.@@@@@= *@@@@@
@+@@@@- =#@@@@@
@ +@@@@: :% @@@@@
@ *@@@@-%: @@@@@
@ *@@@@- @@@@@
-@- #@@+ :@@@@@:
-#@@@#- ## =@@@@@@@=
....... .........
main.fe894587.chunk.js:1:322280
We're hiring! https://medium.com/jobs-at-medium/work-at-medium-959d1a85284e main.fe894587.chunk.js:1:322536
onmozfullscreenchange is deprecated. media.html:11:9799
onmozfullscreenerror is deprecated. media.html:11:9799
Loading failed for the <script> with source “https://d1z2jf7jlzjs58.cloudfront.net/keys/medium.com/p.js”. design-better-data-tables-4ecc99d23356:1:1
Loading failed for the <script> with source “https://cdn.branch.io/branch-latest.min.js”. design-better-data-tables-4ecc99d23356:1:1
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://collector-medium.lightstep.com/api/v0/reports. (Reason: CORS request did not succeed).
This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features! design-better-data-tables-4ecc99d23356
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://collector-medium.lightstep.com/api/v0/reports. (Reason: CORS request did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://collector-medium.lightstep.com/api/v0/reports. (Reason: CORS request did not succeed).Unfortunately, we're all too clever for that nowadays, so you'll probably have to download and compile half a terabyte of Rust from a proprietary package manager just to get something that only works in the nightly build of Chrome.
I wish there were more articles like this. The illustrations are great.