Example design: editable dashboard with chart widgets

Adding this example here, in case anyone wants to provide feedback on how I can better specify these design concepts (or offer any other advice). The actual application gets more complicated (e.g. I did not specify how widgets are edited), but my idea is that it’s better to start with a high-level description and then refine it with more details and more concepts.

Also, it seems to me that while we start with user-facing concepts, it should be possible to also define implementation concepts as well (i.e. redefine from user of the application to user of the code). Does that make sense?


A high-level definition of a dashboard.

Description:

A configurable grid of charts widgets.

When editing the dashboard, the user can drag new widgets onto a grid of drop targets or drag existing widgets to different locations on the grid. The user can edit individual widgets to define the dataset and size for the widget. When displaying the dashboard, widget positions and other properties cannot be edited. When NOT in edit mode, widgets display tooltips. When in edit mode, the user can click on widgets to drag and edit.

concept Widget
purpose render data as a chart
principle
	after fetch(d) a chart can be rendered
state
	edit: Bool
	data: one DataSet
	numRows: one Integer
	numCols: one Integer
	cursorHover: Bool
	showTooltip: Bool
action
	fetch(d: DataSet)
		assign d to data
		
	resize(r: Integer, c: Integer)
		if edit is True
		assign r to numRows and c to numCols
		
	display()
		set edit to False

	editMode()
		set edit to True
		
	showToolTip(e: edit, c: cursorHover)
		if e and c
		set showToolTip to True
		
---

concept Grid
purpose edit widget positions
principle
	after add(w, d) can move(w, d, d2) and remove(w, d)
	cannot add(w, d) or move(w, d, d2) if d in assigned
state
	edit: Bool
	assigned: Widget -> DropTarget
	hidden: set DropTarget
action
	add (w: Widget, d: DropTarget)
		if edit is True
		if w not in assigned and d not in assigned
		and d not in hidden
		associate d with w in assigned
		// A widget is only associated with a single drop target
		// but when rendered it may hide additional drop targets

	move (w: Widget, d: set DropTarget, d2: set DropTarget)
		if edit is True
		if w in assigned and d2 not in assiged and d2 not in hidden
		unassociate d with w in assigned
		and associate d2 with w in assigned

	remove (w: Widget, d: set DropTarget)
		if edit is True
		unassociate d with w in assigned
	
	display()
		edit is False

	editMode()
		edit is True

---

app widget-grid
include
	Widget
	Grid
sync Grid.add(w, d)
	Widget.fetch(d)
sync Grid.display()
	Widget.display()


// Implementation note:
// When Grid.move(w, d, d2), we should not lose widget data, numRows or numCols

Okay… in writing out the concepts, I can already see one obvious improvement, which is that the grid should not be coupled with the chart widgets. The grid should have an Item that can be specialized to a chart widget. This impacts how I think about the implementation, it forces me to write generic drag and drop grid code that has no knowledge of what exactly is being dragged and dropped.

Hi @tom – can you tell us a bit more about what these widgets are for? I think you may be mixing concepts and their UI representation here. Also, I wonder if you’re treating concepts as object classes? Are you assuming that each concept defines a set of objects each of which has the given state? I generally don’t do that, as it’s too restrictive. Also, the mention of Widget inside Grid creates a dependence of one concept on the other, which isn’t desirable.

Thanks for the guidance @dnj I think I understand some of your points. I’m going to write through this here (hopefully it is educational, I can keep some of this thought process private if it becomes too noisy).

In case I am going way off the rails, let me first state my goal: I want to define the concepts for the system of the product, i.e. the product design, and then refine the concepts to describe the system that will implement the product, and so on until the concept design is refined to a low enough level that the returns are diminishing. If I am off-track with this idea, someone can jump in and stop me now.


For the dashboard: let’s say we want a configurable dashboard with configurable widgets. I’ll start with a concrete use case, but I think the “product” should be generalizable.

Concretely, let’s create a dashboard of weather forecasts for different locations, e.g. using the National Weather Service API: API Web Service

Here’s an example of the weather forecast data: https://api.weather.gov/gridpoints/TOP/31,80/forecast


Product Description

Widgets

We can start with two types of widgets:

  1. a line graph chart showing the temperature forecast for the next seven days.
  2. a pie chart showing today’s probability for precipitation

Each widget should be configurable:

  1. Location for the forecast (latitude and longitude coordinates)
  2. Size of widget (num rows and cols it occupies)

Dashboard

The dashboard is a collection of widgets. We want the ability to configure:

  1. Size of the dashboard (num rows and cols)
  2. Placement of widgets on the dashboard (add, move and remove widgets)

Concepts

I see that we don’t want to couple the concept design with implementation details like pixels and API calls. The fact that the dashboard is displayed on a screen shouldn’t pollute the concepts that create the product.

I’m just going to list what sticks out to me as possible concepts to work with, and then maybe that list can turn into something with more substance.

  • add widget
  • move widget
  • remove widget
  • configure widget
  • visualization options (pie chart, line chart, flashing warning, etc.)

I don’t know, it feels like the concept I want is “objects on a grid”.

Maybe I need to get more detailed about the concepts that make it work, like what concepts enable the functionality of removing a widget or configuring a widget.

Definitely feeling a little bit lost after writing this out, so my ears are open for any advice that comes my way to help me understand what concept design should actually look like. Thanks!

@tom: Great to have a chance to talk about examples, so I appreciate you sharing your ideas. Don’t be concerned about being too noisy, since this is in its own thread, so people who are interested can hang out here, and people who aren’t can go to other threads…

