Skip to content

Commit 63d372b

Browse files
big packages rendering warning, browsers size differences fix, IE fixes
1 parent aaf32a6 commit 63d372b

File tree

8 files changed

+136
-23
lines changed

8 files changed

+136
-23
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# CacheUMLExplorer
2-
An UML Class explorer for InterSystems Caché. It is able to build UML class diagram for any class or even for whole package in Caché.
2+
An UML Class explorer for InterSystems Caché.
3+
4+
##### Key features
5+
+ Build class diagrams;
6+
+ Build diagrams for any package or subpackage;
7+
+ Edit diagrams after build;
8+
+ Export diagrams as an image;
9+
+ Zoom in and out, explore big packages and more.
310

411
## Screenshots
512

cache/projectTemplate.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Class name="UMLExplorer.ClassView">
44
<Description>
55
Class contains methods that return structured classes/packages data.</Description>
6-
<TimeChanged>63680,165.360933</TimeChanged>
6+
<TimeChanged>63680,46308.140173</TimeChanged>
77
<TimeCreated>63653,67019.989197</TimeCreated>
88

99
<Method name="getClassTree">
@@ -63,6 +63,7 @@ Return structured data about class.</Description>
6363
set package = $LISTTOSTRING($LIST($LISTFROMSTRING(classDefinition.Name, "."), 1, *-1),".")
6464
set oProperties = ##class(%ZEN.proxyObject).%New()
6565
set oClass.NAMESPACE = $NAMESPACE
66+
set oClass.SYSTEM = classDefinition.System
6667
set oClass.ABSTRACT = classDefinition.Abstract
6768
set oClass.super = classDefinition.Super
6869
@@ -262,7 +263,7 @@ Returns structured package data</Description>
262263
</Class>
263264

264265

265-
<Project name="UMLExplorer" LastModified="2015-04-29 19:47:03.727613">
266+
<Project name="UMLExplorer" LastModified="2015-05-08 00:09:34.590786">
266267
<Items>
267268
<ProjectItem name="UMLExplorer.ClassView" type="CLS"></ProjectItem>
268269
<ProjectItem name="UMLExplorer.Router" type="CLS"></ProjectItem>

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.6.0",
3+
"version": "0.6.1",
44
"description": "An UML Class explorer for InterSystems Caché",
55
"directories": {
66
"test": "test"

web/css/classView.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/* IE fix */
2+
svg {
3+
overflow: hidden;
4+
}
5+
16
#classView {
27
height: 100%;
38
cursor: -webkit-grab; cursor: -moz-grab;

web/js/ClassView.js

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var ClassView = function (parent, container) {
1919
this.MAX_PAPER_SCALE = 4;
2020

2121
this.CLASS_DOC_PATH = "/csp/documatic/%25CSP.Documatic.cls";
22+
this.SYMBOL_12_WIDTH = 6.6;
2223

2324
this.init();
2425

@@ -127,7 +128,8 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
127128
nameClickHandler: function () {
128129
self.openClassDoc(name, classMetaData["NAMESPACE"]);
129130
}
130-
}
131+
},
132+
SYMBOL_12_WIDTH: self.SYMBOL_12_WIDTH
131133
});
132134

133135
this.objects.push(classInstance);
@@ -139,6 +141,61 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
139141

