Release 1.1.0
Release 1.1.0 of VisuallyJs adds a couple of very useful capabilities - a component to manage scrollable lists (such as for data mappers), and the ability to declaratively hide/show content based on zoom level.
Scrolling list manager
Configure a scrollable list with a single DOM attribute.
export function MyList() {
return <div data-vjs-list={true}>
<div data-vjs-port="1">Item One</div>
<div data-vjs-port="2">Item Two</div>
<div data-vjs-port="3">Item Three</div>
...
</div>
}
VisuallyJs will attach a listener to this component and then whenever it is scrolled, edges attached to any of the child elements that are scrolled out of view will be moved so that they are attached to the component's container.
Displaying content based on zoom
In some applications, you might want to display more content on your nodes and groups when the canvas is zoomed in, and less when it is zoomed out, to reduce clutter. In 1.1.0 we've added support for this across our various library integrations.
- React
- Angular
- Vue
- Svelte
Use the new useZoom hook to get access to the current zoom as state:
import { useZoom } from '@visuallyjs/browser-ui-react';
export default function ZoomDisplay({ ui, obj, model }) {
const zoom = useZoom(ui);
return (
<div style={{ position: 'absolute', top: 10, left: 10, background: 'white', padding: '5px' }}>
Current Zoom: {(zoom * 100).toFixed(0)}%
{zoom > 1.5 && <p>High magnification active</p>}
{zoom < 0.5 && <p>Low magnification active</p>}
</div>
);
}
BaseNodeComponent and BaseGroupComponent now have a zoom() signal available for subclasses to use. As shown in this code snippet, you can use the signal both inside your templates, and also to compute dynamic properties:
import { Component, computed } from '@angular/core';
import { BaseNodeComponent } from '@visuallyjs/browser-ui-angular';
@Component({
template:`<div>
{{data.title}}
@if (zoom() > 1.5) {
<div class="details">
<!-- Detailed information shown only when zoomed in -->
<p>{{ data.description }}</p>
</div>
}
</div>`
})
export class MyCustomNode extends BaseNodeComponent {
isZoomedIn = computed(() => this.zoom() > 2);
}
VisuallyJs provides a useZoom composable you can use to show/hide content based on zoom:
<script setup lang="ts">
import { useZoom } from '@visuallyjs/browser-ui-vue';
import { BrowserUI, Node } from '@visuallyjs/browser-ui';
const props = defineProps({
vertex: Node,
ui: BrowserUI
})
// 'zoom' is a reactive Ref<number>
const zoom = useZoom(props.ui)
</script>
<template>
<div class="my-node">
<!-- Show detailed view when zoomed in (zoom > 1) -->
<section v-if="zoom > 1" class="detailed-view">
<p>Detailed Information</p>
</section>
<!-- Show compact view when zoomed out -->
<section v-else class="compact-view">
<span>Compact View</span>
</section>
</div>
</template>
VisuallyJs provides a useZoom reactive state object you can use to selectively show/hide content based on zoom:
<script lang="ts">
import type { SvelteWrapperProps } from "@visuallyjs/browser-ui-svelte";
import { useZoom } from "@visuallyjs/browser-ui-svelte";
// Receive props from VisuallyJS
let p = $props() as SvelteWrapperProps;
let { ui } = p;
// Create the reactive zoom state
const zoom = useZoom(ui);
</script>
<div style="background-color:blue; width:100%; height:100%;">
{#if zoom.current > 1}
<p>This is the detailed description visible at high zoom levels.</p>
{:else}
<p>Small description</p>
{/if}
</div>
Other updates
In addition to these two new capabilities, we've also made a number of small updates:
- Updated the
ForceDirectedlayout to ensure that attraction/repulsion is clamped to a specific range, to avoid blowouts in positioning. - Palette uses
.vjs-palette-drag-activeand.vjs-palette-drag-hoverclasses now, instead of using the same ones that are used in the edge drag lifecycle. - Improved API docs
- Fixed issue in Snaplines plugin that would cause it to not reset if drag was aborted.
- Added the ability to provide sort function to the
GridLayout(andColumnLayout/RowLayout) - Fixed positioning issue when labels on a chart were rotated 45 degrees to maximise space
- Added support for pluggable router
Try VisuallyJs
VisuallyJs offers an extensive list of starter apps, diagrams, charts and dashboards to quick start your development, in React, Angular, Vue, Svelte and Typescript/Javascript.
























