ZahirJS commited on
Commit
5f73d65
·
verified ·
1 Parent(s): 0ff231b

Update entity_relationship_generator.py

Browse files
Files changed (1) hide show
  1. entity_relationship_generator.py +350 -46
entity_relationship_generator.py CHANGED
@@ -1,3 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import graphviz
2
  import json
3
  from tempfile import NamedTemporaryFile
@@ -23,11 +259,39 @@ def generate_entity_relationship_diagram(json_input: str, output_format: str) ->
23
  esep='+15'
24
  )
25
  dot.attr('node', fontname='Arial', fontsize='10', color='#404040')
26
- dot.attr('edge', fontname='Arial', fontsize='9', color='#404040')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  entities = data.get('entities', [])
29
  relationships = data.get('relationships', [])
30
 
 
31
  for entity in entities:
32
  entity_name = entity.get('name')
33
  entity_type = entity.get('type', 'strong')
@@ -36,108 +300,131 @@ def generate_entity_relationship_diagram(json_input: str, output_format: str) ->
36
  if not entity_name:
37
  continue
38
 
 
 
 
 
39
  if entity_type == 'weak':
40
  dot.node(
41
  entity_name,
42
  entity_name,
43
  shape='box',
44
- style='filled',
45
- fillcolor='#f0f0f0',
 
46
  color='#404040',
47
  penwidth='3',
48
  width='1.8',
49
- height='0.8'
 
50
  )
51
  else:
52
  dot.node(
53
  entity_name,
54
  entity_name,
55
  shape='box',
56
- style='filled',
57
- fillcolor='#e8e8e8',
 
58
  color='#404040',
59
  penwidth='1',
60
  width='1.8',
61
- height='0.8'
 
62
  )
63
 
 
64
  for i, attr in enumerate(attributes):
65
  attr_name = attr.get('name', '')
66
  attr_type = attr.get('type', 'regular')
67
 
68
  attr_id = f"{entity_name}_attr_{i}"
 
 
69
 
70
- # CAMBIO CLAVE: Removemos HTML markup que puede causar problemas
71
  if attr_type == 'primary_key':
72
  dot.node(
73
  attr_id,
74
  f'{attr_name} (PK)',
75
  shape='ellipse',
76
- style='filled',
77
- fillcolor='#d8d8d8',
 
78
  color='#404040',
79
  width='1.2',
80
- height='0.6'
 
81
  )
82
  elif attr_type == 'partial_key':
83
  dot.node(
84
  attr_id,
85
  f'{attr_name} (Partial)',
86
  shape='ellipse',
87
- style='filled,dashed',
88
- fillcolor='#d8d8d8',
 
89
  color='#404040',
90
  width='1.2',
91
- height='0.6'
 
92
  )
93
  elif attr_type == 'multivalued':
94
  dot.node(
95
  attr_id,
96
  attr_name,
97
  shape='ellipse',
98
- style='filled',
99
- fillcolor='#d8d8d8',
 
100
  color='#404040',
101
  penwidth='3',
102
  width='1.2',
103
- height='0.6'
 
104
  )
105
  elif attr_type == 'derived':
106
  dot.node(
107
  attr_id,
108
  f'/{attr_name}/',
109
  shape='ellipse',
110
- style='filled,dashed',
111
- fillcolor='#d8d8d8',
 
112
  color='#404040',
113
  width='1.2',
114
- height='0.6'
 
115
  )
116
  elif attr_type == 'composite':
117
  dot.node(
118
  attr_id,
119
  attr_name,
120
  shape='ellipse',
121
- style='filled',
122
- fillcolor='#d8d8d8',
 
123
  color='#404040',
124
  width='1.2',
125
- height='0.6'
 
126
  )
127
- else:
128
  dot.node(
129
  attr_id,
130
  attr_name,
131
  shape='ellipse',
132
- style='filled',
133
- fillcolor='#d8d8d8',
 
134
  color='#404040',
135
  width='1.2',
136
- height='0.6'
 
137
  )
138
 
139
- dot.edge(entity_name, attr_id, color='#404040', len='1.5')
140
 
 
141
  for relationship in relationships:
