How to Make Vega Visualization Scrollable in Kibana Dashboard for All Data?

Hi everyone,

I'm using Vega to create a table visualization in Kibana. The issue I'm facing is that the table only shows data up to the height of the visualization. If I expand the visualization panel, more rows become visible, but I need the table to show all data in a scrollable format, regardless of the panel's height.

Here's what I’ve tried so far:

  1. Set autosize to none with resize: true.
  2. Configured overflow: "scroll" in the group style.
  3. Defined a fixed height using a signal like tableHeight.

While these changes added a scrollbar, the data rendering is still tied to the panel's height. Rows beyond the panel's size are not rendered unless I resize the visualization.

How can I ensure that all data is rendered and scrollable within the table, without requiring the panel to be resized?

Any insights or solutions would be greatly appreciated!

Code:
{
$schema: https://vega.github.io/schema/vega/v5.json
autosize: {
type: fit - y
resize: true
contains: padding
}
signals: [
{
name: tableWidth
update: width
}
{
name: tableHeight
update: rowHeight * length(data('source'))
}
{
name: rowHeight
value: 30
}
{
name: userColumnWidth
update: tableWidth * 0.25
}
{
name: companyColumnWidth
update: tableWidth * 0.15
}
{
name: remainingWidth
update: tableWidth - (userColumnWidth + companyColumnWidth)
}
{
name: otherColumnWidth
update: remainingWidth / 3.5
}
{
name: isEmpty
update: length(data('source')) === 0
}
]
data: [
{
name: source
url: {
%context%: true
index: klenty-call-logs-*
body: {
size: 0
aggs: {
users: {
terms: {
field: username.keyword
size: 1000
}
aggs: {
current_week: {
filter: {
range: {
@timestamp: {
gte: now/w
lt: now
}
}
}
aggs: {
call_count: {
filter: {
bool: {
should: [
{
term: {
event.keyword: call_initialted
}
}
{
term: {
event.keyword: call_initiated
}
}
]
}
}
}
}
}
previous_week: {
filter: {
range: {
@timestamp: {
gte: now-1w/w
lt: now/w
}
}
}
aggs: {
call_count: {
filter: {
bool: {
should: [
{
term: {
event.keyword: call_initialted
}
}
{
term: {
event.keyword: call_initiated
}
}
]
}
}
}
}
}
compare_counts: {
bucket_selector: {
buckets_path: {
current: current_week>call_count._count
previous: previous_week>call_count._count
}
script: params.current < params.previous
}
}
companyName_filtered: {
filter: {
bool: {
must: [
{
exists: {
field: companyName
}
}
]
}
}
aggs: {
companyName: {
top_hits: {
size: 1
_source: [
companyName
]
}
}
}
}
}
}
}
}
}
format: {
property: aggregations.users.buckets
}
}
]
scales: [
{
name: y
type: band
domain: {
data: source
field: key
}
range: [
0
{
signal: rowHeight * length(data('source'))
}
]
padding: 0.1
}
]
config: {
style: {
group: {
overflow: auto
}
}
}
marks: [
{
type: text
encode: {
enter: {
x: {
value: 10
}
y: {
value: 20
}
text: {
value: User
}
fontSize: {
value: 16
}
fontWeight: {
value: bold
}
fill: {
value: black
}
}
}
}
{
type: text
encode: {
enter: {
x: {
signal: userColumnWidth + 10
}
y: {
value: 20
}
text: {
value: Company
}
fontSize: {
value: 16
}
fontWeight: {
value: bold
}
fill: {
value: black
}
}
}
}
{
type: text
encode: {
enter: {
x: {
signal: userColumnWidth + companyColumnWidth + otherColumnWidth
}
y: {
value: 20
}
text: {
value: Previous Week
}
fontSize: {
value: 16
}
fontWeight: {
value: bold
}
fill: {
value: black
}
}
}
}
{
type: text
encode: {
enter: {
x: {
signal: userColumnWidth + companyColumnWidth + otherColumnWidth * 2
}
y: {
value: 20
}
text: {
value: Current Week
}
fontSize: {
value: 16
}
fontWeight: {
value: bold
}
fill: {
value: black
}
}
}
}
{
type: text
encode: {
enter: {
x: {
signal: userColumnWidth + companyColumnWidth + otherColumnWidth * 3
}
y: {
value: 20
}
text: {
value: Difference
}
fontSize: {
value: 16
}
fontWeight: {
value: bold
}
fill: {
value: black
}
}
}
}
{
type: text
from: {
data: source
}
encode: {
enter: {
x: {
value: 10
}
y: {
scale: y
field: key
offset: 50
}
text: {
field: key
}
fontSize: {
value: 15
}
fill: {
value: black
}
}
}
}
{
type: text
from: {
data: source
}
encode: {
enter: {
x: {
signal: userColumnWidth + 10
}
y: {
scale: y
field: key
offset: 50
}
text: {
field: companyName_filtered.companyName.hits.hits[0]._source.companyName
}
fontSize: {
value: 15
}
fill: {
value: black
}
}
}
}
{
type: text
from: {
data: source
}
encode: {
enter: {
x: {
signal: userColumnWidth + companyColumnWidth + otherColumnWidth
offset: 45
}
y: {
scale: y
field: key
offset: 50
}
text: {
field: previous_week.call_count.doc_count
}
fontSize: {
value: 15
}
fill: {
value: black
}
}
}
}
{
type: text
from: {
data: source
}
encode: {
enter: {
x: {
signal: userColumnWidth + companyColumnWidth + otherColumnWidth * 2
offset: 45
}
y: {
scale: y
field: key
offset: 50
}
text: {
field: current_week.call_count.doc_count
}
fontSize: {
value: 15
}
fill: {
value: black
}
}
}
}
{
type: text
from: {
data: source
}
encode: {
enter: {
x: {
signal: userColumnWidth + companyColumnWidth + otherColumnWidth * 3
offset: 30
}
y: {
scale: y
field: key
offset: 50
}
text: {
signal: (datum.previous_week.call_count.doc_count || 0) - (datum.current_week.call_count.doc_count || 0)
}
fontSize: {
value: 15
}
fill: {
value: black
}
}
}
}
{
type: text
encode: {
update: {
x: {
signal: width / 2
}
y: {
signal: height / 2
}
text: {
value: No users found
}
align: {
value: center
}
baseline: {
value: middle
}
fontSize: {
value: 16
}
fill: {
value: grey
}
opacity: {
signal: isEmpty ? 1 : 0
}
}
}
}
]
}

Hi @Yokesh_GK,

Can you confirm which version of Kibana you are using? I did come across this issue with a recent comment that the below snippet worked for them in 8.10 but not 7.17:

"autosize": {"contains": "padding", "type": "fit"  } 

Let us know!

My kibana version is 7.17, Is there any way to solve the problem?