Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用D3.js创建人口金字塔_Javascript_D3.js_Population_Census - Fatal编程技术网

Javascript 使用D3.js创建人口金字塔

Javascript 使用D3.js创建人口金字塔,javascript,d3.js,population,census,Javascript,D3.js,Population,Census,我需要用D3.js制作一个经典的人口金字塔。类似于此图像的内容: 我发现了一些看起来非常好的例子,但它们比我要寻找的要复杂。有谁知道一个好的简单的例子,我可以看看吗?有什么建议吗?我是否应该制作两个相邻的条形图,每个性别组一个?制作这样的可视化效果的关键是在开始绘制任何东西之前,先花大量时间设置布局 当你需要为你的星图制作刻度和坐标时,有一些关键的测量方法可以让你的生活变得更加轻松。然后,您可以使用带有翻译的元素,以便在图表的每个“部分”中,您可以使用本地坐标 目标是创建两个镜像区域,如下所示

我需要用D3.js制作一个经典的人口金字塔。类似于此图像的内容:


我发现了一些看起来非常好的例子,但它们比我要寻找的要复杂。有谁知道一个好的简单的例子,我可以看看吗?有什么建议吗?我是否应该制作两个相邻的条形图,每个性别组一个?

制作这样的可视化效果的关键是在开始绘制任何东西之前,先花大量时间设置布局

当你需要为你的星图制作刻度和坐标时,有一些关键的测量方法可以让你的生活变得更加轻松。然后,您可以使用带有翻译的
元素,以便在图表的每个“部分”中,您可以使用本地坐标

目标是创建两个镜像区域,如下所示:

var width = 400,
    height = 300;

var margin = {
  top: 20,
  right: 10
  bottom: 40,
  left: 10
};

var svg = d3.select('body').append('svg')
  .attr('width', margin.left + width + margin.right)
  .attr('height', margin.top + height + margin.bottom)
  .append('g')
    .attr('class', 'inner-region')
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

这将允许您在两个区域之间共享相同的x和y维度比例

要定义这些区域,您可以首先为svg内部的页边距设置一些值,然后创建一个位于这些页边距内的组。这是d3可视化中的一种常见做法,如果您还不熟悉它,那么现在是学习的好时机。它通常看起来像这样:

var width = 400,
    height = 300;

var margin = {
  top: 20,
  right: 10
  bottom: 40,
  left: 10
};

var svg = d3.select('body').append('svg')
  .attr('width', margin.left + width + margin.right)
  .attr('height', margin.top + height + margin.bottom)
  .append('g')
    .attr('class', 'inner-region')
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
这是一个很好的实践,因为它允许您在svg文档中为轴标记、标签和标题留出空间,而不必在定位可视化本身的部分时考虑到空间。然后,如果您发现需要更多的空间,您可以只调整代码顶部的一个值,而不是重新定位整个图表

其他重要的点是两个y轴的x坐标。换句话说,男性和女性的人口为零的点(如下红线所示)。这将是与内部区域中心线的设定距离(如下蓝色线所示):

可以将中间页边距特性添加到先前创建的页边距对象中,以引用此值:

margin.middle = 28;
您需要创建变量来存储上面两条红线的位置。现在,让我们把它们称为
点A
(男性人口零线的x坐标)和
点B
(女性人口的对应点)

一旦设置了这些点,事情就变得简单多了,因为您可以简单地将这些值插入到svg转换中,以将创建的对象转换到这些位置

最棘手的部分是两个中心y轴,它们共享一组标签。为此,您需要掌握如何
d3.svg.axis()
创建文本标签,以及可以操作哪些属性。为此,需要了解四个重要特性:

  • 轴。定向(方向)
    指定记号从轴中出来的方向。在这种情况下,这会有点混淆,因为我们希望记号指向中心,因此左轴将具有
    .orient('right')
    ,右轴将具有
    .orient('left')

  • 轴。tickSize(内部、外部)
    设置从轴中引出的记号标记的长度(以svg为单位)。“外部”标记是轴端点处的标记,在这种情况下可以设置为
    0
    ,因为我们使用的是带范围带的顺序标度,因此端点不表示值。为内部刻度选择一个小值,在本例中,我将使用
    4

  • 轴。滴答声填充(padding)
    设置标签文本的文本定位点距滴答声标记末端的距离。我们希望将文本定位点放置在图像的中心,即两个轴之间。由于我们已经知道中间边距(从中心线到每个轴的距离)和
    tickSize
    (记号的长度),我们可以通过取这两个值的差来将它们放在中心:
    .tickPadding(margin.middle-4)

  • 轴。勾号格式(格式)
    指定勾号标签的格式。可以将其设置为空字符串以从其中一个轴上删除勾号标签,这样就不会发生重叠:
    .tickFormat(“”)

  • 因此,两个y轴的定义如下:

    var yAxisLeft = d3.svg.axis()
      .scale(yScale)
      .orient('right')
      .tickSize(4,0)
      .tickPadding(margin.middle - 4);
    
    var yAxisRight = d3.svg.axis()
      .scale(yScale)
      .orient('left')
      .tickSize(4,0)
      .tickFormat('');
    
    然后,在实际绘制左y轴时,选择其
    元素,并将文本定位点设置为
    中间
    ,使其以定位点为中心:

    .call(yAxisLeft)
      .selectAll('text')
      .style('text-anchor', 'middle');
    
    这是一个使用一些人为数据的完整图表的简单示例。我试着尽可能多地对总体结构进行评论,以便于理解。我还制作了一个
    translation(x,y)
    函数,使每个平移的x和y坐标比使用字符串连接时更容易识别。您可以在脚本的底部找到它的定义


    我希望这能有所帮助,如果您对具体细节有任何疑问,请告诉我。

    听起来两个条形图并排是最简单的开始方式。哇!谢谢你的回答。如果我有问题,我会告诉你。你如何在原始图形中添加代表“圣安东尼奥”人口的线条?你可以用与彩色线条相同的方式制作清晰的线条,只需将填充设置为“透明”并进行笔划。嗨,杰森利,我发布了这个问题,这是这个人口金字塔的一个变体。你能看一下吗?@jshanley回答得很好。