- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 D3 的新手,所以如果这与其他帖子多余,我很抱歉。我正在尝试制作一张 map ,其中包含用户通过单击条形图选择的点。目前我有一张世界地图,点根据点击的栏进入和退出。我想知道如何还包含缩放效果,该效果会裁剪地球以仅包含所选栏的点区域。例如:第一个栏应显示美利坚合众国 map 。
var data = [{
"name": "Apples",
"value": 20,
"latlong": [
{"latitude": 32.043478, "longitude": -110.7851017},
{"latitude": 40.49, "longitude": -106.83},
{"latitude": 39.1960652, "longitude": -120.2384172},
{"latitude": 36.137076, "longitude": -81.183722},
{"latitude": 35.1380976, "longitude": -90.0611644},
{"latitude": 33.76875, "longitude": -84.376217},
{"latitude": 32.867153, "longitude": -79.9678813},
{"latitude": 39.61078, "longitude": -78.79830099999},
{"latitude": 40.8925, "longitude": -89.5074},
{"latitude": 44.1862, "longitude": -85.8031},
{"latitude": 35.48759154, "longitude": -86.10236359},
{"latitude": 37.9342807, "longitude": -107.8073787999},
{"latitude": 41.3530864, "longitude": -75.6848074},
{"latitude": 38.423137, "longitude": -80.021118},
{"latitude": 43.5121, "longitude": -72.4021},
{"latitude": 48.4070083, "longitude": -114.2827366}
]
},
{
"name": "Oranges",
"value": 26,
"latlong": [
{"latitude": -36.8506158, "longitude": 174.7678785},
{"latitude": -27.4510454, "longitude": 153.0319808},
{"latitude": -33.867111, "longitude": 151.217941},
{"latitude": -34.8450381, "longitude": 138.4985548},
{"latitude": -37.7928386, "longitude": 144.9051327},
{"latitude": -32.0582947, "longitude": 115.7460244},
{"latitude": 29.934926599999, "longitude": -90.0615085},
{"latitude": -34.4829472, "longitude": -58.518548},
{"latitude": -33.460464, "longitude": -70.656868},
{"latitude": 4.8007362, "longitude": -74.0373992},
{"latitude": 4.9375556, "longitude": -73.9649426},
{"latitude": -23.701185, "longitude": -46.7001431},
{"latitude": 33.678023, "longitude": -116.23754},
{"latitude": 51.8451208, "longitude": 5.6872547},
{"latitude": 40.3688321, "longitude": -3.6866294},
{"latitude": 40.4817271, "longitude": -3.6330802},
{"latitude": 40.4642, "longitude": -3.6131},
{"latitude": 52.327353537, "longitude": 1.67658117421},
]
}
];
//set up svg using margin conventions - we'll need plenty of room on the left for labels
var margin = {
top: 15,
right: 25,
bottom: 15,
left: 60
};
var width = 400 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("#graphic").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 x = d3.scale.linear()
.range([0, width])
.domain([0, d3.max(data, function (d) {
return d.value;
})]);
var y = d3.scale.ordinal()
.rangeRoundBands([height, 0], .1)
.domain(data.map(function (d) {
return d.name;
}));
//make y axis to show bar names
var yAxis = d3.svg.axis()
.scale(y)
//no tick marks
.tickSize(0)
.orient("left");
var gy = svg.append("g")
.attr("class", "y axis")
.call(yAxis)
var bars = svg.selectAll(".bar")
.data(data)
.enter()
.append("g")
//append rects
bars.append("rect")
.attr("class", "bar")
.attr("y", function (d) {
return y(d.name);
})
.attr("height", y.rangeBand())
.attr("x", 0)
.attr("width", function (d) {
return x(d.value);
})
.on("click", function (d) {
// d3.select("#chart circle")
// .attr("fill", function () { return "rgb(0, 0, " + Math.round(d.key * 10) + ")"; });
d3.selectAll('rect').style('fill', '#5f89ad');
d3.select(this).style("fill", "#012B4E");
var circle = svg_map.select("g").selectAll("circle")
.data(d.latlong);
circle.exit().remove();//remove unneeded circles
circle.enter().append("circle")
.attr("r",0);//create any new circles needed
//update all circles to new positions
circle.transition()
.duration(500)
.attr("cx", function(d){ return projection([d.longitude, d.latitude])[0] })
.attr("cy", function(d){ return projection([d.longitude, d.latitude])[1] })
.attr("r", 7)
.attr("class", "circle")
.style("fill", "#012B4E")
.attr("stroke", "#012B4E")
.style("opacity", 0.7)
.attr("r", 4)
})
/////////////////////// WORLD MAP ////////////////////////////
var width = window.innerWidth,
height = window.innerHeight,
centered,
clicked_point;
var projection = d3.geoMercator()
// .translate([width / 2.2, height / 1.5]);
var plane_path = d3.geoPath()
.projection(projection);
var svg_map = d3.select("#graphic").append("svg")
.attr("width", 900)
.attr("height", 550)
.attr("class", "map");
var g = svg_map.append("g");
var path = d3.geoPath()
.projection(projection);
// load and display the World
d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function(error, topology) {
g.selectAll("path")
.data(topojson.feature(topology, topology.objects.countries)
.features)
.enter()
.append("path")
.attr("d", path)
;
});
path {
stroke: #2296F3;
stroke-width: 0.25px;
fill: #f8f8ff;
}
body {
font-family: "Arial", sans-serif;
}
.bar {
fill: #5f89ad;
}
.axis {
font-size: 13px;
}
.axis path,
.axis line {
fill: none;
display: none;
}
.label {
font-size: 13px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Simple Bar chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.js"></script>
<script src="https://unpkg.com/topojson-client@3"></script>
<script src="https://unpkg.com/topojson-client@3"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
</head>
<body>
<div id="graphic"></div>
</body>
</html>
最佳答案
此功能基本上可以满足您的需求。用例略有不同,因为它是在使用新数据重新绘制 map 后调用的,但结果是相同的。 map 中会出现一组数据, map 会缩放到其上呈现的点的范围。
recenter() {
console.log('recentering')
try {
// get a handle to the transform object, and reset it to the
// zoom identity (resets to zoom out all the way)
let ztrans = this.zoom.transform
let t = this.d3.zoomIdentity
this.svg.transition().duration(DURATION*2).call(ztrans,t)
// get the object and measurements to determine the virtual
// "bounding" rectangle around the directional extremes of sites
// i.e., north (topmost), east (rightmost), etc
let circles = this.g.selectAll('a > circle')
let data = circles.data()
let long = data.map(o => parseFloat(o.Longitude))
let lat = data.map(o => parseFloat(o.Latitude))
let rightmost = this.d3.max(long)
let leftmost = this.d3.min(long)
let topmost = this.d3.max(lat)
let bottommost = this.d3.min(lat)
// convert the lat/long to points in the projection
let lt = this.projection([leftmost,topmost])
let rb = this.projection([rightmost,bottommost])
// calc the gaps (east - west, south - north) in pixels
let g = rb[0]-lt[0]
let gh = rb[1]-lt[1]
// get the dimensions of the panel in which the map sits
let w = this.svg.node().parentElement.getBoundingClientRect().width
let h = this.svg.node().parentElement.getBoundingClientRect().height
// the goal here is to move the halfway point between leftmost and rightmost
// on the projection sites to the halfway point of the panel in which the
// svg element resides, and same for 'y'
// the scale is the value 90% of the scale factor of either east-west to width
// or south-north to height, whichever is greater
let neoScale = 0.9 / Math.max(g/w, gh/h)
// now recalculate what will be the difference between the current
// center and the center of the scaled virtual rectangle
// this finds the difference between the centers
// the new center of the scaled rectangle is the average of the left and right
// or top and bottom points
let neoX = w/2 - (neoScale * ((lt[0]+rb[0])/2))
let neoY = h/2 - (neoScale * ((lt[1]+rb[1])/2))
// TRANSLATE FIRST! then scale.
t = this.d3.zoomIdentity.translate(neoX,neoY).scale(neoScale)
this.svg.transition().duration(DURATION*2).call(ztrans, t)
}
catch(e)
{
console.log(e)
}
更新
我 fork 了 op 的 fiddle ,并创建了一个 working fiddle具有以下变化:
recenter
函数最初是用 d3 v4 编写的。 op 的 fiddle 在 v3 中。新的 fiddle 使用 v4。recenter
函数是从另一个项目“按原样”复制和粘贴的。它在 fiddle 中进行了修改,以说明局部变量名称和范围。此外,点不会在第一次点击栏时呈现,但会在后续点击时呈现。
关于javascript - D3 : Map Zoom scaled by points,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60214308/
我在学习如何缩放方面经历了一段痛苦的时光。为了学习,我一直在尝试制作树状图缩放。我正在使用这个 jsfiddle 示例( http://jsfiddle.net/6kEpp/1/ )并尝试将其应用于没
使用 orbitcontrols.js(带有 THREE.js),我想在代码中实现与旋转鼠标滚轮相同的效果。例如,我想调用 camera.zoomIn() 之类的东西,让它向目标移动一段设定的距离。有
我已经创建了 map ,如 this link 所示并且运行良好。 但问题是,它只能以一种方式放大(只会变大)。我怎样才能让它以任何一种方式工作? 可能就像我们在 google map 上(加号 -
我正在寻找与 autocad ... 或 solidworks 类似的体验 基本上是内容大小(保持宽高比)Xsize * Ysize 并放大特定区域 并且我已经将 ruby/rails 作为我选择
在bootstrap的重置部分有一个 .clearfix { *zoom: 1; } 请问这里*zoom 和 zoom 有什么区别? 我很感激任何回答。 最佳答案 这是一个 css hack,这意味着
我在单独的子图中有 3 轴加速度计时间序列数据(t,x,y,z)的图,我想一起缩放。也就是说,当我在一个图上使用“缩放到矩形”工具时,当我释放鼠标时,所有 3 个图都会一起缩放。 以前,我只是使用不同
有没有一种简单的方法可以在页面刚加载时默认自动查看 Mapbox map 的所有标记...?这是我的 map :http://www.geometry.be/urbanmaestro/v7/非常感谢您
我已经使用 UIWebView 在 html 文件中设置了以下视口(viewport)标签。 现在,当用户选择时,我得到如图所示的效果。我想禁用此效果但仍然可以放大。 尝试将 UIWebView 的
我现在使用 Core-plot 进行 iPhone 图表开发。但它有一些我无法达到的要求。 我现在使用CorePlot 0.4,示例代码AAPLot来开发 请看下面的图片,然后你就会知道我的问题是什么
最新版本的 Google 地球附带了一项名为“缩放时自动倾斜”的功能。如果启用,Google Earth 会在您拉近表面时自动将相机倾斜到地平线。可以从 GUI 中禁用此功能(首选项 -> 导航选项卡
我找到了使用 rel="smallImage:image1.jpg" 等链接更改缩放图像的方法,但我是在运行时创建图像并将其添加到页面,所以页面首次加载时链接不会存在(这似乎需要存在)。当我在运行时生
我正在使用 ImageView 支持缩放。现在我正在扩展 ImageView 以便我可以在 canvas 上绘图。目前我有 setImageResource 设置一个 drawable 和在 onDr
在缩放行为上手动设置比例后,如何触发缩放事件? var zoom = d3.behavior.zoom() .scaleExtent([0.5, 4]) .on('zoom', onz
我有这个简单的测试代码: ul{ float:left; margin:0; list-style:none; paddi
我正在尝试实现一个具有以下外观的移动网站: 一个固定的标题 可滚动、可缩放的内容 首次加载页面时内容缩小 我一直在试验 IScroll 4,结果似乎不错,但有一个问题我找不到解决办法。我页面的内容是用
嗨,我是 iOS 初学者,在我的项目中,我以编程方式添加了一个 Collection View ,并且已成功添加。 我的要求是,当我单击 UICollectionViewCell 时,它将像下面的第二
遵循此处的建议:How to disable double click zoom for d3.behavior.zoom? 我在页面加载时禁用了双击缩放行为: https://bl.ocks.org
当用户使用鼠标滚轮滚入和滚出时,您可以调整缩放速度吗? 我的理解是 zoom.on (https://github.com/mbostock/d3/wiki/Zoom-Behavior#wiki-on
关于 css 样式和在浏览器中放大和缩小,我遇到了既有趣又奇怪的问题。 我创建了一个 Material ui 卡片,点击它时背景颜色会随着动画而改变。 动画效果很好,但如果您放大或缩小页面,浏览器会在
我将 JQTouch 用于 iPhone 应用程序。 JQtouch 默认情况下禁用捏合和缩放页面的可能性。对于一页(包含大图像),我需要启用捏合和缩放功能。这很容易: var viewport =
我是一名优秀的程序员,十分优秀!