简介

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

image

guide 类型

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

  • 辅助线,例如表示平均值或者预期分布的直线;
  • 辅助图片,在图表上添加辅助图片;
  • 辅助文本,指定位置添加文本说明;
  • 辅助框,框选一段图区,设置背景、边框等;
  • 辅助标签(tag),包含文本标识和辅助线的辅助标记,会从目标到说明文本之间绘制一条线;
  • 辅助 html,指定位置添加自定义html,显示自定义信息。

如何使用

辅助标记绘制过程中所需要的点都是一个数组[x, y],其中

  • x:是 x 轴坐标对应字段的值,是原始数据值,而不是画布坐标
  • y:是 y 轴坐标对应字段的值,是原始数据值,而不是画布坐标

例如:['一月',20][2.3,10000]

如果 x、y 值为分类类型的话,还支持直接传入索引值。

另外我们还提供了两个关键字: min max 用于表示对应字段的最大值和最小值,便于用户快速定位坐标轴的起点和终点。

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

line 辅助线

chart.guide().line(startPoint, endPoint[, cfg]);
参数 说明
startPoint 线的起点,是一个数组 [x, y]。
endPoint 线的终点,是一个数组 [x, y]。
cfg 线的配置信息,如线宽、颜色等。
$.getJSON('../../../../../static/data/diamond.json', function(data) {
  var Stat = G2.Stat;
  var frame = new G2.Frame(data);
  var caratAvg = G2.Frame.mean(frame,'carat'); // 计算克拉数均值
  var priceAvg = G2.Frame.mean(frame,'price'); // 计算价格均值
  var chart = new G2.Chart({ // 创建图表
    id : 'c1',
    forceFit: true,
    height: 300
  });

  chart.source(frame); // 设置数据源
  chart.point().position('carat*price');
  chart.guide().line([caratAvg,0],[caratAvg,20000]);
  chart.guide().line([0,priceAvg],[4,priceAvg]);
  chart.render(); // 图表渲染
});

image 辅助图片

chart.guide().image(startPoint[, endPoint], cfg);
参数 说明
startPoint 图片的起始位置
endPoint 图片的终止位置,可选
cfg 图片的配置项: src(图片路径)、width(宽度,可以不设置,如果设置了end,此属性无效)、height( 高度,可以不设置,如果设置了end,此属性无效)
$.getJSON('../../../../../static/data/diamond.json', function(data) {
  var Stat = G2.Stat;
  var chart = new G2.Chart({
    id: 'c2',
    forceFit: true,
    height: 300
  });
  chart.source(data);
  chart.interval().position(Stat.summary.count(Stat.bin.rect('depth'))).shape('hollowRect');

  chart.guide().image([55, 200], {
    src: 'https://os.alipayobjects.com/rmsportal/IUYwZOlOpysCUsl.png',
    width: 60,
    height: 100
  });
  chart.render();
});

text 辅助文本

chart.guide().text(startPoint, text, [cfg]);
参数 说明
startPoint 文本显示位置,是一个数组 [x, y]
text 辅助文本的显示内容
cfg 文本的配置信息
$.getJSON('../../../../../static/data/diamond.json', function(data) {
  var Stat = G2.Stat;
  G2.Global.setTheme('cheery');
  var colors = G2.Global.colors['default'];
  var chart = new G2.Chart({ // 创建图表
    id : 'c3',
    forceFit: true,
    height: 300,
    plotCfg: {
      margin: [20, 90, 60, 80]
    }
  });
  var defs = {
    'cut': {
      type: 'cat',
      values:['Ideal', 'Premium', 'Very-Good', 'Good', 'Fair']
    }
  };
  chart.source(data, defs); // 设置数据源
  chart.legend(false);
  chart.pointJitter().position('cut*depth').color('cut');
  chart.guide().text(['Ideal', 67], '越完美的钻石切割工艺集中', {
    fill: colors[0],
    textAlign: 'center',
    fontSize: 14
  });
  chart.guide().text(['Fair', 63], '越差的钻石切割工艺分散', {
    fill: colors[4],
    textAlign: 'center',
    fontSize: 14
  });
  chart.render(); // 图表渲染
});

