Guide 辅助元素

Guide 作为 G2 图表的辅助元素,主要用于在图表上标识额外的标记注解。
Guide 辅助元素 - 图1

guide 类型

G2 目前支持 9 种辅助标记类型:

  • line:辅助线(可带文本),例如表示平均值或者预期分布的直线;
  • image:辅助图片,在图表上添加辅助图片;
  • text:辅助文本,指定位置添加文本说明;
  • region:辅助框,框选一段图区,设置背景、边框等;
  • regionFilter:区域着色,将图表中位于矩形选区中的图形元素提取出来,重新着色;
  • html:辅助 html,指定位置添加自定义 html,显示自定义信息;
  • arc:辅助弧线。
  • dataMarker:特殊数据点标注,多用于折线图和面积图
  • dataRegion:特殊数据区间标注,多用于折线图和面积图

如何使用

下面列出了各个 guide 辅助标记类型的使用,更详细的配置项参见 Guide API

guide 辅助标记用于标示位置的方式主要有两种

  • 原始数据的值 如: {time: '2010-01-01', value: 100} 或者 ['2010-01-01', 100]
  • 图表绘图区域的相对位置,从左上角计算 如:['50%', '50%']
    注意

  • 原始数据和百分比的方式不能混用,不支持['2010-01-01', '50%']

  • 不同 guide 中标示位置的参数不完全相同,主要是 start, end, position

line 辅助线

  1. chart.guide().line({
  2. start: {object} | {function} | {array}, // 辅助线起始位置,值为原始数据值,支持 callback
  3. end: {object} | {function}|| {array},// 辅助线结束位置,值为原始数据值,支持 callback
  4. lineStyle: {
  5. stroke: '#999', // 线的颜色
  6. lineDash: [ 0, 2, 2 ], // 虚线的设置
  7. lineWidth: 3 // 线的宽度
  8. }, // 图形样式配置
  9. text: {
  10. position: 'start' | 'center' | 'end' | '39%' | 0.5, // 文本的显示位置
  11. autoRotate: {boolean}, // 是否沿线的角度排布,默认为 true
  12. style: {
  13. // 文本图形样式配置
  14. },
  15. content: {string}, // 文本的内容
  16. offsetX: {number}, // x 方向的偏移量
  17. offsetY: {number} // y 方向的偏移量
  18. } // 文本配置
  19. });
  1. const DataView = DataSet.DataView;
  2. $.getJSON('/assets/data/diamond.json', function(data) {
  3. const dv = (new DataView()).source(data);
  4. const caratAvg = dv.mean('carat'); // 计算克拉数均值
  5. const priceAvg = dv.mean('price'); // 计算价格均值
  6. const chart = new G2.Chart({ // 创建图表
  7. container : 'c1',
  8. forceFit: true,
  9. height: 450
  10. });
  11.  
  12. chart.source(data); // 设置数据源
  13. chart.point().position('carat*price');
  14. chart.guide().line({
  15. start: [ caratAvg, 0 ], // 使用数组格式
  16. end: [ caratAvg, 20000 ],
  17. text: {
  18. position: 'end',
  19. autoRotate: false,
  20. content: '克拉数均值:' + caratAvg
  21. }
  22. });
  23. chart.guide().line({
  24. start: {
  25. carat: 0,
  26. price: priceAvg
  27. }, // 使用对象格式
  28. end: {
  29. carat: 4,
  30. price: priceAvg
  31. },
  32. text: {
  33. position: 'end',
  34. autoRotate: false,
  35. content: '价格均值:' + priceAvg,
  36. style: {
  37. textAlign: 'end'
  38. }
  39. }
  40. });
  41. chart.render(); // 图表渲染
  42. });