142
  rel_name = relationship.get('name')
143
  rel_type = relationship.get('type', 'regular')
@@ -148,28 +435,36 @@ def generate_entity_relationship_diagram(json_input: str, output_format: str) ->
148
  if not rel_name:
149
  continue
150
 
 
 
 
151
  if rel_type == 'isa':
152
  parent = relationship.get('parent')
153
  children = relationship.get('children', [])
154
 
155
  if parent and children:
156
  isa_id = f"isa_{rel_name}"
 
 
 
157
  dot.node(
158
  isa_id,
159
  'ISA',
160
  shape='triangle',
161
- style='filled',
162
- fillcolor='#d0d0d0',
 
163
  color='#404040',
164
  penwidth='2',
165
  width='1.0',
166
- height='0.8'
 
167
  )
168
 
169
- dot.edge(parent, isa_id, color='#404040', len='2.0')
170
 
171
  for child in children:
172
- dot.edge(isa_id, child, color='#404040', len='2.0')
173
 
174
  elif len(entities_involved) >= 2:
175
  if rel_type == 'identifying':
@@ -177,41 +472,50 @@ def generate_entity_relationship_diagram(json_input: str, output_format: str) ->
177
  rel_name,
178
  rel_name,
179
  shape='diamond',
180
- style='filled',
181
- fillcolor='#c8c8c8',
 
182
  color='#404040',
183
  penwidth='3',
184
  width='1.8',
185
- height='1.0'
 
186
  )
187
  else:
188
  dot.node(
189
  rel_name,
190
  rel_name,
191
  shape='diamond',
192
- style='filled',
193
- fillcolor='#c8c8c8',
 
194
  color='#404040',
195
  penwidth='1',
196
  width='1.8',
197
- height='1.0'
 
198
  )
199
 
 
200
  for j, attr in enumerate(rel_attributes):
201
  attr_name = attr.get('name', '')
202
  attr_id = f"{rel_name}_attr_{j}"
 
 
203
 
204
  dot.node(
205
  attr_id,
206
  attr_name,
207
  shape='ellipse',
208
- style='filled',
209
- fillcolor='#d8d8d8',
 
210
  color='#404040',
211
  width='1.0',
212
- height='0.5'
 
213
  )
214
- dot.edge(rel_name, attr_id, color='#404040', len='1.0')
215
 
216
  for entity in entities_involved:
217
  cardinality = cardinalities.get(entity, '1')
@@ -219,10 +523,10 @@ def generate_entity_relationship_diagram(json_input: str, output_format: str) ->
219
  entity,
220
  rel_name,
221
  label=f' {cardinality} ',
222
- color='#404040',
223
  len='2.5',
224
- fontcolor='#000000',
225
- fontsize='11'
226
  )
227
 
228
  with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp:
 
