Gallery › robotparts › Actuator charts

Actuator charts

robotparts' 1,149 actuators as chart presets in one .base file: peak torque vs mass coloured by brand, an Ashby chart with a filled envelope per drivetrain and a constant N·m-per-gram index line, torque density, price vs torque, small multiples by form and median torque by brand. Tick the rail and every chart redraws; hover a dot for the part's photo and values; click it for the record.

robotpartscharttable7 views of one actuators.json

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.

# Actuator charts: robotparts' 1,149 actuators as chart presets, one .base file. Each preset is a view; inside
# `chart:` the vocabulary is Vega-Lite's (docs/SPEC.md §8), everything else is Bases'. The rail filters every chart.
# Check it: node bin/data-ui.mjs check <this file>
data: ../robotparts-actuators/actuators.json
facets:
  - brand
  - form
  - drivetrain
  - buses
  - { property: peak_torque, as: range }
  - { property: mass, as: range }
  - { property: price, as: range }
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: chart
    name: Torque vs mass
    chart:
      mark: { type: point, filled: true }
      encoding:
        x: { field: mass, scale: { type: log } }
        y: { field: peak_torque, scale: { type: log } }
        color: { field: brand }
    hover: { image: photo, title: name, fields: [peak_torque, mass, torque_density, price, drivetrain] }
  - type: chart
    name: Ashby · torque vs mass
    chart:
      mark: { type: point, filled: true, size: 22 }
      encoding:
        x: { field: mass, scale: { type: log } }
        y: { field: peak_torque, scale: { type: log } }
        color: { field: drivetrain }
    guides:
      - { envelope: drivetrain, shape: hull }
      - { indexLine: { slope: 1, through: median }, label: "constant N·m per g (median)" }
    hover: { image: photo, title: name, fields: [peak_torque, mass, torque_density, drivetrain, brand] }
  - type: chart
    name: Torque density
    filters: '!torque_density.isEmpty()'
    chart:
      mark: { type: point, filled: true }
      encoding:
        x: { field: mass, scale: { type: log } }
        y: { field: torque_density }
        color: { field: form }
    guides:
      - { rule: { y: 50 }, label: "50 N·m/kg" }
    hover: { image: photo, title: name, fields: [torque_density, peak_torque, mass, form, price] }
  - type: chart
    name: Price vs torque
    chart:
      mark: { type: point, filled: true }
      encoding:
        x: { field: peak_torque, scale: { type: log } }
        y: { field: price, scale: { type: log } }
        color: { field: drivetrain }
        size: { field: torque_density }
    hover: { image: photo, title: name, fields: [price, peak_torque, torque_density, drivetrain, brand] }
  - type: chart
    name: By form
    chart:
      mark: { type: point, filled: true }
      encoding:
        x: { field: mass, scale: { type: log } }
        y: { field: peak_torque, scale: { type: log } }
        color: { field: drivetrain }
        facet: { field: form, columns: 3 }
    hover: { image: photo, title: name }
  - type: chart
    name: Median torque by brand
    filters: 'form == "integrated actuator"'
    chart:
      mark: bar
      encoding:
        x: { field: brand, sort: -y, title: Brand (integrated actuators) }
        y: { field: peak_torque, aggregate: median }
  - type: table
    name: Rows
    order: [model, brand, form, drivetrain, peak_torque, mass, torque_density, price]
    sort:
      - { property: peak_torque, direction: DESC }
// ../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"
}
skin.css, README.md
/* robotparts' skin, the same block as ../robotparts-actuators/skin.css: its own tokens (site/static/site.css, release 2026.10.25), then the one block that maps them onto
   data-ui's --data-* (docs/SPEC.md §10). The gallery scopes a skin to .data-ui-skin; on robotparts.dev the same
   mapping sits at :root. */
