ea 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +3 -0
- data/TODO.complete/01-t-xref-parsing.md +91 -0
- data/TODO.complete/02-per-label-geometry.md +50 -0
- data/TODO.complete/03-object-properties-constraints.md +57 -0
- data/TODO.complete/04-operation-params.md +37 -0
- data/TODO.complete/05-pdata-flag-matrix.md +52 -0
- data/TODO.complete/06-emf-image-rendering.md +34 -0
- data/TODO.complete/07-auxiliary-tables.md +47 -0
- data/TODO.complete/10-mdg-stereotype-registry.md +40 -0
- data/TODO.complete/11-gml-xsd-generation.md +42 -0
- data/TODO.complete/13-shapescript-interpreter.md +28 -0
- data/TODO.complete/20-cli-diff.md +46 -0
- data/TODO.complete/21-cli-render.md +26 -0
- data/TODO.complete/22-cli-export.md +29 -0
- data/TODO.complete/23-cli-mdg.md +23 -0
- data/TODO.complete/30-headerlines-ocp-refactor.md +72 -0
- data/TODO.complete/31-public-send-cleanup.md +61 -0
- data/TODO.complete/32-spec-coverage.md +33 -0
- data/TODO.complete/33-blocked-parity-gaps.md +41 -0
- data/TODO.complete/36-stereotype-icon-wiring.md +32 -0
- data/TODO.complete/37-cli-lint.md +32 -0
- data/TODO.complete/38-cli-query.md +26 -0
- data/TODO.complete/39-cli-info.md +23 -0
- data/TODO.complete/40-ocl-evaluator.md +31 -0
- data/TODO.complete/41-round-trip-spec.md +18 -0
- data/TODO.complete/42-html-diff-report.md +18 -0
- data/TODO.complete/43-json-schema-export.md +20 -0
- data/TODO.complete/44-remaining-qea-tables.md +40 -0
- data/TODO.complete/45-shapescript-extensions.md +25 -0
- data/TODO.complete/46-xsd-consolidation.md +20 -0
- data/TODO.complete/47-headerlines-legacy-removal.md +20 -0
- data/TODO.complete/STATUS.md +109 -0
- data/TODO.diagrams/01-svg-measurement-harness.md +31 -0
- data/TODO.diagrams/01-xmi-extension-elements-parsing.md +67 -0
- data/TODO.diagrams/02-diagram-element-rich-model.md +61 -0
- data/TODO.diagrams/02-polygon-over-rendering.md +29 -0
- data/TODO.diagrams/03-ea-style-svg-emitter.md +70 -0
- data/TODO.diagrams/03-text-over-rendering.md +30 -0
- data/TODO.diagrams/04-connector-routing-from-soid-eoid.md +55 -0
- data/TODO.diagrams/04-rect-under-rendering.md +33 -0
- data/TODO.diagrams/05-canvas-dimension-parity.md +51 -0
- data/TODO.diagrams/05-marker-rendering-per-relationship-type.md +49 -0
- data/TODO.diagrams/06-connector-labels.md +49 -0
- data/TODO.diagrams/06-group-layering-parity.md +39 -0
- data/TODO.diagrams/07-canvas-size-and-viewbox.md +39 -0
- data/TODO.diagrams/07-text-content-fidelity.md +65 -0
- data/TODO.diagrams/08-qea-direct-pipeline.md +46 -0
- data/TODO.diagrams/08-visual-regression-harness.md +34 -0
- data/TODO.diagrams/09-cli-render-all-diagrams.md +25 -0
- data/TODO.diagrams/10-stereotype-color-config.md +29 -0
- data/TODO.diagrams/11-elkrb-auto-layout-integration.md +53 -0
- data/TODO.diagrams/12-connector-labels.md +40 -0
- data/TODO.diagrams/12-per-entity-svg-layer-ordering.md +24 -0
- data/TODO.diagrams/13-marker-polygon-vs-path-dispatch.md +20 -0
- data/TODO.diagrams/13-per-text-type-font-sizes.md +33 -0
- data/TODO.diagrams/14-center-header-text.md +33 -0
- data/TODO.diagrams/14-filter-diagram-frame-elements.md +18 -0
- data/TODO.diagrams/15-deep-dead-code-audit.md +47 -0
- data/TODO.diagrams/15-per-element-font-from-style.md +24 -0
- data/TODO.diagrams/16-canvas-marker-extent.md +30 -0
- data/TODO.diagrams/16-document-remaining-parity-gaps.md +91 -0
- data/TODO.diagrams/17-italic-abstract-classes.md +28 -0
- data/TODO.diagrams/17-remaining-parity-gaps.md +90 -0
- data/TODO.diagrams/18-canvas-from-image-bounds.md +20 -0
- data/TODO.diagrams/18-property-lookup-index.md +42 -0
- data/TODO.diagrams/19-connector-sx-sy-routing.md +27 -0
- data/TODO.diagrams/19-replace-respond-to-with-is-a.md +31 -0
- data/TODO.diagrams/20-split-labels-emitter.md +56 -0
- data/TODO.diagrams/20-visibility-glyph-font-encoding.md +27 -0
- data/TODO.diagrams/21-aggregation-navigability-arrow.md +21 -0
- data/TODO.diagrams/21-auto-generated-legend-block.md +65 -0
- data/TODO.diagrams/22-ghost-element-discriminator.md +57 -0
- data/TODO.diagrams/22-style-based-path-grouping.md +28 -0
- data/TODO.diagrams/23-marker-polygon-deduplication.md +47 -0
- data/TODO.diagrams/23-multiplicity-label-positioning.md +29 -0
- data/TODO.diagrams/24-marker-anchor-structural.md +35 -0
- data/TODO.diagrams/24-track-marker-anchors-structurally.md +66 -0
- data/TODO.diagrams/24-truncate-properties-to-fit-box.md +24 -0
- data/TODO.diagrams/26-phantom-general-parent-rendering.md +59 -0
- data/TODO.diagrams/27-path-grouping-mode-detection.md +43 -0
- data/TODO.diagrams/28-architecture-cleanup-batch.md +47 -0
- data/TODO.diagrams/30-decompose-elements-groups-for.md +52 -0
- data/TODO.diagrams/32-examples-coverage-batch.md +78 -0
- data/TODO.diagrams/36-instance-specification-model.md +42 -0
- data/TODO.diagrams/37-element-icon-decorations.md +41 -0
- data/TODO.diagrams/38-html-note-and-receptions.md +32 -0
- data/TODO.diagrams/39-property-stereotype-discriminator.md +40 -0
- data/TODO.diagrams/40-standalone-1-discriminator.md +38 -0
- data/TODO.diagrams/41-xmi-to-svg-pipeline.md +113 -0
- data/TODO.diagrams/42-close-all-parity-deltas.md +69 -0
- data/TODO.diagrams/43-marker-deduplication-strategy.md +54 -0
- data/TODO.diagrams/44-element-icon-decorations.md +34 -0
- data/TODO.diagrams/45-phantom-parent-class-boxes.md +40 -0
- data/TODO.diagrams/46-user-drawn-legend-swatches.md +44 -0
- data/TODO.diagrams/47-attribute-line-fidelity.md +72 -0
- data/TODO.diagrams/48-spec-coverage-critical-emitter-components.md +45 -0
- data/TODO.diagrams/49-spec-coverage-orchestrators.md +25 -0
- data/TODO.diagrams/50-examples-parity.md +85 -0
- data/TODO.diagrams/51-property-oy-gap-and-remaining-gaps.md +48 -0
- data/TODO.diagrams/52-marker-registration-architecture.md +89 -0
- data/TODO.diagrams/53-remaining-example-gaps.md +86 -0
- data/TODO.diagrams/54-display-name-nested-classes.md +40 -0
- data/TODO.diagrams/55-visibility-icon-discriminator.md +58 -0
- data/TODO.diagrams/56-package-contents-rendering.md +148 -0
- data/TODO.diagrams/57-instance-specification-model.md +100 -0
- data/TODO.diagrams/58-domain-model-note-text.md +67 -0
- data/TODO.diagrams/59-classes-arrow-discriminator.md +57 -0
- data/TODO.diagrams/60-testschema-association-marker.md +40 -0
- data/TODO.diagrams/61-legend-block-rendering.md +55 -0
- data/TODO.diagrams/61-plateau-parity-gaps.md +59 -0
- data/TODO.diagrams/62-ghost-element-rendering.md +56 -0
- data/TODO.diagrams/63-qualified-name-wrap.md +36 -0
- data/TODO.diagrams/64-property-stereotype-labels.md +22 -0
- data/TODO.diagrams/65-path-coordinate-frame.md +62 -0
- data/TODO.diagrams/67-path-coordinate-frame.md +62 -0
- data/TODO.diagrams/68-inherited-attributes.md +65 -0
- data/TODO.diagrams/69-package-anchor-conditional.md +29 -0
- data/TODO.diagrams/70-mdg-technology-support.md +68 -0
- data/TODO.diagrams/71-off-canvas-parent-ghost.md +45 -0
- data/TODO.diagrams/72-basic-attr-divider-paths.md +39 -0
- data/TODO.diagrams/73-plateau-polygon-gap.md +69 -0
- data/TODO.diagrams/74-plateau-rect-gap.md +22 -0
- data/TODO.diagrams/75-plateau-text-gap.md +39 -0
- data/TODO.diagrams/76-basic-poly-path-gaps.md +41 -0
- data/TODO.diagrams/77-basic-text-overrender.md +40 -0
- data/TODO.diagrams/78-headerlines-ocp-refactor.md +65 -0
- data/TODO.diagrams/79-architecture-backlog.md +65 -0
- data/TODO.diagrams/80-basic-triangle-polygons.md +51 -0
- data/TODO.diagrams/81-plateau-path-overrender.md +53 -0
- data/TODO.diagrams/82-appearance-canvas-offset.md +54 -0
- data/TODO.diagrams/83-3d-diagram-subtitle.md +58 -0
- data/TODO.diagrams/84-canvas-offset-mismatches.md +61 -0
- data/TODO.diagrams/85-phantom-property-overrender.md +95 -0
- data/TODO.diagrams/86-foreign-package-rule.md +62 -0
- data/TODO.diagrams/87-internal-tech-encryption.md +80 -0
- data/TODO.diagrams/EXAMPLES_STATUS.md +88 -0
- data/TODO.diagrams/README.md +69 -0
- data/TODO.diagrams/STATUS.md +73 -0
- data/TODO.fixup/01-default-grouped-paths.md +34 -0
- data/TODO.fixup/02-marker-consolidation-per-connector.md +20 -0
- data/TODO.fixup/03-diagram-font-inference.md +28 -0
- data/TODO.fixup/04-extract-bounds-calculator.md +25 -0
- data/TODO.fixup/05-marker-registry-ocp.md +32 -0
- data/TODO.fixup/06-connector-path-bend-routing.md +28 -0
- data/TODO.fixup/07-edge-attachment-formula.md +22 -0
- data/TODO.fixup/08-visual-diff-harness.md +28 -0
- data/TODO.fixup/09-extract-element-compartments.md +34 -0
- data/TODO.fixup/10-canvas-width-overshoot-fix.md +20 -0
- data/TODO.fixup/11-layer-sequencer-extraction.md +18 -0
- data/TODO.fixup/12-path-style-harmony.md +23 -0
- data/TODO.fixup/13-datatype-stereotype-fallback.md +28 -0
- data/TODO.fixup/14-ea-exe-reverse-engineering-notes.md +56 -0
- data/TODO.fixup/15-enumeration-literal-rendering.md +30 -0
- data/TODO.fixup/16-operation-compartment-rendering.md +42 -0
- data/TODO.fixup/17-path-count-calibration.md +27 -0
- data/TODO.fixup/18-polygon-count-calibration.md +32 -0
- data/TODO.fixup/19-rect-count-undershoot-investigation.md +40 -0
- data/TODO.fixup/20-stereotype-color-from-classifier.md +18 -0
- data/TODO.fixup/21-visibility-filter-for-properties.md +24 -0
- data/TODO.fixup/22-multiplicity-display-rule-calibration.md +25 -0
- data/TODO.fixup/23-diagram-frame-title-element.md +31 -0
- data/TODO.fixup/24-note-element-rendering.md +23 -0
- data/TODO.fixup/25-ea-exe-disassembly-findings.md +177 -0
- data/TODO.fixup/26-svg-renderer-architecture.md +78 -0
- data/TODO.fixup/27-svg-element-emitters-disassembly.md +135 -0
- data/TODO.fixup/28-geometry-parser-identification.md +57 -0
- data/TODO.fixup/29-qea-svg-xmi-triple-comparison.md +185 -0
- data/TODO.fixup/30-theme-system-stub.md +46 -0
- data/TODO.fixup/31-theme-value-object-registry.md +17 -0
- data/TODO.fixup/32-styleex-on-diagram-model.md +22 -0
- data/TODO.fixup/33-text-encoding-decimals-rotation.md +29 -0
- data/TODO.fixup/34-per-type-fill-via-theme.md +18 -0
- data/TODO.fixup/35-stroke-width-per-theme.md +7 -0
- data/TODO.fixup/36-qea-rect-coord-normalization.md +24 -0
- data/TODO.fixup/37-package-shape-rendering.md +22 -0
- data/TODO.fixup/38-note-element-rendering.md +15 -0
- data/TODO.fixup/39-styleex-flag-honoring.md +25 -0
- data/TODO.fixup/40-connector-dashed-lines.md +15 -0
- data/TODO.fixup/41-diagram-frame-showborder-detection.md +23 -0
- data/TODO.fixup/42-textrenderer-centralization.md +10 -0
- data/TODO.fixup/43-colorresolver-unification.md +24 -0
- data/TODO.fixup/44-theme-aware-textrenderer.md +17 -0
- data/TODO.fixup/45-theme-aware-fontresolver.md +22 -0
- data/TODO.fixup/46-style-parameterized-by-theme.md +21 -0
- data/TODO.fixup/47-canvas-frame-inset.md +19 -0
- data/TODO.fixup/48-background-rect-format.md +15 -0
- data/TODO.fixup/49-all-samples-integration-test.md +17 -0
- data/TODO.fixup/50-svg-emitter-architecture-docs.md +33 -0
- data/TODO.fixup/51-promote-theme-to-ea-namespace.md +28 -0
- data/TODO.fixup/52-theme-definition-integrated-fills.md +26 -0
- data/TODO.fixup/53-theme-registry-yaml-loading.md +50 -0
- data/TODO.fixup/54-diagram-theme-api.md +50 -0
- data/TODO.fixup/55-update-eaemitter-to-ea-theme.md +23 -0
- data/TODO.fixup/56-theme-yaml-files.md +65 -0
- data/TODO.fixup/57-theme-specs-and-integration.md +27 -0
- data/TODO.fixup/58-ea-entry-point-theme-autoload.md +20 -0
- data/TODO.fixup/59-thread-theme-through-all-renderers.md +29 -0
- data/TODO.fixup/60-cli-theme-option.md +22 -0
- data/TODO.fixup/61-theme-validation.md +28 -0
- data/TODO.fixup/62-theme-builder-dsl.md +31 -0
- data/TODO.fixup/63-theme-integration-rendering-spec.md +24 -0
- data/TODO.fixup/64-theme-writeback-styleex.md +21 -0
- data/TODO.fixup/65-remove-dead-eaemitter-theme-files.md +30 -0
- data/TODO.fixup/66-styleex-writeback.md +22 -0
- data/TODO.fixup/67-delete-dead-code.md +28 -0
- data/TODO.fixup/68-figure-parity-status.md +82 -0
- data/TODO.fixup/69-package-polygon-rendering.md +54 -0
- data/TODO.fixup/70-tagged-values-compartment.md +39 -0
- data/TODO.fixup/71-auto-detect-theme-from-xmi.md +37 -0
- data/TODO.fixup/72-sample-exports-as-regression-specs.md +37 -0
- data/TODO.fixup/73-delete-dead-transformations.md +14 -0
- data/TODO.fixup/74-delete-dead-diagram-renderers.md +18 -0
- data/TODO.fixup/75-visibility-legend-icons.md +23 -0
- data/TODO.fixup/76-plateau-text-undershoot.md +27 -0
- data/TODO.fixup/77-canvas-frame-margins.md +28 -0
- data/TODO.fixup/78-note-element-rendering.md +30 -0
- data/TODO.fixup/79-operation-compartment-rendering.md +27 -0
- data/TODO.fixup/80-tagged-value-stereotype-visibility.md +37 -0
- data/TODO.fixup/81-figure-parity-current-state.md +63 -0
- data/config/qea_schema.yml +356 -0
- data/config/stereotype_colors.yml +15 -0
- data/config/themes/119.yml +98 -0
- data/config/themes/default.yml +14 -0
- data/examples/exports/20251010_current_plateau_v5/UML_EA.DTD +6856 -0
- data/examples/exports/20251010_current_plateau_v5/model.xml +96709 -0
- data/examples/exports/ArcGISWorkspace_template/UML_EA.DTD +6856 -0
- data/examples/exports/ArcGISWorkspace_template/model.xml +1427 -0
- data/examples/exports/UmlModel_template/UML_EA.DTD +6856 -0
- data/examples/exports/UmlModel_template/model.xml +23 -0
- data/examples/exports/basic/UML_EA.DTD +6856 -0
- data/examples/exports/basic/model.xml +8039 -0
- data/examples/exports/simple/UML_EA.DTD +6856 -0
- data/examples/exports/simple/model.xml +585 -0
- data/examples/exports/simple_example/UML_EA.DTD +6856 -0
- data/examples/exports/simple_example/model.xml +23 -0
- data/examples/exports/test/UML_EA.DTD +6856 -0
- data/examples/exports/test/model.xml +1638 -0
- data/examples/qea/basic.qea +0 -0
- data/frontend/README.md +51 -0
- data/frontend/dist/app.iife.js +24 -0
- data/frontend/dist/style.css +1 -0
- data/frontend/index.html +26 -0
- data/frontend/package-lock.json +2359 -0
- data/frontend/package.json +26 -0
- data/frontend/src/App.vue +59 -0
- data/frontend/src/app.ts +8 -0
- data/frontend/src/components/AppHeader.vue +127 -0
- data/frontend/src/components/AppSidebar.vue +119 -0
- data/frontend/src/components/ClassDetails.vue +247 -0
- data/frontend/src/components/DiagramView.vue +79 -0
- data/frontend/src/components/PackageDetails.vue +92 -0
- data/frontend/src/components/PackageTreeNode.vue +64 -0
- data/frontend/src/components/SearchResults.vue +48 -0
- data/frontend/src/components/WelcomeView.vue +87 -0
- data/frontend/src/shims-vue.d.ts +5 -0
- data/frontend/src/stores/dataStore.ts +79 -0
- data/frontend/src/stores/uiStore.ts +167 -0
- data/frontend/src/styles/main.css +1566 -0
- data/frontend/src/types.ts +221 -0
- data/frontend/tests/e2e/__screenshots__/new-dark-mode.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-package-details.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-search-modal.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-sidebar-collapsed.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-welcome.png +0 -0
- data/frontend/tests/e2e/render.spec.ts +188 -0
- data/frontend/tsconfig.json +20 -0
- data/frontend/vite.config.ts +26 -0
- data/frontend/vitest.config.ts +8 -0
- data/lib/ea/cli/app.rb +62 -1
- data/lib/ea/cli/command/diagrams.rb +37 -28
- data/lib/ea/cli/command/diff.rb +46 -0
- data/lib/ea/cli/command/export.rb +80 -0
- data/lib/ea/cli/command/info.rb +75 -0
- data/lib/ea/cli/command/lint.rb +48 -0
- data/lib/ea/cli/command/mdg.rb +98 -0
- data/lib/ea/cli/command/query.rb +34 -0
- data/lib/ea/cli/command/render.rb +135 -0
- data/lib/ea/cli/command/svg.rb +43 -6
- data/lib/ea/cli/command.rb +7 -0
- data/lib/ea/diagram/display_config.rb +184 -0
- data/lib/ea/diagram.rb +4 -41
- data/lib/ea/diff/change.rb +30 -0
- data/lib/ea/diff/comparator.rb +82 -0
- data/lib/ea/diff/html_reporter.rb +91 -0
- data/lib/ea/diff.rb +15 -0
- data/lib/ea/export/json/generator.rb +42 -0
- data/lib/ea/export/json.rb +12 -0
- data/lib/ea/export/json_schema/generator.rb +77 -0
- data/lib/ea/export/json_schema.rb +12 -0
- data/lib/ea/export/plantuml/generator.rb +73 -0
- data/lib/ea/export/plantuml.rb +12 -0
- data/lib/ea/export/xmi/generator.rb +77 -0
- data/lib/ea/export/xmi.rb +11 -0
- data/lib/ea/export/xsd/class_mapping.rb +65 -0
- data/lib/ea/export/xsd/generator.rb +142 -0
- data/lib/ea/export/xsd/namespace_registry.rb +82 -0
- data/lib/ea/export/xsd.rb +19 -0
- data/lib/ea/export.rb +14 -0
- data/lib/ea/image/emf_renderer.rb +42 -0
- data/lib/ea/image.rb +12 -0
- data/lib/ea/lint/engine.rb +30 -0
- data/lib/ea/lint/lint_rule.rb +38 -0
- data/lib/ea/lint/offense.rb +18 -0
- data/lib/ea/lint/rules/cyclic_generalization.rb +62 -0
- data/lib/ea/lint/rules/duplicate_name.rb +28 -0
- data/lib/ea/lint/rules/missing_stereotype.rb +35 -0
- data/lib/ea/lint/rules/naming_convention.rb +44 -0
- data/lib/ea/lint/rules/orphan_element.rb +28 -0
- data/lib/ea/lint/rules.rb +14 -0
- data/lib/ea/lint.rb +13 -0
- data/lib/ea/mdg/document.rb +120 -0
- data/lib/ea/mdg/loader.rb +118 -0
- data/lib/ea/mdg/registry.rb +98 -0
- data/lib/ea/mdg/stereotype_alias_registry.rb +77 -0
- data/lib/ea/mdg/xml/applies_to.rb +18 -0
- data/lib/ea/mdg/xml/apply.rb +18 -0
- data/lib/ea/mdg/xml/content.rb +18 -0
- data/lib/ea/mdg/xml/documentation.rb +24 -0
- data/lib/ea/mdg/xml/stereotype.rb +28 -0
- data/lib/ea/mdg/xml/stereotypes.rb +18 -0
- data/lib/ea/mdg/xml/tag.rb +28 -0
- data/lib/ea/mdg/xml/tagged_values.rb +18 -0
- data/lib/ea/mdg/xml/technology.rb +28 -0
- data/lib/ea/mdg/xml/uml_profile.rb +22 -0
- data/lib/ea/mdg/xml/uml_profiles.rb +18 -0
- data/lib/ea/mdg/xml.rb +24 -0
- data/lib/ea/mdg.rb +25 -0
- data/lib/ea/model/classifier.rb +4 -0
- data/lib/ea/model/constraint.rb +24 -0
- data/lib/ea/model/diagram.rb +85 -0
- data/lib/ea/model/diagram_connector.rb +53 -1
- data/lib/ea/model/diagram_element.rb +44 -0
- data/lib/ea/model/document.rb +47 -2
- data/lib/ea/model/ghost_label.rb +32 -0
- data/lib/ea/model/instance_specification.rb +34 -0
- data/lib/ea/model/legend.rb +43 -0
- data/lib/ea/model/legend_item.rb +26 -0
- data/lib/ea/model/note.rb +28 -0
- data/lib/ea/model/operation.rb +2 -0
- data/lib/ea/model/property.rb +2 -0
- data/lib/ea/model/relationship.rb +2 -0
- data/lib/ea/model/signal.rb +14 -0
- data/lib/ea/model/slot.rb +19 -0
- data/lib/ea/model.rb +8 -0
- data/lib/ea/ocl/evaluator.rb +94 -0
- data/lib/ea/ocl/nodes.rb +30 -0
- data/lib/ea/ocl/parser.rb +133 -0
- data/lib/ea/ocl/unsupported_error.rb +7 -0
- data/lib/ea/ocl.rb +13 -0
- data/lib/ea/qea/factory/document_builder.rb +24 -10
- data/lib/ea/qea/factory/generalization_builder.rb +9 -11
- data/lib/ea/qea/infrastructure/table_reader.rb +9 -0
- data/lib/ea/qea/models/ea_author.rb +35 -0
- data/lib/ea/qea/models/ea_glossary.rb +34 -0
- data/lib/ea/qea/models/ea_image.rb +53 -0
- data/lib/ea/qea/models/ea_implement.rb +32 -0
- data/lib/ea/qea/models/ea_list.rb +42 -0
- data/lib/ea/qea/models/ea_object_effort.rb +34 -0
- data/lib/ea/qea/models/ea_object_problem.rb +37 -0
- data/lib/ea/qea/models/ea_object_require.rb +34 -0
- data/lib/ea/qea/models/ea_object_resource.rb +34 -0
- data/lib/ea/qea/models/ea_object_risk.rb +34 -0
- data/lib/ea/qea/models/ea_object_scenario.rb +34 -0
- data/lib/ea/qea/models/ea_object_test.rb +35 -0
- data/lib/ea/qea/models/ea_object_trx.rb +34 -0
- data/lib/ea/qea/models/ea_operation.rb +7 -0
- data/lib/ea/qea/models/ea_palette.rb +30 -0
- data/lib/ea/qea/models/ea_palette_item.rb +36 -0
- data/lib/ea/qea/models/ea_phase.rb +40 -0
- data/lib/ea/qea/models/ea_role_constraint.rb +32 -0
- data/lib/ea/qea/models/ea_secrypt.rb +34 -0
- data/lib/ea/qea/models/ea_version.rb +39 -0
- data/lib/ea/qea/models/ea_xref.rb +11 -1
- data/lib/ea/qea/models.rb +19 -0
- data/lib/ea/qea/services/database_loader.rb +22 -1
- data/lib/ea/query/builder.rb +108 -0
- data/lib/ea/query.rb +9 -0
- data/lib/ea/render/image_converter.rb +101 -0
- data/lib/ea/render.rb +10 -0
- data/lib/ea/shapescript/parser.rb +208 -0
- data/lib/ea/shapescript/renderer.rb +74 -0
- data/lib/ea/shapescript/shape.rb +34 -0
- data/lib/ea/shapescript.rb +24 -0
- data/lib/ea/sources/qea/adapter.rb +22 -5
- data/lib/ea/sources/qea/classifier_builder.rb +184 -7
- data/lib/ea/sources/qea/diagram_builder.rb +352 -24
- data/lib/ea/sources/qea/id_normalizer.rb +16 -1
- data/lib/ea/sources/qea/instance_builder.rb +113 -0
- data/lib/ea/sources/qea/legend_builder.rb +137 -0
- data/lib/ea/sources/qea/note_builder.rb +58 -0
- data/lib/ea/sources/qea/object_classifier_map.rb +6 -1
- data/lib/ea/sources/qea/operation_builder.rb +1 -0
- data/lib/ea/sources/qea/package_builder.rb +16 -0
- data/lib/ea/sources/qea/relationship_builder.rb +21 -5
- data/lib/ea/sources/qea/tagged_value_builder.rb +28 -9
- data/lib/ea/sources/qea/xref/legend_definition.rb +35 -0
- data/lib/ea/sources/qea/xref/parser.rb +150 -0
- data/lib/ea/sources/qea/xref/property_definition.rb +29 -0
- data/lib/ea/sources/qea/xref/record.rb +41 -0
- data/lib/ea/sources/qea/xref/stereotype_application.rb +37 -0
- data/lib/ea/sources/qea/xref.rb +27 -0
- data/lib/ea/sources/qea.rb +4 -0
- data/lib/ea/sources/xmi/adapter.rb +80 -2
- data/lib/ea/sources/xmi/annotation_builder.rb +1 -1
- data/lib/ea/sources/xmi/classifier_builder.rb +10 -1
- data/lib/ea/sources/xmi/diagram_builder.rb +242 -45
- data/lib/ea/sources/xmi/extension_elements.rb +74 -0
- data/lib/ea/sources/xmi/extension_geometry_parser.rb +124 -0
- data/lib/ea/sources/xmi/extension_style_parser.rb +91 -0
- data/lib/ea/sources/xmi/note_builder.rb +46 -0
- data/lib/ea/sources/xmi/property_builder.rb +9 -0
- data/lib/ea/sources/xmi/stereotype_builder.rb +54 -0
- data/lib/ea/sources/xmi/tag_builder.rb +45 -0
- data/lib/ea/sources/xmi/umldi_keyword_extractor.rb +87 -0
- data/lib/ea/sources/xmi.rb +7 -0
- data/lib/ea/spa/output/sharded_multi_file_strategy.rb +18 -3
- data/lib/ea/spa/output/single_file_strategy.rb +8 -2
- data/lib/ea/spa/output/strategy.rb +34 -0
- data/lib/ea/svg/connector_router.rb +134 -0
- data/lib/ea/svg/ea_emitter/background.rb +15 -0
- data/lib/ea/svg/ea_emitter/bounds_calculator.rb +142 -0
- data/lib/ea/svg/ea_emitter/canvas.rb +88 -0
- data/lib/ea/svg/ea_emitter/color_resolver.rb +56 -0
- data/lib/ea/svg/ea_emitter/compartment/attributes.rb +28 -0
- data/lib/ea/svg/ea_emitter/compartment/constraints.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +86 -0
- data/lib/ea/svg/ea_emitter/compartment/header.rb +32 -0
- data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +57 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +96 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +67 -0
- data/lib/ea/svg/ea_emitter/compartment/note_body.rb +52 -0
- data/lib/ea/svg/ea_emitter/compartment/note_text.rb +102 -0
- data/lib/ea/svg/ea_emitter/compartment/operations.rb +38 -0
- data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +72 -0
- data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +136 -0
- data/lib/ea/svg/ea_emitter/compartment/shape.rb +82 -0
- data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment.rb +58 -0
- data/lib/ea/svg/ea_emitter/connectors.rb +84 -0
- data/lib/ea/svg/ea_emitter/diagram_frame.rb +143 -0
- data/lib/ea/svg/ea_emitter/document.rb +35 -0
- data/lib/ea/svg/ea_emitter/element/attribute_line_builder.rb +117 -0
- data/lib/ea/svg/ea_emitter/element/attribute_renderer.rb +119 -0
- data/lib/ea/svg/ea_emitter/element/bcol_decoder.rb +29 -0
- data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +113 -0
- data/lib/ea/svg/ea_emitter/element/constraint_renderer.rb +53 -0
- data/lib/ea/svg/ea_emitter/element/divider_renderer.rb +17 -0
- data/lib/ea/svg/ea_emitter/element/enumeration_literal_renderer.rb +34 -0
- data/lib/ea/svg/ea_emitter/element/filter.rb +44 -0
- data/lib/ea/svg/ea_emitter/element/hand_draw_shape_renderer.rb +77 -0
- data/lib/ea/svg/ea_emitter/element/header_line_pipeline.rb +43 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/instance_spec.rb +27 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/name.rb +76 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/parent_ghost.rb +25 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/stereotype_label.rb +68 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider.rb +19 -0
- data/lib/ea/svg/ea_emitter/element/header_lines.rb +27 -0
- data/lib/ea/svg/ea_emitter/element/header_renderer.rb +48 -0
- data/lib/ea/svg/ea_emitter/element/icon_renderer.rb +109 -0
- data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +177 -0
- data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +112 -0
- data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +100 -0
- data/lib/ea/svg/ea_emitter/element/package_shape_renderer.rb +181 -0
- data/lib/ea/svg/ea_emitter/element/row_icon_renderer.rb +156 -0
- data/lib/ea/svg/ea_emitter/element/shape_renderer.rb +17 -0
- data/lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb +82 -0
- data/lib/ea/svg/ea_emitter/element/tagged_value_renderer.rb +50 -0
- data/lib/ea/svg/ea_emitter/element/text_escape.rb +20 -0
- data/lib/ea/svg/ea_emitter/element.rb +37 -0
- data/lib/ea/svg/ea_emitter/elements.rb +357 -0
- data/lib/ea/svg/ea_emitter/font_resolver.rb +111 -0
- data/lib/ea/svg/ea_emitter/ghost_labels.rb +66 -0
- data/lib/ea/svg/ea_emitter/label/end_label.rb +266 -0
- data/lib/ea/svg/ea_emitter/label/midpoint_label.rb +101 -0
- data/lib/ea/svg/ea_emitter/label/registry.rb +50 -0
- data/lib/ea/svg/ea_emitter/label.rb +23 -0
- data/lib/ea/svg/ea_emitter/labels.rb +130 -0
- data/lib/ea/svg/ea_emitter/layer.rb +20 -0
- data/lib/ea/svg/ea_emitter/layer_sequencer.rb +93 -0
- data/lib/ea/svg/ea_emitter/marker/arrow_path.rb +52 -0
- data/lib/ea/svg/ea_emitter/marker/diamond.rb +57 -0
- data/lib/ea/svg/ea_emitter/marker/kind.rb +35 -0
- data/lib/ea/svg/ea_emitter/marker/open_triangle.rb +27 -0
- data/lib/ea/svg/ea_emitter/marker/package_import.rb +39 -0
- data/lib/ea/svg/ea_emitter/marker/plus.rb +40 -0
- data/lib/ea/svg/ea_emitter/marker/registry.rb +42 -0
- data/lib/ea/svg/ea_emitter/marker.rb +37 -0
- data/lib/ea/svg/ea_emitter/markers.rb +404 -0
- data/lib/ea/svg/ea_emitter/render_context.rb +52 -0
- data/lib/ea/svg/ea_emitter/style.rb +15 -0
- data/lib/ea/svg/ea_emitter/text_renderer.rb +92 -0
- data/lib/ea/svg/ea_emitter.rb +51 -0
- data/lib/ea/svg/parity/checker.rb +105 -0
- data/lib/ea/svg/parity/source.rb +59 -0
- data/lib/ea/svg/parity/suite.rb +113 -0
- data/lib/ea/svg/parity.rb +14 -0
- data/lib/ea/svg/stereotype_color_resolver.rb +50 -0
- data/lib/ea/svg.rb +4 -15
- data/lib/ea/theme/definition.rb +176 -0
- data/lib/ea/theme/loader.rb +125 -0
- data/lib/ea/theme/registry.rb +96 -0
- data/lib/ea/theme.rb +37 -0
- data/lib/ea/transformations.rb +5 -88
- data/lib/ea/version.rb +4 -1
- data/lib/ea.rb +14 -4
- data/lib/tasks/svg_bench.rake +87 -0
- data/lutaml-uml-0.5.1.gem +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes-list.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-2-gradients.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-3-colors.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance-fonts.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-5-behavior.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-6-sequence.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-2-objects.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-3-links.png +0 -0
- metadata +473 -26
- data/lib/ea/diagram/configuration.rb +0 -379
- data/lib/ea/diagram/element_renderers/base_renderer.rb +0 -77
- data/lib/ea/diagram/element_renderers/class_renderer.rb +0 -323
- data/lib/ea/diagram/element_renderers/connector_renderer.rb +0 -41
- data/lib/ea/diagram/element_renderers/package_renderer.rb +0 -61
- data/lib/ea/diagram/element_renderers.rb +0 -43
- data/lib/ea/diagram/extractor.rb +0 -566
- data/lib/ea/diagram/layout_engine.rb +0 -170
- data/lib/ea/diagram/path_builder.rb +0 -202
- data/lib/ea/diagram/style_parser.rb +0 -42
- data/lib/ea/diagram/style_resolver.rb +0 -291
- data/lib/ea/diagram/svg_renderer.rb +0 -274
- data/lib/ea/diagram/util.rb +0 -73
- data/lib/ea/svg/bounds_calculator.rb +0 -74
- data/lib/ea/svg/connector_path.rb +0 -138
- data/lib/ea/svg/element_box.rb +0 -256
- data/lib/ea/svg/renderer.rb +0 -77
- data/lib/ea/svg/style_resolver.rb +0 -72
- data/lib/ea/transformations/configuration.rb +0 -333
- data/lib/ea/transformations/format_registry.rb +0 -366
- data/lib/ea/transformations/parsers/base_parser.rb +0 -482
- data/lib/ea/transformations/parsers/qea_parser.rb +0 -401
- data/lib/ea/transformations/parsers/xmi_parser.rb +0 -243
- data/lib/ea/transformations/transformation_engine.rb +0 -390
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# TODO-D 55: Visibility icon discriminator (deferred)
|
|
2
|
+
|
|
3
|
+
## Status: deferred (out of scope for current session)
|
|
4
|
+
|
|
5
|
+
EA renders a "folded page" visibility icon for each attribute row
|
|
6
|
+
in some diagrams. The discriminator is `ShowIcons=1` in the
|
|
7
|
+
diagram's Style1 string.
|
|
8
|
+
|
|
9
|
+
## Icon design (per attribute row)
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
y_top (rect.y)
|
|
13
|
+
y_top..y_top+4: inner rect 11x4 (white fill, blue stroke)
|
|
14
|
+
y_top..y_top+14: outer rect 11x14 (pale yellow, blue stroke)
|
|
15
|
+
y_top+7: horizontal path (midline)
|
|
16
|
+
y_top+5, y_top+9, y_top+11: 3 short "text line" paths (4 wide)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Total: 2 rects + 4 paths = 6 elements per attribute row.
|
|
20
|
+
|
|
21
|
+
## Where it appears
|
|
22
|
+
|
|
23
|
+
| Diagram | rect | path | text | Why |
|
|
24
|
+
|---------|------|------|------|-----|
|
|
25
|
+
| basic.qea Package Imports | -6 | -18 | -4 | 2 attrs × 6 elements = 12 missing |
|
|
26
|
+
| test.qea Test Model | -15 | -58 | -11 | 8 attrs × 6 elements = 48 missing |
|
|
27
|
+
| basic.qea Operations+Object | similar | similar | similar | some object diagrams |
|
|
28
|
+
|
|
29
|
+
## Implementation
|
|
30
|
+
|
|
31
|
+
1. Parse `ShowIcons=N` from `t_diagram.Style1` (or per-element
|
|
32
|
+
`HideIcon=N` from `t_diagramobjects.Style`).
|
|
33
|
+
2. When ShowIcons=1 (or default-icon), pass an `icon_visibility`
|
|
34
|
+
flag through `RenderContext`.
|
|
35
|
+
3. Add a new `Compartment::VisibilityIcon` module that renders
|
|
36
|
+
the 2 rects + 4 paths per attribute row.
|
|
37
|
+
4. Wire it into the Attribute compartment (or render alongside
|
|
38
|
+
it).
|
|
39
|
+
|
|
40
|
+
## Why deferred
|
|
41
|
+
|
|
42
|
+
- Requires parsing the QEA Style1 string (already done in
|
|
43
|
+
DisplayConfig for other flags).
|
|
44
|
+
- Discriminator must be verified across more diagrams (e.g.
|
|
45
|
+
plateau's Building diagram has 1 icon — the same logic should
|
|
46
|
+
apply).
|
|
47
|
+
- Each attribute row needs the icon rendered at a precise offset
|
|
48
|
+
(currently at content_x_offset, attr_y - 9).
|
|
49
|
+
|
|
50
|
+
Closes ~80 rects + ~50 paths in basic.qea + ~70 rects + ~250
|
|
51
|
+
paths in test.qea (Test Model with 8 attrs).
|
|
52
|
+
|
|
53
|
+
## Code-quality alignment
|
|
54
|
+
|
|
55
|
+
The new `Compartment::VisibilityIcon` would follow the OCP
|
|
56
|
+
pattern established by the Compartment pipeline — adding a new
|
|
57
|
+
compartment = appending to `Compartment::ALL`, no modification
|
|
58
|
+
of `Elements#groups_for` needed.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# TODO-D 56: Package contents rendering (DONE)
|
|
2
|
+
|
|
3
|
+
## Before
|
|
4
|
+
|
|
5
|
+
When a diagram's `t_diagram.ShowPackageContents` flag was non-zero,
|
|
6
|
+
EA renders each Package element with:
|
|
7
|
+
- A 2-line tab when the package has a stereotype («applicationSchema»)
|
|
8
|
+
- A body compartment listing child classifiers and sub-packages as
|
|
9
|
+
"+ Name" rows
|
|
10
|
+
- A per-row icon whose shape encodes the child's type
|
|
11
|
+
|
|
12
|
+
Our renderer produced only the bare folder silhouette. All test.qea
|
|
13
|
+
"Test Model" diagrams and basic.qea "Package Imports" diagrams
|
|
14
|
+
under-rendered by ~70 elements each.
|
|
15
|
+
|
|
16
|
+
## After
|
|
17
|
+
|
|
18
|
+
### Source side
|
|
19
|
+
|
|
20
|
+
- `Ea::Sources::Qea::PackageBuilder#stereotype_refs_for`: now reads
|
|
21
|
+
the t_object.Stereotype column for the package's mirror row
|
|
22
|
+
(matched by ea_guid). EA stores the stereotype on t_object, not
|
|
23
|
+
t_package.
|
|
24
|
+
- `Ea::Sources::Qea::DiagramBuilder#package_contents_enabled?`:
|
|
25
|
+
threads `show_package_contents` (non-zero t_diagram column) into
|
|
26
|
+
`Ea::Model::Diagram`.
|
|
27
|
+
- `Ea::Model::Diagram#show_package_contents`: boolean attribute
|
|
28
|
+
controlling whether the package-contents compartment is rendered.
|
|
29
|
+
|
|
30
|
+
### Render side
|
|
31
|
+
|
|
32
|
+
- `Ea::Svg::EaEmitter::Element::PackageShapeRenderer`: now accepts
|
|
33
|
+
an optional `stereotype:` argument. When present, the tab grows
|
|
34
|
+
to 36px tall (vs 20px) and renders two left-aligned text lines
|
|
35
|
+
(«stereotype» + name). Tab width is fixed at 105px (EA convention).
|
|
36
|
+
- `Ea::Svg::EaEmitter::Compartment::PackageContents`: new
|
|
37
|
+
compartment module that renders the body's child rows. Each row
|
|
38
|
+
is one `<text>` element ("+ Name") plus a small per-type icon.
|
|
39
|
+
- `Ea::Svg::EaEmitter::Element::RowIconRenderer`: new renderer for
|
|
40
|
+
the per-row icons. Three kinds:
|
|
41
|
+
- `:enumeration` (12×13 green rect + 7 paths) — used for
|
|
42
|
+
Enumeration classifiers or Klass with stereotype "enumeration".
|
|
43
|
+
- `:package` (13×9 folder rect, no paths) — used for sub-Packages.
|
|
44
|
+
- `:default` (11×14 + 11×4 rects + 7 paths) — used for other
|
|
45
|
+
Classifiers (Klass, DataType, etc.).
|
|
46
|
+
- `Ea::Svg::EaEmitter::Compartment::Shape`: threads the package's
|
|
47
|
+
stereotype to PackageShapeRenderer.
|
|
48
|
+
- `Ea::Svg::EaEmitter::Elements`: computes `package_content_lines`
|
|
49
|
+
for Package model elements when `diagram.show_package_contents`
|
|
50
|
+
is truthy. Children include both Classifier and sub-Package
|
|
51
|
+
instances; the icon kind is chosen by classifier type or
|
|
52
|
+
"enumeration" stereotype.
|
|
53
|
+
|
|
54
|
+
### Specs
|
|
55
|
+
|
|
56
|
+
- Updated `spec/ea/svg/ea_emitter/compartment_spec.rb` to include
|
|
57
|
+
PackageContents in the expected ALL list.
|
|
58
|
+
|
|
59
|
+
## Verification
|
|
60
|
+
|
|
61
|
+
- simple.qea: 2/2 (100% strict-perfect) — unchanged.
|
|
62
|
+
- basic.qea: 21/22 matched within tolerance (up from 20/22).
|
|
63
|
+
14/22 strict-perfect (up from 7/22).
|
|
64
|
+
- test.qea: 2/2 matched within tolerance. Test Model is strict
|
|
65
|
+
perfect (was shape_delta=71). TestSchema still has a small
|
|
66
|
+
pre-existing -4 text gap unrelated to package contents.
|
|
67
|
+
- Plateau: rect/path/polygon deltas unchanged (text improved
|
|
68
|
+
slightly, -626 → -615, from stereotype rendering).
|
|
69
|
+
- 1767 specs pass, 0 failures.
|
|
70
|
+
|
|
71
|
+
## Remaining gaps
|
|
72
|
+
|
|
73
|
+
- test.qea TestSchema: -3 text. Ref includes «voidable» constraint
|
|
74
|
+
stereotype, "constraints" header, and "{pattern}" annotation that
|
|
75
|
+
we don't render yet. Pre-existing.
|
|
76
|
+
- basic.qea Domain Model: rect=+3 (Concept boxes drawn as rects
|
|
77
|
+
but ref uses bezier paths). Pre-existing.
|
|
78
|
+
- basic.qea Class-diagram-with-X diagrams: path deltas from
|
|
79
|
+
association marker encoding differences (QEA polygon vs XMI
|
|
80
|
+
arrow path). Pre-existing.
|
|
81
|
+
- basic.qea Object diagrams: missing instance-name underline paths
|
|
82
|
+
and instance label format ("Object 01 / roleOne: Class A"). Needs
|
|
83
|
+
an InstanceSpecification model. Pre-existing.
|
|
84
|
+
|
|
85
|
+
## Follow-up commits
|
|
86
|
+
|
|
87
|
+
`feat: promote enumeration-stereotyped Class to Enumeration model` —
|
|
88
|
+
ClassifierBuilder now treats a Class with stereotype "enumeration"
|
|
89
|
+
as an Enumeration. Closes 1 additional text delta on TestSchema
|
|
90
|
+
(-4 → -3).
|
|
91
|
+
|
|
92
|
+
`feat: constraints compartment (italic header + {name} expression)` —
|
|
93
|
+
Adds Ea::Model::Constraint, reads t_objectconstraint in the QEA
|
|
94
|
+
classifier builder, and renders via Compartment::Constraints +
|
|
95
|
+
Element::ConstraintRenderer. Closes 2 text deltas on TestSchema
|
|
96
|
+
(-3 → -1).
|
|
97
|
+
|
|
98
|
+
`feat: render attribute stereotypes as separate text lines` —
|
|
99
|
+
AttributeRenderer.lines_for inserts «stereotype» entries before
|
|
100
|
+
stereotyped properties. Closes the final TestSchema text gap
|
|
101
|
+
(-1 → 0).
|
|
102
|
+
|
|
103
|
+
`feat: instance-name underline for object diagrams` — Object
|
|
104
|
+
diagrams draw a horizontal underline below each instance name.
|
|
105
|
+
New Compartment::InstanceUnderline module fires for diagrams
|
|
106
|
+
where diagram_type=="Object". RenderContext gains a :diagram
|
|
107
|
+
field. Improves path delta on all 4 basic.qea object diagrams.
|
|
108
|
+
|
|
109
|
+
`feat: «import» markers for Package connectors` — New
|
|
110
|
+
Marker::PackageImport kind emits both a closed trapezoid at the
|
|
111
|
+
source end and an open V-arrow at the target end of Package
|
|
112
|
+
(«import») connectors. Closes the basic.qea Package Imports
|
|
113
|
+
path delta (-4 → 0).
|
|
114
|
+
|
|
115
|
+
`feat: Object diagram — divider + suppress arrows` — Object
|
|
116
|
+
diagrams render associations as instance-level links without
|
|
117
|
+
navigability arrows. Markers suppresses :arrow specs for
|
|
118
|
+
Association connectors when diagram_type=="Object". HeaderDivider
|
|
119
|
+
gains a diagram-type-aware discriminator: on Object diagrams the
|
|
120
|
+
divider is shown when bounds.height > 50 (matches EA's "has slot
|
|
121
|
+
compartment" heuristic). Closes path deltas on all 4 basic.qea
|
|
122
|
+
Object diagrams. Starter Object Diagram is now strict-perfect.
|
|
123
|
+
|
|
124
|
+
## Final state
|
|
125
|
+
|
|
126
|
+
- simple.qea: 2/2 strict-perfect (100%).
|
|
127
|
+
- basic.qea: **16/22 strict-perfect**, 22/22 within tolerance.
|
|
128
|
+
- test.qea: 1/2 strict-perfect (Test Model perfect; TestSchema at
|
|
129
|
+
text=0, path=-1).
|
|
130
|
+
- Plateau: rect -221, path -280, polygon -6, text -615.
|
|
131
|
+
- 1800 specs pass, 0 failures.
|
|
132
|
+
|
|
133
|
+
## Remaining gaps (all pre-existing, out of scope)
|
|
134
|
+
|
|
135
|
+
- test.qea TestSchema: -1 path (association marker encoding).
|
|
136
|
+
- basic.qea Domain Model: +3 rect (Concept boxes drawn as rects
|
|
137
|
+
but ref uses bezier paths in a "domain class" style with
|
|
138
|
+
Comic Sans MS italic font).
|
|
139
|
+
- basic.qea Classes (×2): +1 path each (extra arrow marker on
|
|
140
|
+
tree-routed Association connectors — source discriminator not
|
|
141
|
+
yet identified; same connectors on Multiplicities render WITH
|
|
142
|
+
arrows in ref, so the rule is more subtle than waypoint count).
|
|
143
|
+
- basic.qea Object diagrams (×3 with text deltas): instance label
|
|
144
|
+
format ("Object 01 / roleOne: Class A"), slot value renderings
|
|
145
|
+
("attr = value"), and "(from package)" subtitle. Needs
|
|
146
|
+
InstanceSpecification model.
|
|
147
|
+
- Association marker encoding: QEA polygon vs XMI arrow path
|
|
148
|
+
discriminator not yet identified.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# TODO-D 57: InstanceSpecification model + slot rendering
|
|
2
|
+
|
|
3
|
+
## Status: open (blocks 3 basic.qea diagrams + plateau)
|
|
4
|
+
|
|
5
|
+
EA stores UML InstanceSpecifications in `t_object` rows with
|
|
6
|
+
`Object_Type="Object"`. Currently we parse these as `Klass`
|
|
7
|
+
instances (the closest classifier shape). Ref renders them as
|
|
8
|
+
instances with three features we don't emit:
|
|
9
|
+
|
|
10
|
+
1. **Instance label format** in the header: `instance_name` plus,
|
|
11
|
+
when the instance is a role in an association, the role +
|
|
12
|
+
classifier name (e.g. `"Object 01 / roleOne: Class A"`).
|
|
13
|
+
2. **Slot compartment** below the header: each `RunState` variable
|
|
14
|
+
is rendered as `"variable = value"` (e.g.
|
|
15
|
+
`"attributeOne = valueOne"`).
|
|
16
|
+
3. **From-package subtitle** below the slots:
|
|
17
|
+
`"(from Objects)"` — the containing package name in italics.
|
|
18
|
+
|
|
19
|
+
## Affected diagrams
|
|
20
|
+
|
|
21
|
+
| Diagram | text_delta | Notes |
|
|
22
|
+
|---------|-----------|-------|
|
|
23
|
+
| Basic Object Diagram with Value Specification | -2 | 1 slot per instance |
|
|
24
|
+
| Objects as Instances of Classes | -9 | 1 instance label + slot + from-package per box |
|
|
25
|
+
| Object with Value Specifications | -19 | 1 instance label + multiple slots + from-package per box |
|
|
26
|
+
|
|
27
|
+
Plus widespread contribution to the plateau text delta (-615).
|
|
28
|
+
|
|
29
|
+
## Source data
|
|
30
|
+
|
|
31
|
+
`t_object` columns for Object instances:
|
|
32
|
+
- `Object_Type="Object"`
|
|
33
|
+
- `Name="Object 01"` (the instance name)
|
|
34
|
+
- `Classifier=<id>` (the class this is an instance of; 0 = none)
|
|
35
|
+
- `RunState="@VAR;Variable=X;Value=Y;Op==;@ENDVAR;..."` (slots)
|
|
36
|
+
|
|
37
|
+
The role name (`"roleOne"`) comes from the connector's source role
|
|
38
|
+
field on the association linking this instance to another.
|
|
39
|
+
|
|
40
|
+
## Implementation plan
|
|
41
|
+
|
|
42
|
+
### 1. Model
|
|
43
|
+
|
|
44
|
+
- `Ea::Model::InstanceSpecification < Base` — new model class
|
|
45
|
+
- `name :string`
|
|
46
|
+
- `classifier_id :string` (id of the class this is an instance of)
|
|
47
|
+
- `slots :Slot, collection: true`
|
|
48
|
+
- `role_name :string` (filled in later by relationship resolver)
|
|
49
|
+
- `package_id :string`
|
|
50
|
+
- `qualified_name :string`
|
|
51
|
+
- `Ea::Model::Slot < Base` — a slot value
|
|
52
|
+
- `name :string` (the variable)
|
|
53
|
+
- `value :string`
|
|
54
|
+
- `op :string` (default `"="`)
|
|
55
|
+
|
|
56
|
+
### 2. Source side
|
|
57
|
+
|
|
58
|
+
- `Ea::Sources::Qea::InstanceBuilder` — new builder that reads
|
|
59
|
+
`t_object` rows where `Object_Type="Object"` and parses `RunState`
|
|
60
|
+
into Slot instances. Replaces the `Object → Klass` mapping in
|
|
61
|
+
`ObjectClassifierMap`.
|
|
62
|
+
- Update `Ea::Sources::Qea::Adapter` to call both `ClassifierBuilder`
|
|
63
|
+
and `InstanceBuilder`.
|
|
64
|
+
- Update `Document#index_by_id` to include instance specifications.
|
|
65
|
+
|
|
66
|
+
### 3. Render side
|
|
67
|
+
|
|
68
|
+
- `Compartment::InstanceHeader` (new) — renders the instance label
|
|
69
|
+
format `name / role: ClassName` in the header.
|
|
70
|
+
- `Compartment::InstanceSlots` (new) — renders the slot compartment
|
|
71
|
+
(`variable = value` lines).
|
|
72
|
+
- `Compartment::InstanceFromPackage` (new) — renders the
|
|
73
|
+
`"(from packageName)"` subtitle in italics.
|
|
74
|
+
- The existing `InstanceUnderline` module is reused for the
|
|
75
|
+
instance-name underline.
|
|
76
|
+
- `Shape` compartment: dispatch instance specs to a new
|
|
77
|
+
`InstanceShapeRenderer` (or reuse `ShapeRenderer` since the box
|
|
78
|
+
shape is the same).
|
|
79
|
+
|
|
80
|
+
### 4. Specs
|
|
81
|
+
|
|
82
|
+
- Instance model spec (round-trip JSON)
|
|
83
|
+
- InstanceBuilder spec (parses RunState correctly)
|
|
84
|
+
- InstanceSlots spec (renders "var = value")
|
|
85
|
+
- InstanceFromPackage spec (renders italic "(from X)")
|
|
86
|
+
|
|
87
|
+
## Discriminator
|
|
88
|
+
|
|
89
|
+
When `diagram.diagram_type == "Object"` AND `model_element.is_a?(InstanceSpecification)`:
|
|
90
|
+
- Header: instance label format
|
|
91
|
+
- Body: slot compartment + from-package subtitle
|
|
92
|
+
|
|
93
|
+
Otherwise: standard classifier rendering.
|
|
94
|
+
|
|
95
|
+
## Why deferred initially
|
|
96
|
+
|
|
97
|
+
Requires a new top-level model class, source-builder wiring, and 3
|
|
98
|
+
new compartments. ~300 lines of code + ~150 lines of specs. Affects
|
|
99
|
+
the parity metric broadly (basic.qea +3 diagrams strict-perfect,
|
|
100
|
+
plateau text delta improves).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# TODO-D 58: Domain Model note text + missing multiplicity
|
|
2
|
+
|
|
3
|
+
## Status: open (blocks 1 basic.qea diagram)
|
|
4
|
+
|
|
5
|
+
Domain Model is at shape_delta_total=0 (sum-zero parity) but has
|
|
6
|
+
text_delta=-7. Two missing items:
|
|
7
|
+
|
|
8
|
+
### A. Wrapped note text (-6)
|
|
9
|
+
|
|
10
|
+
EA wraps long note text across multiple `<text>` lines. For the
|
|
11
|
+
Domain Model Concepts, the note `"Detailed notes that describe the
|
|
12
|
+
concept."` is wrapped onto two lines per element:
|
|
13
|
+
|
|
14
|
+
<text x="45" y="95">[Detailed notes that describe the </text>
|
|
15
|
+
<text x="45" y="109">concept.]</text>
|
|
16
|
+
|
|
17
|
+
The leading `[` and trailing `]` are EA's convention for marking
|
|
18
|
+
the note body (not part of the actual note content). Line-wrap
|
|
19
|
+
width is determined by the element bounds width minus padding
|
|
20
|
+
(~125px usable for a 167px-wide box at font size 7pt).
|
|
21
|
+
|
|
22
|
+
Currently we don't render note text in element bodies at all. The
|
|
23
|
+
note text comes from `t_object.Note`.
|
|
24
|
+
|
|
25
|
+
### B. Missing target multiplicity (-1)
|
|
26
|
+
|
|
27
|
+
One Aggregation connector (`Relationship Two`) has source mult
|
|
28
|
+
`0..*` (rendered at top) and target mult `1..1` (should render
|
|
29
|
+
near Concept A's top edge but doesn't). The target endpoint lands
|
|
30
|
+
inside the element box and our EndLabel skips the label.
|
|
31
|
+
|
|
32
|
+
## Implementation plan
|
|
33
|
+
|
|
34
|
+
### For (A) — wrapped note text
|
|
35
|
+
|
|
36
|
+
- `Ea::Model::Classifier` already has `annotations` — re-use for
|
|
37
|
+
the documentation note OR add `note :string` as a separate field
|
|
38
|
+
(EA's `t_object.Note` is distinct from `t_objectproperties` tagged
|
|
39
|
+
values).
|
|
40
|
+
- `Ea::Sources::Qea::ClassifierBuilder#note_for` reads `object.note`.
|
|
41
|
+
- New `Compartment::NoteText` (different from `Compartment::NoteBody`
|
|
42
|
+
which handles Note elements):
|
|
43
|
+
- Splits the note text into lines based on a width estimate
|
|
44
|
+
- Wraps with `[` ... `]`
|
|
45
|
+
- Renders one `<text>` per line below the header divider
|
|
46
|
+
- Discriminator: render when `classifier.note` is non-empty AND
|
|
47
|
+
the element has no attribute compartment (the note replaces
|
|
48
|
+
attributes in this style).
|
|
49
|
+
|
|
50
|
+
### For (B) — multiplicity inside element
|
|
51
|
+
|
|
52
|
+
- `Ea::Svg::EaEmitter::Label::EndLabel`: relax the
|
|
53
|
+
"skip when inside element" rule for multiplicity labels — they
|
|
54
|
+
should render even when the anchor is inside an element box
|
|
55
|
+
(just offset outward).
|
|
56
|
+
|
|
57
|
+
## Verification
|
|
58
|
+
|
|
59
|
+
- basic.qea "Domain Model": text_delta -7 → 0.
|
|
60
|
+
- basic.qea: 16/22 → 17/22 strict-perfect.
|
|
61
|
+
|
|
62
|
+
## Why deferred
|
|
63
|
+
|
|
64
|
+
Note wrapping needs a width-estimation helper (font size × char
|
|
65
|
+
count × width factor) and a `Compartment::NoteText` module. The
|
|
66
|
+
multiplicity fix requires relaxing EndLabel's collision rule which
|
|
67
|
+
could regress other diagrams.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# TODO-D 59: Classes diagram association arrow discriminator
|
|
2
|
+
|
|
3
|
+
## Status: open (blocks 2 basic.qea diagrams)
|
|
4
|
+
|
|
5
|
+
Two basic.qea "Classes" diagrams have shape_delta=1 each. We render
|
|
6
|
+
one extra `<path>` per diagram — the navigability arrow at the
|
|
7
|
+
target end of an Association connector that EA's reference SVG
|
|
8
|
+
omits.
|
|
9
|
+
|
|
10
|
+
## Investigation summary
|
|
11
|
+
|
|
12
|
+
Compared fields across the rendering-pipeline:
|
|
13
|
+
|
|
14
|
+
| Diagram | Direction | SourceStyle | DestStyle | LineStyle | RouteStyle | SourceCard | DestCard | SourceIsAggregate | DestIsAggregate | SX/SY/EX/EY | Object types |
|
|
15
|
+
|---------|-----------|-------------|-----------|-----------|------------|------------|----------|-------------------|-----------------|-------------|--------------|
|
|
16
|
+
| Multiplicities (HAS arrow) | Unspecified | Navigable=U | Navigable=U | 0 | 3 | 0..* | 0..* | 0 | 0 | -6/-2/-57/-2 | Class ↔ Class |
|
|
17
|
+
| Classes (NO arrow) | Unspecified | Navigable=U | Navigable=U | 0 | 3 | 0..2 | 1 | 0 | 0 | -1/4/3/4 | Class ↔ Class |
|
|
18
|
+
|
|
19
|
+
All fields identical except cardinality and SX/SY/EX/EY values.
|
|
20
|
+
The visual difference: Multiplicities renders as a single straight
|
|
21
|
+
path + arrow polygon; Classes renders as 3 separate horizontal
|
|
22
|
+
segments + no arrow. EA appears to apply an internal "are bends
|
|
23
|
+
real?" heuristic.
|
|
24
|
+
|
|
25
|
+
## Hypothesis
|
|
26
|
+
|
|
27
|
+
EA computes the maximum perpendicular deviation of bend waypoints
|
|
28
|
+
from the straight source-target line. Below a threshold (likely
|
|
29
|
+
~2-3px), bends are treated as noise and the connector renders as
|
|
30
|
+
straight WITH navigability arrow. Above the threshold, the
|
|
31
|
+
connector renders as orthogonal segments with NO arrow.
|
|
32
|
+
|
|
33
|
+
For Multiplicities: deviations 1-2px → straight + arrow.
|
|
34
|
+
For Classes: deviations 4-5px → segmented + no arrow.
|
|
35
|
+
|
|
36
|
+
## Implementation plan
|
|
37
|
+
|
|
38
|
+
- In `Ea::Svg::EaEmitter::Connectors#path_for`, compute the
|
|
39
|
+
perpendicular deviation of each interior waypoint from the
|
|
40
|
+
source-target line. If max deviation ≤ THRESHOLD (try 3), emit
|
|
41
|
+
a straight 2-point path. Otherwise keep current multi-segment
|
|
42
|
+
path.
|
|
43
|
+
- In `Ea::Svg::EaEmitter::Markers#suppress_arrow?`, suppress
|
|
44
|
+
Association arrow when the connector is multi-segment (max
|
|
45
|
+
deviation > THRESHOLD).
|
|
46
|
+
- THRESHOLD constant lives on `Connectors` (or a shared
|
|
47
|
+
`ConnectorRouting` module) so both renderers use the same value.
|
|
48
|
+
|
|
49
|
+
## Verification
|
|
50
|
+
|
|
51
|
+
- basic.qea "Classes" (×2): shape_delta 1 → 0.
|
|
52
|
+
- basic.qea: 16/22 → 18/22 strict-perfect.
|
|
53
|
+
|
|
54
|
+
## Risk
|
|
55
|
+
|
|
56
|
+
The threshold value is reverse-engineered from a single sample.
|
|
57
|
+
Verifying against plateau connectors would confirm.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# TODO-D 60: TestSchema association marker encoding (-1 path)
|
|
2
|
+
|
|
3
|
+
## Status: open (blocks 1 test.qea diagram)
|
|
4
|
+
|
|
5
|
+
test.qea TestSchema is at text_delta=0 but path_delta=-1.
|
|
6
|
+
|
|
7
|
+
## Symptom
|
|
8
|
+
|
|
9
|
+
Ref renders a particular Association connector with an open
|
|
10
|
+
`<path>` V-shape arrow at the target end. We render the connector
|
|
11
|
+
line but no arrow — the marker is suppressed somewhere in our
|
|
12
|
+
dispatch.
|
|
13
|
+
|
|
14
|
+
## Likely cause
|
|
15
|
+
|
|
16
|
+
The connector is on a Logical (not Object) diagram so our
|
|
17
|
+
"Object diagrams suppress Association arrows" rule doesn't apply.
|
|
18
|
+
Yet we still don't emit the marker. The Markers#specs_for path
|
|
19
|
+
returns no specs because... needs investigation.
|
|
20
|
+
|
|
21
|
+
## Plan
|
|
22
|
+
|
|
23
|
+
1. Render TestSchema and identify which connector is missing its
|
|
24
|
+
arrow.
|
|
25
|
+
2. Trace through Marker::Registry.specs_for and confirm ArrowPath
|
|
26
|
+
is registered and returns a spec.
|
|
27
|
+
3. Trace through Markers#entries_for and check whether the spec is
|
|
28
|
+
being filtered out (suppress_arrow? or render_shape returns nil).
|
|
29
|
+
4. Most likely culprit: `unit_vector` returns nil because tip and
|
|
30
|
+
base are coincident (connector shorter than 1 unit vector step).
|
|
31
|
+
|
|
32
|
+
## Verification
|
|
33
|
+
|
|
34
|
+
- test.qea TestSchema: path_delta -1 → 0.
|
|
35
|
+
- test.qea: 1/2 → 2/2 strict-perfect (100%).
|
|
36
|
+
|
|
37
|
+
## Why deferred
|
|
38
|
+
|
|
39
|
+
Small delta (-1 path) and the fix likely requires non-trivial
|
|
40
|
+
debugging of the unit-vector geometry for very short connectors.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# TODO-D 61: Legend block rendering
|
|
2
|
+
|
|
3
|
+
## Status: completed
|
|
4
|
+
|
|
5
|
+
The plateau QEA's `t_object` rows with `Object_Type='Text'` and
|
|
6
|
+
`StyleEx` carrying `LegendOpts=` are auto-generated legend blocks.
|
|
7
|
+
EA renders each as a 4-rect + 4-text cluster (container + 3 colored
|
|
8
|
+
icons + title + 3 labels), with the legend configuration parsed
|
|
9
|
+
from a sibling `t_xref` row keyed off the same GUID.
|
|
10
|
+
|
|
11
|
+
## Implementation
|
|
12
|
+
|
|
13
|
+
- `Ea::Model::Legend` and `Ea::Model::LegendItem` — new models
|
|
14
|
+
carrying the legend title, colors (BGR-packed), and per-item
|
|
15
|
+
background colors. Default colors pulled from plateau SVG refs.
|
|
16
|
+
- `Ea::Model::Note` gains an optional `legend` attribute. Text
|
|
17
|
+
elements with `LegendOpts=` in StyleEx parse the legend payload
|
|
18
|
+
at load time; other Notes stay unencumbered.
|
|
19
|
+
- `Ea::Sources::Qea::LegendBuilder` parses the `@PROP=...@ENDPROP;`
|
|
20
|
+
blobs in `t_xref.Description` for a given Text element GUID.
|
|
21
|
+
- `Ea::Svg::EaEmitter::Element::LegendRenderer` emits the container
|
|
22
|
+
rect, icon rects, title text, and item labels. BGR colors decode
|
|
23
|
+
via the existing `Element::BColDecoder`.
|
|
24
|
+
- `Compartment::Shape` dispatches to `LegendRenderer` when the
|
|
25
|
+
element carries a legend payload; `Compartment::NoteBody` skips
|
|
26
|
+
rendering (legend replaces note body).
|
|
27
|
+
|
|
28
|
+
## Related fix: marker dedup removed
|
|
29
|
+
|
|
30
|
+
Reference inspection showed EA does NOT dedup polygon markers even
|
|
31
|
+
when N connectors share the same anchor — the Bridge diagram emits
|
|
32
|
+
9 distinct triangle polygons at one parent anchor. Removed the
|
|
33
|
+
`Markers::Entry#generalization_tree_routed?` dedup logic; EA emits
|
|
34
|
+
one marker per connector, period.
|
|
35
|
+
|
|
36
|
+
## Related fix: spec pollution
|
|
37
|
+
|
|
38
|
+
`spec/ea/svg/qea_regression_spec.rb` and
|
|
39
|
+
`spec/ea/svg/visual_regression_spec.rb` both defined top-level
|
|
40
|
+
constants named `REF_DIR` inside `RSpec.describe` blocks. Ruby
|
|
41
|
+
resolves these to top-level constants — the spec loaded second
|
|
42
|
+
won, silently pointing the other spec at the wrong reference SVG
|
|
43
|
+
directory. Renamed to `QEA_REF_DIR` and `VISUAL_REF_DIR`.
|
|
44
|
+
|
|
45
|
+
## Results (plateau QEA)
|
|
46
|
+
|
|
47
|
+
| Metric | Before | After | Change |
|
|
48
|
+
|---------|--------|--------|--------|
|
|
49
|
+
| Matched | 130/188| 137/188| +7 |
|
|
50
|
+
| rect | -460 | +4 | +464 |
|
|
51
|
+
| path | -92 | -92 | — |
|
|
52
|
+
| polygon | +27 | +25 | -2 |
|
|
53
|
+
| text | -519 | -55 | +464 |
|
|
54
|
+
|
|
55
|
+
basic.qea and test.qea remain at 22/22 and 2/2 respectively.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# TODO-D 61: Plateau parity gaps
|
|
2
|
+
|
|
3
|
+
## Status: open (broad cross-cutting gaps on plateau QEA)
|
|
4
|
+
|
|
5
|
+
The plateau is the `20251010_current_plateau_v5.1.qea` file at
|
|
6
|
+
`examples/qea/`. Its 188 reference SVGs live at
|
|
7
|
+
`examples/exports/20251010_current_plateau_v5/Images/`.
|
|
8
|
+
|
|
9
|
+
A separate plateau XMI is at
|
|
10
|
+
`~/src/mn/mn-samples-plateau/sources/xmi/plateau_all_packages_export.xmi`
|
|
11
|
+
with its own reference SVGs at
|
|
12
|
+
`~/src/mn/mn-samples-plateau/sources/001-mds/xmi-images/`.
|
|
13
|
+
|
|
14
|
+
## Current state — Plateau QEA (examples/)
|
|
15
|
+
|
|
16
|
+
| Metric | Before | After improvements | Change |
|
|
17
|
+
|--------|--------|-------------------|--------|
|
|
18
|
+
| Matched | 126/188 | **130/188** | +4 |
|
|
19
|
+
| rect | -460 | **-460** | — |
|
|
20
|
+
| path | -455 | **-92** | +363 recovered |
|
|
21
|
+
| polygon | +27 | **+27** | — |
|
|
22
|
+
| text | -519 | **-519** | — |
|
|
23
|
+
|
|
24
|
+
Key improvements this session:
|
|
25
|
+
- Horizontal-tree-routed arrow suppression (narrower check)
|
|
26
|
+
- Marker dedup changed to polygon-only (never dedup arrows)
|
|
27
|
+
→ recovered ~200 association arrow paths on plateau
|
|
28
|
+
|
|
29
|
+
## Current state — Plateau XMI (~/src/mn/)
|
|
30
|
+
|
|
31
|
+
| Metric | Value |
|
|
32
|
+
|--------|-------|
|
|
33
|
+
| Diagrams matched (tolerance ≤5) | 127/185 |
|
|
34
|
+
| rect delta | -221 (-11.0%) |
|
|
35
|
+
| path delta | -338 (-10.2%) |
|
|
36
|
+
| polygon delta | -6 (-0.6%) |
|
|
37
|
+
| text delta | +97 (+0.6%) |
|
|
38
|
+
|
|
39
|
+
## Where the deltas come from
|
|
40
|
+
|
|
41
|
+
### rect -460 (QEA) / -221 (XMI)
|
|
42
|
+
- Missing visibility icons (2 rects per attribute × many elements)
|
|
43
|
+
- Package-content child rows missing on some diagrams
|
|
44
|
+
- Element shape encoding (rect vs polygon)
|
|
45
|
+
|
|
46
|
+
### path -455 (QEA) / -338 (XMI)
|
|
47
|
+
- Connector arrow markers (tree-routed suppression removes some)
|
|
48
|
+
- Visibility icon paths (7 per attr × many elements)
|
|
49
|
+
- Connector routing encoding differences
|
|
50
|
+
|
|
51
|
+
### text -519 (QEA) / +97 (XMI)
|
|
52
|
+
- QEA has richer data (RunState, more tagged values) but some
|
|
53
|
+
texts are not rendered (instance labels, slot values)
|
|
54
|
+
- XMI over-renders some texts (from InstanceSpecification parsing)
|
|
55
|
+
|
|
56
|
+
## Plan
|
|
57
|
+
|
|
58
|
+
Each delta spans dozens of diagrams. Improvements require broad
|
|
59
|
+
pipeline changes rather than single-diagram fixes.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# TODO-D 62: Ghost element rendering (off-canvas connector endpoints)
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
EA phantom-renders classifier names near connector endpoints that
|
|
6
|
+
reference elements NOT placed on the current diagram. These "ghost
|
|
7
|
+
elements" appear as italic class names (e.g. `_CityObject`,
|
|
8
|
+
`_Site`, `_Geometry`) at the connector's off-canvas end. They are
|
|
9
|
+
NOT in `t_diagramobjects` for the diagram but ARE referenced by
|
|
10
|
+
`t_connector.Start_Object_ID` / `End_Object_ID` of connectors
|
|
11
|
+
that ARE on the diagram.
|
|
12
|
+
|
|
13
|
+
## Evidence (plateau QEA, "indoor" diagram)
|
|
14
|
+
|
|
15
|
+
- `_CityObject` does not appear in `t_diagramobjects` for the
|
|
16
|
+
indoor diagram.
|
|
17
|
+
- It IS referenced by connectors on the indoor diagram (e.g.
|
|
18
|
+
generalizations from `Room` to `_CityObject`).
|
|
19
|
+
- EA renders the name as 5+ separate italic `<text>` elements at
|
|
20
|
+
different positions, one per connector endpoint.
|
|
21
|
+
|
|
22
|
+
## Approach
|
|
23
|
+
|
|
24
|
+
1. **Source side**: in `DiagramBuilder`, walk every renderable
|
|
25
|
+
connector and look up its source/target object via
|
|
26
|
+
`database.find_connector` → `start_object_id`/`end_object_id` →
|
|
27
|
+
`database.find_object`. When the object is NOT placed on this
|
|
28
|
+
diagram (no entry in `t_diagramobjects`), synthesise a
|
|
29
|
+
"ghost element" annotation on the connector: the off-canvas
|
|
30
|
+
end's classifier name + a virtual anchor position (probably
|
|
31
|
+
the on-canvas endpoint).
|
|
32
|
+
|
|
33
|
+
2. **Model side**: add `ghost_labels` to `DiagramConnector` —
|
|
34
|
+
a collection of `(name, end_kind, anchor_offset)` tuples.
|
|
35
|
+
|
|
36
|
+
3. **Renderer side**: emit each ghost label as an italic `<text>`
|
|
37
|
+
at the connector's endpoint, offset to one side. Match EA's
|
|
38
|
+
offset rules (need to reverse-engineer from reference SVGs).
|
|
39
|
+
|
|
40
|
+
## Impact
|
|
41
|
+
|
|
42
|
+
Closing the text gap from -292 to near 0 on plateau QEA. Most of
|
|
43
|
+
the missing text delta comes from ghost labels:
|
|
44
|
+
- indoor: -17 (mostly `_CityObject`)
|
|
45
|
+
- frn_1: -7
|
|
46
|
+
- cons_1: -6
|
|
47
|
+
- tran_2: -5
|
|
48
|
+
- bldg_1: -6 (BuildingAttribute)
|
|
49
|
+
- and 10+ more diagrams with -1 to -5 each.
|
|
50
|
+
|
|
51
|
+
Combined: ~80-100 missing ghost labels across the plateau.
|
|
52
|
+
|
|
53
|
+
## Related
|
|
54
|
+
|
|
55
|
+
- TODO-D 26 (Investigate phantom class headers from connector
|
|
56
|
+
endpoints) is the older writeup of the same issue.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# TODO-D 63: Qualified-name line wrap for long class names
|
|
2
|
+
|
|
3
|
+
## Status: completed
|
|
4
|
+
|
|
5
|
+
EA wraps long qualified class names (e.g. `brid::OuterFloorSurface`)
|
|
6
|
+
across TWO `<text>` elements when the rendered width exceeds the
|
|
7
|
+
element's header width.
|
|
8
|
+
|
|
9
|
+
## Implementation
|
|
10
|
+
|
|
11
|
+
`Ea::Svg::EaEmitter::Element::HeaderLines.for` now accepts
|
|
12
|
+
`bounds_width:` and `font_size:` keyword args. When the qualified
|
|
13
|
+
name's estimated rendered width (using `TextRenderer.estimate_width`
|
|
14
|
+
with `width_factor=0.55` and `QUALIFIED_WRAP_PADDING=8`) exceeds
|
|
15
|
+
the element's bounds, the name splits into two header lines:
|
|
16
|
+
|
|
17
|
+
1. `"qualifier::"` (with trailing `::`)
|
|
18
|
+
2. `"ClassName"` (the base name after `::`)
|
|
19
|
+
|
|
20
|
+
The `Elements` orchestrator threads `raw_bounds.width` and the
|
|
21
|
+
resolved `font_size` through to `HeaderLines.for`.
|
|
22
|
+
|
|
23
|
+
## Results
|
|
24
|
+
|
|
25
|
+
- Plateau text delta: -3 → +5 (slight over-rendering on a few
|
|
26
|
+
borderline cases — both name+wrap and not-quite-fit names).
|
|
27
|
+
- 154/188 matched diagrams (unchanged).
|
|
28
|
+
- basic.qea, test.qea, simple.qea: unchanged.
|
|
29
|
+
|
|
30
|
+
## Tuning
|
|
31
|
+
|
|
32
|
+
Width factor 0.55 matches Carlito 9pt bold's average glyph advance
|
|
33
|
+
for the CJK + Latin mix on the plateau. The 8px padding accounts
|
|
34
|
+
for the element's internal left+right padding that EA reserves
|
|
35
|
+
around header text. Both constants are at the top of HeaderLines
|
|
36
|
+
for easy future adjustment if EA's font metrics shift.
|