Skip to content

Commit

Permalink
修改dataset部分内容
Browse files Browse the repository at this point in the history
  • Loading branch information
BambooSword committed Dec 19, 2017
1 parent e460214 commit 81abc4b
Showing 1 changed file with 67 additions and 136 deletions.
203 changes: 67 additions & 136 deletions doc/tutorial/dataset.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# DataSet

自G2 3.0版本开始,原先内置的数据处理模块frame从G2包中抽离出来,独立成为DataSet包。DataSet的目标是为数据可视化场景提供状态驱动(state driven)的、丰富而强大的数据处理能力。
自BizChars 3.0版本开始,原先内置的数据处理模块frame从BizChars包中抽离出来,独立成为DataSet包。DataSet的目标是为数据可视化场景提供状态驱动(state driven)的、丰富而强大的数据处理能力。
BizCharts 对数据的支持跟G2一致,通用支持独立的 DataSet 包。

## 术语表
Expand All @@ -16,9 +16,9 @@ BizCharts 对数据的支持跟G2一致,通用支持独立的 DataSet 包。

## 简介

G2 的 1.x 和 2.x 版本里,统计函数和数据处理是和图形语法混合在一起的。这一方面导致了不必要的隐喻,造成额外的理解成本,另一方面把数据处理模块( Frame 和 Stat )内置也限制了 G2 数据处理能力的进一步发展。
BizChars 的 1.x 和 2.x 版本里,统计函数和数据处理是和图形语法混合在一起的。这一方面导致了不必要的隐喻,造成额外的理解成本,另一方面把数据处理模块( Frame 和 Stat )内置也限制了 BizChars 数据处理能力的进一步发展。

为追求更极致的体验,我们把数据处理部分从 G2 中完全抽离出来,对数据处理本身进行了进一步的抽象,扩展和优化,从而实现了一个独立的数据处理模块 DataSet。
为追求更极致的体验,我们把数据处理部分从 BizChars 中完全抽离出来,对数据处理本身进行了进一步的抽象,扩展和优化,从而实现了一个独立的数据处理模块 DataSet。

首先我们把数据处理分为两个大的步骤:数据连接(Connector)和数据转换(Transform)。Connector 负责导入和归一化数据(譬如导入 CSV 数据,导入 GeoJSON 数据等),Transform 负责进行各种数据转换操作(譬如图布局、数据统计、数据补全等)。通过这样的分层,支持了前端社区非常全面的数据处理相关的算法和模块;其次,我们在单个数据视图(DataView)的基础上增加了数据集(DataSet)的概念,通过统一的 DataSet 管理,实现了各个数据视图之间的状态同步和交互。整个数据处理模块的架构如下图。

Expand All @@ -32,7 +32,7 @@ BizCharts 对数据的支持跟G2一致,通用支持独立的 DataSet 包。

```html
<!-- 引入在线资源 -->
<script src="{{ url.dataSet }}"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/data-set/0.8.0/data-set.min.js"></script>
```

```html
Expand All @@ -43,7 +43,7 @@ BizCharts 对数据的支持跟G2一致,通用支持独立的 DataSet 包。
这样,就可以在后续脚本中得到全局变量 DataSet。

```html
<script src="{{ url.dataSet }}"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/data-set/0.8.0/data-set.min.js"></script>
<script>
var dv = new DataSet.View();
</script>
Expand All @@ -67,9 +67,57 @@ const dv = new View();
```

## api文档
DataSet 主要完成了以下功能:
*源数据的解析,将csv, dsv,geojson 转成标准的JSON
*加工数据,包括 filter,map,fold(补数据) 等操作
*统计函数,汇总统计、百分比、封箱 等统计函数
*特殊数据处理,包括 地理数据、矩形树图、桑基图、文字云 的数据处理
具体参见[dataset api 文档](../api/dataset.md)

## 使用实例
## 使用示例

### 单独使用 DataView
如果仅仅是对数据进行加工,不需要图表联动

### 状态量
在G2 3.0 中使用 DataSet 的状态量(State) 可以很容易的实现图表的联动,步骤如下:
1.创建 DataSet 对象,指定状态量
2.创建 DataView 对象,在 transform 中使用状态量
3.创建图表,引用前面创建 DataView
4.改变状态量,所有 DataView 更新

```js
// step1 创建 dataset 指定状态量
const ds = new DataSet({
state: {
year: '2010'
}
});

