Skip to content

Commit 21c2587

Browse files
diagram search enabled
1 parent 1bfcdf2 commit 21c2587

File tree

7 files changed

+164
-5
lines changed

7 files changed

+164
-5
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ An UML Class explorer for InterSystems Caché.
77
+ Edit diagrams after build;
88
+ Export diagrams as an image;
99
+ View class methods code with syntax highlighting;
10-
+ Zoom in and out, explore big packages and more.
10+
+ Zoom in and out;
11+
+ Search on diagram or in class tree;
12+
+ Explore!
1113

1214
## Screenshots
1315

14-
![Demo](https://cloud.githubusercontent.com/assets/4989256/7898598/7d367720-070d-11e5-9177-dded6abf93e1.png)
16+
![Demo](https://cloud.githubusercontent.com/assets/4989256/7902384/e7882a48-07c0-11e5-9c3f-7203a40263d2.png)
1517

1618
## Installation
1719

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

web/css/classView.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,23 @@ text {
8282

8383
.line-clickable:hover {
8484
fill: red;
85+
}
86+
87+
.inlineSearchBlock {
88+
display: inline-block;
89+
vertical-align: bottom;
90+
}
91+
92+
#diagramSearch {
93+
display: block;
94+
box-sizing: border-box;
95+
border: 1px solid gray;
96+
border-radius: 5px;
97+
width: 200px;
98+
margin: 4px 0 4px 4px;
99+
height: 22px;
100+
}
101+
102+
.element.highlighted {
103+
outline: 4px solid rgba(255, 0, 0, 0.6);
85104
}

web/css/extras.css

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,35 @@
8484
box-shadow: 0 0 5px 2px #ffcc1b;
8585
}
8686

87+
.icon.search:after {
88+
content: "";
89+
position: absolute;
90+
display: block;
91+
width: 6px;
92+
height: 6px;
93+
left: 4px;
94+
top: 4px;
95+
border: 3px solid #fff;
96+
background: transparent;
97+
border-radius: 6px;
98+
}
99+
100+
.icon.search:before {
101+
content: "";
102+
position: absolute;
103+
display: block;
104+
left: 14px;
105+
top: 12px;
106+
width: 3px;
107+
height: 7px;
108+
background: #fff;
109+
-webkit-transform: rotate(-45deg);
110+
-moz-transform: rotate(-45deg);
111+
-ms-transform: rotate(-45deg);
112+
-o-transform: rotate(-45deg);
113+
transform: rotate(-45deg);
114+
}
115+
87116
.icon.select {
88117
width: auto;
89118
color: white;

web/index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<div class="ui-body" id="ui-body">
3030
<div class="ui-sideBlock">
3131
<div class="ui-sideSearchBlock" id="searchBlock">
32-
<input type="search" id="classTreeSearch" placeholder="Search..."/>
32+
<input type="search" id="classTreeSearch" placeholder="Search in class tree..."/>
3333
</div>
3434
<div id="treeView">
3535

@@ -50,6 +50,10 @@
5050
<div id="button.downloadSVG" class="icon download"></div>
5151
</div>
5252
<div class="ui-rightBottomToolBar">
53+
<div class="inlineSearchBlock" id="diagramSearchBlock">
54+
<input type="search" id="diagramSearch" placeholder="Search on diagram..."/>
55+
</div>
56+
<div id="button.diagramSearch" class="icon search"></div>
5357
<div id="button.zoomIn" class="icon plus"></div>
5458
<div id="button.zoomNormal" class="icon scaleNormal"></div>
5559
<div id="button.zoomOut" class="icon minus"></div>

web/js/CacheUMLExplorer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) {
3030
methodViewBounds: id("methodViewBounds"),
3131
namespaces: id("namespaces"),
3232
classTreeSearch: id("classTreeSearch"),
33-
searchBlock: id("searchBlock")
33+
searchBlock: id("searchBlock"),
34+
diagramSearch: id("diagramSearch"),
35+
diagramSearchButton: id("button.diagramSearch")
3436
};
3537

3638
this.UI = new UI(this);

web/js/ClassView.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,29 @@ var ClassView = function (parent, container) {
2121
this.CLASS_DOC_PATH = "/csp/documatic/%25CSP.Documatic.cls";
2222
this.SYMBOL_12_WIDTH = 6.6;
2323

24+
this.HIGHLIGHTED_VIEW = null;
25+
this.SEARCH_INDEX = 0;
26+
2427
this.init();
2528

2629
};
2730

31+
ClassView.prototype.highlightElement = function (jointElement) {
32+
33+
if (this.HIGHLIGHTED_VIEW || (!jointElement && this.HIGHLIGHTED_VIEW)) {
34+
this.HIGHLIGHTED_VIEW.unhighlight();
35+
this.HIGHLIGHTED_VIEW = null;
36+
}
37+
38+
if (!jointElement) return;
39+
var view = this.paper.findViewByModel(jointElement);
40+
if (!view) return;
41+
42+
view.highlight();
43+
this.HIGHLIGHTED_VIEW = view;
44+
45+
};
46+
2847
ClassView.prototype.showLoader = function (html) {
2948

3049
var d2;
@@ -60,6 +79,9 @@ ClassView.prototype.resetView = function () {
6079
this.objects = [];
6180
this.paper.setOrigin(0, 0);
6281
this.graph.clear();
82+
this.HIGHLIGHTED_VIEW = null;
83+
this.SEARCH_INDEX = 0;
84+
this.cacheUMLExplorer.elements.diagramSearch.value = "";
6385

6486
};
6587

@@ -268,6 +290,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
268290
var classParams = classMetaData["parameters"],
269291
classProps = classMetaData["properties"],
270292
classMethods = classMetaData["methods"],
293+
keyWordsArray = [name],
271294
self = this;
272295

273296
var classInstance = new joint.shapes.uml.Class({
@@ -283,6 +306,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
283306
params: (function (params) {
284307
var arr = [], n;
285308
for (n in params) {
309+
keyWordsArray.push(n);
286310
arr.push({
287311
text: n + (params[n]["type"] ? ": " + params[n]["type"] : "")
288312
});
@@ -292,6 +316,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
292316
attributes: (function (ps) {
293317
var arr = [], n;
294318
for (n in ps) {
319+
keyWordsArray.push(n);
295320
arr.push({
296321
text: n + (ps[n]["type"] ? ": " + ps[n]["type"] : ""),
297322
icons: self.getMethodIcons(ps[n])
@@ -302,6 +327,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
302327
methods: (function (met) {
303328
var arr = [], n;
304329
for (n in met) {
330+
keyWordsArray.push(n);
305331
arr.push({
306332
text: n + (met[n]["returns"] ? ": " + met[n]["returns"] : ""),
307333
styles: (function (t) {
@@ -319,6 +345,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
319345
SYMBOL_12_WIDTH: self.SYMBOL_12_WIDTH
320346
});
321347

348+
classInstance.SEARCH_KEYWORDS = keyWordsArray.join(",").toLowerCase();
322349
this.objects.push(classInstance);
323350
this.graph.addCell(classInstance);
324351

@@ -562,6 +589,69 @@ ClassView.prototype.zoom = function (delta) {
562589

563590
};
564591

592+
/**
593+
* Focus on joint instance.
594+
* @param jointInstance
595+
*/
596+
ClassView.prototype.focusOnInstance = function (jointInstance) {
597+
598+
var bb = jointInstance.getBBox();
599+
600+
this.focusOnXY(bb.x + bb.width/2, bb.y + bb.height/2);
601+
602+
};
603+
604+
/**
605+
* Focus on x and y coordinates considering scale.
606+
* @param {number} x
607+
* @param {number} y
608+
*/
609+
ClassView.prototype.focusOnXY = function (x, y) {
610+
611+
var sw = this.cacheUMLExplorer.elements.classViewContainer.offsetWidth,
612+
sh = this.cacheUMLExplorer.elements.classViewContainer.offsetHeight,
613+
scale = this.PAPER_SCALE;
614+
615+
this.paper.setOrigin(
616+
-(x * scale) + sw/2,
617+
-(y * scale) + sh/2
618+
);
619+
620+
};
621+
622+
/**
623+
* Find text on diagram and focus on element.
624+
*
625+
* @param {string} text
626+
*/
627+
ClassView.prototype.searchOnDiagram = function (text) {
628+
629+
var p, found = [], o;
630+
631+
if (!text) {
632+
this.highlightElement(null);
633+
return;
634+
}
635+
636+
text = text.toLowerCase();
637+
638+
for (p in this.objects) {
639+
if (this.objects[p].SEARCH_KEYWORDS.indexOf(text) !== -1) {
640+
found.push(this.objects[p]);
641+
}
642+
}
643+
644+
if (found.length) {
645+
o = found[this.SEARCH_INDEX % found.length];
646+
this.focusOnInstance(o);
647+
this.highlightElement(o);
648+
return;
649+
}
650+
651+
this.highlightElement(null);
652+
653+
};
654+
565655
ClassView.prototype.init = function () {
566656

567657
var p, self = this,
@@ -635,6 +725,19 @@ ClassView.prototype.init = function () {
635725
this.cacheUMLExplorer.elements.helpButton.addEventListener("click", function () {
636726
self.renderInfoGraphic();
637727
});
728+
this.cacheUMLExplorer.elements.diagramSearch.addEventListener("input", function (e) {
729+
self.searchOnDiagram((e.target || e.srcElement).value);
730+
});
731+
this.cacheUMLExplorer.elements.diagramSearch.addEventListener("keydown", function (e) {
732+
if (e.keyCode === 13) {
733+
self.SEARCH_INDEX++;
734+
self.searchOnDiagram((e.target || e.srcElement).value);
735+
}
736+
});
737+
this.cacheUMLExplorer.elements.diagramSearchButton.addEventListener("click", function () {
738+
self.SEARCH_INDEX++;
739+
self.searchOnDiagram(self.cacheUMLExplorer.elements.diagramSearch.value);
740+
});
638741

639742
this.SYMBOL_12_WIDTH = (function () {
640743
var e = document.createElementNS("http://www.w3.org/2000/svg", "text"),

0 commit comments

Comments
 (0)