向圆形饼图/仪表图添加标签

问题描述 投票:0回答:1

我有一个配置可以在Vega图表中绘制多个仪表图表。

我想在代表当前值的每行顶部绘制带有值的文本。文本末尾应显示数值编号和符号“%”。最终结果需要与此图表类似enter image description here

json charts visualization vega
1个回答
-1
投票

enter image description here

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 400,
  "height": 600,
  "signals": [
    {"name": "centerX", "update": "width / 2"},
    {"name": "centerY", "update": "height / 2"},
    {"name": "radiusRef", "update": "min(width / 2, height / 2)"},
    {"name": "padding", "value": 18},
    {"name": "numArcs", "value": 2},
    {"name": "arcStep", "update": "0.4 / numArcs"},
    {"name": "ticksNumber", "value": 6},
    {"name": "ticksColor", "value": "#000000"},
    {"name": "showTicks", "value": true},
    {"name": "arc1", "value": {"value": 70, "fillColor": "#77A7FB"}},
    {"name": "arc2", "value": {"value": 40, "fillColor": "#FFB677"}},
    {"name": "innerRadius1", "update": "radiusRef + padding"},
    {"name": "outerRadius1", "update": "radiusRef * (1 - arcStep) - padding"},
    {"name": "minValue", "value": 0},
    {"name": "maxValue", "value": 100},
    {"name": "fontFactor", "update": "(radiusRef / 5) / 25"},
    {"name": "backgroundColor", "value": "#cbd1d6"},
    {"name": "fillColor3", "value": "#77FF77"}
  ],
  "data": [
    {
      "name": "ticks",
      "transform": [
        {
          "type": "sequence",
          "as": "data",
          "start": {"signal": "0"},
          "stop": {"signal": "(maxValue - minValue) + 0.1"},
          "step": {"signal": "(maxValue - minValue) / (ticksNumber - 1)"}
        },
        {"type": "formula", "expr": "datum.data + minValue", "as": "data_2"},
        {
          "type": "formula",
          "as": "radianRef",
          "expr": "PI * (datum.data / (maxValue - minValue))"
        },
        {
          "type": "formula",
          "as": "x",
          "expr": "centerX - ((outerRadius1 - (outerRadius1 - innerRadius1) * 0.6) * cos(datum.radianRef))"
        },
        {
          "type": "formula",
          "as": "y",
          "expr": "centerY - ((outerRadius1 - (outerRadius1 - innerRadius1) * 0.7) * sin(datum.radianRef))"
        }
      ]
    },
    {
      "name": "mainValues",
      "values": [
        {"name": "Policy 1", "value": 27},
        {"name": "Policy 2", "value": 75}
      ],
      "transform": [{"type": "window", "ops": ["row_number"], "as": ["index"]}]
    }
  ],
  "scales": [
    {
      "name": "gaugeScale",
      "type": "linear",
      "domain": {"data": "ticks", "field": "data_2"},
      "zero": false,
      "range": {"signal": "[-PI / 2, PI / 2]"}
    },
    {
      "name": "color",
      "type": "ordinal",
      "domain": {"data": "mainValues", "field": "name"},
      "range": {"scheme": "category10"}
    }
  ],
  "marks": [
    {
      "type": "arc",
      "name": "gauge3",
      "from": {"data": "mainValues"},
      "encode": {
        "enter": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "startAngle": {"signal": "-PI / 2"},
          "endAngle": {"signal": "PI / 2"},
          "outerRadius": {
            "signal": "radiusRef * (1 - datum.index * arcStep) - padding"
          },
          "innerRadius": {
            "signal": "radiusRef * (1 - datum.index * arcStep) + padding"
          },
          "fill": {"signal": "backgroundColor"}
        }
      }
    },
    {
      "type": "arc",
      "from": {"data": "mainValues"},
      "encode": {
        "enter": {"startAngle": {"signal": "-PI / 2"}},
        "update": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "innerRadius": {
            "signal": "radiusRef * (1 - datum.index * arcStep) + padding"
          },
          "outerRadius": {
            "signal": "radiusRef * (1 - datum.index * arcStep) - padding"
          },
          "endAngle": {"scale": "gaugeScale", "field": "value"},
          "fill": {"scale": "color", "field": "name"}
        }
      }
    },
    {
      "type": "arc",
      "from": {"data": "mainValues"},
      "encode": {
        "enter": {"startAngle": {"signal": "-PI / 2"}},
        "update": {
          "x": {"signal": "centerX"},
          "y": {"signal": "centerY"},
          "innerRadius": {
            "signal": "radiusRef * (1 - datum.index * arcStep) + padding"
          },
          "outerRadius": {
            "signal": "radiusRef * (1 - (datum.index - 1) * arcStep) + datum.index * 15"
          },
          "startAngle": {"scale": "gaugeScale", "signal": "datum.value - 0.3"},
          "endAngle": {"scale": "gaugeScale", "field": "value"},
          "fill": {"scale": "color", "field": "name"}
        }
      }
    },
    {
      "type": "text",
      "from": {"data": "mainValues"},
      "encode": {
        "update": {
          "radius": {
            "signal": "radiusRef * (1 - (datum.index - 1) * arcStep) + datum.index * 15"
          },
          "x": {"signal": "width", "mult": 0.5},
          "y": {"signal": "height", "mult": 0.5},
          "text": {"signal": "datum.value"},
          "align": {"value": "center"},
          "baseline": {"value": "middle"},
          "fill": {"scale": "color", "field": "name"},
          "dy": {"value": -8},
          
          "theta": {"signal": "scale('gaugeScale', datum.value)"}
        }
      }
    }
  ]
}
© www.soinside.com 2019 - 2024. All rights reserved.