MouseClick node event on d3 graph - d3.js

I need insert a mouseclick event on graph nodes, but all ways don't work with me.
My code that done the graph is this:
<!DOCTYPE html>
<html>
<head>
<title>01. Create Graph. Vivagraph SVG tutorial.</title>
<script type="text/javascript" src="VivaGraphJS-master/dist/vivagraph.js"></script>
<script type="text/javascript">
function main () {
// 1- criar um projeto de grafo
var graph = Viva.Graph.graph();
// 2 - adicionando nós e arestas
graph.addNode('natalia', 'ledlightblue.png');
graph.addNode('jessica', 'krec_record.png');
graph.addNode('lucas', 'ledyellow.png');
graph.addNode('leo', 'ledgreen.png');
graph.addNode('hcii', 'ledpurple.png');
graph.addNode('evento', 'krec_record.png');
graph.addLink('natalia', 'hcii');
graph.addLink('jessica', 'hcii');
graph.addLink('lucas', 'hcii');
graph.addLink('leo', 'hcii');
graph.addLink('jessica', 'evento');
var graphics = Viva.Graph.View.svgGraphics();
//var renderer = Viva.Graph.View.renderer(graph);
graphics.node(function(node) {
var ui = Viva.Graph.svg('image')
.attr('width', 32)
.attr('height', 32)
.link('https://cdn1.iconfinder.com/data/icons/nuvola2/32x32/actions/' + node.data);
return(ui);
});
graphics.link(function(link){
return Viva.Graph.svg('path')
.attr('stroke', 'black')
.attr('stroke-width',2);
}).placeLink(function(linkUI, fromPos, toPos) {
var data = 'M' + fromPos.x + ',' + fromPos.y +
'L' + toPos.x + ',' + toPos.y;
linkUI.attr("d", data);
})
var renderer = Viva.Graph.View.renderer(graph, {
graphics : graphics
});
renderer.run();
}
</script>
<style type="text/css" media="screen">
html, body, svg { width: 100%; height: 100%;}
</style>
I tried many ways like this that is used to do mouseover event
I'm using VivaGraph.js to do the graph
Some solution?

D3js and VivaGraphJS are two different libraries, and your question is only about VivaGraphJs (in the code D3 is not even imported), "d3.js" tag should be removed.
A possible solution is to import JQuery and change this portion of code:
graphics.node(function(node) {
var ui = Viva.Graph.svg('image')
.attr('width', 32)
.attr('height', 32)
.link('https://cdn1.iconfinder.com/data/icons/nuvola2/32x32/actions/' + node.data);
return(ui);
});
Into:
graphics.node(function(node) {
var ui = Viva.Graph.svg('image')
.attr('width', 32)
.attr('height', 32)
.link('https://cdn1.iconfinder.com/data/icons/nuvola2/32x32/actions/' + node.data);
$(ui).hover(function() { // mouse over
console.log("hovering in.", node.id);
}, function() { // mouse out
console.log("hovering out.", node.id);
});
$(ui).click(function() { // mouse click
console.log("click.", node.id);
});
return(ui);
});
$(ui).hover and $(ui).click come from JQuery.

Related

Dc.js Boxplot not creating outlines

Why is dc.js boxplot not creating any outlines? I am just created a simplified code based on http://dc-js.github.io/dc.js/examples/boxplot-basic.html
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<body>
<div id = 'boxch1'><br></div>
<script src="https://unpkg.com/crossfilter2#1.4.7/crossfilter.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="http://unpkg.com/dc#3/dc.js"></script>
<script>
let exp = [
{"Expt":1, "Speed":8},
{"Expt":1, "Speed":7},
{"Expt":1, "Speed":9},
{"Expt":1, "Speed":1},
{"Expt":2, "Speed":8},
{"Expt":2, "Speed":6},
{"Expt":2, "Speed":8}];
dc.config.defaultColors(d3.schemeSet1);
var ndx = crossfilter(exp)
runDimension = ndx.dimension(function(d) {return +d.Run;});
runGroup = runDimension.group();
experimentDimension = ndx.dimension(function(d) {return "exp-" + d.Expt;});
speedArrayGroup = experimentDimension.group().reduce(
function(p,v) {
// keep array sorted for efficiency
p.splice(d3.bisectLeft(p, v.Speed), 0, v.Speed);
return p;
},
function(p,v) {
p.splice(d3.bisectLeft(p, v.Speed), 1);
return p;
},
function() {
return [];
}
);
var bp01 = dc.boxPlot("#boxch1");
bp01
.width(768)
.height(480)
.margins({top: 10, right: 50, bottom: 30, left: 50})
.dimension(experimentDimension)
.group(speedArrayGroup)
.elasticY(true)
.elasticX(true);
bp01.render()
</script>
</body>
</html>
I am not getting the box outlines as in the chart drawn below.
https://imgur.com/a/ELH5xlX
Thanks for including a complete example.
These kinds of problems are usually because you are missing dc.css.
In dc.js, and D3 code in general, any static attributes of SVG elements that are not controlled by data can be specified in either JS code or in CSS. This includes axis lines, outlines, fonts, etc.
Generally it makes customization easier to use classnames and leave the static attributes to CSS. But you do need to include dc.css.

