拖动功能不适用于启动单击的第一个选择

时间:2017-03-26 05:13:32

标签: javascript d3.js

以下代码旨在通过mousemove和mouseclick突出显示各县。代码工作大多是正确的,我遇到问题的唯一问题是当我点击并移动鼠标时,第一个选择没有突出显示并被跳过(我可以返回并单击它以选择它但它很烦人它没有从一开始就选择它。

感谢您的帮助。

<!DOCTYPE html>
<title>Heartland Remapping Tool</title>
<link rel="shortcut icon" type="image/png" href="/faviconpng.png"/>
<style>
svg{
  width:100%;
  height: auto;
}
.counties, .unhovered {
  fill: white;
  stroke: #7887AB;
  stroke-width: .5px;
}
.counties .hovered, .counties :hover {
  fill: #061539;
  stroke-width: 0px;
}
.selected {
  fill: #061539;
}
.deselected {
  fill: white;
}
.deselected :hover {
  fill: white;
}
.county-borders {
  fill: none;
  stroke: #F0F8FF;
  stroke-width: .2px;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}
.state-borders {
  fill: none;
  stroke: #162955;
  opacity: .8;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>
var svg = d3.select("svg");
var path = d3.geoPath();
var clickDown = true;
var numSelectedCounties = 0;
var selectedCounties = {};

d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
  if (error) throw error;
  svg.append("g")
      .attr("class", "counties")
      .selectAll("path")
      .data(topojson.feature(us, us.objects.counties).features)
      .enter()
      .append("path")
      .attr("d", path);

  svg.append("g")
      .attr("class", "state-borders")
      .selectAll("path")
      .data(topojson.feature(us, us.objects.nation).features)
      .enter()
      .append("path")
      .attr("d", path);
  svg.append("path")
      .attr("class", "state-borders")
      .attr("d", path(topojson.mesh(us, us.objects.nation, function(a, b) { return a !== b; })));
  svg.append("path")
      .attr("class", "state-borders")
      .attr("d", path(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })));
  svg.append("path")
      .attr("class", "county-borders")
      .attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) { return a !== b; })));

//Clicking stuff below.

  let hoverEnabled = false;

  svg.selectAll('.counties path')
  .on('mousedown', x => hoverEnabled = true)
  .on('mouseup', x => hoverEnabled = false)
  .on('mouseover', function() {
    if (hoverEnabled) {
      if (!d3.select(this).classed('hovered')) {
        d3.select(this).classed('hovered', true);
        numSelectedCounties++;
      }
    }
  })
  .on('click', function() {
      if (d3.select(this).classed('hovered')) {
        d3.select(this).classed('hovered', false);
        numSelectedCounties--;
      }
      else {
        d3.select(this).classed('hovered', true);
        numSelectedCounties++;
      }
  })
  });
</script>

1 个答案:

答案 0 :(得分:1)

在你的mousedown中设置一个标记,看你是否在拖动;然后mouseover设置颜色。那个你刚刚被击落的县的mouseover事件已经发生了,所以它不会设置颜色。

我将您的所有事件处理简化为:

let hoverEnabled = false;
svg.selectAll('.counties path')
  .on('mousedown', function(){
    var self = d3.select(this);
    hoverEnabled = !self.classed('hovered');
    self.classed('hovered', hoverEnabled);
  })
  .on('mouseup', function(){ hoverEnabled = false; })
  .on('mouseover', function() {
    if (hoverEnabled){
      d3.select(this).classed('hovered', true);
    }
  });

另外,我不打算保留选定县的数量&#34;。当你需要它时,它可以清楚地解决它:

d3.selectAll('.hovered').size();

运行代码:

&#13;
&#13;
<!DOCTYPE html>
<title>Heartland Remapping Tool</title>
<link rel="shortcut icon" type="image/png" href="/faviconpng.png"/>
<style>
svg{
  width:100%;
  height: auto;
}
.counties, .unhovered {
  fill: white;
  stroke: #7887AB;
  stroke-width: .5px;
}
.counties .hovered, .counties :hover {
  fill: #061539;
  stroke-width: 0px;
}
.selected {
  fill: #061539;
}
.deselected {
  fill: white;
}
.deselected :hover {
  fill: white;
}
.county-borders {
  fill: none;
  stroke: #F0F8FF;
  stroke-width: .2px;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}
.state-borders {
  fill: none;
  stroke: #162955;
  opacity: .8;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>
var svg = d3.select("svg");
var path = d3.geoPath();
var clickDown = true;
var numSelectedCounties = 0;
var selectedCounties = {};

d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
  if (error) throw error;
  svg.append("g")
      .attr("class", "counties")
      .selectAll("path")
      .data(topojson.feature(us, us.objects.counties).features)
      .enter()
      .append("path")
      .attr("d", path);

  svg.append("g")
      .attr("class", "state-borders")
      .selectAll("path")
      .data(topojson.feature(us, us.objects.nation).features)
      .enter()
      .append("path")
      .attr("d", path);
  svg.append("path")
      .attr("class", "state-borders")
      .attr("d", path(topojson.mesh(us, us.objects.nation, function(a, b) { return a !== b; })));
  svg.append("path")
      .attr("class", "state-borders")
      .attr("d", path(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })));
  svg.append("path")
      .attr("class", "county-borders")
      .attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) { return a !== b; })));

  let hoverEnabled = false;
  svg.selectAll('.counties path')
  .on('mousedown', function(){
    var self = d3.select(this);
    hoverEnabled = !self.classed('hovered');
    self.classed('hovered', hoverEnabled);
  })
  .on('mouseup', function(){ hoverEnabled = false; })
  .on('mouseover', function() {
    if (hoverEnabled){
      d3.select(this).classed('hovered', true);
    }
  });
});

</script>
&#13;
&#13;
&#13;