Created
October 24, 2016 02:56
-
-
Save RMKD/7a99f89b2b7a73a33c298c6635fae926 to your computer and use it in GitHub Desktop.
Revisions
-
RMKD created this gist
Oct 24, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ /* requirements: d3, FontAwesome usage example: var radialMenuItems = [ {"label": "A", "action":function(){return alert("hello menu A")}, "faIcon":"share-alt"}, {"label": "B", "action":function(){return alert("hello menu B")}, "faIcon":"line-chart"}, {"label": "C", "action":function(){return alert("hello menu C")}, "faIcon":"credit-card"}, {"label": "D", "action":function(){return alert("hello menu D")}, "faIcon":"arrows-alt"}, {"label": "E", "action":function(){return alert("hello menu E")}, "faIcon":"external-link"}, ] var radialMenuOptions = { "inner": 52, "outer": 66, "padding": 2, "fractionToCover": Math.PI*.75 } d3.selectAll(".node") .radialMenu(radialMenuItems, radialMenuOptions); */ d3.selection.prototype.radialMenu = function(items, options){ /* pass in items in the form: [ {label:"A", faIcon:"font-awesome-icon-name", action:function(){}}, {label:"B", faIcon:"font-awesome-icon-name", action:function(){}} ] pass in options in the form: {"inner":30, "outer": 50, "fractionToCover": 0.6} */ var fullCircle = Math.PI*2; function destroyMenu(){ d3.selectAll(".radial-menu-group").remove(); } //turn off the context menue for all svg elements d3.selectAll("svg").on("contextmenu", function(data, index) { d3.event.preventDefault(); }); var inner = (options.inner == undefined) ? 20 : options.inner; var outer = (options.outer == undefined) ? 40 : options.outer; var padding = (options.padding == undefined) ? fullCircle / 360 * 2 : fullCircle / 360 * options.padding; var startAt = (options.startAt == undefined) ? fullCircle * -0.10 : options.startAt; var fractionToCover = (options.fractionToCover == undefined) ? fullCircle * 0.33 : options.fractionToCover; var trigger = (options.trigger == undefined) ? "contextmenu" : options.trigger; var cursor = (options.cursor == undefined) ? "pointer" : options.cursor; var segmentSize = fractionToCover / items.length; this.on(trigger, function(event){ destroyMenu(); options = (options == undefined) ? {} : options; var menuArc = d3.arc() .startAngle(function(d,i) {return startAt + i * segmentSize + padding; }) .endAngle(function(d,i) { return startAt + (i+1) * segmentSize - padding; }) .innerRadius(inner) .outerRadius(outer) var parent = d3.select(this.parentNode); parent.on("mouseleave", destroyMenu); var menus = parent.selectAll(".radial-menu-group") .data(items).enter(); //this transparent circle catches other clicks menus.append("circle") .attr("class","radial-menu-group") .attr("r", outer * 1.5) .style("opacity",0); menus.append("path") .attr("class","radial-menu-group") .attr("d", menuArc) .style("cursor", cursor) .on("click",function(d){d.action();}) var labels = menus.append("g") .attr("class","radial-menu-group") .attr("transform", function(d, i){ var angle = (startAt + (i+0.5)* segmentSize)*180/Math.PI -90; return "rotate("+ angle +") translate("+((inner + outer)/2)+") " }) .style("cursor", cursor) .on("click",function(d){d.action();}); labels.append("svg:foreignObject") .attr("class", function(d){return "radial-menu-group fa fa-" + d.faIcon}) .attr("transform", "rotate(90)") .attr("x",-5) .attr("y",-5) .attr("width", 50) .attr("height", 50) .html("<i></i>"); labels.append("text") .attr("class", "radial-menu-group") .attr("dx", outer - (inner + outer)/2 + 5) .attr("dy", 5) .text(function(d){return d.label;}) }); }