数据集

dataset 是专门用于管理数据的组件。尽管你可以在每个系列(series)的 series.data 中设置数据,但自 ECharts 4 起,我们推荐使用 dataset 来管理数据,这样数据可以被多个组件复用,也便于实现“数据与配置分离”。毕竟,数据是最常变化的部分,而其他配置在运行时大多不会改变。

series 中定义数据

如果数据定义在 series 下,例如:

option = {
  xAxis: {
    type: 'category',
    data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie']
  },
  yAxis: {},
  series: [
    {
      type: 'bar',
      name: '2015',
      data: [89.3, 92.1, 94.4, 85.4]
    },
    {
      type: 'bar',
      name: '2016',
      data: [95.8, 89.4, 91.2, 76.9]
    },
    {
      type: 'bar',
      name: '2017',
      data: [97.7, 83.1, 92.5, 78.1]
    }
  ]
};
在线示例

series 下定义 data 适用于一些特殊数据结构(如“树图”、“关系图”)和大数据量的定制。但是,这不利于多个系列共享数据,也不利于根据原始数据进行图表类型和系列的映射编排。另一个缺点是,程序员总是需要先将数据划分到不同的系列(和类别)中。

dataset 中定义数据

如果你在 dataset 中定义 data,有以下优点:

  • 遵循数据可视化的思路:(I) 提供数据,(II) 将数据映射到可视化元素,形成图表。
  • 将数据与其他配置分离。数据经常变动,而其他配置则不然。这样易于分开管理。
  • 数据可以被多个系列或组件复用,你不需要为每个系列创建大量数据的副本。
  • 支持更通用的数据格式,如二维数组、对象数组等,在一定程度上避免了用户进行数据格式转换。

这是一个简单的 dataset 示例:

option = {
  legend: {},
  tooltip: {},
  dataset: {
    // Provide a set of data.
    source: [
      ['product', '2015', '2016', '2017'],
      ['Matcha Latte', 43.3, 85.8, 93.7],
      ['Milk Tea', 83.1, 73.4, 55.1],
      ['Cheese Cocoa', 86.4, 65.2, 82.5],
      ['Walnut Brownie', 72.4, 53.9, 39.1]
    ]
  },
  // Declare an x-axis (category axis).
  // The category map the first column in the dataset by default.
  xAxis: { type: 'category' },
  // Declare a y-axis (value axis).
  yAxis: {},
  // Declare several 'bar' series,
  // every series will auto-map to each column by default.
  series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
};
在线示例

或者尝试使用“对象数组”格式:

option = {
  legend: {},
  tooltip: {},
  dataset: {
    // Define the dimension of array. In cartesian coordinate system,
    // if the type of x-axis is category, map the first dimension to
    // x-axis by default, the second dimension to y-axis.
    // You can also specify 'series.encode' to complete the map
    // without specify dimensions. Please see below.

    dimensions: ['product', '2015', '2016', '2017'],
    source: [
      { product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7 },
      { product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1 },
      { product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5 },
      { product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1 }
    ]
  },
  xAxis: { type: 'category' },
  yAxis: {},
  series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
};
在线示例

从数据到图表的映射

数据可视化的思路是:(I) 提供数据,(II) 将数据映射到可视化元素,形成图表。

简而言之,你可以设置这些映射配置:

  • 指定 dataset 的“列”或“行”来映射到 series。你可以使用 series.seriesLayoutBy 来配置。默认是按列映射。
  • 指定维度映射的规则:如何将“dataset”的维度映射到 axis(坐标轴)、tooltip(提示框)、label(标签)和 visualMap(视觉映射)。要配置映射,请使用 series.encodevisualMap。前面的例子没有给出映射配置,所以 ECharts 会遵循默认规则:如果 x 轴是类目轴,则映射到 dataset.source 的第一行;三个系列的图表则将 dataset.source 中的每一行逐一映射。

配置详情如下所示:

dataset 的行或列映射到 series

有了 dataset,你就可以灵活地配置数据如何映射到坐标轴和系列。

你可以使用 seriesLayoutBy 来改变图表对行和列的理解。seriesLayoutBy 可以是:

  • 'column': 默认值。系列对应于 dataset 的列。
  • 'row': 系列对应于 dataset 的行。