I’m pondering this more and will reply soon. My initial reaction is that there are separate concepts of Weather, Widget (not specific to weather), and maybe Dashboard (which involves tiling of windows, and may not be even widget specific).

Hi Tom,

I agree with @dnj that it will likely be useful to separate the concepts. I see the following domains:

  1. Domain of UI layout specifically for dashboards. This may include the concept of Dashboard made up of rows/columns and Areas . The purpose of those concepts is to allow the user to create Dashboard-like UI layouts. This one is interesting as a concept because it is UI-specific which in general we ignore when talking about concepts unless the domain is about building UIs :slight_smile: The purpose of the Dashboard concept would be to allow the user to directly edit a screen layout made up of semi-regular rectangular areas in a grid.

  2. The second domain I see is the domain of the content of those areas. For those you might have different concepts depending on the type of content. Is it static content? Is it a dataset with different views that the user can toggle between… For static content, the concept would allow the user to set/unset this content on the widget (could be text, image…). For a data-backed widget, the purpose could be for the user to provide the data and render those in multiple ways (table, charts…)

  3. From there you could create new concepts (maybe) specific to a particular domain like the Weather so user can quickly build Weather dashboards depending on their needs.

This is very rough but I hope that helps a bit.

2 Likes

Thank you @benfle for pointing out that the domain is in fact building UIs. I don’t want to ignore that, because like I said in my first post, my interest is in going through all the levels of design, down to implementation (for example, a single-page application framework like Vue is built out of many interesting concepts like views, components, stores, composables, routes, etc.).

However, having you point out the domain of building UIs helps me to see that I could also zoom out on the design process by asking “why are we building a dashboard? what is it supposed to do?” , which brings up more general ideas such as communicating with users, how users access information (push vs pull, etc.), allowing users to customize their experience and so on.


Software purpose and domain (e.g. inform people about the weather)
User experience (customization, push vs pull data, visualization)
User interaction/interface (drag and drop widgets, select options in menus)
High-level implementation
Lower levels of implementation


To benefit the most from concept design, I guess we want to start at the highest-level possible, the problem that the system is solving, and proceed to lower levels from there, that way we avoid unnecessary complications that make sense when we’re in the weeds of implementation, but don’t actually fit into the bigger picture.

In my example, I started us off in kind of a weird place in that I just want to design a general dashboard system, I don’t care if it’s for weather or any other type of information, I’m just taking it as a given that people want to build dashboards (e.g. we already have software like Grafana and Power BI). But I really like where you brought my thinking on this, to at least think through the question of “what is a dashboard, really?”. That kind of thinking could lead to interesting concepts that provide rationale for new ideas that you’d never find by simply copying Grafana of Power BI.

A concept from the Essence Of Software book is “trash can”. In a way, this is a standalone concept that we can use in different contexts, but it obviously brings up the idea of a file system.

So I’m wondering about what concepts make up a file system. I believe it’s things such as:

file, directory, move, copy, delete, permissions, journaling, versioning

Does this sound right?

The reason I bring up this example is because I am trying to understand the problem of conflating objects with concepts and with creating dependencies between concepts. I think that all of the concepts I listed for a filesystem can exist independently, and then relate within the specific application of a file system. Although, if I add “trash can” to the concepts, it feels like the trash can concept inherently depends on the move and delete concepts.

Does “trash” have an inherent dependency on move and delete? If trash is a higher-level concept, does it then make sense that it’s composed of lower-levels concepts?

My bigger question is still if concepts are a suitable way to model and refine a system, in other words, can I use concept design with informal notation as a sort of Alloy pseudo-code? Or is this not the best use case for concept design? Is concept design something that can inform the design of a system, but not be used fo fully model it?

Also, I am reading the Demystifying Dependence paper now, so I apologize if I’m asking questions that are already answered in that paper.

Hi @tom, sorry to be slow in replying to this. I think you’re assuming that concepts are like procedures, in the sense that it’s “concepts all the way down”. I personally don’t think of it like that. Instead I think of the concepts as vertical slices through the system that represent separable aspects of behavior, and that include their entire implementation stacks.

In your file system example, I would expect permissions and versioning to be concepts, because these can be defined and understood independently of the rest of the file system. And directory might be a concept too, holding all the behavior associated with directories and their trees. I’d expect move, copy and delete to be actions of some of these concepts. Journaling is an implementation technique, invisible to the user, so I wouldn’t expect it to be a concept at all.

Now this doesn’t mean that you couldn’t define the concepts that characterize a lower level interface, so at some level you might have a concept like journaling that is visible to the clients above that level. In thet sense, you could perhaps construct a picture in which it is concepts “all the way down”, but elaborating the concepts at every level is probably a huge amount of work and I’m not sure that it’s worth it. The main benefit, in my view, is sorting out the concepts as experienced by the user.

This is very helpful, thank you.

I have my own weird motivations and I don’t want to misunderstand because I’m trying to shoehorn techniques into what I want to accomplish. I feel like I understand more clearly after reading how you think about it.

I think I am starting to understand.

To try to redeem my question about an editable dashboard, I will look into exploring the concepts in this JS library: https://gridstackjs.com/. The idea of a “dashboard” is not important here, it is simply a JS library for creating user editable grid layouts on websites. There are two users that are exposed to concepts: the user of the UI, who has concepts like “drag” and “resize”, and the user of the library, the programmer, who has to deal with the concepts like events, serialization, etc.