NVD3 - Show all tick values

My chart needs to have tick values in multiples of 3. For example, if I have 5 data points, my x-axis should show (3, 6, 9, 12, 15). How do I get nvd3 to display all tick numbers? I pasted my code below for reference
var chart = nv.models.lineChart()
.options({
margin: {left: 100, bottom: 100},
x: function(d,i) { return i*3},
showXAxis: true,
showYAxis: true,
showLegend: true,
reduceXTicks: false,
showMaxMin: false,
//values: $scope.data.values.map( function(d,i) { return i*3; }),
useInteractiveGuideline: true,
transitionDuration: 2500,
showControls : true
})
;
chart.xAxis //Chart x-axis settings
.axisLabel('Ager')
.orient('bottom')
//.tickValues( function(d,i) { return i*3;})
.tickFormat(d3.format(',r'));
chart.yAxis //Chart y-axis settings
.axisLabel('Voltage (v)')
.tickFormat(d3.format('.02f')); nv.utils.windowResize(chart.update);
I've tried everything I can think of and read online to get nvd3 show all ticks in multiples of 3. Please help me out of this tricky situation.
Thanks in advance!
You could have read the d3 docs and see that .tickValues does not accept a function.
Construct the array of tick values based on the domain of the x-axis. Because the domain is not yet set you have to construct it yourself based on the data.
Using the SinCos example from the nvd3 site
var myData = sinAndCos();
var xExtent = d3.extent(myData[0].values, d=>d.x);
xExtent = [Math.floor(xExtent[0]), Math.ceil(xExtent[1])+1];
var xTicks = d3.range(xExtent[0], xExtent[1]).filter(n => n%3===0);
chart.xAxis
.axisLabel('Time (ms)')
.tickValues(xTicks)
.tickFormat(d3.format(',r'));
Complete example. It will not run directly from the browser (will not load nvd3 inside an iframe(??)). Copy it to a local file and run it from there.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="https://nvd3.org/assets/css/nv.d3.css" rel="stylesheet"/>
<script src="https://nvd3.org/assets/lib/d3.v3.js"></script>
<script src="https://nvd3.org/assets/js/nv.d3.js"></script>
</head>
<body>
<div id="chart">
<svg style="width:800px;height:500px;"></svg>
</div>
<script>
/*These lines are all chart setup. Pick and choose which chart features you want to utilize. */
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
var myData = sinAndCos();
var xExtent = d3.extent(myData[0].values, d=>d.x);
xExtent = [Math.floor(xExtent[0]), Math.ceil(xExtent[1])+1];
var xTicks = d3.range(xExtent[0], xExtent[1]).filter(n => n%3===0);
chart.xAxis //Chart x-axis settings
.axisLabel('Time (ms)')
.tickValues(xTicks)
.tickFormat(d3.format(',r'));
chart.yAxis //Chart y-axis settings
.axisLabel('Voltage (v)')
.tickFormat(d3.format('.02f'));
d3.select('#chart svg') //Select the <svg> element you want to render the chart in.
.datum(myData) //Populate the <svg> element with chart data...
.call(chart); //Finally, render the chart!
//Update the chart when window resizes.
nv.utils.windowResize(function() { chart.update() });
return chart;
});
/**************************************
* Simple test data generator
*/
function sinAndCos() {
var sin = [],sin2 = [],
cos = [];
//Data is represented as an array of {x,y} pairs.
for (var i = 0; i < 100; i++) {
sin.push({x: i, y: Math.sin(i/10)});
sin2.push({x: i, y: Math.sin(i/10) *0.25 + 0.5});
cos.push({x: i, y: .5 * Math.cos(i/10)});
}
//Line chart data should be sent as an array of series objects.
return [
{
values: sin, //values - represents the array of {x,y} data points
key: 'Sine Wave', //key - the name of the series.
color: '#ff7f0e' //color - optional: choose your own line color.
},
{
values: cos,
key: 'Cosine Wave',
color: '#2ca02c'
},
{
values: sin2,
key: 'Another sine wave',
color: '#7777ff',
area: true //area - set to true if you want this line to turn into a filled area chart.
}
];
}
</script>
</body>
</html>

How to catch svg image fail to load in D3?

I am using D3 to create a visualization with rows of <image> svg elements.
Could anyone know how I can upload a replacement image if the image file is not available?
var images= imageGroup.append('svg:image')
.attr("xlink:href",function(d,i){
//lines of code to process filename
return "/img/" + filename + ".jpg"
})
This is more a JavaScript question then d3.js:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg width="100" height="100"></svg>
<script>
// set up svg image tag
var images = d3.select("svg")
.append('svg:image')
.attr('width', 50)
.attr('height', 50);
// create a test image
var imgTest = new Image();
// if it loads successfully add it to the svg image
imgTest.onload = function() {
images.attr("xlink:href", imgTest.src);
}
// if it fails test another image
imgTest.onerror = function() {
imgTest.src = "https://dummyimage.com/50x50/000/fff.png&text=An+Image!"
}
// this will fail
imgTest.src = "https://does.not/exist.png";
</script>
</body>
</html>
I know it's an old post but i found a simpler solution than Mark answer. So i post it for future users with the same issue.
In d3.js you can add events listeners on nodes (click, load, error, ...). So when the image fails to load you can change the link (with setAttribute() function) to a fallback image. Here is a working example (note that you should not add xlink: before href ):
var images = imageGroup.append('svg:image')
.attr("href", function(d){
return "ThisImageWillFailsToLoad.jpg"
})
.on("error", function(d){
this.setAttribute("href", "YourFallbackImage.jpg");
})
var images= imageGroup.append('svg:image')
.attr("xlink:href",function(d,i){
return "/img/" + filename + ".jpg"
})
// execute the callback function if the image fails to load
.on('error', function(d) {
// specify a default path for the image
d3.select(this).attr("xlink:href", "/defaultPath");
});

dc.js: Multiple graphs in a single dimension

How do I create multiple graphs that graph one dimension such that they react to filters placed on the other graph. Example here: http://bl.ocks.org/pbutler/9356548
<html>
<head>
<link href="style.css" rel="stylesheet">
<link href="dc.css" rel="stylesheet">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="crossfilter.js"></script>
<script src="dc.js"></script>
</head>
<body>
<div id="chart1">
</div>
<div id="chart2">
</div>
<script>
var data = [];
for (var i = 0; i < 10; i++) {
data.push({'val' : 'a'})
}
for (var i = 0; i < 15; i++) {
data.push({'val' : 'b'})
}
var ndx = crossfilter(data);
var all = ndx.groupAll();
var val = ndx.dimension(function (d) { return d.val; });
var valGroup = val.group()
var chart1 = dc.pieChart("#chart1");
var chart2 = dc.pieChart("#chart2");
chart1.dimension(val)
.group(valGroup);
chart2.dimension(val)
.group(valGroup);
dc.renderAll();
</script>
</body>
</html>
In short the graphs seem to ignore each other in this example.
If you create a second dimension using the same property, the filtering will reflect across charts.
Here is an example of that: http://jsfiddle.net/djmartin_umich/nw8EV/.
// build charts
teamMemberChart
.width(270)
.height(220)
.dimension(teamMemberDimension)
.group(teamMemberGroup)
.valueAccessor(function (d) {
return d.value.projectCount;
})
.elasticX(true);
teamMemberChart2
.width(270)
.height(220)
.dimension(teamMemberDimension)
.group(teamMemberGroup)
.valueAccessor(function (d) {
return d.value.projectCount;
})
.elasticX(true);
teamMemberChart3
.width(270)
.height(220)
.dimension(teamMemberDimension2)
.group(teamMemberGroup2)
.valueAccessor(function (d) {
return d.value.projectCount;
})
.elasticX(true);
The first two charts use the same dimension - picking one option does not reflect the other. The third chart uses a different dimension on the same property - choosing an option on this chart updates the other two charts.
It seems the answer can be found here: https://groups.google.com/forum/#!topic/dc-js-user-group/1nIScnbY0vs . There are two possible ways, add another dimension as suggested by DJ Martin or use an on("click", ...) handler to call the filter on the second chart.

ToolTip not displayed in nvd3 charts(Bar chart)

I am using nvd3 chart library to display reports in our application.I have tried to display bar chart using nvd3 library..Everything working fine except the tooltip.I didnt get the tooltip in mouse-hover function.I cant figure it out where am going wrong..Pls help me to resolve this issue.
Script is provide below,
function BarChart(chartData, chartid) {
var seriesOptions = [];
for (var i = 0; i < chartData.length; i++) {
seriesOptions[i] = {
key: chartData[i].Name,
values: eval("[" + chartData[i].Value + "]")
};
}
nv.addGraph(function () {
var chart = nv.models.multiBarChart().color(d3.scale.category10().range());
chart.xAxis.tickFormat(d3.format(',.2f'));
chart.yAxis.tickFormat(d3.format(',.2f'));
d3.select('#chartcontainer1 svg')
.datum(seriesOptions)
.transition()
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
}
You can call (and personalize) the tooltip by calling the tooltip function, something like this:
chart.tooltip(function (key, x, y, e, graph) {
return '<p><strong>' + key + '</strong></p>' +
'<p>' + y + ' in the month ' + x + '</p>';
});
In your example, you can insert it just before the return chart; line.
I had a similar issue with the lineWithFocusChart and my problem was the libraries which I installed using Bower didn't work for tooltips.
Once I linked to the libraries given on nvd3's live example it worked.
<link rel="stylesheet" href="http://nvd3.org/src/nv.d3.css">
<script src="http://nvd3.org/js/lib/jquery.min.js"></script>
<script src="http://nvd3.org/lib/d3.v2.js"></script>
<script src="http://nvd3.org/nv.d3.js"></script>

Resources