Comments (5)
Yeah, it's something I wanted to do (I made a comment a while ago in #205), but haven't had time with other stuff in life.
from bottom.
@ClementTsang I see! That's helpful to get more context from those other issues.
I think I'll fork and make a mess, but try some things out. If I come up with anything I'll share it back here for your consideration.
from bottom.
Ok so my main focus area is the fact that all of these widgets for graphs have to implement a different draw function depending on the data they receive.
flowchart TD
subgraph src/canvas.rs
A[struct Painter] --> B[impl Painter.draw_data]
end
subgraph src/canvas/widgets/cpu_graph.rs
B --> C[impl Painter.draw_cpu]
end
subgraph src/canvas/widgets/mem_graph.rs
B --> D[impl Painter.draw_memory_graph]
end
subgraph src/canvas/widgets/network_graph.rs
B --> E[impl Painter.draw_network]
end
from bottom.
My plan is to invert control here a bit. Instead of a CPU Widget or a Network Widget... We can have a Graph Widget or a Table Widget.
So then where do we get our data from? From things that are Graphable or Tableable. Which now I think is trapped in the widget state.
This is already kind of how it works. crate::canvas::components::{TimeGraph, GraphData}
take care of this.
Which really helps me hone in on: "how do I remove all these draw_x
functions and just wind up with a draw
.
My current hunch is that it's just a poor separation of concerns: Painter
should not be figuring out the legends and labels for the data. That should come from the State
.
This is tricky. So there's App
which has AppWidgetStates
. AppWidgetStates
just does some real minimal basic stuff. The actual data resides inside the App.converted_data
.
From an ergonomics perspective I think I would enjoy having App not be in charge of so much itself, but instead delegate it out to the widgets.
So my near target is to have the widgets own their converted_data
somehow, so they can use it to return labels.
I think it would be much easier to get down to a single draw
method without much switching if the WidgetState were responsible for the data being displayed in that widget and sending all necessary config to Painter
for drawing.
TLDR; there's too much state in my paint!
from bottom.
I've been exploring more and it seems like separation of concerns is a bit difficult. There are good reasons for everything to be scoped the way it is, but there are ways to separate concerns with a little more added complexity.
One of my big goals is to have the state
objects (TempState
, NetState
) own the data that their widgets need to render.
If we're talking about a Model View Controller framework (which bottom uses?) then the state
objects should own all data that the application uses.
However, we also have the concept of the Collector
. The Collector
runs in a separate thread to collect system metrics on a defined interval.
I first thought it would be good to separate collection to each Widget
so that each Widget
would have a State
and a Collector
. However this isn't ideal because Collector
collects sysinfo
for example and then delivers it to several other widgets.
It would be inefficient at this moment to have each widget have a thread for collecting their info because they would all make redundant calls with sysinfo
.
This pattern could be handled by Channels. However we would now need a thread to pull data into the state objects.
collect -> channel_n -> Vec<i32>
.
Downside: need thread to pull data out of the channel.
Upside: it probably already exists.
Goal: give state
ownership of a data channel
that the collector can send to and give the collector
a reference to transmit to. Just for Temperature, but hopefully if the pattern works well refactor other states to follow.
In the end this will give the states higher authority over their data and we can potentially move the farmer
responsibility into the state.
States being responsible for their data allows us to then focus on making widgets be Views
instead of a whole MVC
architecture themselves.
Models: Battery
, Temperature
, Network
, CPU
, Disk
Views: Graph
, Table
BatteryModel
+ GraphView
= BatteryGraphWidget
TemperatureModel
+ GraphView
= TemperatureGraphWidget
TemperatureModel
+ TableView
= TemperatureTableWidget
etc.
I would probably also do away with the term Widget
all together in favor of Views
. Highlighting an architectural pattern in the naming choices will make it much easier to navigate and construct well. Or saying that a widget is a combination of a Model
and a View
. That could work.
from bottom.
Related Issues (20)
- Prefer showing more disks than more mount points HOT 4
- json schema support HOT 2
- Output metrics for later plotting and analysis HOT 1
- Make ctrl+c behave like Esc (just like vim) HOT 1
- Network RX speed being displayed as ten times the actual value HOT 2
- Wrong Swap Information on Windows11 HOT 1
- have plain color fill instead of "||||" bars to show mem and cpu HOT 2
- on the top or bottom there should be some basic stats like uptime,users, as the 'top' has HOT 1
- bcachefs support for disks widget
- Icon for bottom HOT 3
- Request to make small release that includes the desktop file in master HOT 2
- Ahash v0.8.3 is yanked in registry `crates-io` HOT 1
- Homebrew Formula linked to master, not main HOT 4
- Bug when using --hide_table_gap with Battery Widget.
- There is no CPU temp HOT 3
- Improve temperature sensor detection on Windows
- winget duplicate package cant install HOT 15
- View open file handles, organized by which processes own it
- Reset network traffic on start option HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bottom.