Search code examples
vega-litevega

Can't create correct formula to draw line chart with rules in vega-lite?


Working on project with vega-lite and can't overcome with some visualization. Stuck on this task

I would like to get this result , but getting this.

This is my code I tried:
`

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

  "params": [
    {
      "name": "chart_title",
      "value": " Weekly  Distribution"
    },
    {
      "name": "titleAxisXname",
      "value": "Weekly  Min "
    },
    {
      "name": "tick_Count_X",
      "value": 8
    }
    
  ],
  "width": 425,
  "height": 135,
  "padding": 20,
  "title": {
    "text": {
      "expr": "chart_title"
    },
    "fontSize": 16,
    "color": "white",
    "fontWeight": 700,
    "font": "Google Sans",
    "align": "left",
    "dx": 40,
    "dy": -10
  },
  
  
  "data": {
    "name": "vis",
    "values":[
      {
  "customer": "Customer",
  "type": "monthly",
  "metrics": {
    
    "partitions": [
      {
        "a": {
          "mean": 135,
          "distribution": {
            "min": [ 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,300],
            
            "data": [
              0.01,
              0.01,
              0.02,
              0.03,
              0.05,
              0.08,
              0.13,
              0.21,
              0.28,
              0.31,
              0.33,
              0.3,
              0.28,
              0.26,
              0.24,
              0.22,
              0.21,
              0.2,
              0.19,
              0.18,
              0.17,
              0.16,
              0.15,
              0.14,
              0.13,
              0.12,
              0.11,
              0.1,
              0.09,
              0.08
            ]
          }
        }
      }
    ]
   
  }
    }]
  },
  "transform": [
  
    {"calculate": "datum.metrics.partitions", "as": "P"},
    {"flatten": ["P"]},
    {"calculate": "datum.P.a.distribution.min", "as": "x"},
    {"flatten": ["x"]},
   
   {"calculate": "datum.P.a.distribution.data", "as": "y"},
    {"flatten": ["y"]}
    
   ],
  "layer": [
    {
      "mark": "line",
      "encoding": {
        "x": { "field": "x", 
        "type": "quantitative"
        },
        
        "y": { 
          "field": "y",
          "type": "quantitative"
          
        }
      }
    },
    {
      "data": {
        "values": [
          {}
        ]
      },
      "encoding": {
        "x": {
          "datum": 65
        }
      },
      "layer": [
        {
          "mark": {
            "type": "rule"
          }
        },
        {
          "mark": {
            "type": "text",
            "text": [
              "25th",
              "Percentile"
            ]
          }
        }
      ]
    },
    {
      "encoding": {
        "x": {
          "datum": 130
        }
      },
      "layer": [
        {
          "mark": {
            "type": "rule",
            "color": "#594CB8"
          }
        },
        {
          "mark": {
            "type": "text",
            "text": [
              "50th",
              "Percentile"
            ],
            "color": "#594CB8"
          }
        }
      ]
    },
    {
      "encoding": {
        "x": {
          "datum": 200
        }
      },
      "layer": [
        {
          "mark": {
            "type": "rule",
            "color": "#B4539E"
          }
        },
        {
          "mark": {
            "type": "text",
            "text": [
              "75th",
              "Percentile"
            ],
            "color": "#B4539E"
          }
        }
      ]
    }
  ],
  
  "config": {
    "background": "white",
    "axisX": {
      "title": {
        "expr": "titleAxisXname"
      },
      "tickCount": {
        "expr": "tick_Count_X"
      },
      "titlePadding": 20,
      "titleFont": "Google Sans",
      "titleColor": "black",
      "titleFontSize": 12,
      "titleFontWeight": 700,
      "labelFontSize": 12,
      "labelColor": "#56615F",
      "labelFontWeight": 400
    },
    "axisY": {
      "orient": "right",
      "tickCount": 3,
      "format": "%",
      "title": null,
      "labelFontSize": 12,
      "labelColor": "#56615F",
      "labelFontWeight": 400,
      "labelPadding": 10
    },
    "line": {
      "point": false,
      "interpolate": "cardinal",
      "color": "#006A62"
    },
    "text": {
      "font": "Google Sans",
      "fontSize": 12,
      "color": "#001D33",
      "fontWeight": 700,
      "dx": 15,
      "dy": -105
    },
    "rule": {
      "strokeWidth": 5,
      "strokeDash": [
        0.5,
        16
      ],
      "strokeCap": "round"
    }
  }
}

`

Can't come up with correct calculations which reads x and y fields. It should be way but I can't find in documentations

Thank you in advance


