【问题标题】:dc.js responsive map and zoom function (mousewheel)dc.js 响应式地图和缩放功能(鼠标滚轮)
【发布时间】:2020-03-29 21:22:20
【问题描述】:

我已经分叉了示例 dc.js(版本 4)映射文件是 JsFiddle。我想要的是地图能够响应 Bootstrap 容器。因此,如果屏幕尺寸发生变化,地图将正确显示。 SVG 通过将宽度和高度设置为 null 以及 CSS 格式将宽度和高度设置为 100% 来响应。但是我看到底层的<g> (layer0) 元素没有响应。因此,我尝试在投影中添加比例元素。但不幸的是,我不知道如何让它像我使用 SVG 元素那样灵活。

另外,我希望可以放大。希望有人可以帮助我。

<div class="container">
  <div class="row">
    <div class="col">
      <div id="world-map" class="responsive"></div>
    </div>
  </div>
</div>

<pre id="data">country  total
      Belgium   2   
      Germany   3   
      France    4   
</pre>
function world(data) {
  var xf = crossfilter(data);
  var country = xf.dimension(function(d) {
    return d.country;
  });
  var countryGroup = country.group().reduceSum(d => +d.total);

  var worldMap = new dc.GeoChoroplethChart("#world-map");
  d3.json("https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json").then(function(worldJson) {
    worldMap
      .width(null)
      .height(null)
      .dimension(country)
      .group(countryGroup)
      .colors(d3.scaleQuantize().range(["#E2F2FF", "#C4E4FF", "#9ED2FF", "#81C5FF", "#6BBAFF", "#51AEFF", "#36A2FF", "#1E96FF", "#0089FF", "#0061B5"]))
      .colorDomain([0, 200])
      .colorCalculator(function(d) {
      return d ? worldMap.colors()(d) : '#ccc';
    })
      .overlayGeoJson(worldJson.features, "state", function(d) {
      return d.properties.name;
    })
      .projection(d3.geoEquirectangular()
                  .scale(100)
                  .translate([800 / 2, 400 / 2])
                 )
      .valueAccessor(function(kv) {
      //console.log(kv);
      return kv.value;
    })
      .title(function(d) {
      return d.key + "\nTotal: " + (d.value ? d.value : 0);
    });

    dc.renderAll();

  });
}

const data = d3.tsvParse(d3.select('pre#data').text());

world(data);
.row {
  background: #f8f9fa;
  margin-top: 20px;
}

.col {
  border: solid 1px #6c757d;
  padding: 10px;
}

pre#data {
  display: none;
}

.responsive {
  width: 100%;
  height: 100%;
}

【问题讨论】:

  • 这不是我最喜欢的解决方案,因为文本可能会失真,但您尝试过useViewBoxResizing 吗?否则,有一个folder of resizing examples 可能会有所帮助。困难的部分是检测 div 何时改变大小 - 遗憾的是,2020 年仍然没有跨浏览器方法。
  • 嗨,Gordon,我找到了一个解决方案,通过将变量 innerWidth 和 innerHeight 设置为引导容器并用这些变量替换转换(800 和 400)来使 layer0 响应。但是您也知道放大图表的解决方案吗?
  • 你问的是mouseZoomable还是别的什么?
  • 是的,您知道如何将 mouseZoomable 应用于此地图吗?
  • 哦,我忘了这是地理分布。嗯,它不是内置的,它可能不是那么难,但我不确定接下来的几天我是否有时间。现在我看到你把两个问题合二为一,聪明的把戏。

标签: javascript d3.js zooming responsive dc.js


【解决方案1】:

连接d3-zoom 以更改父&lt;g&gt; 的transform 以响应缩放事件非常容易。

首先,取出投影初始化,因为我们稍后需要初始值:

  const scale0 = 100, x0 = 800 / 2, y0 = 400 / 2, 
    projection = d3.geoEquirectangular()
      .scale(scale0)
      .translate([x0, y0])
  worldMap
    .projection(projection)

然后在图表呈现后添加缩放处理程序:

  worldMap.on('postRender', chart => {
    const zoom = d3.zoom();
    zoom.on('zoom', () => {
      const {k, x, y} = d3.event.transform;
      chart.select('g.layer0')
        .attr('transform', `translate(${x},${y}) scale(${k})`)
    })
    chart.svg().call(zoom);
  });

每次我们收到缩放事件时,我们都会从事件中提取比例、x 和 y 偏移量,并将它们应用于看起来像这样的变换

translate(-350.6778787924404,-173.42665430196223) scale(1.9132163161837539)

在我的第一次尝试中,我应用了一个新的投影并重新绘制了图表。这行得通,但它有性能问题。改变转换是要走的路!

Fork of your fiddle,具有平移和缩放功能。

【讨论】:

  • 再次感谢 Gordon,我刚从 dc 和 d3 开始,所以对我来说一切都是新的。我想知道您是否也可以设置缩放时的最小值和最大值。现在您可以放大到地图消失的程度。
  • 这东西不是来自 dc.js;都是标准的 D3 东西。请查看zoom.extent 和 d3-zoom 文档中的下几个函数。我想这就是你要找的。​​span>
猜你喜欢
  • 2015-10-07
  • 2013-01-30
  • 2015-03-20
  • 1970-01-01
  • 2014-03-26
  • 2014-04-05
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
相关资源
最近更新 更多