1
+ # import graphviz
2
+ # import json
3
+ # from tempfile import NamedTemporaryFile
4
+ # import os
5
+
6
+ # def generate_entity_relationship_diagram(json_input: str, output_format: str) -> str:
7
+ # try:
8
+ # if not json_input.strip():
9
+ # return "Error: Empty input"
10
+
11
+ # data = json.loads(json_input)
12
+
13
+ # if 'entities' not in data:
14
+ # raise ValueError("Missing required field: entities")
15
+
16
+ # dot = graphviz.Graph(comment='ER Diagram', engine='neato')
17
+ # dot.attr(
18
+ # bgcolor='white',
19
+ # pad='1.5',
20
+ # overlap='false',
21
+ # splines='true',
22
+ # sep='+25',
23
+ # esep='+15'
24
+ # )
25
+ # dot.attr('node', fontname='Arial', fontsize='10', color='#404040')
26
+ # dot.attr('edge', fontname='Arial', fontsize='9', color='#404040')
27
+
28
+ # entities = data.get('entities', [])
29
+ # relationships = data.get('relationships', [])
30
+
31
+ # for entity in entities:
32
+ # entity_name = entity.get('name')
33
+ # entity_type = entity.get('type', 'strong')
34
+ # attributes = entity.get('attributes', [])
35
+
36
+ # if not entity_name:
37
+ # continue
38
+
39
+ # if entity_type == 'weak':
40
+ # dot.node(
41
+ # entity_name,
42
+ # entity_name,
43
+ # shape='box',
44
+ # style='filled',
45
+ # fillcolor='#f0f0f0',
46
+ # color='#404040',
47
+ # penwidth='3',
48
+ # width='1.8',
49
+ # height='0.8'
50
+ # )
51
+ # else:
52
+ # dot.node(
53
+ # entity_name,
54
+ # entity_name,
55
+ # shape='box',
56
+ # style='filled',
57
+ # fillcolor='#e8e8e8',
58
+ # color='#404040',
59
+ # penwidth='1',
60
+ # width='1.8',
61
+ # height='0.8'
62
+ # )
63
+
64
+ # for i, attr in enumerate(attributes):
65
+ # attr_name = attr.get('name', '')
66
+ # attr_type = attr.get('type', 'regular')
67
+
68
+ # attr_id = f"{entity_name}_attr_{i}"
69
+
70
+ # # CAMBIO CLAVE: Removemos HTML markup que puede causar problemas
71
+ # if attr_type == 'primary_key':
72
+ # dot.node(
73
+ # attr_id,
74
+ # f'{attr_name} (PK)',
75
+ # shape='ellipse',
76
+ # style='filled',
77
+ # fillcolor='#d8d8d8',
78
+ # color='#404040',
79
+ # width='1.2',
80
+ # height='0.6'
81
+ # )
82
+ # elif attr_type == 'partial_key':
83
+ # dot.node(
84
+ # attr_id,
85
+ # f'{attr_name} (Partial)',
86
+ # shape='ellipse',
87
+ # style='filled,dashed',
88
+ # fillcolor='#d8d8d8',
89
+ # color='#404040',
90
+ # width='1.2',
91
+ # height='0.6'
92
+ # )
93
+ # elif attr_type == 'multivalued':
94
+ # dot.node(
95
+ # attr_id,
96
+ # attr_name,
97
+ # shape='ellipse',
98
+ # style='filled',
99
+ # fillcolor='#d8d8d8',
100
+ # color='#404040',
101
+ # penwidth='3',
102
+ # width='1.2',
103
+ # height='0.6'
104
+ # )
105
+ # elif attr_type == 'derived':
106
+ # dot.node(
107
+ # attr_id,
108
+ # f'/{attr_name}/',
109
+ # shape='ellipse',
110
+ # style='filled,dashed',
111
+ # fillcolor='#d8d8d8',
112
+ # color='#404040',
113
+ # width='1.2',
114
+ # height='0.6'
115
+ # )
116
+ # elif attr_type == 'composite':
117
+ # dot.node(
118
+ # attr_id,
119
+ # attr_name,
120
+ # shape='ellipse',
121
+ # style='filled',
122
+ # fillcolor='#d8d8d8',
123
+ # color='#404040',
124
+ # width='1.2',
125
+ # height='0.6'
126
+ # )
127
+ # else:
128
+ # dot.node(
129
+ # attr_id,
130
+ # attr_name,
131
+ # shape='ellipse',
132
+ # style='filled',
133
+ # fillcolor='#d8d8d8',
134
+ # color='#404040',
135
+ # width='1.2',
136
+ # height='0.6'
137
+ # )
138
+
139
+ # dot.edge(entity_name, attr_id, color='#404040', len='1.5')
140
+
141
+ # for relationship in relationships:
142
+ # rel_name = relationship.get('name')
143
+ # rel_type = relationship.get('type', 'regular')
144
+ # entities_involved = relationship.get('entities', [])
145
+ # cardinalities = relationship.get('cardinalities', {})
146
+ # rel_attributes = relationship.get('attributes', [])
147
+
148
+ # if not rel_name:
149
+ # continue
150
+
151
+ # if rel_type == 'isa':
152
+ # parent = relationship.get('parent')
153
+ # children = relationship.get('children', [])
154
+
155
+ # if parent and children:
156
+ # isa_id = f"isa_{rel_name}"
157
+ # dot.node(
158
+ # isa_id,
159
+ # 'ISA',
160
+ # shape='triangle',
161
+ # style='filled',
162
+ # fillcolor='#d0d0d0',
163
+ # color='#404040',
164
+ # penwidth='2',
165
+ # width='1.0',
166
+ # height='0.8'
167
+ # )
168
+
169
+ # dot.edge(parent, isa_id, color='#404040', len='2.0')
170
+
171
+ # for child in children:
172
+ # dot.edge(isa_id, child, color='#404040', len='2.0')
173
+
174
+ # elif len(entities_involved) >= 2:
175
+ # if rel_type == 'identifying':
176
+ # dot.node(
177
+ # rel_name,
178
+ # rel_name,
179
+ # shape='diamond',
180
+ # style='filled',
181
+ # fillcolor='#c8c8c8',
182
+ # color='#404040',
183
+ # penwidth='3',
184
+ # width='1.8',
185
+ # height='1.0'
186
+ # )
187
+ # else:
188
+ # dot.node(
189
+ # rel_name,
190
+ # rel_name,
191
+ # shape='diamond',
192
+ # style='filled',
193
+ # fillcolor='#c8c8c8',
194
+ # color='#404040',
195
+ # penwidth='1',
196
+ # width='1.8',
197
+ # height='1.0'
198
+ # )
199
+
200
+ # for j, attr in enumerate(rel_attributes):
201
+ # attr_name = attr.get('name', '')
202
+ # attr_id = f"{rel_name}_attr_{j}"
203
+
204
+ # dot.node(
205
+ # attr_id,
206
+ # attr_name,
207
+ # shape='ellipse',
208
+ # style='filled',
209
+ # fillcolor='#d8d8d8',
210
+ # color='#404040',
211
+ # width='1.0',
212
+ # height='0.5'
213
+ # )
214
+ # dot.edge(rel_name, attr_id, color='#404040', len='1.0')
215
+
216
+ # for entity in entities_involved:
217
+ # cardinality = cardinalities.get(entity, '1')
218
+ # dot.edge(
219
+ # entity,
220
+ # rel_name,
221
+ # label=f' {cardinality} ',
222
+ # color='#404040',
223
+ # len='2.5',
224
+ # fontcolor='#000000',
225
+ # fontsize='11'
226
+ # )
227
+
228
+ # with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp:
229
+ # dot.render(tmp.name, format=output_format, cleanup=True)
230
+ # return f"{tmp.name}.{output_format}"
231
+
232
+ # except json.JSONDecodeError:
233
+ # return "Error: Invalid JSON format"
234
+ # except Exception as e:
235
+ # return f"Error: {str(e)}"
236
+
237
  import graphviz
