graph { node [shape=record, height=.1]; Customer [label="{Customer|name\laddress\l|creditRating(String)}"]; Product; OrderLine [label="{OrderLine|quantity : Integer\lprice : Money\lisSatisfied : Boolean\l|}"]; Order [label="{Order|dateRecieved\lisPrepaid\lnumber : String\lprice : Number\l|dispatch()\lclose()\l}"]; CorporateCustomer [label="{Corporate\nCustomer|contactName\lcreditRating\lcreditLimit\l|remind()\lbillForMonth(Integer)\l}"]; PersonalCustomer [label="{Personal\nCustomer|creditCard#|}"]; Order -- Customer [headlabel="*", taillabel="1", dir=none]; CorporateCustomer -- Customer; PersonalCustomer -- Customer; OrderLine -- Order [headlabel="*", taillabel="1", dir=none]; Product -- OrderLine [headlabel="1", taillabel="*", dir=none]; // XXX Why does the below headlabel cross the line?!? CorporateCustomer -- Employee [headlabel="0..1", taillabel="*", dir=none]; OrderConstraint1 [shape=plaintext, label="{if Order.customer.creditRating is\l\"poor,\" then Order.isPrepaid\lmust be true}\l"]; PersonalCustomerConstraint1 [shape=plaintext, label="{creditRating() ==l\"poor\"}\l"]; OrderConstraint1 -- Order [style=dashed, dir=none]; PersonalCustomerConstraint1 -- PersonalCustomer [style=dashed, dir=none]; };