dc.js 响应式地图和缩放功能(鼠标滚轮)
dc.js responsive map and zoom function (mousewheel)
我已经 fork 示例 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%;
}
连接父 <g>
的 d3-zoom to change the 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,具有平移和缩放功能。
我已经 fork 示例 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%;
}
连接父 <g>
的 d3-zoom to change the 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,具有平移和缩放功能。