Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!

Reply
Louis66
Resolver I
Resolver I

Bubbles on a 'timeline'

Hello to all,

 

I found this 'time line' (increasing numbers on the X-axis). For example, if the number is #351, it refers to number #349 and #351 - so a circle with a center at #351, radius = 2 :

Louis66_1-1675609573853.png

Any way to do this in Power BI ? Regards,

 

Louis

 

1 ACCEPTED SOLUTION

Interactive version: 
https://vega.github.io/editor/#/gist/813b7398a99f652252b5cdf2c215b7c2/spec.json

 

giphy



Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!

View solution in original post

12 REPLIES 12
giammariam
Super User
Super User

Thanks @Louis66. If you run into issues getting it working in Deneb, let me know.



Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!
ppm1
Solution Sage
Solution Sage

That should be possible with the Deneb visual. Provide some sample data and describe the logic of the visual a little more (i.e., how the size and position of each circle is defined), and someone here may try it out and provide a "spec" for you.

 

Declarative Visualization in Power BI | Deneb (deneb-viz.github.io)

 

Pat

 

Microsoft Employee

Hello Pat, my file is Excel, like this :

1 : no circle

2 : no circle

3 : no circle

4 : circle of radius 2 (circle goes from 2 to 6)

5 : no circle

6 : circle of radius 3 (circle goes from 3 to 9) & circle of radius 5 (circle goes from 1 to 11)

7...

 

There could ultimately be a lot of circles !

 

Regards,

 

Louis

@Louis66, if you could provide a sanitized .pbix with data, I'd be happy to give this a shot in Deneb. See the below link on best ways to provide files/data:

How to provide sample data in the Power BI Forum - Microsoft Power BI Community



Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!

1    
2    
3    
42   
5    
635  
7    
81   
9    
102347

 

How the circles are rendered makes sense to me. What I'm having a bit of trouble on is understanding what determines the length of the color bars. I get that the color of the bar corresponds and the color of the circle corresponds to a number on the x-axis.



Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!

Well I don't quite know about the color bars - I am more interested in the circles for now...

Hey @Louis66 , still looking into this. I got pretty close, but ran out of time. Will try to get back with a solution ASAP



Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!

Hello,

 

No problem - I am not in a hurry,

 

Louis

Hey @Louis66. Here's my spin on the circle timeline. Now this one was way trickier than I thought it'd be. I'm sure someone out there could find a better implementation; I had to do some workarounds to get it to work (e.g. use a rect mark instead of an arc or circle). You'll also need to transform your data before putting it into Deneb.

Take a look and let me know your thoughts. If this meets the requirement, consider marking this as the solution.

giammariam_1-1676062021529.png

 