image 辅助图片

  1. // 辅助图片 image,只是指定了 start,则该点表示图片左上角坐标
  2. chart.guide().image({
  3. top: {boolean}, // 指定 giude 是否绘制在 canvas 最上层,默认为 false, 即绘制在最下层
  4. zIndex: {number},
  5. start: {object} | {function} | {array}, // 图片起始位置, 值为原始数据值,支持 callback
  6. src: {string}, // 图片路径
  7. width: {number},
  8. height: {number},
  9. offsetX: {number}, // x 方向的偏移量
  10. offsetY: {number} // y 方向偏移量
  11. });
  12. // 辅助图片 image,通过指定 start 和 end 确定图片的位置和宽高
  13. chart.guide().image({
  14. top: {boolean}, // 指定 giude 是否绘制在 canvas 最上层,默认为 false, 即绘制在最下层
  15. start: {array} | {function} | {array}, // 图片起始位置, 值为原始数据值,支持 callback
  16. end: {array} | {function} | {array}, // 图片结束位置, 值为原始数据值,支持 callback
  17. src: {string}, // 图片路径
  18. offsetX: {number}, // x 方向的偏移量
  19. offsetY: {number} // y 方向偏移量
  20. });
  1. const DataView = DataSet.DataView;
  2. $.getJSON('/assets/data/diamond.json', function(data) {
  3. const dv = new DataView();
  4. dv.source(data).transform({
  5. type: 'bin.histogram',
  6. field: 'depth',
  7. binWidth: 0.5,
  8. as: [ 'depth', 'count' ],
  9. });
  10. const chart = new G2.Chart({
  11. container: 'c2',
  12. forceFit: true,
  13. height: 450
  14. });
  15. chart.source(dv);
  16. chart.tooltip({
  17. crosshairs: false
  18. });
  19. chart.interval().position('depth*count').shape('hollowRect');
  20.  
  21. chart.guide().image({
  22. start: [ 55, 200 ],
  23. src: 'https://os.alipayobjects.com/rmsportal/IUYwZOlOpysCUsl.png',
  24. width: 60,
  25. height: 100
  26. });
  27. chart.render();
  28. });

text 辅助文本

  1. chart.guide().text({
  2. top: {boolean}, // 指定 giude 是否绘制在 canvas 最上层,默认为 false, 即绘制在最下层
  3. zIndex: {number},
  4. position: {object} | {function} | {array}, // 文本的起始位置,值为原始数据值,支持 callback
  5. content:
  6. style: {
  7. fill: '#666', // 文本颜色
  8. fontSize: '12', // 文本大小
  9. fontWeight: 'bold' // 文本粗细
  10. rotate: 30 // 旋转角度
  11. }, // 文本的图形样式属性
  12. offsetX: {number}, // x 方向的偏移量
  13. offsetY: {number} // y 方向偏移量
  14. });
  1. const colors = G2.Global.colors;
  2. $.getJSON('/assets/data/diamond.json', function(data) {
  3. const chart = new G2.Chart({ // 创建图表
  4. container : 'c3',
  5. forceFit: true,
  6. height: 450,
  7. padding: [ 20, 90, 60, 80 ]
  8. });
  9. const defs = {
  10. 'cut': {
  11. type: 'cat',
  12. values:[ 'Ideal', 'Premium', 'Very-Good', 'Good', 'Fair' ]
  13. }
  14. };
  15. chart.source(data, defs); // 设置数据源
  16. chart.legend(false);
  17. chart.pointJitter().position('cut*depth').color('cut');
  18. chart.guide().text({
  19. position: [ 'Ideal', 67 ],
  20. content: '越完美的钻石切割工艺越集中',
  21. style: {
  22. fill: colors[0],
  23. textAlign: 'center',
  24. fontSize: 14
  25. }
  26. });
  27. chart.guide().text({
  28. position: [ 'Fair', 63 ],
  29. content: '越差的钻石切割工艺越分散',
  30. style: {
  31. fill: colors[4],
  32. textAlign: 'center',
  33. fontSize: 14
  34. }
  35. });
  36. chart.render(); // 图表渲染
  37. });

