gpt4 book ai didi

javascript - 在D3.JS的Choropleth map 上添加图例

转载 作者:行者123 更新时间:2023-11-29 10:57:31 25 4
gpt4 key购买 nike

我正在D3.js中构建一个Choropleth map 。

考虑到量化标度将值分为几个离散的存储桶,并根据其所属的存储桶为每个存储桶分配颜色。可以从下面的代码中获得,我决定传递一种颜色数组,因为知道scale函数会为每种颜色创建一个存储桶。

var color = d3.scaleQuatize().range([
'rgb(247,251,255)', 'rgb(222,235,247)', 'rgb(198,219,239)',
'rgb(158,202,225)', 'rgb(107,174,214)', 'rgb(66,146,198)',
'rgb(33,113,181)', 'rgb(8,81,156)', 'rgb(8,48,107)'
]);

当我打算基于scaleQuantize从数据创建的“存储桶”构建图例时,对如何执行此操作的任何建议都表示赞赏。

我要重现的传说是这个: https://beta.observablehq.com/@mbostock/d3-choropleth

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VI - Gonçalo Peres</title>

<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css"
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

</head>
<body>
<nav class="navbar navbar-default">
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
<a href="#">Contexto</a>
<a href="#">1.ª Codificação Visual</a>
<a href="#">2.ª Codificação Visual</a>
<a href="#">3.ª Codificação Visual</a>
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; Menu</span>
<br>
<br>
<div class="container">
<a class="navbar-brand" href="#"><img id="logo" src="img/logo.png"></a>
</div>
</nav>

<div id="intro">
<h2>1.ª Codificação Visual</h2>
<span>Lorem ipsum.</span><br>
<span>Lorem Ipsum.</span><br>
</div>
<div id="legenda">
<h4>Legenda</h4>
<span>Lorem ipsum.</span><br>
<span>Lorem ipsum.</span><br>
</div>
<div id="chart"></div>
<div id="buttons">
<button type="button" class="panning up"><i class="fa fa-arrow-up"></i></button>
<button type="button" class="panning down"><i class="fa fa-arrow-down"></i></button>
<button type="button" class="panning left"><i class="fa fa-arrow-left"></i></button>
<button type="button" class="panning right"><i class="fa fa-arrow-right"></i></button>
<button type="button" class="zooming in"><i class="fa fa-plus"></i></button>
<button type="button" class="zooming out"><i class="fa fa-minus"></i></button>
</div>

<div id="note">
<span>Gonçalo Peres | <b><a href="http://goncaloperes.com/" target="_blank">GoncaloPeres.com</a></b></span><br>
<span>Data from: <a href="https://public.enigma.com/datasets/u-s-department-of-agriculture-honey-production-2013/41cf2441-e96f-4113-a02f-402d167a9cd8" target="_blank">Enigma Public</a></span>
</div>

<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>

app.js
// Width and height
var chart_width = 800;
var chart_height = 600;
var color = d3.scaleQuantize().range([
'rgb(247,251,255)', 'rgb(222,235,247)', 'rgb(198,219,239)',
'rgb(158,202,225)', 'rgb(107,174,214)', 'rgb(66,146,198)',
'rgb(33,113,181)', 'rgb(8,81,156)', 'rgb(8,48,107)'
]);


//Navbar
function openNav() {
document.getElementById("mySidenav").style.width = "100%";
}

function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}


// Projection
var projection = d3.geoAlbersUsa()
.translate([ 0,0 ]);
var path = d3.geoPath( projection );
// .projection( projection );

// Create SVG
var svg = d3.select("#chart")
.append("svg")
.attr("width", chart_width)
.attr("height", chart_height);

var zoom_map = d3.zoom()
.scaleExtent([ 0.5, 3.0 ])
.translateExtent([
[ -1000, -500 ],
[ 1000, 500 ]
])
.on( 'zoom', function(){
// console.log( d3.event );
var offset = [
d3.event.transform.x,
d3.event.transform.y
];
var scale = d3.event.transform.k * 2000;

projection.translate( offset )
.scale( scale );

svg.selectAll( 'path' )
.transition()
.attr( 'd', path );

svg.selectAll( 'circle' )
.transition()
.attr( "cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr( "cy", function(d) {
return projection([d.lon, d.lat])[1];
});
});

var map = svg.append( 'g' )
.attr( 'id', 'map' )
.call( zoom_map )
.call(
zoom_map.transform,
d3.zoomIdentity
.translate( chart_width / 2, chart_height / 2 )
.scale( 1 )
);

map.append( 'rect' )
.attr( 'x', 0 )
.attr( 'y', 0 )
.attr( 'width', chart_width )
.attr( 'height', chart_height )
.attr( 'opacity', 0 );

