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

在Vega-Lite中创建关联时间的水平状态栏可行性问询

如何基于时间序列数据绘制状态时段矩形图?

我尝试用矩形标记对象在不同时段的「状态」区域,使用的时间序列数据格式如下:

[
  { "time": "<time>", "value": 1 },
  { "time": "<time>", "value": 1 },
  { "time": "<time>", "value": 0 },
  { "time": "<time>", "value": 0 },
  { "time": "<time>", "value": 0 },
  { "time": "<time>", "value": 1 },
  { "time": "<time>", "value": 1 },
  { "time": "<time>", "value": 0 },
  { "time": "<time>", "value": 0 },
  { "time": "<time>", "value": 0 },
  { "time": "<time>", "value": 2 },
  { "time": "<time>", "value": 2 }
]

普通柱状图只能展示各状态的总时长,无法关联状态与具体时间区间。我想要实现的效果是:X轴为时间轴,Y轴对应不同状态值,每个状态以连续的彩色矩形块展示其持续的时间段,直观呈现状态随时间的变化。

以洗衣机为例:关机、开机、脱水、漂洗等状态对应数字0、1、2、3……,状态变化或定期轮询时,数值会被记录到时间序列数据库,希望在X轴为时间的图表中水平展示这些状态的持续时段。

我测试了以下Vega-Lite代码,但无法得到预期效果:

{  
  "$schema": "https://vega.github.io/schema/vega-lite/v2.json",
  "autosize": {
    "type": "fit",
    "contains": "padding"
  },
  "data": {
    "values": [
      {"state": 0, "time": "2019-10-01"},
      {"state": 2, "time": "2019-10-02"},
      {"state": 0, "time": "2019-10-03"},
      {"state": 1, "time": "2019-10-04"},
      {"state": 0, "time": "2019-10-05"},
      {"state": 0, "time": "2019-10-06"},
      {"state": 1, "time": "2019-10-07"}
    ]
  },
  "mark": {
    "type": "bar"
  },
  "config": {
    "axis": {
      "labels": true,
      "domain": true,
      "ticks": false,
      "grid": false
    },
    "view": {
      "fill": "transparent",
      "stroke": "transparent"
    },
    "scale": {
      "bandPaddingInner": 0
    }
  },
  "encoding": {
    "x": {
      "field": "time",
      "type": "ordinal",
      "axis": true
    },
    "y": {
      "field": "state",
      "type": "ordinal",
      "scale": {
        "domain": []
      },
      "axis": true
    },
    "color": {
      "field": "state", "type": "ordinal",
      "legend": true,
      "scale": {
        "domain": [0,1,2],
        "range": ["#BD0000","#8DB319","#29ABE2"]
      }
    }
  }
}

运行后得到的是每个时间点对应一个独立小柱子,无法展示状态的连续时段。请问该需求是否可行?怎么实现?


解决方案

这个需求完全可行,核心是先将离散的时间点数据转换为状态时段数据,再用Vega-Lite的rect标记绘制连续矩形。

1. 数据格式转换

将连续相同状态的时间点合并,记录每个状态的start(开始时间)、end(结束时间)和对应的state值。转换后的数据格式示例:

[
  {"state": 0, "start": "2019-10-01", "end": "2019-10-01"},
  {"state": 2, "start": "2019-10-02", "end": "2019-10-02"},
  {"state": 0, "start": "2019-10-03", "end": "2019-10-06"},
  {"state": 1, "start": "2019-10-07", "end": "2019-10-07"}
]

如果是动态数据,可以通过Python、JavaScript等代码自动合并连续相同状态的记录。

2. 修改后的Vega-Lite代码

使用rect标记定义时间区间,实现连续状态块的展示:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "autosize": {
    "type": "fit",
    "contains": "padding"
  },
  "data": {
    "values": [
      {"state": 0, "start": "2019-10-01", "end": "2019-10-01"},
      {"state": 2, "start": "2019-10-02", "end": "2019-10-02"},
      {"state": 0, "start": "2019-10-03", "end": "2019-10-06"},
      {"state": 1, "start": "2019-10-07", "end": "2019-10-07"}
    ]
  },
  "mark": "rect",
  "encoding": {
    "x": {
      "field": "start",
      "type": "temporal",
      "axis": {"title": "时间"}
    },
    "x2": {"field": "end"},
    "y": {
      "field": "state",
      "type": "ordinal",
      "axis": {"title": "状态"}
    },
    "color": {
      "field": "state",
      "type": "ordinal",
      "legend": {"title": "状态"},
      "scale": {
        "domain": [0,1,2],
        "range": ["#BD0000","#8DB319","#29ABE2"]
      }
    }
  },
  "config": {
    "axis": {
      "domain": true,
      "ticks": true
    },
    "view": {
      "fill": "transparent"
    }
  }
}

关键说明

  • 用rect标记替代bar,通过x和x2定义每个状态的时间区间
  • 将时间字段设置为temporal(时间类型),确保X轴按时间顺序排列
  • 合并连续相同状态的记录,避免出现碎片化的小矩形

内容的提问来源于stack exchange,提问作者Gene Parmesan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:47:05