2016-10-23 5 views
2

나는 다음과 같은 데이터에 정의 된 산점도를 작성의 각 포인트에 대한, 구름을 그립니다 (단지 처음 두 개의 필드가 현재 플롯에 사용하는 점에 유의) :산점도

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

다음, 우리는 각각의 특정을 클릭하면 scatterplot을 가리키면 응용 프로그램은 data 변수의 세 번째 필드에 저장된 단어에서 정의 된 단어 클라우드를 첨부해야합니다. 제이슨 데이비스의 wordcloud 구현을 사용합니다. 현재 (데모 목적으로), 워드 클 라우드는 변수 frequency_list에 저장된 정적 데이터에서만 생성됩니다. 현재 코드는 JSFiddle에도 저장됩니다.

어떻게 진행할 수 있습니까?

var data = [[5,3,"{'text':'word1',size:4},{'text':'word2','size':1}"], 
      [3,5,"{'text':'word3',size:5},{'text':'word4','size':4}"], 
      [1,4,"{'text':'word1',size:3},{'text':'word2','size':5},{'text':'word3','size':2}"], 
      [2,3,"{'text':'word2',size:1},{'text':'word3','size':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"); 

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) 
    .on("mouseover", function(){d3.select(this).style("fill", "red")}) 
    .on("mouseout", function(){d3.select(this).style("fill", "black")}); 

// FUNCTION TO DISPLAY CIRCLE 
g.on('mouseover', function(){ 
    div.style("display", "block") 
    d3.select("krog").style("fill", "orange"); 
    generate(); 
}); 

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

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


// Functions to draw wordcloud 
var frequency_list = [{"text":"study","size":40},{"text":"motion","size":15},{"text":"forces","size":10},{"text":"electricity","size":15},{"text":"movement","size":10},{"text":"relation","size":5},{"text":"things","size":10},{"text":"force","size":5},{"text":"ad","size":5}]; 

var color = d3.scale.linear() 
      .domain([0,1,2,3,4,5,6,10,15,20,100]) 
      .range(["#ddd", "#ccc", "#bbb", "#aaa", "#999", "#888", "#777", "#666", "#555", "#444", "#333", "#222"]); 

// Generates wordcloud 
function generate(){ 
    d3.layout.cloud().size([800, 300]) 
    .words(frequency_list) 
    .rotate(0) 
    .fontSize(function(d) { return d.size; }) 
    .on("end", draw) 
    .start(); 
} 

function draw(words) { 
    d3.select("div").append("svg") 
    .attr("width", 850) 
    .attr("height", 350) 
    .attr("class", "wordcloud") 
    .append("g") 
    // without the transform, words words would get cutoff to the left and top, they would 
    // appear outside of the SVG area 
    .attr("transform", "translate(320,200)") 
    .selectAll("text") 
    .data(words) 
    .enter().append("text") 
    .style("font-size", function(d) { return d.size + "px"; }) 
    .style("fill", function(d, i) { return color(i); }) 
    .attr("transform", function(d) { 
     return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; 
    }) 
    .text(function(d) { return d.text; }); 
} 

답변

3

여기에 몇 가지 문제가 있습니다.

먼저 데이터에 해당 단어의 문자열이 있습니다. 그 후

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

, 나는 기능 draw 변경 :

div.append("svg") 
    .attr("width", 300) 
    .attr("height", 300) 
    .attr("class", "wordcloud") 
    .append("g") 
: 대신 새로운 사업부 당신이 원을 가져 때마다 추가, 그것은 단지 DIV의 내용을 변경할 나는 객체의 배열을위한 것으로 변경

하지만 이제 가장 중요한 변경 사항이 있습니다.

사용자가 서클을 가리킬 때마다 워드 클럭이 표시되지만 그룹 요소에 대해 마우스 오버를 호출하는 중입니다. 그러면 각 특정 서클에 연결된 데이터에 액세스 할 수 없습니다. 대신 그

우리는 서클 변수를 설정할 것이다 :

var circle = g.selectAll("scatter-dots") 
    .data(data) 
    .enter() 
    .append("svg:circle"); 

을 따라서, 각 어레이의 세 번째 요소 인 원 맴돌고 위해 우리는 데이터를 얻을 수

circle.on('mouseover', function(d){ 
    div.style("display", "block") 
    d3.select("krog").style("fill", "orange"); 
    generate(d[2]);//here, d[2] is the third element in the data array 
}); 

function generate(thisWords){ 
    d3.layout.cloud().size([800, 300]) 
    .words(thisWords) 
    .rotate(0) 
    .fontSize(function(d) { return d.size; }) 
    .on("end", draw) 
    .start(); 
} 
:

는 우린 thisWords라는 파라미터로서 기능 generate이 세 번째 요소 (d[2])를 통과

여기에 귀하의 바이올린입니다 : https://jsfiddle.net/jwrbps4j/

추신 : 그 단어에 대한 translate 개선해야합니다.