绘制视图 View

G2 的图表 Chart,可以创建多个视图 View,每个 View 各自又可以创建其子 View,即在 G2 4.0 中,View 是支持嵌套的。每个 View 同 Chart 一样,拥有自己独立的数据源、坐标系、几何标记、Tooltip 以及图例,你可以这样理解,其实 Chart 也是一种特殊的 View,在类结构设计上,Chart 和 View 的关系如下: 绘制视图 View - 图1

如何创建视图

直接通过调用 chart.createview() 即可创建 View 对象,此时会默认创建一个绘图区域于 Chart 相同的视图,当然你可以通过 region 属性指定 view 的绘图区域。

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

这里需要说明的是:

  • 为了让用户更好更快速得指定视图的绘制区域,start 和 end 这两个参数只接受 0 至 1 范围的数据。
  • View 的绘制起始点是画布左上角。 创建好 view 之后,就可以同 chart 一样载入数据,使用图形语法进行图表的绘制了,语法同 chart。

说明:需要注意的是,view 并不负责最后的画布绘制,统一由 chart 对象进行渲染,即 chart.render()

  1. view.data(data); // 为 View 载入数据
  2. view
  3. .interval()
  4. .position('x*y')
  5. .color('x'); // 使用图形语法绘制图表
  6. chart.render(); // 由 chart 负责统一的渲染

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

示例

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

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

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

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

实例链接