[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