UNPKG

@rws-framework/client

Version:

This package provides the core client-side framework for Realtime Web Suit (RWS), enabling modular, asynchronous web components, state management, and integration with backend services. It is located in `.dev/client`.

180 lines (149 loc) 7.1 kB
/** * * MARK: - Rendering concave hulls of clusters. */ function setupGraphClustersById() { clusterMap = {} currentGraph.nodes.forEach(function(node, i) { let nodeClusterId = 0 if (node.hasOwnProperty('metric_file_result_dependency_graph_louvain_modularity_in_file')) { nodeClusterId = node.metric_file_result_dependency_graph_louvain_modularity_in_file } else if (node.hasOwnProperty('metric_entity_result_dependency_graph_louvain_modularity_in_entity')) { nodeClusterId = node.metric_entity_result_dependency_graph_louvain_modularity_in_entity } else if (node.hasOwnProperty('metric_entity_result_inheritance_graph_louvain_modularity_in_entity')) { nodeClusterId = node.metric_entity_result_inheritance_graph_louvain_modularity_in_entity } else if (node.hasOwnProperty('metric_entity_result_complete_graph_louvain_modularity_in_entity')) { nodeClusterId = node.metric_entity_result_complete_graph_louvain_modularity_in_entity } nodeClusterId = nodeClusterId.toString() if (nodeClusterId in clusterMap) { clusterMap[nodeClusterId].push(node) } else { clusterMap[nodeClusterId] = [] clusterMap[nodeClusterId].push(node) } }) // console.log(clusterMap) } function onMouseOverHullMenuNode(clusterId) { if (!selectedClusterHullIds.includes(clusterId)) { addHighlightToSVGCircle(clusterId) } hoveredClusterHullId = clusterId simulationUpdate() } function onMouseOutHullMenuNode(clusterId) { if (!selectedClusterHullIds.includes(clusterId)) { removeHighlightFromSVGCircle(clusterId) } hoveredClusterHullId = undefined simulationUpdate() } function addHighlightToSVGCircle(clusterId) { let hullNodeSVG = $("#clusterHullNodeSVGCircle-" + clusterId) hullNodeSVG.attr('stroke', 'yellow') hullNodeSVG.attr('stroke-width', '2') } function removeHighlightFromSVGCircle(clusterId) { let hullNodeSVG = $("#clusterHullNodeSVGCircle-" + clusterId) hullNodeSVG.attr('stroke', 'black') hullNodeSVG.attr('stroke-width', '1') } function onClickHullMenuNode(clusterId) { if (selectedClusterHullIds.includes(clusterId)) { removeItemAll(selectedClusterHullIds, clusterId) removeHighlightFromSVGCircle(clusterId) } else { selectedClusterHullIds.push(clusterId) addHighlightToSVGCircle(clusterId) } simulationUpdate() } function createClusterHullMenu() { // check if there is at least one cluster if ("0" in clusterMap) { // build menu let clusterMenuHtml = "<div id=\"clusterHullContainer\"> \ <div class=\"row\">" clusterMenuHtml += "<div class=\"svg-column\">" // insert SVG circles let iteration = 0 Object.keys(clusterMap).forEach(function(key) { if (iteration < maxClusterHulls) { let firstNode = clusterMap[key][0] let color = nodeColorByModularity(firstNode) let svgElement = "<svg onmouseover=\"onMouseOverHullMenuNode(" + key + ")\" onmouseout=\"onMouseOutHullMenuNode(" + key + ")\" onclick=\"onClickHullMenuNode(" + key + ")\" height=\"16px\" width=\"16px\" viewBox=\"0 0 18 18\"><circle id=\"clusterHullNodeSVGCircle-" + key + "\" cx=\"5\" cy=\"10\" r=\"4\" \ stroke=\"black\" stroke-width=\"1\" fill=\"" svgElement += color svgElement += "\" /></svg>" clusterMenuHtml += svgElement } iteration += 1 }); // finish menu and append to div clusterMenuHtml += "</div></div></div>" d3.select("#clusterHullMenu").html(clusterMenuHtml) // add tooltips to cluster hull nodes iteration = 0 Object.keys(clusterMap).forEach(function(clusterId) { if (iteration < maxClusterHulls) { let clusterToolTipDescription = "<u>Cluster metrics</u><br>" let clusterMetrics = clusterMetricsMap[clusterId] // TODO: check why clusterMetrics can be undefined if (clusterMetrics !== undefined) { // add all cluster metrics that we can find Object.keys(clusterMetrics).forEach(function(clusterMetric) { let metricPrettyName = clusterMetric.replace(/_/gi, " ").replace(/metric/gi, "") clusterToolTipDescription += metricPrettyName + ": " + "<b>" + clusterMetrics[clusterMetric] + "</b>" + "<br>" }) $('#' + 'clusterHullNodeSVGCircle-' + clusterId).attr('data-bs-toggle', 'tooltip') $('#' + 'clusterHullNodeSVGCircle-' + clusterId).attr('data-bs-title', clusterToolTipDescription) $('#' + 'clusterHullNodeSVGCircle-' + clusterId).attr('data-bs-html', 'true') $('#' + 'clusterHullNodeSVGCircle-' + clusterId).attr('data-bs-placement', 'bottom') } } }) } const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]') const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)) } function getPointArrayForClusterId(id) { let pointArray = [] let clusterId = id.toString() if (clusterId in clusterMap) { clusterMap[clusterId].forEach(function(node, i) { pointArray.push([node.x, node.y]) }) } return pointArray } // calculate hull function getHullFromPointArray(pointArray) { let hullArray = hull(pointArray, 60) return hullArray } // draw a single cluster hull as a polygon function drawHull(context, clusterId) { let pointArray = getPointArrayForClusterId(clusterId) let hullArray = getHullFromPointArray(pointArray) let firstNodeInCluster = clusterMap[clusterId][0] context.fillStyle = nodeColorByModularity(firstNodeInCluster, 0.2) context.beginPath(); let firstPoint = hullArray[0] context.moveTo(firstPoint[0], firstPoint[1]); hullArray.forEach(function(arrayElement, i) { context.lineTo(arrayElement[0], arrayElement[1]); }) context.closePath(); context.fill(); } // draw all required cluster hulls (selected/hovered nodes from the menu) function drawHulls(context) { // draw a hull if someone hovers ofer a hull menu cluster node if (hoveredClusterHullId !== undefined) { drawHull(context, hoveredClusterHullId) } // draw every hull was was selected by a mouse click before selectedClusterHullIds.forEach(clusterId => { drawHull(context, clusterId) }) }