diff options
Diffstat (limited to 'documentation/4.0/api/lib/diagrams.js')
-rw-r--r-- | documentation/4.0/api/lib/diagrams.js | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/documentation/4.0/api/lib/diagrams.js b/documentation/4.0/api/lib/diagrams.js new file mode 100644 index 0000000..b137327 --- /dev/null +++ b/documentation/4.0/api/lib/diagrams.js @@ -0,0 +1,240 @@ +/** + * JavaScript functions enhancing the SVG diagrams. + * + * @author Damien Obrist + */ + +var diagrams = {}; + +/** + * Initializes the diagrams in the main window. + */ +$(document).ready(function() +{ + // hide diagrams in browsers not supporting SVG + if(Modernizr && !Modernizr.inlinesvg) + return; + + if($("#content-diagram").length) + $("#inheritance-diagram").css("padding-bottom", "20px"); + + $(".diagram-container").css("display", "block"); + + $(".diagram").each(function() { + // store initial dimensions + $(this).data("width", $("svg", $(this)).width()); + $(this).data("height", $("svg", $(this)).height()); + // store unscaled clone of SVG element + $(this).data("svg", $(this).get(0).childNodes[0].cloneNode(true)); + }); + + // make diagram visible, hide container + $(".diagram").css("display", "none"); + $(".diagram svg").css({ + "position": "static", + "visibility": "visible", + "z-index": "auto" + }); + + // enable linking to diagrams + if($(location).attr("hash") == "#inheritance-diagram") { + diagrams.toggle($("#inheritance-diagram-container"), true); + } else if($(location).attr("hash") == "#content-diagram") { + diagrams.toggle($("#content-diagram-container"), true); + } + + $(".diagram-link").click(function() { + diagrams.toggle($(this).parent()); + }); + + // register resize function + $(window).resize(diagrams.resize); + + // don't bubble event to parent div + // when clicking on a node of a resized + // diagram + $("svg a").click(function(e) { + e.stopPropagation(); + }); + + diagrams.initHighlighting(); + + $("button#diagram-fs").click(function() { + $(".diagram-container").toggleClass("full-screen"); + $(".diagram-container > div.diagram").css({ + height: $("svg").height() + "pt" + }); + + $panzoom.panzoom("reset", { animate: false, contain: false }); + }); +}); + +/** + * Initializes highlighting for nodes and edges. + */ +diagrams.initHighlighting = function() +{ + // helper function since $.hover doesn't work in IE + + function hover(elements, fn) + { + elements.mouseover(fn); + elements.mouseout(fn); + } + + // inheritance edges + + hover($("svg .edge.inheritance"), function(evt){ + var toggleClass = evt.type == "mouseout" ? diagrams.removeClass : diagrams.addClass; + var parts = $(this).attr("id").split("_"); + toggleClass($("#" + parts[0] + "_" + parts[1])); + toggleClass($("#" + parts[0] + "_" + parts[2])); + toggleClass($(this)); + }); + + // nodes + + hover($("svg .node"), function(evt){ + var toggleClass = evt.type == "mouseout" ? diagrams.removeClass : diagrams.addClass; + toggleClass($(this)); + var parts = $(this).attr("id").split("_"); + var index = parts[1]; + $("svg#" + parts[0] + " .edge.inheritance").each(function(){ + var parts2 = $(this).attr("id").split("_"); + if(parts2[1] == index) + { + toggleClass($("#" + parts2[0] + "_" + parts2[2])); + toggleClass($(this)); + } else if(parts2[2] == index) + { + toggleClass($("#" + parts2[0] + "_" + parts2[1])); + toggleClass($(this)); + } + }); + }); + + // incoming implicits + + hover($("svg .node.implicit-incoming"), function(evt){ + var toggleClass = evt.type == "mouseout" ? diagrams.removeClass : diagrams.addClass; + toggleClass($(this)); + toggleClass($("svg .edge.implicit-incoming")); + toggleClass($("svg .node.this")); + }); + + hover($("svg .edge.implicit-incoming"), function(evt){ + var toggleClass = evt.type == "mouseout" ? diagrams.removeClass : diagrams.addClass; + toggleClass($(this)); + toggleClass($("svg .node.this")); + $("svg .node.implicit-incoming").each(function(){ + toggleClass($(this)); + }); + }); + + // implicit outgoing nodes + + hover($("svg .node.implicit-outgoing"), function(evt){ + var toggleClass = evt.type == "mouseout" ? diagrams.removeClass : diagrams.addClass; + toggleClass($(this)); + toggleClass($("svg .edge.implicit-outgoing")); + toggleClass($("svg .node.this")); + }); + + hover($("svg .edge.implicit-outgoing"), function(evt){ + var toggleClass = evt.type == "mouseout" ? diagrams.removeClass : diagrams.addClass; + toggleClass($(this)); + toggleClass($("svg .node.this")); + $("svg .node.implicit-outgoing").each(function(){ + toggleClass($(this)); + }); + }); +}; + +/** + * Resizes the diagrams according to the available width. + */ +diagrams.resize = function() { + // available width + var availableWidth = $(".diagram-container").width(); + + $(".diagram-container").each(function() { + // unregister click event on whole div + $(".diagram", this).unbind("click"); + var diagramWidth = $(".diagram", this).data("width"); + var diagramHeight = $(".diagram", this).data("height"); + + if (diagramWidth > availableWidth) { + // resize diagram + var height = diagramHeight / diagramWidth * availableWidth; + $(".diagram svg", this).width(availableWidth); + $(".diagram svg", this).height(height); + } else { + // restore full size of diagram + $(".diagram svg", this).width(diagramWidth); + $(".diagram svg", this).height(diagramHeight); + // don't show custom cursor any more + $(".diagram", this).removeClass("magnifying"); + } + }); +}; + +/** + * Shows or hides a diagram depending on its current state. + */ +diagrams.toggle = function(container, dontAnimate) +{ + // change class of link + $(".diagram-link", container).toggleClass("open"); + // get element to show / hide + var div = $(".diagram", container); + if (div.is(':visible')) { + $(".diagram-help", container).hide(); + div.unbind("click"); + div.slideUp(100); + + $("#diagram-controls", container).hide(); + $("#inheritance-diagram-container").unbind('mousewheel.focal'); + } else { + diagrams.resize(); + if(dontAnimate) + div.show(); + else + div.slideDown(100); + $(".diagram-help", container).show(); + + $("#diagram-controls", container).show(); + + $(".diagram-container").on('mousewheel.focal', function(e) { + e.preventDefault(); + var delta = e.delta || e.originalEvent.wheelDelta; + var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0; + $panzoom.panzoom('zoom', zoomOut, { + increment: 0.1, + animate: true, + focal: e + }); + }); + } +}; + +/** + * Helper method that adds a class to a SVG element. + */ +diagrams.addClass = function(svgElem, newClass) { + newClass = newClass || "over"; + var classes = svgElem.attr("class"); + if ($.inArray(newClass, classes.split(/\s+/)) == -1) { + classes += (classes ? ' ' : '') + newClass; + svgElem.attr("class", classes); + } +}; + +/** + * Helper method that removes a class from a SVG element. + */ +diagrams.removeClass = function(svgElem, oldClass) { + oldClass = oldClass || "over"; + var classes = svgElem.attr("class"); + classes = $.grep(classes.split(/\s+/), function(n, i) { return n != oldClass; }).join(' '); + svgElem.attr("class", classes); +}; |