@ -2,29 +2,29 @@ import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
||||
import { ServersComponent } from "./components/servers/servers.component";
|
||||
import { ProjectsComponent } from "./components/projects/projects.component";
|
||||
import { DefaultLayoutComponent } from "./layouts/default-layout/default-layout.component";
|
||||
import { SettingsComponent } from "./components/settings/settings.component";
|
||||
import { LocalServerComponent } from "./components/local-server/local-server.component";
|
||||
|
||||
import { ServersComponent } from './components/servers/servers.component';
|
||||
import { ProjectsComponent } from './components/projects/projects.component';
|
||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||
import { SettingsComponent } from './components/settings/settings.component';
|
||||
import { LocalServerComponent } from './components/local-server/local-server.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: DefaultLayoutComponent,
|
||||
{
|
||||
path: '',
|
||||
component: DefaultLayoutComponent,
|
||||
children: [
|
||||
{ path: '', redirectTo: 'servers', pathMatch: 'full'},
|
||||
{ path: '', redirectTo: 'servers', pathMatch: 'full' },
|
||||
{ path: 'servers', component: ServersComponent },
|
||||
{ path: 'local', component: LocalServerComponent },
|
||||
{ path: 'server/:server_id/projects', component: ProjectsComponent },
|
||||
{ path: 'settings', component: SettingsComponent },
|
||||
{ path: 'settings', component: SettingsComponent }
|
||||
]
|
||||
},
|
||||
{ path: 'server/:server_id/project/:project_id', component: ProjectMapComponent },
|
||||
{ path: 'server/:server_id/project/:project_id', component: ProjectMapComponent }
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule {}
|
||||
|
@ -1 +1 @@
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet></router-outlet>
|
||||
|
@ -2,13 +2,12 @@ import { TestBed, async, ComponentFixture } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { MatIconModule } from "@angular/material";
|
||||
import { SettingsService } from "./services/settings.service";
|
||||
import { PersistenceService } from "angular-persistence";
|
||||
import { ElectronService, NgxElectronModule } from "ngx-electron";
|
||||
import { MatIconModule } from '@angular/material';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
import { PersistenceService } from 'angular-persistence';
|
||||
import { ElectronService, NgxElectronModule } from 'ngx-electron';
|
||||
import createSpyObj = jasmine.createSpyObj;
|
||||
|
||||
|
||||
describe('AppComponent', () => {
|
||||
let component: AppComponent;
|
||||
let fixture: ComponentFixture<AppComponent>;
|
||||
@ -17,18 +16,9 @@ describe('AppComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
RouterTestingModule,
|
||||
MatIconModule,
|
||||
NgxElectronModule
|
||||
],
|
||||
providers: [
|
||||
SettingsService,
|
||||
PersistenceService,
|
||||
]
|
||||
declarations: [AppComponent],
|
||||
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
|
||||
providers: [SettingsService, PersistenceService]
|
||||
}).compileComponents();
|
||||
|
||||
electronService = TestBed.get(ElectronService);
|
||||
|
@ -1,30 +1,27 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatIconRegistry } from "@angular/material";
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { ElectronService } from "ngx-electron";
|
||||
import { SettingsService } from "./services/settings.service";
|
||||
|
||||
import { MatIconRegistry } from '@angular/material';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { ElectronService } from 'ngx-electron';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: [
|
||||
'./app.component.css'
|
||||
]
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
constructor(
|
||||
iconReg: MatIconRegistry,
|
||||
sanitizer: DomSanitizer,
|
||||
private settingsService: SettingsService,
|
||||
private electronService: ElectronService) {
|
||||
|
||||
iconReg.addSvgIcon('gns3', sanitizer.bypassSecurityTrustResourceUrl('./assets/gns3_icon.svg'));
|
||||
constructor(
|
||||
iconReg: MatIconRegistry,
|
||||
sanitizer: DomSanitizer,
|
||||
private settingsService: SettingsService,
|
||||
private electronService: ElectronService
|
||||
) {
|
||||
iconReg.addSvgIcon('gns3', sanitizer.bypassSecurityTrustResourceUrl('./assets/gns3_icon.svg'));
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.electronService.isElectronApp) {
|
||||
this.settingsService.subscribe((settings) => {
|
||||
this.settingsService.subscribe(settings => {
|
||||
this.electronService.ipcRenderer.send('settings.changed', settings);
|
||||
});
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import * as Raven from 'raven-js';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule, ErrorHandler } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CdkTableModule } from "@angular/cdk/table";
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
@ -16,20 +16,20 @@ import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
import { VersionService } from './services/version.service';
|
||||
import { ProjectService } from './services/project.service';
|
||||
import { SymbolService } from "./services/symbol.service";
|
||||
import { ServerService } from "./services/server.service";
|
||||
import { IndexedDbService } from "./services/indexed-db.service";
|
||||
import { HttpServer, ServerErrorHandler } from "./services/http-server.service";
|
||||
import { SnapshotService } from "./services/snapshot.service";
|
||||
import { ProgressDialogService } from "./common/progress-dialog/progress-dialog.service";
|
||||
import { NodeService } from "./services/node.service";
|
||||
import { TemplateService } from "./services/template.service";
|
||||
import { LinkService } from "./services/link.service";
|
||||
import { SymbolService } from './services/symbol.service';
|
||||
import { ServerService } from './services/server.service';
|
||||
import { IndexedDbService } from './services/indexed-db.service';
|
||||
import { HttpServer, ServerErrorHandler } from './services/http-server.service';
|
||||
import { SnapshotService } from './services/snapshot.service';
|
||||
import { ProgressDialogService } from './common/progress-dialog/progress-dialog.service';
|
||||
import { NodeService } from './services/node.service';
|
||||
import { TemplateService } from './services/template.service';
|
||||
import { LinkService } from './services/link.service';
|
||||
|
||||
import { ProjectsComponent } from './components/projects/projects.component';
|
||||
import { AddBlankProjectDialogComponent } from './components/projects/add-blank-project-dialog/add-blank-project-dialog.component';
|
||||
import { ImportProjectDialogComponent } from './components/projects/import-project-dialog/import-project-dialog.component';
|
||||
import { ConfirmationDialogComponent} from './components/projects/confirmation-dialog/confirmation-dialog.component';
|
||||
import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-dialog.component';
|
||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||
import { ProgressDialogComponent } from './common/progress-dialog/progress-dialog.component';
|
||||
import { AppComponent } from './app.component';
|
||||
@ -43,28 +43,28 @@ import { TemplateComponent } from './components/template/template.component';
|
||||
import { TemplateListDialogComponent } from './components/template/template-list-dialog/template-list-dialog.component';
|
||||
import { CartographyModule } from './cartography/cartography.module';
|
||||
import { ToasterService } from './services/toaster.service';
|
||||
import { ProjectWebServiceHandler } from "./handlers/project-web-service-handler";
|
||||
import { LinksDataSource } from "./cartography/datasources/links-datasource";
|
||||
import { NodesDataSource } from "./cartography/datasources/nodes-datasource";
|
||||
import { SymbolsDataSource } from "./cartography/datasources/symbols-datasource";
|
||||
import { SelectionManager } from "./cartography/managers/selection-manager";
|
||||
import { InRectangleHelper } from "./cartography/helpers/in-rectangle-helper";
|
||||
import { DrawingsDataSource } from "./cartography/datasources/drawings-datasource";
|
||||
import { ProjectWebServiceHandler } from './handlers/project-web-service-handler';
|
||||
import { LinksDataSource } from './cartography/datasources/links-datasource';
|
||||
import { NodesDataSource } from './cartography/datasources/nodes-datasource';
|
||||
import { SymbolsDataSource } from './cartography/datasources/symbols-datasource';
|
||||
import { SelectionManager } from './cartography/managers/selection-manager';
|
||||
import { InRectangleHelper } from './cartography/helpers/in-rectangle-helper';
|
||||
import { DrawingsDataSource } from './cartography/datasources/drawings-datasource';
|
||||
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
||||
import { MoveLayerDownActionComponent } from './components/project-map/context-menu/actions/move-layer-down-action/move-layer-down-action.component';
|
||||
import { MoveLayerUpActionComponent } from './components/project-map/context-menu/actions/move-layer-up-action/move-layer-up-action.component';
|
||||
import { ProjectMapShortcutsComponent } from './components/project-map/project-map-shortcuts/project-map-shortcuts.component';
|
||||
import { SettingsComponent } from './components/settings/settings.component';
|
||||
import { SettingsService } from "./services/settings.service";
|
||||
import { SettingsService } from './services/settings.service';
|
||||
|
||||
import { LocalServerComponent } from './components/local-server/local-server.component';
|
||||
import { ProgressComponent } from './common/progress/progress.component';
|
||||
import { ProgressService } from "./common/progress/progress.service";
|
||||
import { version } from "./version";
|
||||
import { ToasterErrorHandler } from "./common/error-handlers/toaster-error-handler";
|
||||
import { environment } from "../environments/environment";
|
||||
import { RavenState } from "./common/error-handlers/raven-state-communicator";
|
||||
import { ServerDiscoveryComponent } from "./components/servers/server-discovery/server-discovery.component";
|
||||
import { ProgressService } from './common/progress/progress.service';
|
||||
import { version } from './version';
|
||||
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
||||
import { environment } from '../environments/environment';
|
||||
import { RavenState } from './common/error-handlers/raven-state-communicator';
|
||||
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
||||
import { ServerDatabase } from './services/server.database';
|
||||
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
||||
import { SnapshotsComponent } from './components/snapshots/snapshots.component';
|
||||
@ -89,19 +89,15 @@ import { StyleEditorDialogComponent } from './components/project-map/drawings-ed
|
||||
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
||||
import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component';
|
||||
|
||||
|
||||
if (environment.production) {
|
||||
Raven
|
||||
.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
shouldSendCallback: () => {
|
||||
return RavenState.shouldSend;
|
||||
},
|
||||
release: version
|
||||
})
|
||||
.install();
|
||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
shouldSendCallback: () => {
|
||||
return RavenState.shouldSend;
|
||||
},
|
||||
release: version
|
||||
}).install();
|
||||
}
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
@ -202,6 +198,6 @@ if (environment.production) {
|
||||
StyleEditorDialogComponent,
|
||||
TextEditorDialogComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
export class AppModule {}
|
||||
|
@ -11,18 +11,17 @@ import { InterfaceLabelComponent } from './components/experimental-map/interface
|
||||
import { DraggableComponent } from './components/experimental-map/draggable/draggable.component';
|
||||
import { SelectionComponent } from './components/experimental-map/selection/selection.component';
|
||||
|
||||
|
||||
export const ANGULAR_MAP_DECLARATIONS = [
|
||||
NodeComponent,
|
||||
LinkComponent,
|
||||
StatusComponent,
|
||||
DrawingComponent,
|
||||
EllipseComponent,
|
||||
ImageComponent,
|
||||
LineComponent,
|
||||
RectComponent,
|
||||
TextComponent,
|
||||
DraggableComponent,
|
||||
SelectionComponent,
|
||||
InterfaceLabelComponent
|
||||
NodeComponent,
|
||||
LinkComponent,
|
||||
StatusComponent,
|
||||
DrawingComponent,
|
||||
EllipseComponent,
|
||||
ImageComponent,
|
||||
LineComponent,
|
||||
RectComponent,
|
||||
TextComponent,
|
||||
DraggableComponent,
|
||||
SelectionComponent,
|
||||
InterfaceLabelComponent
|
||||
];
|
||||
|
@ -32,7 +32,12 @@ import { PortToMapPortConverter } from './converters/map/port-to-map-port-conver
|
||||
import { SymbolToMapSymbolConverter } from './converters/map/symbol-to-map-symbol-converter';
|
||||
import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter';
|
||||
import { GraphDataManager } from './managers/graph-data-manager';
|
||||
import { MapNodesDataSource, MapLinksDataSource, MapDrawingsDataSource, MapSymbolsDataSource } from './datasources/map-datasource';
|
||||
import {
|
||||
MapNodesDataSource,
|
||||
MapLinksDataSource,
|
||||
MapDrawingsDataSource,
|
||||
MapSymbolsDataSource
|
||||
} from './datasources/map-datasource';
|
||||
import { LinksEventSource } from './events/links-event-source';
|
||||
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
||||
import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component';
|
||||
@ -51,13 +56,8 @@ import { LineElementFactory } from './helpers/drawings-factory/line-element-fact
|
||||
import { TextEditorComponent } from './components/text-editor/text-editor.component';
|
||||
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatMenuModule,
|
||||
MatIconModule
|
||||
],
|
||||
imports: [CommonModule, MatMenuModule, MatIconModule],
|
||||
declarations: [
|
||||
D3MapComponent,
|
||||
ExperimentalMapComponent,
|
||||
@ -113,6 +113,6 @@ import { DrawingAddingComponent } from './components/drawing-adding/drawing-addi
|
||||
StylesToFontConverter,
|
||||
...D3_MAP_IMPORTS
|
||||
],
|
||||
exports: [ D3MapComponent, ExperimentalMapComponent ]
|
||||
exports: [D3MapComponent, ExperimentalMapComponent]
|
||||
})
|
||||
export class CartographyModule { }
|
||||
export class CartographyModule {}
|
||||
|
@ -1,11 +1,5 @@
|
||||
<svg
|
||||
#svg
|
||||
class="map"
|
||||
preserveAspectRatio="none"
|
||||
>
|
||||
<filter id="grayscale">
|
||||
<feColorMatrix id="feGrayscale" type="saturate" values="0"/>
|
||||
</filter>
|
||||
<svg #svg class="map" preserveAspectRatio="none">
|
||||
<filter id="grayscale"><feColorMatrix id="feGrayscale" type="saturate" values="0" /></filter>
|
||||
</svg>
|
||||
|
||||
<app-drawing-adding [svg]="svg"></app-drawing-adding>
|
||||
|
Before Width: | Height: | Size: 486 B After Width: | Height: | Size: 472 B |
@ -1,5 +1,3 @@
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,9 +8,8 @@ describe('D3MapComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ D3MapComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [D3MapComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
// beforeEach(() => {
|
||||
|
@ -1,11 +1,21 @@
|
||||
import {
|
||||
Component, ElementRef, HostListener, Input, OnChanges, OnDestroy, OnInit, SimpleChange, EventEmitter, Output, ViewChild
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
SimpleChange,
|
||||
EventEmitter,
|
||||
Output,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { Selection, select } from 'd3-selection';
|
||||
|
||||
import { GraphLayout } from "../../widgets/graph-layout";
|
||||
import { Context } from "../../models/context";
|
||||
import { Size } from "../../models/size";
|
||||
import { GraphLayout } from '../../widgets/graph-layout';
|
||||
import { Context } from '../../models/context';
|
||||
import { Size } from '../../models/size';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||
import { SelectionTool } from '../../tools/selection-tool';
|
||||
@ -22,7 +32,6 @@ import { Server } from '../../../models/server';
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
import { TextEditorComponent } from '../text-editor/text-editor.component';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-d3-map',
|
||||
templateUrl: './d3-map.component.html',
|
||||
@ -50,7 +59,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private drawLinkTool: boolean;
|
||||
|
||||
protected settings = {
|
||||
'show_interface_labels': true
|
||||
show_interface_labels: true
|
||||
};
|
||||
|
||||
constructor(
|
||||
@ -65,11 +74,11 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
protected movingToolWidget: MovingTool,
|
||||
public graphLayout: GraphLayout,
|
||||
private toolsService: ToolsService
|
||||
) {
|
||||
) {
|
||||
this.parentNativeElement = element.nativeElement;
|
||||
}
|
||||
|
||||
@Input('show-interface-labels')
|
||||
@Input('show-interface-labels')
|
||||
set showInterfaceLabels(value) {
|
||||
this.settings.show_interface_labels = value;
|
||||
this.interfaceLabelWidget.setEnabled(value);
|
||||
@ -79,7 +88,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input('readonly') set readonly(value) {
|
||||
this.mapSettings.isReadOnly = value;
|
||||
}
|
||||
|
||||
|
||||
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
|
||||
if (
|
||||
(changes['width'] && !changes['width'].isFirstChange()) ||
|
||||
@ -142,7 +151,10 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
public createGraph(domElement: HTMLElement) {
|
||||
const rootElement = select(domElement);
|
||||
this.svg = rootElement.select<SVGSVGElement>('svg');
|
||||
this.graphLayout.connect(this.svg, this.context);
|
||||
this.graphLayout.connect(
|
||||
this.svg,
|
||||
this.context
|
||||
);
|
||||
this.graphLayout.draw(this.svg, this.context);
|
||||
this.mapChangeDetectorRef.hasBeenDrawn = true;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import { MapLinkNode } from '../../models/map/map-link-node';
|
||||
import { select } from 'd3-selection';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
|
||||
|
||||
describe('DraggableSelectionComponent', () => {
|
||||
let component: DraggableSelectionComponent;
|
||||
let fixture: ComponentFixture<DraggableSelectionComponent>;
|
||||
@ -62,7 +61,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
interfaceLabelDragEventEmitter = new EventEmitter<DraggableDrag<MapLinkNode>>();
|
||||
interfaceLabelEndEventEmitter = new EventEmitter<DraggableEnd<MapLinkNode>>();
|
||||
|
||||
const nodesWidgetStub = {
|
||||
const nodesWidgetStub = {
|
||||
redrawNode: () => {},
|
||||
draggable: {
|
||||
start: nodesStartEventEmitter,
|
||||
@ -71,7 +70,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const drawingsWidgetStub = {
|
||||
const drawingsWidgetStub = {
|
||||
redrawDrawing: () => {},
|
||||
draggable: {
|
||||
start: drawingsStartEventEmitter,
|
||||
@ -80,7 +79,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
}
|
||||
};
|
||||
const linksWidgetStub = {
|
||||
redrawLink: () => {},
|
||||
redrawLink: () => {}
|
||||
};
|
||||
|
||||
const labelWidgetStub = {
|
||||
@ -91,7 +90,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
end: labelEndEventEmitter
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const interfaceLabelWidgetStub = {
|
||||
draggable: {
|
||||
start: interfaceLabelStartEventEmitter,
|
||||
@ -101,14 +100,14 @@ describe('DraggableSelectionComponent', () => {
|
||||
};
|
||||
|
||||
const nodesEventSourceStub = {
|
||||
dragged: { emit: () => {}},
|
||||
labelDragged: { emit: () => {}}
|
||||
dragged: { emit: () => {} },
|
||||
labelDragged: { emit: () => {} }
|
||||
};
|
||||
const drawingsEventSourceStub = {
|
||||
dragged: { emit: () => {}}
|
||||
dragged: { emit: () => {} }
|
||||
};
|
||||
const linksEventSourceStub = {
|
||||
interfaceDragged: { emit: () => {}}
|
||||
interfaceDragged: { emit: () => {} }
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
@ -122,11 +121,10 @@ describe('DraggableSelectionComponent', () => {
|
||||
{ provide: NodesEventSource, useValue: nodesEventSourceStub },
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSourceStub },
|
||||
{ provide: GraphDataManager, useValue: mockedGraphDataManager },
|
||||
{ provide: LinksEventSource, useValue: linksEventSourceStub },
|
||||
{ provide: LinksEventSource, useValue: linksEventSourceStub }
|
||||
],
|
||||
declarations: [ DraggableSelectionComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [DraggableSelectionComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
@ -151,7 +149,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
linksWidgetStub = fixture.debugElement.injector.get(LinksWidget);
|
||||
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||
node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
node.x = 1;
|
||||
node.y = 2;
|
||||
});
|
||||
@ -237,7 +235,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
drawingsWidgetStub = fixture.debugElement.injector.get(DrawingsWidget);
|
||||
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||
drawing = new MapDrawing();
|
||||
drawing.id = "drawingid";
|
||||
drawing.id = 'drawingid';
|
||||
drawing.x = 1;
|
||||
drawing.y = 2;
|
||||
});
|
||||
@ -297,7 +295,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
labelWidgetStub = fixture.debugElement.injector.get(LabelWidget);
|
||||
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||
label = new MapLabel();
|
||||
label.id = "labelid";
|
||||
label.id = 'labelid';
|
||||
label.x = 1;
|
||||
label.y = 2;
|
||||
});
|
||||
@ -319,7 +317,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
spyOn(labelWidgetStub, 'redrawLabel');
|
||||
selectionManagerStub.setSelected([label]);
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
node.label = label;
|
||||
label.nodeId = node.id;
|
||||
|
||||
@ -339,7 +337,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
it('should not update label position when dragging and parent is selected', fakeAsync(() => {
|
||||
spyOn(labelWidgetStub, 'redrawLabel');
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
node.label = label;
|
||||
label.nodeId = node.id;
|
||||
|
||||
@ -357,7 +355,6 @@ describe('DraggableSelectionComponent', () => {
|
||||
expect(label.y).toEqual(2);
|
||||
}));
|
||||
|
||||
|
||||
it('should emit event when label stopped dragging', fakeAsync(() => {
|
||||
const nodesEventSourceStub = fixture.debugElement.injector.get(NodesEventSource);
|
||||
const spyDragged = spyOn(nodesEventSourceStub.labelDragged, 'emit');
|
||||
@ -379,7 +376,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
const nodesEventSourceStub = fixture.debugElement.injector.get(NodesEventSource);
|
||||
spyOn(nodesEventSourceStub.labelDragged, 'emit');
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
label.nodeId = node.id;
|
||||
|
||||
selectionManagerStub.setSelected([label, node]);
|
||||
@ -407,7 +404,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
linkNode.label = new MapLabel();
|
||||
linkNode.label.x = 1;
|
||||
linkNode.label.y = 2;
|
||||
linkNode.id = "linknodeid";
|
||||
linkNode.id = 'linknodeid';
|
||||
});
|
||||
|
||||
it('should select interface label when started dragging', fakeAsync(() => {
|
||||
@ -427,14 +424,14 @@ describe('DraggableSelectionComponent', () => {
|
||||
spyOn(linksWidgetStub, 'redrawLink');
|
||||
selectionManagerStub.setSelected([linkNode]);
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
linkNode.nodeId = node.id;
|
||||
|
||||
const secondLinkNode = new MapLinkNode();
|
||||
secondLinkNode.label = new MapLabel();
|
||||
secondLinkNode.label.x = 1;
|
||||
secondLinkNode.label.y = 2;
|
||||
secondLinkNode.id = "secondlinknodeid";
|
||||
secondLinkNode.id = 'secondlinknodeid';
|
||||
|
||||
const link = new MapLink();
|
||||
link.nodes = [linkNode, secondLinkNode];
|
||||
@ -456,14 +453,14 @@ describe('DraggableSelectionComponent', () => {
|
||||
spyOn(linksWidgetStub, 'redrawLink');
|
||||
selectionManagerStub.setSelected([linkNode]);
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
linkNode.nodeId = node.id;
|
||||
|
||||
const secondLinkNode = new MapLinkNode();
|
||||
secondLinkNode.label = new MapLabel();
|
||||
secondLinkNode.label.x = 1;
|
||||
secondLinkNode.label.y = 2;
|
||||
secondLinkNode.id = "secondlinknodeid";
|
||||
secondLinkNode.id = 'secondlinknodeid';
|
||||
|
||||
const link = new MapLink();
|
||||
link.nodes = [secondLinkNode, linkNode];
|
||||
@ -484,7 +481,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
it('should not update interface label position when dragging and parent node is selected', fakeAsync(() => {
|
||||
spyOn(linksWidgetStub, 'redrawLink');
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
linkNode.nodeId = node.id;
|
||||
|
||||
selectionManagerStub.setSelected([linkNode, node]);
|
||||
@ -493,7 +490,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
secondLinkNode.label = new MapLabel();
|
||||
secondLinkNode.label.x = 1;
|
||||
secondLinkNode.label.y = 2;
|
||||
secondLinkNode.id = "secondlinknodeid";
|
||||
secondLinkNode.id = 'secondlinknodeid';
|
||||
|
||||
const link = new MapLink();
|
||||
link.nodes = [linkNode, secondLinkNode];
|
||||
@ -533,7 +530,7 @@ describe('DraggableSelectionComponent', () => {
|
||||
spyOn(linksEventSourceStub.interfaceDragged, 'emit');
|
||||
|
||||
const node = new MapNode();
|
||||
node.id = "nodeid";
|
||||
node.id = 'nodeid';
|
||||
linkNode.nodeId = node.id;
|
||||
|
||||
selectionManagerStub.setSelected([linkNode, node]);
|
||||
|
@ -27,7 +27,7 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
private start: Subscription;
|
||||
private drag: Subscription;
|
||||
private end: Subscription;
|
||||
|
||||
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
|
||||
constructor(
|
||||
@ -41,7 +41,7 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private graphDataManager: GraphDataManager,
|
||||
private linksEventSource: LinksEventSource
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const svg = select(this.svg);
|
||||
@ -54,25 +54,25 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
).subscribe((evt: DraggableStart<any>) => {
|
||||
const selected = this.selectionManager.getSelected();
|
||||
if (evt.datum instanceof MapNode) {
|
||||
if (selected.filter((item) => item instanceof MapNode && item.id === evt.datum.id).length === 0) {
|
||||
if (selected.filter(item => item instanceof MapNode && item.id === evt.datum.id).length === 0) {
|
||||
this.selectionManager.setSelected([evt.datum]);
|
||||
}
|
||||
}
|
||||
|
||||
if (evt.datum instanceof MapDrawing) {
|
||||
if (selected.filter((item) => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) {
|
||||
if (selected.filter(item => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) {
|
||||
this.selectionManager.setSelected([evt.datum]);
|
||||
}
|
||||
}
|
||||
|
||||
if (evt.datum instanceof MapLabel) {
|
||||
if (selected.filter((item) => item instanceof MapLabel && item.id === evt.datum.id).length === 0) {
|
||||
if (selected.filter(item => item instanceof MapLabel && item.id === evt.datum.id).length === 0) {
|
||||
this.selectionManager.setSelected([evt.datum]);
|
||||
}
|
||||
}
|
||||
|
||||
if (evt.datum instanceof MapLinkNode) {
|
||||
if (selected.filter((item) => item instanceof MapLinkNode && item.id === evt.datum.id).length === 0) {
|
||||
if (selected.filter(item => item instanceof MapLinkNode && item.id === evt.datum.id).length === 0) {
|
||||
this.selectionManager.setSelected([evt.datum]);
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
this.interfaceWidget.draggable.drag
|
||||
).subscribe((evt: DraggableDrag<any>) => {
|
||||
const selected = this.selectionManager.getSelected();
|
||||
const selectedNodes = selected.filter((item) => item instanceof MapNode);
|
||||
const selectedNodes = selected.filter(item => item instanceof MapNode);
|
||||
// update nodes
|
||||
selectedNodes.forEach((node: MapNode) => {
|
||||
node.x += evt.dx;
|
||||
@ -93,54 +93,66 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.nodesWidget.redrawNode(svg, node);
|
||||
|
||||
const links = this.graphDataManager.getLinks().filter(
|
||||
(link) => (link.target !== undefined && link.target.id === node.id) || (link.source !== undefined && link.source.id === node.id));
|
||||
|
||||
links.forEach((link) => {
|
||||
const links = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(
|
||||
link =>
|
||||
(link.target !== undefined && link.target.id === node.id) ||
|
||||
(link.source !== undefined && link.source.id === node.id)
|
||||
);
|
||||
|
||||
links.forEach(link => {
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
});
|
||||
|
||||
// update drawings
|
||||
selected.filter((item) => item instanceof MapDrawing).forEach((drawing: MapDrawing) => {
|
||||
drawing.x += evt.dx;
|
||||
drawing.y += evt.dy;
|
||||
this.drawingsWidget.redrawDrawing(svg, drawing);
|
||||
});
|
||||
selected
|
||||
.filter(item => item instanceof MapDrawing)
|
||||
.forEach((drawing: MapDrawing) => {
|
||||
drawing.x += evt.dx;
|
||||
drawing.y += evt.dy;
|
||||
this.drawingsWidget.redrawDrawing(svg, drawing);
|
||||
});
|
||||
|
||||
// update labels
|
||||
selected.filter((item) => item instanceof MapLabel).forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
selected
|
||||
.filter(item => item instanceof MapLabel)
|
||||
.forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.graphDataManager.getNodes().filter((node) => node.id === label.nodeId)[0];
|
||||
node.label.x += evt.dx;
|
||||
node.label.y += evt.dy;
|
||||
this.labelWidget.redrawLabel(svg, label);
|
||||
});
|
||||
const node = this.graphDataManager.getNodes().filter(node => node.id === label.nodeId)[0];
|
||||
node.label.x += evt.dx;
|
||||
node.label.y += evt.dy;
|
||||
this.labelWidget.redrawLabel(svg, label);
|
||||
});
|
||||
|
||||
// update interface labels
|
||||
selected.filter((item) => item instanceof MapLinkNode).forEach((interfaceLabel: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === interfaceLabel.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
selected
|
||||
.filter(item => item instanceof MapLinkNode)
|
||||
.forEach((interfaceLabel: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === interfaceLabel.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const link = this.graphDataManager.getLinks().filter((link) => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0];
|
||||
if(link.nodes[0].id === interfaceLabel.id) {
|
||||
link.nodes[0].label.x += evt.dx;
|
||||
link.nodes[0].label.y += evt.dy;
|
||||
}
|
||||
if(link.nodes[1].id === interfaceLabel.id) {
|
||||
link.nodes[1].label.x += evt.dx;
|
||||
link.nodes[1].label.y += evt.dy;
|
||||
}
|
||||
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
const link = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(link => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0];
|
||||
if (link.nodes[0].id === interfaceLabel.id) {
|
||||
link.nodes[0].label.x += evt.dx;
|
||||
link.nodes[0].label.y += evt.dy;
|
||||
}
|
||||
if (link.nodes[1].id === interfaceLabel.id) {
|
||||
link.nodes[1].label.x += evt.dx;
|
||||
link.nodes[1].label.y += evt.dy;
|
||||
}
|
||||
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
});
|
||||
|
||||
this.end = merge(
|
||||
@ -150,35 +162,39 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
this.interfaceWidget.draggable.end
|
||||
).subscribe((evt: DraggableEnd<any>) => {
|
||||
const selected = this.selectionManager.getSelected();
|
||||
const selectedNodes = selected.filter((item) => item instanceof MapNode);
|
||||
const selectedNodes = selected.filter(item => item instanceof MapNode);
|
||||
|
||||
selectedNodes.forEach((item: MapNode) => {
|
||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(item, evt.dx, evt.dy));
|
||||
})
|
||||
|
||||
selected.filter((item) => item instanceof MapDrawing).forEach((item: MapDrawing) => {
|
||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
||||
});
|
||||
|
||||
selected.filter((item) => item instanceof MapLabel).forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
selected
|
||||
.filter(item => item instanceof MapDrawing)
|
||||
.forEach((item: MapDrawing) => {
|
||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
||||
});
|
||||
|
||||
this.nodesEventSource.labelDragged.emit(new DraggedDataEvent<MapLabel>(label, evt.dx, evt.dy));
|
||||
});
|
||||
selected
|
||||
.filter(item => item instanceof MapLabel)
|
||||
.forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
selected.filter((item) => item instanceof MapLinkNode).forEach((label: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
this.linksEventSource.interfaceDragged.emit(new DraggedDataEvent<MapLinkNode>(label, evt.dx, evt.dy));
|
||||
});
|
||||
this.nodesEventSource.labelDragged.emit(new DraggedDataEvent<MapLabel>(label, evt.dx, evt.dy));
|
||||
});
|
||||
|
||||
selected
|
||||
.filter(item => item instanceof MapLinkNode)
|
||||
.forEach((label: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
this.linksEventSource.interfaceDragged.emit(new DraggedDataEvent<MapLinkNode>(label, evt.dx, evt.dy));
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@ -186,5 +202,4 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
this.drag.unsubscribe();
|
||||
this.end.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,53 +1,48 @@
|
||||
import { DrawingAddingComponent } from "./drawing-adding.component";
|
||||
import { DrawingAddingComponent } from './drawing-adding.component';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { Context } from '../../models/context';
|
||||
|
||||
describe('DrawingAddingComponent', () => {
|
||||
let component: DrawingAddingComponent;
|
||||
let fixture: ComponentFixture<DrawingAddingComponent>;
|
||||
let drawingsEventSource = new DrawingsEventSource();
|
||||
let component: DrawingAddingComponent;
|
||||
let fixture: ComponentFixture<DrawingAddingComponent>;
|
||||
let drawingsEventSource = new DrawingsEventSource();
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
NoopAnimationsModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||
{ provide: Context, useClass: Context }
|
||||
],
|
||||
declarations: [
|
||||
DrawingAddingComponent
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||
{ provide: Context, useClass: Context }
|
||||
],
|
||||
declarations: [DrawingAddingComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DrawingAddingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DrawingAddingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should deactivate listener when none of the available drawings is selected', () => {
|
||||
spyOn(component, 'deactivate');
|
||||
it('should deactivate listener when none of the available drawings is selected', () => {
|
||||
spyOn(component, 'deactivate');
|
||||
|
||||
drawingsEventSource.selected.emit("");
|
||||
drawingsEventSource.selected.emit('');
|
||||
|
||||
expect(component.deactivate).toHaveBeenCalled();
|
||||
});
|
||||
expect(component.deactivate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should activate listener when drawing is selected', () => {
|
||||
spyOn(component, 'activate');
|
||||
it('should activate listener when drawing is selected', () => {
|
||||
spyOn(component, 'activate');
|
||||
|
||||
drawingsEventSource.selected.emit("rectangle");
|
||||
drawingsEventSource.selected.emit('rectangle');
|
||||
|
||||
expect(component.activate).toHaveBeenCalled();
|
||||
});
|
||||
expect(component.activate).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -1,51 +1,47 @@
|
||||
import { Component, Input, OnDestroy, OnInit } from "@angular/core";
|
||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Context } from '../../models/context';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { AddedDataEvent } from '../../events/event-source';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawing-adding',
|
||||
templateUrl: './drawing-adding.component.html',
|
||||
styleUrls: ['./drawing-adding.component.scss']
|
||||
selector: 'app-drawing-adding',
|
||||
templateUrl: './drawing-adding.component.html',
|
||||
styleUrls: ['./drawing-adding.component.scss']
|
||||
})
|
||||
export class DrawingAddingComponent implements OnInit, OnDestroy {
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
|
||||
private mapListener: Function;
|
||||
private drawingSelected: Subscription;
|
||||
private mapListener: Function;
|
||||
private drawingSelected: Subscription;
|
||||
|
||||
constructor(
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private context: Context
|
||||
){}
|
||||
constructor(private drawingsEventSource: DrawingsEventSource, private context: Context) {}
|
||||
|
||||
ngOnInit(){
|
||||
this.drawingSelected = this.drawingsEventSource.selected.subscribe((evt) => {
|
||||
evt === "" ? this.deactivate() : this.activate();
|
||||
});
|
||||
}
|
||||
ngOnInit() {
|
||||
this.drawingSelected = this.drawingsEventSource.selected.subscribe(evt => {
|
||||
evt === '' ? this.deactivate() : this.activate();
|
||||
});
|
||||
}
|
||||
|
||||
activate(){
|
||||
let listener = (event: MouseEvent) => {
|
||||
let x = event.clientX - this.context.getZeroZeroTransformationPoint().x;
|
||||
let y = event.clientY - this.context.getZeroZeroTransformationPoint().y;
|
||||
|
||||
this.drawingsEventSource.pointToAddSelected.emit(new AddedDataEvent(x, y));
|
||||
this.deactivate();
|
||||
};
|
||||
activate() {
|
||||
let listener = (event: MouseEvent) => {
|
||||
let x = event.clientX - this.context.getZeroZeroTransformationPoint().x;
|
||||
let y = event.clientY - this.context.getZeroZeroTransformationPoint().y;
|
||||
|
||||
this.deactivate();
|
||||
this.mapListener = listener;
|
||||
this.svg.addEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
this.drawingsEventSource.pointToAddSelected.emit(new AddedDataEvent(x, y));
|
||||
this.deactivate();
|
||||
};
|
||||
|
||||
deactivate(){
|
||||
this.svg.removeEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
this.deactivate();
|
||||
this.mapListener = listener;
|
||||
this.svg.addEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
|
||||
ngOnDestroy(){
|
||||
this.drawingSelected.unsubscribe();
|
||||
}
|
||||
deactivate() {
|
||||
this.svg.removeEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.drawingSelected.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
|
||||
import { DrawingResizingComponent } from './drawing-resizing.component'
|
||||
import { DrawingResizingComponent } from './drawing-resizing.component';
|
||||
import { DrawingsWidget } from '../../widgets/drawings';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
@ -9,65 +9,60 @@ import { ResizingEnd } from '../../events/resizing';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
|
||||
export class DrawingWidgetMock {
|
||||
resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
|
||||
evt: any;
|
||||
constructor(){}
|
||||
resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
|
||||
evt: any;
|
||||
constructor() {}
|
||||
|
||||
emitEvent(){
|
||||
const evt = new ResizingEnd<MapDrawing>();
|
||||
evt.x = 0;
|
||||
evt.y = 0;
|
||||
evt.width = 10;
|
||||
evt.height = 10;
|
||||
evt.datum = {} as MapDrawing;
|
||||
emitEvent() {
|
||||
const evt = new ResizingEnd<MapDrawing>();
|
||||
evt.x = 0;
|
||||
evt.y = 0;
|
||||
evt.width = 10;
|
||||
evt.height = 10;
|
||||
evt.datum = {} as MapDrawing;
|
||||
|
||||
this.resizingFinished.emit(evt);
|
||||
}
|
||||
this.resizingFinished.emit(evt);
|
||||
}
|
||||
}
|
||||
|
||||
describe('DrawingResizingComponent', () => {
|
||||
let component: DrawingResizingComponent;
|
||||
let fixture: ComponentFixture<DrawingResizingComponent>;
|
||||
let drawingsWidgetMock = new DrawingWidgetMock;
|
||||
let drawingsEventSource = new DrawingsEventSource;
|
||||
let component: DrawingResizingComponent;
|
||||
let fixture: ComponentFixture<DrawingResizingComponent>;
|
||||
let drawingsWidgetMock = new DrawingWidgetMock();
|
||||
let drawingsEventSource = new DrawingsEventSource();
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
NoopAnimationsModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource}
|
||||
],
|
||||
declarations: [
|
||||
DrawingResizingComponent
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource }
|
||||
],
|
||||
declarations: [DrawingResizingComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DrawingResizingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DrawingResizingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should emit event after size changes', () => {
|
||||
spyOn(drawingsEventSource.resized, 'emit');
|
||||
const evt = new ResizingEnd<MapDrawing>();
|
||||
evt.x = 0;
|
||||
evt.y = 0;
|
||||
evt.width = 10;
|
||||
evt.height = 10;
|
||||
evt.datum = {} as MapDrawing;
|
||||
it('should emit event after size changes', () => {
|
||||
spyOn(drawingsEventSource.resized, 'emit');
|
||||
const evt = new ResizingEnd<MapDrawing>();
|
||||
evt.x = 0;
|
||||
evt.y = 0;
|
||||
evt.width = 10;
|
||||
evt.height = 10;
|
||||
evt.datum = {} as MapDrawing;
|
||||
|
||||
drawingsWidgetMock.emitEvent();
|
||||
drawingsWidgetMock.emitEvent();
|
||||
|
||||
expect(drawingsEventSource.resized.emit).toHaveBeenCalled();
|
||||
});
|
||||
expect(drawingsEventSource.resized.emit).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -6,27 +6,27 @@ import { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { ResizedDataEvent } from '../../events/event-source';
|
||||
import { ResizingEnd } from '../../events/resizing';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawing-resizing',
|
||||
template: `<ng-content></ng-content>`,
|
||||
styleUrls: ['./drawing-resizing.component.scss']
|
||||
selector: 'app-drawing-resizing',
|
||||
template: `
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
styleUrls: ['./drawing-resizing.component.scss']
|
||||
})
|
||||
export class DrawingResizingComponent implements OnInit, OnDestroy{
|
||||
resizingFinished: Subscription;
|
||||
export class DrawingResizingComponent implements OnInit, OnDestroy {
|
||||
resizingFinished: Subscription;
|
||||
|
||||
constructor(
|
||||
private drawingsWidget: DrawingsWidget,
|
||||
private drawingsEventSource: DrawingsEventSource
|
||||
) {}
|
||||
constructor(private drawingsWidget: DrawingsWidget, private drawingsEventSource: DrawingsEventSource) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.resizingFinished = this.drawingsWidget.resizingFinished.subscribe((evt: ResizingEnd<MapDrawing>) => {
|
||||
this.drawingsEventSource.resized.emit(new ResizedDataEvent<MapDrawing>(evt.datum, evt.x, evt.y, evt.width, evt.height));
|
||||
});
|
||||
}
|
||||
ngOnInit() {
|
||||
this.resizingFinished = this.drawingsWidget.resizingFinished.subscribe((evt: ResizingEnd<MapDrawing>) => {
|
||||
this.drawingsEventSource.resized.emit(
|
||||
new ResizedDataEvent<MapDrawing>(evt.datum, evt.x, evt.y, evt.width, evt.height)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.resizingFinished.unsubscribe();
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.resizingFinished.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,8 @@ describe('DraggableComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DraggableComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [DraggableComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -2,20 +2,15 @@ import { Component, OnInit, ElementRef, AfterViewInit, OnDestroy, Input, Output,
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Point } from '../../../models/point';
|
||||
|
||||
|
||||
export class DraggableDraggedEvent {
|
||||
constructor(
|
||||
public x: number,
|
||||
public y: number,
|
||||
public dx: number,
|
||||
public dy: number
|
||||
) {}
|
||||
constructor(public x: number, public y: number, public dx: number, public dy: number) {}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: '[app-draggable]',
|
||||
template:`<ng-content></ng-content>`,
|
||||
template: `
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
styleUrls: ['./draggable.component.scss']
|
||||
})
|
||||
export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@ -24,22 +19,21 @@ export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@Output() dragged = new EventEmitter<DraggableDraggedEvent>();
|
||||
|
||||
draggable: Subscription;
|
||||
|
||||
|
||||
private startX: number;
|
||||
private startY: number;
|
||||
|
||||
private posX: number;
|
||||
private posY: number;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
constructor(private elementRef: ElementRef) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
const down = Observable.fromEvent(this.elementRef.nativeElement, 'mousedown').do((e: MouseEvent) => e.preventDefault())
|
||||
const down = Observable.fromEvent(this.elementRef.nativeElement, 'mousedown').do((e: MouseEvent) =>
|
||||
e.preventDefault()
|
||||
);
|
||||
|
||||
down.subscribe((e: MouseEvent) => {
|
||||
this.posX = this.item.x;
|
||||
@ -49,45 +43,39 @@ export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.startY = e.clientY;
|
||||
});
|
||||
|
||||
const up = Observable
|
||||
.fromEvent(document, 'mouseup')
|
||||
.do((e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
const up = Observable.fromEvent(document, 'mouseup').do((e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
const mouseMove = Observable
|
||||
.fromEvent(document, 'mousemove')
|
||||
.do((e: MouseEvent) => e.stopPropagation());
|
||||
const mouseMove = Observable.fromEvent(document, 'mousemove').do((e: MouseEvent) => e.stopPropagation());
|
||||
|
||||
const scrollWindow = Observable
|
||||
.fromEvent(document, 'scroll')
|
||||
.startWith({});
|
||||
const scrollWindow = Observable.fromEvent(document, 'scroll').startWith({});
|
||||
|
||||
const move = Observable.combineLatest(mouseMove, scrollWindow);
|
||||
|
||||
const drag = down.mergeMap((md: MouseEvent) => {
|
||||
return move
|
||||
.map(([mm, s]) => mm)
|
||||
.do((mm: MouseEvent) => {
|
||||
const x = this.startX - mm.clientX;
|
||||
const y = this.startY - mm.clientY;
|
||||
.map(([mm, s]) => mm)
|
||||
.do((mm: MouseEvent) => {
|
||||
const x = this.startX - mm.clientX;
|
||||
const y = this.startY - mm.clientY;
|
||||
|
||||
this.item.x = Math.round(this.posX - x);
|
||||
this.item.y = Math.round(this.posY - y);
|
||||
this.dragging.emit(new DraggableDraggedEvent(this.item.x, this.item.y, -x, -y));
|
||||
})
|
||||
.skipUntil(
|
||||
up.take(1).do((e: MouseEvent) => {
|
||||
const x = this.startX - e.clientX;
|
||||
const y = this.startY - e.clientY;
|
||||
|
||||
this.item.x = Math.round(this.posX - x);
|
||||
this.item.y = Math.round(this.posY - y);
|
||||
this.dragging.emit(new DraggableDraggedEvent(this.item.x, this.item.y, -x, -y));
|
||||
})
|
||||
.skipUntil(up
|
||||
.take(1)
|
||||
.do((e: MouseEvent) => {
|
||||
const x = this.startX - e.clientX;
|
||||
const y = this.startY - e.clientY;
|
||||
|
||||
this.item.x = Math.round(this.posX - x);
|
||||
this.item.y = Math.round(this.posY - y);
|
||||
|
||||
this.dragged.emit(new DraggableDraggedEvent(this.item.x, this.item.y, -x, -y));
|
||||
}))
|
||||
.take(1);
|
||||
this.dragged.emit(new DraggableDraggedEvent(this.item.x, this.item.y, -x, -y));
|
||||
})
|
||||
)
|
||||
.take(1);
|
||||
});
|
||||
|
||||
this.draggable = drag.subscribe((e: MouseEvent) => {
|
||||
|
@ -3,30 +3,15 @@
|
||||
[attr.transform]="transformation"
|
||||
[app-draggable]="drawing"
|
||||
(dragging)="OnDragging($event)"
|
||||
(dragged)="OnDragged($event)"
|
||||
(dragged)="OnDragged($event)"
|
||||
>
|
||||
<svg:g
|
||||
*ngIf="is(drawing.element, 'ellipse')"
|
||||
[app-ellipse]="drawing.element"
|
||||
/>
|
||||
<svg:g *ngIf="is(drawing.element, 'ellipse')" [app-ellipse]="drawing.element" />
|
||||
|
||||
<svg:g
|
||||
*ngIf="is(drawing.element, 'image')"
|
||||
[app-image]="drawing.element"
|
||||
/>
|
||||
<svg:g *ngIf="is(drawing.element, 'image')" [app-image]="drawing.element" />
|
||||
|
||||
<svg:g
|
||||
*ngIf="is(drawing.element, 'line')"
|
||||
[app-line]="drawing.element"
|
||||
/>
|
||||
<svg:g *ngIf="is(drawing.element, 'line')" [app-line]="drawing.element" />
|
||||
|
||||
<svg:g
|
||||
*ngIf="is(drawing.element, 'rect')"
|
||||
[app-rect]="drawing.element"
|
||||
/>
|
||||
<svg:g *ngIf="is(drawing.element, 'rect')" [app-rect]="drawing.element" />
|
||||
|
||||
<svg:g
|
||||
*ngIf="is(drawing.element, 'text')"
|
||||
[app-text]="drawing.element"
|
||||
/>
|
||||
</svg:g>
|
||||
<svg:g *ngIf="is(drawing.element, 'text')" [app-text]="drawing.element" />
|
||||
</svg:g>
|
||||
|
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 563 B |
@ -8,9 +8,8 @@ describe('DrawingComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DrawingComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [DrawingComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -16,12 +16,12 @@ import { DrawingsEventSource } from '../../../events/drawings-event-source';
|
||||
})
|
||||
export class DrawingComponent implements OnInit {
|
||||
@Input('app-drawing') drawing: MapDrawing;
|
||||
|
||||
|
||||
constructor(
|
||||
private svgToDrawingConverter: SvgToDrawingConverter,
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private cd: ChangeDetectorRef,
|
||||
) { }
|
||||
private cd: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
try {
|
||||
@ -39,7 +39,7 @@ export class DrawingComponent implements OnInit {
|
||||
|
||||
OnDragged(evt) {
|
||||
this.cd.detectChanges();
|
||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(this.drawing, evt.dx, evt.dy))
|
||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(this.drawing, evt.dx, evt.dy));
|
||||
}
|
||||
|
||||
is(element, type: string) {
|
||||
@ -47,19 +47,19 @@ export class DrawingComponent implements OnInit {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type === "ellipse") {
|
||||
if (type === 'ellipse') {
|
||||
return element instanceof EllipseElement;
|
||||
}
|
||||
if (type === "image") {
|
||||
if (type === 'image') {
|
||||
return element instanceof ImageElement;
|
||||
}
|
||||
if (type === "line") {
|
||||
if (type === 'line') {
|
||||
return element instanceof LineElement;
|
||||
}
|
||||
if (type === "rect") {
|
||||
if (type === 'rect') {
|
||||
return element instanceof RectElement;
|
||||
}
|
||||
if (type === "text") {
|
||||
if (type === 'text') {
|
||||
return element instanceof TextElement;
|
||||
}
|
||||
return false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
<svg:ellipse
|
||||
<svg:ellipse
|
||||
class="ellipse_element noselect"
|
||||
[attr.fill]="ellipse.fill"
|
||||
[attr.fill-opacity]="fill_opacity"
|
||||
|
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 332 B |
@ -8,9 +8,8 @@ describe('EllipseComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ EllipseComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [EllipseComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -9,30 +9,27 @@ import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||
})
|
||||
export class EllipseComponent implements OnInit {
|
||||
@Input('app-ellipse') ellipse: EllipseElement;
|
||||
|
||||
constructor(
|
||||
private qtDasharrayFixer: QtDasharrayFixer
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
constructor(private qtDasharrayFixer: QtDasharrayFixer) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
get fill_opacity() {
|
||||
if(isFinite(this.ellipse.fill_opacity)) {
|
||||
if (isFinite(this.ellipse.fill_opacity)) {
|
||||
return this.ellipse.fill_opacity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get stroke_width() {
|
||||
if(isFinite(this.ellipse.stroke_width)) {
|
||||
if (isFinite(this.ellipse.stroke_width)) {
|
||||
return this.ellipse.stroke_width;
|
||||
}
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
get stroke_dasharray() {
|
||||
if(this.ellipse.stroke_dasharray) {
|
||||
if (this.ellipse.stroke_dasharray) {
|
||||
return this.qtDasharrayFixer.fix(this.ellipse.stroke_dasharray);
|
||||
}
|
||||
return null;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<svg:image
|
||||
<svg:image
|
||||
class="image_element noselect"
|
||||
[attr.xlink:href]="image.data"
|
||||
[attr.width]="image.width"
|
||||
[attr.height]="image.height"
|
||||
/>
|
||||
/>
|
||||
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 140 B |
@ -8,9 +8,8 @@ describe('ImageComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ImageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [ImageComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -7,11 +7,9 @@ import { ImageElement } from '../../../../../models/drawings/image-element';
|
||||
styleUrls: ['./image.component.scss']
|
||||
})
|
||||
export class ImageComponent implements OnInit {
|
||||
|
||||
@Input('app-image') image: ImageElement;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<svg:line
|
||||
<svg:line
|
||||
class="line_element noselect"
|
||||
[attr.stroke]="line.stroke"
|
||||
[attr.stroke-width]="stroke_width"
|
||||
@ -7,4 +7,4 @@
|
||||
[attr.x2]="line.x2"
|
||||
[attr.y1]="line.y1"
|
||||
[attr.y2]="line.y2"
|
||||
/>
|
||||
/>
|
||||
|
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 245 B |
@ -8,9 +8,8 @@ describe('LineComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LineComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [LineComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -9,26 +9,22 @@ import { LineElement } from '../../../../../models/drawings/line-element';
|
||||
})
|
||||
export class LineComponent implements OnInit {
|
||||
@Input('app-line') line: LineElement;
|
||||
|
||||
constructor(
|
||||
private qtDasharrayFixer: QtDasharrayFixer
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
constructor(private qtDasharrayFixer: QtDasharrayFixer) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
get stroke_width() {
|
||||
if(isFinite(this.line.stroke_width)) {
|
||||
if (isFinite(this.line.stroke_width)) {
|
||||
return this.line.stroke_width;
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
get stroke_dasharray() {
|
||||
if(this.line.stroke_dasharray) {
|
||||
return this.qtDasharrayFixer.fix(this.line.stroke_dasharray);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get stroke_dasharray() {
|
||||
if (this.line.stroke_dasharray) {
|
||||
return this.qtDasharrayFixer.fix(this.line.stroke_dasharray);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<svg:rect
|
||||
<svg:rect
|
||||
class="rect_element noselect"
|
||||
[attr.fill]="rect.fill"
|
||||
[attr.fill-opacity]="fill_opacity"
|
||||
@ -7,4 +7,4 @@
|
||||
[attr.stroke-dasharray]="stroke_dasharray"
|
||||
[attr.width]="rect.width"
|
||||
[attr.height]="rect.height"
|
||||
/>
|
||||
/>
|
||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 278 B |
@ -8,9 +8,8 @@ describe('RectComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ RectComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [RectComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -10,32 +10,28 @@ import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||
export class RectComponent implements OnInit {
|
||||
@Input('app-rect') rect: RectElement;
|
||||
|
||||
constructor(
|
||||
private qtDasharrayFixer: QtDasharrayFixer
|
||||
) { }
|
||||
constructor(private qtDasharrayFixer: QtDasharrayFixer) {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
ngOnInit() {}
|
||||
|
||||
get fill_opacity() {
|
||||
if(isFinite(this.rect.fill_opacity)) {
|
||||
if (isFinite(this.rect.fill_opacity)) {
|
||||
return this.rect.fill_opacity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get stroke_width() {
|
||||
if(isFinite(this.rect.stroke_width)) {
|
||||
if (isFinite(this.rect.stroke_width)) {
|
||||
return this.rect.stroke_width;
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
get stroke_dasharray() {
|
||||
if(this.rect.stroke_dasharray) {
|
||||
return this.qtDasharrayFixer.fix(this.rect.stroke_dasharray);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get stroke_dasharray() {
|
||||
if (this.rect.stroke_dasharray) {
|
||||
return this.qtDasharrayFixer.fix(this.rect.stroke_dasharray);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,12 @@
|
||||
<svg:text #text
|
||||
<svg:text
|
||||
#text
|
||||
class="text_element noselect"
|
||||
[attr.style]="style"
|
||||
[attr.text-decoration]="textDecoration"
|
||||
[attr.fill]="text.fill"
|
||||
[attr.transform]="transformation"
|
||||
>
|
||||
<svg:tspan
|
||||
*ngFor="let line of lines; index as i"
|
||||
xml:space="preserve"
|
||||
x="0"
|
||||
[attr.dy]="i == 0 ? '0em' : '1.4em'"
|
||||
>{{line}}</svg:tspan>
|
||||
</svg:text>
|
||||
<svg:tspan *ngFor="let line of lines; index as i" xml:space="preserve" x="0" [attr.dy]="i == 0 ? '0em' : '1.4em'">
|
||||
{{ line }}
|
||||
</svg:tspan>
|
||||
</svg:text>
|
||||
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 338 B |
@ -8,9 +8,8 @@ describe('TextComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ TextComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [TextComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -12,17 +12,14 @@ export class TextComponent implements OnInit, DoCheck {
|
||||
static MARGIN = 4;
|
||||
|
||||
@Input('app-text') text: TextElement;
|
||||
|
||||
|
||||
@ViewChild('text') textRef: ElementRef;
|
||||
|
||||
lines: string[] = [];
|
||||
|
||||
transformation = "";
|
||||
transformation = '';
|
||||
|
||||
constructor(
|
||||
private fontFixer: FontFixer,
|
||||
private sanitizer: DomSanitizer
|
||||
) { }
|
||||
constructor(private fontFixer: FontFixer, private sanitizer: DomSanitizer) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.lines = this.getLines(this.text.text);
|
||||
@ -31,7 +28,7 @@ export class TextComponent implements OnInit, DoCheck {
|
||||
ngDoCheck() {
|
||||
this.transformation = this.calculateTransformation();
|
||||
}
|
||||
|
||||
|
||||
get style() {
|
||||
const font = this.fontFixer.fix(this.text);
|
||||
|
||||
@ -45,7 +42,7 @@ export class TextComponent implements OnInit, DoCheck {
|
||||
if (font.font_weight) {
|
||||
styles.push(`font-weight: ${this.text.font_weight}`);
|
||||
}
|
||||
return this.sanitizer.bypassSecurityTrustStyle(styles.join("; "));
|
||||
return this.sanitizer.bypassSecurityTrustStyle(styles.join('; '));
|
||||
}
|
||||
|
||||
get textDecoration() {
|
||||
@ -54,7 +51,7 @@ export class TextComponent implements OnInit, DoCheck {
|
||||
|
||||
calculateTransformation() {
|
||||
const tspans = this.textRef.nativeElement.getElementsByTagName('tspan');
|
||||
if(tspans.length > 0) {
|
||||
if (tspans.length > 0) {
|
||||
const height = this.textRef.nativeElement.getBBox().height / tspans.length;
|
||||
return `translate(${TextComponent.MARGIN}, ${height - TextComponent.MARGIN})`;
|
||||
}
|
||||
@ -62,7 +59,6 @@ export class TextComponent implements OnInit, DoCheck {
|
||||
}
|
||||
|
||||
getLines(text: string) {
|
||||
return text.split(/\r?\n/)
|
||||
return text.split(/\r?\n/);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,41 +1,25 @@
|
||||
<svg #svg
|
||||
class="map"
|
||||
preserveAspectRatio="none"
|
||||
[attr.width]="width"
|
||||
[attr.height]="height"
|
||||
>
|
||||
<g [attr.transform]="transform">
|
||||
<g *ngFor="let layer of layers">
|
||||
<g class="links">
|
||||
<g
|
||||
*ngFor="let link of layer.links"
|
||||
[app-link]="link"
|
||||
[show-interface-labels]="settings.show_interface_labels"
|
||||
></g>
|
||||
<!-- [node-changed]="nodeChanged" -->
|
||||
</g>
|
||||
<g class="nodes">
|
||||
<g
|
||||
*ngFor="let node of layer.nodes"
|
||||
[app-node]="node"
|
||||
[symbols]="symbols"
|
||||
></g>
|
||||
<!-- [node-changed]="nodeChanged"
|
||||
<svg #svg class="map" preserveAspectRatio="none" [attr.width]="width" [attr.height]="height">
|
||||
<g [attr.transform]="transform">
|
||||
<g *ngFor="let layer of layers">
|
||||
<g class="links">
|
||||
<g
|
||||
*ngFor="let link of layer.links"
|
||||
[app-link]="link"
|
||||
[show-interface-labels]="settings.show_interface_labels"
|
||||
></g>
|
||||
<!-- [node-changed]="nodeChanged" -->
|
||||
</g>
|
||||
<g class="nodes">
|
||||
<g *ngFor="let node of layer.nodes" [app-node]="node" [symbols]="symbols"></g>
|
||||
<!-- [node-changed]="nodeChanged"
|
||||
(valueChange)="onNodeChanged($event)" -->
|
||||
</g>
|
||||
<g class="drawings">
|
||||
<g
|
||||
*ngFor="let drawing of layer.drawings"
|
||||
[app-drawing]="drawing" >
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g class="drawings"><g *ngFor="let drawing of layer.drawings" [app-drawing]="drawing"></g></g>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g [app-selection]="svg"></g>
|
||||
<!-- (selected)="onSelection($event)" -->
|
||||
<g [app-selection]="svg"></g>
|
||||
<!-- (selected)="onSelection($event)" -->
|
||||
|
||||
<filter id="grayscale">
|
||||
<feColorMatrix id="feGrayscale" type="saturate" values="0"/>
|
||||
</filter>
|
||||
</svg>
|
||||
<filter id="grayscale"><feColorMatrix id="feGrayscale" type="saturate" values="0" /></filter>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 930 B |
@ -1,5 +1,3 @@
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,4 +23,4 @@
|
||||
// // expect(component).toBeTruthy();
|
||||
// // });
|
||||
// });
|
||||
// //
|
||||
// //
|
||||
|
@ -1,11 +1,20 @@
|
||||
import {
|
||||
Component, ElementRef, HostListener, Input, OnChanges, OnDestroy, OnInit,
|
||||
SimpleChange, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
SimpleChange,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
|
||||
import { GraphLayout } from "../../widgets/graph-layout";
|
||||
import { Context } from "../../models/context";
|
||||
import { Size } from "../../models/size";
|
||||
import { GraphLayout } from '../../widgets/graph-layout';
|
||||
import { Context } from '../../models/context';
|
||||
import { Size } from '../../models/size';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
||||
@ -16,7 +25,6 @@ import { Symbol } from '../../../models/symbol';
|
||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||
import { LayersManager } from '../../managers/layers-manager';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-experimental-map',
|
||||
templateUrl: './experimental-map.component.html',
|
||||
@ -29,7 +37,7 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() drawings: Drawing[] = [];
|
||||
@Input() symbols: Symbol[] = [];
|
||||
// @Input() changed: EventEmitter<any>;
|
||||
|
||||
|
||||
// @Input('node-updated') nodeUpdated: EventEmitter<any>;
|
||||
|
||||
@Input() width = 1500;
|
||||
@ -40,7 +48,7 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private changesDetected: Subscription;
|
||||
|
||||
protected settings = {
|
||||
'show_interface_labels': true
|
||||
show_interface_labels: true
|
||||
};
|
||||
|
||||
constructor(
|
||||
@ -50,11 +58,10 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private canvasSizeDetector: CanvasSizeDetector,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private layersManger: LayersManager,
|
||||
public graphLayout: GraphLayout,
|
||||
) {
|
||||
}
|
||||
public graphLayout: GraphLayout
|
||||
) {}
|
||||
|
||||
@Input('show-interface-labels')
|
||||
@Input('show-interface-labels')
|
||||
set showInterfaceLabels(value) {
|
||||
this.settings.show_interface_labels = value;
|
||||
this.mapChangeDetectorRef.detectChanges();
|
||||
@ -72,11 +79,9 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
@Input('draw-link-tool') drawLinkTool: boolean;
|
||||
|
||||
@Input('readonly') set readonly(value) {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
|
||||
}
|
||||
@Input('readonly') set readonly(value) {}
|
||||
|
||||
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {}
|
||||
|
||||
ngOnInit() {
|
||||
// this.changeDetectorRef.detach();
|
||||
@ -90,7 +95,6 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.changeDetectorRef.detectChanges();
|
||||
});
|
||||
|
||||
|
||||
// this.changedSubscription = this.changed.subscribe(() => {
|
||||
// this.changeDetectorRef.detectChanges();
|
||||
// });
|
||||
@ -123,9 +127,6 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`;
|
||||
}
|
||||
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event) {
|
||||
|
||||
}
|
||||
onResize(event) {}
|
||||
}
|
||||
|
@ -1,9 +1,4 @@
|
||||
<svg:g
|
||||
class="text_container"
|
||||
[attr.transform]="transform"
|
||||
width="100"
|
||||
height="100"
|
||||
>
|
||||
<svg:g class="text_container" [attr.transform]="transform" width="100" height="100">
|
||||
<svg:rect
|
||||
stroke-dasharray="3,3"
|
||||
stroke-width="0.5"
|
||||
@ -15,14 +10,7 @@
|
||||
[attr.height]="rectHeight"
|
||||
/>
|
||||
|
||||
<svg:text
|
||||
#textSvg
|
||||
class="interface_label"
|
||||
[attr.style]="sanitizedStyle"
|
||||
[attr.x]="borderSize"
|
||||
[attr.y]="-borderSize"
|
||||
>
|
||||
<svg:text #textSvg class="interface_label" [attr.style]="sanitizedStyle" [attr.x]="borderSize" [attr.y]="-borderSize">
|
||||
{{ text }}
|
||||
</svg:text>
|
||||
</svg:g>
|
||||
|
||||
|
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 449 B |
@ -8,9 +8,8 @@ describe('InterfaceLabelComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ InterfaceLabelComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [InterfaceLabelComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -13,15 +13,15 @@ export class InterfaceLabelComponent implements OnInit {
|
||||
@ViewChild('textSvg') textRef: ElementRef;
|
||||
|
||||
private label = {
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
'text': '',
|
||||
'style': '',
|
||||
'rotation': 0
|
||||
x: 0,
|
||||
y: 0,
|
||||
text: '',
|
||||
style: '',
|
||||
rotation: 0
|
||||
};
|
||||
|
||||
borderSize = 5;
|
||||
|
||||
|
||||
textWidth = 0;
|
||||
textHeight = 0;
|
||||
|
||||
@ -30,10 +30,9 @@ export class InterfaceLabelComponent implements OnInit {
|
||||
private ref: ChangeDetectorRef,
|
||||
private sanitizer: DomSanitizer,
|
||||
private cssFixer: CssFixer
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
ngOnInit() {}
|
||||
|
||||
@Input('x')
|
||||
set x(value) {
|
||||
@ -82,7 +81,7 @@ export class InterfaceLabelComponent implements OnInit {
|
||||
}
|
||||
|
||||
get rectWidth() {
|
||||
return this.textRef.nativeElement.getBBox().width + this.borderSize*2;
|
||||
return this.textRef.nativeElement.getBBox().width + this.borderSize * 2;
|
||||
}
|
||||
|
||||
get rectHeight() {
|
||||
|
@ -1,11 +1,12 @@
|
||||
<svg:g
|
||||
<svg:g
|
||||
class="link"
|
||||
[attr.link_id]="link.id"
|
||||
[attr.map-source]="link.source.id"
|
||||
[attr.map-target]="link.target.id"
|
||||
[attr.transform]="transform"
|
||||
>
|
||||
<svg:path #path
|
||||
<svg:path
|
||||
#path
|
||||
*ngIf="link.linkType == 'ethernet'"
|
||||
class="ethernet_link"
|
||||
stroke="#000"
|
||||
@ -13,7 +14,8 @@
|
||||
[attr.d]="d"
|
||||
/>
|
||||
|
||||
<svg:path #path
|
||||
<svg:path
|
||||
#path
|
||||
*ngIf="link.linkType == 'serial'"
|
||||
class="serial_link"
|
||||
stroke="#B22222"
|
||||
@ -22,25 +24,15 @@
|
||||
[attr.d]="d"
|
||||
/>
|
||||
|
||||
<svg:g
|
||||
[app-status]="link.source.status"
|
||||
[direction]="'source'"
|
||||
[path]="path"
|
||||
[d]="d"
|
||||
/>
|
||||
<svg:g [app-status]="link.source.status" [direction]="'source'" [path]="path" [d]="d" />
|
||||
|
||||
<svg:g
|
||||
[app-status]="link.target.status"
|
||||
[direction]="'target'"
|
||||
[path]="path"
|
||||
[d]="d"
|
||||
/>
|
||||
<svg:g [app-status]="link.target.status" [direction]="'target'" [path]="path" [d]="d" />
|
||||
|
||||
<svg:g
|
||||
*ngIf="showInterfaceLabels"
|
||||
[app-interface-label]
|
||||
[x]="link.source.x+link.nodes[0].label.x"
|
||||
[y]="link.source.y+link.nodes[0].label.y"
|
||||
[x]="link.source.x + link.nodes[0].label.x"
|
||||
[y]="link.source.y + link.nodes[0].label.y"
|
||||
[text]="link.nodes[0].label.text"
|
||||
[style]="link.nodes[0].label.style"
|
||||
[rotation]="link.nodes[0].label.rotation"
|
||||
@ -49,11 +41,10 @@
|
||||
<svg:g
|
||||
*ngIf="showInterfaceLabels"
|
||||
[app-interface-label]
|
||||
[x]="link.target.x+link.nodes[1].label.x"
|
||||
[y]="link.target.y+link.nodes[1].label.y"
|
||||
[x]="link.target.x + link.nodes[1].label.x"
|
||||
[y]="link.target.y + link.nodes[1].label.y"
|
||||
[text]="link.nodes[1].label.text"
|
||||
[style]="link.nodes[1].label.style"
|
||||
[rotation]="link.nodes[1].label.rotation"
|
||||
/>
|
||||
|
||||
</svg:g>
|
||||
</svg:g>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@ -8,9 +8,8 @@ describe('LinkComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LinkComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [LinkComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -1,7 +1,13 @@
|
||||
import {
|
||||
Component, OnInit, Input, ViewChild,
|
||||
ElementRef, EventEmitter, ChangeDetectorRef,
|
||||
OnDestroy } from '@angular/core';
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
ChangeDetectorRef,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { LinkStrategy } from './strategies/link-strategy';
|
||||
import { EthernetLinkStrategy } from './strategies/ethernet-link-strategy';
|
||||
@ -10,11 +16,10 @@ import { MultiLinkCalculatorHelper } from '../../../helpers/multi-link-calculato
|
||||
import { Node } from '../../../models/node';
|
||||
import { MapLink } from '../../../models/map/map-link';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: '[app-link]',
|
||||
templateUrl: './link.component.html',
|
||||
styleUrls: ['./link.component.scss'],
|
||||
styleUrls: ['./link.component.scss']
|
||||
})
|
||||
export class LinkComponent implements OnInit, OnDestroy {
|
||||
@Input('app-link') link: MapLink;
|
||||
@ -28,10 +33,7 @@ export class LinkComponent implements OnInit, OnDestroy {
|
||||
|
||||
private nodeChangedSubscription: Subscription;
|
||||
|
||||
constructor(
|
||||
private multiLinkCalculatorHelper: MultiLinkCalculatorHelper,
|
||||
private ref: ChangeDetectorRef
|
||||
) {}
|
||||
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private ref: ChangeDetectorRef) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.ref.detectChanges();
|
||||
@ -54,12 +56,15 @@ export class LinkComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
get transform() {
|
||||
const translation = this.multiLinkCalculatorHelper.linkTranslation(this.link.distance, this.link.source, this.link.target);
|
||||
const translation = this.multiLinkCalculatorHelper.linkTranslation(
|
||||
this.link.distance,
|
||||
this.link.source,
|
||||
this.link.target
|
||||
);
|
||||
return `translate (${translation.dx}, ${translation.dy})`;
|
||||
}
|
||||
|
||||
get d() {
|
||||
return this.strategy.d(this.link);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
import { LinkStrategy } from "./link-strategy";
|
||||
import { path } from "d3-path";
|
||||
import { MapLink } from "../../../../models/map/map-link";
|
||||
|
||||
import { LinkStrategy } from './link-strategy';
|
||||
import { path } from 'd3-path';
|
||||
import { MapLink } from '../../../../models/map/map-link';
|
||||
|
||||
export class EthernetLinkStrategy implements LinkStrategy {
|
||||
public d(link: MapLink): string {
|
||||
const points = [
|
||||
[link.source.x + link.source.width / 2., link.source.y + link.source.height / 2.],
|
||||
[link.target.x + link.target.width / 2., link.target.y + link.target.height / 2.]
|
||||
];
|
||||
|
||||
const line_generator = path();
|
||||
line_generator.moveTo(points[0][0], points[0][1]);
|
||||
line_generator.lineTo(points[1][0], points[1][1]);
|
||||
return line_generator.toString();
|
||||
}
|
||||
}
|
||||
public d(link: MapLink): string {
|
||||
const points = [
|
||||
[link.source.x + link.source.width / 2, link.source.y + link.source.height / 2],
|
||||
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2]
|
||||
];
|
||||
|
||||
const line_generator = path();
|
||||
line_generator.moveTo(points[0][0], points[0][1]);
|
||||
line_generator.lineTo(points[1][0], points[1][1]);
|
||||
return line_generator.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MapLink } from "../../../../models/map/map-link";
|
||||
import { MapLink } from '../../../../models/map/map-link';
|
||||
|
||||
export interface LinkStrategy {
|
||||
d(link: MapLink): string;
|
||||
d(link: MapLink): string;
|
||||
}
|
||||
|
@ -1,55 +1,46 @@
|
||||
import { path } from "d3-path";
|
||||
import { LinkStrategy } from "./link-strategy";
|
||||
import { MapLink } from "../../../../models/map/map-link";
|
||||
|
||||
import { path } from 'd3-path';
|
||||
import { LinkStrategy } from './link-strategy';
|
||||
import { MapLink } from '../../../../models/map/map-link';
|
||||
|
||||
export class SerialLinkStrategy implements LinkStrategy {
|
||||
private linkToPoints(link: MapLink) {
|
||||
const source = {
|
||||
'x': link.source.x + link.source.width / 2,
|
||||
'y': link.source.y + link.source.height / 2
|
||||
};
|
||||
const target = {
|
||||
'x': link.target.x + link.target.width / 2,
|
||||
'y': link.target.y + link.target.height / 2
|
||||
};
|
||||
|
||||
const dx = target.x - source.x;
|
||||
const dy = target.y - source.y;
|
||||
|
||||
const vector_angle = Math.atan2(dy, dx);
|
||||
const rot_angle = -Math.PI / 4.0;
|
||||
const vect_rot = [
|
||||
Math.cos(vector_angle + rot_angle),
|
||||
Math.sin(vector_angle + rot_angle)
|
||||
];
|
||||
|
||||
const angle_source: [number, number] = [
|
||||
source.x + dx / 2.0 + 15 * vect_rot[0],
|
||||
source.y + dy / 2.0 + 15 * vect_rot[1]
|
||||
];
|
||||
|
||||
const angle_target: [number, number] = [
|
||||
target.x - dx / 2.0 - 15 * vect_rot[0],
|
||||
target.y - dy / 2.0 - 15 * vect_rot[1]
|
||||
];
|
||||
|
||||
return [
|
||||
[source.x, source.y],
|
||||
angle_source,
|
||||
angle_target,
|
||||
[target.x, target.y]
|
||||
];
|
||||
}
|
||||
|
||||
d(link: MapLink): string {
|
||||
const points = this.linkToPoints(link);
|
||||
|
||||
const line_generator = path();
|
||||
line_generator.moveTo(points[0][0], points[0][1]);
|
||||
line_generator.lineTo(points[1][0], points[1][1]);
|
||||
line_generator.lineTo(points[2][0], points[2][1]);
|
||||
line_generator.lineTo(points[3][0], points[3][1]);
|
||||
return line_generator.toString();
|
||||
}
|
||||
private linkToPoints(link: MapLink) {
|
||||
const source = {
|
||||
x: link.source.x + link.source.width / 2,
|
||||
y: link.source.y + link.source.height / 2
|
||||
};
|
||||
const target = {
|
||||
x: link.target.x + link.target.width / 2,
|
||||
y: link.target.y + link.target.height / 2
|
||||
};
|
||||
|
||||
const dx = target.x - source.x;
|
||||
const dy = target.y - source.y;
|
||||
|
||||
const vector_angle = Math.atan2(dy, dx);
|
||||
const rot_angle = -Math.PI / 4.0;
|
||||
const vect_rot = [Math.cos(vector_angle + rot_angle), Math.sin(vector_angle + rot_angle)];
|
||||
|
||||
const angle_source: [number, number] = [
|
||||
source.x + dx / 2.0 + 15 * vect_rot[0],
|
||||
source.y + dy / 2.0 + 15 * vect_rot[1]
|
||||
];
|
||||
|
||||
const angle_target: [number, number] = [
|
||||
target.x - dx / 2.0 - 15 * vect_rot[0],
|
||||
target.y - dy / 2.0 - 15 * vect_rot[1]
|
||||
];
|
||||
|
||||
return [[source.x, source.y], angle_source, angle_target, [target.x, target.y]];
|
||||
}
|
||||
|
||||
d(link: MapLink): string {
|
||||
const points = this.linkToPoints(link);
|
||||
|
||||
const line_generator = path();
|
||||
line_generator.moveTo(points[0][0], points[0][1]);
|
||||
line_generator.lineTo(points[1][0], points[1][1]);
|
||||
line_generator.lineTo(points[2][0], points[2][1]);
|
||||
line_generator.lineTo(points[3][0], points[3][1]);
|
||||
return line_generator.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
<svg:g
|
||||
class="node"
|
||||
[attr.transform]="'translate(' + node.x + ',' + node.y + ')'"
|
||||
>
|
||||
<svg:image
|
||||
<svg:g class="node" [attr.transform]="'translate(' + node.x + ',' + node.y + ')'">
|
||||
<svg:image
|
||||
#image
|
||||
[attr.width]="node.width"
|
||||
[attr.height]="node.height"
|
||||
@ -13,13 +10,7 @@
|
||||
(dragging)="OnDragging($event)"
|
||||
(dragged)="OnDragged($event)"
|
||||
/>
|
||||
<svg:text
|
||||
#label
|
||||
class="label"
|
||||
[attr.style]="label_style"
|
||||
[attr.x]="label_x"
|
||||
[attr.y]="label_y"
|
||||
>
|
||||
<svg:text #label class="label" [attr.style]="label_style" [attr.x]="label_x" [attr.y]="label_y">
|
||||
{{ node.label.text }}
|
||||
</svg:text>
|
||||
</svg:g>
|
||||
</svg:g>
|
||||
|
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 484 B |
@ -8,9 +8,8 @@ describe('NodeComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NodeComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [NodeComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -1,7 +1,17 @@
|
||||
import {
|
||||
Component, OnInit, Input, ElementRef,
|
||||
ViewChild, ChangeDetectorRef, ChangeDetectionStrategy, Output,
|
||||
EventEmitter, OnDestroy, OnChanges, AfterViewInit } from '@angular/core';
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
ElementRef,
|
||||
ViewChild,
|
||||
ChangeDetectorRef,
|
||||
ChangeDetectionStrategy,
|
||||
Output,
|
||||
EventEmitter,
|
||||
OnDestroy,
|
||||
OnChanges,
|
||||
AfterViewInit
|
||||
} from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CssFixer } from '../../../helpers/css-fixer';
|
||||
@ -26,9 +36,9 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
||||
@Input('app-node') node: MapNode;
|
||||
@Input('symbols') symbols: Symbol[];
|
||||
@Input('node-changed') nodeChanged: EventEmitter<Node>;
|
||||
|
||||
|
||||
// @Output() valueChange = new EventEmitter<Node>();
|
||||
|
||||
|
||||
nodeChangedSubscription: Subscription;
|
||||
|
||||
private labelHeight = 0;
|
||||
@ -40,7 +50,7 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
||||
protected element: ElementRef,
|
||||
private cd: ChangeDetectorRef,
|
||||
private nodesEventSource: NodesEventSource
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
// this.nodeChangedSubscription = this.nodeChanged.subscribe((node: Node) => {
|
||||
@ -72,10 +82,9 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
||||
|
||||
OnDragged(evt) {
|
||||
this.cd.detectChanges();
|
||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(this.node, evt.dx, evt.dy))
|
||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(this.node, evt.dx, evt.dy));
|
||||
}
|
||||
|
||||
|
||||
get symbol(): string {
|
||||
const symbol = this.symbols.find((s: Symbol) => s.symbol_id === this.node.symbol);
|
||||
if (symbol) {
|
||||
@ -86,7 +95,6 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
||||
}
|
||||
|
||||
get label_style() {
|
||||
|
||||
let styles = this.cssFixer.fix(this.node.label.style);
|
||||
styles = this.fontFixer.fixStyles(styles);
|
||||
return this.sanitizer.bypassSecurityTrustStyle(styles);
|
||||
@ -96,18 +104,18 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
||||
if (this.node.label.x === null) {
|
||||
// center
|
||||
const bbox = this.label.nativeElement.getBBox();
|
||||
|
||||
return -bbox.width / 2.;
|
||||
|
||||
return -bbox.width / 2;
|
||||
}
|
||||
return this.node.label.x + NodeComponent.NODE_LABEL_MARGIN;
|
||||
}
|
||||
|
||||
get label_y(): number {
|
||||
this.labelHeight = this.getLabelHeight();
|
||||
|
||||
|
||||
if (this.node.label.x === null) {
|
||||
// center
|
||||
return - this.node.height / 2. - this.labelHeight ;
|
||||
return -this.node.height / 2 - this.labelHeight;
|
||||
}
|
||||
return this.node.label.y + this.labelHeight - NodeComponent.NODE_LABEL_MARGIN;
|
||||
}
|
||||
|
@ -1,10 +1 @@
|
||||
<svg:g
|
||||
class="selection-line-tool"
|
||||
>
|
||||
<svg:path
|
||||
class="selection"
|
||||
*ngIf="visible"
|
||||
[attr.d]="d"
|
||||
>
|
||||
</svg:path>
|
||||
</svg:g>
|
||||
<svg:g class="selection-line-tool"><svg:path class="selection" *ngIf="visible" [attr.d]="d"></svg:path></svg:g>
|
||||
|
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 112 B |
@ -8,9 +8,8 @@ describe('SelectionComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SelectionComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [SelectionComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -9,7 +9,7 @@ import { Rectangle } from '../../../models/rectangle';
|
||||
})
|
||||
export class SelectionComponent implements OnInit, AfterViewInit {
|
||||
@Input('app-selection') svg: SVGSVGElement;
|
||||
|
||||
|
||||
private startX: number;
|
||||
private startY: number;
|
||||
|
||||
@ -20,25 +20,20 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
||||
visible = false;
|
||||
draggable: Subscription;
|
||||
|
||||
|
||||
@Output('selected') rectangleSelected = new EventEmitter<Rectangle>();
|
||||
|
||||
constructor(
|
||||
private ref: ChangeDetectorRef
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
constructor(private ref: ChangeDetectorRef) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
const down = Observable.fromEvent(this.svg, 'mousedown').do((e: MouseEvent) => e.preventDefault());
|
||||
|
||||
down.subscribe((e: MouseEvent) => {
|
||||
if(e.target !== this.svg) {
|
||||
if (e.target !== this.svg) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.started = true;
|
||||
this.startX = e.clientX + window.scrollX;
|
||||
this.startY = e.clientY + window.scrollY;
|
||||
@ -48,51 +43,48 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
||||
this.ref.detectChanges();
|
||||
});
|
||||
|
||||
const up = Observable.fromEvent(document, 'mouseup')
|
||||
.do((e: MouseEvent) => {
|
||||
const up = Observable.fromEvent(document, 'mouseup').do((e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
const mouseMove = Observable.fromEvent(document, 'mousemove')
|
||||
.do((e: MouseEvent) => e.stopPropagation());
|
||||
const mouseMove = Observable.fromEvent(document, 'mousemove').do((e: MouseEvent) => e.stopPropagation());
|
||||
|
||||
const scrollWindow = Observable.fromEvent(document, 'scroll')
|
||||
.startWith({});
|
||||
const scrollWindow = Observable.fromEvent(document, 'scroll').startWith({});
|
||||
|
||||
const move = Observable.combineLatest(mouseMove, scrollWindow);
|
||||
|
||||
const drag = down.mergeMap((md: MouseEvent) => {
|
||||
return move
|
||||
.map(([mm, s]) => mm)
|
||||
.do((mm: MouseEvent) => {
|
||||
if(!this.started) {
|
||||
.map(([mm, s]) => mm)
|
||||
.do((mm: MouseEvent) => {
|
||||
if (!this.started) {
|
||||
return;
|
||||
}
|
||||
this.visible = true;
|
||||
this.width = mm.clientX - this.startX + window.scrollX;
|
||||
this.height = mm.clientY - this.startY + window.scrollY;
|
||||
|
||||
this.ref.detectChanges();
|
||||
|
||||
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
||||
})
|
||||
.skipUntil(
|
||||
up.take(1).do((e: MouseEvent) => {
|
||||
if (!this.started) {
|
||||
return;
|
||||
}
|
||||
this.visible = true;
|
||||
this.width = mm.clientX - this.startX + window.scrollX;
|
||||
this.height = mm.clientY - this.startY + window.scrollY;
|
||||
this.visible = false;
|
||||
this.started = false;
|
||||
|
||||
this.width = e.clientX - this.startX + window.scrollX;
|
||||
this.height = e.clientY - this.startY + window.scrollY;
|
||||
|
||||
this.ref.detectChanges();
|
||||
|
||||
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
||||
})
|
||||
.skipUntil(up
|
||||
.take(1)
|
||||
.do((e: MouseEvent) => {
|
||||
if(!this.started) {
|
||||
return;
|
||||
}
|
||||
this.visible = false;
|
||||
this.started = false;
|
||||
|
||||
this.width = e.clientX - this.startX + window.scrollX;
|
||||
this.height = e.clientY - this.startY + window.scrollY;
|
||||
|
||||
this.ref.detectChanges();
|
||||
|
||||
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
||||
}))
|
||||
.take(1);
|
||||
)
|
||||
.take(1);
|
||||
});
|
||||
|
||||
this.draggable = drag.subscribe((e: MouseEvent) => {
|
||||
@ -109,7 +101,7 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
private rect(x: number, y: number, w: number, h: number) {
|
||||
return "M" + [x, y] + " l" + [w, 0] + " l" + [0, h] + " l" + [-w, 0] + "z";
|
||||
return 'M' + [x, y] + ' l' + [w, 0] + ' l' + [0, h] + ' l' + [-w, 0] + 'z';
|
||||
}
|
||||
|
||||
private selectedEvent(start, end) {
|
||||
|
@ -11,11 +11,11 @@
|
||||
<svg:rect
|
||||
*ngIf="status == 'stopped'"
|
||||
class="status_stopped"
|
||||
[attr.x]="point.x - 10/2"
|
||||
[attr.y]="point.y - 10/2"
|
||||
[attr.x]="point.x - 10 / 2"
|
||||
[attr.y]="point.y - 10 / 2"
|
||||
width="10"
|
||||
height="10"
|
||||
r="6"
|
||||
fill="red"
|
||||
/>
|
||||
</svg:g>
|
||||
</svg:g>
|
||||
|
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 406 B |
@ -8,9 +8,8 @@ describe('StatusComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ StatusComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [StatusComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -1,27 +1,23 @@
|
||||
import { Component, ElementRef, Input, ChangeDetectorRef } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: '[app-status]',
|
||||
templateUrl: './status.component.html',
|
||||
styleUrls: ['./status.component.scss'],
|
||||
styleUrls: ['./status.component.scss']
|
||||
})
|
||||
export class StatusComponent {
|
||||
export class StatusComponent {
|
||||
static STOPPED_STATUS_RECT_WIDTH = 10;
|
||||
|
||||
data = {
|
||||
'status': '',
|
||||
'path': null,
|
||||
'direction': null,
|
||||
'd': null
|
||||
status: '',
|
||||
path: null,
|
||||
direction: null,
|
||||
d: null
|
||||
};
|
||||
|
||||
constructor(
|
||||
protected element: ElementRef,
|
||||
private ref: ChangeDetectorRef
|
||||
) {}
|
||||
constructor(protected element: ElementRef, private ref: ChangeDetectorRef) {}
|
||||
|
||||
@Input('app-status')
|
||||
@Input('app-status')
|
||||
set status(value) {
|
||||
this.data.status = value;
|
||||
this.ref.markForCheck();
|
||||
@ -54,7 +50,7 @@ export class StatusComponent {
|
||||
get direction() {
|
||||
return this.data.direction;
|
||||
}
|
||||
|
||||
|
||||
get path() {
|
||||
return this.data.path;
|
||||
}
|
||||
@ -79,5 +75,4 @@ export class StatusComponent {
|
||||
}
|
||||
return this.targetStatusPoint;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,23 +16,22 @@ describe('SelectionControlComponent', () => {
|
||||
let selectionEventSource: SelectionEventSource;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
const mockedGraphData = mock(GraphDataManager);
|
||||
|
||||
const node_1 = new MapNode();
|
||||
node_1.id = "test1";
|
||||
node_1.name = "Node 1";
|
||||
node_1.id = 'test1';
|
||||
node_1.name = 'Node 1';
|
||||
node_1.x = 150;
|
||||
node_1.y = 150;
|
||||
|
||||
const node_2 = new MapNode();
|
||||
node_2.id = "test2";
|
||||
node_2.name = "Node 2";
|
||||
node_2.id = 'test2';
|
||||
node_2.name = 'Node 2';
|
||||
node_2.x = 300;
|
||||
node_2.y = 300;
|
||||
|
||||
const link_1 = new MapLink();
|
||||
link_1.id = "test1";
|
||||
link_1.id = 'test1';
|
||||
|
||||
when(mockedGraphData.getNodes()).thenReturn([node_1, node_2]);
|
||||
when(mockedGraphData.getLinks()).thenReturn([link_1]);
|
||||
@ -50,7 +49,7 @@ describe('SelectionControlComponent', () => {
|
||||
|
||||
afterEach(() => {
|
||||
component.ngOnDestroy();
|
||||
})
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
|
@ -13,68 +13,74 @@ import { Rectangle } from '../../models/rectangle';
|
||||
})
|
||||
export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
private onSelection: Subscription;
|
||||
|
||||
|
||||
constructor(
|
||||
private selectionEventSource: SelectionEventSource,
|
||||
private graphDataManager: GraphDataManager,
|
||||
private inRectangleHelper: InRectangleHelper,
|
||||
private selectionManager: SelectionManager
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.onSelection = this.selectionEventSource.selected.subscribe((rectangle: Rectangle) => {
|
||||
const selectedNodes = this.graphDataManager.getNodes().filter((node) => {
|
||||
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y)
|
||||
const selectedNodes = this.graphDataManager.getNodes().filter(node => {
|
||||
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y);
|
||||
});
|
||||
|
||||
const selectedLinks = this.graphDataManager.getLinks().filter((link) => {
|
||||
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y)
|
||||
const selectedLinks = this.graphDataManager.getLinks().filter(link => {
|
||||
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y);
|
||||
});
|
||||
|
||||
const selectedDrawings = this.graphDataManager.getDrawings().filter((drawing) => {
|
||||
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y)
|
||||
|
||||
const selectedDrawings = this.graphDataManager.getDrawings().filter(drawing => {
|
||||
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y);
|
||||
});
|
||||
|
||||
const selectedLabels = this.graphDataManager.getNodes().filter((node) => {
|
||||
if (node.label === undefined) {
|
||||
return false;
|
||||
}
|
||||
const labelX = node.x + node.label.x;
|
||||
const labelY = node.y + node.label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY);
|
||||
}).map((node) => node.label);
|
||||
|
||||
const selectedInterfacesLabelsSources = this.graphDataManager.getLinks().filter((link) => {
|
||||
if (link.source === undefined || link.nodes.length != 2 || link.nodes[0].label === undefined) {
|
||||
return false;
|
||||
}
|
||||
const interfaceLabelX = link.source.x + link.nodes[0].label.x;
|
||||
const interfaceLabelY = link.source.y + link.nodes[0].label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||
}).map((link) => link.nodes[0]);
|
||||
const selectedLabels = this.graphDataManager
|
||||
.getNodes()
|
||||
.filter(node => {
|
||||
if (node.label === undefined) {
|
||||
return false;
|
||||
}
|
||||
const labelX = node.x + node.label.x;
|
||||
const labelY = node.y + node.label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY);
|
||||
})
|
||||
.map(node => node.label);
|
||||
|
||||
const selectedInterfacesLabelsTargets = this.graphDataManager.getLinks().filter((link) => {
|
||||
if (link.target === undefined || link.nodes.length != 2 || link.nodes[1].label === undefined) {
|
||||
return false;
|
||||
}
|
||||
const interfaceLabelX = link.target.x + link.nodes[1].label.x;
|
||||
const interfaceLabelY = link.target.y + link.nodes[1].label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||
}).map((link) => link.nodes[1]);
|
||||
const selectedInterfacesLabelsSources = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(link => {
|
||||
if (link.source === undefined || link.nodes.length != 2 || link.nodes[0].label === undefined) {
|
||||
return false;
|
||||
}
|
||||
const interfaceLabelX = link.source.x + link.nodes[0].label.x;
|
||||
const interfaceLabelY = link.source.y + link.nodes[0].label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||
})
|
||||
.map(link => link.nodes[0]);
|
||||
|
||||
const selectedInterfaces = [
|
||||
...selectedInterfacesLabelsSources,
|
||||
...selectedInterfacesLabelsTargets,
|
||||
]
|
||||
const selectedInterfacesLabelsTargets = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(link => {
|
||||
if (link.target === undefined || link.nodes.length != 2 || link.nodes[1].label === undefined) {
|
||||
return false;
|
||||
}
|
||||
const interfaceLabelX = link.target.x + link.nodes[1].label.x;
|
||||
const interfaceLabelY = link.target.y + link.nodes[1].label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||
})
|
||||
.map(link => link.nodes[1]);
|
||||
|
||||
const selectedInterfaces = [...selectedInterfacesLabelsSources, ...selectedInterfacesLabelsTargets];
|
||||
|
||||
const selected = [
|
||||
...selectedNodes,
|
||||
...selectedLinks,
|
||||
...selectedDrawings,
|
||||
...selectedLabels,
|
||||
...selectedInterfaces,
|
||||
...selectedInterfaces
|
||||
];
|
||||
|
||||
|
||||
this.selectionManager.setSelected(selected);
|
||||
});
|
||||
}
|
||||
@ -82,5 +88,4 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
ngOnDestroy() {
|
||||
this.onSelection.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,9 +8,8 @@ describe('SelectionSelectComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SelectionSelectComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [SelectionSelectComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -11,11 +11,8 @@ import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||
export class SelectionSelectComponent implements OnInit, OnDestroy {
|
||||
private onSelected: Subscription;
|
||||
private onUnselected: Subscription;
|
||||
|
||||
constructor(
|
||||
private selectionManager: SelectionManager,
|
||||
private mapChangeDetectorRef: MapChangeDetectorRef
|
||||
) { }
|
||||
|
||||
constructor(private selectionManager: SelectionManager, private mapChangeDetectorRef: MapChangeDetectorRef) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
||||
@ -30,5 +27,4 @@ export class SelectionSelectComponent implements OnInit, OnDestroy {
|
||||
this.onSelected.unsubscribe();
|
||||
this.onUnselected.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
<div #temporaryTextElement id="temporaryElement" class="temporaryElement" contenteditable="true"
|
||||
[style.top]=topPosition
|
||||
[style.left]=leftPosition>
|
||||
{{innerText}}
|
||||
</div>
|
||||
<div
|
||||
#temporaryTextElement
|
||||
id="temporaryElement"
|
||||
class="temporaryElement"
|
||||
contenteditable="true"
|
||||
[style.top]="topPosition"
|
||||
[style.left]="leftPosition"
|
||||
>
|
||||
{{ innerText }}
|
||||
</div>
|
||||
|
@ -1,10 +1,10 @@
|
||||
.temporaryElement{
|
||||
padding-left: 4px;
|
||||
width: fit-content;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
font-family: 'Noto Sans';
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
.temporaryElement {
|
||||
padding-left: 4px;
|
||||
width: fit-content;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
font-family: 'Noto Sans';
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { TextEditorComponent } from "./text-editor.component";
|
||||
import { TextEditorComponent } from './text-editor.component';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
@ -7,34 +7,29 @@ import { Context } from '../../models/context';
|
||||
import { Renderer2 } from '@angular/core';
|
||||
|
||||
describe('TemporaryTextElementComponent', () => {
|
||||
let component: TextEditorComponent;
|
||||
let fixture: ComponentFixture<TextEditorComponent>;
|
||||
let component: TextEditorComponent;
|
||||
let fixture: ComponentFixture<TextEditorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
NoopAnimationsModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: DrawingsEventSource, useClass: DrawingsEventSource },
|
||||
{ provide: ToolsService, useClass: ToolsService },
|
||||
{ provide: Context, useClass: Context },
|
||||
{ provide: Renderer2, useClass: Renderer2 }
|
||||
],
|
||||
declarations: [
|
||||
TextEditorComponent
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: DrawingsEventSource, useClass: DrawingsEventSource },
|
||||
{ provide: ToolsService, useClass: ToolsService },
|
||||
{ provide: Context, useClass: Context },
|
||||
{ provide: Renderer2, useClass: Renderer2 }
|
||||
],
|
||||
declarations: [TextEditorComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TextEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TextEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, ViewChild, ElementRef, OnInit, Input, EventEmitter, OnDestroy, Renderer2 } from "@angular/core";
|
||||
import { Component, ViewChild, ElementRef, OnInit, Input, EventEmitter, OnDestroy, Renderer2 } from '@angular/core';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { TextAddedDataEvent, TextEditedDataEvent } from '../../events/event-source';
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
@ -7,126 +7,133 @@ import { TextElement } from '../../models/drawings/text-element';
|
||||
import { Context } from '../../models/context';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-text-editor',
|
||||
templateUrl: './text-editor.component.html',
|
||||
styleUrls: ['./text-editor.component.scss']
|
||||
selector: 'app-text-editor',
|
||||
templateUrl: './text-editor.component.html',
|
||||
styleUrls: ['./text-editor.component.scss']
|
||||
})
|
||||
export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
|
||||
leftPosition: string = '0px';
|
||||
topPosition: string = '0px';
|
||||
innerText: string = '';
|
||||
leftPosition: string = '0px';
|
||||
topPosition: string = '0px';
|
||||
innerText: string = '';
|
||||
|
||||
private editingDrawingId: string;
|
||||
private editedElement: any;
|
||||
private editingDrawingId: string;
|
||||
private editedElement: any;
|
||||
|
||||
private mapListener: Function;
|
||||
private textListener: Function;
|
||||
private textAddingSubscription: Subscription;
|
||||
public addingFinished = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private toolsService: ToolsService,
|
||||
private context: Context,
|
||||
private renderer: Renderer2
|
||||
){}
|
||||
private mapListener: Function;
|
||||
private textListener: Function;
|
||||
private textAddingSubscription: Subscription;
|
||||
public addingFinished = new EventEmitter<any>();
|
||||
|
||||
ngOnInit(){
|
||||
this.textAddingSubscription = this.toolsService.isTextAddingToolActivated.subscribe((isActive: boolean) => {
|
||||
isActive ? this.activateTextAdding() : this.deactivateTextAdding()
|
||||
});
|
||||
constructor(
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private toolsService: ToolsService,
|
||||
private context: Context,
|
||||
private renderer: Renderer2
|
||||
) {}
|
||||
|
||||
this.activateTextEditing();
|
||||
}
|
||||
ngOnInit() {
|
||||
this.textAddingSubscription = this.toolsService.isTextAddingToolActivated.subscribe((isActive: boolean) => {
|
||||
isActive ? this.activateTextAdding() : this.deactivateTextAdding();
|
||||
});
|
||||
|
||||
activateTextAdding(){
|
||||
let addTextListener = (event: MouseEvent) => {
|
||||
this.leftPosition = event.clientX.toString() + 'px';
|
||||
this.topPosition = (event.clientY + window.pageYOffset).toString() + 'px';
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||
this.temporaryTextElement.nativeElement.focus();
|
||||
this.activateTextEditing();
|
||||
}
|
||||
|
||||
let textListener = () => {
|
||||
this.drawingsEventSource.textAdded.emit(new TextAddedDataEvent(this.temporaryTextElement.nativeElement.innerText.replace(/\n$/, ""), event.clientX, event.clientY));
|
||||
this.deactivateTextAdding();
|
||||
this.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.removeEventListener("focusout", this.textListener);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'none');
|
||||
}
|
||||
this.textListener = textListener;
|
||||
this.temporaryTextElement.nativeElement.addEventListener('focusout', this.textListener);
|
||||
}
|
||||
activateTextAdding() {
|
||||
let addTextListener = (event: MouseEvent) => {
|
||||
this.leftPosition = event.clientX.toString() + 'px';
|
||||
this.topPosition = (event.clientY + window.pageYOffset).toString() + 'px';
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||
this.temporaryTextElement.nativeElement.focus();
|
||||
|
||||
let textListener = () => {
|
||||
this.drawingsEventSource.textAdded.emit(
|
||||
new TextAddedDataEvent(
|
||||
this.temporaryTextElement.nativeElement.innerText.replace(/\n$/, ''),
|
||||
event.clientX,
|
||||
event.clientY
|
||||
)
|
||||
);
|
||||
this.deactivateTextAdding();
|
||||
this.mapListener = addTextListener;
|
||||
this.svg.addEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
this.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.removeEventListener('focusout', this.textListener);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'none');
|
||||
};
|
||||
this.textListener = textListener;
|
||||
this.temporaryTextElement.nativeElement.addEventListener('focusout', this.textListener);
|
||||
};
|
||||
|
||||
deactivateTextAdding(){
|
||||
this.svg.removeEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
this.deactivateTextAdding();
|
||||
this.mapListener = addTextListener;
|
||||
this.svg.addEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
|
||||
activateTextEditing(){
|
||||
const rootElement = select(this.svg);
|
||||
deactivateTextAdding() {
|
||||
this.svg.removeEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
|
||||
rootElement.selectAll<SVGTextElement, TextElement>('text.text_element')
|
||||
.on("dblclick", (elem, index, textElements) => {
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||
this.editedElement = elem;
|
||||
activateTextEditing() {
|
||||
const rootElement = select(this.svg);
|
||||
|
||||
select(textElements[index])
|
||||
.attr("visibility", "hidden");
|
||||
rootElement
|
||||
.selectAll<SVGTextElement, TextElement>('text.text_element')
|
||||
.on('dblclick', (elem, index, textElements) => {
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||
this.editedElement = elem;
|
||||
|
||||
select(textElements[index])
|
||||
.classed("editingMode", true);
|
||||
select(textElements[index]).attr('visibility', 'hidden');
|
||||
|
||||
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute("drawing_id");
|
||||
var transformData = textElements[index].parentElement.getAttribute("transform").split(/\(|\)/);
|
||||
var x = Number(transformData[1].split(/,/)[0]) + this.context.getZeroZeroTransformationPoint().x;
|
||||
var y = Number(transformData[1].split(/,/)[1]) + this.context.getZeroZeroTransformationPoint().y;
|
||||
this.leftPosition = x.toString() + 'px';
|
||||
this.topPosition = y.toString() + 'px';
|
||||
this.temporaryTextElement.nativeElement.innerText = elem.text;
|
||||
select(textElements[index]).classed('editingMode', true);
|
||||
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'color', elem.fill);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', elem.font_family);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', `${elem.font_size}pt`);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', elem.font_weight);
|
||||
|
||||
let listener = () => {
|
||||
let innerText = this.temporaryTextElement.nativeElement.innerText;
|
||||
this.drawingsEventSource.textEdited.emit(new TextEditedDataEvent(this.editingDrawingId, innerText.replace(/\n$/, ""), this.editedElement));
|
||||
|
||||
rootElement.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||
.attr("visibility", "visible")
|
||||
.classed("editingMode", false);
|
||||
|
||||
this.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.removeEventListener("focusout", this.textListener);
|
||||
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute('drawing_id');
|
||||
var transformData = textElements[index].parentElement.getAttribute('transform').split(/\(|\)/);
|
||||
var x = Number(transformData[1].split(/,/)[0]) + this.context.getZeroZeroTransformationPoint().x;
|
||||
var y = Number(transformData[1].split(/,/)[1]) + this.context.getZeroZeroTransformationPoint().y;
|
||||
this.leftPosition = x.toString() + 'px';
|
||||
this.topPosition = y.toString() + 'px';
|
||||
this.temporaryTextElement.nativeElement.innerText = elem.text;
|
||||
|
||||
this.clearStyle();
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'none');
|
||||
};
|
||||
this.textListener = listener;
|
||||
this.temporaryTextElement.nativeElement.addEventListener("focusout", this.textListener);
|
||||
this.temporaryTextElement.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'color', elem.fill);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', elem.font_family);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', `${elem.font_size}pt`);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', elem.font_weight);
|
||||
|
||||
ngOnDestroy(){
|
||||
this.textAddingSubscription.unsubscribe();
|
||||
}
|
||||
let listener = () => {
|
||||
let innerText = this.temporaryTextElement.nativeElement.innerText;
|
||||
this.drawingsEventSource.textEdited.emit(
|
||||
new TextEditedDataEvent(this.editingDrawingId, innerText.replace(/\n$/, ''), this.editedElement)
|
||||
);
|
||||
|
||||
clearStyle(){
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'color', '#000000');
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', 'Noto Sans');
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', '11pt');
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', 'bold');
|
||||
}
|
||||
rootElement
|
||||
.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||
.attr('visibility', 'visible')
|
||||
.classed('editingMode', false);
|
||||
|
||||
this.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.removeEventListener('focusout', this.textListener);
|
||||
|
||||
this.clearStyle();
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'none');
|
||||
};
|
||||
this.textListener = listener;
|
||||
this.temporaryTextElement.nativeElement.addEventListener('focusout', this.textListener);
|
||||
this.temporaryTextElement.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.textAddingSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
clearStyle() {
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'color', '#000000');
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', 'Noto Sans');
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', '11pt');
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', 'bold');
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
export interface Converter<F, T> {
|
||||
convert(obj: F): T;
|
||||
convert(obj: F): T;
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Drawing } from "../../models/drawing";
|
||||
import { MapDrawing } from "../../models/map/map-drawing";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Drawing } from '../../models/drawing';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
|
||||
@Injectable()
|
||||
export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawing> {
|
||||
constructor(
|
||||
) {}
|
||||
|
||||
constructor() {}
|
||||
|
||||
convert(drawing: Drawing) {
|
||||
const mapDrawing = new MapDrawing();
|
||||
mapDrawing.id = drawing.drawing_id;
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Label } from "../../models/label";
|
||||
import { MapLabel } from "../../models/map/map-label";
|
||||
import { Converter } from '../converter';
|
||||
import { Label } from '../../models/label';
|
||||
import { MapLabel } from '../../models/map/map-label';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||
constructor(
|
||||
@ -15,7 +14,7 @@ export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||
private cssFixer: CssFixer,
|
||||
private fontFixer: FontFixer
|
||||
) {}
|
||||
convert(label: Label, paramaters?: {[node_id: string]: string}) {
|
||||
convert(label: Label, paramaters?: { [node_id: string]: string }) {
|
||||
const mapLabel = new MapLabel();
|
||||
mapLabel.rotation = label.rotation;
|
||||
mapLabel.style = label.style;
|
||||
@ -33,7 +32,7 @@ export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||
const fixedCss = this.cssFixer.fix(mapLabel.style);
|
||||
const fixedFont = this.fontFixer.fixStyles(fixedCss);
|
||||
const box = this.fontBBoxCalculator.calculate(mapLabel.text, fixedFont);
|
||||
|
||||
|
||||
if (mapLabel.x !== null) {
|
||||
mapLabel.x += 3;
|
||||
}
|
||||
|
@ -1,29 +1,26 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { LabelToMapLabelConverter } from "./label-to-map-label-converter";
|
||||
import { LinkNode } from "../../../models/link-node";
|
||||
import { MapLinkNode } from "../../models/map/map-link-node";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
||||
import { LinkNode } from '../../../models/link-node';
|
||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||
|
||||
@Injectable()
|
||||
export class LinkNodeToMapLinkNodeConverter implements Converter<LinkNode, MapLinkNode> {
|
||||
constructor(
|
||||
private labelToMapLabel: LabelToMapLabelConverter,
|
||||
) {}
|
||||
|
||||
convert(linkNode: LinkNode, paramaters?: {[link_id: string]: string}) {
|
||||
const mapLinkNode = new MapLinkNode();
|
||||
mapLinkNode.nodeId = linkNode.node_id;
|
||||
mapLinkNode.adapterNumber = linkNode.adapter_number;
|
||||
mapLinkNode.portNumber = linkNode.port_number;
|
||||
mapLinkNode.label = this.labelToMapLabel.convert(linkNode.label);
|
||||
constructor(private labelToMapLabel: LabelToMapLabelConverter) {}
|
||||
|
||||
if (paramaters !== undefined) {
|
||||
mapLinkNode.linkId = paramaters.link_id;
|
||||
mapLinkNode.id = `${mapLinkNode.nodeId}-${mapLinkNode.linkId}`;
|
||||
}
|
||||
convert(linkNode: LinkNode, paramaters?: { [link_id: string]: string }) {
|
||||
const mapLinkNode = new MapLinkNode();
|
||||
mapLinkNode.nodeId = linkNode.node_id;
|
||||
mapLinkNode.adapterNumber = linkNode.adapter_number;
|
||||
mapLinkNode.portNumber = linkNode.port_number;
|
||||
mapLinkNode.label = this.labelToMapLabel.convert(linkNode.label);
|
||||
|
||||
return mapLinkNode;
|
||||
if (paramaters !== undefined) {
|
||||
mapLinkNode.linkId = paramaters.link_id;
|
||||
mapLinkNode.id = `${mapLinkNode.nodeId}-${mapLinkNode.linkId}`;
|
||||
}
|
||||
|
||||
return mapLinkNode;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,23 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { LinkNodeToMapLinkNodeConverter } from "./link-node-to-map-link-node-converter";
|
||||
import { Link } from "../../../models/link";
|
||||
import { MapLink } from "../../models/map/map-link";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { LinkNodeToMapLinkNodeConverter } from './link-node-to-map-link-node-converter';
|
||||
import { Link } from '../../../models/link';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
|
||||
@Injectable()
|
||||
export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
||||
constructor(
|
||||
private linkNodeToMapLinkNode: LinkNodeToMapLinkNodeConverter
|
||||
) {}
|
||||
|
||||
convert(link: Link) {
|
||||
const mapLink = new MapLink();
|
||||
mapLink.id = link.link_id;
|
||||
mapLink.captureFileName = link.capture_file_name;
|
||||
mapLink.captureFilePath = link.capture_file_path;
|
||||
mapLink.capturing = link.capturing;
|
||||
mapLink.linkType = link.link_type;
|
||||
mapLink.nodes = link.nodes.map((linkNode) => this.linkNodeToMapLinkNode.convert(linkNode,{ link_id: link.link_id }));
|
||||
mapLink.projectId = link.project_id;
|
||||
return mapLink;
|
||||
}
|
||||
constructor(private linkNodeToMapLinkNode: LinkNodeToMapLinkNodeConverter) {}
|
||||
|
||||
convert(link: Link) {
|
||||
const mapLink = new MapLink();
|
||||
mapLink.id = link.link_id;
|
||||
mapLink.captureFileName = link.capture_file_name;
|
||||
mapLink.captureFilePath = link.capture_file_path;
|
||||
mapLink.capturing = link.capturing;
|
||||
mapLink.linkType = link.link_type;
|
||||
mapLink.nodes = link.nodes.map(linkNode => this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id }));
|
||||
mapLink.projectId = link.project_id;
|
||||
return mapLink;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,23 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Drawing } from "../../models/drawing";
|
||||
import { MapDrawing } from "../../models/map/map-drawing";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Drawing } from '../../models/drawing';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
|
||||
@Injectable()
|
||||
export class MapDrawingToDrawingConverter implements Converter<MapDrawing, Drawing> {
|
||||
constructor(
|
||||
) {}
|
||||
|
||||
convert(mapDrawing: MapDrawing) {
|
||||
const drawing = new Drawing();
|
||||
drawing.drawing_id = mapDrawing.id;
|
||||
drawing.project_id = mapDrawing.projectId;
|
||||
drawing.rotation = mapDrawing.rotation;
|
||||
drawing.svg = mapDrawing.svg;
|
||||
drawing.x = mapDrawing.x;
|
||||
drawing.y = mapDrawing.y;
|
||||
drawing.z = mapDrawing.z;
|
||||
drawing.element = mapDrawing.element;
|
||||
return drawing;
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
convert(mapDrawing: MapDrawing) {
|
||||
const drawing = new Drawing();
|
||||
drawing.drawing_id = mapDrawing.id;
|
||||
drawing.project_id = mapDrawing.projectId;
|
||||
drawing.rotation = mapDrawing.rotation;
|
||||
drawing.svg = mapDrawing.svg;
|
||||
drawing.x = mapDrawing.x;
|
||||
drawing.y = mapDrawing.y;
|
||||
drawing.z = mapDrawing.z;
|
||||
drawing.element = mapDrawing.element;
|
||||
return drawing;
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,37 @@ import { EllipseElement } from '../../models/drawings/ellipse-element';
|
||||
import { LineElement } from '../../models/drawings/line-element';
|
||||
import { TextElement } from '../../models/drawings/text-element';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
||||
constructor(
|
||||
) {}
|
||||
constructor() {}
|
||||
|
||||
convert(mapDrawing: MapDrawing) {
|
||||
let elem = ``;
|
||||
|
||||
if (mapDrawing.element instanceof RectElement) {
|
||||
elem = `<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" />`;
|
||||
} else if (mapDrawing.element instanceof EllipseElement) {
|
||||
elem = `<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${mapDrawing.element.cx}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" />`;
|
||||
} else if (mapDrawing.element instanceof LineElement) {
|
||||
elem = `<line stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" x1=\"${mapDrawing.element.x1}\" x2=\"${mapDrawing.element.x2}\" y1=\"${mapDrawing.element.y1}\" y2=\"${mapDrawing.element.y2}\" />`
|
||||
} else if (mapDrawing.element instanceof TextElement) {
|
||||
elem = `<text fill=\"${mapDrawing.element.fill}\" fill-opacity=\"1.0\" font-family=\"${mapDrawing.element.font_family}\" font-size=\"${mapDrawing.element.font_size}\" font-weight=\"${mapDrawing.element.font_weight}\">${mapDrawing.element.text}</text>`;
|
||||
} else return "";
|
||||
convert(mapDrawing: MapDrawing) {
|
||||
let elem = ``;
|
||||
|
||||
return `<svg height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\">${elem}</svg>`;
|
||||
}
|
||||
}
|
||||
if (mapDrawing.element instanceof RectElement) {
|
||||
elem = `<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${
|
||||
mapDrawing.element.height
|
||||
}\" width=\"${mapDrawing.element.width}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${
|
||||
mapDrawing.element.stroke_width
|
||||
}\" />`;
|
||||
} else if (mapDrawing.element instanceof EllipseElement) {
|
||||
elem = `<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${
|
||||
mapDrawing.element.cx
|
||||
}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" stroke=\"${
|
||||
mapDrawing.element.stroke
|
||||
}\" stroke-width=\"${mapDrawing.element.stroke_width}\" />`;
|
||||
} else if (mapDrawing.element instanceof LineElement) {
|
||||
elem = `<line stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" x1=\"${
|
||||
mapDrawing.element.x1
|
||||
}\" x2=\"${mapDrawing.element.x2}\" y1=\"${mapDrawing.element.y1}\" y2=\"${mapDrawing.element.y2}\" />`;
|
||||
} else if (mapDrawing.element instanceof TextElement) {
|
||||
elem = `<text fill=\"${mapDrawing.element.fill}\" fill-opacity=\"1.0\" font-family=\"${
|
||||
mapDrawing.element.font_family
|
||||
}\" font-size=\"${mapDrawing.element.font_size}\" font-weight=\"${mapDrawing.element.font_weight}\">${
|
||||
mapDrawing.element.text
|
||||
}</text>`;
|
||||
} else return '';
|
||||
|
||||
return `<svg height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\">${elem}</svg>`;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Label } from "../../models/label";
|
||||
import { MapLabel } from "../../models/map/map-label";
|
||||
import { Converter } from '../converter';
|
||||
import { Label } from '../../models/label';
|
||||
import { MapLabel } from '../../models/map/map-label';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class MapLabelToLabelConverter implements Converter<MapLabel, Label> {
|
||||
constructor(
|
||||
|
@ -1,23 +1,20 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { MapLinkNode } from "../../models/map/map-link-node";
|
||||
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
|
||||
import { LinkNode } from "../../../models/link-node";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||
import { MapLabelToLabelConverter } from './map-label-to-label-converter';
|
||||
import { LinkNode } from '../../../models/link-node';
|
||||
|
||||
@Injectable()
|
||||
export class MapLinkNodeToLinkNodeConverter implements Converter<MapLinkNode, LinkNode> {
|
||||
constructor(
|
||||
private mapLabelToLabel: MapLabelToLabelConverter
|
||||
) {}
|
||||
|
||||
convert(mapLinkNode: MapLinkNode) {
|
||||
const linkNode = new LinkNode();
|
||||
linkNode.node_id = mapLinkNode.nodeId;
|
||||
linkNode.adapter_number = mapLinkNode.adapterNumber;
|
||||
linkNode.port_number = mapLinkNode.portNumber;
|
||||
linkNode.label = this.mapLabelToLabel.convert(mapLinkNode.label);
|
||||
return linkNode;
|
||||
}
|
||||
constructor(private mapLabelToLabel: MapLabelToLabelConverter) {}
|
||||
|
||||
convert(mapLinkNode: MapLinkNode) {
|
||||
const linkNode = new LinkNode();
|
||||
linkNode.node_id = mapLinkNode.nodeId;
|
||||
linkNode.adapter_number = mapLinkNode.adapterNumber;
|
||||
linkNode.port_number = mapLinkNode.portNumber;
|
||||
linkNode.label = this.mapLabelToLabel.convert(mapLinkNode.label);
|
||||
return linkNode;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,23 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { MapLinkNodeToLinkNodeConverter } from "./map-link-node-to-link-node-converter";
|
||||
import { Link } from "../../../models/link";
|
||||
import { MapLink } from "../../models/map/map-link";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapLinkNodeToLinkNodeConverter } from './map-link-node-to-link-node-converter';
|
||||
import { Link } from '../../../models/link';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
|
||||
@Injectable()
|
||||
export class MapLinkToLinkConverter implements Converter<MapLink, Link> {
|
||||
constructor(
|
||||
private mapLinkNodeToMapLinkNode: MapLinkNodeToLinkNodeConverter
|
||||
) {}
|
||||
constructor(private mapLinkNodeToMapLinkNode: MapLinkNodeToLinkNodeConverter) {}
|
||||
|
||||
convert(mapLink: MapLink) {
|
||||
const link = new Link();
|
||||
link.link_id = mapLink.id;
|
||||
link.capture_file_name = mapLink.captureFileName;
|
||||
link.capture_file_path = mapLink.captureFilePath;
|
||||
link.capturing = mapLink.capturing;
|
||||
link.link_type = mapLink.linkType;
|
||||
link.nodes = mapLink.nodes.map((mapLinkNode) => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||
link.project_id = mapLink.projectId;
|
||||
return link;
|
||||
}
|
||||
convert(mapLink: MapLink) {
|
||||
const link = new Link();
|
||||
link.link_id = mapLink.id;
|
||||
link.capture_file_name = mapLink.captureFileName;
|
||||
link.capture_file_path = mapLink.captureFilePath;
|
||||
link.capturing = mapLink.capturing;
|
||||
link.link_type = mapLink.linkType;
|
||||
link.nodes = mapLink.nodes.map(mapLinkNode => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||
link.project_id = mapLink.projectId;
|
||||
return link;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,15 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { MapNode } from "../../models/map/map-node";
|
||||
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
|
||||
import { MapPortToPortConverter } from "./map-port-to-port-converter";
|
||||
import { Node } from "../../models/node";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapNode } from '../../models/map/map-node';
|
||||
import { MapLabelToLabelConverter } from './map-label-to-label-converter';
|
||||
import { MapPortToPortConverter } from './map-port-to-port-converter';
|
||||
import { Node } from '../../models/node';
|
||||
|
||||
@Injectable()
|
||||
export class MapNodeToNodeConverter implements Converter<MapNode, Node> {
|
||||
constructor(
|
||||
private mapLabelToLabel: MapLabelToLabelConverter,
|
||||
private mapPortToPort: MapPortToPortConverter
|
||||
) {}
|
||||
|
||||
constructor(private mapLabelToLabel: MapLabelToLabelConverter, private mapPortToPort: MapPortToPortConverter) {}
|
||||
|
||||
convert(mapNode: MapNode) {
|
||||
const node = new Node();
|
||||
node.node_id = mapNode.id;
|
||||
@ -29,7 +25,7 @@ export class MapNodeToNodeConverter implements Converter<MapNode, Node> {
|
||||
node.node_type = mapNode.nodeType;
|
||||
node.port_name_format = mapNode.portNameFormat;
|
||||
node.port_segment_size = mapNode.portSegmentSize;
|
||||
node.ports = mapNode.ports ? mapNode.ports.map((mapPort) => this.mapPortToPort.convert(mapPort)) : [];
|
||||
node.ports = mapNode.ports ? mapNode.ports.map(mapPort => this.mapPortToPort.convert(mapPort)) : [];
|
||||
node.project_id = mapNode.projectId;
|
||||
node.status = mapNode.status;
|
||||
node.symbol = mapNode.symbol;
|
||||
|
@ -1,19 +1,18 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Port } from "../../../models/port";
|
||||
import { MapPort } from "../../models/map/map-port";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Port } from '../../../models/port';
|
||||
import { MapPort } from '../../models/map/map-port';
|
||||
|
||||
@Injectable()
|
||||
export class MapPortToPortConverter implements Converter<MapPort, Port> {
|
||||
convert(mapPort: MapPort) {
|
||||
const port = new Port();
|
||||
port.adapter_number = mapPort.adapterNumber;
|
||||
port.link_type = mapPort.linkType;
|
||||
port.name = mapPort.name;
|
||||
port.port_number = mapPort.portNumber;
|
||||
port.short_name = mapPort.shortName;
|
||||
return port;
|
||||
}
|
||||
convert(mapPort: MapPort) {
|
||||
const port = new Port();
|
||||
port.adapter_number = mapPort.adapterNumber;
|
||||
port.link_type = mapPort.linkType;
|
||||
port.name = mapPort.name;
|
||||
port.port_number = mapPort.portNumber;
|
||||
port.short_name = mapPort.shortName;
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { MapSymbol } from "../../models/map/map-symbol";
|
||||
import { Symbol } from "../../../models/symbol";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapSymbol } from '../../models/map/map-symbol';
|
||||
import { Symbol } from '../../../models/symbol';
|
||||
|
||||
@Injectable()
|
||||
export class MapSymbolToSymbolConverter implements Converter<MapSymbol, Symbol> {
|
||||
convert(mapSymbol: MapSymbol) {
|
||||
const symbol = new Symbol();
|
||||
symbol.symbol_id = mapSymbol.id;
|
||||
symbol.builtin = mapSymbol.builtin;
|
||||
symbol.filename = mapSymbol.filename;
|
||||
symbol.raw = mapSymbol.raw;
|
||||
return symbol;
|
||||
}
|
||||
convert(mapSymbol: MapSymbol) {
|
||||
const symbol = new Symbol();
|
||||
symbol.symbol_id = mapSymbol.id;
|
||||
symbol.builtin = mapSymbol.builtin;
|
||||
symbol.filename = mapSymbol.filename;
|
||||
symbol.raw = mapSymbol.raw;
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { MapNode } from "../../models/map/map-node";
|
||||
import { Node } from "../../models/node";
|
||||
import { LabelToMapLabelConverter } from "./label-to-map-label-converter";
|
||||
import { PortToMapPortConverter } from "./port-to-map-port-converter";
|
||||
import { Converter } from '../converter';
|
||||
import { MapNode } from '../../models/map/map-node';
|
||||
import { Node } from '../../models/node';
|
||||
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
||||
import { PortToMapPortConverter } from './port-to-map-port-converter';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
||||
constructor(
|
||||
@ -19,7 +18,7 @@ export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
||||
private cssFixer: CssFixer,
|
||||
private fontFixer: FontFixer
|
||||
) {}
|
||||
|
||||
|
||||
convert(node: Node) {
|
||||
const mapNode = new MapNode();
|
||||
mapNode.id = node.node_id;
|
||||
@ -35,7 +34,7 @@ export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
||||
mapNode.nodeType = node.node_type;
|
||||
mapNode.portNameFormat = node.port_name_format;
|
||||
mapNode.portSegmentSize = node.port_segment_size;
|
||||
mapNode.ports = node.ports.map((port) => this.portToMapPort.convert(port));
|
||||
mapNode.ports = node.ports.map(port => this.portToMapPort.convert(port));
|
||||
mapNode.projectId = node.project_id;
|
||||
mapNode.status = node.status;
|
||||
mapNode.symbol = node.symbol;
|
||||
@ -45,17 +44,16 @@ export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
||||
mapNode.y = node.y;
|
||||
mapNode.z = node.z;
|
||||
|
||||
|
||||
if (mapNode.label !== undefined) {
|
||||
const fixedCss = this.cssFixer.fix(mapNode.label.style);
|
||||
const fixedFont = this.fontFixer.fixStyles(fixedCss);
|
||||
const box = this.fontBBoxCalculator.calculate(mapNode.label.text, fixedFont);
|
||||
|
||||
if (node.label.x === null || node.label.y === null) {
|
||||
mapNode.label.x = node.width / 2. - box.width / 2. + 3;
|
||||
mapNode.label.x = node.width / 2 - box.width / 2 + 3;
|
||||
mapNode.label.y = -8;
|
||||
}
|
||||
}
|
||||
return mapNode;
|
||||
return mapNode;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Port } from "../../../models/port";
|
||||
import { MapPort } from "../../models/map/map-port";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Port } from '../../../models/port';
|
||||
import { MapPort } from '../../models/map/map-port';
|
||||
|
||||
@Injectable()
|
||||
export class PortToMapPortConverter implements Converter<Port, MapPort> {
|
||||
convert(port: Port) {
|
||||
const mapPort = new MapPort();
|
||||
mapPort.adapterNumber = port.adapter_number;
|
||||
mapPort.linkType = port.link_type;
|
||||
mapPort.name = port.name;
|
||||
mapPort.portNumber = port.port_number;
|
||||
mapPort.shortName = port.short_name;
|
||||
return mapPort;
|
||||
}
|
||||
convert(port: Port) {
|
||||
const mapPort = new MapPort();
|
||||
mapPort.adapterNumber = port.adapter_number;
|
||||
mapPort.linkType = port.link_type;
|
||||
mapPort.name = port.name;
|
||||
mapPort.portNumber = port.port_number;
|
||||
mapPort.shortName = port.short_name;
|
||||
return mapPort;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Converter } from "../converter";
|
||||
import { Symbol } from "../../../models/symbol";
|
||||
import { MapSymbol } from "../../models/map/map-symbol";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Symbol } from '../../../models/symbol';
|
||||
import { MapSymbol } from '../../models/map/map-symbol';
|
||||
|
||||
@Injectable()
|
||||
export class SymbolToMapSymbolConverter implements Converter<Symbol, MapSymbol> {
|
||||
convert(symbol: Symbol) {
|
||||
const mapSymbol = new MapSymbol();
|
||||
mapSymbol.id = symbol.symbol_id;
|
||||
mapSymbol.builtin = symbol.builtin;
|
||||
mapSymbol.filename = symbol.filename;
|
||||
mapSymbol.raw = symbol.raw;
|
||||
return mapSymbol;
|
||||
}
|
||||
convert(symbol: Symbol) {
|
||||
const mapSymbol = new MapSymbol();
|
||||
mapSymbol.id = symbol.symbol_id;
|
||||
mapSymbol.builtin = symbol.builtin;
|
||||
mapSymbol.filename = symbol.filename;
|
||||
mapSymbol.raw = symbol.raw;
|
||||
return mapSymbol;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Font } from "../models/font";
|
||||
import { Font } from '../models/font';
|
||||
import { StylesToFontConverter } from './styles-to-font-converter';
|
||||
|
||||
|
||||
describe('StylesToFontConverter', () => {
|
||||
let converter: StylesToFontConverter;
|
||||
|
||||
@ -10,15 +9,14 @@ describe('StylesToFontConverter', () => {
|
||||
});
|
||||
|
||||
it('should parse fonts from styles', () => {
|
||||
const styles = "font-family: TypeWriter; font-size: 10px; font-weight: bold";
|
||||
const styles = 'font-family: TypeWriter; font-size: 10px; font-weight: bold';
|
||||
|
||||
const expectedFont: Font = {
|
||||
'font_family': 'TypeWriter',
|
||||
'font_size': 10,
|
||||
'font_weight': 'bold'
|
||||
font_family: 'TypeWriter',
|
||||
font_size: 10,
|
||||
font_weight: 'bold'
|
||||
};
|
||||
|
||||
expect(converter.convert(styles)).toEqual(expectedFont);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,41 +1,40 @@
|
||||
import * as csstree from 'css-tree';
|
||||
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Converter } from './converter';
|
||||
import { Font } from '../models/font';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class StylesToFontConverter implements Converter<string, Font> {
|
||||
convert(styles: string) {
|
||||
const font: Font = {
|
||||
'font_family': undefined,
|
||||
'font_size': undefined,
|
||||
'font_weight': undefined
|
||||
font_family: undefined,
|
||||
font_size: undefined,
|
||||
font_weight: undefined
|
||||
};
|
||||
|
||||
const ast = csstree.parse(styles, {
|
||||
'context': 'declarationList'
|
||||
context: 'declarationList'
|
||||
});
|
||||
|
||||
ast.children.forEach((child) => {
|
||||
ast.children.forEach(child => {
|
||||
if (child.property === 'font-size') {
|
||||
child.value.children.forEach((value) => {
|
||||
child.value.children.forEach(value => {
|
||||
if (value.type === 'Dimension') {
|
||||
font.font_size = parseInt(value.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (child.property === 'font-family') {
|
||||
child.value.children.forEach((value) => {
|
||||
if (value.type === "Identifier") {
|
||||
child.value.children.forEach(value => {
|
||||
if (value.type === 'Identifier') {
|
||||
font.font_family = value.name;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (child.property === 'font-weight') {
|
||||
child.value.children.forEach((value) => {
|
||||
if (value.type === "Identifier") {
|
||||
child.value.children.forEach(value => {
|
||||
if (value.type === 'Identifier') {
|
||||
font.font_weight = value.name;
|
||||
}
|
||||
});
|
||||
|
@ -19,23 +19,23 @@ import { DrawingWidget } from './widgets/drawing';
|
||||
import { LabelWidget } from './widgets/label';
|
||||
|
||||
export const D3_MAP_IMPORTS = [
|
||||
GraphLayout,
|
||||
LinksWidget,
|
||||
NodesWidget,
|
||||
NodeWidget,
|
||||
LabelWidget,
|
||||
DrawingsWidget,
|
||||
DrawingLineWidget,
|
||||
SelectionTool,
|
||||
MovingTool,
|
||||
LayersWidget,
|
||||
LinkWidget,
|
||||
InterfaceStatusWidget,
|
||||
InterfaceLabelWidget,
|
||||
EllipseDrawingWidget,
|
||||
ImageDrawingWidget,
|
||||
LineDrawingWidget,
|
||||
RectDrawingWidget,
|
||||
TextDrawingWidget,
|
||||
DrawingWidget
|
||||
GraphLayout,
|
||||
LinksWidget,
|
||||
NodesWidget,
|
||||
NodeWidget,
|
||||
LabelWidget,
|
||||
DrawingsWidget,
|
||||
DrawingLineWidget,
|
||||
SelectionTool,
|
||||
MovingTool,
|
||||
LayersWidget,
|
||||
LinkWidget,
|
||||
InterfaceStatusWidget,
|
||||
InterfaceLabelWidget,
|
||||
EllipseDrawingWidget,
|
||||
ImageDrawingWidget,
|
||||
LineDrawingWidget,
|
||||
RectDrawingWidget,
|
||||
TextDrawingWidget,
|
||||
DrawingWidget
|
||||
];
|
||||
|
@ -1,17 +1,15 @@
|
||||
import { DataSource } from "./datasource";
|
||||
import { DataSource } from './datasource';
|
||||
|
||||
class Item {
|
||||
constructor(public id: string, public property1?: string, public property2?: string) {}
|
||||
}
|
||||
|
||||
|
||||
class TestDataSource extends DataSource<Item> {
|
||||
protected getItemKey(item: Item) {
|
||||
return item.id;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
describe('TestDataSource', () => {
|
||||
let dataSource: TestDataSource;
|
||||
let data: Item[];
|
||||
@ -25,72 +23,65 @@ describe('TestDataSource', () => {
|
||||
|
||||
describe('Item can be added', () => {
|
||||
beforeEach(() => {
|
||||
dataSource.add(new Item("test1", "property1"));
|
||||
dataSource.add(new Item('test1', 'property1'));
|
||||
});
|
||||
|
||||
it('item should be in data', () => {
|
||||
expect(data).toEqual([new Item("test1", "property1")]);
|
||||
expect(data).toEqual([new Item('test1', 'property1')]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Item can be added when key duplocates', () => {
|
||||
beforeEach(() => {
|
||||
dataSource.add(new Item("test1", "property1"));
|
||||
dataSource.add(new Item("test1", "property2"));
|
||||
dataSource.add(new Item('test1', 'property1'));
|
||||
dataSource.add(new Item('test1', 'property2'));
|
||||
});
|
||||
|
||||
it('item should be in data', () => {
|
||||
expect(data).toEqual([new Item("test1", "property2")]);
|
||||
expect(data).toEqual([new Item('test1', 'property2')]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Items can be set', () => {
|
||||
beforeEach(() => {
|
||||
dataSource.set([new Item("test1", "property1"), new Item("test2", "property2")]);
|
||||
dataSource.set([new Item('test1', 'property1'), new Item('test2', 'property2')]);
|
||||
});
|
||||
|
||||
it('items should be in data', () => {
|
||||
expect(data).toEqual([new Item("test1", "property1"), new Item("test2", "property2")]);
|
||||
expect(data).toEqual([new Item('test1', 'property1'), new Item('test2', 'property2')]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Items can be removed', () => {
|
||||
beforeEach(() => {
|
||||
dataSource.set([new Item("test1", "property1"), new Item("test2", "property2")]);
|
||||
dataSource.remove(new Item("test1", "property1"));
|
||||
dataSource.set([new Item('test1', 'property1'), new Item('test2', 'property2')]);
|
||||
dataSource.remove(new Item('test1', 'property1'));
|
||||
});
|
||||
|
||||
it('item should not be in data', () => {
|
||||
expect(data).toEqual([new Item("test2", "property2")]);
|
||||
expect(data).toEqual([new Item('test2', 'property2')]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Item can be updated', () => {
|
||||
beforeEach(() => {
|
||||
dataSource.set([new Item("test1", "property1", "another"), new Item("test2", "property2")]);
|
||||
dataSource.update(new Item("test1", "property3"));
|
||||
dataSource.set([new Item('test1', 'property1', 'another'), new Item('test2', 'property2')]);
|
||||
dataSource.update(new Item('test1', 'property3'));
|
||||
});
|
||||
|
||||
it('item should be updated', () => {
|
||||
expect(data).toEqual([
|
||||
new Item("test1", "property3"),
|
||||
new Item("test2", "property2")
|
||||
]);
|
||||
expect(data).toEqual([new Item('test1', 'property3'), new Item('test2', 'property2')]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Items should be cleared', () => {
|
||||
beforeEach(() => {
|
||||
dataSource.set([new Item("test1", "property1", "another"), new Item("test2", "property2")]);
|
||||
dataSource.set([new Item('test1', 'property1', 'another'), new Item('test2', 'property2')]);
|
||||
dataSource.clear();
|
||||
});
|
||||
|
||||
it('items should be cleared', () => {
|
||||
expect(data).toEqual([]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BehaviorSubject, Subject } from "rxjs";
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
|
||||
export abstract class DataSource<T> {
|
||||
protected data: T[] = [];
|
||||
@ -20,19 +20,20 @@ export abstract class DataSource<T> {
|
||||
}
|
||||
|
||||
public set(data: T[]) {
|
||||
data.forEach((item) => {
|
||||
data.forEach(item => {
|
||||
const index = this.findIndex(item);
|
||||
if (index >= 0) {
|
||||
const updated = Object.assign(this.data[index], item);
|
||||
this.data[index] = updated;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.data.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
const toRemove = this.data.filter((item) => data.filter((i) => this.getItemKey(i) === this.getItemKey(item)).length === 0);
|
||||
toRemove.forEach((item) => this.remove(item));
|
||||
|
||||
const toRemove = this.data.filter(
|
||||
item => data.filter(i => this.getItemKey(i) === this.getItemKey(item)).length === 0
|
||||
);
|
||||
toRemove.forEach(item => this.remove(item));
|
||||
|
||||
this.dataChange.next(this.data);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { DrawingsDataSource } from "./drawings-datasource";
|
||||
import { Drawing } from "../models/drawing";
|
||||
|
||||
import { DrawingsDataSource } from './drawings-datasource';
|
||||
import { Drawing } from '../models/drawing';
|
||||
|
||||
describe('DrawingsDataSource', () => {
|
||||
let dataSource: DrawingsDataSource;
|
||||
@ -16,18 +15,17 @@ describe('DrawingsDataSource', () => {
|
||||
describe('Drawing can be updated', () => {
|
||||
beforeEach(() => {
|
||||
const drawing = new Drawing();
|
||||
drawing.drawing_id = "1";
|
||||
drawing.project_id = "project1";
|
||||
drawing.drawing_id = '1';
|
||||
drawing.project_id = 'project1';
|
||||
dataSource.add(drawing);
|
||||
|
||||
drawing.project_id = "project2";
|
||||
drawing.project_id = 'project2';
|
||||
dataSource.update(drawing);
|
||||
});
|
||||
|
||||
it('project_id should change', () => {
|
||||
expect(data[0].drawing_id).toEqual("1");
|
||||
expect(data[0].project_id).toEqual("project2");
|
||||
expect(data[0].drawing_id).toEqual('1');
|
||||
expect(data[0].project_id).toEqual('project2');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { DataSource } from "./datasource";
|
||||
import { Drawing } from "../models/drawing";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { DataSource } from './datasource';
|
||||
import { Drawing } from '../models/drawing';
|
||||
|
||||
@Injectable()
|
||||
export class DrawingsDataSource extends DataSource<Drawing> {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { LinksDataSource } from "./links-datasource";
|
||||
import { Link } from "../../models/link";
|
||||
|
||||
import { LinksDataSource } from './links-datasource';
|
||||
import { Link } from '../../models/link';
|
||||
|
||||
describe('LinksDataSource', () => {
|
||||
let dataSource: LinksDataSource;
|
||||
@ -16,18 +15,17 @@ describe('LinksDataSource', () => {
|
||||
describe('Link can be updated', () => {
|
||||
beforeEach(() => {
|
||||
const link = new Link();
|
||||
link.link_id = "1";
|
||||
link.project_id = "project-1";
|
||||
link.link_id = '1';
|
||||
link.project_id = 'project-1';
|
||||
dataSource.add(link);
|
||||
|
||||
link.project_id = "project-2";
|
||||
link.project_id = 'project-2';
|
||||
dataSource.update(link);
|
||||
});
|
||||
|
||||
it('project_id should change', () => {
|
||||
expect(data[0].link_id).toEqual("1");
|
||||
expect(data[0].project_id).toEqual("project-2");
|
||||
expect(data[0].link_id).toEqual('1');
|
||||
expect(data[0].project_id).toEqual('project-2');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { DataSource } from "./datasource";
|
||||
import { Link } from "../../models/link";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { DataSource } from './datasource';
|
||||
import { Link } from '../../models/link';
|
||||
|
||||
@Injectable()
|
||||
export class LinksDataSource extends DataSource<Link> {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { DataSource } from "./datasource";
|
||||
import { MapNode } from "../models/map/map-node";
|
||||
import { MapLink } from "../models/map/map-link";
|
||||
import { MapDrawing } from "../models/map/map-drawing";
|
||||
import { MapSymbol } from "../models/map/map-symbol";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { DataSource } from './datasource';
|
||||
import { MapNode } from '../models/map/map-node';
|
||||
import { MapLink } from '../models/map/map-link';
|
||||
import { MapDrawing } from '../models/map/map-drawing';
|
||||
import { MapSymbol } from '../models/map/map-symbol';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface Indexed {
|
||||
id: number | string;
|
||||
@ -25,4 +25,4 @@ export class MapLinksDataSource extends MapDataSource<MapLink> {}
|
||||
export class MapDrawingsDataSource extends MapDataSource<MapDrawing> {}
|
||||
|
||||
@Injectable()
|
||||
export class MapSymbolsDataSource extends MapDataSource<MapSymbol> {}
|
||||
export class MapSymbolsDataSource extends MapDataSource<MapSymbol> {}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { NodesDataSource } from "./nodes-datasource";
|
||||
import { Node } from "../models/node";
|
||||
|
||||
import { NodesDataSource } from './nodes-datasource';
|
||||
import { Node } from '../models/node';
|
||||
|
||||
describe('NodesDataSource', () => {
|
||||
let dataSource: NodesDataSource;
|
||||
@ -16,18 +15,17 @@ describe('NodesDataSource', () => {
|
||||
describe('Node can be updated', () => {
|
||||
beforeEach(() => {
|
||||
const node = new Node();
|
||||
node.node_id = "1";
|
||||
node.name = "Node 1";
|
||||
node.node_id = '1';
|
||||
node.name = 'Node 1';
|
||||
dataSource.add(node);
|
||||
|
||||
node.name = "Node 2";
|
||||
node.name = 'Node 2';
|
||||
dataSource.update(node);
|
||||
});
|
||||
|
||||
it('name should change', () => {
|
||||
expect(data[0].node_id).toEqual("1");
|
||||
expect(data[0].name).toEqual("Node 2");
|
||||
expect(data[0].node_id).toEqual('1');
|
||||
expect(data[0].name).toEqual('Node 2');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { Node } from "../models/node";
|
||||
import { DataSource } from "./datasource";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Node } from '../models/node';
|
||||
import { DataSource } from './datasource';
|
||||
|
||||
@Injectable()
|
||||
export class NodesDataSource extends DataSource<Node> {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { SymbolsDataSource } from "./symbols-datasource";
|
||||
import { Symbol } from "../../models/symbol";
|
||||
|
||||
import { SymbolsDataSource } from './symbols-datasource';
|
||||
import { Symbol } from '../../models/symbol';
|
||||
|
||||
describe('SymbolsDataSource', () => {
|
||||
let dataSource: SymbolsDataSource;
|
||||
@ -16,18 +15,17 @@ describe('SymbolsDataSource', () => {
|
||||
describe('Symbol can be updated', () => {
|
||||
beforeEach(() => {
|
||||
const symbol = new Symbol();
|
||||
symbol.symbol_id = "1";
|
||||
symbol.filename = "test-1";
|
||||
symbol.symbol_id = '1';
|
||||
symbol.filename = 'test-1';
|
||||
dataSource.add(symbol);
|
||||
|
||||
symbol.filename = "test-2";
|
||||
symbol.filename = 'test-2';
|
||||
dataSource.update(symbol);
|
||||
});
|
||||
|
||||
it('filename should change', () => {
|
||||
expect(data[0].symbol_id).toEqual("1");
|
||||
expect(data[0].filename).toEqual("test-2");
|
||||
expect(data[0].symbol_id).toEqual('1');
|
||||
expect(data[0].filename).toEqual('test-2');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { DataSource } from "./datasource";
|
||||
import { Symbol } from "../../models/symbol";
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { DataSource } from './datasource';
|
||||
import { Symbol } from '../../models/symbol';
|
||||
|
||||
@Injectable()
|
||||
export class SymbolsDataSource extends DataSource<Symbol> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { EventEmitter } from "@angular/core";
|
||||
import { drag, DraggedElementBaseType } from "d3-drag";
|
||||
import { event } from "d3-selection";
|
||||
import { EventEmitter } from '@angular/core';
|
||||
import { drag, DraggedElementBaseType } from 'd3-drag';
|
||||
import { event } from 'd3-selection';
|
||||
|
||||
class DraggableEvent {
|
||||
public x: number;
|
||||
@ -10,25 +10,19 @@ class DraggableEvent {
|
||||
}
|
||||
|
||||
export class DraggableStart<T> extends DraggableEvent {
|
||||
constructor(
|
||||
public datum: T
|
||||
){
|
||||
constructor(public datum: T) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class DraggableDrag<T> extends DraggableEvent {
|
||||
constructor(
|
||||
public datum: T
|
||||
){
|
||||
constructor(public datum: T) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class DraggableEnd<T> extends DraggableEvent {
|
||||
constructor(
|
||||
public datum: T
|
||||
){
|
||||
constructor(public datum: T) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@ -73,4 +67,4 @@ export class Draggable<GElement extends DraggedElementBaseType, Datum> {
|
||||
this.end.emit(evt);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,12 @@
|
||||
import { Injectable, EventEmitter } from "@angular/core";
|
||||
import { DraggedDataEvent, ResizedDataEvent, TextAddedDataEvent, TextEditedDataEvent, AddedDataEvent } from "./event-source";
|
||||
import { MapDrawing } from "../models/map/map-drawing";
|
||||
|
||||
import { Injectable, EventEmitter } from '@angular/core';
|
||||
import {
|
||||
DraggedDataEvent,
|
||||
ResizedDataEvent,
|
||||
TextAddedDataEvent,
|
||||
TextEditedDataEvent,
|
||||
AddedDataEvent
|
||||
} from './event-source';
|
||||
import { MapDrawing } from '../models/map/map-drawing';
|
||||
|
||||
@Injectable()
|
||||
export class DrawingsEventSource {
|
||||
@ -10,7 +15,7 @@ export class DrawingsEventSource {
|
||||
public selected = new EventEmitter<string>();
|
||||
public pointToAddSelected = new EventEmitter<AddedDataEvent>();
|
||||
public saved = new EventEmitter<any>();
|
||||
|
||||
|
||||
public textAdded = new EventEmitter<TextAddedDataEvent>();
|
||||
public textEdited = new EventEmitter<TextEditedDataEvent>();
|
||||
public textSaved = new EventEmitter<any>();
|
||||
|
@ -2,59 +2,31 @@ import { TextElement } from '../models/drawings/text-element';
|
||||
import { MapDrawing } from '../models/map/map-drawing';
|
||||
|
||||
export class DataEventSource<T> {
|
||||
constructor(
|
||||
public datum: T,
|
||||
public dx: number,
|
||||
public dy: number
|
||||
) {}
|
||||
constructor(public datum: T, public dx: number, public dy: number) {}
|
||||
}
|
||||
|
||||
export class DraggedDataEvent<T> extends DataEventSource<T> {}
|
||||
|
||||
export class ResizedDataEvent<T> {
|
||||
constructor(
|
||||
public datum: T,
|
||||
public x: number,
|
||||
public y: number,
|
||||
public width: number,
|
||||
public height: number
|
||||
) {}
|
||||
constructor(public datum: T, public x: number, public y: number, public width: number, public height: number) {}
|
||||
}
|
||||
|
||||
export class AddedDataEvent {
|
||||
constructor(
|
||||
public x: number,
|
||||
public y: number
|
||||
) {}
|
||||
constructor(public x: number, public y: number) {}
|
||||
}
|
||||
|
||||
export class ClickedDataEvent<T> {
|
||||
constructor(
|
||||
public datum: T,
|
||||
public x: number,
|
||||
public y: number
|
||||
) {}
|
||||
constructor(public datum: T, public x: number, public y: number) {}
|
||||
}
|
||||
|
||||
export class TextAddedDataEvent {
|
||||
constructor(
|
||||
public savedText: string,
|
||||
public x: number,
|
||||
public y: number
|
||||
) {}
|
||||
constructor(public savedText: string, public x: number, public y: number) {}
|
||||
}
|
||||
|
||||
export class TextEditedDataEvent {
|
||||
constructor(
|
||||
public textDrawingId: string,
|
||||
public editedText: string,
|
||||
public textElement: TextElement
|
||||
) {}
|
||||
constructor(public textDrawingId: string, public editedText: string, public textElement: TextElement) {}
|
||||
}
|
||||
|
||||
export class DrawingContextMenu {
|
||||
constructor(
|
||||
public event: any,
|
||||
public drawing: MapDrawing
|
||||
) {}
|
||||
constructor(public event: any, public drawing: MapDrawing) {}
|
||||
}
|
||||
|