Search code examples
vega-litevega-lite-api

custom labels on x axis


I am trying to put labels on x-axis but I am getting 'undefined'.

this is what i achieve so far:

flatten not working, I tried separate flatten as well as one array. I need replace density values with labels.

Any help appreciated.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width":"container",

"data": {
    "values":[
     {"data": [0,0,0.09,0.12,0.23,0.24,0.29],"lower": 0.25,"q25":0.04,"middle":0.5, "q50":0.12, "upper":0.75,"q75":0.23, "names":["0","2000", "4000","6000","8000","10000", "12000"]}
     
    
  ]

  },
"layer":[
{
"transform": [
  {"calculate": "datum.data", "as":"d"},
  
  {"flatten": ["d"]},
  {"cumulative": true, "density": "d", "steps": 6,"bandwidth": 0.001 },
],
"encoding": {
    "x":{"field":"value", "type": "quantitative",
    "axis":null,
    
    },
    "y":{"field":"density", "type": "quantitative", "axis":{"format":"%"}},
    
},
"mark":{"type": "line", "interpolate":"linear"},
},

{
   
    "transform": [
        {"calculate": "datum.q25", "as": "q25"},
        {"calculate": "datum.lower", "as": "lower"}
    ],
    "layer":[{
    "mark":"rule",
    "encoding": {"x":{"field":"q25", "type": "quantitative"},
    "y":{"field":"lower", "type": "quantitative", "scale":{"domain":[0,1]}}
    }},
    {"mark":"point",
    "encoding": {"x":{"field":"q25", "type": "quantitative"}, "y":{"field":"lower", "type": "quantitative"}}},
    
    
]},


{
   
    "transform": [
        {"calculate": "datum.q50", "as": "q50"},
        {"calculate": "datum.middle", "as": "middle"}
    ],
    "layer":[{
    "mark":"rule",
    "encoding": {"x":{"field":"q50", "type": "quantitative"},
    "y":{"field":"middle", "type": "quantitative", "scale":{"domain":[0,1]}}
    }},
    {"mark":"point",
    "encoding": {"x":{"field":"q50", "type": "quantitative"}, "y":{"field":"middle", "type": "quantitative"}}},
    
    
]},
{
   
    "transform": [
        {"calculate": "datum.q75", "as": "q75"},
        {"calculate": "datum.upper", "as": "upper"}
    ],
    "layer":[{
    "mark":"rule",
    "encoding": {"x":{"field":"q75", "type": "quantitative"},
    "y":{"field":"upper", "type": "quantitative", "scale":{"domain":[0,1]}}
    }},
    {"mark":"point",
    "encoding": {"x":{"field":"q75", "type": "quantitative"}, "y":{"field":"upper", "type": "quantitative"}}},
    
    
]},
{
   
    "transform": [
        {"calculate": "datum.names", "as":"l"},
        {"calculate": "datum.data", "as":"d"},
  
  {"flatten": ["d","l"]},
  {"cumulative": true, "density": "d", "steps": 6,"bandwidth": 0.001 },
  
  ],
    "layer":[{
    "mark":"text",
    "encoding": {"text":{"field":"l","type": "ordinal"},
    "x":{"field":"value", "type": "quantitative"},
    "y":{"datum":0}
    
    }},
   ]},
],
 "resolve": {"scale": {"x": "shared", "y": "shared"}, "axis": {"x": "shared"}},
 "config": {
            "view": { "stroke": "transparent"},
            "background": "#EFF1EF",
            "axis": {"labelAngle":0, "domain": false, "grid": true, "title":null},
            
            "point": {"size":70, "color":"#006B5B"},
            }
}

Note that vega-lite not flatten names array, but does data array.

img, need undefined labels changed to values of "names" field("names":["0","2000", "4000","6000","8000","10000", "12000"]) from dataset.

Please advise, where i missing

thank you

ps. Edited original question, added screenshot of current result


Solution

  • I don't think Fold will work with 2 separate data arrays. You will need to improve your data set with additional data and name columns then you could apply a fold.

    "data": {
      "values": [
        {"name": "0", "data": 0},
        {"name": "2000", "data": 0},
        {"name": "4000", "data": 0.09},
        {"name": "6000", "data": 0.12},
        {"name": "8000", "data": 0.23},
        {"name": "10000", "data": 0.24},
        {"name": "12000", "data": 0.29}
      ]
    },
    "transform": [
      {
        "fold": ["name", "data"]
      }
    ],
    

    If this is not possible then you could fold your data with JavaScript:

    let data = [0,0,0.09,0.12,0.23,0.24,0.29];
    let names = ["0","2000", "4000","6000","8000","10000", "12000"];
    
    let processedData = data.map((value, index) => {
      return {
        data: value,
        name: names[index]
      };
    });
    
    console.log(processedData);