2017-06-29 2 views
0

J'ai créé un diagramme de dispersion et une carte choroplèthe dans la même page Web. Les données sont stockées dans un .CSV et .json, et les éléments sont liés avec un champ "nom".D3 - Sélection dans différents DIV

J'ai créé une info-bulle au passage de la souris sur les deux. Je veux maintenant une certaine interactivité entre eux: quand la souris est sur un élément sur scatterplot, cet élément sur choropleth réagit et quand la souris est sur la carte choropleth scatterplot réagit.

Scatterplot et choropleth sont en différents div avec les détails ID et je ne sais pas comment je peux refeer de l'un à l'autre. J'ai essayé d3.select("this#scatterplot"); comme this example mais cela ne fonctionne pas pour moi.

Comment puis-je sélectionner des éléments dans différents DIV et functions?

Je veux quelque chose comme ceci:

function handleMouseOverMap(d, i) {    
      d3.select('this#choropleth').style('stroke-width', 3); 
      d3.select('this#scatterplot').attr('r', 8); 
} 
function handleMouseOverGraph(d, i) {    
     d3.select('this#scatterplot').attr('r', 8); 
     d3.select('this#choropleth').style('stroke-width', 3); 
} 

code

<div id="scatterplot"></div> 
<div id="choropleth"></div> 
<script> 
d3.queue() 
.defer(d3.csv, 'data.csv', function (d) { 
    return {  
     name: d.name, 
     sau: +d.sau, 
     uta: +d.uta 
    } 
}) 
.defer(d3.json, 'dept.json') 
.awaitAll(initialize) 

var color = d3.scaleThreshold() 
.domain([150000, 300000, 450000]) 
.range(['#5cc567', '#e7dc2b', '#e59231', '#cb0000']) 

function initialize(error, results) { 
if (error) { throw error } 

var data = results[0] 
var features = results[1].features 

var components = [ 
    choropleth(features), 
    scatterplot(onBrush) 
] 

function update() { 
    components.forEach(function (component) { component(data) }) 
} 

function onBrush(x0, x1, y0, y1) { 
    var clear = x0 === x1 || y0 === y1 
    data.forEach(function (d) { 
     d.filtered = clear ? false 
      : d.uta < x0 || d.uta > x1 || d.sau < y0 || d.sau > y1 
    }) 
    update() 
    } 

update() 
} 

/* Graphique */ 
function scatterplot(onBrush) { 
var margin = { top: 10, right: 15, bottom: 40, left: 75 } 
var width = 680 - margin.left - margin.right 
var height = 550 - margin.top - margin.bottom 

var x = d3.scaleLinear() 
    .range([0, width]) 
var y = d3.scaleLinear() 
    .range([height, 0]) 

// Tooltip 
var xValue = function(d) { return d.sau;}; 
var yValue = function(d) { return d.uta;}; 

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

var xAxis = d3.axisBottom() 
    .scale(x) 
    .tickFormat(d3.format('')) 
var yAxis = d3.axisLeft() 
    .scale(y) 
    .tickFormat(d3.format('')) 

// Selection 
var brush = d3.brush() 
    .extent([[0, 0], [width, height]]) 
    .on('start brush', function() { 
     var selection = d3.event.selection 

     var x0 = x.invert(selection[0][0]) 
     var x1 = x.invert(selection[1][0]) 
     var y0 = y.invert(selection[1][1]) 
     var y1 = y.invert(selection[0][1]) 

     onBrush(x0, x1, y0, y1) 
    }) 

var svg = d3.select('#scatterplot') 
    .append('svg') 
    .attr('width', width + margin.left + margin.right) 
    .attr('height', height + margin.top + margin.bottom) 
    .append('g') 
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')') 

var bg = svg.append('g') 
var gx = svg.append('g') 
    .attr('class', 'x axis') 
    .attr('transform', 'translate(0,' + height + ')') 
var gy = svg.append('g') 
    .attr('class', 'y axis') 

gx.append('text') 
    .attr('x', width) 
    .attr('y', 35) 
    .style('text-anchor', 'end') 
    .style('fill', '#000') 
    .style('font-weight', 'bold') 
    .text('UTA') 

gy.append('text') 
    .attr('transform', 'rotate(-90)') 
    .attr('x', 0) 
    .attr('y', -55) 
    .style('text-anchor', 'end') 
    .style('fill', '#000') 
    .style('font-weight', 'bold') 
    .text('SAU - ha') 

svg.append('g') 
    .attr('class', 'brush') 
    .call(brush) 

