创建 View

G2 的图表可以由多个视图 View 构成,同时各个视图可以拥有各自的数据源,即支持异构数据。在结构上,视图和 chart 相同,拥有自己独立的数据源、坐标系和图层。

Chart 是一种特殊的View,两者之间也有一定的差异:

  • View 的功能 Chart 都具有
  • Tooltip(提示信息)和 Legend(图例)仅在 Chart 上支持
  • Chart 上可以创建 View ,但是 View 不再支持创建子 View

如何创建视图

直接通过调用 chart.view(cfg) 即可创建 View 对象,此时会默认创建一个绘图区域于 Chart 相同的视图,当然你可以为 view 手动设置 startend 属性手动指定绘制范围,如下所示:

  1. // step 1: 需要创建 chart 对象
  2. const chart = new G2.Chart({
  3. id: 'c1',
  4. width: 1000,
  5. height: 500,
  6. padding: [ 20, 200 ]
  7. });
  8. // step 2: 然后创建一个视图
  9. const view = chart.view({
  10. start: {
  11. x: 0.2,
  12. y: 0.2
  13. }, // 指定该视图绘制的起始位置,x y 为 [0 - 1] 范围的数据
  14. end: {
  15. x: 1,
  16. y: 1
  17. }, // 指定该视图绘制的结束位置,x y 为 [0 - 1] 范围的数据
  18. padding: [ 20, 40 ] // 指定视图的留白
  19. });

这里需要说明的是:

  • 为了让用户更好更快速得指定视图的绘制区域,start 和 end 这两个参数只接受 0 至 1 范围的数据。
  • View 的绘制起始点是画布左上角。
    创建好 view 之后,就可以同 chart 一样载入数据,使用图形语法进行图表的绘制了,语法同 chart。在这里,view 并不负责最后的画布绘制,统一由 chart 对象进行渲染,即 chart.render()
  1. view.source(data); // 为 View 载入数据
  2. view.interval().position('x*y').color('x'); // 使用图形语法绘制图表
  3.  
  4. chart.render(); // 由 chart 负责统一的渲染

关于 view 的更多方法请查看 view api。

示例

在进行地理数据的可视化的时候,使用多视图的绘制方式就会非常方便。

通常情况下,地理数据的可视化会包含多份数据:一份是用于绘制地图的经纬度数据,一份是用户真正想要可视化的用户数据。

在这个例子中,需要在世界地图上标注各个国家的男女比例情况,这个时候就可以使用多视图的可视化方案:

  • 首先绘制世界地图背景,使用包含世界地图经纬度的数据;
  • 然后再可视化包含各个国家男女比例的用户数据。
  1. $.getJSON('/assets/data/world.geo.json', function(mapData) {
  2. const chart = new G2.Chart({
  3. container: 'c1',
  4. forceFit: true,
  5. height: 450,
  6. padding: [ 55, 20 ]
  7. });
  8. chart.tooltip({
  9. showTitle: false
  10. });
  11. // 同步度量
  12. chart.scale({
  13. longitude: {
  14. sync: true
  15. },
  16. latitude: {
  17. sync: true
  18. },
  19. });
  20. chart.axis(false);
  21. chart.legend('trend', {
  22. position: 'left'
  23. });
  24.  
  25. // 绘制世界地图背景
  26. const ds = new DataSet();
  27. const worldMap = ds.createView('back')
  28. .source(mapData, {
  29. type: 'GeoJSON'
  30. });
  31. const worldMapView = chart.view();
  32. worldMapView.source(worldMap);
  33. worldMapView.tooltip(false);
  34. worldMapView.polygon().position('longitude*latitude').style({
  35. fill: '#fff',
  36. stroke: '#ccc',
  37. lineWidth: 1
  38. });
  39.  
  40. // 可视化用户数据
  41. const userData = [
  42. { name: 'Russia', value: 86.8 },
  43. { name: 'China', value: 106.3 },
  44. { name: 'Japan', value: 94.7 },
  45. { name: 'Mongolia', value: 98 },
  46. { name: 'Canada', value: 98.4 },
  47. { name: 'United Kingdom', value: 97.2 },
  48. { name: 'United States of America', value: 98.3 },
  49. { name: 'Brazil', value: 96.7 },
  50. { name: 'Argentina', value: 95.8 },
  51. { name: 'Algeria', value: 101.3 },
  52. { name: 'France', value: 94.8 },
  53. { name: 'Germany', value: 96.6 },
  54. { name: 'Ukraine', value: 86.3 },
  55. { name: 'Egypt', value: 102.1 },
  56. { name: 'South Africa', value: 101.3 },
  57. { name: 'India', value: 107.6 },
  58. { name: 'Australia', value: 99.9 },
  59. { name: 'Saudi Arabia', value: 130.1 },
  60. { name: 'Afghanistan', value: 106.5 },
  61. { name: 'Kazakhstan', value: 93.4 },
  62. { name: 'Indonesia', value: 101.4 }
  63. ];
  64. const userDv = ds.createView()
  65. .source(userData)
  66. .transform({
  67. geoDataView: worldMap,
  68. field: 'name',
  69. type: 'geo.region',
  70. as: [ 'longitude', 'latitude' ]
  71. })
  72. .transform({
  73. type: 'map',
  74. callback: obj => {
  75. obj.trend = (obj.value > 100) ? '男性更多' : '女性更多';
  76. return obj;
  77. }
  78. });
  79. const userView = chart.view();
  80. userView.source(userDv, {
  81. 'trend': {
  82. alias: '每100位女性对应的男性数量'
  83. }
  84. });
  85. userView.polygon()
  86. .position('longitude*latitude')
  87. .color('trend', [ '#C45A5A', '#14647D' ])
  88. .opacity('value')
  89. .tooltip('name*trend')
  90. .animate({
  91. leave: {
  92. animation: 'fadeOut'
  93. }
  94. });
  95. chart.render();
  96. });

自定义 动画 图形语法简介

原文: https://antv.alipay.com/zh-cn/g2/3.x/tutorial/how-to-create-view.html