Carson Rajcan
banner
wellofcarse.bsky.social
Carson Rajcan
@wellofcarse.bsky.social
Building UIs with Rust
The latest version enabled the user to perform CRUD ops on Operators (functions) with drag and drop. Users could then view validation errors, rebuild their project, view compiler errors, and re-deploy.
April 30, 2025 at 5:40 PM
Well I lost my job at Infinyon so unfortunately I won't be able to tell the whole story of how I built #sdfstudio, a data pipeline editor. But for about 10 of the last 18 months I got paid to build a web app with #rustlang, something I never thought I would get to do.

#buildinpublic #webdev #leptos
April 30, 2025 at 5:40 PM
I was pretty happy with the final result. The arrow is dynamic enough to not be distracting, although there are a couple orientations where it isn't quite perfect. If you know anything about the math behind graphics like these, perhaps someone from #gamedev, leave me a hint!

SDF Studio thread 7
April 24, 2025 at 3:56 AM
Determining the angle of the arrows is also difficult. A perfectly horizontal edge can have a tip that points horizontal, but one that points more vertical will need more angle. I tried calculating this angle dynamically but wasn't sure quite how to model it. In the end I hardcoded the 4 edges.
April 24, 2025 at 3:56 AM
The 2nd update to #sdfstudio edges was the arrows. At this stage, edges are still made from basic html divs, so arrows would just be divs with borders on two sides, rotated to point at the node. Positioning the arrows would have to be pixel-perfect.

#buildinpublic #rustlang #leptos #webdev #css
April 24, 2025 at 3:56 AM
The end result communicates the flow of data through the service, operator by operator.
April 24, 2025 at 3:56 AM
The code to determine the edge entry/exit point for Service nodes is again a lot of math, The height of the service's operators (functions) has to be taken into account, as well as the gap between them and the parent div's padding. This is all done with respect to the #css positioning.
April 24, 2025 at 3:56 AM
To handle #1 above, each node type needed new methods to calculate entry/exit points.

Ideally in Rust, we would create a "Node" trait for common methods like these, but at this point I need JSON de/serialization, which is complicated with trait objects, so I stuck with basic enums to start.
April 24, 2025 at 3:56 AM
In yesterday's thread about #sdfstudio, the data pipeline editor I was hired to build, I skipped over two slight changes to graph edges. #1, the edges leading to and from Services now point to the first and last operators. #2, edges now have arrows! #buildinpublic #rustlang #leptos #webdev
April 24, 2025 at 3:56 AM
The final visualization reflects the use case for Services and also saves a lot of space on the screen. There will be a lot more work on designing Service nodes and organizing large graphs in a readable way. SDF studio thread 6.
April 23, 2025 at 2:10 AM
After calculating the service dimensions, the dot file gets generated and fed into the #graphviz dot algorithm. The output is used to create the final Graph object which is returned to the client and rendered. The node with id 2 is the Service in this case.
April 23, 2025 at 2:10 AM
Calculating the dimensions requires calculating the sizes of all the component parts, which is a lot of math and negates some of the benefit of being able to draw with html. Long term, the goal will be to render the nodes first, get the dimensions, run the layout algorithm client side then re-render
April 23, 2025 at 2:10 AM
My previous thread on my data pipeline editor left off after I had created nodes and edges, and organized them algorithmically.

My first challenge as a paid contractor was to render a real config used by the processing engine.

#buildinpublic #rustlang #softwaredevelopment #sdfstudio #leptos
April 23, 2025 at 2:10 AM
Dot can output json, so I was able to use serde::Deserialize to parse just a Vec of nodes with "name" and "position" fields.

Using this output yields a very human readable DAG.

This was enough to satisfy the startup and we inked a contract!

#buildinpublic #rustlang #webdev #sdfstudio #leptos
April 14, 2025 at 5:59 PM
The dot cli uses it's own language (also called dot) for configuration. The config expects a list of nodes and edges. I had to adjust the default "rankdir" to left -> right (the default is top -> bottom). Dot also expects that node sizes are given in inches, so I had to later convert to pixels.
April 14, 2025 at 5:55 PM
My plan was to call the dot CLI with my graph's configuration, which meant I needed to introduce a server.
#leptos offers a convenient abstraction for integrating with an actix or axum webserver, called server functions. Server_fns let you just call an endpoint like any other function #rustlang
April 14, 2025 at 5:46 PM
After creating a draggable flow chart for my data pipeline editor poc, there was just one more feature I needed to add to ink a contract with the startup.

I needed to find a way for the graph to be organized algorithmically.

#buildinpublic #rustlang #webdev #sdfstudio #leptos
April 14, 2025 at 5:33 PM
I put together a real life example and used it to pitch my solution to the client. They were impressed by the example! They are still worried about the difficulty of laying out the graph programmatically, so I need to solve that to get the contract #buildinpublic #rustlang #webdev #sdfstudio #leptos
April 12, 2025 at 2:55 PM
After I implemented the SouthWest edge I added a NorthWest edge as well. I'm happy with the appearance and performance of the final example. Implemented with four divs, the code for westward edges is not so clean this time so I'll spare you.
April 12, 2025 at 2:47 PM
Selecting the correct edge to use given the node orientation proves to be an interesting challenge. The answer is to take the node width and some offset into account when switching between east and west edges. So westward edges are preferred when the nodes are close. #buildinpublic #rustlang #webdev
April 12, 2025 at 2:37 PM
This expands into a lot of math. It is an interesting feeling when most of your refactoring steps are require simplifying algebra.
April 12, 2025 at 2:16 PM
Westward pointing edges are a bit harder to implement. Using the current approach, they require four divs because the edges need to begin traveling right before they turn left. I introduce an "α" value to ensure the edge does not travel too close to the nodes.
April 12, 2025 at 2:13 PM
Previously, I figured out how to make rightward pointing edges for my data pipeline editor (I'm calling them NorthEast, SouthEast). Before I bring the poc to the startup that proposed the project, I want to complete left pointing edges: NW and SW

#buildinpublic #rustlang #webdev #sdfstudio #leptos
April 12, 2025 at 2:04 PM
In this initial version there are no svgs. So each edge is made up of two divs. The width, height, left and top values are all reactive.

In leptos, `#[component]` functions only runs once, and accessing a closure or a signal in the `view!` macro registers an effect in the react system.
April 11, 2025 at 12:17 PM
I was pretty happy with how smooth the final product ended up. Next I would have to implement the SouthWest and NorthWest edges which would be more complicated. After that these probably need some direction arrows or animations on the edges.

#buildinpublic #rustlang #webdev #sdfstudio #leptos
April 10, 2025 at 10:54 PM