rect 辅助框

chart.guide().rect(startPoint, endPoint, [cfg]);
参数 说明
startPoint 起始点位置
endPoint 结束点位置
cfg 矩形框的配置信息
var data = [
  {"month":0,"tem":7,"city":"tokyo"},
  {"month":1,"tem":6.9,"city":"tokyo"},
  {"month":2,"tem":9.5,"city":"tokyo"},
  {"month":3,"tem":14.5,"city":"tokyo"},
  {"month":4,"tem":18.2,"city":"tokyo"},
  {"month":5,"tem":21.5,"city":"tokyo"},
  {"month":6,"tem":25.2,"city":"tokyo"},
  {"month":7,"tem":26.5,"city":"tokyo"},
  {"month":8,"tem":23.3,"city":"tokyo"},
  {"month":9,"tem":18.3,"city":"tokyo"},
  {"month":10,"tem":13.9,"city":"tokyo"},
  {"month":11,"tem":9.6,"city":"tokyo"},
  {"month":0,"tem":-0.2,"city":"newYork"},
  {"month":1,"tem":0.8,"city":"newYork"},
  {"month":2,"tem":5.7,"city":"newYork"},
  {"month":3,"tem":11.3,"city":"newYork"},
  {"month":4,"tem":17,"city":"newYork"},
  {"month":5,"tem":22,"city":"newYork"},
  {"month":6,"tem":24.8,"city":"newYork"},
  {"month":7,"tem":24.1,"city":"newYork"},
  {"month":8,"tem":20.1,"city":"newYork"},
  {"month":9,"tem":14.1,"city":"newYork"},
  {"month":10,"tem":8.6,"city":"newYork"},
  {"month":11,"tem":2.5,"city":"newYork"},
  {"month":0,"tem":-0.9,"city":"berlin"},
  {"month":1,"tem":0.6,"city":"berlin"},
  {"month":2,"tem":3.5,"city":"berlin"},
  {"month":3,"tem":8.4,"city":"berlin"},
  {"month":4,"tem":13.5,"city":"berlin"},
  {"month":5,"tem":17,"city":"berlin"},
  {"month":6,"tem":18.6,"city":"berlin"},
  {"month":7,"tem":17.9,"city":"berlin"},
  {"month":8,"tem":14.3,"city":"berlin"},
  {"month":9,"tem":9,"city":"berlin"},
  {"month":10,"tem":3.9,"city":"berlin"},
  {"month":11,"tem":1,"city":"berlin"}
];
var chart = new G2.Chart({
  id: 'c4',
  forceFit: true,
  height: 300
});
chart.source(data);
chart.line().position('month*tem').color('city');
chart.guide().rect([5, 'min'], [7, 'max']); // 6月 - 8月最低温度
chart.render();

tag 辅助标签

chart.guide().tag(startPoint, endPoint, text[, cfg]);
参数 说明
startPoint 线的起始点,是一个数组 [x, y]
endPoint 线的起始点,是一个数组 [x, y]
text 标记文本
cfg 配置信息
$.getJSON('../../../../../static/data/diamond.json', function(data) {
  G2.Global.setTheme('cheery');
  var Stat = G2.Stat;
  var frame = new G2.Frame(data);
  var caratAvg = G2.Frame.mean(frame,'carat'); // 计算克拉数均值
  var priceAvg = G2.Frame.mean(frame,'price'); // 计算价格均值
  var chart = new G2.Chart({ // 创建图表
    id : 'c5',
    forceFit : true,
    height : 300
  });
  chart.source(frame); // 设置数据源
  chart.point().position('carat*price');
  chart.guide().tag([caratAvg,0],[caratAvg,20000],'钻石均值:'+caratAvg.toFixed(2))
  chart.guide().tag([0,priceAvg],[4,priceAvg],'价格均值' + priceAvg.toFixed(2))
  chart.guide().tag([3.65,11688],[4.2,16000],'异常值')
  chart.render(); // 图表渲染
});

