App-Netdisco
view release on metacpan or search on metacpan
share/public/javascripts/d3-force-network-chart.js view on Meta::CPAN
if (v.confDefaults[this.name].type === "text") {
graph[this.name](this.options[this.selectedIndex].value).render();
} else if (v.confDefaults[this.name].type === "number") {
graph[this.name](parseFloat(this.options[this.selectedIndex].value)).render();
} else if (v.confDefaults[this.name].type === "bool") {
graph[this.name]((this.options[this.selectedIndex].value === "true")).render();
}
};
var appendOptionsToSelect = function(key) {
v.confDefaults[key].options.forEach(function(option) {
currentOption = option;
form.append("option")
.attr("value", option)
.attr("selected", function() {
if (v.confDefaults[key].type === "text" || v.confDefaults[key].type === "bool") {
if (currentOption === v.conf[key]) {
valueInOptions = true;
return "selected";
} else {
return null;
}
} else if (v.confDefaults[key].type === "number") {
if (parseFloat(currentOption) === v.conf[key]) {
valueInOptions = true;
return "selected";
} else {
return null;
}
}
})
.text(option);
});
};
// render customization wizard only if we have the right status, otherwise remove the wizard
if (!v.status.customize) {
v.tools.removeCustomizeWizard();
v.tools.createCustomizeLink();
} else {
v.tools.removeCustomizeLink();
// set initial position
if (!v.dom.customizePosition) {
v.dom.customizePosition = v.tools.getOffsetRect(v.dom.svg.node());
v.dom.customizePosition.left = v.dom.customizePosition.left + v.conf.width + 8;
}
if (document.querySelector("#" + v.dom.containerId + "_customizing") !== null) {
v.dom.customize.remove();
}
v.dom.customize = v.dom.body.insert("div")
.attr("id", v.dom.containerId + "_customizing")
.attr("class", "net_gobrechts_d3_force_customize")
.style("left", v.dom.customizePosition.left + "px")
.style("top", v.dom.customizePosition.top + "px");
v.dom.customize.append("span")
.attr("class", "drag")
.call(v.tools.customizeDrag)
.append("span")
.attr("class", "title")
.text("Customize \"" + v.dom.containerId + "\"");
v.dom.customize.append("a")
.attr("class", "close focus")
.attr("tabindex", 1)
.text("Close")
.on("click", function() {
v.status.customize = false;
v.tools.removeCustomizeWizard();
v.tools.createCustomizeLink();
})
.on("keydown", function() {
if (d3.event.keyCode === 13) {
v.status.customize = false;
v.tools.removeCustomizeWizard();
v.tools.createCustomizeLink();
}
});
grid = v.dom.customize.append("table");
gridRow = grid.append("tr");
gridCell = gridRow.append("td").style("vertical-align", "top");
v.dom.customizeMenu = gridCell.append("span");
v.dom.customizeOptionsTable = gridCell.append("table");
for (key in v.confDefaults) {
if (v.confDefaults.hasOwnProperty(key) && v.confDefaults[key].display) {
i += 1;
row = v.dom.customizeOptionsTable.append("tr")
.attr("class", v.confDefaults[key].relation + "-related");
row.append("td")
.attr("class", "label")
.html("<a href=\"https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#." +
key + "\" target=\"github_d3_force\" tabindex=\"" + i + 100 + "\">" +
key + "</a>");
td = row.append("td");
form = td.append("select")
.attr("id", v.dom.containerId + "_" + key)
.attr("name", key)
.attr("value", v.conf[key])
.attr("tabindex", i + 1)
.classed("warning", v.confDefaults[key].internal)
.on("change", onSelectChange);
valueInOptions = false;
appendOptionsToSelect(key);
// append current value if not existing in default options
if (!valueInOptions) {
form.append("option")
.attr("value", v.conf[key])
.attr("selected", "selected")
.text(v.conf[key]);
v.confDefaults[key].options.push(v.conf[key]);
}
// add short link to release all fixed (pinned) nodes
if (key === "pinMode") {
td.append("a")
.text(" release all")
.attr("href", null)
.on("click", releaseFixedNodesAndResume);
}
}
}
v.dom.customizeOptionsTable.style("width", d3.select(v.dom.customizeOptionsTable).node()[0][0].clientWidth +
"px");
gridCell.append("span").html("<br>");
gridCell = gridRow.append("td")
.style("vertical-align", "top")
.style("padding-left", "5px");
gridCell.append("span")
.html("Your Configuration Object<p style=\"font-size:10px;margin:0;\">" +
(v.status.apexPluginId ?
"To save your options please copy<br>this to your plugin region attributes.<br>" +
"Only non-default options are shown.</p>" :
"Use this to initialize your graph.<br>Only non-default options are shown.</p>")
);
v.dom.customizeConfObject = gridCell.append("textarea")
.attr("tabindex", i + 5)
.attr("readonly", "readonly");
gridCell.append("span").html("<br><br>Current Positions<br>");
v.dom.customizePositions = gridCell.append("textarea")
.attr("tabindex", i + 6)
.attr("readonly", "readonly")
.text((v.status.forceRunning ? "Force started - wait for end event to show positions..." :
JSON.stringify(graph.positions())));
gridCell.append("span").html("<br><br>Debug Log (descending)<br>");
v.dom.customizeLog = gridCell.append("textarea")
.attr("tabindex", i + 7)
.attr("readonly", "readonly");
gridRow = grid.append("tr");
gridCell = gridRow.append("td")
.attr("colspan", 2)
.html("Copyrights:");
gridRow = grid.append("tr");
gridCell = gridRow.append("td")
.attr("colspan", 2)
.html("<table><tr><td style=\"padding-right:20px;\">" +
"<a href=\"https://github.com/ogobrecht/d3-force-apex-plugin\" target=\"_blank\" " +
"tabindex=\"" + (i + 8) + "\">D3 Force APEX Plugin</a> (" + v.version +
")<br>Ottmar Gobrecht</td><td style=\"padding-right:20px;\">" +
"<a href=\"https://github.com/mbostock/d3\" target=\"d3js_org\" tabindex=\"" + (i + 9) +
"\">D3.js</a> (" + d3.version + ") and " +
"<a href=\"https://github.com/d3/d3-plugins/tree/master/lasso\" target=\"_blank\" tabindex=\"" +
(i + 10) + "\">D3 Lasso Plugin</a> (modified)<br>Mike Bostock" +
"</td></tr><tr><td colspan=\"3\">" +
"<a href=\"https://github.com/tinker10/D3-Labeler\" target=\"github_d3_labeler\" " +
"tabindex=\"" + (i + 11) +
"\">D3 Labeler Plugin</a> (automatic label placement using simulated annealing)" +
"<br>Evan Wang</td></tr></table>"); // https://github.com/tinker10/D3-Labeler
v.tools.createCustomizeMenu(v.status.customizeCurrentMenu);
v.tools.writeConfObjectIntoWizard();
if (v.status.customizeCurrentTabPosition) {
document.getElementById(v.status.customizeCurrentTabPosition).focus();
}
}
};
v.tools.removeCustomizeWizard = function() {
d3.select("#" + v.dom.containerId + "_customizing").remove();
};
v.tools.createCustomizeMenu = function(relation) {
v.status.customizeCurrentMenu = relation;
v.dom.customizeMenu.selectAll("*").remove();
v.dom.customizeMenu.append("span").text("Show options for:");
if (v.status.customizeCurrentMenu === "nodes") {
v.dom.customizeMenu.append("span").style("font-weight", "bold").style("margin-left", "10px").text("NODES");
v.dom.customizeOptionsTable.selectAll("tr.node-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.label-related,tr.link-related,tr.graph-related")
.classed("hidden", true);
} else {
v.dom.customizeMenu.append("a")
.style("font-weight", "bold")
.style("margin-left", "10px")
.text("NODES")
.attr("tabindex", 2)
.on("click", function() {
v.tools.createCustomizeMenu("nodes");
v.dom.customizeOptionsTable.selectAll("tr.node-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.label-related,tr.link-related,tr.graph-related")
.classed("hidden", true);
})
.on("keydown", function() {
if (d3.event.keyCode === 13) {
v.tools.createCustomizeMenu("nodes");
v.dom.customizeOptionsTable.selectAll("tr.node-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.label-related,tr.link-related,tr.graph-related")
.classed("hidden", true);
}
});
}
if (v.status.customizeCurrentMenu === "labels") {
v.dom.customizeMenu.append("span").style("font-weight", "bold").style("margin-left", "10px").text("LABELS");
v.dom.customizeOptionsTable.selectAll("tr.label-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.link-related,tr.graph-related")
.classed("hidden", true);
} else {
v.dom.customizeMenu.append("a")
.style("font-weight", "bold")
.style("margin-left", "10px")
.text("LABELS")
.attr("tabindex", 2)
.on("click", function() {
v.tools.createCustomizeMenu("labels");
v.dom.customizeOptionsTable.selectAll("tr.label-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.link-related,tr.graph-related")
.classed("hidden", true);
})
.on("keydown", function() {
if (d3.event.keyCode === 13) {
v.tools.createCustomizeMenu("labels");
v.dom.customizeOptionsTable.selectAll("tr.label-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.link-related,tr.graph-related")
.classed("hidden", true);
}
});
}
if (v.status.customizeCurrentMenu === "links") {
v.dom.customizeMenu.append("span").style("font-weight", "bold").style("margin-left", "10px").text("LINKS");
v.dom.customizeOptionsTable.selectAll("tr.link-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.label-related,tr.graph-related")
.classed("hidden", true);
} else {
v.dom.customizeMenu.append("a")
.style("font-weight", "bold")
.style("margin-left", "10px")
.text("LINKS")
.attr("tabindex", 3)
.on("click", function() {
v.tools.createCustomizeMenu("links");
v.dom.customizeOptionsTable.selectAll("tr.link-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.label-related,tr.graph-related")
.classed("hidden", true);
})
.on("keydown", function() {
if (d3.event.keyCode === 13) {
v.tools.createCustomizeMenu("links");
v.dom.customizeOptionsTable.selectAll("tr.link-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.label-related,tr.graph-related")
.classed("hidden", true);
}
});
}
if (v.status.customizeCurrentMenu === "graph") {
v.dom.customizeMenu.append("span").style("font-weight", "bold").style("margin-left", "10px").text("GRAPH");
v.dom.customizeOptionsTable.selectAll("tr.graph-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.label-related,tr.link-related")
.classed("hidden", true);
} else {
v.dom.customizeMenu.append("a")
.style("font-weight", "bold")
.style("margin-left", "10px")
.text("GRAPH")
.attr("tabindex", 4)
.on("click", function() {
v.tools.createCustomizeMenu("graph");
v.dom.customizeOptionsTable.selectAll("tr.graph-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.label-related,tr.link-related")
.classed("hidden", true);
})
.on("keydown", function() {
if (d3.event.keyCode === 13) {
v.tools.createCustomizeMenu("graph");
v.dom.customizeOptionsTable.selectAll("tr.graph-related").classed("hidden", false);
v.dom.customizeOptionsTable.selectAll("tr.node-related,tr.label-related,tr.link-related")
.classed("hidden", true);
}
});
}
v.dom.customizeMenu.append("span").html("<br><br>");
};
// helper function to wrap text - https://bl.ocks.org/mbostock/7555321
v.tools.wrapLabels = function(labels, width) {
labels.each(function(label, i) {
var text = d3.select(this);
if (i === 0) {
v.status.labelFontSize = parseInt(text.style("font-size"));
}
if (!this.hasAttribute("lines")) {
var words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = v.status.labelFontSize * v.conf.wrappedLabelLineHeight,
x = text.attr("x"),
y = text.attr("y"),
dy = 0,
tspan = text.text(null).append("tspan").attr("x", x).attr("y", y).attr("dy", dy + "px");
while (word = words.pop()) { // jshint ignore:line
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight +
dy + "px").text(word);
}
}
//save number of lines
text.attr("lines", lineNumber + 1);
}
});
};
/*******************************************************************************************************************
* LIBRARIES
*/
// D3 labeler plugin
/* Source Code: https://github.com/tinker10/D3-Labeler
The MIT License (MIT)
share/public/javascripts/d3-force-network-chart.js view on Meta::CPAN
*
* example.debug(true);
* @see {@link module:API.customize}
* @param {boolean} [value] - The new mode.
* @returns {(boolean|Object)} The current mode if no parameter is given or the graph object for method chaining.
*/
graph.debug = function(value) {
if (!arguments.length) {
return v.conf.debug;
}
v.conf.debug = value;
if (v.status.graphStarted) {
if (v.conf.debug) {
v.tools.createCustomizeLink();
} else {
v.tools.removeCustomizeLink();
}
}
return graph;
};
/**
* Returns the detected user agent. Expects no parameter and terminates the method chain:
*
* example.userAgent();
* @see {@link module:API.inspect}
* @returns {string} The detected user agent.
*/
graph.userAgent = function() {
return v.status.userAgent;
};
/**
* Shows the current closure object, which holds all functions and data. This method expects no parameter and terminates the method chain:
*
* example.inspect();
* @see {@link module:API.userAgent}
* @returns {Object} The graph's internal object with all functions and data.
*/
graph.inspect = function() {
return v;
};
/**
* Shows the current plugin version. This method expects no parameter and terminates the method chain:
*
* example.version();
* @see {@link module:API.userAgent}
* @returns {string} The plugin version.
*/
graph.version = function() {
return v.version;
};
/*******************************************************************************************************************
* Startup code - runs one time after the initialization of a new chart - example:
* var myChart = net_gobrechts_d3_force( domContainerId, pConf, apexPluginId ).start();
*/
if (v.status.apexPluginId) {
// bind to the apexrefresh event, so that this region can be refreshed by a dynamic action
apex.jQuery("#" + v.dom.containerId).bind("apexrefresh", function() {
graph.start();
});
//rerender on window resize
apex.jQuery(window).on("apexwindowresized", function() {
graph.render();
});
apex.jQuery("#t_Button_navControl").click(function() {
setTimeout(function() {
graph.render();
}, 500);
});
}
// final return
return graph;
}
( run in 0.517 second using v1.01-cache-2.11-cpan-2398b32b56e )