140142
ClassView.prototype.render = function (data) {
141143

144+
var self = this,
145+
number = lib.countProperties(data["classes"]);
146+
147+
if (number < 30) return this.confirmRender(data);
148+
149+
var c = document.createElement("div"),
150+
c1 = document.createElement("h3"),
151+
cS = document.createElement("h6"),
152+
c2 = document.createElement("div"),
153+
load = document.createElement("div"),
154+
lt = document.createElement("div"),
155+
spinner = document.createElement("div"),
156+
bOk = document.createElement("button"),
157+
bOff = document.createElement("button");
158+
159+
c1.textContent = "Warning!";
160+
cS.textContent = "There are a huge number of classes to render (over " + (number - (number % 10))
161+
+ " elements)"
162+
+ (function(n){var s=n<40?".":"!",c=0; while (n>50) { s+="!"; n-=10+c++; } return s; })(number)
163+
+ " Rendering may take a lot of time.";
164+
165+
bOk.textContent = "Render this!";
166+
bOk.style.color = "red";
167+
bOff.textContent = "No, thanks";
168+
load.style.textAlign = "center";
169+
spinner.className = "spinner";
170+
lt.innerHTML = "<br/><br/><br/><br/>Rendering, please wait...";
171+
lt.style.textAlign = "center";
172+
173+
bOk.addEventListener("click", function () {
174+
c.appendChild(load);
175+
c1.parentNode.removeChild(c1);
176+
cS.parentNode.removeChild(cS);
177+
c2.parentNode.removeChild(c2);
178+
setTimeout(function () {
179+
self.confirmRender(data); self.cacheUMLExplorer.UI.removeMessage();
180+
}, 25);
181+
});
182+
bOff.addEventListener("click", function () {
183+
self.cacheUMLExplorer.UI.removeMessage();
184+
});
185+
186+
c.appendChild(c1);
187+
c.appendChild(cS);
188+
c.appendChild(c2);
189+
c2.appendChild(bOk);
190+
c2.appendChild(bOff);
191+
load.appendChild(lt);
192+
load.appendChild(spinner);
193+
this.cacheUMLExplorer.UI.displayMessage(c, false);
194+
195+
};
196+
197+
ClassView.prototype.confirmRender = function (data) {
198+
142199
var self = this, p, pp, className,
143200
uml = joint.shapes.uml, relFrom, relTo,
144201
classes = {}, connector;
@@ -349,4 +406,20 @@ ClassView.prototype.init = function () {
349406
self.zoom(null);
350407
});
351408

409+
this.SYMBOL_12_WIDTH = (function () {
410+
var e = document.createElementNS("http://www.w3.org/2000/svg", "text"),
411+
s = document.createElementNS("http://www.w3.org/2000/svg", "svg"),
412+
w;
413+
s.appendChild(e);
414+
s.setAttribute("xmlns", "http://www.w3.org/2000/svg");
415+
s.setAttribute("version", "1.1");
416+
e.setAttribute("font-family", "monospace");
417+
e.setAttribute("font-size", "12");
418+
e.textContent = "aBcDeFgGhH";
419+
document.body.appendChild(s);
420+
w = e.getBBox().width/10;
421+
s.parentNode.removeChild(s);
422+
return w;
423+
})();
424+
352425
};

web/js/Lib.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,28 @@ Lib.prototype.load = function (url, data, callback) {
1515

1616
xhr.onreadystatechange = function () {
1717
if (xhr.readyState === 4 && xhr.status === 200) {
18-
//try {
19-
return callback(null, JSON.parse(xhr.responseText) || {})
20-
//} catch (e) {
21-
// console.error(e);
22-
// return callback(
23-
// "<h1>Unable to parse server response</h1><p>" + xhr.responseText + "</p>",
24-
// null
25-
// );
26-
//}
18+
return callback(null, JSON.parse(xhr.responseText) || {});
2719
} else if (xhr.readyState === 4) {
2820
callback(xhr.responseText + ", " + xhr.status + ": " + xhr.statusText);
2921
}
3022
};
3123

3224
xhr.send(data ? JSON.stringify(data) : undefined);
3325

26+
};
27+
28+
/**
29+
* Return number of readable properties in object.
30+
* @param object
31+
*/
32+
Lib.prototype.countProperties = function (object) {
33+
34+
var c = 0, p;
35+
36+
for (p in object) {
37+
c++;
38+
}
39+
40+
return c;
41+
3442
};

