Skip to content

Commit cafce6d

Browse files
feat(#1532): modernize dj.Diagram rendering style
Replace the alpha-blended Graphviz-default look with a readable, modern palette and typography (parts 2 and 4 of #1532): - Tier palette: each tier gets a fill / stroke / text triple (Manual green, Lookup slate, Imported blue, Computed red, Part near-white) in place of the alpha-blended primaries. Shape stays load-bearing and unchanged. - Rounded corners + generous label margins on box tiers; explicit Helvetica font (no more Times fallback). - Renamed-FK edges use a desaturated amber (#C77D3A) instead of vivid #FF8800; ordinary edges a light translucent slate. - Left-to-right, no arrowheads (already the config default). Entity-group clustering (master+parts) and a visual-regression fixture follow.
1 parent 0753104 commit cafce6d

1 file changed

Lines changed: 43 additions & 21 deletions

File tree

‎src/datajoint/diagram.py‎

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,62 +1411,81 @@ def make_dot(self):
14111411
schema_map[node] = data["schema_name"]
14121412

14131413
scale = 1.2 # scaling factor for fonts and boxes
1414-
label_props = { # http://matplotlib.org/examples/color/named_colors.html
1414+
# Modernized tier palette (#1532): each tier gets a readable
1415+
# fill / stroke / text triple in place of the old alpha-blended primary
1416+
# fills. Shape stays load-bearing and unchanged so an existing diagram
1417+
# reads without relearning: Manual = rounded rectangle, Imported and
1418+
# Computed = ellipse, Lookup and Part = subtle (white/near-white) box.
1419+
label_props = {
14151420
None: dict(
14161421
shape="circle",
1417-
color="#FFFF0040",
1418-
fontcolor="yellow",
1422+
fill="#FFFDE7",
1423+
stroke="#C9BC5B",
1424+
fontcolor="#6B6420",
14191425
fontsize=round(scale * 8),
14201426
size=0.4 * scale,
14211427
fixed=False,
1428+
rounded=False,
14221429
),
14231430
Manual: dict(
14241431
shape="box",
1425-
color="#00FF0030",
1426-
fontcolor="darkgreen",
1432+
fill="#E7F3EC",
1433+
stroke="#2F7D5B",
1434+
fontcolor="#1B5138",
14271435
fontsize=round(scale * 10),
14281436
size=0.4 * scale,
14291437
fixed=False,
1438+
rounded=True,
14301439
),
14311440
Lookup: dict(
1432-
shape="plaintext",
1433-
color="#00000020",
1434-
fontcolor="black",
1441+
shape="box",
1442+
fill="#F2F4F7",
1443+
stroke="#A9B1BD",
1444+
fontcolor="#495261",
14351445
fontsize=round(scale * 8),
14361446
size=0.4 * scale,
14371447
fixed=False,
1448+
rounded=True,
14381449
),
14391450
Computed: dict(
14401451
shape="ellipse",
1441-
color="#FF000020",
1442-
fontcolor="#7F0000A0",
1452+
fill="#FBEAEC",
1453+
stroke="#B23A48",
1454+
fontcolor="#7C2430",
14431455
fontsize=round(scale * 10),
14441456
size=0.4 * scale,
14451457
fixed=False,
1458+
rounded=False,
14461459
),
14471460
Imported: dict(
14481461
shape="ellipse",
1449-
color="#00007F40",
1450-
fontcolor="#00007FA0",
1462+
fill="#E2ECFA",
1463+
stroke="#2A5FA5",
1464+
fontcolor="#123A6D",
14511465
fontsize=round(scale * 10),
14521466
size=0.4 * scale,
14531467
fixed=False,
1468+
rounded=False,
14541469
),
14551470
Part: dict(
1456-
shape="plaintext",
1457-
color="#00000000",
1458-
fontcolor="black",
1471+
shape="box",
1472+
fill="#FFFFFF",
1473+
stroke="#9AA6B8",
1474+
fontcolor="#46536B",
14591475
fontsize=round(scale * 8),
14601476
size=0.1 * scale,
14611477
fixed=False,
1478+
rounded=True,
14621479
),
14631480
"collapsed": dict(
14641481
shape="box3d",
1465-
color="#80808060",
1482+
fill="#EDEEF0",
1483+
stroke="#808890",
14661484
fontcolor="#404040",
14671485
fontsize=round(scale * 10),
14681486
size=0.5 * scale,
14691487
fixed=False,
1488+
rounded=False,
14701489
),
14711490
}
14721491
# Build node_props, handling collapsed nodes specially
@@ -1501,10 +1520,11 @@ def make_dot(self):
15011520
node.set_fontsize(props["fontsize"])
15021521
node.set_fontcolor(props["fontcolor"])
15031522
node.set_shape(props["shape"])
1504-
node.set_fontname("arial")
1523+
node.set_fontname("Helvetica")
15051524
node.set_fixedsize("shape" if props["fixed"] else False)
15061525
node.set_width(props["size"])
15071526
node.set_height(props["size"])
1527+
node.set_margin("0.11,0.06") # generous label padding (inches)
15081528

15091529
# Handle collapsed nodes specially
15101530
node_data = graph.nodes.get(f'"{name}"', {})
@@ -1531,8 +1551,9 @@ def make_dot(self):
15311551
if cluster_label and name.startswith(cluster_label + "."):
15321552
display_name = name[len(cluster_label) + 1 :]
15331553
node.set_label("<<u>" + display_name + "</u>>" if node.get("distinguished") == "True" else display_name)
1534-
node.set_color(props["color"])
1535-
node.set_style("filled")
1554+
node.set_fillcolor(props["fill"])
1555+
node.set_color(props["stroke"])
1556+
node.set_style("rounded,filled" if props.get("rounded") else "filled")
15361557

15371558
for edge in dot.get_edges():
15381559
# see https://graphviz.org/doc/info/attrs.html
@@ -1543,8 +1564,9 @@ def make_dot(self):
15431564
primary = str(edge.get("primary")) == "True"
15441565
multi = str(edge.get("multi")) == "True"
15451566
aliased = str(edge.get("aliased")) == "True"
1546-
# Renamed FK → distinct color; others → the usual translucent black.
1547-
edge.set_color("#FF8800" if aliased else "#00000040")
1567+
# Renamed FK → a distinct, desaturated amber consistent with the
1568+
# modernized palette (#1532); others → a light translucent slate.
1569+
edge.set_color("#C77D3A" if aliased else "#3A424F33")
15481570
edge.set_style("solid" if primary else "dashed")
15491571
# Line weight encodes cardinality, and only cardinality. `multi` is
15501572
# True when the child has primary-key attributes beyond those this

0 commit comments

Comments
 (0)