archi
archi copied to clipboard
[Feature request] Diagram zooming in HTML reports
I also use Archimate to create deployment diagrams, as it has the nice feature of clickable documentation. This use-case comes with giant diagrams which contain all the features in one encompassing diagram.
Currently the HTML report shows the entire diagram, making it hard to read the actual content. And there is no way of zooming, to get to a readible level.
By offering a zooming solution within the diagram frame, you can explore the elements in a readeble fashion. Perhaps even with an outline, just as in the normal Archimate UI.
Another solution to this problem might be sub-diagrams, so that by double clicking on an element, you can get a sub-diagram providing more detail on the element just clicked.
Reading further into the details, I see that the https://github.com/davidjbradshaw/image-map-resizer is already used in the current version of the HTML view. So theoretical, if the image can be resized and panned, than the imageMapResize()
should correct the image map to enable interaction.
Considering that the topright frame includes more than just the image, just the image should zoom and pan, not the entire iframe. Ideally it would be easily discoverable, either by mouseover or with UI elements like a +, - and a D-pad.
Ideally this should also work in the future HTML report update https://github.com/archimatetool/archi/wiki/HTML-export-v3
Perhaps there are better ways than just a image map for making it interactive. I'm not sure about that. But that might be a greater overhaul.
Hi
At my company, my colleague Anita (@anitaMistry) implemented a zoom slider that keeps the image map working correctly.
It looks like this:
Please let me know if you want more info, but basically, we just attach this function to the iframe's load event:
document.querySelector('iframe[name=view]').addEventListener('load', initZoomSlider);
function initZoomSlider() {
let ifrm = document.querySelector('iframe[name=view]');
let lnkHtml = ifrm.contentWindow.location.pathname.substring(1);
const sliderAndLinkHtml = ' \
<style>#btnZoomIn, #btnZoomOut{cursor:pointer;}</style> \
<div class="row" style="width: 230px;float:right;"> \
<div class="col-xs-1" id="btnZoomOut"><span class="glyphicon glyphicon-minus"></span></div> \
<div class="col-xs-7"><input type="range" min="50" max="400" value="100" id="zoomRange"></div> \
<div class="col-xs-1" id="btnZoomIn" style="padding:0"><span class="glyphicon glyphicon-plus"></span></div> \
<div class="col-xs-2" id="linkToView"> <a target="_blank" href="/?link=' + lnkHtml + '">link</a></div> \
</div>';
let doc = ifrm.contentDocument ? ifrm.contentDocument : ifrm.contentWindow.document;
$(doc.getElementsByClassName("panel-heading")[0]).append(sliderAndLinkHtml);
var slider = doc.getElementById("zoomRange");
let img = doc.getElementsByClassName("diagram")[0];
img.style.maxWidth = slider.value + "%";
slider.oninput = function () {
img.style.maxWidth = this.value + "%";
img.style.width = this.value + "%";
window.focus();
}
const step = 10;
doc.getElementById("btnZoomOut").onclick = function () {
slider.value = ((parseInt(slider.value)) - step);
$(slider).trigger("input");
}
doc.getElementById("btnZoomIn").onclick = function () {
slider.value = ((parseInt(slider.value)) + step);
$(slider).trigger("input");
}
}
Update: I have updated the code to be compatible with ES5, IE11
@jbsarrodie maybe this could be useful for others as well
Hi
At my company, my colleague Anita (@anitaMistry) implemented a zoom slider that keeps the image map working correctly.
It looks like this:
Please let me know if you want more info, but basically, we just attach this function to the iframe's load event:
document.querySelector('iframe[name=view]').addEventListener('load', initZoomSlider); function initZoomSlider() { let ifrm = document.querySelector('iframe[name=view]'); let lnkHtml = ifrm.contentWindow.location.pathname.substring(1); const sliderAndLinkHtml = ' \ <style>#btnZoomIn, #btnZoomOut{cursor:pointer;}</style> \ <div class="row" style="width: 230px;float:right;"> \ <div class="col-xs-1" id="btnZoomOut"><span class="glyphicon glyphicon-minus"></span></div> \ <div class="col-xs-7"><input type="range" min="50" max="400" value="100" id="zoomRange"></div> \ <div class="col-xs-1" id="btnZoomIn" style="padding:0"><span class="glyphicon glyphicon-plus"></span></div> \ <div class="col-xs-2" id="linkToView"> <a target="_blank" href="/?link=' + lnkHtml + '">link</a></div> \ </div>'; let doc = ifrm.contentDocument ? ifrm.contentDocument : ifrm.contentWindow.document; $(doc.getElementsByClassName("panel-heading")[0]).append(sliderAndLinkHtml); var slider = doc.getElementById("zoomRange"); let img = doc.getElementsByClassName("diagram")[0]; img.style.maxWidth = slider.value + "%"; slider.oninput = function () { img.style.maxWidth = this.value + "%"; img.style.width = this.value + "%"; window.focus(); } const step = 10; doc.getElementById("btnZoomOut").onclick = function () { slider.value = ((parseInt(slider.value)) - step); $(slider).trigger("input"); } doc.getElementById("btnZoomIn").onclick = function () { slider.value = ((parseInt(slider.value)) + step); $(slider).trigger("input"); } }
Update: I have updated the code to be compatible with ES5, IE11
Hi, Could you tell me where to copy this code ? I put it in model.js but it doesn't work. Thanks a lot.
Hi, Could you tell me where to copy this code ? I put it in model.js but it doesn't work. Thanks a lot.
You'de better use the latest version of the HTML report template which includes this and other changes. It will be shipped with Archi 4.9 but in the meantime you can easily use it: simply replace the plugins\com.archimatetool.reports_x.x.x\templates
folder by the one you can get inside the html-report branch. You can get the zip version of this branch here.
Report now looks like this:
You'll note the zoom slider but also the serach feature on the model tree. There's also now a way to hide views, concepts or folders from the export (based on properties set inside your model).
Thanks a lot ! Works very well, this new template is very nice. Great job !
Le 10 juin 2021 à 18:28, Jean-Baptiste Sarrodie @.***> a écrit :
Hi, Could you tell me where to copy this code ? I put it in model.js but it doesn't work. Thanks a lot.
You'de better use the latest version of the HTML report template which includes this and other changes. It will be shipped with Archi 4.9 but in the meantime you can easily use it: simply replace the plugins\com.archimatetool.reports_x.x.x\templates folder by the one you can get inside the html-report branch. You can get the zip version of this branch here.
Report now looks like this:
You'll note the zoom slider but also the serach feature on the model tree. There's also now a way to hide views, concepts or folders from the export (based on properties set inside your model).
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
HI guys! Do you keep in mind the hot keys like Ctrl+mouse wheel (or Ctrl +/-)? It's always quicker to roll the wheel rather than using particular controls.
As big brother GitHub already indicates, I created a docker container so I can generate html reports easily during CI without uploading or downloading Archi in the pipeline directly.
The new template does look really nice, but unfortunately trying to zoom kind of nukes the layout most of the time. Occasionally it works fine. By nuking I mean: title bar of the diagram looses color en the diagram image just vanishes.
Going back and forth a few times between Views seems to somehow solve the issues.
The console if full of these errors, maybe that helps:
Any idea on what I am doing wrong?
Hi, I've had no issues and I tested with IE, Edge, Chrome and Firefox. Can you provide more information on your exact setup?
Of course, thanks for replying 👍 I really appreciate it. I have downloaded the Archi linux version, coArchi plugin and new html template. Copy everything inside a docker container where I:
- unzip Archi
- add the coArchi jars to the plugins folder
- delete the reports.xxx/templates folder en replace it with the new template (included in the repo)
- run Archi report generator from the cli, using the linux headless instructions
- deploy as a static website to an Azure Web App
the entire source can be found here: https://github.com/YoeriVD/archi-html-report-container
I have tested in Edge (mac) and Safari (mac) and my repro steps are the following:
- Launch website
- open specific View (important: do not click on anything else)
- zoom using the slider
- Diagram vanishes sometimes
if I click on an element before zooming, somehow zooming seems to work fine. Refreshing the page also helps sometimes. In any case, the console is spammed with the "Uncaught TypeError: e.originalEvent.data.split is not a function" error.
Does this help?
I can confirm the diagram vanishing on Mac with Safari. A Refresh seems to help.
Wild guess, going from the js code sample above: Could it be a race condition?
- load view
- init slider for loaded iframe
- change view
- zoom before new iframe loaded event
- ?? unexpected behavior
It would explain why it works after a refresh or clicking something. Also why it only happens sometimes.
If you click on the link for the View in the Model Tree twice it works OK.
@Phillipus does your latest commit fix the race condition? In my case it is quite persistent. I have been getting remarks that the website "doesn't work" rendering it almost unusable.
@Phillipus does your latest commit fix the race condition? In my case it is quite persistent. I have been getting remarks that the website "doesn't work" rendering it almost unusable.
No. I haven't worked on this aspect of the HTML report nor do I know how to fix it. Perhaps someone could contribute a patch.
I experimented using Safari on Mac.
In file frame.js
, function initZoomSlider
, there is this line:
let imgNativeWidth = img.width;
Sometimes img.width
is 0 which causes the problem.
A workaround is to add a small delay to calling the function initZoomSlider
at line 171:
// initZoomSlider();
setTimeout(initZoomSlider, 50)
@YoeriVD Can you edit your frame.js
file and try this?
Hi, I was looking at the modified implementation, I guess that the problem is that the $(document).ready() does not wait for the images to be loaded. If you can rely on the onload event instead, it can do the work without using the setTimeout call
Hi, I was looking at the modified implementation, I guess that the problem is that the $(document).ready() does not wait for the images to be loaded. If you can rely on the onload event instead, it can do the work without using the setTimeout call
Indeed, that is the case. Thanks for the heads up.
@YoeriVD Please replace line 134 with:
$(window).on('load', function() {
and try that.
This looks good to me! I was not able to break it anymore :) I really appreciate the effort guys, helps a lot.
This looks good to me! I was not able to break it anymore :) I really appreciate the effort guys, helps a lot.
Thanks for confirmation. We'll get this fix into the next maintenance release. In the meantime, you can simply use the modified frame.js
file.