DC Heatmap 如何为正值和负值指定 2 色图

DC Heatmap how to specify a 2 Color Map for Positive and Negative values

我正在尝试将热图添加到 DC/Crossfilter 仪表板。我想看到的是一条水平线,由小矩形组成,颜色为红色或绿色,具体取决于交易 return 是正数还是负数,这是为了遵循交易顺序。

所以我无法弄清楚如何将颜色与交易价值相关联(尝试使用类型文本"Profit"/"Loss" 字段但也无法弄清楚)。以下是我目前所在的位置,但似乎 return 的前半部分是绿色,后半部分是红色。所以坚持将颜色与价值联系起来的机制。也可能有奇数零值,我想将其与正值匹配。

我只是这里的业余爱好者,所以没有很深的知识,并且阅读了很多几乎到达那里但最终让我意识到我不知道多少的问题。因此,在我向前迈进的过程中,任何帮助都将不胜感激。

这是Fiddle

干杯

弗雷德

这是我的代码

var transactions = [
{date: "2020-01-23T11:15:11Z", sequence: 1, rturn: -280.00, type: "Loss"},
{date: "2020-01-23T11:22:19Z", sequence: 2, rturn: -43.75, type: "Loss"},
{date: "2020-01-23T11:28:47Z", sequence: 3, rturn: -4.05, type: "Loss"},
{date: "2020-01-23T11:33:26Z", sequence: 4, rturn: 9.47, type: "Profit"},
{date: "2020-01-23T11:50:34Z", sequence: 5, rturn: 0.11, type: "Profit"},
{date: "2020-01-23T11:53:40Z", sequence: 6, rturn: 16.46, type: "Profit"},
{date: "2020-01-23T12:16:34Z", sequence: 7, rturn: 19.23, type: "Profit"},
{date: "2020-01-23T12:24:03Z", sequence: 8, rturn: 26.65, type: "Profit"},
{date: "2020-01-23T12:38:19Z", sequence: 9, rturn: 7.70, type: "Profit"},
{date: "2020-01-23T13:12:50Z", sequence: 10, rturn: 9.80, type: "Profit"},
{date: "2020-01-23T13:27:43Z", sequence: 11, rturn: -15.58, type: "Loss"},
{date: "2020-01-23T13:35:45Z", sequence: 12, rturn: 6.18, type: "Profit"}
];

var facts = crossfilter(transactions);

var dimensionByType = facts.dimension(function(d){ return d.sequence; });
var groupByType = dimensionByType.group().reduceCount(function(d){ return d.type; });

var barChart = dc.heatMap('#heatMap')
      .width(1024)
      .height(250)
      .dimension(dimensionByType)
      .group(groupByType)
      .title(function(d){ return "Total Payment: $" + d.key + " => Tip: $" +d.value; })
      .xBorderRadius([25])
      .yBorderRadius([25])
      .colors(["steelblue","red"])
      .calculateColorDomain();

  dc.renderAll();
<!DOCTYPE html>
<html lang="EN">
    <head>
      <meta charset="utf-8">
      <title>Heat Map</title>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.1/d3.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.9/dc.min.js"></script>
      <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.9/dc.min.css" />
    </head>
    <body>
        <h1>Transactions Result Sequence</h1>
        <div id="heatMap"></div>
    </body>
</html>

dc.js 是围绕很多 "accessors" 和 "scales".

构建的

"Accessors" 取一组 bin({key,value} 对)和 return 一些有用的值。

"Scales"(D3 概念)获取一个值并将其映射到一些视觉编码,如颜色、X 或 Y。

热图使用

  • keyAccessor 和 X
  • 的私有 d3.scaleBand
  • valueAccessor 和 Y
  • 的私有 d3.scaleBand
  • colorAccessor 和颜色比例 .colors()

在你的情况下,你想要

  • 为 X

    使用 sequence
      .keyAccessor(d => d.key)
    
  • 为 Y

    使用 0(或任何常数值)
      .valueAccessor(d => 0)
    
  • 使用 rturntype 作为颜色访问器,以及将盈利映射到绿色并将亏损映射到红色的色标

您正在使用 sequence 作为维度;这将提供 d.key.

交叉过滤器组聚合所有落入键分配的容器中的行。

查看盈利或亏损的一种简单方法是 reduceSum 使用 rturn:

var groupByType = dimensionByType.group().reduceSum(row => row.rturn);

每个序列只有一行,所以它只是通过 rturn。现在 d.value 将有 row.rturn 我们可以告诉 colorAccessor 根据符号来决定它是盈利还是亏损:

      .colorAccessor(d => d.value >= 0 ? 'Profit' : 'Loss')

并使用顺序尺度将利润分配给绿色,将红色分配给亏损:

      .colors(d3.scale.ordinal().domain(['Profit', 'Loss']).range(["green","red"]))

有很多其他方法可以做到这一点,使用 type 或其他色标,但我认为这是最简单的,如果你的热图箱被聚合,它仍然有效。

var transactions = [
{date: "2020-01-23T11:15:11Z", sequence: 1, rturn: -280.00, type: "Loss"},
{date: "2020-01-23T11:22:19Z", sequence: 2, rturn: -43.75, type: "Loss"},
{date: "2020-01-23T11:28:47Z", sequence: 3, rturn: -4.05, type: "Loss"},
{date: "2020-01-23T11:33:26Z", sequence: 4, rturn: 9.47, type: "Profit"},
{date: "2020-01-23T11:50:34Z", sequence: 5, rturn: 0.11, type: "Profit"},
{date: "2020-01-23T11:53:40Z", sequence: 6, rturn: 16.46, type: "Profit"},
{date: "2020-01-23T12:16:34Z", sequence: 7, rturn: 19.23, type: "Profit"},
{date: "2020-01-23T12:24:03Z", sequence: 8, rturn: 26.65, type: "Profit"},
{date: "2020-01-23T12:38:19Z", sequence: 9, rturn: 7.70, type: "Profit"},
{date: "2020-01-23T13:12:50Z", sequence: 10, rturn: 9.80, type: "Profit"},
{date: "2020-01-23T13:27:43Z", sequence: 11, rturn: -15.58, type: "Loss"},
{date: "2020-01-23T13:35:45Z", sequence: 12, rturn: 6.18, type: "Profit"}
];

var facts = crossfilter(transactions);

var dimensionByType = facts.dimension(function(d){ return d.sequence; });
var groupByType = dimensionByType.group().reduceSum(row => row.rturn);

var heatMap = dc.heatMap('#heatMap')
      .width(1024)
      .height(250)
      .dimension(dimensionByType)
      .group(groupByType)
      .keyAccessor(d => d.key)
      .valueAccessor(d => 0)
      .colorAccessor(d => d.value >= 0 ? 'Profit' : 'Loss')
      .title(function(d){ return "Total Payment: $" + d.key + " => Tip: $" +d.value; })
      .xBorderRadius([25])
      .yBorderRadius([25])
      .colors(d3.scale.ordinal().domain(['Profit', 'Loss']).range(["green","red"]))
      //.calculateColorDomain();

  dc.renderAll();
<!DOCTYPE html>
<html lang="EN">
    <head>
      <meta charset="utf-8">
      <title>Heat Map</title>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.1/d3.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.9/dc.min.js"></script>
      <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.9/dc.min.css" />
    </head>
    <body>
        <h1>Transactions Result Sequence</h1>
        <div id="heatMap"></div>
    </body>
</html>