dc.js:如何交叉过滤复杂对象?

菲利克斯·威格纳

我有一个复杂的JSON对象,并且想对数据进行交叉过滤(键应为x轴,值应为y轴),如何使用该对象呢?

signalData: {
    signal1: {
      name: "",
      data: {2,3,1,4,5,1,3},
    },
    signal2: {
      name: "",
      data: {2,3,1,4,5,1,3},
    },
    signal3: {
      name: "",
      data: {2,3,1,4,5,1,3},
    },

我认为主要的想法是对数据键进行交叉过滤,因为我想在3个不同的图表中使用此数据。

这里的图形可能更好地描述了我想做什么;)

在此处输入图片说明

这是一些代码:

var data = {
   "1": 10,
   "2": 20,
   "3": 30,
   "4": 40,
   "5": 50,
   "6": 60
 };
var dataModel = Object.keys(data).map(function(d) {
  return {
     key: +d,
     value: data[d]
   };
});
signalCF = crossfilter(dataModel);
signalDim = signalCF.dimension(dc.pluck("key"));
signalGroup = signalDim.group().reduceSum(function(d) {
  return d.value; });
高登

我不确定是否使用相同的“过滤器”定义;我的意思是要问您是否打算使用crossfilter的过滤功能,即在一个维度上进行刷涂并在不相关的视图中仅看到选定的数据

范围/焦点功能不需要过滤,因为所有图表都在同一维上,并且没有数据被过滤。

假设您确实要过滤此数据维,则需要展平数据。

如果您的原始数据看起来像

signalData: {
    signal1: {
      name: "",
      data: {2,3,1,4,5,1,3},
    },
    signal2: {
      name: "",
      data: {2,3,1,4,5,1,3},
    },
    signal3: {
      name: "",
      data: {2,3,1,4,5,1,3},
    },

展平的数据可能看起来像

[
  {
    signal1: 2,
    signal2: 2,
    signal3: 2
  },
  {
    signal1: 3,
    signal2: 3,
    signal3: 3
  },
  {
    signal1: 1,
    signal2: 1,
    signal3: 1
  },
  {
    signal1: 4,
    signal2: 4,
    signal3: 4
  },
  // ...

这是我想要了解的唯一一点,其余的内容应该很明显...

我会警惕Object.keys在数组上使用它可能有效,但是数据可能会混乱。d3.range将做同样的事情。

将密钥添加到上述数据中:

var dataModel = d3.range(0, data.length).map(function(d) {
  return {
     key: +d,
     ...data[d]
   };
});

现在数据看起来像

[
  {
    key: 0,
    signal1: 2,
    signal2: 2,
    signal3: 2
  },
  // ...

您可以定义维度和组,例如:

signalCF = crossfilter(dataModel);
signalDim = signalCF.dimension(dc.pluck("key"));
signalGroup1 = signalDim.group().reduceSum(function(d) {
  return d.signal1; });
signalGroup2 = signalDim.group().reduceSum(function(d) {
  return d.signal2; });

显然,您还可以编写代码以将数据结构平整为此类数据。我要介绍的唯一一点是,交叉过滤器的本机格式是扁平化的数组。可以压缩其他格式的数据,但是仅当数据是数组时才进行过滤。

这是执行转换的一些代码。将列主要数据转换为行主要数据是一项常见任务,尽管有其他方法,我通常为此使用d3.rangeArray.reduce

function rotate_data(odata) {
  const keys = Object.keys(odata),
    len = d3.max(keys, key => odata[key].data.length); // 1
  if(keys.some(key => odata[key].data.length < len))
    console.warn('warning: data not same length; padding with zeros'); // 2
  return d3.range(0, len).map(i => keys.reduce(
    (p, k) => (p[k] = odata[k].data[i] || 0, p), {key: i}); // 3
}

rotate_data计算data对象(1)的所有值的最大长度字段。然后,如果这些数组中的任何一个都不是该长度(2),则会发出警告。最后(3)将整数[1,length)映射到具有

  • key整数的字段i
  • 原始对象的每个键的字段,其中包含i对应数组th值

我在这里测试了功能请注意,示例数据中有一个拼写错误-数组应放在方括号中,不要卷曲。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章