// step2 创建 DataView
const dv = ds.createView().source(data);

dv.transform({
type: 'filter',
callback(row) {
return row.year === ds.state.year;
}
});


// step3 引用 DataView
<Chart data={dv}>
</Chart>

// step4 更新状态量
ds.setState('year', '2012');

```
####注意:
*在 DataSet 创建了状态量后,默认会影响其管理的所有的 DataView, 可以通过 watchingStates 明确的指定受那些状态量影响,设置为空数组时不受状态量的影响。
*所有引用了 DataSet 管理的 DataView 的图表都会受自动刷新,不需要手工刷新。

### 图表联动示例

假设我们有一个 CSV 文件 `population-by-age.csv`,里面的数据是美国各个州不同年龄段的人口数量,文件内容如下:

Expand Down Expand Up @@ -126,135 +174,18 @@ dvForAll.transform({
> Step4:为饼图创建数据视图实例,继承上一个数据视图的数据,通过状态量 currentState 过滤数据、统计不同年龄段人口占比
```js
const dvForOneState = ds
.createView('populationOfOneState')
.source(dvForAll); // 从全量数据继承,写法也可以是 .source('populationByAge')

dvForOneState
.transform({ // 过滤数据
type: 'filter',
callback(row) {
return row.state === ds.state.currentState;
}
})
.transform({
type: 'percent',
field: 'population',
dimension: 'age',
as: 'percent'
});
```

> Step5:最后使用 G2 绘图、绑定事件
> 效果:
<div id="c1"></div><div id="c2"></div>

> 代码:
```js+
var ds = new DataSet({
state: {
currentState: 'WY'
}
});
$.get('/assets/data/population-by-age.csv', function(data) {
var dvForAll = ds
.createView('populationByAge', {
watchingStates: [], // 用空数组,使得这个实例不监听 state 变化
}) // 在 DataSet 实例下创建名为 populationByAge 的数据视图
.source(data, { // 使用 CSV 类型的 Connector 装载 data
type: 'csv',
});
dvForAll
.transform({ // 合并列
type: 'fold',
fields: [ '小于5岁','5至13岁','14至17岁','18至24岁','25至44岁','45至64岁','65岁及以上' ],
key: 'age',
value: 'population'
})
.transform({
type: 'map',
callback: function(row) {
row.population = parseInt(row.population, 10);
return row;
}
});
var dvForOneState = ds
.createView('populationForOneState')
.source(dvForAll);
dvForOneState
.transform({ // 过滤数据
type: 'filter',
callback: function(row) {
return row.state === ds.state.currentState;
}
})
.transform({
type: 'percent',
field: 'population',
dimension: 'age',
as: 'percent'
});
console.log(dvForAll, dvForOneState);
G2.Global.widthRatio.column = .95;
var c1 = new G2.Chart({
id: 'c1',
forceFit: true,
height: 400,
});
c1.source(dvForAll);
c1.legend({
position: 'top',
});
c1.axis('population', {
label: {
formatter: function(val) {
return val / 1000000 + 'M';
}
}
});
c1.intervalStack()
.position('state*population')
.color('age')
.select(true, {
mode: 'single',
style: {
stroke: 'red',
strokeWidth: 5
}
});
c1.on('tooltip:change', function(evt) {
var items = evt.items || [];
if (items[0]) {
ds.setState('currentState', items[0].title);
}
});
var c2 = new G2.Chart({
id: 'c2',
forceFit: true,
height: 300,
padding: 0,
});
c2.source(dvForOneState);
c2.coord('theta', {
radius: 0.8 // 设置饼图的大小
});
c2.legend(false);
c2.intervalStack()
.position('percent')
.color('age')
.label('age*percent',function(age, percent) {
percent = (percent * 100).toFixed(2) + '%';
return age + ' ' + percent;
});
c1.render();
c2.render();
});
<Chart data={dvForAll} height={400} scale={scale} forceFit={true} >
<Legend position='top' />
<Axis >
<Facet type='list' fields={['cut']} cols={3} padding={30} eachView={(view, facet)=>{
view.point()
.position('carat*price')
.color('cut')
.shape('circle')
.opacity(0.3)
.size(3);
}}>
</Facet>
</Chart>
```

0 comments on commit 81abc4b

Please sign in to comment.