Inspectors
An inspector is a form that can be used to edit the properties of some object, or set of objects, in the VisuallyJs dataset. Inspectors listen to selection events from the underlying model and then draw a suitable UI for editing the selected object(s) based upon the configuration you provide.
In the canvas below we've setup a simple inspector and selected a vertex to begin with. You can edit the various fields in the form on the left. Note that with the text input, changes are persisted on blur and when the enter key is pressed, but for the textarea changes are only persisted on blur.
Setup
Create a Vue component that renders an InspectorComponent, and pass it a v-model that points to a ref
<script setup>
import { ref } from "vue"
const current = ref(null)
</script>
<template>
<InspectorComponent v-model="current">
<div v-if="current?.objectType==='Node'" class="node-inspector">
<div>Text</div>
<input type="text" vjs-att="text" vjs-focus="true"/>
<div>Fill</div>
<input type="color" vjs-att="fill"/>
</div>
<div v-if="current?.objectType==='Edge'" class="edge-inspector">
<div>Label</div>
<input type="text" vjs-att="label"/>
<div>Color</div>
<input type="color" vjs-att="color"/>
</div>
<div v-if="current == null">
<h3>Nothing selected</h3>
</div>
</InspectorComponent>
</template>
In our template here we examine the objectType from the selected object, which tells us whether it's a Node, Edge, Group or Port. Our UI then paints itself accordingly. At the bottom of the template we write out a message if current is null.
<script setup>
import MyInspectorComponent from './MyInspectorComponent.vue'
const data = {}
</script>
<template>
<DiagramProvider>
<DiagramComponent :data="data"/>
<MyInspectorComponent/>
</DiagramProvider>
</template>
The InspectorComponent is discussed in detail in the reference docs on this page.
Binding data
Fields in your data objects are bound to HTML elements via an vjs-att attribute. For instance, here's the form we use in the example canvas above:
<input type="text" vjs-att="label">
<textarea vjs-att="description" rows="10" cols="10"></textarea>
<select vjs-att="someNumber">
<option value="1">1</option>
<option value="5">5</option>
<option value="10">10</option>
</select>
Each of the vjs-att attributes in the HTML above maps to a property in the backing data of the object(s) being inspected:
{
label:"My Object",
description:"This is my object, with a label and a description and some number",
someNumber:5
}
Supported input types
This is the list of supported input types. We show a simple example for each type, but keep in mind you can use all the available attributes on these in your markup - for instance, for a number field, perhaps you want to limit the allowed values. Or you could supply a regular expression to a text input, etc.
Text Input
<input type='text' vjs-att="someProperty">
Radio Button
<input type='radio' vjs-att="someProperty" value="radioValue" name="someProperty">
Checkbox(es)
<input type='checkbox' vjs-att="someProperty">
The inspector supports rendering multiple checkboxes with the same vjs-att, for example:
<div class="my-inspector">
<input type='checkbox' vjs-att="someProperty" value="type1">
<input type='checkbox' vjs-att="someProperty" value="type2">
</div>
You need to be using an array in your data to support this:
{
id:"my-vertex",
someProperty:["type1", "type2"]
}
Number Input
<input type='number' vjs-att="someProperty">
Textarea
<textarea vjs-att="someProperty" rows="10" cols="5">
Select
<select vjs-att="someProperty">
<option value="someValue">Some Value</option>
<option value="someOtherValue">Some Other Value</option>
</select>
Color Input
<input type='color' vjs-att="someProperty">
Hidden Input
<input type='hidden' vjs-att="someProperty" value="someValue">
Non-string datatypes
By default, HTML element values are strings, which may not be ideal for your data model. You can instruct VisuallyJs to cast the value of certain elements to a number, by declaring a vjs-datatype attribute in your inspector template:
<div>
<select vjs-att="threshold" vjs-datatype="integer">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
</select>
</div>
In this example, VisuallyJs will attempt to cast the value to an integer. Currently, supported values for vjs-datatype are:
- integer Cast the value to an integer
- float Cast the value to a float, eg 1.5, 2.0, etc.
The vjs-datatype attribute is supported on:
<select.../><input type="radio" .../><input type="text" .../>
If you're using an input of type text and you want a number, it's probably better to use an input of type number - see MDN's discussion here.
Multiple selections
By default, an inspector supports selections containing multiple objects. When multiple objects are being edited, the inspector calculates a set of "common data", ie. the set of keys for which every object in the inspector has a value. For text inputs and text areas, if every value for some given key is the same across all the managed objects, that value is shown and can be edited, resulting in a change to all the managed objects. Otherwise, if not every value is the same, the text input or text area will display a blank value. If the user types in the input field then that change will be propagated to all the managed objects.
To switch off multiple selections you can do this:
<script setup>
import { ref } from "vue"
const current = ref(null)
</script>
<template>
<InspectorComponent v-model="current"
:multipleSelections="true">
...
</InspectorComponent>
</template>