简体   繁体   中英

Add day to a date in Vega-Lite

I'm trying to add a day to my dates which look like "2020-11-20" for November, 20, 2020. However I am encountering difficulty doing that - do I need to use the offset function? The reason I am doing this is that Vega-Lite is automatically offsetting my dates back 1 day through its GMT conversion and I cannot get it to stop. Please help!

Here is an example . If you look at the timeline graph it ends at 2020-11-19, but the final date in my data is 2020-11-20, and I need to make it so 2020-11-20 is the last date on my timeline graph.

This issue comes from an unfortunate "feature" of how javascript parses dates. Here is a minimal example of the problem you're seeing ( open in editor ):

{
  "data": {
    "values": [
      {"date": "2020-11-17", "value": 5},
      {"date": "2020-11-18", "value": 6},
      {"date": "2020-11-19", "value": 7},
      {"date": "2020-11-20", "value": 8}
    ]
  },
  "mark": "bar",
  "encoding": {
    "x": {"field": "value", "type": "quantitative"},
    "y": {
      "field": "date",
      "timeUnit": "yearmonthdate",
      "type": "ordinal"
    },
    "tooltip": [
      {
        "field": "date",
        "timeUnit": "yearmonthdate",
        "type": "temporal"
      }
    ]
  }
}

在此处输入图像描述

Each of the days in the chart are off by one compared to the input. So why is this happening?

Well, it turns out that the Vega-Lite's renderer makes use of Javascript's built-in date parsing, and Javascript's date parsing treats inputs differently depending on how they're formatted. In particular, Javascript will parse non-standard timestamps in UTC time, but will parse full ISO-8601 timestamps in local time, a fact you can confirm in your browser's javascript console (I executed this on a computer set to PST):

> new Date('2020-11-20')
Thu Nov 19 2020 16:00:00 GMT-0800 (Pacific Standard Time)

> new Date('2020-11-20T00:00:00')
Fri Nov 20 2020 00:00:00 GMT-0800 (Pacific Standard Time)

The Vega-Lite docs recommend using UTC timeUnits and scales to work around this, but I tend to find that approach a bit clunky. Instead, I try to always specify dates in Vega-Lite via full ISO 8601 timestamps.

In your case, the best approach is probably to use a calculate transform to regularize your dates, and proceed from there. Modifying the simplified example above, it might look something like this ( open in editor ):

{
  "data": {
    "values": [
      {"date": "2020-11-17", "value": 5},
      {"date": "2020-11-18", "value": 6},
      {"date": "2020-11-19", "value": 7},
      {"date": "2020-11-20", "value": 8}
    ]
  },
  "transform": [
    {"calculate": "toDate(datum.date + 'T00:00:00')", "as": "date"}
  ],
  "mark": "bar",
  "encoding": {
    "x": {"field": "value", "type": "quantitative"},
    "y": {
      "field": "date",
      "timeUnit": "yearmonthdate",
      "type": "ordinal"
    },
    "tooltip": [
      {
        "field": "date",
        "timeUnit": "yearmonthdate",
        "type": "temporal"
      }
    ]
  }
}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM