Classdiagram

The arrowhead carries the relationship. A hollow triangle is generalisation, a filled diamond is composition, a hollow one is aggregation, and an open head is a plain association - so none of these four edges needs a word on it to say which is which. The class box itself is not Python: it is a <define> in the shipped uml library, imported by name. Read it with cat sauvignon/prelude/uml.svgn — and copy it into this file under the same name if you want a different one. A local <define> wins.

Diagrams 375 × 520 <class><column><connect><import><row><text>

Result

Source examples/classdiagram.svgn

<diagram padding="30">
  <import name="uml"/>

  <!-- The arrowhead carries the relationship. A hollow triangle is
       generalisation, a filled diamond is composition, a hollow one is
       aggregation, and an open head is a plain association - so none of these
       four edges needs a word on it to say which is which.

       The class box itself is not Python: it is a <define> in the shipped
       `uml` library, imported by name. Read it with
       `cat sauvignon/prelude/uml.svgn` — and copy it into this file under the
       same name if you want a different one. A local <define> wins. -->
  <column gap="70" align="center">
    <class id="shape" title="Shape">
      <text class="member">+ area(): float</text>
      <text class="member">+ move(dx, dy)</text>
    </class>
    <row gap="60" align="start">
      <class id="circle" title="Circle">
        <text class="member">- radius: float</text>
      </class>
      <class id="poly" title="Polygon">
        <text class="member">- points: list</text>
      </class>
    </row>
    <row gap="60" align="start">
      <class id="point" title="Point">
        <text class="member">- x: float</text>
        <text class="member">- y: float</text>
      </class>
      <class id="style" title="Style">
        <text class="member">- stroke: str</text>
      </class>
    </row>
  </column>

  <!-- generalisation: the subclass points at what it inherits from -->
  <connect from="circle" to="shape" head="triangle"/>
  <connect from="poly"   to="shape" head="triangle"/>
  <!-- composition: a polygon owns its points outright -->
  <connect from="poly" to="point" head="diamond"/>
  <!-- aggregation: a shape refers to a style it does not own -->
  <connect from="circle" to="style" head="odiamond" routing="curved"/>
</diagram>

Open the SVG →