# Customize the UI
# Overview
The viewer UI is composed of three main parts :
- First, there is the menu. The menu is where some useful actions can be performed like customizing the rest of the UI using the window manager. The menu is not displayed on the bottom-right image. It is a special case where the user wants to hide it. By default, a button (top-right) is automatically added to customize the windows.
- Next, there is the main view where windows are displayed. The user can resize, add, delete, split or swap windows to create his own workspace, according to his needs. On the images above there is one, two or three windows with spatial arborescence, a 2d and 3d representations of the model displayed on different windows.
- Last, there are plugins displayed on windows. Different display possibilities are shown on the image below (full, left, right, small...).
# Menu
By default, the menu is always displayed as a top bar. However, it can be changed if only one window is present, or totally removed if you need to.
# Hidden menu
To hide the menu on a single window, the menu
property on a window configuration object must be set to false
.
const bimdataViewer = makeBIMDataViewer(/* {...} */);
const windowConfigurationObject = {
name: "windowName",
menu: false,
plugins: [
/* plugins */
],
};
bimdataViewer.registerWindow(windowConfigurationObject);
Then, if this window is displayed, the menu will be hidden like on the image below.
If there is more than one windows displayed, even if they have the menu property set to false, the header will be displayed as a top bar. To completely hide it, set the viewer ui.menuVisible
property to false:
const bimdataViewer = makeBIMDataViewer({
/* */
ui: {
menuVisible: false,
},
});
# Window manager tools
The menu contains the window manager tools.
It is displayed on the right of the bar or as a right plugin if the menu is hidden.
You can choose to disable it to do not let the user update the UI:
const bimdataViewer = makeBIMDataViewer({
/* */
ui: {
windowManager: false,
},
});
# Window
A window is composed of plugins and can be registered using two ways :
- The first is by adding a window configuration object in a plugin configuration.
- The second is by registering it directly on the BIMData viewer object.
# Window configuration object
Property | Description |
---|---|
name : string | Required The name of the window. Must be unique. |
label : string | The label that is displayed to the user. Can be a key to be translated like : "viewer3d.window_label". |
plugins : array | An array of plugins which will be added to the window. |
icon.imgUri : string | A string that is injected into an img HTML element as a src. This image will be displayed while selecting the window on the window selector |
menu : boolean | Default to true . If false , the menu is hidden if there is only one window displayed. |
const bimdataViewer = makeBIMDataViewer(/* {...} */);
const windowConfigurationObject = {
name: "windowName",
plugins: [
/* plugins */
],
};
// first way
bimdataViewer.registerPlugin({
/* plugin specific fields */
window: windowConfigurationObject,
});
// second way
bimdataViewer.registerWindow(windowConfigurationObject);
# Plugin
The viewer is shipped with native BIMData plugins but others can be added to add new features and more possibilities. A plugin is mainly either a Vuejs component (opens new window) or/and a simple function that is run when the viewer is mounted into the DOM (opens new window).
TIP
See the plugins documentation to know how to develop a plugin and add new features to the viewer.
A plugin is added to the viewer by registering it :
import makeBIMDataViewer from "@bimdata/viewer";
import MyPlugin from "@myOrganisation/plugin";
const bimdataViewer = makeBIMDataViewer(/* {...} */);
bimdataViewer.registerPlugin(MyPlugin);
# Plugin registration API
The registerPlugin method take an object as argument. The options are the followings:
Property | Description |
---|---|
name : string | Required The name of the plugin. Must be unique. |
component : object | A Vuejs (v2.x) component. |
i18n : object | An object containing translations for internationalization. |
startupScript($viewer) | A function that is executed when the viewer is mounted, with $viewer as argument. |
button : object | An object that describe the display of the plugin if the plugin is shown as button. |
window : object | An object used to register a window with this plugin in it. |
addToWindows : string[] | An array of window name in which to include this plugin. |
# Button
Property | Description |
---|---|
position : string | "left" or "right". The position of the button in the window. |
content : string | "simple", "panel" or "free"(default). Different way to display the component when the button is clicked. (see images below) |
tooltip : string | A string that is displayed when the plugin button is hovered. It can be a key to be translated ex: "myPluginName.tooltip" |
keepOpen : boolean | Default to false . If true , the plugin stay open even if the user click away from it. |
icon.imgUri : string | An uri to an image for the button. |
If only the icon
is defined, the corresponding image is always displayed on the button.
A similar option, iconOpen can be defined to display a different icon when the button is open.
The images below show the different way to display plugin as button. (top-left : content = simple
, top-right : content = free
, bottom : content = panel
)
The simple
mode display the component in a small div adapted for small menu interfaces like switching between few options.
The free
mode display the component in a div. The developer of the plugin is responsible to decide the style of the component because the div is related to the component size.
The panel
mode open the component in a Panel. The panel height is 100% of the window.
# Window content
A plugin that is not displayed as a button is displayed on the window content. The viewer 3D and the viewer 2D are plugins displayed this way.
Example: this is the file content (simplified) used to register the viewer 3D:
import Viewer3D from "./Viewer3D.vue";
export default {
name: "viewer3d",
component: Viewer3D,
window: {
name: "3d",
},
};
There is no button configuration in this file. The viewer 3D is registered as "viewer3d" and a window named "3d" is created with the viewer 3d plugin as a child.
# mount
Once created, the BIMDataViewer must be mounted to a DOM (opens new window) element in order to be displayed to the user.
bimdataViewer.mount("#app"); // 'app' is the id of an existing element.
The mount method take an optional second argument: the layout
. The layout
is the configuration of the windows displayed at startup. The default value is "3d", which is the name of a window registered by default. The "3d" window includes many BIMData plugins like "viewer3d", "section", "projection", "structure-properties"...
# Layout
The layout object can be either a string
or an object
.
- If
string
, it must be the name of a registered window. - If
object
, thelayout
is a recursive object representing a container of window names. A container have ratios that represent the amount of space taken by given windows, a direction that can be "column" or "row"(default) and an array of children. A child can be a window name asstring
or another container asobject
.
Examples :
# A simple window name
bimdataViewer.mount("#app", "3d");

