diff --git a/css/empty-view.css b/css/empty-view.css new file mode 100644 index 00000000..da3d2073 --- /dev/null +++ b/css/empty-view.css @@ -0,0 +1,18 @@ +#empty-view { + display: none; + align-items: center; + background-color: #e1e1e1; + padding: 10px; + position: fixed; + z-index: 2; + height: 30px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border-radius: 5px; + border: 1px solid #000; +} + +#empty-view p { + margin-left: 10px; +} diff --git a/img/blue-info.svg b/img/blue-info.svg new file mode 100644 index 00000000..760cf319 --- /dev/null +++ b/img/blue-info.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 48d7fdab..ae678fe2 100644 --- a/index.html +++ b/index.html @@ -17,6 +17,7 @@ + @@ -156,6 +157,11 @@
+
+ Empty view +

This view has no elements

+
+

Switch to

diff --git a/js/draw.js b/js/draw.js index e5c31903..555d8173 100644 --- a/js/draw.js +++ b/js/draw.js @@ -1,4 +1,5 @@ import { canvas, ctx } from "./main.js"; +import { updateCanvas } from "./lib/graphic-primitives.js"; function draw(objects) { const datatypes = objects.datatypes; @@ -32,19 +33,26 @@ function draw(objects) { } export function drawAll(loadedObjects) { - ctx.clearRect(0, 0, canvas.width, canvas.height); - + emptyCanvas(); draw(loadedObjects); } export function drawVisible(visibleObjects) { + emptyVisibleCanvas(); + draw(visibleObjects); +} + +export function emptyCanvas() { + updateCanvas(ctx, 0, 0, canvas.width, canvas.height); +} + +function emptyVisibleCanvas() { const boundigClientRect = canvas.getBoundingClientRect(); - ctx.clearRect( + updateCanvas( + ctx, 0 - boundigClientRect.x, 0 - boundigClientRect.y, window.innerWidth, window.innerHeight ); - - draw(visibleObjects); } diff --git a/js/lib/empty-object.js b/js/lib/empty-object.js new file mode 100644 index 00000000..8b24aecd --- /dev/null +++ b/js/lib/empty-object.js @@ -0,0 +1,32 @@ +const updateEmpty = (empty, length) => { + if (length === 0) { + empty.value = empty.value && true; + } else { + empty.value = false; + } +}; + +export function checkEmptyObject(obj) { + const datatypes = obj.datatypes; + const associations = obj.associations; + + let empty = { value: true }; + + Object.values(datatypes).forEach((datatype) => { + updateEmpty(empty, datatype.collection.length); + + Object.values(datatype.oneToMany).forEach((oneToMany) => { + updateEmpty(empty, oneToMany.length); + }); + + Object.values(datatype.oneToOne).forEach((oneToOne) => { + updateEmpty(empty, oneToOne.length); + }); + }); + + Object.values(associations).forEach((association) => { + updateEmpty(empty, association.length); + }); + + return empty.value; +} diff --git a/js/lib/graphic-primitives.js b/js/lib/graphic-primitives.js index a09cf63f..1318b7cb 100644 --- a/js/lib/graphic-primitives.js +++ b/js/lib/graphic-primitives.js @@ -108,6 +108,10 @@ export function drawStraightLink(ctx, link) { ctx.restore(); } +export function updateCanvas(ctx, x, y, width, height) { + ctx.clearRect(x, y, width, height); +} + export function drawObjectHeader(ctx, object) { ctx.save(); ctx.font = "bold 16px sans-serif"; diff --git a/js/lib/messages.js b/js/lib/messages.js index 4b24f73e..495bb3b9 100644 --- a/js/lib/messages.js +++ b/js/lib/messages.js @@ -11,3 +11,13 @@ export function errorMsg(msg) { msgDiv.style.color = "red"; msgDiv.innerHTML = "

ERROR: " + msg + "

"; } + +export function emptyViewMessage() { + const msgDiv = document.getElementById("empty-view"); + msgDiv.style.display = "flex"; +} + +export function hideEmptyViewMessage() { + const msgDiv = document.getElementById("empty-view"); + msgDiv.style.display = "none"; +} diff --git a/js/views/association-view.js b/js/views/association-view.js index 5c931c04..4f04bf03 100644 --- a/js/views/association-view.js +++ b/js/views/association-view.js @@ -5,11 +5,6 @@ export function buildAssociationView(viewObjects, associationName) { const associations = viewObjects.associations[associationName]; const length = associations.length; - if (length === 0) { - alert("No association found!"); - return; - } - const fromWidth = associations[0].from.width; const toWidth = associations[0].to.width; const fromHorizontalGap = 0.3 * fromWidth; diff --git a/js/views/clustertree.js b/js/views/clustertree.js index f4ce1ca9..e38432c3 100644 --- a/js/views/clustertree.js +++ b/js/views/clustertree.js @@ -5,11 +5,6 @@ export function clusterTree(viewCurrentObjects) { const clusterCollection = viewCurrentObjects.datatypes["edm4hep::Cluster"].collection ?? []; - if (clusterCollection.length === 0) { - alert("No Clusters found in this event."); - return; - } - buildTree(clusterCollection, "clusters"); } diff --git a/js/views/list.js b/js/views/list.js index 99aa7ce4..a6806249 100644 --- a/js/views/list.js +++ b/js/views/list.js @@ -1,10 +1,6 @@ import { canvas } from "../main.js"; export function listView(collection) { - if (collection.length === 0) { - alert("No objects found!"); - return; - } const width = window.innerWidth; canvas.width = width; diff --git a/js/views/mcparticletree.js b/js/views/mcparticletree.js index 4b702cc1..7f4ec1cf 100644 --- a/js/views/mcparticletree.js +++ b/js/views/mcparticletree.js @@ -5,10 +5,6 @@ export function mcParticleTree(viewCurrentObjects) { const mcCollection = viewCurrentObjects.datatypes["edm4hep::MCParticle"].collection ?? []; - if (mcCollection.length === 0) { - alert("No MCParticles found in this event."); - } - const getMaxRow = (parentLinks) => { let maxRow = -1; for (const parentLink of parentLinks) { diff --git a/js/views/onewayview.js b/js/views/onewayview.js index 1a6f8683..c69bddaa 100644 --- a/js/views/onewayview.js +++ b/js/views/onewayview.js @@ -7,11 +7,6 @@ export function oneWayView(viewObjects, fromCollectionName, relationName) { const fromCollection = relations.map((relation) => relation.from); const toCollection = relations.map((relation) => relation.to); - if (fromCollection.length === 0 || toCollection.length === 0) { - alert("No association found!"); - return; - } - const fromWidth = fromCollection[0].width; const toWidth = toCollection[0].width; const fromHorizontalGap = 0.3 * fromWidth; diff --git a/js/views/recoclustertrack.js b/js/views/recoclustertrack.js index 874f9630..d9fd30ea 100644 --- a/js/views/recoclustertrack.js +++ b/js/views/recoclustertrack.js @@ -5,11 +5,6 @@ export function recoClusterTrackVertex(viewObjects) { const recoParticles = viewObjects.datatypes["edm4hep::ReconstructedParticle"].collection; - if (recoParticles.length === 0) { - alert("No reconstructed particles found!"); - return; - } - const findFirstObject = (relationName) => { const object = recoParticles.find((particle) => { const relation = particle.oneToManyRelations[relationName]; diff --git a/js/views/recoparticletree.js b/js/views/recoparticletree.js index 26a73e32..a578a90a 100644 --- a/js/views/recoparticletree.js +++ b/js/views/recoparticletree.js @@ -6,10 +6,6 @@ export function recoParticleTree(viewCurrentObjects) { viewCurrentObjects.datatypes["edm4hep::ReconstructedParticle"].collection ?? []; - if (recoCollection.length === 0) { - alert("No ReconstructedParticles found in this event."); - } - buildTree(recoCollection, "particles"); } diff --git a/js/views/tracktree.js b/js/views/tracktree.js index 523441b8..6ff0ff36 100644 --- a/js/views/tracktree.js +++ b/js/views/tracktree.js @@ -5,11 +5,6 @@ export function trackTree(viewCurrentObjects) { const trackCollection = viewCurrentObjects.datatypes["edm4hep::Track"].collection ?? []; - if (trackCollection.length === 0) { - alert("No Tracks found in this event."); - return; - } - buildTree(trackCollection, "tracks"); } diff --git a/js/views/views.js b/js/views/views.js index ce655a2a..f74cb3ba 100644 --- a/js/views/views.js +++ b/js/views/views.js @@ -1,5 +1,6 @@ import { currentObjects, currentEvent } from "../event-number.js"; import { copyObject } from "../lib/copy.js"; +import { checkEmptyObject } from "../lib/empty-object.js"; import { getVisible } from "../events.js"; import { drawAll } from "../draw.js"; import { canvas } from "../main.js"; @@ -11,6 +12,8 @@ import { mouseMove, onScroll, } from "../events.js"; +import { emptyViewMessage, hideEmptyViewMessage } from "../lib/messages.js"; +import { emptyCanvas } from "../draw.js"; const currentView = {}; @@ -55,6 +58,15 @@ const drawView = (view) => { const viewVisibleObjects = {}; preFilterFunction(currentObjects, viewObjects); + const isEmpty = checkEmptyObject(viewObjects); + + if (isEmpty) { + emptyCanvas(); + emptyViewMessage(); + return; + } + hideEmptyViewMessage(); + viewFunction(viewObjects); copyObject(viewObjects, viewCurrentObjects);