UNPKG

visjs-network

Version:

A dynamic, browser-based network visualization library.

240 lines (227 loc) 7.5 kB
// DOM utility methods /** * this prepares the JSON container for allocating SVG elements * @param {Object} JSONcontainer * @private */ exports.prepareElements = function(JSONcontainer) { // cleanup the redundant svgElements; for (var elementType in JSONcontainer) { if (JSONcontainer.hasOwnProperty(elementType)) { JSONcontainer[elementType].redundant = JSONcontainer[elementType].used JSONcontainer[elementType].used = [] } } } /** * this cleans up all the unused SVG elements. By asking for the parentNode, we only need to supply the JSON container from * which to remove the redundant elements. * * @param {Object} JSONcontainer * @private */ exports.cleanupElements = function(JSONcontainer) { // cleanup the redundant svgElements; for (var elementType in JSONcontainer) { if (JSONcontainer.hasOwnProperty(elementType)) { if (JSONcontainer[elementType].redundant) { for (var i = 0; i < JSONcontainer[elementType].redundant.length; i++) { JSONcontainer[elementType].redundant[i].parentNode.removeChild( JSONcontainer[elementType].redundant[i] ) } JSONcontainer[elementType].redundant = [] } } } } /** * Ensures that all elements are removed first up so they can be recreated cleanly * @param {Object} JSONcontainer */ exports.resetElements = function(JSONcontainer) { exports.prepareElements(JSONcontainer) exports.cleanupElements(JSONcontainer) exports.prepareElements(JSONcontainer) } /** * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this. * * @param {string} elementType * @param {Object} JSONcontainer * @param {Object} svgContainer * @returns {Element} * @private */ exports.getSVGElement = function(elementType, JSONcontainer, svgContainer) { var element // allocate SVG element, if it doesnt yet exist, create one. if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before // check if there is an redundant element if (JSONcontainer[elementType].redundant.length > 0) { element = JSONcontainer[elementType].redundant[0] JSONcontainer[elementType].redundant.shift() } else { // create a new element and add it to the SVG element = document.createElementNS( 'http://www.w3.org/2000/svg', elementType ) svgContainer.appendChild(element) } } else { // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it. element = document.createElementNS( 'http://www.w3.org/2000/svg', elementType ) JSONcontainer[elementType] = { used: [], redundant: [] } svgContainer.appendChild(element) } JSONcontainer[elementType].used.push(element) return element } /** * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this. * * @param {string} elementType * @param {Object} JSONcontainer * @param {Element} DOMContainer * @param {Element} insertBefore * @returns {*} */ exports.getDOMElement = function( elementType, JSONcontainer, DOMContainer, insertBefore ) { var element // allocate DOM element, if it doesnt yet exist, create one. if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before // check if there is an redundant element if (JSONcontainer[elementType].redundant.length > 0) { element = JSONcontainer[elementType].redundant[0] JSONcontainer[elementType].redundant.shift() } else { // create a new element and add it to the SVG element = document.createElement(elementType) if (insertBefore !== undefined) { DOMContainer.insertBefore(element, insertBefore) } else { DOMContainer.appendChild(element) } } } else { // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it. element = document.createElement(elementType) JSONcontainer[elementType] = { used: [], redundant: [] } if (insertBefore !== undefined) { DOMContainer.insertBefore(element, insertBefore) } else { DOMContainer.appendChild(element) } } JSONcontainer[elementType].used.push(element) return element } /** * Draw a point object. This is a separate function because it can also be called by the legend. * The reason the JSONcontainer and the target SVG svgContainer have to be supplied is so the legend can use these functions * as well. * * @param {number} x * @param {number} y * @param {Object} groupTemplate: A template containing the necessary information to draw the datapoint e.g., {style: 'circle', size: 5, className: 'className' } * @param {Object} JSONcontainer * @param {Object} svgContainer * @param {Object} labelObj * @returns {vis.PointItem} */ exports.drawPoint = function( x, y, groupTemplate, JSONcontainer, svgContainer, labelObj ) { var point if (groupTemplate.style == 'circle') { point = exports.getSVGElement('circle', JSONcontainer, svgContainer) point.setAttributeNS(null, 'cx', x) point.setAttributeNS(null, 'cy', y) point.setAttributeNS(null, 'r', 0.5 * groupTemplate.size) } else { point = exports.getSVGElement('rect', JSONcontainer, svgContainer) point.setAttributeNS(null, 'x', x - 0.5 * groupTemplate.size) point.setAttributeNS(null, 'y', y - 0.5 * groupTemplate.size) point.setAttributeNS(null, 'width', groupTemplate.size) point.setAttributeNS(null, 'height', groupTemplate.size) } if (groupTemplate.styles !== undefined) { point.setAttributeNS(null, 'style', groupTemplate.styles) } point.setAttributeNS(null, 'class', groupTemplate.className + ' vis-point') //handle label if (labelObj) { var label = exports.getSVGElement('text', JSONcontainer, svgContainer) if (labelObj.xOffset) { x = x + labelObj.xOffset } if (labelObj.yOffset) { y = y + labelObj.yOffset } if (labelObj.content) { label.textContent = labelObj.content } if (labelObj.className) { label.setAttributeNS(null, 'class', labelObj.className + ' vis-label') } label.setAttributeNS(null, 'x', x) label.setAttributeNS(null, 'y', y) } return point } /** * draw a bar SVG element centered on the X coordinate * * @param {number} x * @param {number} y * @param {number} width * @param {number} height * @param {string} className * @param {Object} JSONcontainer * @param {Object} svgContainer * @param {string} style */ exports.drawBar = function( x, y, width, height, className, JSONcontainer, svgContainer, style ) { if (height != 0) { if (height < 0) { height *= -1 y -= height } var rect = exports.getSVGElement('rect', JSONcontainer, svgContainer) rect.setAttributeNS(null, 'x', x - 0.5 * width) rect.setAttributeNS(null, 'y', y) rect.setAttributeNS(null, 'width', width) rect.setAttributeNS(null, 'height', height) rect.setAttributeNS(null, 'class', className) if (style) { rect.setAttributeNS(null, 'style', style) } } }