diff --git a/app/svganim/strokes.py b/app/svganim/strokes.py
index 50796bf..e624853 100644
--- a/app/svganim/strokes.py
+++ b/app/svganim/strokes.py
@@ -14,7 +14,7 @@ import tempfile
import io
import logging
from anytree import NodeMixin, RenderTree, iterators
-from anytree.exporter import JsonExporter
+from anytree.exporter import JsonExporter, DictExporter
from anytree.importer import JsonImporter, DictImporter
logger = logging.getLogger('svganim.strokes')
@@ -538,10 +538,15 @@ class AnnotationIndex:
self.shelve['_annotations'][annotation.id] = annotation
if annotation.tag not in self.shelve['_tags']:
self.shelve['_tags'][annotation.tag] = [annotation]
+ logger.error(f"Use of non-existing tag {annotation.tag}")
else:
self.shelve['_tags'][annotation.tag].append(
annotation
)
+ tag = self.root_tag.find_by_id(annotation.tag)
+ if tag is not None:
+ tag.annotation_count += 1
+
@property
def drawings(self) -> dict[str, Drawing]:
@@ -715,7 +720,7 @@ def strokes2D(strokes):
return d
class Tag(NodeMixin):
- def __init__(self, id, name = None, description = "", color = None, parent=None, children=None):
+ def __init__(self, id, name = None, description = "", color = None, parent=None, children=None, annotation_count=None):
self.id = id
self.name = self.id if name is None else name
self.color = color
@@ -724,6 +729,8 @@ class Tag(NodeMixin):
if children:
self.children = children
+ self.annotation_count = 0 #always zero!
+
if self.id == 'root' and not self.is_root:
logger.error("Root node shouldn't have a parent assigned")
@@ -747,8 +754,11 @@ class Tag(NodeMixin):
return t
return None
- def toJson(self) -> str:
- return JsonExporter(indent=2).export(self)
+ def toJson(self, with_counts=False) -> str:
+ ignore_counts=lambda attrs: [(k, v) for k, v in attrs if k != "annotation_count"]
+ attrFilter = None if with_counts else ignore_counts
+
+ return JsonExporter(DictExporter(attriter=attrFilter), indent=2).export(self)
def loadTagFromJson(string) -> Tag:
tree: Tag = JsonImporter(DictImporter(Tag)).import_(string)
diff --git a/app/templates/index.html b/app/templates/index.html
index 429bf93..af69133 100644
--- a/app/templates/index.html
+++ b/app/templates/index.html
@@ -44,17 +44,23 @@
visibility: visible;
;
} */
- #tags li.selected > ul>li.add-tag {
+ #tags li.selected>ul>li.add-tag {
display: block;
}
- #tags > li > ul >li.add-tag {
+ #tags>li>ul>li.add-tag {
display: block;
;
}
-
-
+ #annotations .annotations-actions {
+ margin-bottom: 10px;
+ color: darkgray;
+ font-size: 80%;
+ border-bottom: solid 3px #444;
+ }
+
+
#tags .add-tag {
display: none;
@@ -73,33 +79,37 @@
vertical-align: middle;
margin-right: 10px;
}
- #tags li:hover > div > input.rm-tag{
+
+ #tags li:hover>div>input.rm-tag {
display: inline-block;
}
- #tags li div{
- position:relative
+
+ #tags li div {
+ position: relative
}
- #tags input.rm-tag:hover{
+
+ #tags input.rm-tag:hover {
color: red;
transform: rotate(20deg);
}
- #tags input.rm-tag{
+
+ #tags input.rm-tag {
/* display: none; */
- position:absolute;
- right:0;
- top:0;
- padding:0;
+ position: absolute;
+ right: 0;
+ top: 0;
+ padding: 0;
background: none;
border: none;
color: white;
- cursor:pointer;
+ cursor: pointer;
}
#tags .selected>div {
background: lightblue
}
-
+
summary h2 {
display: inline-block;
cursor: pointer;
@@ -117,7 +127,7 @@
display: block;;
} */
-
+
#annotation_manager {
display: grid;
@@ -143,9 +153,7 @@
}
- #annotations li {
-
- }
+ #annotations li {}
#annotations img {
/* width: 400px; */
@@ -179,7 +187,6 @@
#annotations .svganim_player:hover .controls {
visibility: visible !important;
}
-
diff --git a/app/webserver.py b/app/webserver.py
index 243e0d4..99ca601 100644
--- a/app/webserver.py
+++ b/app/webserver.py
@@ -558,9 +558,10 @@ class TagsHandler(tornado.web.RequestHandler):
def get(self):
self.set_header("Content-Type", "application/json")
- with open('www/tags.json', 'r') as fp:
- # TODO: enrich with counts
- self.write(fp.read())
+ self.write(self.index.root_tag.toJson(with_counts=True))
+ # with open('www/tags.json', 'r') as fp:
+ # # TODO: enrich with counts
+ # self.write(fp.read())
def put(self):
# data = json.loads(self.request.body)
diff --git a/app/www/annotations.js b/app/www/annotations.js
index a3f1e7a..0ab6c04 100644
--- a/app/www/annotations.js
+++ b/app/www/annotations.js
@@ -8,12 +8,13 @@ class AnnotationManager {
this.selectedAnnotations = [];
this.selectedTag = null;
- this.loadTags(tagsUrl);
+ this.tagsUrl = tagsUrl;
+ this.loadTags();
}
- loadTags(tagFile) {
+ loadTags() {
// tags config
- const request = new Request(tagFile);
+ const request = new Request(this.tagsUrl);
return fetch(request)
.then(response => response.json())
.then(rootTag => {
@@ -31,7 +32,7 @@ class AnnotationManager {
const tagSubEl = document.createElement('ul');
const tagEl = document.createElement('div');
- tagEl.innerText = tag.get_name();
+ tagEl.innerText = `${tag.get_name()} (${tag.annotation_count ?? 0})`;
tagEl.addEventListener('click', (ev) => {
this.selectTag(tag);
})
@@ -318,6 +319,7 @@ class AnnotationManager {
}));
this.loadAnnotationsForTag(this.selectedTag)
+ this.loadTags() //updates the counts
}
async saveTags() {