我希望将鼠标悬停在地图上的国家/地区时显示多个值(价格,点数)。例如,当我将鼠标悬停在英国时,我希望同时看到平均价格和积分。但我只能用d.properties.name
显示其中一个。
代码取自here.
我对代码的更改:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
#canvas {
}
#canvas-svg {
}
.land {
fill: #222;
}
.boundary {
fill: none;
stroke: #fff;
stroke-width: 1px;
}
#tooltip-container {
position: absolute;
background-color: #fff;
color: #000;
padding: 10px;
border: 1px solid;
display: none;
}
.tooltip_key {
font-weight: bold;
}
.tooltip_value {
margin-left: 20px;
float: right;
}
</style>
<div id="tooltip-container"></div>
<div id="canvas-svg"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.1.0/topojson.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
d3.csv("MyData130.csv", function(err, data) {
var config = {"data0":"country","data1":"price", "data2": "points",
"label0":"label 0","label1":"label 1","label2":"label 2", "color0":"#99ccff","color1":"#0050A1", "color3":"#4398ef",
"width":900,"height":900}
var width = config.width,
height = config.height;
var COLOR_COUNTS = 9;
function Interpolate(start, end, steps, count) {
var s = start,
e = end,
final = s + (((e - s) / steps) * count);
return Math.floor(final);
}
function Color(_r, _g, _b) {
var r, g, b;
var setColors = function(_r, _g, _b) {
r = _r;
g = _g;
b = _b;
};
setColors(_r, _g, _b);
this.getColors = function() {
var colors = {
r: r,
g: g,
b: b
};
return colors;
};
}
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function valueFormat(d) {
if (d > 1000000000) {
return Math.round(d / 1000000000 * 10) / 10 + "B";
} else if (d > 1000000) {
return Math.round(d / 1000000 * 10) / 10 + "M";
} else if (d > 1000) {
return Math.round(d / 1000 * 10) / 10 + "K";
} else {
return d;
}
}
var COLOR_FIRST = config.color0, COLOR_LAST = config.color1;
var rgb = hexToRgb(COLOR_FIRST);
var COLOR_START = new Color(rgb.r, rgb.g, rgb.b);
rgb = hexToRgb(COLOR_LAST);
var COLOR_END = new Color(rgb.r, rgb.g, rgb.b);
var startColors = COLOR_START.getColors(),
endColors = COLOR_END.getColors();
var colors = [];
for (var i = 0; i < COLOR_COUNTS; i++) {
var r = Interpolate(startColors.r, endColors.r, COLOR_COUNTS, i);
var g = Interpolate(startColors.g, endColors.g, COLOR_COUNTS, i);
var b = Interpolate(startColors.b, endColors.b, COLOR_COUNTS, i);
colors.push(new Color(r, g, b));
}
var MAP_KEY = config.data0;
var MAP_VALUE = config.data1;
var MAP_KEY2 = config.data0;
var MAP_VALUE2 = config.data2;
var projection = d3.geo.mercator()
.scale((width + 1) / 2 / Math.PI)
.translate([width / 2, height / 2])
.precision(.1);
var path = d3.geo.path()
.projection(projection);
var graticule = d3.geo.graticule();
var svg = d3.select("#canvas-svg").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
var valueHash = {};
function log10(val) {
return Math.log(val);
}
data.forEach(function(d) {
valueHash[d[MAP_KEY]] = +d[MAP_VALUE];
valueHash[d[MAP_KEY2]] = +d[MAP_VALUE2];
});
var quantize = d3.scale.quantize()
.domain([0, 1.0])
.range(d3.range(COLOR_COUNTS).map(function(i) { return i }));
quantize.domain([d3.min(data, function(d){
return (+d[MAP_VALUE], +d[MAP_VALUE2]) }),
d3.max(data, function(d){
return (+d[MAP_VALUE], +d[MAP_VALUE2])})]);
d3.json("https://s3-us-west-2.amazonaws.com/vida-public/geo/world-topo-min.json", function(error, world) {
var countries = topojson.feature(world, world.objects.countries).features;
svg.append("path")
.datum(graticule)
.attr("class", "choropleth")
.attr("d", path);
var g = svg.append("g");
g.append("path")
.datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
.attr("class", "equator")
.attr("d", path);
var country = g.selectAll(".country").data(countries);
country.enter().insert("path")
.attr("class", "country")
.attr("d", path)
.attr("id", function(d,i) { return d.id; })
.attr("title", function(d) { return d.properties.name; })
.style("fill", function(d) {
if ((valueHash[d.properties.name])) {
valueHash[d.properties.value] = valueHash[d[MAP_KEY2]];
var c = quantize((valueHash[d.properties.name]) );
var color = colors[c].getColors();
return "rgb(" + color.r + "," + color.g +
"," + color.b + ")";
} else {
return "#ccc";
}
})
.on("mousemove", function(d) {
var html = "";
html += "<div class=\"tooltip_kv\">";
html += "<span class=\"tooltip_key\">";
html += d.properties.name + "<br/>";
// html += d.properties.value;
html += "</span>";
html += "<span class=\"tooltip_value\">";
html += (valueHash[d.properties.name] ? "Average Price: " + valueFormat(valueHash[d.properties.name]) +" $"+
"<br/>" + "Average Points: " + valueFormat(valueHash[d.properties.value]) : "");
html += "";
html += "</span>";
html += "</div>";
$("#tooltip-container").html(html);
$(this).attr("fill-opacity", "0.8");
$("#tooltip-container").show();
var coordinates = d3.mouse(this);
var map_width = $('.choropleth')[0].getBoundingClientRect().width;
if (d3.event.pageX < map_width / 2) {
d3.select("#tooltip-container")
.style("top", (d3.event.layerY + 15) + "px")
.style("left", (d3.event.layerX + 15) + "px");
} else {
var tooltip_width = $("#tooltip-container").width();
d3.select("#tooltip-container")
.style("top", (d3.event.layerY + 15) + "px")
.style("left", (d3.event.layerX - tooltip_width - 30) + "px");
}
})
.on("mouseout", function() {
$(this).attr("fill-opacity", "1.0");
$("#tooltip-container").hide();
});
g.append("path")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "boundary")
.attr("d", path);
svg.attr("height", config.height * 2.2 / 3);
});
d3.select(self.frameElement).style("height", (height * 2.3 / 3) + "px");
});
</script>
&#13;
CSV文件:
country price points
1 Azerbaijan 24.59322034 88.63492063
2 Argentina 24.51011715 86.71026316
3 Armenia 14.5 87.5
4 Australia 35.43766347 88.58050666
5 Austria 30.76277242 90.10134529
6 Bosnia and Herzegovina 12.5 86.5
7 Brazil 23.76595745 84.67307692
8 Bulgaria 14.64539007 87.93617021
9 Canada 35.71259843 89.36964981
10 Chile 20.78645833 86.49351521
&#13;
我非常愿意自己实施,但我不知道如何做到这一点。我用Google搜索了很多次,但找不到任何有用的东西。也许有人有想法或给我一些提示,所以我可以做得对。
答案 0 :(得分:1)
几个问题:
valueHash[d[MAP_KEY]] = +d[MAP_VALUE]; valueHash[d[MAP_KEY2]] = +d[MAP_VALUE2];
我在价格和点数上使用了不同的哈希值,但我建议您使用更好的数据结构来保存两者。这是更正后的代码:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
#canvas {
}
#canvas-svg {
}
.land {
fill: #222;
}
.boundary {
fill: none;
stroke: #fff;
stroke-width: 1px;
}
#tooltip-container {
position: absolute;
background-color: #fff;
color: #000;
padding: 10px;
border: 1px solid;
display: none;
}
.tooltip_key {
font-weight: bold;
}
.tooltip_value {
margin-left: 20px;
float: right;
}
</style>
<div id="tooltip-container"></div>
<div id="canvas-svg"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.1.0/topojson.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
d3.tsv("dat.tsv", function(err, data) {
var config = {"data0":"country","data1":"price", "data2": "points",
"label0":"label 0","label1":"label 1","label2":"label 2", "color0":"#99ccff","color1":"#0050A1", "color3":"#4398ef",
"width":900,"height":900}
var width = config.width,
height = config.height;
var COLOR_COUNTS = 9;
function Interpolate(start, end, steps, count) {
var s = start,
e = end,
final = s + (((e - s) / steps) * count);
return Math.floor(final);
}
function Color(_r, _g, _b) {
var r, g, b;
var setColors = function(_r, _g, _b) {
r = _r;
g = _g;
b = _b;
};
setColors(_r, _g, _b);
this.getColors = function() {
var colors = {
r: r,
g: g,
b: b
};
return colors;
};
}
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function valueFormat(d) {
if (d > 1000000000) {
return Math.round(d / 1000000000 * 10) / 10 + "B";
} else if (d > 1000000) {
return Math.round(d / 1000000 * 10) / 10 + "M";
} else if (d > 1000) {
return Math.round(d / 1000 * 10) / 10 + "K";
} else {
return d;
}
}
var COLOR_FIRST = config.color0, COLOR_LAST = config.color1;
var rgb = hexToRgb(COLOR_FIRST);
var COLOR_START = new Color(rgb.r, rgb.g, rgb.b);
rgb = hexToRgb(COLOR_LAST);
var COLOR_END = new Color(rgb.r, rgb.g, rgb.b);
var startColors = COLOR_START.getColors(),
endColors = COLOR_END.getColors();
var colors = [];
for (var i = 0; i < COLOR_COUNTS; i++) {
var r = Interpolate(startColors.r, endColors.r, COLOR_COUNTS, i);
var g = Interpolate(startColors.g, endColors.g, COLOR_COUNTS, i);
var b = Interpolate(startColors.b, endColors.b, COLOR_COUNTS, i);
colors.push(new Color(r, g, b));
}
var MAP_KEY = config.data0;
var MAP_VALUE = config.data1;
var MAP_KEY2 = config.data0;
var MAP_VALUE2 = config.data2;
var projection = d3.geo.mercator()
.scale((width + 1) / 2 / Math.PI)
.translate([width / 2, height / 2])
.precision(.1);
var path = d3.geo.path()
.projection(projection);
var graticule = d3.geo.graticule();
var svg = d3.select("#canvas-svg").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
var valueHash = {};
function log10(val) {
return Math.log(val);
}
data.forEach(function(d) {
valueHash[d[MAP_KEY]] = +d[MAP_VALUE];
});
var pointsHash = {};
data.forEach(function(d) {
pointsHash[d[MAP_KEY2]] = +d[MAP_VALUE2];
});
var quantize = d3.scale.quantize()
.domain([0, 1.0])
.range(d3.range(COLOR_COUNTS).map(function(i) { return i }));
quantize.domain([d3.min(data, function(d){
return (+d[MAP_VALUE], +d[MAP_VALUE2]) }),
d3.max(data, function(d){
return (+d[MAP_VALUE], +d[MAP_VALUE2])})]);
d3.json("https://s3-us-west-2.amazonaws.com/vida-public/geo/world-topo-min.json", function(error, world) {
var countries = topojson.feature(world, world.objects.countries).features;
svg.append("path")
.datum(graticule)
.attr("class", "choropleth")
.attr("d", path);
var g = svg.append("g");
g.append("path")
.datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
.attr("class", "equator")
.attr("d", path);
var country = g.selectAll(".country").data(countries);
country.enter().insert("path")
.attr("class", "country")
.attr("d", path)
.attr("id", function(d,i) { return d.id; })
.attr("title", function(d) { return d.properties.name; })
.style("fill", function(d) {
if ((valueHash[d.properties.name])) {
valueHash[d.properties.value] = valueHash[d[MAP_KEY2]];
var c = quantize((valueHash[d.properties.name]) );
var color = colors[c].getColors();
return "rgb(" + color.r + "," + color.g +
"," + color.b + ")";
} else {
return "#ccc";
}
})
.on("mousemove", function(d) {
debugger;
var html = "";
html += "<div class=\"tooltip_kv\">";
html += "<span class=\"tooltip_key\">";
html += d.properties.name + "<br/>";
// html += d.properties.value;
html += "</span>";
html += "<span class=\"tooltip_value\">";
html += (valueHash[d.properties.name] ? "Average Price: " + valueFormat(valueHash[d.properties.name]) +" $"+
"<br/>" + "Average Points: " + valueFormat(pointsHash[d.properties.name]) : "");
html += "";
html += "</span>";
html += "</div>";
$("#tooltip-container").html(html);
$(this).attr("fill-opacity", "0.8");
$("#tooltip-container").show();
var coordinates = d3.mouse(this);
var map_width = $('.choropleth')[0].getBoundingClientRect().width;
if (d3.event.pageX < map_width / 2) {
d3.select("#tooltip-container")
.style("top", (d3.event.layerY + 15) + "px")
.style("left", (d3.event.layerX + 15) + "px");
} else {
var tooltip_width = $("#tooltip-container").width();
d3.select("#tooltip-container")
.style("top", (d3.event.layerY + 15) + "px")
.style("left", (d3.event.layerX - tooltip_width - 30) + "px");
}
})
.on("mouseout", function() {
$(this).attr("fill-opacity", "1.0");
$("#tooltip-container").hide();
});
g.append("path")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "boundary")
.attr("d", path);
svg.attr("height", config.height * 2.2 / 3);
});
d3.select(self.frameElement).style("height", (height * 2.3 / 3) + "px");
});
</script>
no country price points
1 Azerbaijan 24.59322034 88.63492063
2 Argentina 24.51011715 86.71026316
3 Armenia 14.5 87.5
4 Australia 35.43766347 88.58050666
5 Austria 30.76277242 90.10134529
6 Bosnia and Herzegovina 12.5 86.5
7 Brazil 23.76595745 84.67307692
8 Bulgaria 14.64539007 87.93617021
9 Canada 35.71259843 89.36964981
10 Chile 20.78645833 86.49351521