d3.js可以使用同一来源的数据在同一个图上绘制两个散点图吗? [英] Can d3.js draw two scatterplots on the same graph using data from the same source?

查看:217
本文介绍了d3.js可以使用同一来源的数据在同一个图上绘制两个散点图吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现的所有d3教程都使用以对象数组排列的数据,从中为数组中的每个对象绘制一个点。给定以下结构中的数据:

All of the d3 tutorials I've found use data arranged in arrays of objects from which they graph one point for each object in the array. Given data in the following structure:

data = [
     {id: 1, x: 4, y: 10, type: 1},
     {id: 2, x: 5, y: 20, type: 2}
     ...
]

x和y值用于创建散点图。 type参数用于更改每个点的颜色。请参阅此jsfiddle的示例: http://jsfiddle.net/uxbHv/

The x and y values are used to make a scatterplot. The type parameter is used to change the color of each point. See this jsfiddle for an example: http://jsfiddle.net/uxbHv/

不幸的是,我有一个不同的数据结构,我不知道如何通过为每个对象绘制两个数据点来创建相同的图形。下面是一些示例数据:

Unfortuately, I have a different data structure and I can't figure out how to create the same graph by drawing two data points for each object. Here is some example data:

dataSet = [
     {xVar: 5, yVar1: 90, yVar2: 22},
     {xVar: 25, yVar1: 30, yVar2: 25},
     {xVar: 45, yVar1: 50, yVar2: 80},
     {xVar: 65, yVar1: 55, yVar2: 9},
     {xVar: 85, yVar1: 25, yVar2: 95}
]


b $ b

我可以单独图形化xVar与yVar1或yVar2,但我不知道如何获得两个在同一个图: http://jsfiddle.net/634QG/

推荐答案

使用 data-join 是您希望从数据到元素的一对一映射。因此,如果您的散点图中有两个系列,则需要两个容器元素(例如 G元素)来表示系列。由于您目前只有一个数据数组,因此您还需要使用 array.map 将数据表示转换为具有相同表示的两个并行数组。这样,您不必为每个系列重复代码。

The general rule when using a data-join is that you want a one-to-one mapping from data to elements. So, if you have two series in your scatterplot, you’ll want two container elements (such as G elements) to represent the series. Since you currently have only one data array, you’ll also want to use array.map to convert the data representation into two parallel arrays with the same representation. This way, you don’t have to duplicate code for each series.

假设您的数据表示为CSV文件,其中一列为 x - 值和多个其他列的每个系列的 y 值:

Say your data was represented in a CSV file with one column for the x-values, and multiple other columns for the y-values of each series:

x,y1,y2
5,90,22
25,30,25
45,50,80
65,55,9
85,25,95

如果您希望代码完全通用,您首先需要计算系列的名称,例如 [y1,y2] 。 (如果您向CSV文件添加了第三列,它可能是 [y1,y2,y3] 。)您可以使用< a href =https://github.com/mbostock/d3/wiki/Arrays#wiki-d3_keys =noreferrer> d3.keys ,它从对象中提取命名属性。例如, d3.keys({foo:1,bar:2})返回 [foo,bar]

If you want the code to be completely generic, you first need to compute the series’ names, such as ["y1", "y2"]. (If you added a third column to the CSV file, it might be ["y1", "y2", "y3"].) You can compute the names using d3.keys, which extracts the named properties from an object. For example, d3.keys({foo: 1, bar: 2}) returns ["foo", "bar"].

// Compute the series names ("y1", "y2", etc.) from the loaded CSV.
var seriesNames = d3.keys(data[0])
    .filter(function(d) { return d !== "x"; })
    .sort();

既然你有了系列名称,你可以创建一个点数组数组。外部数组表示系列(其中有两个),内部数组存储数据点。您可以同时将点转换为一致的表示(具有 x y 属性的对象),允许您重复使用代码

Now that you have the series names, you can create an array of arrays of points. The outer array represents the series (of which there are two) and the inner arrays store the data points. You can simultaneously convert the points to a consistent representation (objects with x and y properties), allowing you to reuse code across series.

// Map the data to an array of arrays of {x, y} tuples.
var series = seriesNames.map(function(series) {
  return data.map(function(d) {
    return {x: +d.x, y: +d[series]};
  });
});

请注意,此代码使用 + 将CSV值强制转换为数字。 (CSV文件没有类型,因此它们最初是字符串。)

Note this code uses the + operator to coerce the CSV values to numbers. (CSV files are untyped, so they are initially strings.)

现在您已将数据映射为常规格式,您可以为每个系列创建G元素,然后为每个点内的圆圈元素。生成的SVG结构将如下所示:

Now that you’ve mapped your data to a regular format, you can create G elements for each series, and then circle elements within for each point. The resulting SVG structure will look like this:

<g class="series">
  <circle class="point" r="4.5" cx="1" cy="2"/>
  <circle class="point" r="4.5" cx="3" cy="2"/>
  …
</g>
<g class="series">
  <circle class="point" r="4.5" cx="5" cy="4"/>
  <circle class="point" r="4.5" cx="7" cy="6"/>
  …
</g>

以及相应的D3代码:

// Add the points!
svg.selectAll(".series")
    .data(series)
  .enter().append("g")
    .attr("class", "series")
    .style("fill", function(d, i) { return z(i); })
  .selectAll(".point")
    .data(function(d) { return d; })
  .enter().append("circle")
    .attr("class", "point")
    .attr("r", 4.5)
    .attr("cx", function(d) { return x(d.x); })
    .attr("cy", function(d) { return y(d.y); });

我还添加了一些代码,通过添加填充样式到含有G元素。当然有很多不同的方法来做到这一点。 (例如,您可能希望更具体地了解每个系列的颜色。)我还省略了计算您的 x y 缩放(以及渲染轴),但如果您想查看整个工作示例:

I’ve also added a bit of code to assign each series a unique color by adding a fill style to the containing G element. There are lots of different ways to do this, of course. (You might want to be more specific about the color for each series, for example.) I’ve also left out the code that computes the domains of your x and y scales (as well as rendering the axes), but if you want to see the entire working example:

  • http://bl.ocks.org/3183403

这篇关于d3.js可以使用同一来源的数据在同一个图上绘制两个散点图吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