COVID-19 Dashboard Creation

Ok here is what I have been able to hobble together. I have found the Staffing part has been working (I am using a collection to obtain the current active staff for a shift in the command center).

I am not sure if this is the right way to go about patients and locations. Right now I have created adornments for different COVID units. I am having some trouble changing attributes on children that are dragged onto each adornment (I would like to have the $UnitLocation changed to the name of the adornment ie SICU when they are moved from lets say 4 south to this unit).

I am also trying to determine how to best tally things such as negative pressure rooms remaining, number of intubated patients (and maybe other resources. Once I figure out the best way to track and count I can add any number of them as attributes).

I would like to create another table to display total counts for things such as number of patients with covid (ie by status), total number of ventilators in use and remaining (I would need to count the number in each ‘unit’ and then do the math. Not sure how to access these attributes from all of the various adornments (unless there is a better away to arrange these).

Here is a sample of what I have thus far. I will keep plugging away at this. Thanks in advance for any thoughts or directions to pursue.

COVID-19 Dashboard - Working File.tbx (155.5 KB)

Made some changes, I created Note collections for the locations instead of adornments (I thought adornments would behave like collections but they do not appear to do so). Please let me know if there is a use for adornments in this design. I am starting to get some of the aspects I was looking for. Here is an updated file

COVID-19 Dashboard - Working File.tbx (125.4 KB)

1 Like

Not sure this helps. With cross-tabs you can display generally display your notes in a 2D grid based on two attributes. With the addition of a well chosen display parameter in the controls above you can actually display one additional attribute. If for instance you would like to display your patient name, the status of their Covid-tests and whether they are located in SICU and MICU (or any other department) you can easily generate the following using the test file you provided:

Left you see the patient names, the columns represent their test status and I use the display to show the container for each note (MICU or SICU). The beauty of TinderBox is that you can display each note and click on it for additional information, editing or updating in the grid.

In a similar vein here an example now displaying the room number of the patient.

I sense that in addition to a better overview of your notes you would also like to address th Capacity and Occupancy Grid that you provided as illustration at the beginning of the post. If I’ve understood correctly the first column of your table is static e.g. the total capacity of critical care beds, ventilators etc… is a constraint that does not vary with time (unfortunately in many cases). The 2nd column however reflects the current number of patients and their medical equipment needs. Could you please confirm ?

Thank you Malcome (and Paul). I agree with both of you that I think the Cross-Tabs will be useful in this dashboard. I have to work more with this to understand. As I am working on this document, I am realizing there are more levels I should be thinking about. Let me see if I can outline these levels, and then also answer your question about current resources, patients and their needs.

As you see in the document (I am adding another update since I have begun to look at the idea from Tinderbox Way Summaries and Repeaters - still trying to figure out the correct rules to sum the children elements).

COVID-19 Dashboard - Working File.tbx (137.5 KB)

I am thinking about the following prototypes:

Patient

Room - with attributes - isNegativePressure, RoomNumber, Location (this would be SICU, MICU, 4S, etc). When A patient is assigned to a room, I would ‘drop’ a patent Note into the room (ie room would contain a patient).

Ward - Considering using an agent to ‘collect’ all Rooms that match Room.$Location with Ward.$Name. Then I could add additional attributes to calculate - Total number of rooms, Total occupied rooms would then be a sum of all children (rooms) that are occupied (ie have a child which is of type Patient).

Then would need a summary Agent (as I have now called Resources by Location) which would collect all the Wards and perform the calculations as I have them.

To answer your question - As we work through this Pandemic, the goal is to track our current capacity and that which remains. For example, by creating locations in the hospital (which I am calling Wards) and assigning the available rooms (these could be current physical rooms or other locations that have been converted to rooms to address the needs of the surge). I would then be able to display the current capacity as well as the number of occupied rooms. I would ultimately look at setting some criteria, maybe using text color, to indicate when we are reaching capacity (for example change color to Orange when we are at 80% filled and Red when we reach 100%). In addition, we would need to track limited resources as well, such as Ventilators. I will likely create notes to hold total available ventilators and then reference this to determine remaining ventilators (by summing each patient note where isIntubated == true).

I hope this makes sense. I am not sure if this is the right way to proceed with laying this out or not so any feedback is appreciated.

I am having trouble with getting the numbers to work out. For example, if you look at this latest document I liked in this reply, The Note Available Beds (currently lists 64) but this should be 62 (68 Total Beds - 3 used in SICU - 3 used in MICU). Not sure why this Rule is not working as I have it??

Thanks again, let me know if what I communicated makes sense.

Don

The result of the calculation is correct per the rule you are using in Available Beds:

$Subtitle = $TotalCapacity(/Resources By Location) - $ActiveCensus(/Resources By Location);

because $TotalCapacity in the Resources by Location note is “68” and $ActiveCensus in that note is “4”, thus 68-4=64.

Are you thinking of a different calculation.

In that vein, the $Rule for the Resources by Location note is

$ActiveCensus = sum(children,1)

Which merely counts the children of the agent. (Is that what you want to be doing?). And I see nothing that sets Total Capacity in that agent. What is the rule for Total Capacity? Number of Rooms? Is it a hardcoded setting?

I also noticed that there were some composited notes in the Outline. I suggest running an agent to remove all composites (setting $IsComposite = false); and turn off compositing globally (setting $NeverComposite = true in all notes as well as the default setting for that attribute.

Thanks for this. A few observations, from experience…

Don’t build big maps in the document root—or, as here—maps that will grow big. A few reasons are:

  • As the doc grows the sheer number of things on the map becomes overwhelming. It’s useful to put all the ‘content’ in a separate root-level container to thru-doc stuff like containers of prototypes, templates, action code snippets, etc., and notes related to the ‘how’ of the document.
  • Within the content area, put things of a type together. You’re quite correctly thinking ahead with prototypes. So a good idea might be to have, inside the content branch of the outline, a ‘Locations’ container, to hold locations. Theese containers can have an OnAdd to set the right prototype to aid rapid configuration. Thus the 'Staff' container's OnAdd would be ` Prototype=“Staff”`, etc. But the later shows another easily made sub-par choice.
  • Prototype names. Like as note you’ll wants a folder to hold things of a type, e.g. Staff. so, for prototypes avoid-using a name that might/will be a note or container name. The simplest method is to use a prefix for prototype names. I use ‘p’ (pStaff), some like an asterisk (*Staff). anyway, pick a style you like and use it for all your prototypes. Not only will it avoid name collisions but will make reference to prototypes very clear (especially when using action code). Note that if renaming existing prototypes you will need to review existing rules/edicts/queries/etc that use the old name. The latter task is another good reason to use distinctive prototypes as the later in the process you need to do this the more checking is needed.
  • For (will get) big categories—likely, patients—you may well get to the point where having all notes of a common (proto)type in one container is unwieldy. Watch for using inside() in your code/queries. Likely for the actual work you’ll want to replace inside() with descendedFrom() with an additional & $Prototype==… filter to ignore structural non-content sub-containers, for instance if you split staff into ‘A-M’ and ‘N-Z’ containers.
  • At the early stage, agents and rules are really quick ways to prototype things but be aware that as things grow, now everything needs to be always-on. $AgentPriority can be used to make (some) agents run less frequently. Moving rules to edicts can stop unnecessary over-calculation. Edicts can still be run on demand. Keep rules for where you can’t afford the possibility of data not being correct without (minimal) user effort to update it. The balance here is a very personal thing. I only mention it so if/when agents and rules start to slow down the document, you know there are approaches to deal with that.
    *Dashboard. Think where you want it. If outside the outline branch holding your content/data then you’ll be forced to use agents more that you want. If inside the top level of the content branch you may be able to use table expressions where otherwise you’d use (more) agents.

On the separate issue of table expressions vs. other views, such as Crosstabs. I think the the narrow A vs B context of a Crosstab isn’t the thing here, but Attribute Browser+Column view might. Whether using the latter or Table expression, the way to do this is to calculate these values and store them per-note (where relevant, i.e. not every note) ready for display in TEs or in AB view. Calculate them using action code in a rule (or edict, as explained above).

Thanks again for the help. The most amazing thing I find in this forum is how your insights clear up my understandings and lack of great organization.

To response to a few points, I have been using the current document that I have been sharing as a playground of sorts to try and understand exactly what I need to do. I have realize that I have not abstracted things like I should have in the beginning so I am working to refactor the entire design from the ground up.

Paul - No I did not communicate this very well (And also did not follow good programming practices by naming something that makes no sense). The Agent - Resources by Location (Maybe a better name would be Total Capacity/Use), is collecting all locations (ie MICU, SICU, 4 South, 5 South) so I do not just want to sum the children (this would count the number of locations (or maybe in a hospital framework should call these Wards).

$TotalCapacity in Resources by Location comes from the Total Capacity in each of these locations added together. Again, in my act of building this as I think (Probably not the best idea, but it has allowed me to understand my flaws in thinking and will guide my refactoring) I used $BedCapacityByLocation in the Location Prototype thinking I would need different names for these attributes which in fact I do not. So I should have used a single attribute $TotalBeds or $TotalCapacity. In the Location’s, it would = sum(children,1). Then in the Agent (currently named Resources By Location) it would simply be sum(children, $TotalCapactiy). In the ‘working’ document, I have modified the rule so this now works as I expected.

On a separate note: I have noticed when I make changes in my Rules (for example in the Location Prototype), these did not propagate down to Locations that already contained other notes. Is this something I am doing wrong? Or is there an issue with modifying rules that are containers holding other notes?? To fix this, I removed all of the Patient notes from the MICU and SICU note collections, deleted them and recreated them. When I added the patient notes back the Rules now ran and everything was in sync. I am guessing this is something I am doing wrong in the order I update things, but thought I would ask to see if other people had this problem as well. (This is why in the last version Paul could not see how I arrived at $TotalCapacity - this part of the rule was not there (I think I deleted it in my edits) yet the last calculation remained).

Corrected Document:
COVID-19 Dashboard - Working File.tbx (147.6 KB)

I will respond to Mark below since this is already very long. Thank you for all of the help. I have made far more progress on this over the weekend than I would have ever imagined.

Sincerely Grateful for all the Help!!
Don

Mark,

Wow, there is so much contained in this short reply! Yes, it makes sense and thank you. I can use this as my outline in refactoring this. I really apologize for the messiness of this. When I have used tinderbox for my own personal documents, I have started in the outline and was much more diligent on how I organized things. This being said, I have not used Tinderbox to the level I am using it now with this COVID dashboard. In this light, I need to appreciate all you mentioned with respect to rules, agents and edicts. I completely understand what you are saying and for the most part, I do not need these to run as frequently as I am here with my development of ideas and learning so I appreciate this warning as I move forward on trying to bring this into use (I will likely be using this as a dashboard being sent out 2x pre day so I can always run things as a final before I export, if that makes sense).

I also agree with your thoughts on using Attribute Browser. I think this is where I Am going to find a lot of power for this. I am working on this now so I can further see how to structure things so this becomes useful as a dive into the specifics of patients and locations.

Thanks again for all of the help and pointing me in the right direction for exploration!

Appreciate everything.

Don

1 Like

No, please don’t feel a need to apologise. The real world is messy. Luckily we have a tool to work through that.

Paging @JFallows who’s ideas worked so hard to convince all of value of such a feature.

The root issue is probably breaking an inheritance chain. If a prototype has a $Rule, and then we edit the $Rule in one or more of the notes that use that prototype, the local edits take precedence over the inherited $Rule. It’s a common mistake and easy to fall into – @mwra and I were exchanging thoughts about that the other day, as a matter of fact.

In the case where inheritance of $Rule or $KeyAttributes or other inherited value of an attribute gets broken, the QuickStamp is my favorite (quick) method to fix the error. Here’s how:

2 Likes

A general comment about this sort of project. Usually, the advice is to let structure of a document emerge as you develop the notes, etc. However, emergent structure is not always the best approach to developing something that will be used for tracking and reporting. @DMV you’ve been sketching your ideas with Tinderbox and iterating toward a solution. When I get to that stage, I set aside Tinderbox for a while, and with pen and paper (metaphorically or actually) I sketch out a more formal visual spec for the document I want. Then I go back fresh to Tinderbox and build based on the sketch.

A problem with “emergent structure” is what I see you’ve encountered. You change the idea for what prototypes or containers you want, and spend time fiddling with prototype edits, or various agents, etc., and then sometimes end in a debugging muddle. To me that’s a clue to step back, make some sketches and specs, and then start fresh.

2 Likes

Thank you! This is exactly what I think has been happening! Easy to do and appreciate the fix. I did not know how to fix these mistakes other than deleting what I had an reconstructing. This is very helpful!

Don

1 Like

You have another great piece of advice. Today, I set aside the computer and restarted with paper as you suggested. In my templating of the idea over the weekend, I learned what was possible. Then I tried to build it from my iterations, but found it is better to be very clear on the design and then add the data to see the results. In other words, I am doing what you have mentioned using paper and being clear instead of changing on the fly.

Thanks again to this group for all of your help! I feel like I need to pay this back to the community. After things settle down (I am an ultimate optimist and know we will all get through this), I feel like I should use this type of project to create some educational materials on what I learned. There is no question about the power of Tinderbox and I would love others to appreciate this in there work!

Thanks again for all the help!
Don

1 Like

we’re eager to see and hear about the new design, and your experience using it!

1 Like

Further to @PaulWalters’ useful reminder about editing prototype-inherited rules, edicts, etc. at local (i.e. note using prototype) level, the Action inspector has a useful tell back. Consider this:

We have a note ‘Jane Doe’ using a prototype ‘Person’. With ‘Jane Doe’ selected, we see the Rule Inspector shows a ‘default’ label. This tells us the value being inherited by the the note us the document default for $Rule. Note that it doesn’t tell you if that doc-level default is edited but as the user you likely would know if you’d made that non-incidental edit! Now I’ll set a rule in the prototype:

Action Inspector: untitled 2020-04-14 10-21-45

With the result in ‘Jane Doe’ that the label now says ‘inherited’:

![Action Inspector: untitled 2020-04-14 10-25-44|618x340]
(upload://naDunKhuSkXg5cRfZMehZoGMMev.png)

This tells us the attribute (in this case the $Rule) is inherited from a prototype, i.e. we can expect this note’s attribute to change if the same attribute is changed in the prototype. Lastly, if we change the rule in the note itself, and unintentionally break inheritance:

Action Inspector: untitled 2020-04-14 10-28-43

See the result, there is now no label showing inheritance state. Were you to view the same attribute as a Key Attributes or in Get Info, you would see it bolded to indicate a locally set value:

Lastly, if you realise with dread that you may have lots of notes with values unintentionally set locally, then hasLocalValue() is your friend. For instance we could fix the $Rule inheritance of all notes using the ‘Person’ prototype using an agent with a query:

$Prototype=="Person" & hasLocalValue("Rule")

and agent action:

$Rule=;

The agent should run and end up empty as all notes in query scope should now be correctly configured. I don’t suggest leaving agents like this once finished with or they are just more clutter/overhead, especially when they are so easy to configure.

1 Like

Hi Don,

You might like to consider tweaking the display expression to allow for a quick visual of important KAs - could be useful in conjunction with a filtered outline to give a quick and dirty screenshot printout ahead of a more structured export?

Good luck and keep safe my friend
x


$Name+"[Loc:"+$UnitLocation+"/"+$PatientLocation+": Rm - “+$RoomNumber+” St: “+$COVIDTestStatus+”]"

I expect you will have a lot of information scattered around in spreadsheets re staff and patients from other sources - this thread might be useful to you in achieving an import into your tbx

Hi DMV,

is there any updated version of your file that you are happy to share? How did you create the “resources by location” dashboard? is that an agent/adornement? just looking for inspiration…

As a fellow intensivier I hope you made it through the last few years ok.

Cheers,
Doc_C