neherlab / covid19_scenarios

Models of COVID-19 outbreak trajectories and hospital demand
https://covid19-scenarios.org
MIT License
1.36k stars 354 forks source link

"Expand" the results panel #284

Closed ivan-aksamentov closed 4 years ago

ivan-aksamentov commented 4 years ago

πŸ™‹ Feature Request

I want to discuss the possibility of "zooming in" to a particular parts of the application. In this case, the results card and results plot.

πŸ”¦ Context

"Results" panel is the most important one. It's a heart of the app. But depending on screen size there are usability issues.

Even on large screens:

In terms of highlighting of the important data none of this makes sense

😯 Describe the feature

I imagine a small button that will bring up (animated) the whole results panel and/or a separate section of it full-screen or almost full-screen. Sort of like the images of items on shopping websites. A large popup of a kind.

In this case, after user is happy with the parameters and no longer needs the "Scenarios" panel, they could expand the Results panel in and see the data outputs more clearly.

Additionally, it gives us a change to restructure the layout in the popup, becaue it can be different from the current one:

πŸ’» Examples

πŸ’ Possible Solution

We currently use a couple of popups already (disclaimer, export), so this could be implemented similarly. It just has to be bigger.

Related

ivan-aksamentov commented 4 years ago

Alternative or a complementary implementation is to collapse the "Scenario" panel when no longer needed.

Even more aswesome is to move the layout from hardcoded bootstrap grid to something dynamic like https://github.com/STRML/react-grid-layout with draggable, resizeable and expandable/zoomable panels

rcbevans commented 4 years ago

I think having an "expand" on each of the three result graphs is a very easy start to make exploring the results easier; could start with that, then move to a more flexible/dynamic layout.

I'll work on an expand now.

rcbevans commented 4 years ago

@ivan-aksamentov I have a prototype that would allow displaying the entire result card body, or individual charts 'maximized' in a modal dialog, launched by clicking the 'expand' arrows beside the title of the component to be expanded.

Screen shot showing the expand icon by the results header

Screenshot of results rendering in a modal dialog

Is this the sort of thing you had in mind?

miksa1987 commented 4 years ago

Even more aswesome is to move the layout from hardcoded bootstrap grid to something dynamic like https://github.com/STRML/react-grid-layout with draggable, resizeable and expandable/zoomable panels

@ivan-aksamentov Could the cards in Scenario panel be made collapsible like the severity card? I'd imagine it would improve user experience by reducing the amount of scrolling around.

rcbevans commented 4 years ago

@miksa1987 problem is the layout is currently split 50/50, between scenario and results, and even if the scenario cards were collapsible, that wouldn't help much with the lack of space for results. It would make it easier if you're changing severity values, whilst trying to watch live updating graph values.

Another idea... It'd be pretty easy to 'pop' the results card out of the primary browser window and into a secondary window allowing the scenario card to fill one window, and results to fill a secondary window. People with multiple monitors could then view both side by side on different screens.

miksa1987 commented 4 years ago

@rcbevans I think splitting the cards in different windows is pretty nice idea. How would you go about it? I've no experience with that kind of things.

rcbevans commented 4 years ago

@rcbevans I think splitting the cards in different windows is pretty nice idea. How would you go about it? I've no experience with that kind of things.

It's very easy using portals . There is a fairly well used library called react-new-window which makes popping components out very simple, and best part is they can share state the same state, so autorun and re-render can still work between windows.

I'm about to head to bed; feel free to have a play. Let me know if you get anywhere with it, else I'll make a prototype tomorrow.

miksa1987 commented 4 years ago

@rcbevans I'm going to have a look into it. I'll let you know if I get something sensible out of it.

miksa1987 commented 4 years ago

I'm experimenting with the react-new-window library, and I got the rudimentary logic down: A boolean in UI state for multi window, and a NewWindowWrapper component with a bit of conditional logic for toggling the window. But for the life of me I can't figure out where I should wrap the ScenarioCard inside NewWindowWrapper without Reactstrap exploding. It seems to lose all the help tooltips when I try to put it in another window?

See screenshot: newwindowwrapper_error

rcbevans commented 4 years ago

@miksa1987 Sorry I didn't get back to you, been busy with work. Did you make any further progress?

If you have a branch, I'd be happy to take a look.

miksa1987 commented 4 years ago

@rcbevans No problem. I've been busy with stuff too.

