Examples › robotparts › The bar, Obsidian's way: one chip and spread-out words
The bar, Obsidian's way: one chip and spread-out words
The same 1,149 actuators under toolbar="bar" views="dropdown" promote="sort group filter properties" display="panel": Bases' view chip
(its chevron lights on hover; its menu has a find box, a ✓ on the current view and Add view), then Sort · Group ·
Filter · Properties as words that say what is set ("Sort: Peak torque"). Zach: "obsidan has compact views and spread
out filters".
The .base file and its data
Every tab above is one entry of this file; the views read these rows. ⋯ in the toolbar copies the current view as YAML.
# The bar, Obsidian's way (docs/CONTRACT.md §15): views="dropdown", filters="expanded", display="panel". The same file
# as the toolbar-bar case (robotparts' 1,149 actuators); only the element's attributes differ (site.json). Bases keeps
# the views compact in one chip and spreads Sort · Group · Filter · Properties out as words. Check it:
# node bin/data-ui.mjs check <this file>
data: ../robotparts-actuators/actuators.json
facets:
- brand
- form
- drivetrain
- buses
- level
- { property: peak_torque, as: range }
- { property: mass, as: range }
- { property: price, as: range }
- { property: torque_density, as: has }
properties:
model: { displayName: Model }
brand: { displayName: Brand }
form: { displayName: Form }
drivetrain: { displayName: Drivetrain }
peak_torque: { displayName: Peak torque }
rated_torque: { displayName: Rated torque }
max_speed: { displayName: Max speed }
mass: { displayName: Mass }
gear_ratio: { displayName: Ratio }
voltage: { displayName: Voltage }
od: { displayName: OD }
length: { displayName: Length }
buses: { displayName: Bus }
torque_density: { displayName: Peak N·m/kg }
price: { displayName: Price from }
sellers: { displayName: Sellers }
level: { displayName: Level }
views:
- type: table
name: Rows
order: [model, brand, form, drivetrain, peak_torque, rated_torque, mass, price, buses]
sort:
- { property: peak_torque, direction: DESC }
- type: cards
name: Gallery
order: [model, brand, peak_torque, mass, price]
image: photo
imageFit: contain
imageAspectRatio: 0.8
cardSize: 190
- type: chart
name: Torque vs mass
chart:
mark: point
encoding:
x: { field: mass, type: quantitative }
y: { field: peak_torque, type: quantitative }
color: { field: brand, type: nominal }
- type: table
name: By brand
order: [model, form, peak_torque, rated_torque, max_speed, mass, gear_ratio, voltage, od, length, buses, price]
groupBy: { property: brand, direction: ASC }
sort:
- { property: peak_torque, direction: DESC }
summaries: { peak_torque: Max, mass: Min, price: Min }
- type: table
name: Brand › form
order: [model, peak_torque, mass, gear_ratio, voltage, price]
groupBy: { property: brand, direction: ASC }
subGroupBy: { property: form, direction: ASC }
sort:
- { property: peak_torque, direction: DESC }
summaries: { peak_torque: Max, price: Min }
fold: closed
- type: table
name: Torque density
filters: '!torque_density.isEmpty()'
order: [model, brand, torque_density, peak_torque, mass, price]
sort:
- { property: torque_density, direction: DESC }
display: { torque_density: bar }
- type: table
name: Geared CAN under $150
filters:
and:
- 'drivetrain == "geared"'
- 'buses.contains("can")'
- 'price < 150'
order: [model, brand, price, peak_torque, mass, gear_ratio, voltage]
sort:
- { property: price, direction: ASC }
display: { price: bar }
- type: table
name: All, flat
order: [model, brand, form, drivetrain, peak_torque, rated_torque, max_speed, mass, gear_ratio, voltage, od, length, buses, torque_density, price, sellers, level]
sort:
- { property: brand, direction: ASC }
- { property: model, direction: ASC }
- type: pivot
name: Brand × form
order: [brand]
splitBy: [form]
value: { property: null, summary: Count }
sort:
- { property: brand, direction: ASC }
- type: pivot
name: Torque by drivetrain × form
order: [drivetrain]
splitBy: [form]
value: { property: peak_torque, summary: Median, display: dist }
// ../robotparts-actuators/actuators.json: 1,149 rows, 608 KB; the first 3
{
"id": "actuators",
"title": "Actuators",
"titleProperty": "name",
"linkProperty": "url",
"source": "robotparts dist/site/v2/catalog.json, release 2026.10.25 (lane/tables @ ab5ba92); mass from each spec's own unit; photo: robotparts media/photos.jsonl, 150 of 1725 copied at 240 px",
"properties": {
"name": {
"type": "text",
"hidden": true
},
"model": {
"type": "text",
"width": 190
},
"brand": {
"type": "text",
"width": 120
},
"form": {
"type": "text",
"width": 140,
"display": "badge"
},
"drivetrain": {
"type": "text",
"width": 104
},
"buses": {
"type": "list",
"width": 120
},
"level": {
"type": "number",
"width": 58
},
"url": {
"type": "text",
"hidden": true
},
"torque_density": {
"type": "number",
"unitText": "N·m/kg",
"width": 130,
"derived": "peak torque / mass, by robotparts"
},
"price": {
"type": "number",
"unitText": "USD",
"decimals": 0,
"width": 120
},
"sellers": {
"type": "number",
"width": 70
},
"peak_torque": {
"type": "number",
"unitText": "N·m",
"width": 126
},
"rated_torque": {
"type": "number",
"unitText": "N·m",
"width": 126
},
"max_speed": {
"type": "number",
"unitText": "rpm",
"width": 126
},
"mass": {
"type": "number",
"unitText": "g",
"width": 126
},
"gear_ratio": {
"type": "number",
"unitText": ":1",
"width": 126
},
"voltage": {
"type": "number",
"unitText": "V",
"width": 126
},
"od": {
"type": "number",
"unitText": "mm",
"width": 126
},
"length": {
"type": "number",
"unitText": "mm",
"width": 126
},
"photo": {
"type": "text",
"hidden": true,
"display": "image",
"note": "robotparts' primary photo, resized; only the parts this case copied have one"
},
"step_up": {
"type": "text",
"hidden": true,
"derived": "the next photographed part of the same brand up in peak torque (build_examples.py)",
"note": "an edge for the graph view: among the parts with a photo here, the brand's next one up in peak torque"
}
},
"rows": [
{
"id": "aifitlab-8541438771336",
"name": "Steadywin GIM4305-10",
"brand": "Steadywin",
"model": "GIM4305-10",
"form": "integrated actuator",
"drivetrain": "geared",
"buses": [
"can",
"rs485"
],
"level": 4,
"url": "https://robotparts.dev/actuator/aifitlab-8541438771336/",
"peak_torque": {
"value": 3.82,
"basis": "seller",
"source": "aifitlab.com"
},
"rated_torque": 1.05,
"max_speed": 402,
"mass": {
"value": 150,
"basis": "seller",
"source": "aifitlab.com"
},
"gear_ratio": 10,
"voltage": 24,
"od": 53,
"length": 26,
"torque_density": 25.467,
"price": 70,
"sellers": 1,
"photo": "photos/aifitlab-8541438771336.webp",
"step_up": "aifitlab-8542347853960"
},
{
"id": "aifitlab-8542347853960",
"name": "Steadywin GIM6010-8",
"brand": "Steadywin",
"model": "GIM6010-8",
"form": "integrated actuator",
"drivetrain": "geared",
"buses": [
"can",
"rs485"
],
"level": 1,
"url": "https://robotparts.dev/actuator/aifitlab-8542347853960/",
"peak_torque": {
"value": 11,
"basis": "seller",
"source": "aifitlab.com"
},
"rated_torque": 5,
"max_speed": 420,
"mass": {
"value": 388,
"basis": "seller",
"source": "aifitlab.com"
},
"gear_ratio": 8,
"voltage": 24,
"od": 80,
"length": 40,
"torque_density": 28.351,
"price": 70,
"sellers": 1,
"photo": "photos/aifitlab-8542347853960.webp",
"step_up": "aifitlab-8542620287112"
},
{
"id": "aifitlab-8542620287112",
"name": "Steadywin GIM8108-8",
"brand": "Steadywin",
"model": "GIM8108-8",
"form": "integrated actuator",
"drivetrain": "geared",
"buses": [
"can",
"rs485"
],
"level": 1,
"url": "https://robotparts.dev/actuator/aifitlab-8542620287112/",
"peak_torque": {
"value": 22,
"basis": "seller",
"source": "aifitlab.com"
},
"rated_torque": 7.5,
"max_speed": 320,
"mass": {
"value": 396,
"basis": "seller",
"source": "aifitlab.com"
},
"gear_ratio": 8,
"voltage": 48,
"od": 92,
"length": 55,
"torque_density": 55.556,
"price": 85,
"sellers": 1,
"photo": "photos/aifitlab-8542620287112.webp",
"step_up": null
}
],
"imageProperty": "photo"
}README.md
# The bar, Obsidian's way: one chip and spread-out words
The same 1,149 actuators under `toolbar="bar" views="dropdown" promote="sort group filter properties" display="panel"`: Bases' view chip
(its chevron lights on hover; its menu has a find box, a ✓ on the current view and Add view), then Sort · Group ·
Filter · Properties as words that say what is set ("Sort: Peak torque"). Zach: "obsidan has compact views and spread
out filters".
- **App:** robotparts
- **Replaces:** Obsidian Bases' toolbar (the view chip and its Configure view menu, and the Sort / Group / Filter /
Properties words; zach_brain Sources/Images/Pasted image 20261026122137.png, …122154.png and …122424.png).
- **Shows:** `views="dropdown"`, `promote="sort group filter properties"` (the four Display sections promoted onto the bar as words with their active state; `filters="expanded"` is the same, as an alias), `display="panel"`.
- **Data:** `../robotparts-actuators/actuators.json` (the robotparts-actuators case's file).
The original UI it replaces
Obsidian Bases' toolbar (the view chip and its Configure view menu, and the Sort / Group / Filter / Properties words; zach_brain Sources/Images/Pasted image 20261026122137.png, …122154.png and …122424.png).
What it shows
views="dropdown", promote="sort group filter properties" (the four Display sections promoted onto the bar as words with their active state; filters="expanded" is the same, as an alias), display="panel".
Data
../robotparts-actuators/actuators.json (the robotparts-actuators case's file).