是否可以为NVD3区域创建焦点图表?

时间:2014-01-17 12:16:11

标签: d3.js nvd3.js

NVD3是一个基于D3构建的javascript库包装器。它提供了使用Crossfilter for Line chart创建画笔效果。

以下参考: http://nvd3.org/ghpages/lineWithFocus.html

我很想知道是否可以为面积图或散点图建立类似的刷牙/聚焦效果?请帮帮我。

1 个答案:

答案 0 :(得分:4)

我是NVD3的新手(截至昨天)并且对D3有一定的经验,但绝不是高级用户。我一直在处理同样的问题,为自己找到了一个可能有帮助的快乐解决方案。

首先,由于您提到对“散点图”使用类似的焦点/上下文接口,您应该知道构建LineWithFocus图表的nvd3.models.line对象本身实际构建在{ {1}}。我发现这一点是因为为了得到一个折线图来显示实际上必须使用的时间尺度的x轴标签:nvd3.models.scatter

现在,至于显示带有填充区域的折线图,您可以像@AmeliaBR一样注释,使用内置的chart.lines.scatter.xScale(d3.time.scale());(实际上我发现设置chart.isArea(true)更好。这会完全生成线条 - 填充在下面,但正如@AmeliaBR所提到的,相互作用会引起一些问题,对我来说,线条相互填充。我想要的东西看起来更像一个流图。它最终变得非常简单。我的线条排序很好(跟踪这些相同数据的最小值,平均值和最大值),这可能与您的情况不同,因此您可能需要添加一些额外的工作来正确设置数据以填写您想要的方式。读取我的数据,我为每一行设置y和y0值,如下所示:

lines.isArea(true); lines2.isArea(true);

这将设置它,以便数据可以在三条线之间绘制两个形状,一条在最小和平均之间(颜色最小),一条在平均值和最大值之间(颜色类似于最大值)。为了让代码使用该数据,我通过将完整定义从nv.d3.js源代码复制到我自己的文件来重载nv.models.line对象定义,并进行了以下更改:

  1. 在顶部,我添加了一个在getX和getY函数之后建模的getY0函数:

    var line_data = [ {key: "minimum", values: []}, {key: "average", values: []}, {key: "maximum", values: []}]; data.forEach(function(d) { var date = new Date(+d.epoch*1000); //new Date(+d.epoch*1000); line_data[0]["values"].push({x: date, y: +d.minimum, y0: +d.average }); line_data[1]["values"].push({x: date, y: +d.average, y0: +d.average }); line_data[2]["values"].push({x: date, y: +d.maximum, y0: +d.average }); });

    getX = function(d) { return d.x }

    getY = function(d) { return d.y }

  2. 稍低一点,您会找到getY0 = function(d) { return d.y0 }的定义,并在另一个启动areaPaths = groups.selectAll('path.nv-area')的块下方。两个地方都进行了相同的areaPaths.transition()通话。在这两个地方你都需要做出同样的改变。

  3. 而不是:attr('d',...)

    使用:.y1(function(d,i) { return y0( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) })

    您会注意到该行现在几乎与上面的行完全相同:

    .y1(function(d,i) { return nv.utils.NaNtoZero(y(getY0(d,i))) })

    .y0(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) })更改为y0

    y

    说明:

    您对该区域的.y0(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })定义是行数据中的.y0值 您对该区域的d.y定义是行数据

    中的.y1

    包装d.y0的{​​{1}}调用实际上是对正在使用的比例的引用。如果您从y0()定义中的getY稍微查看一下,您会看到有一条评论定义了这些评论:areaPaths

    如果我最初离开y0()包装器,我发现该图最初出现了我想要的但后来没有正确更新。当我将这些函数中的所有nv.models.line包装器更改为var x0, y0 //used to store previous scales并使用当前比例而不是前一个比例更新它们时。从那以后没有任何问题。