Dec 7th, 2022: [EN] Map your distributed team in Kibana

Working in a distributed company like Elastic is great, but can sometimes be hard to grasp. Answering some seemingly simple questions can be surprisingly complicated, like:

  • Show our team on a map, so I can explain our reach and structure.
  • Let me find anyone in a certain area, so we know who is "local".
  • Find someone with a specific skill close by.
  • Show the team growth over time.
  • Document region coverage, so anyone can look it up.

Luckily, Kibana can help here and the goal of this post is to create a map like this:

Mapping and Data in Elasticsearch

Before you can jump into the visualization, you need to create the correct mapping (or schemaΒ β€” this isn't directly related to a map yet :sweat_smile:). Run the following request in Kibana's Console to create the mapping:

PUT team
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "name": {
        "type": "keyword"
      },
      "team": {
        "type": "keyword"
      },
      "role": {
        "type": "keyword"
      },
      "start_date": {
        "type": "date"
      },
      "country_code": {
        "type": "keyword"
      },
      "city": {
        "type": "keyword"
      },
      "location": {
        "type": "geo_point"
      },
      "technology": {
        "type": "keyword"
      },
      "region": {
        "type": "keyword"
      },
      "picture": {
        "type": "keyword"
      }
    }
  }
}

Most important in the mapping is:

  • geo_point is the most important data type to use on a map.
  • The date field is necessary to show the development over time.

To keep it simple, the sample data set used only includes the Community team in Europe:

PUT team/_doc/david
{
  "name": "David Pilato",
  "team": "community",
  "role": "Developer πŸ₯‘",
  "start_date": "2013-01-10",
  "country_code": "fr",
  "city": "Cergy",
  "location": {
    "lat": 49.05,
    "lon": 2.04
  },
  "technology": ["java", "elasticsearch", "search"],
  "picture": "https://avatars.githubusercontent.com/u/274222"
}
PUT team/_doc/philipp
{
  "name": "Philipp Krenn",
  "team": "community",
  "role": "Developer πŸ₯‘ | EMEA Lead",
  "start_date": "2016-04-01",
  "country_code": "at",
  "city": "Vienna",
  "location": {
    "lat": 48.21,
    "lon": 16.37
  },
  "technology": ["java", "automation", "observability"],
  "picture": "https://avatars.githubusercontent.com/u/432211"
}
PUT team/_doc/adrienne
{
  "name": "Adrienne de Vries",
  "team": "community",
  "role": "Community Programs",
  "start_date": "2019-12-02",
  "country_code": "nl",
  "city": "Rotterdam",
  "location": {
    "lat": 51.92,
    "lon": 4.48
  },
  "region": ["FR", "ES", "PT", "IT", "GR", "TR", "CY", "NL", "BE", "DK", "LU", "NO", "SE", "FI", "IS", "EE", "LV", "LT", "MA", "TN", "DZ"],
  "picture": "https://ca.slack-edge.com/T0CUZ52US-UQQ55JABU-56457843fc81-512"
}
PUT team/_doc/naoise
{
  "name": "Naoise Rush",
  "team": "community",
  "role": "Community Programs",
  "start_date": "2022-02-28",
  "country_code": "gb",
  "city": "Belfast",
  "location": {
    "lat": 54.60,
    "lon": -5.93
  },
  "region": ["GB", "IE", "DE", "AT", "CH", "PL", "CZ", "SK", "SI", "HU", "RO", "BG", "MD", "UA", "HR", "RS", "BA", "AL", "XK", "ME", "MK", "IL", "SA", "EG", "AE", "JO", "LB", "KW", "QA", "OM", "BH"],
  "picture": "https://ca.slack-edge.com/T0CUZ52US-U033ZF1HPM3-3f8511dbc26f-512"
}
PUT team/_doc/carly
{
  "name": "Carly Richmond",
  "team": "community",
  "role": "Developer πŸ₯‘",
  "start_date": "2022-04-25",
  "country_code": "uk",
  "city": "London",
  "location": {
    "lat": 51.55,
    "lon": 0.16
  },
  "technology": ["javascript", "frontend", "observability"],
  "picture": "https://avatars.githubusercontent.com/u/74931905"
}

