/**
* Constructs a {@link GraphBuilder} host with the provided number associated
* with the provided graph builder.
*
* @classdesc
*
* GraphBuilderHost represents a host in a {@link GraphBuilder}. This class
* contains methods to access and modify the nodes contained in this host.
*
* @constructor
* @param {GraphBuilder} graphBuilder
* @param {Number} hostNum The host number. The graph builder host with hostNum =
* i should be the ith host in the graphBuilder.
*/
function GraphBuilderHost(graphBuilder, hostNum, motifSearch) {
var host = this;
/** @private */
this.hostNum = hostNum;
/** @private */
this.graphBuilder = graphBuilder;
/** @private */
this.rx = (motifSearch ? hostNum * 40 : hostNum * 65);
/** @private */
this.x = (motifSearch ? this.rx + 10 : this.rx + 12.5);
/** @private */
this.color = graphBuilder.colors.pop();
/** @private */
this.motifSearch = motifSearch;
/** @private */
this.nodes = [];
/** @private */
this.constraint = "";
/** @private */
this.constraintSVG = $(Util.svgElement("text"));
/** @private */
this.rect = Util.svgElement("rect").attr({
"width": 25,
"height": 25,
"fill": this.color,
"x": this.rx,
"y": 0
})
if (!motifSearch) {
graphBuilder.bindHost(this);
this.rect.prependTo(graphBuilder.getSVG());
}
/** @private */
this.line = Util.svgElement("line").attr({
"x1": this.x,
"y1": 30,
"x2": this.x,
"y2": 1000
}).prependTo(graphBuilder.getSVG());
}
/**
* Gets the name of this host that acts as an ID for this host.
*
* @returns {String} the name of this host
*/
GraphBuilderHost.prototype.getName = function() {
var constraint = this.getConstraint();
if (constraint) {
return constraint;
} else {
return String.fromCharCode(97 + this.hostNum);
}
};
/**
* Gets the nodes this host contains as an array.
*
* @returns {Array<GraphBuilderNode>} the nodes as an array
*/
GraphBuilderHost.prototype.getNodes = function() {
return this.nodes.slice();
};
/**
* Gets the nodes this host contains as an array sorted by the nodes' y values
* in ascending order
*
* @returns {Array<GraphBuilderNode>} the nodes as a sorted array
*/
GraphBuilderHost.prototype.getNodesSorted = function() {
return this.getNodes().sort(function(a, b) {
return a.y - b.y;
});
};
/**
* Creates a GraphBuilderNode and adds it to this host.
*
* @param {Number} y The y-coordinate of the node
* @param {Boolean} tmp Whether the created node is temporary (i.e. user
* has not yet completed drawing action)
* @returns {GraphBuilderNode} the newly created and added node
*/
GraphBuilderHost.prototype.addNode = function(y, tmp) {
var node = new GraphBuilderNode(this.graphBuilder, this.x, y, tmp, this.color);
if (this.motifSearch) {
node.setCircleRadius(3);
}
this.nodes.push(node);
this.graphBuilder.invokeUpdateCallback();
// Don't bind any mouse events to motif drawings in the sidebar
if (!this.motifSearch) {
this.graphBuilder.bindNodes();
}
return node;
};
/**
* Removes the provided node from this host
*
* @param {GraphBuilderNode} node the node to remove
*/
GraphBuilderHost.prototype.removeNode = function(node) {
node.getLines().forEach(function(l) {
l.remove();
});
Util.removeFromArray(this.nodes, node);
node.getCircle().remove();
this.graphBuilder.invokeUpdateCallback();
};
/**
* Removes all nodes from this host
*/
GraphBuilderHost.prototype.removeAllNodes = function() {
while (this.nodes.length > 0)
this.removeNode(this.nodes[0]);
this.nodes = [];
};
/**
* Gets this hosts' own color
*
* @returns {String} The color
*/
GraphBuilderHost.prototype.getColor = function() {
return this.color;
};
/**
* Gets the rectangle SVG associated with this graphBuilderHost
*
* @returns {svg.Element} The rectangle svg
*/
GraphBuilderHost.prototype.getHostSquare = function() {
return this.rect;
}
/**
* Gets the rectangle SVG associated with this graphBuilderHost
*
* @returns {svg.Element} The rectangle svg
*/
GraphBuilderHost.prototype.getX = function() {
return this.x;
}
/**
* Updates the host number associated with this graphBuilderHost
*
* @param {Number} hostNum
*/
GraphBuilderHost.prototype.setHostNum = function(hostNum) {
this.hostNum = hostNum;
}
/**
* Gets the host number associated with this graphBuilderHost
*
* @returns {Number}
*/
GraphBuilderHost.prototype.getHostNum = function() {
return this.hostNum;
}
/**
* Sets the constraint associated with this graphBuilderHost
*
* @param {} constraint
*/
GraphBuilderHost.prototype.setConstraint = function(constraint) {
this.constraint = constraint;
var gbh = this;
if (constraint) {
// If the constraint is not empty, add an indicator to the host box
this.constraintSVG.attr({
"font-family": "arial",
"font-size": "15px",
"x": parseFloat(gbh.getHostSquare().attr("x")) + 8,
"y": parseFloat(gbh.getHostSquare().attr("y")) + 18
}).text("C").css("cursor", "default");
gbh.graphBuilder.getSVG().append(this.constraintSVG);
// Clicking on the constraint indicator triggers a click on the host box
this.constraintSVG.on("click", function() {
// Need to pass in gbh here or the value of "this" in handleHostClick will be for $constraintText
gbh.graphBuilder.handleHostClick(gbh);
}).on("dblclick", function() {
gbh.graphBuilder.handleHostDblClick(gbh);
});
// For an empty constraint, remove the indicator
} else {
this.constraintSVG.remove();
}
}
/**
* Gets the constraint associated with this graphBuilderHost
*
* @returns {String}
*/
GraphBuilderHost.prototype.getConstraint = function() {
return this.constraint;
}
/**
* Gets the svg text element for showing a graph builder host has a constraint
*
* @returns {svg.Element} The constraint text svg element
*/
GraphBuilderHost.prototype.getConstraintSVG = function() {
return this.constraintSVG;
}
/**
* Sets the y coordinates for the line segment of this host
*
* @param {Number} y1 The top coordinate for the line
* @param {Number} y2 The bottom coordinate for the line
*/
GraphBuilderHost.prototype.setLineYCoordinates = function(y1, y2) {
this.line.attr("y1", y1);
this.line.attr("y2", y2);
}