Skip to content

Commit aaf32a6

Browse files
🔥 new experience: rendering only necessary classes, a lot of improvements
1 parent 9021361 commit aaf32a6

File tree

6 files changed

+123
-92
lines changed

6 files changed

+123
-92
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ An UML Class explorer for InterSystems Caché. It is able to build UML class dia
33

44
## Screenshots
55

6-
![2015-04-21_214058](https://cloud.githubusercontent.com/assets/4989256/7396518/65ba1924-eeaa-11e4-808b-5f648c0011e4.png)
6+
![2015-04-21_214058](https://cloud.githubusercontent.com/assets/4989256/7525432/180dafd8-f512-11e4-80dc-3c5721d3b858.png)
77

88
## Installation
99

cache/projectTemplate.xml

Lines changed: 99 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.2 (Build 540)" ts="2015-04-28 19:50:48">
33
<Class name="UMLExplorer.ClassView">
44
<Description>
5-
Class contains methods that return structured class data.</Description>
6-
<TimeChanged>63671,64479.682329</TimeChanged>
5+
Class contains methods that return structured classes/packages data.</Description>
6+
<TimeChanged>63680,165.360933</TimeChanged>
77
<TimeCreated>63653,67019.989197</TimeCreated>
88

99
<Method name="getClassTree">
@@ -47,21 +47,27 @@ Returns structured class tree with all classes available in current namespace</D
4747
]]></Implementation>
4848
</Method>
4949

