D3的新手,所以我感谢您的耐心等待!我制作了一张地图,其中附加到城市坐标的圆圈的大小是.csv中的值。我还从Mike Bostock的一个例子中添加了点击缩放功能。
但是,放大时圈子不会调整大小。我不确定如何在放大和缩小时重新调整大小或重绘?
欢迎任何提示,示例或建议!这是我的代码:
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta charset='utf-8'>
<meta name="viewport" content='width=device-width, initial-scale=1.0'>
<title></title>
<style>
.tooltip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
</style>
<script>
function draw(geo_data) {
var margin = 20,
width = 1500 - margin,
height = 500 - margin;
var centered;
var svg = d3.select('#map')
.append('svg')
.attr('width', width + margin)
.attr('height', height + margin)
.append('g')
.attr('class', 'map');
var formatComma = d3.format(",")
var projection = d3.geoAlbersUsa();
var path = d3.geoPath().projection(projection);
var map = svg.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.attr('fill', 'rgba(253, 227, 167, 0.8)')
.attr('stroke', 'black')
.attr('stroke-width', 0.4)
.on('mouseover', function(d) {
return d3.select(this).attr('fill', 'rgba(149, 165, 166, 0.8)')
})
.on('mouseout', function() {
return d3.select(this).attr('fill', 'rgba(253, 227, 167, 0.8)')
})
// Why is this not working???
.on('click', function() {
return d3.select(this).attr('fill', 'rgba(149, 165, 166, 0.8)')
})
// Calls click-to-zoom function defined below.
.on('click', clicked);
var tooltip = svg.append('g')
.attr('class', tooltip);
tooltip.append('text')
.attr('x', 15)
.attr('class', 'tooltip')
.attr('dy', '1.2em')
.style('font-size', '1.5em')
.attr('font-weight', 'bold');
// Click-to-zoom function taken from Mike Bostock's code: https://bl.ocks.org/mbostock/2206590
function clicked(d) {
var x, y, k;
if (d && centered !== d) {
var centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = width / 2;
y = height / 2;
k = 1;
centered = null;
}
map.selectAll('path')
.classed('active', centered && function(d) {
return d === centered;
});
map.transition()
.duration(750)
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')scale(' + k + ')translate(' + -x + ',' + -y + ')')
.style('stroke-width', 1 / k + 'px');
}
d3.csv('top100cities.csv', function(error, data) {
// Converts strings in csv to integers so they can be used.
data.forEach(function(d) {
return d.guns = +d.guns;
})
// This returns the max number of guns.
var guns = data.map(function(d) {
return d.guns;
});
var guns_extent = d3.extent(data, function(d) {
return d.guns;
});
var radius = d3.scaleSqrt()
.domain(guns_extent)
.range([0, 50]);
svg.append('g')
.attr('class', 'bubble')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d) {
return projection([d.lon, d.lat])[0];
})
.attr('cy', function(d) {
return projection([d.lon, d.lat])[1];
})
.attr('r', function(d) {
return radius(d.guns);
})
.attr('fill', 'rgba(103, 65, 114, 0.5)')
.attr('stroke', 'black')
.on('mouseover', function(d) {
return d3.select(this).attr('fill', 'rgba(103, 65, 114, 0.8)');
tooltip.select('text').style('opacity', 1);
})
.on('mousemove', function(d) {
var xPos = d3.mouse(this)[0] - 15;
var yPos = d3.mouse(this)[1] - 55;
tooltip.attr('transform', 'translate(' + xPos + ',' + yPos + ')');
tooltip.select('text').style('opacity', 1);
tooltip.select('text').text(d.city + ', ' + d.state + ': ' + formatComma(d.guns));
})
.on('mouseout', function(d) {
tooltip.select('text').style('opacity', 0);
return d3.select(this).attr('fill', 'rgba(103, 65, 114, 0.5)');
});
});
};
</script>
</head>
<body>
<div id='map'></div>
<script>
d3.json('us_states.json', draw);
</script>
</body>
答案 0 :(得分:2)
您可以完成与地图完全相同的操作:
在clicked
功能中,在transform
项path
之后,您可以插入适用于circles
的以下转换:
svg.selectAll('circle')
.transition()
.duration(750)
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')scale(' + k + ')translate(' + -x + ',' + -y + ')')
.style('stroke-width', 1 / k + 'px');
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta charset='utf-8'>
<meta name="viewport" content='width=device-width, initial-scale=1.0'>
<title></title>
<style>
.tooltip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
</style>
<script>
function draw(geo_data) {
var margin = 20,
width = 1500 - margin,
height = 500 - margin;
var centered;
var svg = d3.select('#map')
.append('svg')
.attr('width', width + margin)
.attr('height', height + margin)
.append('g')
.attr('class', 'map');
var formatComma = d3.format(",")
var projection = d3.geoAlbersUsa();
var path = d3.geoPath().projection(projection);
var map = svg.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.attr('fill', 'rgba(253, 227, 167, 0.8)')
.attr('stroke', 'black')
.attr('stroke-width', 0.4)
.on('mouseover', function(d) {
return d3.select(this).attr('fill', 'rgba(149, 165, 166, 0.8)')
})
.on('mouseout', function() {
return d3.select(this).attr('fill', 'rgba(253, 227, 167, 0.8)')
})
// Why is this not working???
.on('click', function() {
return d3.select(this).attr('fill', 'rgba(149, 165, 166, 0.8)')
})
// Calls click-to-zoom function defined below.
.on('click', clicked);
var tooltip = svg.append('g')
.attr('class', tooltip);
tooltip.append('text')
.attr('x', 15)
.attr('class', 'tooltip')
.attr('dy', '1.2em')
.style('font-size', '1.5em')
.attr('font-weight', 'bold');
// Click-to-zoom function taken from Mike Bostock's code: https://bl.ocks.org/mbostock/2206590
function clicked(d) {
var x, y, k;
if (d && centered !== d) {
var centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = width / 2;
y = height / 2;
k = 1;
centered = null;
}
map.selectAll('path')
.classed('active', centered && function(d) {
return d === centered;
});
map.transition()
.duration(750)
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')scale(' + k + ')translate(' + -x + ',' + -y + ')')
.style('stroke-width', 1 / k + 'px');
svg.selectAll('circle')
.transition()
.duration(750)
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')scale(' + k + ')translate(' + -x + ',' + -y + ')')
.style('stroke-width', 1 / k + 'px');
}
d3.csv('https://raw.githubusercontent.com/dieterholger/US-Gun-Manufacturing-Interactive/master/top100cities.csv', function(error, data) {
// Converts strings in csv to integers so they can be used.
data.forEach(function(d) {
return d.guns = +d.guns;
})
// This returns the max number of guns.
var guns = data.map(function(d) {
return d.guns;
});
var guns_extent = d3.extent(data, function(d) {
return d.guns;
});
var radius = d3.scaleSqrt()
.domain(guns_extent)
.range([0, 50]);
svg.append('g')
.attr('class', 'bubble')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d) {
return projection([d.lon, d.lat])[0];
})
.attr('cy', function(d) {
return projection([d.lon, d.lat])[1];
})
.attr('r', function(d) {
return radius(d.guns);
})
.attr('fill', 'rgba(103, 65, 114, 0.5)')
.attr('stroke', 'black')
.on('mouseover', function(d) {
return d3.select(this).attr('fill', 'rgba(103, 65, 114, 0.8)');
tooltip.select('text').style('opacity', 1);
})
.on('mousemove', function(d) {
var xPos = d3.mouse(this)[0] - 15;
var yPos = d3.mouse(this)[1] - 55;
tooltip.attr('transform', 'translate(' + xPos + ',' + yPos + ')');
tooltip.select('text').style('opacity', 1);
tooltip.select('text').text(d.city + ', ' + d.state + ': ' + formatComma(d.guns));
})
.on('mouseout', function(d) {
tooltip.select('text').style('opacity', 0);
return d3.select(this).attr('fill', 'rgba(103, 65, 114, 0.5)');
});
});
};
</script>
</head>
<body>
<div id='map'></div>
<script>
d3.json('https://raw.githubusercontent.com/dieterholger/US-Gun-Manufacturing-Interactive/master/us_states.json', draw);
</script>
</body>
&#13;