Skip to content

Commit c43e9cd

Browse files
authored
Merge pull request #41 from funktechno/f/updates
improved fk line support and recursive fk
2 parents 1c20778 + ad02326 commit c43e9cd

File tree

6 files changed

+748
-743
lines changed

6 files changed

+748
-743
lines changed

src/nosql-ts.ts

Lines changed: 8 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { convertCoreTypesToJsonSchema, convertOpenApiToCoreTypes, jsonSchemaDocu
66
import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openapi-json-schema";
77
import { convertTypeScriptToCoreTypes } from "core-types-ts/dist/lib/ts-to-core-types";
88
import { convertCoreTypesToTypeScript } from "core-types-ts";
9-
import { GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils";
9+
import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils";
1010
import { pluginVersion } from "./utils/constants";
1111
import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils";
1212
import { defaultReset, defaultResetOpenApi } from "./utils/constants-nosql";
@@ -146,36 +146,6 @@ Draw.loadPlugin(function(ui) {
146146
wndFromNOSQL.setResizable(false);
147147
wndFromNOSQL.setClosable(true);
148148

149-
function AddRow(propertyModel: PropertyModel, tableName: string) {
150-
151-
const cellName = propertyModel.Name + (propertyModel.ColumnProperties ? " " + propertyModel.ColumnProperties: "");
152-
153-
rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26),
154-
"shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;");
155-
rowCell.vertex = true;
156-
157-
const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey ? "PK | FK" : propertyModel.IsPrimaryKey ? "PK" : propertyModel.IsForeignKey ? "FK" : "";
158-
159-
const left = sb.cloneCell(rowCell, columnType);
160-
left.connectable = false;
161-
left.style = "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;";
162-
left.geometry.width = 54;
163-
left.geometry.height = 26;
164-
rowCell.insert(left);
165-
166-
const size = ui.editor.graph.getPreferredSizeForCell(rowCell);
167-
168-
if(tableCell){
169-
if (size !== null && tableCell.geometry.width < size.width + 10) {
170-
tableCell.geometry.width = size.width + 10;
171-
}
172-
173-
tableCell.insert(rowCell);
174-
tableCell.geometry.height += 26;
175-
}
176-
177-
};
178-
179149
function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) {
180150
// reset values
181151
cells = [];
@@ -208,7 +178,13 @@ Draw.loadPlugin(function(ui) {
208178
primaryKeyList = models.PrimaryKeyList;
209179
tableList = models.TableList;
210180
exportedTables = tableList.length;
211-
CreateTableUI(type);
181+
const createTableResult = CreateTableUI(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type);
182+
if(createTableResult){
183+
cells = createTableResult.cells;
184+
dx = createTableResult.dx;
185+
tableCell = createTableResult.tableCell;
186+
rowCell = createTableResult.rowCell;
187+
}
212188
}
213189

214190
} catch (error) {
@@ -217,113 +193,6 @@ Draw.loadPlugin(function(ui) {
217193
}
218194
};
219195

220-
function CreateTableUI(type: "ts" | "openapi" | undefined) {
221-
tableList.forEach(function(tableModel) {
222-
//Define table size width
223-
const maxNameLenght = 100 + tableModel.Name.length;
224-
225-
//Create Table
226-
tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26),
227-
"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;");
228-
tableCell.vertex = true;
229-
230-
//Resize row
231-
if(rowCell){
232-
const size = ui.editor.graph.getPreferredSizeForCell(rowCell);
233-
if (size !== null) {
234-
tableCell.geometry.width = size.width + maxNameLenght;
235-
}
236-
}
237-
238-
//Add Table to cells
239-
cells.push(tableCell);
240-
241-
//Add properties
242-
tableModel.Properties.forEach(function(propertyModel) {
243-
244-
//Add row
245-
AddRow(propertyModel, tableModel.Name);
246-
});
247-
248-
//Close table
249-
dx += tableCell.geometry.width + 40;
250-
tableCell = null;
251-
});
252-
253-
if (cells.length > 0) {
254-
const graph = ui.editor.graph;
255-
const view = graph.view;
256-
const bds = graph.getGraphBounds();
257-
258-
// Computes unscaled, untranslated graph bounds
259-
const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize);
260-
const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize);
261-
262-
graph.setSelectionCells(graph.importCells(cells, x, y));
263-
// add foreign key edges
264-
const model = graph.getModel();
265-
const columnQuantifiers = GetColumnQuantifiers(type);
266-
// const pt = graph.getFreeInsertPoint();
267-
foreignKeyList.forEach(function(fk){
268-
if(fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName &&
269-
fk.PrimaryKeyTableName && fk.ReferencesTableName) {
270-
const insertEdge = mxUtils.bind(this, function(targetCell, sourceCell, edge){
271-
const label = "";
272-
const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;";
273-
const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ?
274-
sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle);
275-
});
276-
const edge = {
277-
invert: true
278-
};
279-
let targetCell = null;
280-
let sourceCell = null;
281-
// locate edge source and target cells
282-
for (const key in model.cells) {
283-
if(targetCell && sourceCell)
284-
break;
285-
if (Object.hasOwnProperty.call(model.cells, key)) {
286-
const mxcell = model.cells[key];
287-
if(mxcell.style && mxcell.style.trim().startsWith("swimlane;")){
288-
const entity = {
289-
name: mxcell.value,
290-
attributes: []
291-
};
292-
const isPrimaryTable = entity.name == fk.PrimaryKeyTableName;
293-
const isForeignTable = entity.name == fk.ReferencesTableName;
294-
if(isPrimaryTable || isForeignTable){
295-
for (let c = 0; c < mxcell.children.length; c++) {
296-
if(targetCell && sourceCell)
297-
break;
298-
const col = mxcell.children[c];
299-
if(col.mxObjectId.indexOf("mxCell") !== -1) {
300-
if(col.style && col.style.trim().startsWith("shape=partialRectangle")){
301-
const attribute = getDbLabel(col.value, columnQuantifiers);
302-
if(isPrimaryTable && dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName){
303-
targetCell = col;
304-
break;
305-
} else if(isForeignTable && dbTypeEnds(attribute.attributeName) == fk.ReferencesPropertyName){
306-
sourceCell = col;
307-
break;
308-
}
309-
}
310-
}
311-
}
312-
}
313-
314-
}
315-
}
316-
}
317-
if(targetCell && sourceCell)
318-
insertEdge(targetCell, sourceCell, edge);
319-
}
320-
});
321-
graph.scrollCellToVisible(graph.getSelectionCell());
322-
}
323-
324-
wndFromNOSQL.setVisible(false);
325-
};
326-
327196
mxUtils.br(divFromNOSQL);
328197