region 辅助框

  1. chart.guide().region({
  2. top: {boolean}, // 指定 giude 是否绘制在 canvas 最上层,默认为 false, 即绘制在最下层
  3. start: {object} | {function} | {array}, // 辅助框起始位置,值为原始数据值,支持 callback
  4. end: {object} | {function} | {array},// 辅助框结束位置,值为原始数据值,支持 callback
  5. style: {
  6. lineWidth: 0, // 辅助框的边框宽度
  7. fill: '#f80', // 辅助框填充的颜色
  8. fillOpacity: 0.1, // 辅助框的背景透明度
  9. stroke: '#ccc' // 辅助框的边框颜色设置
  10. } // 辅助框的图形样式属性
  11. });
  1. const data = [
  2. { month: 0, tem: 7, city: 'tokyo' },
  3. { month: 1, tem: 6.9, city: 'tokyo' },
  4. { month: 2, tem: 9.5, city: 'tokyo' },
  5. { month: 3, tem: 14.5, city: 'tokyo' },
  6. { month: 4, tem: 18.2, city: 'tokyo' },
  7. { month: 5, tem: 21.5, city: 'tokyo' },
  8. { month: 6, tem: 25.2, city: 'tokyo' },
  9. { month: 7, tem: 26.5, city: 'tokyo' },
  10. { month: 8, tem: 23.3, city: 'tokyo' },
  11. { month: 9, tem: 18.3, city: 'tokyo' },
  12. { month: 10, tem: 13.9, city: 'tokyo' },
  13. { month: 11, tem: 9.6, city: 'tokyo' },
  14. { month: 0, tem: -0.2, city: 'newYork' },
  15. { month: 1, tem: 0.8, city: 'newYork' },
  16. { month: 2, tem: 5.7, city: 'newYork' },
  17. { month: 3, tem: 11.3, city: 'newYork' },
  18. { month: 4, tem: 17, city: 'newYork' },
  19. { month: 5, tem: 22, city: 'newYork' },
  20. { month: 6, tem: 24.8, city: 'newYork' },
  21. { month: 7, tem: 24.1, city: 'newYork' },
  22. { month: 8, tem: 20.1, city: 'newYork' },
  23. { month: 9, tem: 14.1, city: 'newYork' },
  24. { month: 10, tem: 8.6, city: 'newYork' },
  25. { month: 11, tem: 2.5, city: 'newYork' },
  26. { month: 0, tem: -0.9, city: 'berlin' },
  27. { month: 1, tem: 0.6, city: 'berlin' },
  28. { month: 2, tem: 3.5, city: 'berlin' },
  29. { month: 3, tem: 8.4, city: 'berlin' },
  30. { month: 4, tem: 13.5, city: 'berlin' },
  31. { month: 5, tem: 17, city: 'berlin' },
  32. { month: 6, tem: 18.6, city: 'berlin' },
  33. { month: 7, tem: 17.9, city: 'berlin' },
  34. { month: 8, tem: 14.3, city: 'berlin' },
  35. { month: 9, tem: 9, city: 'berlin' },
  36. { month: 10, tem: 3.9, city: 'berlin' },
  37. { month: 11, tem: 1, city: 'berlin' }
  38. ];
  39. const chart = new G2.Chart({
  40. container: 'c4',
  41. forceFit: true,
  42. height: 450
  43. });
  44. chart.source(data);
  45. chart.line().position('month*tem').color('city');
  46. chart.guide().region({
  47. start: [ 5, 'min' ],
  48. end: [ 7, 'max' ]
  49. }); // 6月 - 8月最低温度
  50. chart.render();

辅助 html

  1. chart.guide().html({
  2. position: {object} | {function} | {array}, // html 的中心位置, 值为原始数据值,支持 callback
  3. alignX: 'left' | 'middle' | 'right',
  4. alignY: 'top' | 'middle' | 'bottom',
  5. offsetX: {number},
  6. offsetY: {number},
  7. html: {string}, // html 代码,也支持callback,可能是最大值、最小值之类的判定
  8. zIndex: {number}
  9. });
  1. const DataView = DataSet.DataView;
  2. $.getJSON('/assets/data/diamond.json', function(data) {
  3. const dv = (new DataView()).source(data);
  4. const caratAvg = dv.mean('carat'); // 计算克拉数均值
  5. const priceAvg = dv.mean('price'); // 计算价格均值
  6. const chart = new G2.Chart({
  7. container: 'c5',
  8. forceFit: true,
  9. height: 450
  10. });
  11. chart.source(data);
  12. chart.point().position('carat*price');
  13. // 坐标点
  14. const point = [ 3.5, 12000 ];
  15. //html字符串
  16. const tooltipHtml = "<div style='border: 2px solid #0f8de8;width: 50px;height: 26px;color: #0f8de8;position: relative;'>" +
  17. "<span style='color:#63c6c2;font-size:15px'>异常值</span>" +
  18. "<div style='width: 0;height: 0;border-bottom: 8px solid #0f8de8;border-right:10px solid transparent;position: absolute;top: 16px;left: 46px;'></div>" +
  19. "</div>";
  20. chart.guide().html({
  21. position: point,
  22. html: tooltipHtml,
  23. alignX: 'right',
  24. alignY: 'bottom',
  25. offsetX: 10
  26. });
  27. chart.render(); // 图表渲染
  28. });

辅助 regionFilter

