Dynamic fetch data from index to generate TreeFlow

Yup document need to be skipped .. OK will explore that option .. Thanks

@markov00 Could you pls confirm if we can collapse and expand this tree flow. We have too much data and its cluttered . So wanted to check if we can collapse and expand the tree

mmm, I'm pretty sure something can be done but it can be complex.
For sure you can filter out by depth, like showing only the first two layers for example, but collapse/expand on click can be probably a bit more complicated.

1 Like

Hey Anjana,
could you please share the final code, with which you were able to create tree flow dynamically? I am working on a similar thing.

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "An example of Cartesian layouts for a node-link diagram of hierarchical data.",
  "width": 600,
  "height": 600,
  "padding": 5,
  "signals": [
    {
      "name": "labels",
      "value": true,
      "bind": {
        "input": "checkbox"
      }
    },
    {
      "name": "layout",
      "value": "tidy",
      "bind": {
        "input": "radio",
        "options": [
          "tidy",
          "cluster"
        ]
      }
    },
    {
      "name": "links",
      "value": "diagonal",
      "bind": {
        "input": "select",
        "options": [
          "line",
          "curve",
          "diagonal",
          "orthogonal"
        ]
      }
    },
    {
      "name": "separation",
      "value": false,
      "bind": {
        "input": "checkbox"
      }
    }
  ],
  "data": [
    {
      "name": "table",
      "url": {
      "%context%": true,
      "%timefield%": "@timestamp",
      "index": "apm-*",
      "body": {
        "aggs": {
          "time_buckets": {
            "date_histogram": {
              "field": "@timestamp",
              "interval": {"%autointerval%": true},
              "extended_bounds": {
                "min": {"%timefilter%": "min"},
                "max": {"%timefilter%": "max"}
              },
              "min_doc_count": 0
            }
          }
        },
        "size": 10
     } }
      "format": {"property": "hits.hits"
      } ,
   
      "transform": [
      
      {"type": "formula", "as": "OrgId", "expr": "datum._source['labels.OrgId']"},
       {"type": "formula", "as": "Region", "expr": "datum._source.OrgHier.Region"},
       {"type": "formula", "as": "StoreNum", "expr": "datum._source['labels.StoreNum']"},
        {"type": "formula", "as": "RegisterNum", "expr": "datum._source['labels.RegisterNum']"},
        {"type": "formula", "as": "ServiceName", "expr": "datum._source.ServiceName"},
        {"type": "formula", "as": "ServiceSummary", "expr": "datum._source.ServiceSummary"},
        {
          "type": "fold",
          "fields": [
            "OrgId",
            "Region",
            "StoreNum",
            "RegisterNum",
            "ServiceName",
            "ServiceSummary"
          ]
        },
        {
          "type": "formula",
        "as": "id",
          "expr": "datum.key == 'OrgId' ? datum.OrgId : datum.key == 'Region' ? join([datum.OrgId,datum.Region],'-') : datum.key == 'StoreNum' ? join([datum.OrgId, datum.Region, datum.StoreNum],'-') : datum.key == 'RegisterNum' ? join([datum.OrgId, datum.Region, datum.StoreNum, datum.RegisterNum],'-') : datum.key == 'ServiceName' ? join([datum.OrgId, datum.Region, datum.StoreNum, datum.RegisterNum,datum.ServiceName],'-'):datum.key == 'ServiceSummary' ? join([datum.OrgId, datum.Region, datum.StoreNum, datum.RegisterNum,datum.ServiceName,datum.ServiceSummary],'-'):null"
        },
        {
          "type": "formula",
          "as": "parent",
          "expr": "datum.key == 'OrgId' ? null : datum.key == 'Region' ? datum.OrgId : datum.key == 'StoreNum' ? join([datum.OrgId, datum.Region],'-') : datum.key == 'RegisterNum' ? join([datum.OrgId, datum.Region, datum.StoreNum],'-') :  datum.key == 'ServiceName' ? join([datum.OrgId, datum.Region, datum.StoreNum,datum.RegisterNum],'-'):  datum.key == 'ServiceSummary' ? join([datum.OrgId, datum.Region, datum.StoreNum,datum.RegisterNum,datum.ServiceName],'-'):null"
        },
        {
          "type": "filter",
          "expr": "isDefined(datum.value)"
        },
        {
          "type": "aggregate",
          "groupby": [
            "id",
            "parent"
          ]
        },
        {
          "type": "formula",
          "as": "label",
          "expr": "peek(split(datum.id,'-'))"
        }
      ]
    },
    {
      "name": "tree",
      "source": "table",
      "transform": [
        {
          "type": "stratify",
          "key": "id",
          "parentKey": "parent"
        },
        {
          "type": "tree",
          "method": {
            "signal": "layout"
          },
          "size": [
            {
              "signal": "height"
            },
            {
              "signal": "width - 100"
            }
          ],
          "separation": {
            "signal": "separation"
          },
          "as": [
            "y",
            "x",
            "depth",
            "children"
          ]
        }
      ]
    },
    {
      "name": "links",
      "source": "tree",
      "transform": [
        {
          "type": "treelinks"
        },
        {
          "type": "linkpath",
          "orient": "horizontal",
          "shape": {
            "signal": "links"
          }
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "color",
      "type": "linear",
      "range": {
        "scheme": "magma"
      },
      "domain": {
        "data": "tree",
        "field": "depth"
      },
      "zero": true
    }
  ],
  "marks": [
    {
      "type": "path",
      "from": {
        "data": "links"
      },
      "encode": {
        "update": {
          "path": {
            "field": "path"
          },
          "stroke": {
            "value": "#ccc"
          }
        }
      }
    },
    {
      "type": "symbol",
      "from": {
        "data": "tree"
      },
      "encode": {
        "enter": {
          "size": {
            "value": 100
          },
          "stroke": {
            "value": "#fff"
          }
        },
        "update": {
          "x": {
            "field": "x"
          },
          "y": {
            "field": "y"
          },
          "fill": {
            "scale": "color",
            "field": "depth"
          }
        }
      }
    },
    {
      "type": "text",
      "from": {
        "data": "tree"
      },
      "encode": {
        "enter": {
          "text": {
            "field": "label"
          },
          "fontSize": {
            "value": 9
          },
          "baseline": {
            "value": "middle"
          }
        },
        "update": {
          "x": {
            "field": "x"
          },
          "y": {
            "field": "y"
          },
          "dx": {
            "signal": "datum.children ? -7 : 7"
          },
          "align": {
            "signal": "datum.children ? 'right' : 'left'"
          },
          "opacity": {
            "signal": "labels ? 1 : 0"
          }
        }
      }
    }
  ]
}

Thank you very much, Anjana! In my case, it shows multiple roots or ambiguous errors. As I am dealing with Urls child may refer to multiple parents (causing multiple root or ambiguous errors). Is it possible to resolve this ambiguity or multiple root errors? please suggest.

Hi @markov00 ,

I had another question here. The values that are shows here, like 1001, EAST etc how do we change its color. I have a black background and the values are not readable now Thanks

hi @anjana1
Looking at your vega spec, one thing you can try is to change the color scale to ordinal (that should at least work better then the linear in your case)
something like that should work:

 {
      "name": "color",
      "type": "ordinal",
      "range": {"scheme": "category20"},
      "domain": {
        "data": "tree",
        "field": "depth"
      },
      "zero": true
    }

and try one of the color schemes allowed: Color Schemes | Vega

Thanks @markov00


tried and it didn't change the text color . It only changes those node colors.

oh sorry, I was thinking at the nodes, sorry. For labels just add the fill to the text like:

{
      "type": "text",
      "from": {
        "data": "tree"
      },
      "encode": {
        "enter": {
          "text": {
            "field": "label"
          },
          "fill": {
            "value": "white"
          },
          "fontSize": {
            "value": 9
          },
          "baseline": {
            "value": "middle"
          }
        },

You can use css colors or hex values

1 Like

hei @Ashvin_Bhutekar can you please provide an example for that dataset and the kind of error you are receiving?