如何对2个对象属性的D3堆叠条形图进行排序

zf2sa74q  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(157)

我是一个使用D3的新手,已经创建了一个基于https://observablehq.com/@d3/stacked-horizontal-bar-chart的堆叠水平条形图。
这是我的图表:

我目前能够通过升序和降序对图表进行排序。我现在需要做的是首先按y轴标签的字母顺序对图表进行排序,然后按x轴上的值升序排序,我不知道如何做到这一点。
图表需要看起来像这样:

其中,图表首先按y轴上的刻度名称按字母顺序排序,然后按x轴上的值按降序或升序排序。
这是我用来生成图表并按升序/降序排序的代码:

chartGenerate = stackedBarChart(pandas, 
  {
    x: d => d.value,
    y: d => d.scale,
    z: d => d.key,
    yDomain: d3.groupSort(pandas, 
      D => d3.sum(D, d => (order === "ascending" ? -d.value : d.value)), 
      d => d.scale),
    zDomain: key,
  }
)

其中value是x轴上的大条中的一个条的值,scale是y轴上的标签,key是数组:

var key = ["punnets_underweight", "punnets_overweight", "punnets_on_weight"]

顺序是当按下按钮时在值“升序”和“降序”之间变化的状态。
是否有任何方法可以修改groupSort函数,使其可以对2个对象属性进行排序?我可能遗漏了很多信息,因为我不确定如何将所有内容作为一个整体来表达,但这是我的问题的核心。

aurhwmvo

aurhwmvo1#

你写道:
我现在需要做的是首先按y轴标签的字母顺序对图表进行排序,然后按x轴上的值升序排序
如果我对你的例子理解正确的话,你不想在完整的y标签上排序(因为那会完全排序yDomain),而只是在第一部分上排序-也许只是到Line ${n}或其他。然后,您希望根据大小对这些组中的进行排序?
我相信这可以用d3.groupSort来完成,使用更通用的比较器作为第二个参数。有时,我发现很难找到更专业,更高级别的功能,虽然特殊的咒语。这肯定可以通过d3.groupd3.sort来完成。
由于我没有访问您的数据的权限,因此我分叉了您引用的Observable笔记本和built an example there。在这个例子中,我将状态随机地分为字母表的前半部分,然后是第二部分。然后,我按这两组中的人口进行排序。这里的代码看起来像这样:

// An Array of objects with {state, population} keys:
state_populations = Array.from(
  d3.group(stateages, (o) => o.state).values()
).map((a) => ({
  state: a[0].state,
  population: d3.sum(a, (o) => o.population)
}));

/// The yDomain
yDomain = d3
  .sort(
    state_populations,
    (s) => (s.state < "M" ? 1 : 0),
    (s) => s.population
  )
  .map((s) => s.state)

您可以查看更多详情in the notebook。下面是生成图像的顶部:

相关问题