Search code examples
jsonchartsvisualizationvega

Extra padding added to the Vega legend element


I'm rendering a chart with the attached JSON. While doing it in the Vega editor everything is fine but while rendering SVG with a code, an extra right padding is added to the legend element. Take a look at bellow screenshots:

enter image description here

enter image description here

Here is a very simple code:

const vega = require('vega');
module.exports = async function (context, req) {
    try {
        const vview = await new vega.View(vega.parse(req.body), { renderer: 'none' });
        let svg = await vview.toSVG();
        context.res = {
            body: svg,
            contentType: 'image/svg+xml'
        };
    }
    catch (error) {
        context.log(`Error during rendering vega chart: ${error}.`);
        throw error;
    }
}

The req.body contains JSON with a chart definition. Are there any settings with which I could control that padding? I tried all options from the documentation without luck.

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "Sample",
  "width": 600,
  "height": 300,
  "autosize":
  {
    "type": "fit", 
    "contains": "padding"
  },
  "padding": 10,
  "data": [
    {
      "name": "table",
      "values": [
        {
          "category": "Portfolio",
          "year": 2020,
          "section" : "vor 1900",
          "volume": 0.04
        },
        {
          "category": "Portfolio",
          "year": 2020,
          "section" : "1900-1950",
          "volume": 0.07
        },
        {
          "category": "Portfolio",
          "year": 2020,
          "section" : "1950-1970",
          "volume": 0.13
        },
        {
          "category": "Portfolio",
          "year": 2020,
          "section" : "1970-1990",
          "volume": 0.19
        },
        {
          "category": "Portfolio",
          "year": 2020,
          "section" : "1990-2010",
          "volume": 0.24
        },
        {
          "category": "Portfolio",
          "year": 2020,
          "section" : "nach 2010",
          "volume": 0.33
        },



        
        {
          "category": "Portfolio",
          "year": 2021,
          "section" : "vor 1900",
          "volume": 0.03
        },
        {
          "category": "Portfolio",
          "year": 2021,
          "section" : "1900-1950",
          "volume": 0.06
        },
        {
          "category": "Portfolio",
          "year": 2021,
          "section" : "1950-1970",
          "volume": 0.11
        },
        {
          "category": "Portfolio",
          "year": 2021,
          "section" : "1970-1990",
          "volume": 0.19
        },
        {
          "category": "Portfolio",
          "year": 2021,
          "section" : "1990-2010",
          "volume": 0.25
        },
        {
          "category": "Portfolio",
          "year": 2021,
          "section" : "nach 2010",
          "volume": 0.36
        },






        {
          "category": "Benchmark",
          "year": 2020,
          "section" : "vor 1900",
          "volume": 0.06
        },
        {
          "category": "Benchmark",
          "year": 2020,
          "section" : "1900-1950",
          "volume": 0.09
        },
        {
          "category": "Benchmark",
          "year": 2020,
          "section" : "1950-1970",
          "volume": 0.15
        },
        {
          "category": "Benchmark",
          "year": 2020,
          "section" : "1970-1990",
          "volume": 0.23
        },
        {
          "category": "Benchmark",
          "year": 2020,
          "section" : "1990-2010",
          "volume": 0.25
        },
        {
          "category": "Benchmark",
          "year": 2020,
          "section" : "nach 2010",
          "volume": 0.22
        },



        
        {
          "category": "Benchmark",
          "year": 2021,
          "section" : "vor 1900",
          "volume": 0.05
        },
        {
          "category": "Benchmark",
          "year": 2021,
          "section" : "1900-1950",
          "volume": 0.09
        },
        {
          "category": "Benchmark",
          "year": 2021,
          "section" : "1950-1970",
          "volume": 0.14
        },
        {
          "category": "Benchmark",
          "year": 2021,
          "section" : "1970-1990",
          "volume": 0.24
        },
        {
          "category": "Benchmark",
          "year": 2021,
          "section" : "1990-2010",
          "volume": 0.25
        },
        {
          "category": "Benchmark",
          "year": 2021,
          "section" : "nach 2010",
          "volume": 0.23
        }



      ],
      "transform": [
        {
          "type": "stack",
          "groupby": ["category","year"],
          "field": "volume"
        },
        {
          "type": "formula",
          "as": "colorParam",
          "expr": "datum.section+' '+datum.category"
        },          
        {
          "type": "formula", 
          "as": "volumePerc", 
          "expr": "format(datum.volume,'.0%')"
        }
      ]
    }
  ],


  "signals": [
    { "name": "sfont", "value" : "Arial Narrow, serif"},
    { "name": "sfontBold", "value" : "Arial Black, serif"},
    { "name": "sfontSize", "value" : 16},
    { "name": "sfontColor", "value" : "#595959"}
  ],



  "scales": [
    {
      "name": "xCategoryScale",
      "type": "band",
      "domain": {
        "data": "table",
        "field": "category"
      },
      "range": "width"
    },
    {
      "name": "yscale",
      "type": "linear",
      "domain": [0,1],
      "range": "height",
      "nice": true
    },
    {
      "name": "colorScale",
      "type": "ordinal",        
      "domain": {
        "data": "table",
        "field": "colorParam"
      },
      "range": [
          "#172431",
          "#426990",
          "#638EB9",
          "#8BABCB",
          "#BFD1E3",
          "#D7E2ED",

          "#322B22", 
          "#6F5F4D",
          "#958069",
          "#AE9D8B",
          "#D3C9BF",
          "#F1EEEB"
      ]
    },
    {
      "name": "legendColorScale",
      "type": "ordinal",     
      "domain": [
        "nach 2010",
        "1990-2010",
        "1970-1990",
        "1950-1970",
        "1900-1950",
        "vor 1900"
        ],
      "range": [
          "#d9d9d9",
          "#bfbfbf",
          "#a6a6a6",
          "#7f7f7f",
          "#595959",
          "#262626"
      ]
    }
  ],
  "axes": [
    {
      "orient": "left",
      "scale": "yscale",
      "tickCount": 6,
      "grid": true,
      "title": "m²EBF-%",
      "titleX":-40,
      "titleFontSize": {"signal": "sfontSize"},
      "titleFont": {"signal": "sfont"},
      "titleColor":{"signal": "sfontColor"},
      "titleFontWeight": "normal",
      "labelFontSize": {"signal": "sfontSize"},
      "labelFont": {"signal": "sfont"},
      "labelColor":{"signal": "sfontColor"},    
      "encode": {
      "labels": {
        "update": {
          "text": {"signal": "format(datum.value, '.0%')"}
        }
      }
    }
    },
    {
      "orient": "bottom",
      "scale": "xCategoryScale",
      "tickBand": "extent",
      "tickSize": 50,    
      "titleFontSize": {"signal": "sfontSize"},
      "titleFont": {"signal": "sfont"},
      "titleColor":{"signal": "sfontColor"},
      "titleFontWeight": "normal",
      "labelFontSize": {"signal": "sfontSize"},
      "labelFont": {"signal": "sfont"},
      "labelColor":{"signal": "sfontColor"},     
      "encode": {
        "labels": {
          "update": {
            "dy": {
              "value": -20
            }
          }
        }
      }
    }
  ],

