ZahirJS commited on
Commit
53aab24
·
verified ·
1 Parent(s): ca0234e

Update class_diagram_generator.py

Browse files
Files changed (1) hide show
  1. class_diagram_generator.py +8 -32
class_diagram_generator.py CHANGED
@@ -486,20 +486,17 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
486
  {
487
  "from": "Car",
488
  "to": "Vehicle",
489
- "type": "inheritance",
490
- "label": "extends"
491
  },
492
  {
493
  "from": "Motorcycle",
494
  "to": "Vehicle",
495
- "type": "inheritance",
496
- "label": "extends"
497
  },
498
  {
499
  "from": "Car",
500
  "to": "Engine",
501
  "type": "composition",
502
- "label": "has",
503
  "multiplicity_from": "1",
504
  "multiplicity_to": "1"
505
  },
@@ -507,7 +504,6 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
507
  "from": "Motorcycle",
508
  "to": "Engine",
509
  "type": "composition",
510
- "label": "has",
511
  "multiplicity_from": "1",
512
  "multiplicity_to": "1"
513
  },
@@ -515,7 +511,6 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
515
  "from": "Car",
516
  "to": "TransmissionType",
517
  "type": "association",
518
- "label": "uses",
519
  "multiplicity_from": "1",
520
  "multiplicity_to": "1"
521
  },
@@ -523,21 +518,18 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
523
  "from": "Vehicle",
524
  "to": "FuelType",
525
  "type": "association",
526
- "label": "uses",
527
  "multiplicity_from": "1",
528
  "multiplicity_to": "1"
529
  },
530
  {
531
  "from": "GarageService",
532
  "to": "VehicleService",
533
- "type": "realization",
534
- "label": "implements"
535
  },
536
  {
537
  "from": "GarageService",
538
  "to": "Vehicle",
539
  "type": "dependency",
540
- "label": "services",
541
  "multiplicity_from": "1",
542
  "multiplicity_to": "*"
543
  }
@@ -556,7 +548,6 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
556
  if 'classes' not in data:
557
  raise ValueError("Missing required field: classes")
558
 
559
- # Configuración del diagrama usando la misma estrategia exitosa del mapa conceptual
560
  dot = graphviz.Digraph(comment='Class Diagram')
561
  dot.attr(rankdir='TB', bgcolor='white', pad='0.5', nodesep='0.8', ranksep='1.2', splines='ortho')
562
  dot.attr('node', shape='plaintext', fontname='Arial', fontsize='11')
@@ -574,10 +565,8 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
574
  if not class_name:
575
  continue
576
 
577
- # Crear tabla HTML para estructura de clase
578
  html_label = '<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0" CELLPADDING="5" BGCOLOR="white">'
579
 
580
- # Header con nombre de clase y estereotipo
581
  if class_type == 'abstract':
582
  html_label += f'<TR><TD ALIGN="CENTER"><B>&lt;&lt;abstract&gt;&gt;<BR/>{class_name}</B></TD></TR>'
583
  elif class_type == 'interface':
@@ -587,10 +576,8 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
587
  else:
588
  html_label += f'<TR><TD ALIGN="CENTER"><B>{class_name}</B></TD></TR>'
589
 
590
- # Línea separadora después del nombre
591
  html_label += '<HR/>'
592
 
593
- # Sección de atributos
594
  if attributes:
595
  for attr in attributes:
596
  visibility = attr.get('visibility', '+')
@@ -602,17 +589,14 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
602
  if attr_type:
603
  line += f" : {attr_type}"
604
  if is_static:
605
- line = f"<U>{line}</U>" # Subrayado para elementos estáticos
606
 
607
  html_label += f'<TR><TD ALIGN="LEFT">{line}</TD></TR>'
608
  else:
609
- # Espacio vacío si no hay atributos
610
  html_label += '<TR><TD ALIGN="LEFT"> </TD></TR>'
611
 
612
- # Línea separadora entre atributos y métodos
613
  html_label += '<HR/>'
614
 
615
- # Sección de métodos
616
  if methods:
617
  for method in methods:
618
  visibility = method.get('visibility', '+')
@@ -633,21 +617,18 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
633
  line += f") : {return_type}"
634
 
635
  if is_static:
636
- line = f"<U>{line}</U>" # Subrayado para métodos estáticos
637
  if is_abstract:
638
- line = f"<I>{line}</I>" # Cursiva para métodos abstractos
639
 
640
  html_label += f'<TR><TD ALIGN="LEFT">{line}</TD></TR>'
641
  else:
642
- # Espacio vacío si no hay métodos
643
  html_label += '<TR><TD ALIGN="LEFT"> </TD></TR>'
644
 
645
  html_label += '</TABLE>'
646
 
647
- # Agregar nodo con la tabla HTML
648
  dot.node(class_name, f'<{html_label}>')
649
 
650
- # Procesar relaciones con líneas rectas
651
  for relationship in relationships:
652
  from_class = relationship.get('from')
653
  to_class = relationship.get('to')
@@ -660,19 +641,15 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
660
  continue
661
 
662
  edge_attrs = {
663
- 'color': 'black' # Simplificamos a solo color negro, sin configuraciones conflictivas
664
  }
665
 
666
- if label:
667
- edge_attrs['label'] = label
668
-
669
  if multiplicity_from:
670
  edge_attrs['taillabel'] = multiplicity_from
671
 
672
  if multiplicity_to:
673
  edge_attrs['headlabel'] = multiplicity_to
674
 
