Mermaid-Chart / vscode-mermaid-preview

Previews Mermaid diagrams
MIT License
142 stars 15 forks source link

Better UX for wide diagrams #44

Closed vstirbu closed 5 years ago

vstirbu commented 6 years ago

Wide diagrams are scaled down in a way that makes reading the text hard.

With version 0.8.0 I've tried to add pan and zooming support to address this problem. The library included in that release was svg-pan-zoom, which had some side effects related to scaling on retina displays, so I had to revert. Version 0.8.1, removed the pan and zoom feature and allowed the flowcharts to use as wide area as they need. Version 0.8.2 added a minimap that renders in the upper left corner a smaller version of the diagram.

(panzoom seems to integrate better with mermaid but there are still issues related to integrating it with the previewHTML component of vscode.)

I would appreciate ideas to improve this situation.

g3o2 commented 5 years ago

64 could be a solution for that, at least up to a certain scale.

GaryBer commented 5 years ago

Need some ability to zoom or scroll. Very long diagrams become too scaled to read.

Are you able to do some CSS magic perhaps using overflow: auto to add horizontal and vertical scrollbars?

Also, you could do a simple zoom using a few buttons and the transform: scale() css property.

GaryBer commented 5 years ago

I fixed my vertical zoom issue by changing the line: https://github.com/vstirbu/vscode-mermaid-preview/blob/298a7a9a4d51b7ec728e2e0fe64899ab48bbbaf3/extension.js#L50

To:

<div id="diagram" class="mermaid" style="height: 100%; padding: 15px; overflow: auto;"></div>

This gave me a nice vertical scrollbar.


One issue that arrises is that when clicking on the source code the preview view scrolls back to the top.


Changing that line to:

<div id="diagram" class="mermaid" style="height: 100%; width: 100vw; padding: 15px; overflow: auto;"></div>

Gave me both vertical and horizontal scrollbars.


A simple zoom in and zoom out feature would be nice on top of this.

GaryBer commented 5 years ago

Added a simple zoom ability on top of the scroll bars. Seems to work quite nicely :)

<div id="diagram-container" style="height: 100%; width: 100%; padding: 15px 0; overflow: auto;">
    <div id="diagram" class="mermaid" style="height: 100%; width: 100%; overflow: visible;"></div>
</div>

<div style="position: fixed; top: 10px; right: 10px; z-index: 100; display: block; font-weight: 700; -webkit-text-stroke-width: 1px; -webkit-text-stroke-color: black; font-size: 16px; line-height: 16px; user-select: none; color: #fff;">
  <div id="zoom-in" style="cursor: pointer; padding: 7px;">&plus;</div>
  <div id="zoom-out" style="cursor: pointer; padding: 7px;">&minus;</div>
</div>

<script>
  const zoomIn = document.getElementById('zoom-in');
  const zoomOut = document.getElementById('zoom-out');
  const diagramView = document.getElementById('diagram');

  let currentScale = 1;

  function setDiagramScale(scale) {
    const size = 100 * scale;
    diagramView.style.width = size + '%';
    diagramView.style.height = size + '%';
  }

  setDiagramScale(currentScale);

  zoomIn.addEventListener('click', () => {
    currentScale+=0.25;
    setDiagramScale(currentScale);
  });

  zoomOut.addEventListener('click', () => {
    currentScale-=0.25;
    setDiagramScale(currentScale);
  });
</script>
GaryBer commented 5 years ago

Fixed the scroll bug that I was having.

const diagramContainer = document.getElementById('diagram-container');

    let currentScrollTop = 0;

    function setDiagramScrollTop(value) {
      window.scrollTo({
        top: value
      });
    }

    document.addEventListener('scroll', () => {
      const value = parseInt(window.scrollY);
      if (value) {
        currentScrollTop = value;
      }
    });

Just add setDiagramScrollTop(currentScrollTop); to the end of the window message event listener.

window.addEventListener('message', event => {
        const message = event.data;

        minimap.textContent = message.diagram;
        minimap.removeAttribute('data-processed');

        diagram.textContent = message.diagram;
        diagram.removeAttribute('data-processed');

        mermaid.init();

        setDiagramScrollTop(currentScrollTop);
});