将图表中位于矩形选区中的图形元素提取出来,重新着色,可以用于区域筛选、图表分段着色。

  1. chart.guide().regionFilter({
  2. top: {boolean}, // 指定 giude 是否绘制在 canvas 最上层,默认为 true, 即绘制在最上层
  3. start: {object} | {function} | {array}, // 辅助框起始位置,值为原始数据值,支持 callback
  4. end: {object} | {function} | {array},// 辅助框结束位置,值为原始数据值,支持 callback
  5. color:'#ccc' //染色色值
  6. apply:{array} //可选,设定regionFilter只对特定geom类型起作用,如apply:['area'],默认regionFilter的作用域为整个图表
  7. });
  1. const data = [
  2. { year: '1991', value: 15468 },
  3. { year: '1992', value: 16100 },
  4. { year: '1993', value: 15900 },
  5. { year: '1994', value: 17409 },
  6. { year: '1995', value: 17000 },
  7. { year: '1996', value: 31056 },
  8. { year: '1997', value: 31982 },
  9. { year: '1998', value: 32040 },
  10. { year: '1999', value: 33233 }
  11. ];
  12. const chart = new G2.Chart({
  13. container: 'c6',
  14. forceFit: true,
  15. height: 450
  16. });
  17. chart.source(data);
  18. chart.scale({
  19. value: {
  20. min: 10000
  21. },
  22. year: {
  23. range: [ 0, 1 ]
  24. }
  25. });
  26. chart.axis('value', {
  27. label: {
  28. formatter: val => {
  29. return (val / 10000).toFixed(1) + 'k';
  30. }
  31. }
  32. });
  33. chart.tooltip({
  34. crosshairs: {
  35. type: 'line'
  36. }
  37. });
  38.  
  39. chart.line().position('year*value').size(2);
  40.  
  41. chart.guide().regionFilter({
  42. start: [ '1991', 'min' ],
  43. end: [ '1995', 'max' ],
  44. color: '#178fff'
  45. });
  46. chart.guide().regionFilter({
  47. start: [ '1995', 'min' ],
  48. end: [ '1999', 'max' ],
  49. color: '#2ec15a'
  50. });
  51. chart.render();

arc 辅助弧线

  1. chart.guide().arc({
  2. top: true | false, // 指定 giude 是否绘制在 canvas 最上层,默认为 false, 即绘制在最下层
  3. start: {object} | {function} | {array}, // 辅助框起始位置,值为原始数据值,支持 callback
  4. end: {object} | {function} | {array},// 辅助框结束位置,值为原始数据值,支持 callback
  5. style: {} // 图形样式属性
  6. });

注意

dataMarker 特殊数据标注点

对图表中的某个特殊数据点进行标注。默认状态的特殊数据标注点由point、line、text三部分组成,同时开放接口对各部分是否显示及显示样式等进行设置。

  1. chart.guide().dataMarker({
  2. top:true | false, // 指定 giude 是否绘制在 canvas 最上层,默认为true, 即绘制在最上层
  3. position: {object} | {function} | {array}, // 标注点起始位置,值为原始数据值,支持 callback ,
  4. content: {string}, // 显示的文本内容
  5. style: {
  6. text: {object},
  7. point:{object},
  8. line:{object}
  9. },//可选,文本/point/line样式
  10. display:{
  11. text:{boolean},
  12. point:{boolean},
  13. line:{boolean}
  14. },//可选,是否显示文本/point/line,默认为全部显示
  15. lineLength:{number},//可选,line长度,default为30
  16. direction:'upward' | 'downward' //可选,朝向,默认为upwaard
  17. });

注意

  • dataMarker 特殊数据标注点,适用于折线图和面积图
  1. var data = [{ year: '1991',value: 3},
  2. { year: '1992',value: 4},
  3. { year: '1993',value: 3.5},
  4. { year: '1994',value: 5},
  5. { year: '1995',value: 4.9},
  6. { year: '1996',value: 6},
  7. { year: '1997',value: 7},
  8. { year: '1998',value: 9},
  9. { year: '1999',value: 13}];
  10. var chart = new G2.Chart({
  11. container: 'c7',
  12. forceFit: true,
  13. height: window.innerHeight
  14. });
  15. chart.source(data);
  16. chart.scale('value', {
  17. min: 0
  18. });
  19. chart.scale('year', {
  20. range: [0, 1]
  21. });
  22. chart.line().position('year*value');
  23. chart.guide().dataMarker({
  24. position: [ '1997', 7 ],
  25. content: '特殊数据标注点'
  26. });
  27. chart.render();

dataRegion 特殊数据区间标注