238
  import json
239
  from tempfile import NamedTemporaryFile
 
259
  esep='+15'
260
  )
261
  dot.attr('node', fontname='Arial', fontsize='10', color='#404040')
262
+ dot.attr('edge', fontname='Arial', fontsize='9', color='#4a4a4a')
263
+
264
+ # Base color system like your other generators
265
+ base_color = '#19191a'
266
+ lightening_factor = 0.12
267
+
268
+ def get_gradient_color(depth, base_hex_color, lightening_factor=0.12):
269
+ """Get lightened color based on depth, same as your other generators"""
270
+ if not isinstance(base_hex_color, str) or not base_hex_color.startswith('#') or len(base_hex_color) != 7:
271
+ base_hex_color = '#19191a'
272
+
273
+ base_r = int(base_hex_color[1:3], 16)
274
+ base_g = int(base_hex_color[3:5], 16)
275
+ base_b = int(base_hex_color[5:7], 16)
276
+
277
+ current_r = base_r + int((255 - base_r) * depth * lightening_factor)
278
+ current_g = base_g + int((255 - base_g) * depth * lightening_factor)
279
+ current_b = base_b + int((255 - base_b) * depth * lightening_factor)
280
+
281
+ current_r = min(255, current_r)
282
+ current_g = min(255, current_g)
283
+ current_b = min(255, current_b)
284
+
285
+ return f'#{current_r:02x}{current_g:02x}{current_b:02x}'
286
+
287
+ def get_font_color_for_background(depth, lightening_factor=0.12):
288
+ """Get appropriate font color based on background lightness"""
289
+ return 'white' if depth * lightening_factor < 0.6 else 'black'
290
 
