使用正方形表示地图中的计数

Posted

技术标签:

【中文标题】使用正方形表示地图中的计数【英文标题】:Using squares to represent counts in a map 【发布时间】:2017-01-30 04:17:17 【问题描述】:

这可能是一个简单的问题,但我在 d3 中有一张地图,我想将事件计数表示为正方形。

这是我想要的示例 png:

它们在图片中没有完美对齐,但假设我有一个 JSON:

[
    city:'New York', count:3,
    city:'Washington, D.C.', count:1,
    city:'Austin', count:5,
    city:'Havana', count:8
] 

我想用正方形表示的计数,最好以有序的方式聚集。

我对此摸不着头脑——我想也许力导向图可以解决问题?我也看过这个:http://bl.ocks.org/XavierGimenez/8070956 和这个:http://bl.ocks.org/mbostock/4063269,这可能会让我很接近。

对于上下文和设置(我不需要帮助制作地图,只是为了分享),这是我用于该项目的存储库:https://github.com/alex2awesome/custom-map,它显示了我表示计数的旧方式(以每个城市为中心的圆的半径)。

【问题讨论】:

另一个可能的途径可能是使用treemap()? bl.ocks.org/mbostock/4063582 至少有人知道这可能叫什么吗?我什至不知道现在该谷歌什么——尝试d3 layout pack rectangles 并没有让我走得太远。 使每个计数组成为一个大小相等的分区可能是有希望的:animateddata.co.uk/slides/d3-layouts/partition.html。计算上可行吗? 也超级有前途:bl.ocks.org/mbostock/1009139 Mike Bostock 的方格 【参考方案1】:

至少有人知道这可能叫什么吗?

这个在dataviz中的技术名称是pictogram

这是绘制矩形的通用代码,您必须根据需要更改某些部分。最重要的部分是计算矩形xy 的位置,使用modulo operator。

首先,让我们设置每个矩形的初始位置和大小。您必须根据您的坐标进行设置。

var positionX = 5;
var positionY = 5;
var size = 5;

然后,让我们设置你想要多少个矩形(在你的代码中,这将是d.count):

var count = 15;
var gridSize = Math.ceil(Math.sqrt(count));
var data = d3.range(count);

根据计数,我们设置gridSize(只是平方根)和data

现在我们绘制矩形:

var rects = svg.selectAll(".rects")
    .data(data)
    .enter()
    .append("rect");

rects.attr("width", size)
    .attr("height", size)
    .attr("x", function(d,i) return positionX + (i%gridSize)*(size*1.1))
    .attr("y", function(d,i) return positionY + (Math.floor((i/gridSize)%gridSize))*(size*1.1) )
    .attr("fill", "red");

这是一个有效的 sn-p,使用 15 作为计数(4、9、16、25 等会给你一个完美的正方形)。更改count 看看它是如何适应的:

var svg = d3.select("body")
	.append("svg")
	.attr("width", 50)
	.attr("height", 50);
	
var count = 15;
var size = 5;
var positionX = 5;
var positionY = 5;
var gridSize = Math.ceil(Math.sqrt(count));
var data = d3.range(count);

var rects = svg.selectAll(".rects")
	.data(data)
	.enter()
	.append("rect");
	
rects.attr("width", size)
	.attr("height", size)
	.attr("x", function(d,i) return positionX + (i%gridSize)*(size*1.2))
	.attr("y", function(d,i) return positionY + (Math.floor((i/gridSize)%gridSize))*(size*1.2) )
	.attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

【讨论】:

我忘了说:xy 位置中的值“1.2”是矩形之间的空间(即它们大小的 20℅)。 感谢@gerardo,这很棒而且相对简单!有时我会沉迷于搜索库,以至于我没有考虑从头开始实现某些东西的机制 @GerardoFurtado var gridSize = Math.ceil(Math.sqrt(count)); 平方根背后的原因是什么 @alt255 因为我需要一个正方形来分配点。例如,有 15 个点,它给我们一个 4x4 的网格(4 是 Math.ceil(Math.sqrt(15))。例如,如果我们有 17 个点,它会给我们 5x5。

以上是关于使用正方形表示地图中的计数的主要内容,如果未能解决你的问题,请参考以下文章

岛屿问题--DFS问题

数学(容斥计数):LNOI 2016 方

Acwing 99 激光炸弹 (二维前缀和)

Acwing-99-激光炸弹(二维前缀和)

BZOJ1218 [HNOI2003]激光炸弹

BZOJ-1218-[HNOI2003]激光炸弹