# A container with two windows
bimdataViewer.mount("#app", {
ratios: [40, 60],
direction: "row",
children: ["structure", "2d"],
});

# Nested containers
bimdataViewer.mount("#app", {
ratios: [55, 45],
direction: "column",
children: [
{
ratios: [50, 50],
children: ["structure", "2d"],
},
"3d",
],
});

# Embed Design System
The BIMData design system (opens new window) is globally available on the viewer and can be use to quickly stylize the components:
const component = {
template: `
<div style="display: flex; justify-content: center; align-items: center; height: 100%; flex-direction: column;">
<p>Plugin Window component content.</p>
<BIMDataButton color="primary" fill radius @click="onClick">Click Me !</BimdataButton>
</div>
`,
methods: {
onClick() {
console.log("button clicked !");
},
},
};
In this example, there is no need to import BIMDataButton
(opens new window).
# Complete UI example
<body>
<div id="app"></div>
<script type="module">
import makeBIMDataViewer from "@bimdata/viewer";
const bimdataViewer = makeBIMDataViewer({
api: {
modelIds: [15097],
cloudId: 10344,
projectId: 237466,
accessToken: "TAbdyPzoQeYgVSMe4GUKoCEfYctVhcwJ", // Demo token
},
});
bimdataViewer.registerPlugin({
name: "buttonPlugin",
component: {
render(h) {
return h("div", "Plugin Button component content.");
},
},
button: {
position: "left",
content: "panel",
},
});
bimdataViewer.registerPlugin({
name: "windowPlugin",
component: {
template: `
<div style="display: flex; justify-content: center; align-items: center; height: 100%; flex-direction: column;">
<p>Plugin Window component content.</p>
<BIMDataButton color="primary" fill radius @click="onClick">Click Me !</BimdataButton>
</div>
`,
methods: {
onClick() {
console.log("button clicked !");
},
},
},
window: {
name: "window-1",
plugins: ["buttonPlugin"],
},
});
bimdataViewer.registerWindow({
name: "window-2",
plugins: ["buttonPlugin"],
});
bimdataViewer.mount("#app", {
ratios: [30, 70],
children: [
"window-1",
{
ratios: [40, 60],
direction: "column",
children: ["window-2", "3d"],
},
],
});
</script>
</body>
