I am creating context menu based on javascript array with callback functions but getting two issues
unable to hide submenu when mouse moves to an element with no children nodes(On Delete Section).
unable to show submenus in proper hierarchy(After moving to Sibling Section unable to go back to submenu of child section).
My code:
d3.contextMenu = function (menu, openCallback) {
// create the div element that will hold the context menu
d3.selectAll('.d3-context-menu').data([1])
.enter()
.append('div')
.attr('class', 'd3-context-menu');
// close menu
d3.select('body').on('click.d3-context-menu', function() {
d3.select('.d3-context-menu').style('display', 'none');
});
// this gets executed when a contextmenu event occurs
return function(data, index) {
var elm = this;
d3.selectAll('.d3-context-menu').html('');
var list = d3.selectAll('.d3-context-menu').append('ul');
list.selectAll('li').data(menu).enter()
.append('li')
.html(function(d) {
return d.title;
})
.on('click', function(d, i) {
d.onMouseClick(elm, data, index);
})
.on('mouseover',function(d,i){
d.onMouseOver(elm,data,index);
if(d.chidernItems.length>0 )
{
d3.select(this).selectAll("ul").remove();
d3.select(this)
.append("ul")
.selectAll("li")
.data(d.chidernItems)
.enter().append("li")
.text(function(d) { return d.title; })
.on("mouseover", function(d,i){
d.onMouseOver(elm,data,index);
})
.on('click', function(d, i) {
d.onMouseClick(elm, data, index);
})
.on('mouseout',function(d,i){
d3.select(this).remove();
});
}
else
return false;
})
.on('mouseout',function(d,i){
if(d.chidernItems.length==0 )
{
d3.select(this).selectAll("ul").remove();
}
});
// the openCallback allows an action to fire before the menu is displayed
// an example usage would be closing a tooltip
if (openCallback) openCallback(data, index);
// display context menu
d3.select('.d3-context-menu')
.style('left', (d3.event.pageX - 2) + 'px')
.style('top', (d3.event.pageY - 2) + 'px')
.style('display', 'block');
d3.event.preventDefault();
};
};
var menu = [
{
title: 'Create Child Section',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Create Child Section clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Create Child mouseover data = ' +d );
},
chidernItems: [
{
title: 'Vertical',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Vertical Create Child clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Vertical Create Child mouseover data = ' +d );
}
},
{
title: 'Horizontal',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Horizontal Create Child clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Horizontal Create Child mouseover data = ' +d );
}
}
]
},
{
title: 'Create Sibling Section',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Create Sibling Section clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Sibling Section mouseover data = ' +d );
},
chidernItems: [
{
title: 'Vertical',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Sibling Vertical clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Sibling Vertical mouseover data = ' +d );
}
},
{
title: 'Horizontal',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Horizontal clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Horizontal mouseover data = ' +d );
}
}
]
},
{
title: 'Delete Section',
// Exceute Action
onMouseClick: function(elm, d, i) {
console.log('Delete Section Section clicked!');
console.log('The data for this circle is: ' + d);
},
onMouseOver: function(elm,d,i){
console.log('Delete Section mouseover data = ' +d );
},
chidernItems: []
}]
var data = [1];
var g = d3.select('body').append('svg')
.attr('width', 200)
.attr('height', 400)
.append('g');
g.selectAll('circles')
.data(data)
.enter()
.append('circle')
.attr('r', 30)
.attr('fill', 'steelblue')
.attr('cx', function(d) {
return 100;
})
.attr('cy', function(d) {
return d * 100;
})
.on('contextmenu', d3.contextMenu(menu));
.d3-context-menu {
position: absolute;
display: none;
background-color: #f2f2f2;
border-radius: 4px;
font-family: Arial, sans-serif;
font-size: 14px;
min-width: 150px;
border: 1px solid #d4d4d4;
z-index:1200;
}
.d3-context-menu ul {
list-style-type: none;
margin: 4px 0px;
padding: 0px;
cursor: default;
}
.d3-context-menu ul li {
padding: 4px 16px;
}
.d3-context-menu ul li:hover {
background-color: #4677f8;
color: #fefefe;
}
.d3-context-menu ul li > ul {
position: absolute;
background-color: #f2f2f2;
top: 0;
left: 175px;
z-index: -1;
}
.d3-context-menu ul li > ul li:hover
{
background-color: #4677f8;
color: #fefefe;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>
I have many elements with same name: <input type="text" name="Education[GraduationDate][0]" /> <input type="text" name="Education[GraduationDate][1]" /> <input type="text" name="...
I have many elements with same name: <input type="text" name="Education[GraduationDate][0]" /> <input type="text" name="Education[GraduationDate][1]" /> <input type="text" name="...
I'm currently using the command: $ ember build --watch --output-path=../public/ to build my ember app. Any ways of achieving the same thing but with a livereload? Thank you.
I'm currently using the command: $ ember build --watch --output-path=../public/ to build my ember app. Any ways of achieving the same thing but with a livereload? Thank you.
I receive a base64 pdf from the server which I want to print. I have been trying the following: $.ajax({ type: "POST", url: url, data: blahblahblah, success: function(data) { ...
I receive a base64 pdf from the server which I want to print. I have been trying the following: $.ajax({ type: "POST", url: url, data: blahblahblah, success: function(data) { ...
If I create an Object as follows: window.Something = { X: function() { // statements... } }; What is the best way to access this object without using this? Example: If I call the X ...
If I create an Object as follows: window.Something = { X: function() { // statements... } }; What is the best way to access this object without using this? Example: If I call the X ...