return function update(data) { 
    x.domain(d3.extent(data, function (d) { return d.uta })).nice() 
    y.domain(d3.extent(data, function (d) { return d.sau })).nice() 

    gx.call(xAxis) 
    gy.call(yAxis) 

    var bgRect = bg.selectAll('rect') 
     .data(d3.pairs(d3.merge([[y.domain()[0]], color.domain(), [y.domain()[1]]]))) 
    bgRect.exit().remove() 
    bgRect.enter().append('rect') 
     .attr('x', 0) 
     .attr('width', width) 
     .merge(bgRect) 
     .attr('y', function (d) { return y(d[1]) }) 
     .attr('height', function (d) { return y(d[0]) - y(d[1]) }) 
     .style('fill', function (d) { return color(d[0]) }) 

    var circle = svg.selectAll('circle') 
     .data(data, function (d) { return d.name }) 
    circle.exit().remove() 
    circle.enter().append('circle') 
     .attr('r', 4) 
     .style('stroke', '#fff') 
     .merge(circle) 
     .attr('cx', function (d) { return x(d.uta) }) 
     .attr('cy', function (d) { return y(d.sau) }) 
     .style('fill', function (d) { return color(d.sau) }) 
     .style('opacity', function (d) { return d.filtered ? 0.5 : 1 }) 
     .style('stroke-width', function (d) { return d.filtered ? 1 : 2 }) 
     // Event 
     .on("mouseover", function(d) { 
      tooltipOverGraph.call(this, d);    
      handleMouseOverGraph.call(this, d); 
      }) 
     .on("mouseout", function(d) { 
      tooltipOutGraph.call(this, d); 
      handleMouseOutGraph.call(this, d); 
      }) 
     } 
    // Tooltip 
    function tooltipOverGraph(d) { 
      tooltip.transition() 
       .duration(200) 
       .style("opacity", .9); 
      tooltip.html(d["name"] + "<br>" + xValue(d) 
       + " ha" +", " + yValue(d) + " UTA") 
       .style("left", (d3.event.pageX + 5) + "px") 
       .style("top", (d3.event.pageY - 28) + "px");   
    } 

    function tooltipOutGraph(d) { 
      tooltip.transition() 
      .duration(500) 
      .style("opacity", 0); 
    }  
} 

// Create Event Handlers for mouse 
    function handleMouseOverGraph(d, i) {    
     d3.select(this).attr('r', 8);   
    } 

    function handleMouseOutGraph(d, i) {    
     d3.select(this).attr('r', 4); 
    } 


/* Carte */ 
function choropleth(features) { 
var width = 680 
var height = 550 

// Tooltip 
var xValue = function(d) { return d.sau;}; 
var yValue = function(d) { return d.uta;}; 

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

// Projection et centrage de la carte 
var projection = d3.geoMercator() 
    .center([ 3, 46.5 ]) 
    .scale([width * 3.1]) 
    .translate([width/2, height/2]) 

var path = d3.geoPath().projection(projection) 

var svg = d3.select('#choropleth') 
    .append('svg') 
    .attr('width', width) 
    .attr('height', height) 

svg.selectAll('path') 
    .data(features) 
    .enter() 
    .append('path') 
    .attr('d', path) 
    .style('stroke', '#fff') 
    .style('stroke-width', 1)  
    // Event 
    .on("mouseover", function(d) { 
     tooltipOverMap.call(this, d); 
     handleMouseOverMap.call(this, d);   
    }) 
    .on("mouseout", function(d) { 
     tooltipOutMap.call(this, d); 
     handleMouseOutMap.call(this, d);    
    }) 

    // Tooltip 
    function tooltipOverMap(d) { 
     tooltip.transition() 
      .duration(200) 
      .style("opacity", .9); 
     tooltip.html(d["name"] + "<br>" + xValue(d) 
       + " ha" +", " + yValue(d) + " UTA") 
       .style("left", (d3.event.pageX + 5) + "px") 
       .style("top", (d3.event.pageY - 28) + "px");    
    } 

    function tooltipOutMap(d) { 
     tooltip.transition() 
      .duration(500) 
      .style("opacity", 0); 
    } 


return function update(data) { 
    svg.selectAll('path') 
     .data(data, function (d) { return d.name || d.properties.name }) 
     .style('fill', function (d) { return d.filtered ? '#ddd' : color(d.sau) }) 
    } 
} 

// Create Event Handlers for mouse 
    function handleMouseOverMap(d, i) {    
     d3.select(this).style('stroke-width', 3);   
    } 

    function handleMouseOutMap(d, i) {    
     d3.select(this).style('stroke-width', 1);   
    } 
</script> 

Example

Répondre

0

D'abord, ajouter class distincts attributs aux rect et circle éléments lorsque vous entrez + les ajouter:

bgRect.enter().append('rect') 
    .attr('class', function(d,i) { return 'classRect' + i; }) 


circle.enter().append('circle') 
    .attr('class', function(d,i) { return 'classCircle' + i; }) 

Ensuite, mettez à jour votre souris sur les fonctions:

function handleMouseOverMap(d) { 

     // update the choropleth // 
     d3.select(d).style('stroke-width', 3); 

     // update the scatterplot // 
     // capture the number contained in class (e.g. "1" for "classRect1") 
     var i = d3.select(d).class.substr(-1); 

     // select corresponding circle in scatter and update 
     d3.select('circle.classCircle'+i).attr('r', 8); 
} 


function handleMouseOverGraph(d) { 

     // update the scatter //   
     d3.select(d).attr('r', 8); 

     // update the choropleth // 
     // capture the number contained in class (e.g. "1" for "classCircle1") 
     var i = d3.select(d).class.substr(-1); 

     // select corresponding rect in the choropleth and update 
     d3.select('rect.classRect'+i).style('stroke-width', 3); 
} 
+0

Il me renvoie une erreur. 'D3.select (...) la classe est undefined' dans cette ligne' var i = d3. select (d) .class.substr (-1); 'Est-ce que l'extension des variables et des fonctions est en cause? Parce que 'scatterplot' et' choropleth' sont des fonctions distinctes. – GeoGyro