Currently I'm working on a small project. At this stage I have several word cloud SVGs with the help of d3.js word cloud.
Now I want to make the SVG's 'text' element draggable with JQuery UI so that user can drag the text element and then drop it on certain area (say a droppable div).
But after several attempts, it seems that JQuery-UI is not that compatible with SVG. I've compared several similar questions and tried on my own code, but none of them worked. The most up-voted answer of this question is very close to what I want. The text element is draggable, but when I click the element, it doesn't appear in the right position and it would appear elsewhere. And also the element cannot be dragged out of its SVG container.
Here's my JS code:
var fill = d3.scale.category20();
function draw(words) {
d3.select('#wordCloud').append("svg")
.attr("width", 600)
.attr("height", 600)
.append("g")
.attr("transform", "translate(300,300)")
.selectAll("text")
.data(words)
.enter().append("text")
.style("font-size", function(d) { return d.size + "px"; })
.style("font-family", "Impact")
.style("fill", function(d, i) { return fill(i); })
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) { return d.text; });
}
wordCloudData.map((model) => {
let modelName = model.modelName;
let wordsArray = model.specArray;
var $title = $('<h4></h4>').text(modelName);
$('#wordCloud').append($title);
d3.layout.cloud().size([600, 600])
.words(wordsArray.map(function(d) {
return {text: d, size: 10 + Math.random() * 90};
}))
// .rotate(function() { return ~~(Math.random() * 2) * 90; })
.font("Impact")
.fontSize(function(d) { return d.size * 0.6; })
.on("end", draw)
.start();
});
$(document).ready(function() {
let wordCloudCount = $('#wordCloud svg').length;
let svgArray = $('#wordCloud svg').clone();
let titleArray = $('#wordCloud h4').clone();
for (let i = 0; i < wordCloudCount; i++) {
let $wordCloudDiv = $('<div></div>').attr('class', 'wordCloud');
let $title = titleArray[i];
let $svg = svgArray[i];
$wordCloudDiv.append($title);
$wordCloudDiv.append($svg);
$('#wordCloudFinal').append($wordCloudDiv);
}
$('#wordCloud').hide();
$('text')
.draggable()
.bind('mousedown', function(event, ui){
$(event.target.parentElement).append( event.target );
})
.bind('drag', function(event, ui){
event.target.setAttribute('x', ui.position.left);
event.target.setAttribute('y', ui.position.top);
});
});
Here is my HTML code:
<div class="container">
<div id="wordCloud"></div>
<div id="wordCloudFinal"></div>
</div>