Skip to content

Layout and orientation

Horizontal or vertical

orientation on the Chart sets the direction bars run:

  • "horizontal" (the default): bars run left to right, and slats stack top to bottom, as rows.
  • "vertical": bars run bottom to top, and slats sit side by side, as columns.

The same slat works both ways: labels, gaps and rounded ends follow the turn. A vertical chart is 240px tall unless you set height on the Chart. Give a horizontal chart a height too, and slats without a thickness share it, so they fit the space you have.

Slat size and room for text

slat() takes two layout settings besides css:

  • thickness: how thick a slat is along the stack, in px: its height in a horizontal chart, its width in a vertical one. Leave it out and the slats share what the chart has: a vertical chart’s width, a horizontal chart’s height. A horizontal chart with no height has none to share, so its slats are 32px each and the chart grows with them.
  • room: the space the slat’s labels need outside the chart, in px. start is before the chart, where names go; end is after it, where numbers go past the bars.
English
1500 M
Mandarin Chinese
1140 M
Hindi
610 M
Spanish
560 M
import { Chart, Plot, Bar, Label, slat } from "@bezda/rhp";

// thickness: a slat's size. room: the space for the names (start) and numbers (end).
const Language = slat({ thickness: 30, room: { start: 150, end: 60 } }, (d) => (
  <div>
    <Label edge="start">{d.language}</Label>
    <Bar to={d.speakers} />
    <Label at={d.speakers}>{d.speakers} M</Label>
  </div>
));

export default function Languages() {
  return (
    <Chart scale={[0, 1600]} ticks={[0, 400, 800, 1200, 1600]}>
      <Plot
        language={["English", "Mandarin Chinese", "Hindi", "Spanish"]}
        speakers={[1500, 1140, 610, 560]}
      >
        {Language}
      </Plot>
    </Chart>
  );
}

room can also hold before and after: space above the first slat and below the last. When the settings differ by direction, give each its own: thickness: { horizontal: 40, vertical: 60 }.

The chart makes room for the largest room any of its slats ask for, and for its axis numbers.

Room that fits the names

With room: "auto", the chart works the room out itself: the start is as wide as the widest name, and the end as wide as the widest label there. It’s done in CSS, so a chart drawn on a server has it right too.

Ops
42%
Web
35%
Data
23%
import { createSignal } from "solid-js";
import { Chart, Plot, Bar, Label, slat } from "@bezda/rhp";

// room: "auto": each side is as wide as its widest label.
const Team = slat({ room: "auto" }, (d) => (
  <div>
    <Label edge="start">{d.team}</Label>
    <Bar to={d.share} />
    <Label edge="end">{d.share}%</Label>
  </div>
));

const SHORT = ["Ops", "Web", "Data"];
const LONG = ["Operations", "Web platform", "Data engineering"];

export default function Teams() {
  const [long, setLong] = createSignal(false);
  return (
    <>
      <div class="demo-controls">
        <button onClick={() => setLong(!long())}>
          {long() ? "Short names" : "Long names"}
        </button>
      </div>
      <Chart scale={[0, 100]}>
        <Plot team={long() ? LONG : SHORT} share={[42, 35, 23]}>
          {Team}
        </Plot>
      </Chart>
    </>
  );
}

You still decide how much room names get, in the slat’s CSS: size the label and the room follows.

.name { max-width: 9em; }                 /* longer names end in "…" */
.name:vertical { white-space: normal; }   /* names wrap under their columns */

By default a name takes at most 40% of the chart; --rhp-gutter-max on a label changes that. Each side can be set on its own: room: { start: "auto", end: 40 } fits the names and keeps 40px at the end.

A few things to know:

  • Each slat then reaches into the room as well, so a slat’s background runs under its own name.
  • Only a label that is a child of the slat’s root element is measured. A label inside another element gets no room, and rhp warns about it in the console.
  • When the widest name changes, the room changes at once, and the bars resize with it instead of animating.
  • Firefox makes the room under a vertical chart one line tall, so names that wrap onto more lines there need room in px.

When px is better

"auto" suits charts of tens of slats whose names don’t change much. Give room in px when:

  • the chart has hundreds of slats,
  • its names change often, with new data or reorder="refill",
  • many of your readers use Safari.

Each time a name changes, the chart lays out all its slats again to find the widest one, and Safari is the slowest at it.

Width

A chart is as wide as the element it’s in, like any block element. Set its width with CSS on a wrapper, or with class or style on the Chart.