You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vega词云:如何用自定义标记替代纯文本并显示词下方计数?

解决Vega词云显示下方计数的问题

Vega的词云transform仅负责计算单个文本的布局,单个text mark无法直接实现不同样式的多行文本,因此核心解决思路是将词云布局计算移到数据源层面,再用两个text mark分别渲染主词和计数,复用布局结果。

核心修改点

  1. 把wordcloud transform从mark移到data中,让所有mark共享计算出的坐标、旋转角度、字体大小等属性
  2. 添加独立的text mark渲染计数文本,基于主文本的位置做偏移,设置更小的字体
  3. 调整主文本的基线,确保计数能正确显示在下方

修改后的完整代码

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "词云显示主词及下方计数",
  "width": 800,
  "height": 400,
  "padding": 0,

  "data": [
    {
      "name": "table",
      "values": [
        {"text": "apple", "weight": 15, "count": 1000},
        {"text": "banana", "weight": 20, "count": 1700},
        {"text": "orange", "weight": 20, "count": 1200}
      ],
      "transform": [
        {
          "type": "formula", "as": "angle",
          "expr": "[-45, 0, 45][~~(random() * 3)]"
        },
        {
          "type": "formula", "as": "weight",
          "expr": "if(datum.text=='VEGA', 600, 300)"
        },
        // 将词云布局移到data层,计算所有位置属性
        {
          "type": "wordcloud",
          "size": [800, 400],
          "text": {"field": "text"},
          "rotate": {"field": "datum.angle"},
          "font": "Helvetica Neue, Arial",
          "fontSize": {"field": "datum.count"},
          "fontWeight": {"field": "datum.weight"},
          "fontSizeRange": [12, 56],
          "padding": 2
        }
      ]
    }
  ],

  "scales": [
    {
      "name": "color",
      "type": "ordinal",
      "domain": {"data": "table", "field": "text"},
      "range": ["#d5a928", "#652c90", "#939597"]
    }
  ],

  "marks": [
    // 渲染主词
    {
      "type": "text",
      "from": {"data": "table"},
      "encode": {
        "enter": {
          "text": {"field": "text"},
          "x": {"field": "x"},
          "y": {"field": "y"},
          "align": {"value": "center"},
          "baseline": {"value": "bottom"}, // 调整基线,让计数在下方
          "fill": {"scale": "color", "field": "text"},
          "fontSize": {"field": "fontSize"},
          "fontWeight": {"field": "fontWeight"},
          "font": {"value": "Helvetica Neue, Arial"},
          "angle": {"field": "angle"}
        },
        "update": {
          "fillOpacity": {"value": 1}
        },
        "hover": {
          "fillOpacity": {"value": 0.5}
        }
      }
    },
    // 渲染下方的计数
    {
      "type": "text",
      "from": {"data": "table"},
      "encode": {
        "enter": {
          "text": {"field": "count"},
          "x": {"field": "x"},
          // 基于主文本的y坐标偏移,偏移量为主字体大小的1/2 + 间距
          "y": {"expr": "datum.y + datum.fontSize/2 + 4"},
          "align": {"value": "center"},
          "baseline": {"value": "top"},
          "fill": {"value": "#333"}, // 计数用深色,和主词区分
          "fontSize": {"expr": "datum.fontSize * 0.4"}, // 计数字体为主字体的40%
          "font": {"value": "Helvetica Neue, Arial"},
          "angle": {"field": "angle"}
        },
        "update": {
          "fillOpacity": {"value": 1}
        },
        "hover": {
          "fillOpacity": {"value": 0.5}
        }
      }
    }
  ]
}

对问题的针对性说明

  • \n无法解析:Vega的text mark默认不支持多行文本的样式分离,即使使用数组形式的text,也无法为不同行设置独立字体大小,双mark方案更可靠。
  • HTML标签无效:Vega的text mark不支持HTML渲染,所有标签都会被当作纯文本,因此不能依赖<br>实现换行,必须用独立的text元素。
  • 自定义SVG结合:不需要额外插入SVG,通过复用词云计算出的x/y/angle等属性,就能让计数文本精准定位在主词下方,实现需求。

内容的提问来源于stack exchange,提问作者John Smith Optional

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:02:19