.data-ui-skin {
  --bg: #ffffff; --bg2: #f6f7f8; --hover: #f1f5fb; --ink: #15181c; --ink2: #545c66;
  --rule: #d9dde2; --rule2: #e9ebee; --accent: #0a5bb5; --on-accent: #ffffff; --warn: #9a3412;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Liberation Sans", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", "DejaVu Sans Mono", monospace;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .data-ui-skin {
    --bg: #111317; --bg2: #181b20; --hover: #1a2433; --ink: #e6e8eb; --ink2: #a4abb4;
    --rule: #30353c; --rule2: #252930; --accent: #6ea8ec; --on-accent: #0b1220; --warn: #f0a070;
  }
}
:root[data-theme="dark"] .data-ui-skin {
  --bg: #111317; --bg2: #181b20; --hover: #1a2433; --ink: #e6e8eb; --ink2: #a4abb4;
  --rule: #30353c; --rule2: #252930; --accent: #6ea8ec; --on-accent: #0b1220; --warn: #f0a070;
}
/* the mapping: this is all a vanilla app writes */
.data-ui-skin {
  --data-bg: var(--bg); --data-fg: var(--ink); --data-muted: var(--ink2); --data-subtle: var(--bg2);
  --data-border: var(--rule); --data-rule: var(--rule2); --data-hover: var(--hover); --data-accent: var(--accent);
  --data-on-accent: var(--on-accent); --data-warn: var(--warn); --data-font: var(--sans); --data-mono: var(--mono);
  --data-radius: 6px;
}
# Actuator charts

robotparts' 1,149 actuators as chart presets in one `.base` file: peak torque vs mass coloured by brand, an Ashby
chart with a filled envelope per drivetrain and a constant N·m-per-gram index line, torque density, price vs torque,
small multiples by form and median torque by brand. Tick the rail and every chart redraws; hover a dot for the
part's photo and values; click it for the record.

- **App:** robotparts
- **Replaces:** robotparts.dev's hand-rolled Chart view (`site/static/site.js` `scatter()`: one log-log SVG with an
  X and a Y picker, no colour, no presets, no hover card) and the views lane's demo chart
  (`docs/views/demo/views/chart.mjs`).
- **Shows:** each preset a `type: chart` view whose `chart:` block is Vega-Lite; log or linear per axis; colour by
  any field (past eight values the commonest seven keep a colour and the rest read Other); size; `facet`; the
  Encode menu (Encode, top left of the chart) rewriting `chart:` live, so Reset and Save view appear; the hover
  card with the photo, the title and each value with its unit and basis; Rows, the same filtered rows as the table;
  `guides:` envelopes (convex hulls in log space, filled), an index line and a rule.
- **Data:** the sibling case's rows, `../robotparts-actuators/actuators.json` (`data:` points there), whose `photo`
  column `gallery/tools/build_examples.py` writes: `../robotparts-actuators/photos/*.webp` are 150 of robotparts'
  primary photos (one or more per brand, 240 px), resolved against the data file, not this page. The other 999 parts'
  cards say "no photo". 128 parts lack a peak torque or a mass, so the
  torque-vs-mass charts draw 1,021 dots and say so.
- **Skin:** `skin.css` is robotparts' token mapping, the same block as the sibling case's.

The original UI it replaces

robotparts.dev's hand-rolled Chart view (site/static/site.js scatter(): one log-log SVG with an X and a Y picker, no colour, no presets, no hover card) and the views lane's demo chart (docs/views/demo/views/chart.mjs).

What it shows

each preset a type: chart view whose chart: block is Vega-Lite; log or linear per axis; colour by any field (past eight values the commonest seven keep a colour and the rest read Other); size; facet; the Encode menu (Encode, top left of the chart) rewriting chart: live, so Reset and Save view appear; the hover card with the photo, the title and each value with its unit and basis; Rows, the same filtered rows as the table; guides: envelopes (convex hulls in log space, filled), an index line and a rule.

Data

the sibling case's rows, ../robotparts-actuators/actuators.json (data: points there), whose photo column gallery/tools/build_examples.py writes: ../robotparts-actuators/photos/*.webp are 150 of robotparts' primary photos (one or more per brand, 240 px), resolved against the data file, not this page. The other 999 parts' cards say "no photo". 128 parts lack a peak torque or a mass, so the torque-vs-mass charts draw 1,021 dots and say so.

Skin

skin.css is robotparts' token mapping, the same block as the sibling case's.