// Data
d3.json( 'data/USDepartmentofAgriculture-HoneyProduction-2013_properties.json', function( honey_data ){
color.domain([
d3.min( honey_data, function(d){
return d.honey_producing_colonies;
}),
d3.max( honey_data, function(d){
return d.honey_producing_colonies;
})
]);

d3.json( 'data/us.json', function( us_data ){
us_data.features.forEach(function(us_e, us_i){
honey_data.forEach(function(h_e,h_i){
if( us_e.properties.name !== h_e.state ){
return null;
}

us_data.features[us_i].properties.average_price_per_pound = parseFloat(h_e.average_price_per_pound);
});
});

// console.log(us_data);

map.selectAll( 'path' )
.data( us_data.features )
.enter()
.append( 'path' )
.attr( 'd', path )
.attr( 'fill', function( d ){
var average_price_per_pound = d.properties.average_price_per_pound;
return average_price_per_pound ? color( average_price_per_pound ) : '#525252';
})
.attr( 'stroke', '#fff' )
.attr( 'stroke-width', 1 );

// draw_cities();
});
});

// function draw_cities(){
// d3.json( 'data/us-cities.json', function( city_data ){
// map.selectAll("circle")
// .data(city_data)
// .enter()
// .append( "circle" )
// .style( "fill", "#9D497A" )
// .style( "opacity", 0.8 )
// .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 Math.sqrt( parseInt(d.population) * 0.00005 );
// })
// .append( 'title' )
// .text(function(d){
// return d.city;
// });
// });
// }

d3.selectAll( '#buttons button.panning' ).on( 'click', function(){
var x = 0;
var y = 0;
var distance = 100;
var direction = d3.select( this ).attr( 'class' ).replace( 'panning ', '' );

if( direction === "up" ){
y += distance; // Increase y offset
}else if( direction === "down" ){
y -= distance; // Decrease y offset
}else if( direction === "left" ){
x += distance; // Increase x offset
}else if( direction === "right" ){
x -= distance; // Decrease x offset
}

map.transition()
.call( zoom_map.translateBy, x, y );
});

d3.selectAll( '#buttons button.zooming' ).on( 'click', function(){
var scale = 1;
var direction = d3.select(this).attr("class").replace( 'zooming ', '' );

if( direction === "in" ){
scale = 1.25;
}else if(direction === "out"){
scale = 0.75;
}

map.transition()
.call(zoom_map.scaleBy, scale);
});

style.css
#intro {
position: absolute;
top: 250px;
left: 125px;
width: 180px;
text-align: left;
color: #B5B5B5;
}

#intro h2{
font-family: Oswald;
font-size: 25px;
font-weight: 300;
text-align: center;
color: white;
-webkit-margin-before: 0.5em;
-webkit-margin-after: 0.3em;
}

#legenda {
position: absolute;
top: 250px;
right: 125px;
width: 180px;
text-align: left;
color: #B5B5B5;
}

#legenda h4{
font-family: Oswald;
font-size: 20px;
font-weight: 300;
text-align: center;
color: white;
-webkit-margin-before: 0.5em;
-webkit-margin-after: 0.3em;
}

body {
font-size: 11px;
font-weight: 400;
font-family: 'Open Sans', sans-serif;
text-align: center;
vertical-align: middle;
background: #111;
fill: white;
color: white;
cursor:default;
}

.navbar-brand {
height: 60px;
padding: 5px 0px;
}

#chart{
width: 800px;
height: 600px;
background-color: #111;
margin: 25px auto;
}
#buttons{
width: 800px;
margin: 25px auto;
text-align: center;
}
button{
background-color: white;
color: black;
width: 100px;
padding: 10px;
font-size: 20px;
text-align: center;
border: 0;
outline: 0;
transition: all .2s linear;
cursor: pointer;
}
button:hover{
background-color: #50B98C;
}

#note {
top: -10px;
left: 10px;
font-size: 12px;
font-weight: 300;
color: #6E6E6E;
text-align: center;
}

a {
color: #6E6E6E;
}


.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: black;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
text-align:center;
}

.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;

}

.sidenav a:hover{
color: #f1f1f1;
}

.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}

@media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}

最佳答案

通过使用以下命令更新d3.json的末尾来解决:

    const x = d3.scaleLinear()
.domain(d3.extent(color.domain()))
.rangeRound([600, 860]);

const g = svg.append("g")
.attr("transform", "translate(0,40)");

g.selectAll("rect")
.data(color.range().map(d => color.invertExtent(d)))
.enter().append("rect")
.attr("height", 8)
.attr("x", d => x(d[0]))
.attr("width", d => x(d[1]) - x(d[0]))
.attr("fill", d => color(d[0]));

g.append("text")
.attr("class", "caption")
.attr("x", x.range()[0])
.attr("y", -6)
.attr("fill", "#fff")
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text('Average Price per Pound (cents)');

g.call(d3.axisBottom(x)
.tickSize(13)
.tickFormat(( honey_data, function(d){
return d.average_price_per_pound;
}),)
.tickValues(color.range().slice(1).map(d => color.invertExtent(d)[0])))
.select(".domain")
.remove();

svg.append("g")
.selectAll("path")
.data(honey_data, function(d){
return d.average_price_per_pound;
})
.enter().append("path")
.attr("fill", d => color(d.average_price_per_pound))
.attr("d", path)
.append("title")
.text(d => (d.average_price_per_pound));

svg.append("path")
.datum(honey_data, function(d){
return d.average_price_per_pound;
})
.attr("fill", "none")
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr("d", path);

关于javascript - 在D3.JS的Choropleth map 上添加图例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54293177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com