675
- # Configurar estilos de flecha según el tipo de relación
676
  if rel_type == 'inheritance':
677
  edge_attrs['arrowhead'] = 'empty'
678
  edge_attrs['color'] = 'black'
@@ -694,13 +671,12 @@ def generate_class_diagram(json_input: str, output_format: str) -> str:
694
  edge_attrs['arrowhead'] = 'normal'
695
  edge_attrs['style'] = 'dashed'
696
  edge_attrs['color'] = 'black'
697
- else: # association
698
  edge_attrs['arrowhead'] = 'normal'
699
  edge_attrs['color'] = 'black'
700
 
701
  dot.edge(from_class, to_class, **edge_attrs)
702
 
703
- # Renderizar el diagrama
704
  with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp:
705
  dot.render(tmp.name, format=output_format, cleanup=True)
706
  return f"{tmp.name}.{output_format}"
 
486
  {
487
  "from": "Car",
488
  "to": "Vehicle",
489
+ "type": "inheritance"
 
490
  },
491
  {
492
  "from": "Motorcycle",
493
  "to": "Vehicle",
494
+ "type": "inheritance"
 
495
  },
496
  {
497
  "from": "Car",
498
  "to": "Engine",
499
  "type": "composition",
 
500
  "multiplicity_from": "1",
501
  "multiplicity_to": "1"
502
  },
 
504
  "from": "Motorcycle",
505
  "to": "Engine",
506
  "type": "composition",
 
507
  "multiplicity_from": "1",
508
  "multiplicity_to": "1"
509
  },
 
511
  "from": "Car",
512
  "to": "TransmissionType",
513
  "type": "association",
 
514
  "multiplicity_from": "1",
515
  "multiplicity_to": "1"
516
  },
 
518
  "from": "Vehicle",
519
  "to": "FuelType",
520
  "type": "association",
 
521
  "multiplicity_from": "1",
522
  "multiplicity_to": "1"
523
  },
524
  {
525
  "from": "GarageService",
526
  "to": "VehicleService",
527
+ "type": "realization"
 
528
  },
529
  {
530
  "from": "GarageService",
531
  "to": "Vehicle",
532
  "type": "dependency",
 
533
  "multiplicity_from": "1",
534
  "multiplicity_to": "*"
535
  }
 
548
  if 'classes' not in data:
549
  raise ValueError("Missing required field: classes")
550
 
 
551
  dot = graphviz.Digraph(comment='Class Diagram')
552
  dot.attr(rankdir='TB', bgcolor='white', pad='0.5', nodesep='0.8', ranksep='1.2', splines='ortho')
553
  dot.attr('node', shape='plaintext', fontname='Arial', fontsize='11')
 
565
  if not class_name:
566
  continue
567
 
 
568
  html_label = '<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0" CELLPADDING="5" BGCOLOR="white">'
569
 
 
570
  if class_type == 'abstract':
571
  html_label += f'<TR><TD ALIGN="CENTER"><B>&lt;&lt;abstract&gt;&gt;<BR/>{class_name}</B></TD></TR>'
572
  elif class_type == 'interface':
 
576
  else:
577
  html_label += f'<TR><TD ALIGN="CENTER"><B>{class_name}</B></TD></TR>'
578
 
 
579
  html_label += '<HR/>'
580
 
 
581
  if attributes:
582
  for attr in attributes:
583
  visibility = attr.get('visibility', '+')
 
589
  if attr_type:
590
  line += f" : {attr_type}"
591
  if is_static:
592
+ line = f"<U>{line}</U>"
593
 
594
  html_label += f'<TR><TD ALIGN="LEFT">{line}</TD></TR>'
595
  else:
 
596
  html_label += '<TR><TD ALIGN="LEFT"> </TD></TR>'
597
 
 
598
  html_label += '<HR/>'
599
 
 
600
  if methods:
601
  for method in methods:
602
  visibility = method.get('visibility', '+')
 
617
  line += f") : {return_type}"
618
 
619
  if is_static:
620
+ line = f"<U>{line}</U>"
621
  if is_abstract:
622
+ line = f"<I>{line}</I>"
623
 
624
  html_label += f'<TR><TD ALIGN="LEFT">{line}</TD></TR>'
625
  else:
 
626
  html_label += '<TR><TD ALIGN="LEFT"> </TD></TR>'
627
 
628
  html_label += '</TABLE>'
629
 
 
630
  dot.node(class_name, f'<{html_label}>')
631
 
 
632
  for relationship in relationships:
633
  from_class = relationship.get('from')
634
  to_class = relationship.get('to')
 
641
  continue
642
 
643
  edge_attrs = {
644
+ 'color': 'black'
645
  }
646
 
 
 
 
647
  if multiplicity_from:
648
  edge_attrs['taillabel'] = multiplicity_from
649
 
650
  if multiplicity_to:
651
  edge_attrs['headlabel'] = multiplicity_to
652
 
 
653
  if rel_type == 'inheritance':
654
  edge_attrs['arrowhead'] = 'empty'
655
  edge_attrs['color'] = 'black'
 
671
  edge_attrs['arrowhead'] = 'normal'
672
  edge_attrs['style'] = 'dashed'
673
  edge_attrs['color'] = 'black'
674
+ else:
675
  edge_attrs['arrowhead'] = 'normal'
676
  edge_attrs['color'] = 'black'
677
 
678
  dot.edge(from_class, to_class, **edge_attrs)
679
 
 
680
  with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp:
681
  dot.render(tmp.name, format=output_format, cleanup=True)
682
  return f"{tmp.name}.{output_format}"