"legends": [
{
  "type": "symbol",
  "fill": "legendColorScale",    
  "symbolType": "square",
  "orient":"right",
  "legendX": {"signal": "width", "offset": 20},
  "legendY": {"signal": "height / 2", "offset":-40},
  "labelFontSize": {"signal": "sfontSize"},
  "labelFont": {"signal": "sfont"},
  "labelColor":{"signal": "sfontColor"}   
}
],

  "marks": [
    {
      "name": "categories",
      "type": "group",
      "from": {
      "facet": { 
        "data": "table",
        "name": "perCategory",
        "groupby": "category"          
        }
      },
      "encode": {
        "enter": {
          "x": {
            "scale": "xCategoryScale",
            "field": "category"
          },
          "width": {
            "scale": "xYearScale",
            "band": 1
          },
          "y": {
            "scale": "yscale",
            "field": "volume"
          },
          "y2": {
            "scale": "yscale",
            "value": 0
          }
        }
      },

      "signals": [
        {
          "name": "width",
          "update": "bandwidth('xCategoryScale')"
        }
      ],
      "scales": [
        {
          "name": "xYearScale",
          "type": "band",
          "range": "width",
          "domain": {
            "data": "perCategory",
            "field": "year"
          },
          "padding": 0.06
        }
      ],

    "axes": [
        {
          "orient": "bottom", 
          "scale": "xYearScale", 
          "zindex": 1,
          "offset": {"signal": "height"},
          "tickSize":{"value": 0},     
          "labelFontSize": {"signal": "sfontSize"},
          "labelFont": {"signal": "sfont"},
          "labelColor":{"signal": "sfontColor"},    
          "encode": {
            "labels": {
              "update": {
                "dy" : {"value": 5}
              }
            }
          }
        }
      ],

      "marks": [
        {
            "name": "volumeBars",
            "from": { "data": "perCategory"},
            "type": "rect",
            "encode": {
              "enter": {
                "x": {
                  "scale": "xYearScale",
                  "field": "year",
                  "band": 0.3
                },
                "width": {
                  "scale": "xYearScale",
                  "band": 0.4
                },
                "y": {
                  "scale": "yscale",
                  "field": "y0"
                },
                "y2": {
                  "scale": "yscale",
                  "field": "y1"
                },
                "fill": {
                  "scale": "colorScale",
                  "signal": "datum.colorParam"
                }
              }
            }
          },
          {
            "name": "barLabel",
            "type": "text",
            "from": {
              "data": "volumeBars"
            },
            "encode": {
              "enter": {
                "y": {
                  "field": "y",
                  "offset": {
                    "field": "height",
                    "mult":0.5
                  }
                },
                "x": {
                  "field": "x",
                  "offset": {
                    "field": "width",
                    "mult": 0.5
                  }
                },
                "stroke":{"value": "white"},
                "strokeWidth":{"value": 0.4},
                "fontSize": {"signal": "sfontSize"},
                "font": {"signal": "sfontBold"},
                "color":{"signal": "sfontColor"},
                "baseline":{"value": "middle"},
                "fill":{"value": "black"},                  
                "align": [
                  {
                    "test": "indexof(data('volumeBars'), datum) % 2 == 0",
                    "value": "right"
                  },
                  {
                    "value": "left"
                  }
                ],               
                "text": {
                  "field": "datum.volumePerc"                    
                }
              }
            }
          }   
          
      ]
    }
  ]


}