对图表中的某个特殊数据区间进行标注。

  1. chart.guide().dataRegion({
  2. top:true | false, // 指定 giude 是否绘制在 canvas 最上层,默认为 true, 即绘制在最上层
  3. start: {object} | {function} | {array}, // 标注点起始位置,值为原始数据值,支持 callback ,
  4. end: {object} | {function} | {array}, // 标注点结束位置,值为原始数据值,支持 callback ,
  5. content: {string}, // 显示的文本内容
  6. style: {
  7. text: {object},
  8. point:{object},
  9. line:{object}
  10. },//可选,文本/point/line样式
  11. display:{
  12. text:{boolean},
  13. point:{boolean},
  14. line:{boolean}
  15. },//可选,是否显示文本/point/line,默认为全部显示
  16. lineLength:{number},//可选,line长度,default为30
  17. direction:'upward' | 'downward' //可选,朝向,默认为upwaard
  18. });

注意

  • dataRegion 特殊数据区间标注,适用于折线图和面积图
  1. var data = [{ year: '1991',value: 3},
  2. { year: '1992',value: 4},
  3. { year: '1993',value: 3.5},
  4. { year: '1994',value: 5},
  5. { year: '1995',value: 4.9},
  6. { year: '1996',value: 6},
  7. { year: '1997',value: 7},
  8. { year: '1998',value: 9},
  9. { year: '1999',value: 13}];
  10. var chart = new G2.Chart({
  11. container: 'c8',
  12. forceFit: true,
  13. height: window.innerHeight
  14. });
  15. chart.source(data);
  16. chart.scale('value', {
  17. min: 0
  18. });
  19. chart.scale('year', {
  20. range: [0, 1]
  21. });
  22. chart.line().position('year*value');
  23. chart.guide().dataRegion({
  24. start: [ '1994', 5 ],
  25. end: [ '1996', 6 ],
  26. content: '数据区间标注',
  27. lineLength: 50
  28. });
  29. chart.render();

动态辅助标记

辅助标记接受的位置信息的参数都是原始数据值,辅助标记一旦生成后就是固定了位置,如果数据发生改变,辅助标记就需要删除掉重新创建

  1. // 清除图表
  2. chart.clear();
  3. // 重新声明图形语法
  4. chart.point().position('carat*price');
  5. chart.guide().html([ newX, newY ], htmlstring);
  6. chart.render();
  • newX,newY 是重新计算的位置
    如果数据是动态更新的那么这个过程需要频繁进行,基于这种场景 guide 提供两种计算动态位置的:

  • 可以使用'min', 'median', 'max' 字符串代表原始值的最小值、平均值、最大值,例如: [0, 'min'] 表示 x 轴上数值为 0,y 轴位置在数值的最小值上;

  • 表示位置的数组可以换成回调函数,函数原型: function(xScale, yScale) {return [];}
    • xScale, yScale 映射到 x 轴上的字段生成的度量,详情查看 度量, api;
    • 分类度量常用的值是 values 包含了所有的分类,连续度量常用的是 min, max
  1. const data = [];
  2. const time = Math.floor((new Date()).getTime() / 1000) * 1000;
  3.  
  4. for (let i = -19; i <= 0; i++) {
  5. data.push({
  6. time: time + i * 3 * 1000,
  7. value: Math.random() + .25
  8. });
  9. }
  10.  
  11. // 查找最大值
  12. function findMax() {
  13. let maxValue = 0;
  14. let maxObj = null;
  15. data.forEach(obj => {
  16. if (obj.value > maxValue) {
  17. maxValue = obj.value;
  18. maxObj = obj;
  19. }
  20. });
  21. return maxObj;
  22. }
  23.  
  24. const chart = new G2.Chart({ // 创建图表
  25. container: 'c9',
  26. forceFit: true,
  27. height: 450
  28. });
  29.  
  30. chart.source(data, {
  31. time: {
  32. type: 'time',
  33. mask: 'HH:mm:ss'
  34. }
  35. });
  36.  
  37. chart.line().position('time*value');
  38. // 添加一条虚线
  39. chart.guide().line({
  40. start: [ 'min', 0.25 ],
  41. end: [ 'max', 0.25]
  42. });
  43. chart.guide().text({
  44. position() {
  45. const obj = findMax();
  46. return [ obj.time, obj.value ];
  47. },
  48. content: '最大值'
  49. });
  50.  
  51. chart.render();
  52.  
  53. setInterval(function() {
  54. data.shift();
  55. data.push({
  56. time: new Date().getTime(),
  57. value: Math.random() + .25
  58. });
  59. chart.changeData(data);
  60. }, 3000);

Tooltip 提示信息 Facet 分面

原文: https://antv.alipay.com/zh-cn/g2/3.x/tutorial/guide.html