Solution

  • enter image description here

    Your flatten created a Cartesian product and needed to be done in a single step.

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      
    
      "params": [
        {
          "name": "chart_title",
          "value": " Weekly A Distribution"
        },
        {
          "name": "titleAxisXname",
          "value": "Weekly A Minutes "
        },
        {
          "name": "tick_Count_X",
          "value": 8
        }
        
      ],
      "width": 425,
      "height": 135,
      "padding": 20,
      "title": {
        "text": {
          "expr": "chart_title"
        },
        "fontSize": 16,
        "color": "#56615F",
        "fontWeight": 700,
        "font": "Google Sans",
        "align": "right",
        "dx": 40,
        "dy": -10
      },
      
      
      "data": {
        "name": "report",
        "values":[
          {
      "customer": "Customer",
      "type": "monthly",
      "period": "2022-10",
      "schema": "1.0.0",
      "metrics": {
        "filters": {
          "age": [
            "all",
            "18-39",
            "40-64",
            "65+"
          ],
          "gender": [
            "all",
            "male",
            "female"
          ]
        },
        "partitions": [
          {
            "segment": {
              "age": "*",
              "gender": "*"
            },
            "count": 10000,
            "a": {
              "mean": 135,
              "p10": 10,
              "p25": 60,
              "p50": 130,
              "p75": 198,
              "p90": 255,
              "goal": {
                "value": 150,
                "p": 0.37
              },
              "distribution": {
                "min": [ 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,300],
                "max": 300,
                "step": 10,
                "data": [
                  0.01,
                  0.01,
                  0.02,
                  0.03,
                  0.05,
                  0.08,
                  0.13,
                  0.21,
                  0.28,
                  0.31,
                  0.33,
                  0.3,
                  0.28,
                  0.26,
                  0.24,
                  0.22,
                  0.21,
                  0.2,
                  0.19,
                  0.18,
                  0.17,
                  0.16,
                  0.15,
                  0.14,
                  0.13,
                  0.12,
                  0.11,
                  0.1,
                  0.09,
                  0.08
                ]
              }
            }
          }
        ]
       
      }
        }]
      },
      "transform": [
      
        {"calculate": "datum.metrics.partitions", "as": "P"},
        {"flatten": ["P"]},
        {"calculate": "datum.P.a.distribution.min", "as": "x"},
      
       
       {"calculate": "datum.P.a.distribution.data", "as": "y"},
        {"flatten": ["x","y"]}
        
       ],
      "layer": [
        {
          "mark": "line",
          "encoding": {
            "x": { "field": "x", 
            "type": "quantitative"
            },
            
            "y": { 
              "field": "y",
              "type": "quantitative"
              
            }
          }
        },
        {
          "data": {
            "values": [
              {}
            ]
          },
          "encoding": {
            "x": {
              "datum": 65
            }
          },
          "layer": [
            {
              "mark": {
                "type": "rule"
              }
            },
            {
              "mark": {
                "type": "text",
                "text": [
                  "25th",
                  "Percentile"
                ]
              }
            }
          ]
        },
        {
          "encoding": {
            "x": {
              "datum": 130
            }
          },
          "layer": [
            {
              "mark": {
                "type": "rule",
                "color": "#594CB8"
              }
            },
            {
              "mark": {
                "type": "text",
                "text": [
                  "50th",
                  "Percentile"
                ],
                "color": "#594CB8"
              }
            }
          ]
        },
        {
          "encoding": {
            "x": {
              "datum": 200
            }
          },
          "layer": [
            {
              "mark": {
                "type": "rule",
                "color": "#B4539E"
              }
            },
            {
              "mark": {
                "type": "text",
                "text": [
                  "75th",
                  "Percentile"
                ],
                "color": "#B4539E"
              }
            }
          ]
        }
      ],
      
      "config": {
        "background": "#eff1ef",
        "axisX": {
          "title": {
            "expr": "titleAxisXname"
          },
          "tickCount": {
            "expr": "tick_Count_X"
          },
          "titlePadding": 20,
          "titleFont": "Google Sans",
          "titleColor": "#56615F",
          "titleFontSize": 12,
          "titleFontWeight": 700,
          "labelFontSize": 12,
          "labelColor": "#56615F",
          "labelFontWeight": 400
        },
        "axisY": {
          "orient": "right",
          "tickCount": 3,
          "format": "%",
          "title": null,
          "labelFontSize": 12,
          "labelColor": "#56615F",
          "labelFontWeight": 400,
          "labelPadding": 10
        },
        "line": {
          "point": false,
          "interpolate": "cardinal",
          "color": "#006A62"
        },
        "text": {
          "font": "Google Sans",
          "fontSize": 12,
          "color": "#001D33",
          "fontWeight": 700,
          "dx": 15,
          "dy": -105
        },
        "rule": {
          "strokeWidth": 5,
          "strokeDash": [
            0.5,
            16
          ],
          "strokeCap": "round"
        }
      }
    }