首页 > 解决方案 > Vega 条形图中的多个组,带有单个条形

问题描述

我正在尝试做一个多轴/多组 vega 图表。

这就是我想要实现的目标:

多组条形图

我希望能够首先将数据分类为年份:2018、2019 等。然后我希望它分成“0,1,2,3”类别,然后我想查看每个大小的数据“s, m,l”等。基本上,我想要的是:我在 2019 年拥有的“第三批”中有多少件尺寸为“M”的 T 恤。

我希望我说得很清楚。

我不想要堆叠的条,而是单独的条。另外,我希望顶轴根据年份有不同的颜色。

我将不胜感激任何可能的帮助。

这是我到目前为止所拥有的:

{
  $schema: https://vega.github.io/schema/vega/v4.json
  padding: {left: 5, top: 25, right: 5, bottom: 50}
  data: [
    {
      name: source_0
      values: [
        {speedName: "A", connectionType: "s", speedCount: 0.1, speedValue: "2018"}
        {speedName: "A", connectionType: "m", speedCount: 0.3, speedValue: "2018"}
        {speedName: "A", connectionType: "l", speedCount: 0.5, speedValue: "2018"}
        {speedName: "A", connectionType: "s", speedCount: 0.6, speedValue: "2019"}
        {speedName: "A", connectionType: "m", speedCount: 0.3, speedValue: "2019"}
        {speedName: "A", connectionType: "l", speedCount: 0.5, speedValue: "2019"}
        {speedName: "A", connectionType: "l", speedCount: 0.9, speedValue: "2020"}
        {speedName: "B", connectionType: "s", speedCount: 0.7, speedValue: "2019"}
        {speedName: "B", connectionType: "m", speedCount: 0.2, speedValue: "2020"}
        {speedName: "B", connectionType: "l", speedCount: 1.1, speedValue: "2018"}
        {speedName: "C", connectionType: "s", speedCount: 0.6, speedValue: "2020"}
        {speedName: "C", connectionType: "m", speedCount: 0.1, speedValue: "2018"}
        {speedName: "C", connectionType: "l", speedCount: 0.2, speedValue: "2021"}
      ]
      transform: [
        {
          type: collect
          sort: {
            field: ["connectionType", "speedName", "speedValue"]
            order: ["ascending", "ascending", "ascending"]
          }
        }
        {
          type: collect
          sort: {
            field: ["connectionType", "speedValue", "speedNameSort"]
            order: ["ascending", "ascending", "ascending"]
          }
        }
        {type: "filter", expr: "datum.speedCount < 100"}
        {
          type: aggregate
          groupby: ["speedValue", "speedName", "connectionType"]
          ops: ["sum", "count"]
          fields: ["speedCount", "speedValue"]
          as: ["speedCount", "count"]
        }
      ]
    }
    {
      name: data_0
      source: source_0
      transform: [
        {
          type: aggregate
          groupby: ["speedName", "connectionType", "speedValue"]
          ops: ["sum"]
          fields: ["speedCount"]
          as: ["speedCount"]
        }
        {
          type: filter
          expr: (datum["speedCount"]) && isFinite(+datum["speedCount"])
        }
      ]
    }
    {
      name: column_domain
      source: data_0
      transform: [
        {
          type: aggregate
          groupby: ["speedValue"]
        }
      ]
    }
  ]
  signals: [
    {name: "x_step", value: 30}
    {
      name: child_width
      update: bandspace(domain('x').length, 0.1, 0.05) * x_step
    }
    {name: "child_height", value: 200}
  ]
  layout: {
    padding: 25
    columns: {signal: "length(data('column_domain'))"}
    bounds: full
    align: all
  }
  marks: [
    {
      name: row_header
      type: group
      role: row-header
      encode: {
        update: {
          height: {signal: "child_height"}
        }
      }
      axes: [
        {
          orient: left
          scale: y
          domain: false
          grid: false
          labelOverlap: true
          ticks: false
          domain: false
          labelPadding: 10
          tickCount: {signal: "ceil(child_height/40)"}
          offset: 2
          tickCount: {signal: "ceil(child_height/40)"}
          zindex: 0
          labelColor: "#6c6c6c"
        }
      ]
    }
    {
      name: column_header
      type: group
      role: column-header
      from: {data: "column_domain"}
      sort: {field: "datum[\"speedValue\"]", order: "ascending"}
      encode: {
        update: {
          width: {signal: "child_width"}
        }
      }
      marks: [
        {
          name: rule
          from: {data: "column_domain"}
          type: rect
          encode: {
            enter: {
              stroke: {scale: "colors", field: "speedValue"}
            }
            update: {
              x: {signal: 0}
              y: {signal: "-25"}
              x2: {signal: "child_width"}
              fill: {scale: "colors", field: "speedValue"}
              strokeWidth: {signal: "2"}
            }
          }
        }
        {
          type: text
          from: {data: "column_domain"}
          encode: {
            update: {
              x: {signal: "child_width/2", field: "speedValue"}
              y: {signal: "-35"}
              x2: {signal: "child_width"}
              fill: {scale: "colors", field: "speedValue"}
              fontSize: {signal: "child_width/10 + 5"}
              align: {value: "center"}
              text: {
                signal: (parent["speedValue"]) ? parent["speedValue"] : ""+parent["speedValue"]
              }
            }
          }
        }
      ]
    }
    {
      name: column_footer
      type: group
      role: column-footer
      from: {
        facet: {
          name: facet
          data: data_0
          groupby: ["speedValue"]
        }
      }
      sort: {field: "datum[\"speedValue\"]", order: "ascending"}
      encode: {
        update: {
          width: {signal: "child_width"}
        }
        enter: {
          x: {scale: "x", field: "speedName"}
        }
      }
      axes: [
        {
          orient: bottom
          scale: x
          labelPadding: 25
          labelAngle: 0
          labelAlign: right
          labelBaseline: middle
          labelOverlap: true
          ticks: false
          speedValue: x
          labelColor: "#6c6c6c"
          grid: false
          domainColor: "#6c6c6c"
          domainWidth: 2.5
          zindex: 0
        }
      ]
      marks: [
        {
          type: group
          from: {
            facet: {data: "facet", name: "facet", groupby: "speedName"}
          }
          encode: {
            enter: {
              x: {scale: "x", field: "speedName"}
            }
          }
          scales: [
            {
              name: pos
              type: band
              range: width
              domain: {data: "facet", field: "connectionType"}
            }
          ]
          axes: [
            {
              orient: bottom
              scale: pos
              labelAngle: 0
              labelAlign: middle
              labelBaseline: middle
              labelOverlap: true
              ticks: false
              labelColor: "#6c6c6c"
              grid: false
              domainColor: "#6c6c6c"
              domainWidth: 2.5
              zindex: 0
              offset: 10
            }
          ]
        }
      ]
    }
    {
      name: cell
      type: group
      style: cell
      from: {
        facet: {
          name: facet
          data: data_0
          groupby: ["speedValue"]
        }
      }
      sort: {
        field: ["datum[\"speedValue\"]"]
        order: ["ascending"]
      }
      encode: {
        update: {
          width: {signal: "child_width"}
          height: {signal: "child_height"}
        }
      }
      marks: [
        {
          type: group
          from: {
            facet: {data: "facet", name: "facet", groupby: "speedName"}
          }
          encode: {
            enter: {
              x: {scale: "x", field: "speedName"}
            }
          }
          scales: [
            {
              name: pos
              type: band
              range: width
              domain: {data: "facet", field: "connectionType"}
            }
          ]
          axes: [
            {
              orient: bottom
              scale: pos
              tickSize: 3
              labelPadding: 2
              offset: 5
              ticks: false
              labels: false
            }
          ]
          marks: [
            {
              name: child_marks
              type: rect
              style: ["bar"]
              from: {data: "facet"}
              encode: {
                update: {
                  fill: {scale: "color", field: "connectionType"}
                  ariaRoleDescription: {value: "bar"}
                  tooltip: {
                    signal: '''{"Speed Type": ''+datum["speedName"], "Speed": ''+datum["speedValue"], "Speed Count": datum['speedCount'], "Connection Type": ''+datum["connectionType"]}'''
                  }
                  x: {scale: "x", field: "connectionType"}
                  width: {scale: "x", band: 1}
                  y: {scale: "y", field: "speedCount"}
                  y2: {scale: "y", value: "0"}
                }
              }
            }
          ]
        }
      ]
    }
  ]
  scales: [
    {
      name: x
      type: band
      domain: {data: "data_0", field: "speedName"}
      range: {
        step: {signal: "x_step"}
      }
      paddingInner: 0.1
      paddingOuter: 0.05
    }
    {
      name: y
      type: linear
      domain: {data: "data_0", field: "speedCount"}
      range: [
        {signal: "child_height"}
        0
      ]
      nice: true
      zero: true
    }
    {
      name: color
      type: ordinal
      domain: {data: "source_0", field: "connectionType", sort: true}
      range: [
        "#e20074"
        "#000000"
        "#6c6c6c"
        "#b3b3b3"
        "#1063ad"
        "#1bada2"
        "#ea75b6"
      ]
    }
    {
      name: colors
      type: ordinal
      domain: [2018, 2019, 2020, 2021, 2022]
      range: ["#ff9a1e", "#bfcb44", "#1bada2", "#53baf2", "#1063ad"]
    }
  ]
  legends: [
    {
      fill: color
      direction: vertical
      padding: 10
      encode: {
        symbols: {
          update: {
            shape: {value: "square"}
          }
        }
      }
    }
  ]
}

到目前为止,这就是它的样子:

到目前为止的结果

标签: vega

解决方案


推荐阅读