Label mark

The vgg-label mark is used to plot text elements.

 <vgg-label
  :x="row.year"
  :y="row.population"
  :text="row.population"
  :font-size="12"
  font-family="Comic Sans MS"
  fill="#c66366"
/>

Properties

Positioning

Prop Input Required Types Default Unit(s)
x x coordinate see Usage Number
| String
| Date
undefined Local coordinates
y y coordinate see Usage Number
| String
| Date
undefined Local coordinates
geometry GeoJSON Point object see Usage Object undefined Local coordinates

Other aesthetics

Prop Required Types Default Description Unit(s)
text false Number
| String
undefined Text to display NA
font-size false Number 16 Font size Screen pixel
font-weight false Number
| String
'normal' Font weight Either a number between 0 and 1000, or 'normal', 'bold', etc.
font-family false String 'Helvetica' Font family Name of font family
rotation false Number 0 Degrees with which to rotate the mark Degrees
anchor-point false String 'center' Anchor point for x/y coordinate One of ['center', 'lb', 'lt', 'rt', 'rb', 'l', 'r', 't', 'b']
stroke false String 'none' Stroke color Named color, hex, rgb, hsl
stroke-width false Number 0 Stroke width Screen pixel
stroke-opacity false Number 1 Stroke opacity Number between 0 and 1
fill false String '#000000' Fill color Named color, hex, rgb, hsl
fill-opacity false Number 1 Fill opacity Number between 0 and 1
opacity false Number 1 Mark opacity Number between 0 and 1

These are analogous to the CSS properties of the same names.

Usage

Positioning

To render the Label mark, you will need to provide one of the following positioning props:

  • x and y or
  • geometry

x and y can be used with data of types Number, String or Date, while geometry should be used for geographic data containing Point objects only. To render other geometry types, see the overview on Geo marks.

Data is passed to the x, y and geometry props via row mapping, which renders one mark per data row. For a more in-depth explanation on how mapping works, see the Map section under Core components.

Recall that input data (whether in row or column oriented format)

<vgg-data
  :data="{
    year: [2000, 2005, 2010, 2015],
    population: [100, 110, 130, 180]
  }"
>
</vgg-data>

is represented internally in tabular form, with each row corresponding to a single data instance

year population
2000 100
2005 110
2010 130
2015 180

To pass data into the x and y props, simply access each data row's column name:

<vgg-map v-slot="{ row }">
  <vgg-label
    :x="row.year"
    :y="row.population"
  />
</vgg-map>

GeoJSON input such as

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          3.384082,
          6.455027
        ]
      },
      "properties": {
        "name": "Lagos",
        "anchor": "rb",
        "fill": "#f2e5d7"
      }
    }
    ...
  ]
}

is similarly tabularized, with each row representing one feature

geometry name anchor fill
geometry Object 'Lagos' 'rb' '#f2e5d7'
... ... ... ...

To pass data to the geometry prop, simply access the geometry column of each feature with row.geometry:

<vgg-map v-slot="{ row }">
  <vgg-label
    :geometry="row.geometry"
  />
</vgg-map>

Examples

The graphic below shows the 10 most populous cities on the African continent according to World Atlas and demonstrates how vgg-label can be used to annotate cities on a map.

First, we need geodata supplied as a json indicating the geographical coordinates of each city and its attributes. Shown here is a single data point describing the city of Lagos.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          3.384082,
          6.455027
        ]
      },
      "properties": {
        "name": "Lagos", // text to be displayed
        "anchor": "rb", // relative position of coordinates with respect to text
        "fill": "#f2e5d7" // color of text
      }
    }
  ]
}

Next we will define the mark using the vgg-label component. Each prop serves to instruct the component on how the label should be rendered. The coordinates tell us where the label should be positioned at [ 3.384082, 6.455027 ], anchor that the coordinates should be positioned at 'rb' (right-bottom of the text element), name that our label will display the text 'Lagos', and fill that it should be a light grayish orange color.