291
  entities = data.get('entities', [])
292
  relationships = data.get('relationships', [])
293
 
294
+ # Process entities with new styling
295
  for entity in entities:
296
  entity_name = entity.get('name')
297
  entity_type = entity.get('type', 'strong')
 
300
  if not entity_name:
301
  continue
302
 
303
+ # Entity colors - depth 1 for entities
304
+ entity_color = get_gradient_color(1, base_color, lightening_factor)
305
+ entity_font_color = get_font_color_for_background(1, lightening_factor)
306
+
307
  if entity_type == 'weak':
308
  dot.node(
309
  entity_name,
310
  entity_name,
311
  shape='box',
312
+ style='filled,rounded', # KEY CHANGE: rounded borders like your other generators
313
+ fillcolor=entity_color,
314
+ fontcolor=entity_font_color,
315
  color='#404040',
316
  penwidth='3',
317
  width='1.8',
318
+ height='0.8',
319
+ fontsize='12'
320
  )
321
  else:
322
  dot.node(
323
  entity_name,
324
  entity_name,
325
  shape='box',
326
+ style='filled,rounded', # KEY CHANGE: rounded borders
327
+ fillcolor=entity_color,
328
+ fontcolor=entity_font_color,
329
  color='#404040',
330
  penwidth='1',
331
  width='1.8',
332
+ height='0.8',
333
+ fontsize='12'
334
  )
335
 
336
+ # Process attributes with gradient colors - depth 2 for attributes
337
  for i, attr in enumerate(attributes):
338
  attr_name = attr.get('name', '')
339
  attr_type = attr.get('type', 'regular')
340
 
341
  attr_id = f"{entity_name}_attr_{i}"
342
+ attr_color = get_gradient_color(2, base_color, lightening_factor)
343
+ attr_font_color = get_font_color_for_background(2, lightening_factor)
344
 
 
345
  if attr_type == 'primary_key':
346
  dot.node(
347
  attr_id,
348
  f'{attr_name} (PK)',
349
  shape='ellipse',
350
+ style='filled,rounded', # KEY CHANGE: rounded borders
351
+ fillcolor=attr_color,
352
+ fontcolor=attr_font_color,
353
  color='#404040',
354
  width='1.2',
355
+ height='0.6',
356
+ fontsize='10'
357
  )
358
  elif attr_type == 'partial_key':
359
  dot.node(
360
  attr_id,
361
  f'{attr_name} (Partial)',
362
  shape='ellipse',
363
+ style='filled,rounded,dashed', # KEY CHANGE: rounded borders
364
+ fillcolor=attr_color,
365
+ fontcolor=attr_font_color,
366
  color='#404040',
367
  width='1.2',
368
+ height='0.6',
369
+ fontsize='10'
370
  )
371
  elif attr_type == 'multivalued':
372
  dot.node(
373
  attr_id,
374
  attr_name,
375
  shape='ellipse',
376
+ style='filled,rounded', # KEY CHANGE: rounded borders
377
+ fillcolor=attr_color,
378
+ fontcolor=attr_font_color,
379
  color='#404040',
380
  penwidth='3',
381
  width='1.2',
382
+ height='0.6',
383
+ fontsize='10'
384
  )
385
  elif attr_type == 'derived':
386
  dot.node(
387
  attr_id,
388
  f'/{attr_name}/',
389
  shape='ellipse',
390
+ style='filled,rounded,dashed', # KEY CHANGE: rounded borders
391
+ fillcolor=attr_color,
392
+ fontcolor=attr_font_color,
393
  color='#404040',
394
  width='1.2',
395
+ height='0.6',
396
+ fontsize='10'
397
  )
398
  elif attr_type == 'composite':
399
  dot.node(
400
  attr_id,
401
  attr_name,
402
  shape='ellipse',
403
+ style='filled,rounded', # KEY CHANGE: rounded borders
404
+ fillcolor=attr_color,
405
+ fontcolor=attr_font_color,
406
  color='#404040',
407
  width='1.2',
408
+ height='0.6',
409
+ fontsize='10'
410
  )
