HTML Drawing Control

Add markers to a drawing

Overview

Use marker control to:

  • Place, move, and edit symbols on drawings.
  • Connect new symbols to Archibus database records, in order to create asset symbols.
  • Report back given x-y positions in the drawing. The add-in manager saves these positions to fields of the database, to redisplay the markers. Add-in managers also use position information to synchronize new items and new locations back to the CAD drawing, if the managers use CAD drawings as the system of record for these specific elements.

Marker control does not inherit from HTML drawing control. Rather, HTML drawing control incorporates marker control as an add-on.

marker.png

Signature of a marker symbol

The HTML syntax for a marker symbol resembles:

marker_syntax.png

where the symbol definition for the wrench is:

marker_syntax_wrench.png

The image of the symbol is a base64 string, centered to the x, y position of its parent <g> node. The splotch enables styling and click-touch events. The label for the symbol also resides on the same layer to facilitate dynamic scaling as users zoom in and out of the drawing during clustering (see Cluster Control ).

wrench_symbol.png

To minimize the footprint of the drawing, the images are <use> elements, similar to published assets. The base64 images themselves reside in the <def> section as unique entries. Uniqueness is defined by the image, width, and height. Consolidation is performed client-side, as each marker is added to the drawing via addMarker() .

Difference from published symbols

Similar to markers, symbols generated from publishing will typically contain a <use> element, with a reference to a definition in another section of the drawing. However, the symbol information is stored in the drawing. If you needed to update the position or change the image, you would need to do so in the CAD drawing and then republish.

Marker symbols used by the Marker control reside in the database, in a table that you choose, with an image that you choose. Each symbol corresponds to its own record. For a particular layer, you should either use published symbols or marker symbols, but not both. If you do use both, only the marker symbols will be able to move and be editable on the fly.

Format for marker symbols

It's best to use .svg format for a marker symbol.

To convert an image to a marker (data-uri/base64 string), you can use utilities such as:

http://localhost:8080/archibus/schema/ab-products/solutions/programming/svg/marker/ab-ex-svg-dwg-marker-generator.axvw

Storing marker symbols

The Web Central Solutions Template example uses the afm_redlines table to store each marker. The following fields in afm_redlines store marker information:

  • Rotation - afm_redlines.rotation
  • Layer - afm_redlines.layer_name
  • Redline type - afm_redlines.redline_type
  • Position Right Lower X, Position Right Lower Y, Position Left Lower X, Position Left Upper Y
  • Auto-numbered ID
  • Drawing Name
  • Redline Elements

Note that the Marker control does not using the position fields to store the diagonals. Rather, the Marker control uses the position fields to store the x, y, width, and height of the marker.

The Marker control allows you to save symbol information to other database tables, but you will need a similar set of fields to store this information. You may even use a standards or validating table to store unique instances of the symbols, and then reference those symbols.

View Definition

Include the necessary libraries and files for the marker control. In WebCentral, you can simply include one file (ab-common-controls-marker.axvw), which will in turn, include all control resources specific to the marker control. In addition, you will need to include the drawing control files.

<panel type="view" id="markerFiles" file="ab-common-controls-marker.axvw"/>

Add an HTML panel with a <div> to hold the drawing:

<!-- drawing panel -->
<panel type="html" id="drawingPanel" dataSource="none" region="center">
<title></title>
<html>
<div id="drawingDiv"></div>
</html>
</panel>

The legend panel is created entirely by application code. (Could be a popup, for example.) After selecting a symbol in the legend, call the placeMarker() api to place the symbol on the drawing.

JavaScript Runtime API

Initialization and access

Similar to other drawing control add-ons, you use the drawing control's addOnsConfig object to enable the marker control:

// enable the marker and cluster add-ons
parameters['addOnsConfig'] = {
'Marker': {'divId': 'drawingDiv'}
};

// load drawing
this.drawingControl = new Ab.svg.DrawingControl("drawingDiv", "drawingPanel", parameters);

To access the marker add-on, use the drawing control's getAddOn() API:

this.markerControl = this.drawingControl.getAddOn('Marker');

Enable or disable markers

Under certain conditions, in Web Central or in the Mobile app, you want the ability to enable or disable drawing markers. To do so, marker control contains the following API:

this.markerControl.enable(enabled);

where (enabled) is true or false.

In the marker add-on config object, ensure you specify the layer name for markers:

parameters['addOnsConfig'] = { Marker: { divId: 'drawingDiv', layerName : this.layerName }, … }

Placing a marker

After selecting a marker from the marker legend, call this API, which performs the following sequence of events:

  1. On desktop browsers, change the mouse cursor to a cross.
  2. Turn on the sensor for the floorplan to capture the next click or tap.
  3. When the user clicks or taps on a location in the floorplan, determine the position.
  4. Call addMarker() to insert the selected symbol onto the drawing.
  5. Turn off the sensor, change the mouse cursor back, and return to regular mode.
  6. Issue callback handler.

For example:

markerControl.placeMarker(svg, parameters);

