数据处理
| 术语 | 名称 | 说明 |
|---|---|---|
| 数据集 | DataSet | 数据集合 |
| 数据视图 | DataView | 具有特定结构的数据,如二维数据、树形数据、图数据、地理信息数据 |
| 状态量 | state | 数据集内部流转的控制数据状态的变量 |
| 变换 | Transform | 数据变换函数,对数据进行过滤,格式化等处理 |
| 连接器 | Connector | 数据接入函数,用于将数据源记载到数据视图中 |
安装
shell
npm i @antv/data-setDataSet
js
import DataSet from "@/antv/data-set";
DataSet.connectors; // 存储已注册的 Connector
DataSet.transforms; // 存储已注册的 Transform
const ds = new DataSet({
state: {
key: "val",
},
});
ds.isDataSet;
ds.views;
ds.state;
const dv = ds.createView("dvName", {
watchingStates: ["key"],
});
ds.setView("oo", dv);
ds.getView("oo");
ds.setState("key", "value");
// DataSet 继承自 EventEmitter
ds.on("statechange", (key, val) => {});
ds.emit();DataView
js
const dv = new DataSet.DataView(ds, {
watchingStates: ["key"], // 默认监听 ds 上所有状态
});
dv.isView;
dv.loose; // 是否关联了数据集
dv.dataType; // 数据类型,默认 DataSet.TABLE (二维数据), 还支持 .GEO(地理) .HIERARCHY(树) .GRAPH(图)
dv.origin; // 原始数据
dv.rows; // 处理后数据
dv.transforms;
dv.source(data, {}); //
dv.transform({});方法
js
// 注册数据连接函数
const connectorName = "parse-some-data";
DataSet.registerConnector(connectorName, (data, options) => {
// 对原始数据处理后返回
return data;
});
DataSet.getConnector(connectorName);
const dv = new DataSet.View().source(mockData, { type: connectorName });
dv.rows; // 解析后的数据
// 注册数据转换函数
const transformName = "format-some-data";
DataSet.registerTransform(transformName, (dv, options) => {
// 对解析后数据进行转换
dv.rows = dv.rows.map(options.someFormat);
});
DataSet.getTransform(transformName);
dv.transform({
type: transformName,
someFormat(row) {
return row;
},
});Connector
js
dv.source(data, { type: "dsv", delimiter: "|" }); // 解析 dsv
dv.source(data, { type: "csv", delimiter: "," }); // 解析 csv
dv.source(data, { type: "tsv" }); // 解析 tsv
dv.source(data, { type: "GeoJSON" }); // 别名 'geo' | 'geojson'
dv.source(data, {
type: "TopoJSON", // 别名 'topojson'
object: "xxx", // 每一个 object 相当于一份 GeoJSON 数据,指定 object 相当于提取一份 geo 数据
});
dv.source(data, {
// dv.root 为根节点
type: "hierarchy", // 别名 'tree'
children: d => d.children, // 定义获取子树的方式
});
dv.source(data, {
type: "graph",
nodes: d => d.nodes,
edges: d => d.edges,
});Transform
静态处理相关
js
const dv = new DateView().source(data);
dv.transform({
type: "filter",
callback(row) {
return true;
},
});
dv.transform({
type: "map",
callback(row) {
return row;
},
});
dv.transform({
type: "pick",
fields: ["field"], // 字段提取, 如 [{ field: 'f', others: 'o' }] -> [{ field: 'f' }]
});
dv.transform({
type: "rename",
map: {
a: "x",
b: "y",
},
});
dv.transform({
type: "reverse",
});
dv.transform({
type: "sort",
callback(a, b) {
return a.val - b.val;
},
});
dv.transform({
type: "sort-by",
fields: ["field"],
order: "DESC", // 默认 ASC(升序)
});
dv.transform({
type: "subset", // 获取子集
startRowIndex: 1,
endRowIndex: 2,
fields: ["field"],
});
dv.transform({
type: "partition",
groupBy: ["field"],
orderBy: ["value"],
});
dv.rows;数据形变补全
js
// 根据字段分组排序后填充剩余字段
// fillBy: 'group' 以最长组为基准,对缺省组进行数据补全
// fillBy: 'order' 以排序字段为基准,对缺省组进行数据补全
dv.transform({
type: "fill-rows",
groupBy: ["field"],
orderBy: ["value"],
fillBy: "group", // 默认 'group', 可选 'order'
});
// 字段补全,用于数据缺省状态
// 如 [{ x: 1, y: 0 }, { x: 2 }] -> [{ x: 1, y: 0 }, { x: 2, y: 0 }]
dv.transform({
type: "impute",
field: "y", // 待补全字段
groupBy: ["x"], // 分组字段集
method: "max", // 补全字段时执行的规则, 支持 'max' | 'min' | 'median' | 'mean' | 'value'
// value: 0 // method 指定为 'value' 时 指定填充的常量
});
// 将数据按指定字段进行展开
dv.transform({
type: "fold",
fields: ["field"],
key: "key",
value: "val",
});数据比例转换
- 'percent': 统计 '数据值' 的占比
- 'proportion': 统计 '数据条数' 的占比
js
dv.transform({
type: "percent",
field: "field",
dimension: "", // 统计的维度字段, 每个不同的 dimension 下, field 值占总和的百分比
groupBy: ["category"],
as: "percent", // 结果存储在指定字段
});
// 统计某个维度下某个字段的数据条数占总条数的比例
dv.transform({
type: "proportion",
dimension: "",
groupBy: ["category"],
as: "proportion",
});数据统计相关
js
dv.transform({
type: "aggregate", // 别名 'summary'
fields: [],
operations: [],
as: [],
groupBy: [],
});
// 支持的 operations 有:
// count | max | min | mean | median |
// mode | product | standardDeviation
// sum | sumSimple | variance
// 计算两个字段的回归拟合曲线
dv.transform({
type: "regression",
method: "linear",
fields: ["x", "y"],
bandwidth: 0.1,
extent: [0, 5],
as: ["x", "y"],
});
// 支持的回归算法类型
// linear | exponential | logarithmic | power | polynomial数据分箱
js
// 直方图分箱
dv.transform({
type: "bin.histogram", // 直方图分箱
field: "a",
bins: 30, // 分箱个数
binWidth: 10, // 分箱步长,覆盖 bins 选项
offset: 0, // 分箱偏移量
groupBy: [], // 用于层叠直方图
as: ["x", "count"],
});
dv.transform({
type: "bin.quantile", // 分位置分箱
field: "y",
as: "_bin",
groupBy: [],
fraction: 4, // 默认四分位
p: [0.5, 0.3], // p参数列表,与 fraction 二选一
});
// 六边形分箱
dv.transform({
type: "bin.hexagon",
fields: ["a", "b"],
bins: [30, 30],
binWidth: [10, 1000],
offset: [0, 0],
sizeByCount: false,
as: ["x", "y", "count"],
});
// 矩形分箱
dv.transform({
type: "bin.rectangle",
fields: ["a", "b"],
bins: [30, 30],
binsWidth: [10, 10],
offset: [0, 0],
sizeByCount: false,
as: ["x", "y", "count"],
});核函数(略)
树
js
// 树形图
dv.transform({
type: "hierarchy.treemap",
field: "value",
tile: "treemapSquarify", // 布局类型
size: [1, 1], // width, height
round: false,
padding: 0,
paddingInner: 0,
paddingOuter: 0,
paddingTop: 0,
paddingRight: 0,
paddingLeft: 0,
paddingBottom: 0,
as: ["x", "y"],
});
// 支持的布局类型
// treemapBinary | treemapDice | treemapSlice | treemapSliceDice | treemapSquarify | treemapResquarify
// 相邻层次图
dv.transform({
type: "hierarchy.partition",
field: "value",
size: [1, 1],
round: false,
padding: 0,
as: ["x", "y"],
});图
js
// 弧长链接图
dv.transform({
type: "diagram.arc",
y: 0,
thickness: 0.05, // 节点高度,区间 (0, 1)
weight: false, // 是否带权重,无权重为弧长链接图,带权重为和弦图
marginRatio: 0.1, // 空隙比例,区间[0, 1)
id: (node) => node.id, // 获取节点id
source: (edge) => edge.source, // 获取边起始点id
target: (edge) => edge.target, // 获取边结束点id
sourceWeight: (edge) => edge.value, // 获取边起始点权重
targetWeight: (edge) => edge.value1, // 获取边结束点权重
sortBy: null, // 排序,可以按照id,权重('weight')或者边数量('frequency')排序,也可以自定排序函数
});
// 桑基图
dv.transform({
type: 'diagram.sankey',
source: (edge) => edge.source, // 边起点id
target: (edge) => edge.target, // 边终点id
nodeAlign: 'sankeyJustify', // sankeyLeft / sankeyRight / sankeyCenter
nodeWidth: 0.02, // 节点宽,范围:(0, 1)
nodePadding: 0.02, // 节点上下间距,范围:(0, 1)
sort: undefined | null | ((a: any, b: any) => number); // 同列节点排序 undefined 默认值 在每次迭代过程中按宽度递增、null 按照数据排序 不重新排序、function 根据指定函数进行排序,并在初始化的时候排序一次
});
// voronoi 图
dv.transform({
type: 'diagram.voronoi',
fields: ['field0', 'field1'], // 对应坐标轴上的一个点
extend: [
[x0, y0],
[x1, y1],
], // 范围
size: [width, height], // 范围
as: ['x', 'y'], // 每个点包围多边形的顶点集
// x: [ x0, x1, x2, ... ], y: [ y0, y1, y2, ... ]
});地理数据
js
// 地理映射
dv.transform({
type: "geo.projection",
projection: "geoAiry", // 指定映射类型
as: ["x", "y", "centroid_x", "centroid_y"], // x,y是对应多边形的顶点集
// centroid_x是中心点的x坐标
// centroid_y是中心点y坐标
});
// 由地名获取地理位置点
dv.transform({
type: "geo.centroid",
field: "name", // 标注地名的字段
geoDataView: geoDataView, // 使用的geo数据来源,可以是DataView实例,也可以是DataView实例的name
as: ["_centroid_x", "_centroid_y"], // _centroid_x是中心点的x坐标
// _centroid_y是中心点y坐标
});
// 由地名获取地理位置区域
dv.transform({
type: "geo.region",
field: "name", // 标注地名的字段
geoDataView: geoDataView, // 使用的geo数据来源,可以是DataView实例,也可以是DataView实例的name
as: ["_x", "_y"], // 多边形的顶点集
// _x: [ x0, x1, x2, ... ], _y: [ y0, y1, y2, ... ]
});词云布局
js
dv.transform({
type: "tag-cloud",
fields: ["text", "value"], // 参与标签云layout的字段集(前者为文本内容,后者为权重值)
font: "serif", // 标签字体
size: [500, 500], // 画布size,[ width, height ]
padding: 0,
spiral: "archimedean", // 标签螺旋排布规律函数 'archimedean' || 'rectangular' || {function}
fontSize(d) {
return d.value;
}, // 计算标签字体大小的回调函数,d为一行数据
timeInterval: Infinity, // 最大迭代时间,默认为无限大
imageMask: { Image }, // Image的实例,必须是 loaded 状态
});