Unfortunately, I didn't get further than my last message. For some reason, using react-new-window, putting the ResultsCard or ScenarioCard in new window seems to blow up Reactstrap's help tooltips. If you have an idea of what's going on, I'm listening.

dkozar commented 4 years ago

@miksa1987 I've been playing with this task too (just to wrap my head about the project) and bumped into the same problem when using React.portal to popup the results panel.

It seems that TooltipPopoverWrapper is not playing well with React portal.

Tooltip is used by FormHelpButton (a question mark button used in Results panel):

image

Here's what I get:

image

dkozar commented 4 years ago

I think there is an even better usability pattern for our purpose than using a popup. Bear with me.

Similarly how the page renders on mobile (input and output one of top of other), we could render it on desktop. We would just put the most important thing on top, and that is the graphs (we would put the input parameters below).

This is a pattern similar to what YouTube does when the video is put into the "full screen mode" (on desktop). Try putting any YouTube video to full screen mode, and you'll see that the page in full screen mode is still scrollable; it's just that the video cleverly stretches to cover the screen dimensions (thus giving impression that there's no scroll).

Now, we could have this "maximised" mode by default, or make it an alternative - stil retaining the current 2-column view, and showing the "maximised" mode only when the user clicks "Maximise" button.

This would make our app much mode "dashboard like", where (when the user lands to the shared link) there are a big bold graphs on top that could be shown to the public. Maybe we could even put the "Full screen" switch so the browse chrome is removed, so the graphs could be shown on the TV etc.

YouTube "full screen" example:

you-tube

dkozar commented 4 years ago

Not only that, but I think that initially the 2nd column doesn't need to exist, since there's nothing to show.

This means that we could display our input parameters using a full screen width. I re-arranged the display for demonstration:

input

dkozar commented 4 years ago

After the Run button is clicked for the 1st time, the graphs are drawn, and the input parameters would be rendered below the graphs:

image

Note a horizontal rule for emphasizing the boundary between input (params) and output (graphs).

dkozar commented 4 years ago

Let me explain the buttons:

share-1

Run in new tab button would run the simulation in another browser tab. This would allow user to generate multiple reports for comparison. The tabs are detachable in modern browsers, so the user can rearrange them across multiple monitors etc. I think this would be much better than the react-new-window solution mentioned above, which is giving only a "temporary" popup, that cannot be shared (no link in the opened window), bookmarked etc.

Share button would open the dialog with the link to simulation ready to be copied (and pasted into the email). Probably we could at some point allow the entry of (optional) title and description, which would be displayed on top of the page (above the graphs) when the recipient clicks the link.

share-2

What do you think?

gj262 commented 4 years ago

@miksa1987 it is probably because the tooltip is bound/references the original window. I will look for a fix for that.

cc: @rcbevans

gj262 commented 4 years ago

@miksa1987 it is probably because the tooltip is bound/references the original window. I will look for a fix for that.

cc: @rcbevans

Yeah, we'd need to tell the target handling code in reactstrap to look at the parent and any child windows when finding the tooltip target. I cannot think of a quick hack off the top of my head though... https://github.com/reactstrap/reactstrap/blob/853b56ec818101aa3f28e6b916f401e108147234/src/utils.js#L273

dkozar commented 4 years ago

But please, take a look at my idea above - maybe we don’t need to solve the tooltip problem at all.

gj262 commented 4 years ago

But please, take a look at my idea above - maybe we don’t need to solve the tooltip problem at all.

Hi @dkozar Yeah having a view with input parameters below the result makes sense. And I like the graph popup idea because you can size the graph as you wish with another window. I think some use cases might be based on the autorun feature where you want parameters and results side by side. i.e. tweak something and see what happens. And you still get that with the window,open() because its all controlled by the same JS.

rcbevans commented 4 years ago

I think there are a few different user personas with different goals of what they would likely wish to achieve using the tool.

An experimenter would like to have graphs and scenarios open simultaneously, experimenting with different algorithm parameters to observe how the simulated results fit case history.

A presenter would want a distraction free way to easily show graphical results without emphasis on the parameters that produced the results.

I think they're two valid scenarios and would both best suit different user experiences. I think your idea, @dkozar, of the youtube style focus on the graphs is great for a presenter. I think the idea of two windows in sync of scenario parameters and results is good for an experimenter. I think it's worth pursuing both ideas, as long as there is a sane way to move between them.

I love the UX mockups, and URL sharing idea also @dkozar!

rcbevans commented 4 years ago

I spent a while hacking around with react-new-window, and I was able to get tooltips showing in the secondary window.

  1. add onOpen method to the NewWindow, and keep track of the reference to the new window which was created.
  2. Pass it down (very ugly I know) all the way to the FormHelpButtons on the results card.
  3. Only render the UncontrolledPopover if the passed window reference is not null/undefined.
  4. For FormHelpButtons rendering in the secondary window, pass the target property as a callback function returning secondarywindow.document., also pass the container property as a callback, returning a reference to the root element of the secondary window.

This is pretty ugly just to get popups working. A lot of components need to pass the secondary window reference down and around, and the FormHelpButton needs to make sure it doesn't render the popover too early, else it'll fail to find the secondary window root element, or the target.

It also seems pretty buggy when making changes and recompiling the code; sometimes the popover called my container callback just fine, but other times it doesn't, so the secondary window popups don't show. I'm not sure how to set breakpoints in npm library dependencies to see what's going on...

dkozar commented 4 years ago

An experimenter would like to have graphs and scenarios open simultaneously, experimenting with different algorithm parameters to observe how the simulated results fit case history.

A presenter would want a distraction free way to easily show graphical results without emphasis on the parameters that produced the results.

That's very nicely deduced! πŸ₯‡

So, I suggest that we build 2 views of the app:

  1. Experimenter view
  2. Presenter view

What do you think?

dkozar commented 4 years ago

Of course, this doesn't exclude the option that each graph could be maximized in a popup.

gj262 commented 4 years ago

Hi @rcbevans @miksa1987 I tried monkey patching window.open() and modifying reactstrap tooltip args but could get none of that to work. So I switched to trying to find a replacement. I think #339 will work after I fix styling and tests. Then you guys can try react-new-window again which would be awesome :)

rcbevans commented 4 years ago

An experimenter would like to have graphs and scenarios open simultaneously, experimenting with different algorithm parameters to observe how the simulated results fit case history.

A presenter would want a distraction free way to easily show graphical results without emphasis on the parameters that produced the results.

That's very nicely deduced! πŸ₯‡

So, I suggest that we build 2 views of the app:

  1. Experimenter view
  2. Presenter view
  • type of the view would be toggle-able using a button on top of the app
  • both views would render the same (child) components, they would you lay out them differently
  • the setting would be persisted in a link, so the user would be able to open the presenter view in a new tab right from the experimenter view, and would be able to share the presenter view via link

What do you think?

That sounds great. For experimenter the current side by side (/ideally pop out) view, then for presenter either collapse, or place scenario after the results with both full width?

I've noticed that when the results card is full monitor width the graphs only take up a fixed maximum width, likely due to conserving height because of the fixed aspect ratio.

Could look at finding a better use of space to arrange the results.

rcbevans commented 4 years ago

Hi @rcbevans @miksa1987 I tried monkey patching window.open() and modifying reactstrap tooltip args but could get none of that to work. So I switched to trying to find a replacement. I think #339 will work after I fix styling and tests. Then you guys can try react-new-window again which would be awesome :)

That's great. Looking for an alternative to the popover which was less dependent on directly accessing global Dom elements was a next thought that I didn't get around to looking at.

Everything else, for submission, autorun etc all just worked popped out into a new window. It's pretty cool.

dkozar commented 4 years ago

@rcbevans any ideas why the popover doesn't show up in my PR? πŸ˜„

https://github.com/neherlab/covid19_scenarios/pull/366/files#r402329029

I managed to ensure that the target element exists, however I'm not able to make the popover render. It should show up after the button is clicked:

image

Thanks,

dkozar commented 4 years ago

@miksa1987 Probably you already figured it out, but anyways. So the target problem of the popover is related to the existence of the element of some ID in the DOM.

target is element ID (string) or the element itself

I crated an utility method for checking if the element with ID exists, and if not, creating it on the fly:

export const createNonExistingElement = (id: string, type = 'div') => {
  let element = document.getElementById(id)

  if (!element) {
    element = document.createElement(type)
    element.setAttribute('id', id)
    document.body.append(element)
  }
}
dkozar commented 4 years ago

I'm interested in this task. Are there any new moments or UX input?

Thanks,

ivan-aksamentov commented 4 years ago

Resolved in #548