Solution

  • See how the legend is now clipped with a negative right padding below.

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega/v5.json",
      "description": "Sample",
      "width": 600,
      "height": 300,
      "autosize":
      {
        "type": "fit", 
        "contains": "padding"
      },
      "padding": {"left": 5, "top": 5, "right": -15, "bottom": 5},
      "data": [
        {
          "name": "table",
          "values": [
            {
              "category": "Portfolio",
              "year": 2020,
              "section" : "vor 1900",
              "volume": 0.04
            },
            {
              "category": "Portfolio",
              "year": 2020,
              "section" : "1900-1950",
              "volume": 0.07
            },
            {
              "category": "Portfolio",
              "year": 2020,
              "section" : "1950-1970",
              "volume": 0.13
            },
            {
              "category": "Portfolio",
              "year": 2020,
              "section" : "1970-1990",
              "volume": 0.19
            },
            {
              "category": "Portfolio",
              "year": 2020,
              "section" : "1990-2010",
              "volume": 0.24
            },
            {
              "category": "Portfolio",
              "year": 2020,
              "section" : "nach 2010",
              "volume": 0.33
            },
    
    
    
            
            {
              "category": "Portfolio",
              "year": 2021,
              "section" : "vor 1900",
              "volume": 0.03
            },
            {
              "category": "Portfolio",
              "year": 2021,
              "section" : "1900-1950",
              "volume": 0.06
            },
            {
              "category": "Portfolio",
              "year": 2021,
              "section" : "1950-1970",
              "volume": 0.11
            },
            {
              "category": "Portfolio",
              "year": 2021,
              "section" : "1970-1990",
              "volume": 0.19
            },
            {
              "category": "Portfolio",
              "year": 2021,
              "section" : "1990-2010",
              "volume": 0.25
            },
            {
              "category": "Portfolio",
              "year": 2021,
              "section" : "nach 2010",
              "volume": 0.36
            },
    
    
    
    
    
    
            {
              "category": "Benchmark",
              "year": 2020,
              "section" : "vor 1900",
              "volume": 0.06
            },
            {
              "category": "Benchmark",
              "year": 2020,
              "section" : "1900-1950",
              "volume": 0.09
            },
            {
              "category": "Benchmark",
              "year": 2020,
              "section" : "1950-1970",
              "volume": 0.15
            },
            {
              "category": "Benchmark",
              "year": 2020,
              "section" : "1970-1990",
              "volume": 0.23
            },
            {
              "category": "Benchmark",
              "year": 2020,
              "section" : "1990-2010",
              "volume": 0.25
            },
            {
              "category": "Benchmark",
              "year": 2020,
              "section" : "nach 2010",
              "volume": 0.22
            },
    
    
    
            
            {
              "category": "Benchmark",
              "year": 2021,
              "section" : "vor 1900",
              "volume": 0.05
            },
            {
              "category": "Benchmark",
              "year": 2021,
              "section" : "1900-1950",
              "volume": 0.09
            },
            {
              "category": "Benchmark",
              "year": 2021,
              "section" : "1950-1970",
              "volume": 0.14
            },
            {
              "category": "Benchmark",
              "year": 2021,
              "section" : "1970-1990",
              "volume": 0.24
            },
            {
              "category": "Benchmark",
              "year": 2021,
              "section" : "1990-2010",
              "volume": 0.25
            },
            {
              "category": "Benchmark",
              "year": 2021,
              "section" : "nach 2010",
              "volume": 0.23
            }
    
    
    
          ],
          "transform": [
            {
              "type": "stack",
              "groupby": ["category","year"],
              "field": "volume"
            },
            {
              "type": "formula",
              "as": "colorParam",
              "expr": "datum.section+' '+datum.category"
            },          
            {
              "type": "formula", 
              "as": "volumePerc", 
              "expr": "format(datum.volume,'.0%')"
            }
          ]
        }
      ],
    
    
      "signals": [
        { "name": "sfont", "value" : "Arial Narrow, serif"},
        { "name": "sfontBold", "value" : "Arial Black, serif"},
        { "name": "sfontSize", "value" : 16},
        { "name": "sfontColor", "value" : "#595959"}
      ],
    
    
    
      "scales": [
        {
          "name": "xCategoryScale",
          "type": "band",
          "domain": {
            "data": "table",
            "field": "category"
          },
          "range": "width"
        },
        {
          "name": "yscale",
          "type": "linear",
          "domain": [0,1],
          "range": "height",
          "nice": true
        },
        {
          "name": "colorScale",
          "type": "ordinal",        
          "domain": {
            "data": "table",
            "field": "colorParam"
          },
          "range": [
              "#172431",
              "#426990",
              "#638EB9",
              "#8BABCB",
              "#BFD1E3",
              "#D7E2ED",
    
              "#322B22", 
              "#6F5F4D",
              "#958069",
              "#AE9D8B",
              "#D3C9BF",
              "#F1EEEB"
          ]
        },
        {
          "name": "legendColorScale",
          "type": "ordinal",     
          "domain": [
            "nach 2010",
            "1990-2010",
            "1970-1990",
            "1950-1970",
            "1900-1950",
            "vor 1900"
            ],
          "range": [
              "#d9d9d9",
              "#bfbfbf",
              "#a6a6a6",
              "#7f7f7f",
              "#595959",
              "#262626"
          ]
        }
      ],
      "axes": [
        {
          "orient": "left",
          "scale": "yscale",
          "tickCount": 6,
          "grid": true,
          "title": "m²EBF-%",
          "titleX":-40,
          "titleFontSize": {"signal": "sfontSize"},
          "titleFont": {"signal": "sfont"},
          "titleColor":{"signal": "sfontColor"},
          "titleFontWeight": "normal",
          "labelFontSize": {"signal": "sfontSize"},
          "labelFont": {"signal": "sfont"},
          "labelColor":{"signal": "sfontColor"},    
          "encode": {
          "labels": {
            "update": {
              "text": {"signal": "format(datum.value, '.0%')"}
            }
          }
        }
        },
        {
          "orient": "bottom",
          "scale": "xCategoryScale",
          "tickBand": "extent",
          "tickSize": 50,    
          "titleFontSize": {"signal": "sfontSize"},
          "titleFont": {"signal": "sfont"},
          "titleColor":{"signal": "sfontColor"},
          "titleFontWeight": "normal",
          "labelFontSize": {"signal": "sfontSize"},
          "labelFont": {"signal": "sfont"},
          "labelColor":{"signal": "sfontColor"},     
          "encode": {
            "labels": {
              "update": {
                "dy": {
                  "value": -20
                }
              }
            }
          }
        }
      ],
    
    "legends": [
    {
      "type": "symbol",
      "fill": "legendColorScale",    
      "symbolType": "square",
      "orient":"right",
      "legendX": {"signal": "width", "offset": 20},
      "legendY": {"signal": "height / 2", "offset":-40},
      "labelFontSize": {"signal": "sfontSize"},
      "labelFont": {"signal": "sfont"},
      "labelColor":{"signal": "sfontColor"}   
    }
    ],
    
      "marks": [
        {
          "name": "categories",
          "type": "group",
          "from": {
          "facet": { 
            "data": "table",
            "name": "perCategory",
            "groupby": "category"          
            }
          },
          "encode": {
            "enter": {
              "x": {
                "scale": "xCategoryScale",
                "field": "category"
              },
              "width": {
                "scale": "xYearScale",
                "band": 1
              },
              "y": {
                "scale": "yscale",
                "field": "volume"
              },
              "y2": {
                "scale": "yscale",
                "value": 0
              }
            }
          },
    
          "signals": [
            {
              "name": "width",
              "update": "bandwidth('xCategoryScale')"
            }
          ],
          "scales": [
            {
              "name": "xYearScale",
              "type": "band",
              "range": "width",
              "domain": {
                "data": "perCategory",
                "field": "year"
              },
              "padding": 0.06
            }
          ],
    
        "axes": [
            {
              "orient": "bottom", 
              "scale": "xYearScale", 
              "zindex": 1,
              "offset": {"signal": "height"},
              "tickSize":{"value": 0},     
              "labelFontSize": {"signal": "sfontSize"},
              "labelFont": {"signal": "sfont"},
              "labelColor":{"signal": "sfontColor"},    
              "encode": {
                "labels": {
                  "update": {
                    "dy" : {"value": 5}
                  }
                }
              }
            }
          ],
    
          "marks": [
            {
                "name": "volumeBars",
                "from": { "data": "perCategory"},
                "type": "rect",
                "encode": {
                  "enter": {
                    "x": {
                      "scale": "xYearScale",
                      "field": "year",
                      "band": 0.3
                    },
                    "width": {
                      "scale": "xYearScale",
                      "band": 0.4
                    },
                    "y": {
                      "scale": "yscale",
                      "field": "y0"
                    },
                    "y2": {
                      "scale": "yscale",
                      "field": "y1"
                    },
                    "fill": {
                      "scale": "colorScale",
                      "signal": "datum.colorParam"
                    }
                  }
                }
              },
              {
                "name": "barLabel",
                "type": "text",
                "from": {
                  "data": "volumeBars"
                },
                "encode": {
                  "enter": {
                    "y": {
                      "field": "y",
                      "offset": {
                        "field": "height",
                        "mult":0.5
                      }
                    },
                    "x": {
                      "field": "x",
                      "offset": {
                        "field": "width",
                        "mult": 0.5
                      }
                    },
                    "stroke":{"value": "white"},
                    "strokeWidth":{"value": 0.4},
                    "fontSize": {"signal": "sfontSize"},
                    "font": {"signal": "sfontBold"},
                    "color":{"signal": "sfontColor"},
                    "baseline":{"value": "middle"},
                    "fill":{"value": "black"},                  
                    "align": [
                      {
                        "test": "indexof(data('volumeBars'), datum) % 2 == 0",
                        "value": "right"
                      },
                      {
                        "value": "left"
                      }
                    ],               
                    "text": {
                      "field": "datum.volumePerc"                    
                    }
                  }
                }
              }   
              
          ]
        }
      ]
    
    
    }