[TOC]
- Facet 分面如何设置分面分面的类型rect 矩形分面list 水平列表分面circle 圆形分面tree 树形分面mirror 镜像分面matrix 矩阵分面
Facet 分面
分面,将一份数据按照某个维度分隔成若干子集,然后创建一个图表的矩阵,将每一个数据子集绘制到图形矩阵的窗格中。
总结起来,分面其实提供了两个功能:
- 按照指定的维度划分数据集;
- 对图表进行排版。对于探索型数据分析来说,分面是一个强大有力的工具,能帮你迅速地分析出数据各个子集模式的异同。如何设置分面
chart.facet(type, { fileds: [field1, field2...], showTitle: true, // 显示标题 autoSetAxis: true,// 自动设置坐标轴的文本,避免重复和遮挡 padding: 10, // 每个view 之间的间距 /** * 创建每个分面中的视图 * @param {object} view 视图对象 * @param {object} facet facet中有行列等信息,常见属性:data rows cols rowIndex colIndex rowField colField * @return {null} */ eachView(view, facet) {}, // 列标题 colTitle: { offsetY: -15, style: { fontSize: 14, textAlign: 'center', fill: '#444' } }, // 行标题 rowTitle: { offsetX: 15, style: { fontSize: 14, textAlign: 'center', rotate: 90, fill: '#444' } }})
说明:
- 第一个参数 type 用于指定分面的类型;
- fileds 属性用于指定数据集划分依据的字段;
- eachView 回调函数中创建各个视图的图表类型;也可以设置每个分面之间的间距 padding
chart.facet('list', { fileds: [ 'cut', 'carat' ], padding: 20 // 各个分面之间的间距,也可以是数组 [top, right, bottom, left]});
更多配置信息,请查阅 Facet API。
分面的类型
G2 支持的分面类型如下表所示:
| 分面类型 | 说明 |
|---|---|
| rect | 默认类型,指定 2 个维度作为行列,形成图表的矩阵。 |
| list | 指定一个维度,可以指定一行有几列,超出自动换行。 |
| circle | 指定一个维度,沿着圆分布。 |
| tree | 指定多个维度,每个维度作为树的一级,展开多层图表。 |
| mirror | 指定一个维度,形成镜像图表。 |
| matrix | 指定一个维度,形成矩阵分面。 |
rect 矩形分面
rect 矩形分面是 G2 的默认分面类型。支持按照一个或者两个维度的数据划分,按照先列后行的顺序。
chart.facet('rect', { fields: [ 'cut', 'clarity' ], eachView(view) { view.point().position('carat*price').color('cut'); }});
分面矩阵每列按照 cut 字段划分,每行按照 clarity 字段划分。
$.getJSON('/assets/data/diamond.json', function(data) { const chart = new G2.Chart({ container: 'c1', forceFit: true, height: 600, padding: [ 30, 80, 80, 80 ] }); chart.source(data, { carat: { sync: true }, price: { sync: true }, cut: { sync: true } }); chart.facet('rect', { fields: [ 'cut', 'clarity' ], eachView(view) { view.point().position('carat*price').color('cut'); } }); chart.render();});
说明:
- 可以将 fields 字段中表示行和列的字段名时,可以设置行或者列为 null,会变成单行或者单列的分面
list 水平列表分面
该类型分面可以通过设置 cols 属性来指定每行可显示分面的个数,超出时会自动换行。
$.getJSON('/assets/data/diamond.json', function(data) { const chart = new G2.Chart({ container: 'c2', width: 800, height: 400, padding: [ 30, 90, 80, 80 ] }); chart.source(data, { carat: { sync: true }, price: { sync: true }, cut: { sync: true } }); chart.facet('list', { fields: [ 'cut' ], cols: 3, // 超过3个换行 padding: 30, eachView(view) { view.point().position('carat*price').color('cut'); } }); chart.render();});
circle 圆形分面
const DataView = DataSet.DataView;$.getJSON('/assets/data/diamond.json',function (data) { const chart = new G2.Chart({ container: 'c3', width: 600, height: 600, animate: false, padding: [ 20, 20, 70, 20 ] }); chart.source(data, { mean: { sync: true }, cut: { sync: true } }); chart.coord('polar'); chart.axis(false); chart.facet('circle', { fields: [ 'clarity' ], padding: 0, eachView(view, facet) { const data = facet.data; const dv = new DataView(); dv.source(data).transform({ type: 'aggregate', fields: [ 'price' ], operations: [ 'mean' ], as: [ 'mean' ], groupBy: [ 'cut' ] }); view.source(dv); view.interval().position('cut*mean').color('cut'); } }); // 分面设置 chart.render();});
tree 树形分面
树形分面一般用于展示存在层次结构的数据,展示的是整体和部分之间的关系
提供了 line 和 lineSmooth 两个属性,用于配置连接各个分面的线的样式,其中:
- line,用于配置线的显示属性。
- lineSmooth,各个树节点的连接线是否是平滑的曲线,默认为 false。
下图展示了树形多层级的分面。
const data = [ { gender: '男', count: 40, class: '一班', grade: '一年级' }, { gender: '女', count: 30, class: '一班', grade: '一年级' }, { gender: '男', count: 35, class: '二班', grade: '一年级' }, { gender: '女', count: 45, class: '二班', grade: '一年级' }, { gender: '男', count: 20, class: '三班', grade: '一年级' }, { gender: '女', count: 35, class: '三班', grade: '一年级' }, { gender: '男', count: 30, class: '一班', grade: '二年级' }, { gender: '女', count: 40, class: '一班', grade: '二年级' }, { gender: '男', count: 25, class: '二班', grade: '二年级' }, { gender: '女', count: 32, class: '二班', grade: '二年级' }, { gender: '男', count: 28, class: '三班', grade: '二年级' }, { gender: '女', count: 36, class: '三班', grade: '二年级' }];const DataView = DataSet.DataView;const chart = new G2.Chart({ container: 'c4', width: 800, height: 400, animate: false, padding: [ 0, 90, 80, 80 ]});chart.source(data);chart.coord('theta');chart.tooltip({ showTitle: false});chart.facet('tree', { fields: [ 'grade','class' ], line: { stroke: '#00a3d7' }, lineSmooth: true, eachView(view, facet) { const data = facet.data; const dv = new DataView(); dv.source(data).transform({ type: 'percent', field: 'count', dimension: 'gender', as: 'percent' }); view.source(dv, { percent: { formatter(val) { return (val * 100).toFixed(2) + '%'; } } }); view.intervalStack().position('percent').color('gender'); }}); chart.render();
mirror 镜像分面
镜像分面一般用于对比两类数据的场景,例如 男女的比例、正确错误的对比等
通过配置 transpose 属性为 true,可以将镜像分面翻转。
选择年份
$.getJSON('/assets/data/population.json', function(data) { const tmp = []; const dates = []; const selEl = $('#selYear'); data.male.values.forEach(function(obj) { if (dates.indexOf(obj.date) === -1) { dates.push(obj.date); } obj.age_groups.forEach(function(subObject) { subObject.gender = 'male'; subObject.date = obj.date; tmp.push(subObject); }); }); data.female.values.forEach(function(obj) { obj.age_groups.forEach(function(subObject) { subObject.gender = 'female'; subObject.date = obj.date; tmp.push(subObject); }); }); dates.forEach(date => { $('<option value="' + date + '">' + new Date(date * 1000).getFullYear() + '</option>').appendTo(selEl); }); const ds = new DataSet({ state: { date: dates[0] } }); const dv = ds.createView() .source(tmp) .transform({ type: 'filter', callback(row) { // 判断某一行是否保留,默认返回true return new Date(row.date * 1000).getFullYear() === new Date(ds.state.date * 1000).getFullYear(); } }); const chart = new G2.Chart({ container: 'c5', forceFit: true, height: 600 }); chart.source(dv, { age: { sync: true, tickCount: 11 }, total_percentage: { sync: true, formatter(v) { return v + '%'; } }, gender: { sync: true } }); chart.facet('mirror', { fields: [ 'gender' ], transpose: true, eachView(view) { view.interval().position('age*total_percentage') .color('gender', [ 'rgb(113,192,235)', 'rgb(246,170,203)' ]); } }); chart.render(); selEl.on('change', function() { const val = selEl.val(); const date = parseInt(val); ds.setState('date', date); });});
matrix 矩阵分面
矩阵分面主要对比数据中多个字段之间的关系,例如常见的散点矩阵图
const DataView = DataSet.DataView;$.getJSON('/assets/data/iris.json', function(data) { const chart = new G2.Chart({ container: 'c6', forceFit: true, height: 600 }); chart.source(data, { Species: { sync: true } }); chart.facet('matrix', { fields: [ 'SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth' ], eachView(view, facet) { if (facet.rowIndex === facet.colIndex) { const dv = new DataView(); dv.source(facet.data) .transform({ type: 'bin.histogram', field: facet.colField, // 对应数轴上的一个点 bins: 30, // 分箱个数 as: [ facet.colField, 'count' ], groupBy: [ 'Species' ] }); view.source(dv.rows); view.intervalStack() .position(facet.colField + '*count') .color('Species', [ '#880000', '#008800', '#000088' ]); } else { view.point() .position([ facet.colField, facet.rowField ]) .color('Species', [ '#880000', '#008800', '#000088' ]); } } }); chart.render();});
Guide 辅助元素 Theme 图表皮肤主题
原文: https://antv.alipay.com/zh-cn/g2/3.x/tutorial/facet.html