329198
const resetBtnFromNOSQL = mxUtils.button(mxResources.get("Reset TS"), function() {

src/nosql.ts

Lines changed: 8 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { DatabaseModel, ForeignKeyModel, PrimaryKeyModel, PropertyModel, TableMo
44
import { JSONSchema4, JSONSchema4TypeName } from "json-schema";
55
import { convertCoreTypesToJsonSchema, convertOpenApiToCoreTypes, jsonSchemaDocumentToOpenApi } from "core-types-json-schema";
66
import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openapi-json-schema";
7-
import { GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils";
7+
import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils";
88
import { pluginVersion } from "./utils/constants";
99
import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils";
1010
import { defaultResetOpenApi } from "./utils/constants-nosql";
@@ -130,36 +130,6 @@ Draw.loadPlugin(function(ui) {
130130
wndFromNOSQL.setResizable(false);
131131
wndFromNOSQL.setClosable(true);
132132

133-
function AddRow(propertyModel: PropertyModel, tableName: string) {
134-
135-
const cellName = propertyModel.Name + (propertyModel.ColumnProperties ? " " + propertyModel.ColumnProperties: "");
136-
137-
rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26),
138-
"shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;");
139-
rowCell.vertex = true;
140-
141-
const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey ? "PK | FK" : propertyModel.IsPrimaryKey ? "PK" : propertyModel.IsForeignKey ? "FK" : "";
142-
143-
const left = sb.cloneCell(rowCell, columnType);
144-
left.connectable = false;
145-
left.style = "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;";
146-
left.geometry.width = 54;
147-
left.geometry.height = 26;
148-
rowCell.insert(left);
149-
150-
const size = ui.editor.graph.getPreferredSizeForCell(rowCell);
151-
152-
if(tableCell){
153-
if (size !== null && tableCell.geometry.width < size.width + 10) {
154-
tableCell.geometry.width = size.width + 10;
155-
}
156-
157-
tableCell.insert(rowCell);
158-
tableCell.geometry.height += 26;
159-
}
160-
161-
};
162-
163133
function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) {
164134
// reset values
165135
cells = [];
@@ -190,7 +160,13 @@ Draw.loadPlugin(function(ui) {
190160
primaryKeyList = models.PrimaryKeyList;
191161
tableList = models.TableList;
192162
exportedTables = tableList.length;
193-
CreateTableUI(type);
163+
const createTableResult = CreateTableUI(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type);
164+
if(createTableResult){
165+
cells = createTableResult.cells;
166+
dx = createTableResult.dx;
167+
tableCell = createTableResult.tableCell;
168+
rowCell = createTableResult.rowCell;
169+
}
194170
}
195171

196172
} catch (error) {
@@ -199,113 +175,6 @@ Draw.loadPlugin(function(ui) {
199175
}
200176
};
201177

202-
function CreateTableUI(type: "ts" | "openapi" | undefined) {
203-
tableList.forEach(function(tableModel) {
204-
//Define table size width
205-
const maxNameLenght = 100 + tableModel.Name.length;
206-
207-
//Create Table
208-
tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26),
209-
"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;");
210-
tableCell.vertex = true;
211-
212-
//Resize row
213-
if(rowCell){
214-
const size = ui.editor.graph.getPreferredSizeForCell(rowCell);
215-
if (size !== null) {
216-
tableCell.geometry.width = size.width + maxNameLenght;
217-
}
218-
}
219-
220-
//Add Table to cells
221-
cells.push(tableCell);
222-
223-
//Add properties
224-
tableModel.Properties.forEach(function(propertyModel) {
225-
226-
//Add row
227-
AddRow(propertyModel, tableModel.Name);
228-
});
229-
230-
//Close table
231-
dx += tableCell.geometry.width + 40;
232-
tableCell = null;
233-
});
234-
235-
if (cells.length > 0) {
236-
const graph = ui.editor.graph;
237-
const view = graph.view;
238-
const bds = graph.getGraphBounds();
239-
240-
// Computes unscaled, untranslated graph bounds
241-
const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize);
242-
const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize);
243-
244-
graph.setSelectionCells(graph.importCells(cells, x, y));
245-
// add foreign key edges
246-
const model = graph.getModel();
247-
const columnQuantifiers = GetColumnQuantifiers(type);
248-
// const pt = graph.getFreeInsertPoint();
249-
foreignKeyList.forEach(function(fk){
250-
if(fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName &&
251-
fk.PrimaryKeyTableName && fk.ReferencesTableName) {
252-
const insertEdge = mxUtils.bind(this, function(targetCell, sourceCell, edge){
253-
const label = "";
254-
const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;";
255-
const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ?
256-
sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle);
257-
});
258-
const edge = {
259-
invert: true
260-
};
261-
let targetCell = null;
262-
let sourceCell = null;
263-
// locate edge source and target cells
264-
for (const key in model.cells) {
265-
if(targetCell && sourceCell)
266-
break;
267-
if (Object.hasOwnProperty.call(model.cells, key)) {
268-
const mxcell = model.cells[key];
269-
if(mxcell.style && mxcell.style.trim().startsWith("swimlane;")){
270-
const entity = {
271-
name: mxcell.value,
272-
attributes: []
273-
};
274-
const isPrimaryTable = entity.name == fk.PrimaryKeyTableName;
275-
const isForeignTable = entity.name == fk.ReferencesTableName;
276-
if(isPrimaryTable || isForeignTable){
277-
for (let c = 0; c < mxcell.children.length; c++) {
278-
if(targetCell && sourceCell)
279-
break;
280-
const col = mxcell.children[c];
281-
if(col.mxObjectId.indexOf("mxCell") !== -1) {
282-
if(col.style && col.style.trim().startsWith("shape=partialRectangle")){
283-
const attribute = getDbLabel(col.value, columnQuantifiers);
284-
if(isPrimaryTable && dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName){
285-
targetCell = col;
286-
break;
287-
} else if(isForeignTable && dbTypeEnds(attribute.attributeName) == fk.ReferencesPropertyName){
288-
sourceCell = col;
289-
break;
290-
}
291-
}
292-
}
293-
}
294-
}
295-
296-
}
297-
}
298-
}
299-
if(targetCell && sourceCell)
300-
insertEdge(targetCell, sourceCell, edge);
301-
}
302-
});
303-
graph.scrollCellToVisible(graph.getSelectionCell());
304-
}
305-
306-
wndFromNOSQL.setVisible(false);
307-
};
308-
309178
mxUtils.br(divFromNOSQL);
310179

311180
const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function() {

0 commit comments

Comments
 (0)