【问题标题】:dc.js bubble chart fails to display pointsdc.js 气泡图无法显示点
【发布时间】:2014-11-10 17:24:40
【问题描述】:

我正在尝试使用 crossfilter 和 dc.js 制作气泡图。但我无法让我的分数出现在我的图表上。我在这里建立了一个 JSFiddle:

http://jsfiddle.net/4asmb7h1/

var data = [
    {date: "12/27/2012", label: "a1", x: 2, y: 190, bubble: 5},
    {date: "12/28/2012", label: "a2", x: 2, y: 10,  bubble: 5},
    {date: "12/29/2012", label: "a3", x: 95, y: 300, bubble: 10}
];
var ndx = crossfilter(data);
var parseDate = d3.time.format("%m/%d/%Y").parse;
data.forEach(function(d) {
    d.date = parseDate(d.date);
});
var dateDim = ndx.dimension(function(d) {return d.date;});
var xDim = ndx.dimension(function(d) {return d.x;});
var bubbleChart  = dc.bubbleChart("#bubble-chart"); 
bubbleChart
    .dimension(dateDim)
    .group(xDim)
    .x(d3.scale.linear().domain([0, 100]))
    .y(d3.scale.linear().domain([0, 100]))
    .width(400)
    .height(400)
    .yAxisPadding(50)
    .xAxisPadding(50)
    .xAxisLabel('X') // (optional) render an axis label below the x axis
    .yAxisLabel('Y') // (optional) render a vertical axis lable left of the y axis
    .label(function (p) {
        return p.label;
    })
    .renderLabel(true)
    .title(function (p) {
        return [
               "x: " + p.x,
               "y: " + p.y,
               "Bubble: " + p.bubble,
               ]
               .join("\n");
    })
    .renderTitle(true)
    .renderHorizontalGridLines(true) // (optional) render horizontal grid lines, :default=false
    .renderVerticalGridLines(true)
    .maxBubbleRelativeSize(0.3)
    .keyAccessor(function (p) {
        return p.y;
    })
    .valueAccessor(function (p) {
        return p.x;
    })
    .radiusValueAccessor(function (p) {
        return p.bubble;
    })
;

可以通过底部的数据表查看数据,因此我知道正在查看数据。在这一点上我最好的猜测是我没有正确实施我的组或维度,但我似乎没有尝试对我有用。

谁能看到我在这里做错了什么?我正在寻找要显示为 data.x、data.y 且气泡大小为 data.bubble 的点。

编辑:更新了问题以包含更多设置 JS。 (所有代码都在我的小提琴上)

【问题讨论】:

  • 我很抱歉,但只是要求其他人调试您的代码并不是一个很好的 SO 问题。特别是,您需要 1. 查看调试控制台是否有任何错误 2. github.com/dc-js/dc.js/wiki/… 3. 浏览器中的调试器是您的朋友。
  • 我不是想让你调试我的代码。正如我所说,我想我明白我的问题出在哪里(组/维度)。这实际上不是我的“代码”,而是试图重现该问题的小提琴。我已经大大简化了代码以尝试使其更容易。没有控制台错误。我认为很明显我在分组方面遇到了问题,因为这是我理解最少的代码部分。
  • 哇,您似乎发现了一个非常奇怪的 dc.js 角落案例。应该不可能将维度作为一个组传递。只是碰巧他们都有一个.top 函数,所以这就是它没有产生任何错误的原因。呃。
  • 戈登,是的,所以这是在多次尝试使其正常工作后出现的,并且可能作为复制粘贴错误引入我的代码中。我不怀疑很多人会这样做,但也许可以设置一个检查来强制检查是否正在传递一个组?也许在基组类上有一个 isGroup(){return true} 方法或其他东西(这对我来说似乎有点骇人听闻,这真的太糟糕了 JS 不支持类型提示。
  • 嗯,这很有趣,因为很多人实际上用看起来像正确对象的其他对象替换(例如,参见“假组”模式,以及根本不使用交叉过滤器的人)。如果传入的对象与预期的界面不匹配,最好的方法可能是发出控制台警告,人们可以禁用该界面。我一直在考虑将内部接口形式化,所以我可以做到。

标签: javascript d3.js dc.js crossfilter bubble-chart


【解决方案1】:

我可以看出一些错误:

  1. 在气泡图中,您将维度作为组参数传入。 dc.js 期望您将先前声明的组传递给该参数。

  2. 看起来您实际上并没有在这里使用crossfilter 的好处。这个想法是对数据进行分组和总结。您的维度会导致为维度的每个值创建一个唯一值,这没关系,但它有点错过了crossfilter 的要点。

  3. 当您引用分组对象的属性时,您没有正确引用它们。当crossfilter 对项目进行分组时,它将创建具有keyvalue 属性的新对象,其中包含键(匹配dimension 值)和值(从reduce 函数计算)。您没有使用分组对象中的这些属性。

说了这么多,这里有一个jsfiddle 可以帮助你:http://jsfiddle.net/0w3xnbu0/5/

我想我已经生成了你想要的东西。

我创建的更改是:

  1. 创建了一个dateGroup 对象,该对象对您的数据进行分组和减少,以便bubbleChart 可以加载它。这可能是不正确的,尤其是当您的真实数据包含多个具有相同日期的记录时。要使其适应其他数据集,您肯定需要更改此对象的 reduce 部分中的函数。

    var dateGroup = dateDim.group().reduce(
        function(p, v) {
            ++p.count;
            p.label = v.label;
            p.bubble = v.bubble;
            p.x = v.x;
            p.y = v.y;
    
            return p;
        },
        function(p, v) {
            --p.count;
            p.bubble = 0;
            p.label = "";
            p.x = 0;
            p.y = 0;
    
            return p;
        }, function() {
            return { count: 0, x: 0, y:0, label: "" };
        });
    
  2. 创建了一个 xRangeyRange 对象来正确设置 xy 值的 minmax 值,而不仅仅是硬编码为 [0, 100]

    var xRange = [-10, d3.max(dateGroup.all(), function(d) { return d.value.x + d.value.bubble*2; }) ],
        yRange = [-10, d3.max(dateGroup.all(), function(d) { return d.value.y + d.value.bubble*2; }) ];
    
  3. 更新了 bubbleChart 对象以使用新的 dateGroup 以及在 bubbleChart 调用中的 x 和 y 比例以使用上面的新范围

    bubbleChart
        .dimension(dateDim)
        .group(dateGroup)
        .x(d3.scale.linear().domain(xRange))
        .y(d3.scale.linear().domain(yRange))
    
  4. 更改了bubbleCharttitlekeyAccessorvalueAccessorradiusValueAccessor 函数,以正确引用分组对象中的适当值。

        .title(function (p) {
            return [
               "x: " + p.value.x,
               "y: " + p.value.y,
               "Bubble: " + p.value.bubble,
               ]
               .join("\n");
        })
    ...
        .keyAccessor(function (p) {
            return p.value.x;
        })
        .valueAccessor(function (p) {
            return p.value.y;
        })
        .radiusValueAccessor(function (p) {
            return p.value.bubble;
        })
    

【讨论】:

  • 本,非常感谢这篇文章。今天早上我会玩弄它。你是对的,我在我处理的示例中没有使用交叉过滤器,但这主要是因为我试图简化我的代码以提高可读性。我将需要在我的最终代码中使用交叉过滤器来过滤其他相关的元数据(日期等)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多