Richard.Huang 发表于 2023-12-29 11:19:22

如何通过自定义迷你图提高数据可读性

本帖最后由 Richard.Huang 于 2024-1-3 15:39 编辑

背景大家为了让数据可视化程度更高,往往会通过插入图表的方式来将数据可视化,在有些行业领域,例如房地产企业,他们对于楼盘数据往往会要求数据和图表中的数据形状一一对应,从而方便阅读者更加容易理解,如下图,我们会要求成交面积和前面的楼盘一一对应。
存在问题但是我们发现,通过图表中的条状图实现的图表会存在和数据不对应的情况,例如上图中成交面积和成交套数后面几条数据和前面的楼盘完全错位了,因此为了能够完美对应,我们需要不停的去调整整个图表的大小,系列的大小。这个过程是费时费力的。因此为了避免这个问题,更好地解决办法是使用“横向条状迷你图”。但是该迷你图是没有label信息的,如果大家可以接受,那么完全可以使用原生的横向条状迷你图。如果还想精益求精,建议使用我们的“自定义迷你图”功能。在单元格内添加条状图的同时还在后面添加label
实现方法1. 构建迷你图函数function Rectangle() {
    spreadNS.Sparklines.SparklineEx.call(this);
}
Rectangle.prototype = new spreadNS.Sparklines.SparklineEx();
Rectangle.prototype.createFunction = function () {
    function RectangleFunction() {
      this.name = "RECTANGLE";// 函数名
      this.maxArgs = 2;// 参数最多2个
      this.minArgs = 2;// 参数最少2个
    }
    RectangleFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();

    RectangleFunction.prototype.acceptsReference = function () {
      return true;//函数的参数接受引用单元格区域
    }

    RectangleFunction.prototype.isContextSensitive = function () {
      return true;
    }

    RectangleFunction.prototype.evaluate = function (arg) {
      let arg1;
      let arg2;
      let result = 0;
      if (!isNaN(parseInt(arg))) {// 判断参数是引用范围还是一个给定的值
            arg1 = arg;
      } else {
            arg1 = arg.getValueByIndex(0);
      }

      if (!isNaN(parseInt(arg))) {
            result = arg;
      } else {
            let sheet = arg.getSource();
            let startRow = arg.getRow();
            let startCol = arg.getColumn()
            let rowCount = arg.getRowCount();
            let colCount = arg.getColumnCount();
            for (let i = startRow; i < startRow + rowCount; i++) {
                for (let j = startCol; j < startCol + colCount; j++) {
                  result += sheet.getValue(i, j);
                }
            }
      }
      arg2 = arg1 / result;

      return {
            arg1,
            arg2
      };
    };
    return new RectangleFunction();
};
Rectangle.prototype._drawRect = function (context, value, x, y, width, height) {
    var rectX = x;
    var rectY = y + height * 0.1;// 矩形上下留空隙更加美观
    var rectWidth = width;
    var rectHeight = height * 0.8;
    var backgroundColor = '#3498db';// 矩形背景色
    context.fillStyle = backgroundColor;
    context.fillRect(rectX, rectY, rectWidth, rectHeight);// 画矩形

    // 设置文本的属性
    var textColor = '#000000'; // 文本颜色
    var fontSize = '13px'; // 字体大小
    var fontFamily = 'Arial'; // 字体
    var text = "空"
    if (value) {
      text = value.toString(); // 长方形宽度转换为字符串表示
    }
    // 设置文本样式
    context.fillStyle = textColor;
    context.font = fontSize + ' ' + fontFamily;
    // 计算文本的x和y位置,确保文本显示在长方形右侧
    var textX = rectX + rectWidth + 10; // 在长方形的宽度后留出一点间隔
    var textY = (2 * rectY + rectHeight) / 2 - 5; // 文本与长方形垂直居中
    context.textBaseline = "top";
    context.textAlign = "left"
    // 画文本
    context.fillText(text, textX, textY);
};

Rectangle.prototype.paint = function (context, value, x, y, width, height) {
    context.save();
    this._drawRect(context, value.arg1, x, y, width * value.arg2, height);
    context.restore();
};2. 注册自定义迷你图函数spread.addSparklineEx(new Rectangle());
实现效果而对于使用者来说,更加方便,只需要和插入普通公式一样,在单元格中通过自定义的迷你图函数即可实现,而不用插入图表调整图标大小形状等
页: [1]
查看完整版本: 如何通过自定义迷你图提高数据可读性