Andrej
Andrej

Reputation: 3849

Combine d3.js with jquery function call

This question is motivated on the basis of my previous question on drawing scatterplots and wordcloud. Jason Davies's wordcloud somehow didn't worked for me, so I replaced it with pure jQuery wordcloud - jQCloud.

The aim of the application stays the same. When I go over the point on the scatterplot, the wordcloud should appear. I have two questions:

  1. When the page is loaded I should go over the point twice to render the wordcloud. I have no idea why.
  2. In current setting the wordcloud won't hide when the mouseout event is called. How to repair that?

Any ideas are appreciated. The code is pasted below and also on JSFiddle.

$(document).ready(function() {

var data = [[5,3,[{'text':'word1','weight':4},{'text':'word2','weight':10}]], 
            [3,5,[{'text':'word3','weight':5},{'text':'word4','weight':4}]],
            [1,4,[{'text':'word1','weight':3},{'text':'word2','weight':5},{'text':'word3','weight':2}]],
            [2,3,[{'text':'word2','weight':1},{'text':'word3','weight':5}]]];

var margin = {top: 20, right: 15, bottom: 60, left: 60},
    width = 500 - margin.left - margin.right,
    height = 250 - margin.top - margin.bottom;

var x = d3.scale.linear()
  .domain([0, d3.max(data, function(d) { return d[0]; })])
  .range([ 0, width ]);

var y = d3.scale.linear()
  .domain([0, d3.max(data, function(d) { return d[1]; })])
  .range([ height, 0 ]);

var chart = d3.select('body')
  .append('svg:svg')
  .attr('width', width + margin.right + margin.left)
  .attr('height', height + margin.top + margin.bottom)
  .attr('class', 'chart')

var main = chart.append('g')
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
  .attr('width', width)
  .attr('height', height)
  .attr('class', 'main')   

// Draw the x axis
var xAxis = d3.svg.axis()
  .scale(x)
  .orient('bottom');

main.append('g')
  .attr('transform', 'translate(0,' + height + ')')
  .attr('class', 'main axis date')
  .call(xAxis);

// draw the y axis
var yAxis = d3.svg.axis()
  .scale(y)
  .orient('left');

main.append('g')
  .attr('transform', 'translate(0,0)')
  .attr('class', 'main axis date')
  .call(yAxis);

var g = main.append("svg:g"); 

var circle = g.selectAll("scatter-dots")
  .data(data)
  .enter().append("svg:circle")
  .attr("cx", function (d,i) { return x(d[0]); } )
  .attr("cy", function (d) { return y(d[1]); } )
  .attr("r", 5);

// FUNCTION TO DISPLAY WORDCLOUD
circle.on('mouseover', function(d){
  div.style("display", "block")
  $("#my_words").jQCloud('update',d[2]);
});

circle.on('mouseout', function(){
  div.style("display", "none")
  div.select("svg").remove();
});

var div = d3.select("body")
  .append("div")
  .style("display", "none");

});

Upvotes: 0

Views: 438

Answers (1)

Nixie
Nixie

Reputation: 637

  1. You are using an 'update' function of jCloud, which I was unable to find documentation for. If you call 'update' only when cloud is already populated, everything goes fine:

    var cloudInitialized = false;
    // FUNCTION TO DISPLAY WORDCLOUD
    circle.on('mouseover', function(d){
      d3.selectAll("#my_words span").style("display", "inline");
    
      if (cloudInitialized)
        $("#my_words").jQCloud("update", d[2]);
      else
        $("#my_words").jQCloud(d[2]);
    
      cloudInitialized = true;
    });
    
  2. You are hiding a different div in your code (a kind of a tooltip, not wordcloud).

Working example: https://jsfiddle.net/povrp9sk/10/

Upvotes: 1

Related Questions