411
+ else: # regular
412
  dot.node(
413
  attr_id,
414
  attr_name,
415
  shape='ellipse',
416
+ style='filled,rounded', # KEY CHANGE: rounded borders
417
+ fillcolor=attr_color,
418
+ fontcolor=attr_font_color,
419
  color='#404040',
420
  width='1.2',
421
+ height='0.6',
422
+ fontsize='10'
423
  )
424
 
425
+ dot.edge(entity_name, attr_id, color='#4a4a4a', len='1.5')
426
 
427
+ # Process relationships with gradient colors - depth 1.5 for relationships
428
  for relationship in relationships:
429
  rel_name = relationship.get('name')
430
  rel_type = relationship.get('type', 'regular')
 
435
  if not rel_name:
436
  continue
437
 
438
+ rel_color = get_gradient_color(1.5, base_color, lightening_factor)
439
+ rel_font_color = get_font_color_for_background(1.5, lightening_factor)
440
+
441
  if rel_type == 'isa':
442
  parent = relationship.get('parent')
443
  children = relationship.get('children', [])
444
 
445
  if parent and children:
446
  isa_id = f"isa_{rel_name}"
447
+ isa_color = get_gradient_color(1.2, base_color, lightening_factor)
448
+ isa_font_color = get_font_color_for_background(1.2, lightening_factor)
449
+
450
  dot.node(
451
  isa_id,
452
  'ISA',
453
  shape='triangle',
454
+ style='filled,rounded', # KEY CHANGE: rounded borders
455
+ fillcolor=isa_color,
456
+ fontcolor=isa_font_color,
457
  color='#404040',
458
  penwidth='2',
459
  width='1.0',
460
+ height='0.8',
461
+ fontsize='10'
462
  )
463
 
464
+ dot.edge(parent, isa_id, color='#4a4a4a', len='2.0')
465
 
466
  for child in children:
467
+ dot.edge(isa_id, child, color='#4a4a4a', len='2.0')
468
 
469
  elif len(entities_involved) >= 2:
470
  if rel_type == 'identifying':
 
472
  rel_name,
473
  rel_name,
474
  shape='diamond',
475
+ style='filled,rounded', # KEY CHANGE: rounded borders
476
+ fillcolor=rel_color,
477
+ fontcolor=rel_font_color,
478
  color='#404040',
479
  penwidth='3',
480
  width='1.8',
481
+ height='1.0',
482
+ fontsize='11'
483
  )
484
  else:
485
  dot.node(
486
  rel_name,
487
  rel_name,
488
  shape='diamond',
489
+ style='filled,rounded', # KEY CHANGE: rounded borders
490
+ fillcolor=rel_color,
491
+ fontcolor=rel_font_color,
492
  color='#404040',
493
  penwidth='1',
494
  width='1.8',
495
+ height='1.0',
496
+ fontsize='11'
497
  )
498
 
499
+ # Relationship attributes - depth 2.5
500
  for j, attr in enumerate(rel_attributes):
501
  attr_name = attr.get('name', '')
502
  attr_id = f"{rel_name}_attr_{j}"
503
+ rel_attr_color = get_gradient_color(2.5, base_color, lightening_factor)
504
+ rel_attr_font_color = get_font_color_for_background(2.5, lightening_factor)
505
 
506
  dot.node(
507
  attr_id,
508
  attr_name,
509
  shape='ellipse',
510
+ style='filled,rounded', # KEY CHANGE: rounded borders
511
+ fillcolor=rel_attr_color,
512
+ fontcolor=rel_attr_font_color,
513
  color='#404040',
514
  width='1.0',
515
+ height='0.5',
516
+ fontsize='9'
517
  )
518
+ dot.edge(rel_name, attr_id, color='#4a4a4a', len='1.0')
519
 
520
  for entity in entities_involved:
521
  cardinality = cardinalities.get(entity, '1')
 
523
  entity,
524
  rel_name,
525
  label=f' {cardinality} ',
526
+ color='#4a4a4a',
527
  len='2.5',
528
+ fontcolor='#4a4a4a',
529
+ fontsize='10'
530
  )
531
 
532
  with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp: