should d3 drag (v5) update object datum during dragging? - d3.js

I'm dragging a single rectangle ... it drags correctly the first time, but the second time it jumps back to its starting point at the start of the drag.
I notice many drag examples on the net drag circles, where there is a fortunate correspondance between the point and the cx, cy. But with a rectangle there is an offset, which looks like it is supposed to be handled using the objects data. But I'm not sure exactly how.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
svg {
background-color: linen;
}
</style>
</head>
<body>
<svg id="svgc" width="450" height="450">
</svg>
<script>
d3.select("#svgc").selectAll("rect")
.data([{x: 100, y:200}])
.enter()
.append("rect")
.attr("x",function(d) {return d.x; })
.attr("y",function(d) {return d.y; })
.attr("width",40)
.attr("height",80)
.attr("fill","steelblue");
makeDragDrop();
function makeDragDrop() {
var widget=undefined, color=undefined;
var dragR=d3.drag()
.on("start", function() {
color=d3.select(this).attr("fill");
widget=d3.select(this).attr("fill","lime");
})
.on("drag", function(d) {
d3.select(this)
.attr("x",d3.event.x)
.attr("y",d3.event.y);
})
.on("end", function() {
widget.attr("fill",color);
widget=undefined;
})
dragR(d3.select("#svgc").selectAll("rect"));
}
</script>
</body>
</html>

Related

How to make paths to fill green all the time when there is mouseover using d3

d3 loaded external svg which contains closed paths,Code is highlighting green fill only once per each path from the refresh. Is it possible to make green fills for all the mouseovers.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="./d3.min.js"></script>
<title>svg and d3</title>
</head>
<body>
<script type="text/javascript">
d3.xml("t.svg")
.mimeType("image/svg+xml")
.get(function(error, xml) {
if (error) throw error;
document.body.appendChild(xml.documentElement);
d3.selectAll('path.tel')
.on("mouseover", function(d) {
d3.select(this).style("fill", "green");
})
.on("mouseout", function(d) {
d3.select(this).style("fill", "none");
});
});
</script>
</body>
</html>

Wrap text in a circle with D3 v4 and D3plus

I'm using D3 v4 and I want to wrap text in a circle with D3plus.
I was trying two approaches but nothing worked for me.
First approach
I adopted the example from https://bl.ocks.org/davelandry/a39f0c3fc52804ee859a .
This is the essential part of my code:
<head>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="https://d3plus.org/js/d3plus.js"></script>
</head>
<body>
<div id="graphContainer" class="graphContainer">
<svg width="960" height="600"></svg>
</div>
<script>
d3.json('licenseSmall.json', function(error, graph) {
if (error) throw error;
var nodeContainer = svg.append("g")
.attr("class", "nodeContainer");
var node = nodeContainer.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "nodes")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var circle = node.append("circle")
.attr("r", 20)
.attr("fill", function(d) { return color(d.color); });
node.append("text")
.attr("id", "text")
.attr("dx", -10)
.attr("dy", ".35em")
.attr("test-anchor", "middle")
.text(function(d) { return getText(d) });
// Wrap text in a circle.
d3plus.textwrap()
.container(d3.select("#text"))
.draw();
});
</script>
</body>
With this code I get 2 errors:
TypeError: d3.scale is undefined
ReferenceError: d3plus is not defined
So it looks like d3plus is not working with D3 v4...
Then I found this post https://groups.google.com/forum/#!topic/d3plus/WN2Ruj3kjPA
and tried to take the example from the linked Github project d3plus-text (sorry, I've got not enough reputation to post the link).
So I changed my code:
old
<head>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="https://d3plus.org/js/d3plus.js"></script>
</head>
new
<head>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3plus.org/js/d3plus-text.v0.9.full.min.js"></script>
</head>
And in the script I just replaced
// Wrap text in a circle.
d3plus.textwrap()
.container(d3.select("#text"))
.draw();
with
new d3plus.TextBox()
.data(d3.select("#text").data())
.fontSize(16)
.width(200)
.x(function(d, i) { return i * 250; })
.render();
But actually nothing happens. The text looks the same as before.
And I get this error:
TypeError: t is undefined at d3.v4.min.js:4:27260
I have no idea how to adopt the example correctly. And I didn't find any other example on how to use d3plus.TextBox()
What I'm doing wrong?
use d3plus
d3plus.textwrap()
.container(d3.select("#your-div"))
.shape('circle')
.width(290)
.height(75)
.resize(true)
.draw();
I got it to work by using d3plus-text.Textbox()

Is there a kind of "Wobble" efect in d3?

i am looking for a special effect in D3.js.
For example, if you click on a button, a kind of "wobble" effect start so shake that clicked button.
Can someone of you help me about this effect?
It really sounds like you want something like this from jquery-ui. d3 doesn't really provide canned "effects" like that.
But, of course, with some effort, you could code that in d3:
<!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>
<button>This is a button</button>
<script>
var button = d3.select('button');
button
.style('position', 'absolute')
.on("click", function() {
var shakeTimes = 5;
button.transition()
.duration(100)
.on("start", function repeat() {
if (shakeTimes-- < 0) return;
d3.active(this)
.style("left", "50px")
.transition()
.style("left", "0px")
.transition()
.on("start", repeat);
});
});
</script>
</body>
</html>

d3.scale doesn't work when offline?

This doesn't work offline, it works just fine when internet connection is available :
<!doctype html>
<html>
<head>
<title>d3 SVG barchart</title>
<script src="http://d3js.org/d3.v3.min.js"></script><!--Line A-->
<script src="d3.js"></script>
<script src="d3.min.js"></script>
</head>
<body>
<script>
var dataArray = [20, 40, 50, 60];
var width=500;
var height=500;
var canvas = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var widthScale = d3.scale.linear()
.domain([0, 60])
.range([0, width]);
var bars = canvas.selectAll("rect")
.data(dataArray)
.enter()
.append("rect")
.attr("width", function(d){
return widthScale(d);
})
.attr("height", 50)
.attr("y", function(d, i){
return i*100;
});
</script>
</body>
</html>
It seems like the scale operation(s) of d3.js library doesn't work when I'm offline (or when Line A in is put in a comment block), why? Is there any d3.js version that works for offline user?
I enjoy snap.svg practices offline (I don't have private internet connection available), is there any way to do this with d3.js?
Your problem is here
<script src="http://d3js.org/d3.v3.min.js"></script><!--Line A-->
<script src="d3.js"></script>
<script src="d3.min.js"></script>
Download
<script src="http://d3js.org/d3.v3.min.js"></script>
Refer correctly to it locally and remove:
<script src="d3.js"></script>
<script src="d3.min.js"></script>
1.download and add d3.v3.min.js in asset folder
2.remove
<script src="http://d3js.org/d3.v3.min.js"></script><!--Line A-->
<script src="d3.js"></script>
<script src="d3.min.js"></script>
3.add
<script src="d3.v3.min.js"></script>
then d3 graph will work in offline .

Very simple d3js example not working

I'm trying to start with d3 but have bad exp. :)
I can't make a simple example run localy. I'm runing it under chrome with webstorm local server;
http://localhost:63342/svg-tests/index.html
There are no errors but no red circles are drawen. And "console.log(d);" is not fired;
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script src="js/d3.v3.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<script>
var dataSet = [10, 20, 30, 40];
var svg = d3.select('svg');
var circle = svg.selectAll('circle')
.data(dataSet)
.enter()
.append('circle')
.attr({
r: function(d){ console.log(d); return d },
cx: 10,
cy: 10,
fill: 'red'
});
</script>
<svg></svg>
</body>
</html>
Please help!?
You just need to define the <svg> element before the script as it relies on it:
<svg></svg>
<script>
...
</script>

Resources