arc 辅助弧线

chart.guide().arc(startPoint, endPoint[, cfg]);
参数 说明
startPoint 线的起始点,是一个数组 [x, y]
endPoint 线的结束点,是一个数组 [x, y]
cfg 配置信息

辅助html

chart.guide().html(startPoint, html, [cfg]);
参数 说明
startPoint 文本位置,是一个数组 [x, y]
html 辅助html的自定义内容
cfg html 的配置信息,支持对齐(align)和偏移(offset),对齐方式支持tr、tc、tl、br、bc、bl、lc、rc、cc 9 点对齐。如图所示,image
$.getJSON('../../../../../static/data/diamond.json', function(data) {
  var Stat = G2.Stat;
  var frame = new G2.Frame(data);
  var caratAvg = G2.Frame.mean(frame,'carat'); // 计算克拉数均值
  var priceAvg = G2.Frame.mean(frame,'price'); // 计算价格均值
  var chart = new G2.Chart({ // 创建图表
    id : 'c6',
    forceFit : true,
    height : 300
  });
  chart.source(frame); // 设置数据源
  chart.point().position('carat*price');
  // 坐标点
  var point = [3.5,12000];
  //html字符串
  var tooltipHtml = "<div style='border: 2px solid #0f8de8;width: 50px;height: 26px;color: #0f8de8;position: relative;'>" +
      "<span style='color:#63c6c2;font-size:15px'>异常值</span>" +
      "<div style='width: 0;height: 0;border-bottom: 8px solid #0f8de8;border-right:10px solid transparent;position: absolute;top: 16px;left: 46px;'></div>" +
      "</div>";
  chart.guide().html(point, tooltipHtml, {align:'br',offset:[10,0]});
  chart.render(); // 图表渲染
});

动态辅助标记

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


// 清除图表
chart.clear();

// 重新声明图形语法
chart.point().position('carat*price');

chart.guide().html([newX, newY], htmlstring);

chart.render();
  • newX,newY 是重新计算的位置

如果数据是动态更新的那么这个过程需要频繁进行,基于这种场景guide提供两种计算动态位置的:

  • 可以使用'min', 'max' 字符串代表原始值的最小值最大值,例如: [0, 'min'] 表示 x 轴上数值为0,y 轴位置在数值的最小值上
  • 表示位置的数组可以换成回调函数,函数原型: function(xScale, yScale) {return []}
    • xScale,yScale 映射到x轴上的字段生成的度量,详情查看 度量, api
    • 分类度量常用的值是 values 包含了所有的分类,连续度量常用的是 min,max
var data = [];                                                 
var time = Math.floor((new Date()).getTime()/1000) * 1000;                             

for (var i = -19; i <= 0; i++) {                                    
  data.push({                                                 
    time: time + i * 3 * 1000,                                     
    value: Math.random() + .25                                      
  });                                                         
}   

// 查找最大值
function findMax() {
  var maxValue = 0;
  var maxObj = null;
  data.forEach(function(obj) {
    if (obj.value > maxValue) {
      maxValue = obj.value;
      maxObj = obj;
    }
  });
  return maxObj;
}

var chart = new G2.Chart({ // 创建图表
  id : 'c7',
  forceFit : true,
  height : 300
});

chart.source(data, {
  time: {
    type: 'time',
    mask: 'HH:mm:ss'
  }
});

chart.line().position('time*value');

// 添加一条虚线
chart.guide().line(['min',0.25], ['max', 0.25]);

chart.guide().text(function(){
  var obj = findMax();
  return [obj.time, obj.value];
},'最大值');

chart.render();

setTimeout(function() {
  data.pop();
  data.push({
    time: new Date().getTime(),
    value: Math.random() + .25
  });
}, 3000);