where:

  • svg is the targeted svg floorplan
  • parameters is the marker object. (See the" Marker Object Properties" section at the end of this topic.)

Adding a marker

Creates and inserts a marker symbol onto floorplan, attaching any event handlers and labels.

For example:

var image = markerControl.addMarker(parameters);

where:

  • parameters is the marker object. (See the" Marker Object Properties" section at the end of this topic.)
  • returns <image> element

Adding or setting a label to a marker

addMarker() automatically calls this method, so ordinarily, you should not need to use this API.

For example:

setLabel(parameters);

where parameters is the marker object. (See the" Marker Object Properties" section at the end of this topic.)

Moving a marker

addMarker() automatically calls this method, so ordinarily, you should not need to use this API.

Example:

move(parameters);

where parameters is the marker object. (See the" Marker Object Properties" section at the end of this topic.)

Removing a marker

removeMarker() deletes a marker and its label from the floor plan. This method removes the markers from the floor plan. It does not make changes to the database.

Example:

removeMarker(id);

where id is the id of the marker to be deleted.

To remove all markers from a given layer on the floor plan, use:

markerControl.removeMarkers(layerName);

where layerName is the name of the maker layer (such as eq-assets ). This method removes the markers from the floor plan. It does not make changes to the database. This is handy because it is often faster than fetching and reloading the drawing.

On cancel, fly marker back to original position

After moving a symbol, you can specify a callback function. In this callback function, the application level has full control over what to do once the user has finished moving a symbol from one position to another. For example, you might choose to save the new position right away or to first seek confirmation. If the user chooses to seek confirmation and chooses Cancel, allow the symbol to fly back to original position.

Example:

returnToOriginalPosition(node, toX, toY, toRotation)

where:

  • node is marker to be removed
  • toX is the x position to return to
  • toY is the y position to return to
  • toRotation is the angle of rotation to return to

Locating markers

Use the Drawing Control’s findAsset() method to locate markers. Note that the marker structure will be different, but you just need adjust the .css styling accordingly. For example, traditionally, the default css class for highlighting a room is:

// to highlight a room
.zoomed-asset-default {
fill: yellow;
opacity: 0.8;
stroke: #000000;
}

Because markers can be read-only images, to highlight a marker, you need to apply the style to the . splotch instead, such as:

// to highlight a marker
.zoomed-asset-default .splotch{
stroke: blue;
stroke-dasharray: 5, 2, 5, 1;
stroke-width: 5px;
}

You can keep both in the .css file. But when you pass in the parameter in findAssets , use zoomed-asset-default .

Patching published symbols

Patch any <use> elements in the floor plan for the specified layer. Mainly used for searching a symbol. Storing the published symbols is not supported.

Example:

patchAssets('eq-assets');

where:

- name of the layer table is eq-assets

Marker object properties

Property Example Comments
icon ‘data:image/svg+xml;base64,PD94bWwgdmVyc2…’ The 64-base string that holds the marker symbol
layer ‘eq-assets’ Name of drawing layer that the symbol should reside in
width 30 Width of the marker symbol
height 30 Height of the marker symbol
scope Self Scope
handler self.afterInsert Callback for when the marker is placed
clickHandler Self.onClick Called when a marker symbol is clicked
moveEndHandler Self.onMoveEnd Called after moving a marker symbol
beforeDeleteHandler Self.onBeforeDeleteHandler Called after clicking the trashcan/”Delete” icon (see note below)
deleteHandler Self.onDelete Called after beforeDeleteHandler*

Note on Delete icon

Typically, for event handlers, the core control attaches a listener to a method passed in by the application code. The application code then takes on full responsibility of what happens next. Here, the ‘Delete’ action contains some reusable components, some parts that are handled by application code, and some parts that are handled by core code.

The following sequence outlines the workflow of the ‘Delete’ icon and the relationship between beforeDeleteHandler vs. deleteHandler :

  1. Optional. When the user clicks the "Delete" icon, application code may want the ability to do something beforehand (such as check whether or not the symbol can be deleted). If so, application code can use beforeDeleteHandler() to specify a function.
  2. Optional.
    • If the beforeDeleteHandler() function indicates that symbol should not be deleted, return. Core code does nothing else. Application code will provide feedback to user.
    • If beforeDeleteHandler() indicates that symbol can be deleted, proceed with Item #3.
  3. Show confirmation, asking if user want to proceed with delete, which has Yes or No option.
    • If Yes, perform actual delete:
      • Application code uses delete() handler to do something, such as attempt to delete item from the database via a workflow rule.
      • Delete() handler returns a boolean to indicate success or failure.
      • Based on this boolean, core code decides whether or not to delete a symbol and its label from DOM.
    • If No, core code does nothing. Symbol remains on screen.

To summarize, basically, use beforeDeleteHandler if you need to do something before bringing up the delete confirmation and subsequent deleteHandler function. In the beforeDeleteHandler function:

  • return true if you want to indicate that the symbol can be deleted and want to proceed with the deleteHandler .
  • return false if you want to indicate the symbol should not be deleted.