Adding the Data in Kibana

Before you can use the data in Kibana, you need to add the indexed data to a Data View:

And to use the pictures, you need to customize the picture field to a Url of the type Image and set the URL template to {{rawValue}}:

Once set up, you can view the underlying documents in Discover and change the timeframe to 10 years (from the default of 15 minutes):

Adding the First Map β€” at Last

Maps in Kibana have a lot of features, but the example will keep it simple. Add a layer of the type Documents:

And in the team index, pick the only available geo-point location:

Add the most relevant tooltip fields:

And adjust the color of each document by the role:

And that's all we need to get the team on the map. If you don't see anything, double-check that you have picked the past 10 years and not just 15 minutes again. Hovering over one of them reveals their profile and based on the color you can tell their role:

Mapping Time

Based on the start_date field for each team member, you can show how it developed over time or even autoplay it year by year:

Putting Search on the Map

Search is core to what we do. So if you want to figure out who on our team could help you out with all things "frontend", you could also find that on the map:

Mapping Regions

Our team also has the concept of owning certain regions. Time to add another layer to the map β€” this time it's the Choropleth. The region array of the Elasticsearch documents maps to the ISO 3166-1 alpha-2 code of countries. And we can limit it to the role of "Community Programs", since only they own regions:

Sprinkling a bit of color on top by name:

And we have neatly mapped out the ownership of the entire region:

Helping Santa Find the Team

To add something more Christmas related, let's help Santa find the team. This information should go in a new index with the simple mapping for source and destination geo-points in one document:

PUT santa
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "@timestamp": {
        "type": "date"
      },
      "source": {
        "type": "geo_point"
      },
      "destination": {
        "type": "geo_point"
      }
    }
  }
}

And these are the documents for the actual travel route:

POST santa/_doc
{
  "@timestamp": "2022-12-24T19:30Z",
  "source": {
    "lat": 48.21,
    "lon": 100
  },
  "destination": {
    "lat": 48.21,
    "lon": 16.37
  }
}
POST santa/_doc
{
  "@timestamp": "2022-12-24T19:40Z",
  "source": {
    "lat": 48.21,
    "lon": 16.37
  },
  "destination": {
    "lat": 49.05,
    "lon": 2.04
  }
}
POST santa/_doc
{
  "@timestamp": "2022-12-24T19:50Z",
  "source": {
    "lat": 49.05,
    "lon": 2.04
  },
  "destination": {
    "lat": 51.92,
    "lon": 4.48
  }
}
POST santa/_doc
{
  "@timestamp": "2022-12-24T20:00Z",
  "source": {
    "lat": 51.92,
    "lon": 4.48
  },
  "destination": {
    "lat": 51.55,
    "lon": 0.16
  }
}
POST santa/_doc
{
  "@timestamp": "2022-12-24T20:10Z",
  "source": {
    "lat": 51.55,
    "lon": 0.16
  },
  "destination": {
    "lat": 54.60,
    "lon": -5.93
  }
}
POST santa/_doc
{
  "@timestamp": "2022-12-24T20:20Z",
  "source": {
    "lat": 54.60,
    "lon": -5.93
  },
  "destination": {
    "lat": 54.60,
    "lon": -20.00
  }
}

Add one more layer, this time with Point to point. In which you map source and destination:

And with some minor customization, you can show Santa the way to everyone on the team. Picking the right timeframe, you could even follow along as the reindeers are traversing every segment on the route:

Conclusion

We hope that this gave you some ideas on how to put distributed teams on the map. Kibana can still do a lot more β€” the documentation for maps is a great starting point there.

5 Likes

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.