(function($){ $.fn.geoflow = function(options){ var providername = options.providername; var NPI = options.NPI; var color = d3.scale.category20(); var LEAKAGE_LINES = '#d62728', LOYAL_LINES = '#005C85', COMPETITOR_NODES = '#756bb1', SELECTED_HOSPITAL_NODE = '#2ca02c', LEAKAGE_THRESHOLD = [0, 12.5, 25.0, 37.5, 50.0, 62.5, 75.0, 87.5], LINK_OPACITY = 0.6, NODE_OPACITY = 0.7, MAP_ZOOM = 8, RECENT_LIST_LENGTH = 9, // legend vars SVG_CIRCLE_HEIGHT = 16, SVG_CIRCLE_WIDTH = 20, LEGEND_CX = 8, LEGEND_CY = 8, LEGEND_RADIUS = 8, SVG_LINE_HEIGHT = 5, SVG_LINE_WIDTH = 20, LEGEND_STROKE_WIDTH = 5, LEGEND_X1 = 0, LEGEND_Y1 = 0, LEGEND_X2 = 16, LEGEND_Y2 = 0; var uniq = function(a) { return Array.from(new Set(a)); } var getCheckedInputs = function(opt){ // get all checked NPIs var checked = [] d3.selectAll('.recentInputList')[0].forEach(function(v, k){ if (opt == 'checked'){ if ($(v)[0].checked){ checked.push($(v)[0].id) } } else if (opt == 'all'){ checked.push($(v)[0].id) } }) return checked; }; $('body').append('
' + '
' + '
' + '
Leakage %
" : '') + '' + (LEAKAGE_THRESHOLD[i]+(i==0 ? 0 : 0)) + (LEAKAGE_THRESHOLD[i + 1] ? ' – ' + LEAKAGE_THRESHOLD[i + 1] + 'Highlight Links
' + '' + nodes.features[d.target].name + ' recieves ' + formatNumber(d.flow) + ' visits from ' + nodes.features[d.source].name + '
'; } else { bodyText = '' + nodes.features[d.source].name + ' refers ' + formatNumber(d.flow) + ' visits to ' + nodes.features[d.target].name + '
'; } } else { var firstname = nodes.features[d].name.replace(".", "").split(" ")[0]; var lastname = nodes.features[d].name.replace(".", "").split(" ")[1]; var inputs = getCheckedInputs("all"); if (inputs.indexOf(nodes.features[d].npi) == -1){ $('#recentLegend').prepend('Inflow: ' + formatNumber(nodes.features[d].aggregate_inflows) } else { bodyText = '
Outflow: ' + formatNumber(nodes.features[d].aggregate_outflows) + '
' + 'Total Charges: $' + formatNumber(nodes.features[d].charges) + '
' + 'Leakage: ' + Math.round(nodes.features[d].leakage*10000)/100 + '%' } } d3.select("#tooltip") .style("left", xPosition + "px") .style("top", yPosition + "px"); d3.select("#tooltip #heading") .html(function(){ return headerText; }); d3.select("#tooltip #visits") .html(function(){ return bodyText; }); d3.select("#tooltip").classed("hidden", false); }; var mouseHideTooltip = function() { d3.select("#tooltip").classed("hidden", true); }; var hideSpecificLinks = function(npi){ var checked = getCheckedInputs("checked"); linklayer.selectAll("path").remove(); // Get link data for this node var nodelinks = spatialsankey.links().filter(function(link){ return checked.indexOf(link.target) > -1 || checked.indexOf(link.source) > -1; }); // Add data to link layer var beziers = linklayer.selectAll("path").data(nodelinks); link = spatialsankey.link(options) // Draw new links beziers.enter() .append("path") .attr("d", link) .attr('id', function(d){return npi}) .style("stroke-width", spatialsankey.link().width()) .style("stroke", function(a){ if (!showingAll){ return a.source == NPI || a.target == NPI ? LOYAL_LINES : LEAKAGE_LINES; } }) .on("mousemove", mouseShowTooltip) .on("mouseout", mouseHideTooltip); // Remove old links beziers.exit().remove(); if (showingAll){ beziers.transition().style("stroke", function(link){ return link.source == npi ? LEAKAGE_LINES : LOYAL_LINES && link.target == npi ? LEAKAGE_LINES : LOYAL_LINES; }); }; if (linkType == 'target' || linkType == 'comp'){ hoveredOverHospitalNode = true; } else { hoveredOverHospitalNode = false; } // Hide inactive nodes var circleUnderMouse = this; circs.transition().style('opacity',function (d) { var checked = getCheckedInputs('checked'); return (nodes.features[d].type == "target" || nodes.features[d].type == "comp" || this === circleUnderMouse || checked.indexOf(nodes.features[d].npi) > -1) ? NODE_OPACITY : 0; }); // show all nodes when input has none checked if (checked.length == 0){ circs.call(mouseout); } } var specificLinks = function(npi){ // Hide inactive nodes var circleUnderMouse = this; circs.transition().style('opacity',function (d) { // return (this === circleUnderMouse) ? NODE_OPACITY : 0; var checked = getCheckedInputs('checked'); return (nodes.features[d].type == "target" || nodes.features[d].type == "comp" || this === circleUnderMouse || checked.indexOf(nodes.features[d].npi) > -1) ? NODE_OPACITY : 0; }); }; // hide tooltip when clicking outside circ $('body').on('click', function(e){ var container = $('#tooltip'); if (!container.is(e.target) && e.target.nodeName == 'svg'){ d3.select("#tooltip").classed("hidden", true); } }); // hide tooltip on zoom start map.on('zoomstart', function() { d3.select("#tooltip").classed("hidden", true); }); // hide tooltip on move start map.on('movestart', function(){ d3.select("#tooltip").classed("hidden", true); }); // Draw nodes var node = spatialsankey.node(); var circs = nodelayer.selectAll("circle") .data(Object.keys(nodes.features)) .enter() .append("circle") .attr("cx", node.cx) .attr("cy", node.cy) .attr("r", node.r) .style("fill", function(d){ return node.fill(d, NPI); }) .attr("opacity", NODE_OPACITY) .on('mouseover', mouseover) .on("mouseup", mouseShowTooltip) .on("mouseout", mouseout); // Adopt size of drawn objects after leaflet zoom reset var zoomend = function(){ linklayer.selectAll("path").attr("d", spatialsankey.link()); circs.attr("cx", node.cx) .attr("cy", node.cy); }; map.on("zoomend", zoomend); $('#loading').hide(); }); // end .get data } return this })(jQuery);