查看这个例子

option = {
  legend: {},
  tooltip: {},
  dataset: {
    source: [
      ['product', '2012', '2013', '2014', '2015'],
      ['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
      ['Milk Tea', 86.5, 92.1, 85.7, 83.1],
      ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
    ]
  },
  xAxis: [
    { type: 'category', gridIndex: 0 },
    { type: 'category', gridIndex: 1 }
  ],
  yAxis: [{ gridIndex: 0 }, { gridIndex: 1 }],
  grid: [{ bottom: '55%' }, { top: '55%' }],
  series: [
    // These series will show in the first coordinate, each series map a row in dataset.
    { type: 'bar', seriesLayoutBy: 'row', xAxisIndex: 0, yAxisIndex: 0 },
    { type: 'bar', seriesLayoutBy: 'row', xAxisIndex: 0, yAxisIndex: 0 },
    { type: 'bar', seriesLayoutBy: 'row', xAxisIndex: 0, yAxisIndex: 0 },
    // These series will show in the second coordinate, each series map a column in dataset.
    { type: 'bar', seriesLayoutBy: 'column', xAxisIndex: 1, yAxisIndex: 1 },
    { type: 'bar', seriesLayoutBy: 'column', xAxisIndex: 1, yAxisIndex: 1 },
    { type: 'bar', seriesLayoutBy: 'column', xAxisIndex: 1, yAxisIndex: 1 },
    { type: 'bar', seriesLayoutBy: 'column', xAxisIndex: 1, yAxisIndex: 1 }
  ]
};
在线示例

配置效果如此示例所示。

维度(Dimension)

常用图表中描述的数据大多是“二维表”结构,在前面的例子中,我们使用二维数组来表示二维表。现在,当我们把一个系列映射到一个列时,该列被称为一个“维度”,而每一行被称为一个“数据项”,反之亦然。

维度可以有自己的名称以便在图表中显示。维度名称可以在第一列(行)中定义。在下一个示例中,'score''amount''product' 是维度的名称。实际数据从第二行开始。ECharts 会自动检查 dataset.source 的第一列(行)是否包含维度名称。你也可以使用 dataset.sourceHeader: true 来声明第一列(行)代表维度名称。

尝试使用单个 dataset.dimensions 或某些 series.dimensions 来定义维度,这样你可以同时指定名称和类型。

var option1 = {
  dataset: {
    dimensions: [
      { name: 'score' },
      // can be abbreviated as 'string', to indicate dimension name
      'amount',
      // Specify dimensions in 'type'.
      { name: 'product', type: 'ordinal' }
    ],
    source: []
  }
  // ...
};

var option2 = {
  dataset: {
    source: []
  },
  series: {
    type: 'line',
    // series.dimensions will cover the config in dataset.dimension
    dimensions: [
      null, // use null if you do not want dimension name.
      'amount',
      { name: 'product', type: 'ordinal' }
    ]
  }
  // ...
};

在大多数情况下,你不需要定义维度类型,因为 ECharts 会自动判断。如果判断不准确,你可以手动定义。

维度类型可以是以下值:

  • 'number': 默认值,普通数据。
  • 'ordinal': 字符串类型的数据,如类别、文本,只有维度类型为 'ordinal' 时才能用于坐标轴。ECharts 会尝试自动判断此类型,但可能不准确,所以你可以手动指定。
  • 'time': 用于表示时间数据,如果维度类型定义为 'time',ECharts 可以自动将数据解析为时间戳。例如,如果这个维度的数据是 '2017-05-10',ECharts 会自动解析。如果维度用作时间轴 (axis.type = 'time'),维度类型也会是 'time'。更多支持的时间类型请参见 data
  • 'float': 在 'float' 维度中使用 TypedArray 优化性能。
  • 'int': 在 'int' 维度中使用 TypedArray 优化性能。

从数据到图表的映射 (series.encode)

理解了维度的概念后,你可以使用 series.encode 来进行映射:

var option = {
  dataset: {
    source: [
      ['score', 'amount', 'product'],
      [89.3, 58212, 'Matcha Latte'],
      [57.1, 78254, 'Milk Tea'],
      [74.4, 41032, 'Cheese Cocoa'],
      [50.1, 12755, 'Cheese Brownie'],
      [89.7, 20145, 'Matcha Cocoa'],
      [68.1, 79146, 'Tea'],
      [19.6, 91852, 'Orange Juice'],
      [10.6, 101852, 'Lemon Juice'],
      [32.7, 20112, 'Walnut Brownie']
    ]
  },
  xAxis: {},
  yAxis: { type: 'category' },
  series: [
    {
      type: 'bar',
      encode: {
        // Map "amount" column to x-axis.
        x: 'amount',
        // Map "product" row to y-axis.
        y: 'product'
      }
    }
  ]
};
在线示例

series.encode 声明的基本结构:

  • 冒号左边:坐标轴或标签的特定名称。
  • 冒号右边:维度名称(字符串)或数字(整数,从0开始计数),用于指定一个或多个维度(使用数组)。

通常,以下信息不是必须定义的。按需填写。

series.encode 建议的属性:

// Supported in every coordinate and series:
encode: {
  // Display the value of dimension named "product" and "score" in tooltip.
  tooltip: ['product', 'score']
  // Connect dimension name of "Dimension 1" and "Dimension 3" as the series name. (Avoid to repeat longer names in series.name)
  seriesName: [1, 3],
  // Means to use the value in "Dimension 2" as the id. It makes the new and old data correspond by id
	// when using setOption to update data, so that it can show animation properly.
  itemId: 2,
  // The itemName will show in the legend of Pie Charts.
  itemName: 3
}

// Grid/cartesian coordinate unique configs:
encode: {
  // Map "Dimension 1", "Dimension 5" and "dimension named 'score'" to x-axis:
  x: [1, 5, 'score'],
  // Map "Dimension 0" to y-axis:
  y: 0
}

// singleAxis unique configs:
encode: {
  single: 3
}

// Polar coordinate unique configs:
encode: {
  radius: 3,
  angle: 2
}

// Geo-coordinate unique configs:
encode: {
  lng: 3,
  lat: 2
}

// For some charts without coordinate like pie chart, funnel chart:
encode: {
  value: 3
}

这是一个更丰富的 series.encode 示例

默认的 series.encode

值得一提的是,如果没有指定 series.encode,ECharts 会对一些常规图表(如折线图、柱状图、散点图、K线图等)使用一些默认的映射规则。默认规则是:

  • 在坐标系中(如直角坐标系、极坐标系):
    • 如果存在类目轴 (axis.type = 'category'),则将第一列(行)映射到该轴,后续的每一列(行)依次映射到一个系列。
    • 如果两个轴都不是类目轴,则将每两列映射到一个系列,分别对应两个坐标轴。
  • 无坐标系的图表(如饼图):
    • 使用第一列(行)作为名称,第二列(行)作为值。如果只有一列(行),ECharts 不会设置名称。

当默认规则无法满足需求时,你可以自己配置 encode,这并不复杂。这是一个示例

一些常见的 series.encode 设置

问:如何将第3列设置为x轴,第5列设置为y轴?

答:

option = {
  series: {
    // dimensionIndex count from 0, so the 3rd line is dimensions[2].
    encode: { x: 2, y: 4 }
    // ...
  }
};

问:如何将第3行设置为x轴,第5行设置为y轴?

答:

option = {
  series: {
    encode: { x: 2, y: 4 },
    seriesLayoutBy: 'row'
    // ...
  }
};

问:如何将第2列设置为标签?

答:我们现在支持通过 label.formatter 从特定维度取值。

series: {
  label: {
    // `'{@score}'` means the value in the dimension named "score".
    // `'{@[4]}'` means the value in dimension 4.
    formatter: 'aaa{@product}bbb{@score}ccc{@[4]}ddd';
  }
}

问:如何在提示框(tooltip)中显示第2列和第3列?

答:

option = {
  series: {
    encode: {
      tooltip: [1, 2]
      // ...
    }
    // ...
  }
};

问:如果维度名称没有包含在数据集中,如何定义?

答:

var option = {
  dataset: {
    dimensions: ['score', 'amount'],
    source: [
      [89.3, 3371],
      [92.1, 8123],
      [94.4, 1954],
      [85.4, 829]
    ]
  }
};

问:如何将第3列映射到散点图的大小?

答:

var option = {
  dataset: {
    source: [
      [12, 323, 11.2],
      [23, 167, 8.3],
      [81, 284, 12],
      [91, 413, 4.1],
      [13, 287, 13.5]
    ]
  },
  visualMap: {
    show: false,
    dimension: 2, // means the 3rd column
    min: 2, // lower bound
    max: 15, // higher bound
    inRange: {
      // Size of the bubble.
      symbolSize: [5, 60]
    }
  },
  xAxis: {},
  yAxis: {},
  series: {
    type: 'scatter'
  }
};
在线示例

问:我在 encode 中指定了映射,为什么没有生效?

答:检查你的拼写,例如,在 encode 中是否将维度名称 'Life Expectancy' 错拼成了 'Life Expectency'

视觉通道映射

我们可以使用 visualMap 来映射视觉通道。详情请查看 visualMap 文档。这是一个示例

图表的数据格式

在大多数常规图表中,数据适合用二维表的形式来描述。像“MS Excel”和“Numbers”这类著名软件都使用二维表。它们的数据可以导出为 JSON 格式并输入到 dataset.source 中,从而避免一些数据处理步骤。

你可以使用像 dsvPapaParse 这样的工具将 .csv 文件转换为 JSON。

如下面的例子所示,在 JavaScript 的数据传输中,二维数据可以直接用二维数组存储。

除了二维数组,dataset 还支持使用键值对(key-value)的方式,这也是一种常见的方式。但是,我们目前在这种格式下不支持 seriesLayoutBy

dataset: [
  {
    // column by column key-value array is a normal format
    source: [
      { product: 'Matcha Latte', count: 823, score: 95.8 },
      { product: 'Milk Tea', count: 235, score: 81.4 },
      { product: 'Cheese Cocoa', count: 1042, score: 91.2 },
      { product: 'Walnut Brownie', count: 988, score: 76.9 }
    ]
  },
  {
    // row by row key-value
    source: {
      product: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'],
      count: [823, 235, 1042, 988],
      score: [95.8, 81.4, 91.2, 76.9]
    }
  }
];

如何引用多个数据集

ECharts 支持同时定义多个数据集。系列可以通过 series.datasetIndex 指定引用哪一个。例如:

var option = {
  dataset: [
    {
      // 1st Dataset
      source: []
    },
    {
      // 2nd Dataset
      source: []
    },
    {
      // 3rd Dataset
      source: []
    }
  ],
  series: [
    {
      // Use 2nd dataset
      datasetIndex: 1
    },
    {
      // Use 1st dataset
      datasetIndex: 0
    }
  ]
};

ECharts 3 中的 series.data

ECharts 4 仍然支持 ECharts 3 中的数据声明方式。如果系列已经声明了 series.data,那么会使用 series.data 而不是 dataset

option = {
  xAxis: {
    type: 'category',
    data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie']
  },
  yAxis: {},
  series: [
    {
      type: 'bar',
      name: '2015',
      data: [89.3, 92.1, 94.4, 85.4]
    },
    {
      type: 'bar',
      name: '2016',
      data: [95.8, 89.4, 91.2, 76.9]
    },
    {
      type: 'bar',
      name: '2017',
      data: [97.7, 83.1, 92.5, 78.1]
    }
  ]
};

事实上,series.data 是一种重要的设置方法,它将一直存在。一些特殊的非表格格式图表,如矩形树图关系图路径图,仍然不能在 dataset 中编辑,你仍然需要使用 series.data。另一方面,对于渲染海量数据(超过一百万),你需要使用 dataset 不支持的 appendData

其他

目前支持 dataset 的图表有:line(折线图)、bar(柱状图)、pie(饼图)、scatter(散点图)、effectScatter(涟漪散点图)、parallel(平行坐标系)、candlestick(K线图)、map(地图)、funnel(漏斗图)、custom(自定义系列)。ECharts 将来会支持更多图表。

最后,这里是一个多个图表共享一个 dataset 并进行联动交互的示例

贡献者 在 GitHub 上编辑此页

plainheartpissangOvilia100pahHertz-HuBruce20190410YuanyeChisimonmcconnell