50-
<Method name="getClassData">
50+
<Method name="setClassData">
5151
<Description>
52-
return structured data about class</Description>
52+
Return structured data about class.</Description>
5353
<ClassMethod>1</ClassMethod>
54-
<FormalSpec>oData:%ZEN.proxyObject,classDefinition:%Dictionary.ClassDefinition</FormalSpec>
54+
<FormalSpec>oData:%ZEN.proxyObject,className:%String</FormalSpec>
55+
<Private>1</Private>
5556
<ReturnType>%ZEN.proxyObject</ReturnType>
5657
<Implementation><![CDATA[
57-
set oClass = ##class(%ZEN.proxyObject).%New()
58-
59-
set basePack = $LISTTOSTRING($LIST($LISTFROMSTRING(classDefinition.Name, "."), 1, *-1),".")
58+
set classDefinition = ##class(%Dictionary.ClassDefinition).%OpenId(className)
59+
if (classDefinition = "") || (oData.classes.%DispatchGetProperty(classDefinition.Name) '= "") quit ""
6060
61+
set oClass = ##class(%ZEN.proxyObject).%New()
62+
do oData.classes.%DispatchSetProperty(classDefinition.Name, oClass) // prevent from recursive setup
63+
set package = $LISTTOSTRING($LIST($LISTFROMSTRING(classDefinition.Name, "."), 1, *-1),".")
6164
set oProperties = ##class(%ZEN.proxyObject).%New()
6265
set oClass.NAMESPACE = $NAMESPACE
6366
set oClass.ABSTRACT = classDefinition.Abstract
6467
set oClass.super = classDefinition.Super
68+
69+
if (oData.restrictPackage) && ('..inPackage(oData.basePackageName, package)) quit oClass
70+
6571
set oClass.properties = oProperties
6672
set count = classDefinition.Properties.Count()
6773
for i = 1:1:count {
@@ -71,8 +77,8 @@ return structured data about class</Description>
7177
do oProp.%DispatchSetProperty("private", p.Private)
7278
do oProp.%DispatchSetProperty("readOnly", p.ReadOnly)
7379
do oProp.%DispatchSetProperty("type", p.Type)
74-
do ..collectAggregation(oData, classDefinition.Name, p.Type, p.Private)
75-
do ..collectAggregation(oData, classDefinition.Name, basePack _ "." _ p.Type, p.Private)
80+
do ..collectAggregation(oData, classDefinition, p.Type, p.Private)
81+
do ..collectAggregation(oData, classDefinition, package _ "." _ p.Type, p.Private)
7682
}
7783
7884
set oMethods = ##class(%ZEN.proxyObject).%New()
@@ -97,121 +103,156 @@ return structured data about class</Description>
97103
do oPar.%DispatchSetProperty("type", p.Type)
98104
}
99105
106+
do ..collectInheritance(oData, classDefinition, package)
107+
100108
quit oClass
101109
]]></Implementation>
102110
</Method>
103111

112+
<Method name="inPackage">
113+
<Description><![CDATA[
114+
Returns if <var>packageName</var> is in <var>basePackageName</var>.]]></Description>
115+
<ClassMethod>1</ClassMethod>
116+
<FormalSpec>basePackageName:%String,packageName:%String</FormalSpec>
117+
<Private>1</Private>
118+
<ReturnType>%Boolean</ReturnType>
119+
<Implementation><![CDATA[ quit $FIND(packageName, basePackageName) - $LENGTH(basePackageName) = 1
120+
]]></Implementation>
121+
</Method>
122+
104123
<Method name="extendClassFromType">
124+
<Description>
125+
Wrap registered types to class names</Description>
105126
<ClassMethod>1</ClassMethod>
106127
<FormalSpec>typeName:%String</FormalSpec>
128+
<Private>1</Private>
107129
<ReturnType>%String</ReturnType>
108130
<Implementation><![CDATA[
109-
return $CASE(typeName,
131+
return typeName
132+
/*$CASE(typeName,
110133
"%String": "%Library.String",
111134
"%Integer": "%Library.Integer",
112135
"%DataType": "%Library.DataType",
113136
"%Status": "%Library.Status",
114137
"%CacheString": "%Library.CacheString",
115138
"%Persistent": "%Library.Persistent",
116-
:typeName)
139+
:typeName)*/
117140
]]></Implementation>
118141
</Method>
119142

120143
<Method name="collectInheritance">
144+
<Description>
145+
Fill inheritance data</Description>
121146
<ClassMethod>1</ClassMethod>
122-
<FormalSpec>oData:%ZEN.proxyObject,baseClassDefinition:%Dictionary.ClassDefinition</FormalSpec>
147+
<FormalSpec>oData:%ZEN.proxyObject,baseClassDefinition:%Dictionary.ClassDefinition,basePack:%String</FormalSpec>
148+
<Private>1</Private>
123149
<ReturnType>%Status</ReturnType>
124150
<Implementation><![CDATA[
125151
set superParts = $LISTFROMSTRING(baseClassDefinition.Super, ",")
126-
if (oData.inheritance.%DispatchGetProperty(baseClassDefinition.Name) = "") {
127-
do oData.inheritance.%DispatchSetProperty(baseClassDefinition.Name, ##class(%ZEN.proxyObject).%New())
128-
}
129-
set oInherit = oData.inheritance.%DispatchGetProperty(baseClassDefinition.Name)
152+
set oInherit = ##class(%ZEN.proxyObject).%New()
153+
do oData.inheritance.%DispatchSetProperty(baseClassDefinition.Name, oInherit)
130154
for i=1:1:$LISTLENGTH(superParts) {
131155
set className = ..extendClassFromType($LISTGET(superParts, i))
132-
do oInherit.%DispatchSetProperty(className, 1)
133-
if (oData.classes.%DispatchGetProperty(className) = "") {
134-
set cdef = ##class(%Dictionary.ClassDefinition).%OpenId(className)
135-
if (cdef '= "") {
136-
do oData.classes.%DispatchSetProperty(className, ..getClassData(oData, cdef))
137-
do ..collectInheritance(oData, cdef)
138-
}
156+
157+
// try to find class with base package, if not successfull - try to add class as it is
158+
if (..classExists(basePack_"."_className)) {
159+
set clsName = basePack_"."_className
160+
} else {
161+
set clsName = className
139162
}
163+
164+
do oInherit.%DispatchSetProperty(clsName, 1)
165+
do ..setClassData(oData, clsName)
140166
}
141167
quit $$$OK
142168
]]></Implementation>
143169
</Method>
144170

145171
<Method name="collectAggregation">
172+
<Description>
173+
Fill aggregation/composition data</Description>
146174
<ClassMethod>1</ClassMethod>
147-
<FormalSpec>oData:%ZEN.proxyObject,className:%String,type:%String,private:%String</FormalSpec>
175+
<FormalSpec>oData:%ZEN.proxyObject,classDef:%Dictionary.ClassDefinition,aggClassName:%String,private:%String</FormalSpec>
176+
<Private>1</Private>
148177
<ReturnType>%Status</ReturnType>
149178
<Implementation><![CDATA[
150-
set classDef = ##class(%Dictionary.ClassDefinition).%OpenId(type)
151-
if (classDef '= "") {
179+
set aggClassDef = ##class(%Dictionary.ClassDefinition).%OpenId(aggClassName)
180+
if (aggClassDef '= "") {
152181
if (private) { set t = "composition" } else { set t = "aggregation" }
153-
set oAgg = oData.%DispatchGetProperty(t).%DispatchGetProperty(className)
182+
set oAgg = oData.%DispatchGetProperty(t).%DispatchGetProperty(classDef.Name)
154183
if (oAgg = "") {
155184
set oAgg = ##class(%ZEN.proxyObject).%New()
156-
do oData.%DispatchGetProperty(t).%DispatchSetProperty(className, oAgg)
185+
do oData.%DispatchGetProperty(t).%DispatchSetProperty(classDef.Name, oAgg)
157186
}
158187
} else { quit $$$OK }
159188
160-
do oAgg.%DispatchSetProperty(type, "1..1")
161-
do ..collectClass(oData, classDef)
189+
do oAgg.%DispatchSetProperty(aggClassName, "1..1")
190+
do ..setClassData(oData, aggClassName)
162191
163192
quit $$$OK
164193
]]></Implementation>
165194
</Method>
166195

167-
<Method name="collectClass">
196+
<Method name="getBaseOData">
197+
<Description>
198+
Setup basic output data object</Description>
168199
<ClassMethod>1</ClassMethod>
169-
<FormalSpec>oData:%ZEN.proxyObject,cdef:%Dictionary.ClassDefinition</FormalSpec>
170-
<ReturnType>%Status</ReturnType>
200+
<FormalSpec>packageName:%String</FormalSpec>
201+
<Private>1</Private>
202+
<ReturnType>%ZEN.proxyObject</ReturnType>
171203
<Implementation><![CDATA[
172-
if (oData.classes.%DispatchGetProperty(cdef.Name) '= "") { quit $$$OK }
173-
do oData.classes.%DispatchSetProperty(cdef.Name, "IDLE")
174-
do oData.classes.%DispatchSetProperty(cdef.Name, ..getClassData(oData, cdef))
175-
do ..collectInheritance(oData, cdef)
204+
set oData = ##class(%ZEN.proxyObject).%New()
205+
set oData.basePackageName = packageName
206+
set oData.restrictPackage = 1 // expand classes only in base package
207+
set oData.classes = ##class(%ZEN.proxyObject).%New()
208+
set oData.inheritance = ##class(%ZEN.proxyObject).%New()
209+
set oData.aggregation = ##class(%ZEN.proxyObject).%New()
210+
set oData.composition = ##class(%ZEN.proxyObject).%New()
211+
quit oData
212+
]]></Implementation>
213+
</Method>
214+
215+
<Method name="classExists">
216+
<Description>
217+
Returns if class with given name exists.</Description>
218+
<ClassMethod>1</ClassMethod>
219+
<FormalSpec>className:%String</FormalSpec>
220+
<ReturnType>%Boolean</ReturnType>
221+
<Implementation><![CDATA[ quit ##class(%Dictionary.ClassDefinition).%OpenId(className) '= ""
176222
]]></Implementation>
177223
</Method>
178224

179225
<Method name="getClassView">
226+
<Description>
227+
Returns structured class data</Description>
180228
<ClassMethod>1</ClassMethod>
181-
<FormalSpec>baseClassDefinition:%Dictionary.ClassDefinition</FormalSpec>
229+
<FormalSpec>className:%String</FormalSpec>
182230
<ReturnType>%ZEN.proxyObject</ReturnType>
183231
<Implementation><![CDATA[
184-
set oData = ##class(%ZEN.proxyObject).%New()
185-
set oData.classes = ##class(%ZEN.proxyObject).%New()
186-
set oData.inheritance = ##class(%ZEN.proxyObject).%New()
187-
set oData.aggregation = ##class(%ZEN.proxyObject).%New()
188-
do ..collectClass(oData, baseClassDefinition)
189-
232+
set package = $LISTTOSTRING($LIST($LISTFROMSTRING(className, "."), 1, *-1), ".")
233+
set oData = ..getBaseOData(package)
234+
do ..setClassData(oData, className)
190235
quit oData
191236
]]></Implementation>
192237
</Method>
193238

194239
<Method name="getPackageView">
240+
<Description>
241+
Returns structured package data</Description>
195242
<ClassMethod>1</ClassMethod>
196243
<FormalSpec>rootPackageName:%String</FormalSpec>
197244
<ReturnType>%ZEN.proxyObject</ReturnType>
198245
<Implementation><![CDATA[
199-
set oData = ##class(%ZEN.proxyObject).%New()
200-
set oData.classes = ##class(%ZEN.proxyObject).%New()
201-
set oData.inheritance = ##class(%ZEN.proxyObject).%New()
202-
set oData.aggregation = ##class(%ZEN.proxyObject).%New()
203-
set oData.composition = ##class(%ZEN.proxyObject).%New()
204-
246+
set oData = ..getBaseOData(rootPackageName)
205247
set classes = ##class(%ResultSet).%New("%Dictionary.ClassDefinition:Summary")
206248
do classes.Execute()
207-
set listLen = $LISTLENGTH($LISTFROMSTRING(rootPackageName, "."))
249+
set listLen = $LISTLENGTH($LISTFROMSTRING(rootPackageName, ".")) // bottom level of package to extract
250+
208251
while (classes.Next()) {
209252
set className = classes.Data("Name")
210253
set packageName = $LISTTOSTRING($LIST($LISTFROMSTRING(className, "."), 1, listLen), ".")
211254
if (packageName = rootPackageName) {
212-
set classDef = ##class(%Dictionary.ClassDefinition).%OpenId(className)
213-
do oData.classes.%DispatchSetProperty(classDef.Name, ..getClassData(oData, classDef))
214-
do ..collectInheritance(oData, classDef)
255+
do ..setClassData(oData, className)
215256
}
216257
}
217258
@@ -221,7 +262,7 @@ return structured data about class</Description>
221262
</Class>
222263

223264

224-
<Project name="UMLExplorer" LastModified="2015-04-28 23:30:37.941872">
265+
<Project name="UMLExplorer" LastModified="2015-04-29 19:47:03.727613">
225266
<Items>
226267
<ProjectItem name="UMLExplorer.ClassView" type="CLS"></ProjectItem>
227268
<ProjectItem name="UMLExplorer.Router" type="CLS"></ProjectItem>
@@ -234,7 +275,7 @@ return structured data about class</Description>
234275
<Description>
235276
REST interface for UMLExplorer</Description>
236277
<Super>%CSP.REST</Super>
237-
<TimeChanged>63670,71431.319061</TimeChanged>
278+
<TimeChanged>63679,81701.423669</TimeChanged>
238279
<TimeCreated>63648,30450.187229</TimeCreated>
239280

240281
<XData name="UrlMap">
@@ -270,9 +311,7 @@ Returns classTree by given class name</Description>
270311
<FormalSpec>className:%String</FormalSpec>
271312
<ReturnType>%Status</ReturnType>
272313
<Implementation><![CDATA[
273-
set cdef = ##class(%Dictionary.ClassDefinition).%OpenId(className)
274-
if (cdef = "") quit ..Http404()
275-
set classData = ##class(UMLExplorer.ClassView).getClassView(cdef)
314+
set classData = ##class(UMLExplorer.ClassView).getClassView(className)
276315
do classData.%ToJSON(, "ou")
277316
return $$$OK
278317
]]></Implementation>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "CacheUMLExplorer",
3-
"version": "0.5.2",
3+
"version": "0.6.0",
44
"description": "An UML Class explorer for InterSystems Caché",
55
"directories": {
66
"test": "test"

web/js/ClassView.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
8888
array.push(string + (extraString ? extraString : ""));
8989
};
9090

91-
return new joint.shapes.uml.Class({
91+
var classInstance = new joint.shapes.uml.Class({
9292
name: (classMetaData["ABSTRACT"] ? ["<<Abstract>>", name] : [name]),
9393
params: (function (params) {
9494
var arr = [], n;
@@ -130,11 +130,16 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
130130
}
131131
});
132132

133+
this.objects.push(classInstance);
134+
this.graph.addCell(classInstance);
135+
136+
return classInstance;
137+
133138
};
134139

135140
ClassView.prototype.render = function (data) {
136141

137-
var self = this, p, pp, className, classInstance,
142+
var self = this, p, pp, className,
138143
uml = joint.shapes.uml, relFrom, relTo,
139144
classes = {}, connector;
140145

@@ -144,14 +149,9 @@ ClassView.prototype.render = function (data) {
144149
}
145150

146151
for (className in data["classes"]) {
147-
classInstance = this.createClassInstance(className, data["classes"][className]);
148-
this.objects.push(classInstance);
149152
classes[className] = {
150-
instance: classInstance
153+
instance: this.createClassInstance(className, data["classes"][className])
151154
};
152-
153-
this.graph.addCell(classInstance);
154-
155155
}
156156

157157
var link = function (type) {
@@ -161,6 +161,11 @@ ClassView.prototype.render = function (data) {
161161
relFrom = (classes[p] || {}).instance;
162162
for (pp in data[type][p]) {
163163
relTo = (classes[pp] || {}).instance;
164+
if (!relTo) {
165+
classes[pp] = {
166+
instance: relTo = self.createClassInstance(pp, {})
167+
};
168+
}
164169
if (relFrom && relTo) {
165170
self.graph.addCell(connector = new uml[name]({
166171
source: { id: type === "inheritance" ? relFrom.id : relTo.id },
@@ -181,7 +186,8 @@ ClassView.prototype.render = function (data) {
181186
joint.layout.DirectedGraph.layout(this.graph, {
182187
setLinkVertices: false,
183188
nodeSep: 100,
184-
rankSep: 100
189+
rankSep: 100,
190+
edgeSep: 20
185191
});
186192

187193
this.updateSizes();

web/jsLib/joint.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
1818
*
1919
* Date: 2013-07-03T13:30Z
2020
*/
21+
/*
22+
* Modified by ZitRo
23+
*/
2124
(function( window, undefined ) {
2225

2326
// Can't do this because several apps including ASP.NET trace

0 commit comments

Comments
 (0)