Source: metrics/CustomMetric.js

/**
 * @class CustomMetric is a class to represent custom metrics of the user
 * 
 * @constructor
 * 
 * @param {string} formulaFontSize The formula to calculate the font size of the nodes
 * @param {array} domainFontSize The domain from which to map to the range of font sizes
 * @param {array} rangeFontSize The range of font sizes to map the domain to
 * @param {string} formulaFontColor The formula to calculate the font color of the nodes
 * @param {array} domainFontColor The domain from which to map to the range of font colors
 * @param {array} rangeFontColor The range of font colors to map the domain to
 * @param {string} formulaLinkWidth The formula to calculate the width of the links
 * @param {array} domainLinkWidth The domain from which to map to the range of link widths
 * @param {array} rangeLinkWidth The range of link widths to map the domain to
 */
function CustomMetric(formulaFontSize, domainFontSize, rangeFontSize, formulaFontColor, domainFontColor, rangeFontColor, formulaLinkWidth, domainLinkWidth, rangeLinkWidth)
{
	//define the ranges for the visual link- and node-properties
	this.scaleFontSize = d3.scale.linear().range([ parseFloat(rangeFontSize[0]), parseFloat(rangeFontSize[1]) ]);
	this.scaleFontColor = d3.scale.linear().range([ "#" + rangeFontColor[0], "#" + rangeFontColor[1] ]);
	this.scaleLinkWidth = d3.scale.linear().range([ parseFloat(rangeLinkWidth[0]), parseFloat(rangeLinkWidth[1]) ]);
	
	// save specified domains
	this.domainFontSize = domainFontSize;
	this.domainFontColor = domainFontColor;
	this.domainLinkWidth = domainLinkWidth;

	// parse the given formulas to expressions
	this.exprFontSize = Parser.parse(formulaFontSize);
	this.exprFontColor = Parser.parse(formulaFontColor);
	this.exprLinkWidth = Parser.parse(formulaLinkWidth);
}



/**
 * determines the domains of the ranges for the visual link- and node-properties
 * 
 * @param {array} nodes All nodes of a graph
 * @param {array} links All links of a graph
 */
CustomMetric.prototype.setDomains = function(nodes, links)
{
	var thisInstance = this;

	// get min and max values for node-properties
	var domainFontSize_min = d3.min(nodes, function(node) {
		return d3.min(node.subnodes, function(subnode) {
			return thisInstance.exprFontSize.evaluate({
				inDegree : subnode.inDegree,
				outDegree : subnode.outDegree,
				count : subnode.count
			});
		})
	});
	var domainFontSize_max = d3.max(nodes, function(node) {
		return d3.max(node.subnodes, function(subnode) {
			return thisInstance.exprFontSize.evaluate({
				inDegree : subnode.inDegree,
				outDegree : subnode.outDegree,
				count : subnode.count
			});
		})
	});
	var domainFontColor_min = d3.min(nodes, function(node) {
		return d3.min(node.subnodes, function(subnode) {
			return thisInstance.exprFontColor.evaluate({
				inDegree : subnode.inDegree,
				outDegree : subnode.outDegree,
				count : subnode.count
			});
		})
	});
	var domainFontColor_max = d3.max(nodes, function(node) {
		return d3.max(node.subnodes, function(subnode) {
			return thisInstance.exprFontColor.evaluate({
				inDegree : subnode.inDegree,
				outDegree : subnode.outDegree,
				count : subnode.count
			});
		})
	});

	// get min and max values for link-properties
	var domainLinkWidth_min = d3.min(links, function(link) {
		return thisInstance.exprLinkWidth.evaluate({
			count : link.count
		});
	});
	var domainLinkWidth_max = d3.max(links, function(link) {
		return thisInstance.exprLinkWidth.evaluate({
			count : link.count
		});
	});
	
	
	var domainFontSize_0;
	var domainFontSize_1;
	
	// get first value for the font-size domain
	if (this.domainFontSize[0] == "min")
		domainFontSize_0 = domainFontSize_min;
	else if (this.domainFontSize[0] == "max")
		domainFontSize_0 = domainFontSize_max;
	else
		domainFontSize_0 = parseFloat(this.domainFontSize[0]);
	
	// get second value for the font-size domain
	if (this.domainFontSize[1] == "min")
		domainFontSize_1 = domainFontSize_min;
	else if (this.domainFontSize[1] == "max")
		domainFontSize_1 = domainFontSize_max;
	else
		domainFontSize_1 = parseFloat(this.domainFontSize[1]);
	
	// set font-size domain
	this.scaleFontSize.domain([domainFontSize_0, domainFontSize_1]);
	
	
	var domainFontColor_0;
	var domainFontColor_1;
	
	// get first value for the font-color domain
	if (this.domainFontColor[0] == "min")
		domainFontColor_0 = domainFontColor_min;
	else if (this.domainFontColor[0] == "max")
		domainFontColor_0 = domainFontColor_max;
	else
		domainFontColor_0 = parseFloat(this.domainFontColor[0]);
	
	// get second value for the font-color domain
	if (this.domainFontColor[1] == "min")
		domainFontColor_1 = domainFontColor_min;
	else if (this.domainFontColor[1] == "max")
		domainFontColor_1 = domainFontColor_max;
	else
		domainFontColor_1 = parseFloat(this.domainFontColor[1]);
	
	// set font-color domain
	this.scaleFontColor.domain([domainFontColor_0, domainFontColor_1]);
	
	
	var domainLinkWidth_0;
	var domainLinkWidth_1;
	
	// get first value for the link-width domain
	if (this.domainLinkWidth[0] == "min")
		domainLinkWidth_0 = domainLinkWidth_min;
	else if (this.domainLinkWidth[0] == "max")
		domainLinkWidth_0 = domainLinkWidth_max;
	else
		domainLinkWidth_0 = parseFloat(this.domainLinkWidth[0]);
	
	// get second value for the link-width domain
	if (this.domainLinkWidth[1] == "min")
		domainLinkWidth_1 = domainLinkWidth_min;
	else if (this.domainLinkWidth[1] == "max")
		domainLinkWidth_1 = domainLinkWidth_max;
	else
		domainLinkWidth_1 = parseFloat(this.domainLinkWidth[1]);
	
	// set link-width domain
	this.scaleLinkWidth.domain([domainLinkWidth_0, domainLinkWidth_1]);
}



/**
 * determines the font-size for the given node according to this metric
 * 
 * @param {object} node A single node of a graph
 * 
 * @returns the font-size
 */
CustomMetric.prototype.getFontSize = function(node)
{
	return this.scaleFontSize(this.exprFontSize.evaluate({
		inDegree : node.inDegree,
		outDegree : node.outDegree,
		count : node.count
	}));
}



/**
 * determines the font-color for the given node according to this metric
 * 
 * @param {object} node A single node of a graph
 * 
 * @returns the font-color
 */
CustomMetric.prototype.getFontColor = function(node)
{
	return this.scaleFontColor(this.exprFontColor.evaluate({
		inDegree : node.inDegree,
		outDegree : node.outDegree,
		count : node.count
	}));
}



/**
 * determines the width for the given link according to this metric
 * 
 * @param {object} link A single link of a graph
 * 
 * @returns the link-width
 */
CustomMetric.prototype.getLinkWidth = function(link)
{
	return this.scaleLinkWidth(this.exprLinkWidth.evaluate({
		count : link.count
	}));
}