如何在React-Vega中为自动避让文本添加原点连线?
解决方案
要实现文本到原始symbol位置的连线,你只需要在现有marks里加一个line类型的标记,同时在文本标记里存好原始位置就行,具体修改如下:
- 先修改「name-label」文本标记的
encode.enter,把原始坐标存到自定义字段
在文本标记的enter里添加originalX和originalY,用来保留未避让前的原始位置:
"encode": { "enter": { "x": {"scale": "xscale", "field": "x"}, "y": {"scale": "yscale", "field": "y"}, "originalX": {"scale": "xscale", "field": "x"}, // 新增:存储原始x坐标 "originalY": {"scale": "yscale", "field": "y"}, // 新增:存储原始y坐标 "text": {"field": "name"} } }
- 在marks数组里新增一个连线标记,引用文本标记的数据,用原始坐标当起点、避让后的坐标当终点:
{ "name": "label-connector", "type": "line", "from": {"mark": "name-label"}, // 从文本标记获取数据(包含原始位置+最终避让位置) "encode": { "enter": { "x": {"field": "originalX"}, // 连线起点:对应symbol的原始位置 "y": {"field": "originalY"}, "x2": {"field": "x"}, // 连线终点:文本避让后的最终位置 "y2": {"field": "y"}, "stroke": {"value": "#999"}, // 连线颜色可自定义 "strokeWidth": {"value": 1} // 连线粗细可自定义 } } }
完整的marks代码
"marks": [ { "name": "dot", "type": "symbol", "from": {"data": "table"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "x"}, "y": {"scale": "yscale", "field": "y"}, "size": {"value": 100} } } }, { "name": "label-connector", // 新增的连线标记 "type": "line", "from": {"mark": "name-label"}, "encode": { "enter": { "x": {"field": "originalX"}, "y": {"field": "originalY"}, "x2": {"field": "x"}, "y2": {"field": "y"}, "stroke": {"value": "#999"}, "strokeWidth": {"value": 1} } } }, { "name": "name-label", "type": "text", "from": {"data": "table"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "x"}, "y": {"scale": "yscale", "field": "y"}, "originalX": {"scale": "xscale", "field": "x"}, // 新增 "originalY": {"scale": "yscale", "field": "y"}, // 新增 "text": {"field": "name"} } }, "transform": [ { "type": "label", "avoidMarks": ["dot"], "offset": [1, 50], "size": {"signal": "[width + 100, height + 100]"} } ] } ]
原理说明
label transform会自动把文本的x、y修改为避让后的最终位置,但我们提前把原始坐标存在了originalX/originalY字段里;连线标记直接引用文本标记的数据,就能同时拿到原始的symbol位置和文本最终位置,从而画出两者之间的连线。
内容的提问来源于stack exchange,提问作者theNotSoPro
相关产品推荐
相关产品推荐