web/js/UI.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ var UI = function (cacheUMLExplorer) {
1919
/**
2020
* Display hovering message.
2121
*
22-
* @param {string} text
22+
* @param {string|HTMLElement} content
2323
* @param {boolean} [removeByClick] - Define whether user be able to remove message by clicking on
2424
* it.
2525
*/
26-
UI.prototype.displayMessage = function (text, removeByClick) {
26+
UI.prototype.displayMessage = function (content, removeByClick) {
2727

2828
this.removeMessage();
2929

@@ -34,7 +34,11 @@ UI.prototype.displayMessage = function (text, removeByClick) {
3434

3535
d1.className = "central message";
3636
d1.style.opacity = 0;
37-
d3.innerHTML = text;
37+
if (content instanceof HTMLElement) {
38+
d3.appendChild(content);
39+
} else {
40+
d3.innerHTML = content;
41+
}
3842
d2.appendChild(d3);
3943
d1.appendChild(d2);
4044
this.BODY.appendChild(d1);

web/jsLib/joint.shapes.uml.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,20 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
1515
markup: [
1616
'<g class="rotatable">',
1717
'<g class="scalable">',
18-
'<rect class="uml-class-name-rect"/><rect class="uml-class-params-rect"/><text class="uml-class-params-label">Parameters</text><rect class="uml-class-attrs-rect"/><text class="uml-class-attrs-label">Properties</text><rect class="uml-class-methods-rect"/><text class="uml-class-methods-label">Methods</text>',
18+
'<rect class="uml-class-name-rect"/>',
19+
'<rect class="uml-class-params-rect"/>',
20+
'<text class="uml-class-params-label">Parameters</text>',
21+
'<rect class="uml-class-attrs-rect"/>',
22+
'<text class="uml-class-attrs-label">Properties</text>',
23+
'<rect class="uml-class-methods-rect"/>',
24+
'<text class="uml-class-methods-label">Methods</text>',
1925
'</g>',
20-
'<text class="uml-class-name-text"/><text class="uml-class-params-text"/><text class="uml-class-attrs-text"/><text class="uml-class-methods-text"/>',
26+
//'<image xlink:href="img/icons/yellowCube.png" x="3" y="3" width="12" height="12"/>',
27+
//'<text fill="black" font-size="12" x="16" y="13">System</text>',
28+
'<text class="uml-class-name-text"/>',
29+
'<text class="uml-class-params-text"/>',
30+
'<text class="uml-class-attrs-text"/>',
31+
'<text class="uml-class-methods-text"/>',
2132
'</g>'
2233
].join(''),
2334

@@ -89,7 +100,8 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
89100
updateRectangles: function() {
90101

91102
var attrs = this.get('attrs'),
92-
self = this;
103+
self = this,
104+
SYMBOL_12_WIDTH = this.get('SYMBOL_12_WIDTH') || 6.6;
93105

94106
var rects = [
95107
{ type: 'name', text: this.getClassName() },
@@ -105,7 +117,7 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
105117
nameClickHandler = dp.nameClickHandler;
106118

107119
_.each(rects, function (rect) {
108-
(rect.text instanceof Array ? rect.text : [rect.text]).forEach(function (s) { var t = s.split("\x1b")[0].length*6.66 + 8; if (t > maxWidth) {
120+
(rect.text instanceof Array ? rect.text : [rect.text]).forEach(function (s) { var t = s.split("\x1b")[0].length*SYMBOL_12_WIDTH + 8; if (t > maxWidth) {
109121
maxWidth = t;
110122
}});
111123
});
@@ -114,8 +126,11 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
114126

115127
_.each(rects, function(rect) {
116128

117-
var lines = _.isArray(rect.text) ? rect.text : [rect.text],
118-
rectHeight = lines.length * 12 + (lines.length ? 10 : 0),
129+
var lines = _.isArray(rect.text) ? rect.text : [rect.text];
130+
131+
//if (rect.type === "name") lines.unshift("");
132+
133+
var rectHeight = lines.length * 12 + (lines.length ? 10 : 0),
119134
rectText = attrs['.uml-class-' + rect.type + '-text'],
120135
rectRect = attrs['.uml-class-' + rect.type + '-rect'],
121136
rectLabel = attrs['.uml-class-' + rect.type + '-label'];

0 commit comments

Comments
 (0)