Gist: https://vega.github.io/editor/#/gist/540669549e03f852075e5fcac91f16c2/spec.json
Spec:

 

 

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "params": [
    {"name": "min_adj_pos", "expr": "data('data_0')[0]['min_adj_pos']"},
    {"name": "max_adj_pos", "expr": "data('data_0')[0]['max_adj_pos']"},
    {"name": "color_scheme", "expr": "'tableau20'"},
    {
      "name": "pill_path",
      "expr": "'m 64.920826,87.413086 h 92.524964 c 14.1599,0 25.55938,14.249354 25.55938,31.949234 0,17.69986 -11.39948,31.94922 -25.55938,31.94922 H 64.920826 c -14.159896,0 -25.55938,-14.24936 -25.55938,-31.94922 0,-17.69988 11.399484,-31.949234 25.55938,-31.949234 z'"
    },
    {"name": "pill_xOffset", "expr": "-33"},
    {"name": "pill_yOffset", "expr": "-36"}
  ],
  "data": {
    "name": "dataset",
    "values": [
      {"index": 1, "r": 0},
      {"index": 2, "r": 0},
      {"index": 3, "r": 2},
      {"index": 4, "r": 0},
      {"index": 5, "r": 3},
      {"index": 6, "r": 0},
      {"index": 6, "r": 1},
      {"index": 6, "r": 4},
      {"index": 7, "r": 5},
      {"index": 8, "r": 0},
      {"index": 9, "r": 0},
      {"index": 10, "r": 2},
      {"index": 10, "r": 4},
      {"index": 11, "r": 7},
      {"index": 12, "r": 0}
    ]
  },
  "transform": [
    {
      "window": [{"op": "dense_rank", "as": "index_dr"}],
      "sort": [{"field": "index"}]
    },
    {
      "calculate": "datum['r']<= 0 ? 0 : datum['index']-datum['r']",
      "as": "adj_min_pos"
    },
    {
      "calculate": "datum['r']<= 0 ? 0 : datum['index']+datum['r']",
      "as": "adj_max_pos"
    },
    {
      "joinaggregate": [
        {"op": "min", "field": "adj_min_pos", "as": "min_adj_pos"},
        {"op": "max", "field": "adj_max_pos", "as": "max_adj_pos"}
      ]
    },
    {
      "calculate": "(datum['max_adj_pos']-datum['min_adj_pos'])/2",
      "as": "median_adj_pos"
    }
  ],
  "spacing": 0,
  "vconcat": [
    {
      "width": 800,
      "height": 800,
      "encoding": {
        "x": {
          "field": "index",
          "type": "quantitative",
          "scale": {
            "domain": [{"expr": "min_adj_pos"}, {"expr": "max_adj_pos"}]
          },
          "axis": null
        },
        "y": {
          "field": "index",
          "type": "quantitative",
          "scale": {
            "domain": [{"expr": "min_adj_pos"}, {"expr": "max_adj_pos"}]
          },
          "axis": {"tickCount": {"expr": "max_adj_pos-min_adj_pos"}}
        }
      },
      "layer": [
        {
          "encoding": {
            "color": {
              "field": "index",
              "scale": {"scheme": {"expr": "color_scheme"}},
              "legend": null
            }
          },
          "transform": [
            {"calculate": "width", "as": "width"},
            {"calculate": "datum['median_adj_pos']-datum['r']", "as": "y"},
            {"calculate": "datum['median_adj_pos']+datum['r']", "as": "y2"}
          ],
          "layer": [
            {
              "description": "circles",
              "mark": {
                "type": "rect",
                "opacity": 1,
                "cornerRadius": 9000000000,
                "strokeWidth": 1,
                "fillOpacity": 0
              },
              "encoding": {
                "stroke": {
                  "field": "index",
                  "scale": {"scheme": {"expr": "color_scheme"}},
                  "legend": null
                },
                "x": {"field": "adj_min_pos", "type": "quantitative"},
                "x2": {"field": "adj_max_pos"},
                "y": {"field": "y", "type": "quantitative", "axis": null},
                "y2": {"field": "y2"}
              }
            },
            {
              "layer": [
                {
                  "transform": [
                    {"filter": "datum['r']>0"},
                    {
                      "window": [
                        {"op": "dense_rank", "as": "dr_index_updated"}
                      ],
                      "sort": [{"field": "index"}]
                    },
                    {
                      "calculate": "datum['dr_index_updated']%2",
                      "as": "alternate"
                    },
                    {
                      "calculate": "datum['alternate'] == 1 ? datum['y'] : datum['y2']",
                      "as": "y"
                    }
                  ],
                  "description": "vertical lines",
                  "mark": {
                    "type": "rule",
                    "opacity": 1,
                    "strokeWidth": 1,
                    "fillOpacity": 0,
                    "strokeDash": [5, 5]
                  },
                  "encoding": {
                    "stroke": {
                      "field": "index",
                      "scale": {"scheme": {"expr": "color_scheme"}},
                      "legend": null
                    },
                    "x": {"field": "index", "type": "quantitative"},
                    "x2": {"field": "index"},
                    "y": {"field": "y", "type": "quantitative", "axis": null},
                    "y2": {"field": "median_adj_pos"}
                  }
                },
                {
                  "description": "line label background (color)",
                  "transform": [{"filter": "datum['r']>0"}],
                  "mark": {
                    "type": "point",
                    "shape": {"expr": "pill_path"},
                    "xOffset": {"expr": "pill_xOffset"},
                    "yOffset": {"expr": "pill_yOffset"}
                  },
                  "encoding": {
                    "x": {"field": "index", "type": "quantitative"},
                    "y": {
                      "field": "median_adj_pos",
                      "type": "quantitative",
                      "axis": null
                    },
                    "size": {"value": 0.35}
                  }
                },
                {
                  "description": "line label background (white)",
                  "transform": [{"filter": "datum['r']==0"}],
                  "mark": {
                    "type": "point",
                    "shape": {"expr": "pill_path"},
                    "xOffset": {"expr": "pill_xOffset"},
                    "yOffset": {"expr": "pill_yOffset"}
                  },
                  "encoding": {
                    "x": {"field": "index", "type": "quantitative"},
                    "y": {
                      "field": "median_adj_pos",
                      "type": "quantitative",
                      "axis": null
                    },
                    "size": {"value": 0.35},
                    "color": {"value": "white"}
                  }
                },
                {
                  "description": "line labels",
                  "transform": [
                    {
                      "window": [{"op": "row_number", "as": "dr_index_rn"}],
                      "groupby": ["index"]
                    },
                    {"filter": "datum['dr_index_rn'] == 1"}
                  ],
                  "mark": {
                    "type": "text",
                    "opacity": 1,
                    "stroke": "gray",
                    "filled": false,
                    "strokeOffset": {"expr": "1"},
                    "fontSize": 18,
                    "align": "center"
                  },
                  "encoding": {
                    "text": {"field": "index"},
                    "x": {"field": "index", "type": "quantitative"},
                    "y": {
                      "field": "median_adj_pos",
                      "type": "quantitative",
                      "axis": null
                    }
                  }
                }
              ],
              "resolve": {"legend": {"color": "independent"}}
            }
          ]
        }
      ]
    }
  ],
  "resolve": {"axis": {"x": "shared"}, "scale": {"x": "shared"}}
}

 

 

 

@dm-p, would love to get your thoughts on how you'd implement this one. Probably would be more suitable for Vega instead of Vega-Lite.






Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!

Interactive version: 
https://vega.github.io/editor/#/gist/813b7398a99f652252b5cdf2c215b7c2/spec.json

 

giphy



Madison Giammaria
Proud to be a Super User 😄
LinkedIn

Do you frequently use Deneb to provide insights to your stakeholders? Have you considered sponsoring this free and open source custom visual? More info here!

Djeez - this is something ! Good job !

Helpful resources

Announcements
April AMA free

Microsoft Fabric AMA Livestream

Join us Tuesday, April 09, 9:00 – 10:00 AM PST for a live, expert-led Q&A session on all things Microsoft Fabric!

March Fabric Community Update

Fabric Community Update - March 2024

Find out what's new and trending in the Fabric Community.