<vgg-data :data="points">

  <vgg-map v-slot="{ row }">

    <vgg-label
      :geometry="row.geometry"
      :text="row.name"
      :anchor-point="row.anchor"
      :fill="row.fill"
      :font-size="12"
      :font-family="'Verdana'"
    />

  </vgg-map>

</vgg-data>

Finally we are left with rendering the continent itself, which can be drawn with the Polygon mark. Here are the earlier code blocks in full context, with all other props required to generate the map:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          3.384082,
          6.455027
        ]
      },
      "properties": {
        "name": "Lagos",
        "population": "21 million",
        "anchor": "rb",
        "fill": "#f2e5d7"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          31.233333,
          30.033333
        ]
      },
      "properties": {
        "name": "Cairo",
        "population": "20.4 million",
        "anchor": "rt",
        "fill": "#f2e5d7"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          15.322222,
          -4.325
        ]
      },
      "properties": {
        "name": "Kinshasa",
        "population": "13.3 million",
        "anchor": "b",
        "fill": "#f2e5d7"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          13.234444,
          -8.838333
        ]
      },
      "properties": {
        "name": "Luanda",
        "population": "6.5 million",
        "anchor": "rt",
        "fill": "#335c67"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          36.817222,
          -1.286389
        ]
      },
      "properties": {
        "name": "Nairobi",
        "population": "3.5 million",
        "anchor": "t",
        "fill": "#f2e5d7"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          45.333333,
          2.033333
        ]
      },
      "properties": {
        "name": "Mogadishu",
        "population": "2.1 million",
        "anchor": "rb",
        "fill": "#f2e5d7"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -4.033333,
          5.316667
        ]
      },
      "properties": {
        "name": "Abidjan",
        "population": "4.707 million",
        "anchor": "t",
        "fill": "#335c67"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          29.916667,
          31.2
        ]
      },
      "properties": {
        "name": "Alexandria",
        "population": "4.7 million",
        "anchor": "b",
        "fill": "#335c67"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          38.74,
          9.03

        ]
      },
      "properties": {
        "name": "Addis Ababa",
        "population": "3.4 million",
        "anchor": "r",
        "fill": "#f2e5d7"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          28.045556,
          -26.204444
        ]
      },
      "properties": {
        "name": "Johannesburg",
        "population": "4.4 million",
        "anchor": "r",
        "fill": "#f2e5d7"
      }
    }
  ]
}
<template>

  <vgg-graphic
    v-if="dataLoaded"
    :width="600"
    :height="600"
    :data="polygons"
    :transform="{ reproject: {
      from: '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs',
      to: 'WGS84'
    } }"
  >

    <vgg-section
      :x1="0"
      :x2="500"
      :y1="0"
      :y2="500"
      :scale-geo="{}"
    >

      <vgg-map v-slot="{ row }">

        <vgg-polygon
          :geometry="row.geometry"
          :fill="'#7f2704'"
          :opacity="0.9"
          stroke="#d3d3d3"
          :stroke-width="0.05"
        />

      </vgg-map>

      <vgg-data
        v-if="points"
        :data="points"
      >

        <vgg-map v-slot="{ row }">

          <vgg-symbol
            :geometry="row.geometry"
            :shape="'star'"
            :size="15"
            :fill="'#e09f3e'"
          />

          <vgg-label
            :geometry="row.geometry"
            :text="row.name"
            :anchor-point="row.anchor"
            :fill="row.fill"
            :font-size="12"
            font-family="Verdana"
          />

        </vgg-map>

      </vgg-data>

    </vgg-section>

  </vgg-graphic>

</template>

<script>
import { africa } from './africa.js'
import { points } from './populousCities.js'

export default {
  name: 'GeoShape',

  data () {
    return {
      polygons: {},
      points: null
    }
  },

  computed: {
    dataLoaded () {
      return this.polygons && Object.keys(this.polygons).length !== 0
    }
  },

  mounted () {
    this.loadData()
  },

  methods: {
    loadData () {
      africa().then(data => {
        this.polygons = Object.freeze(data)
      })
      points().then(data =>{
        this.points = Object.freeze(data)
      })
    }
  }
}
</script>