[{"data":1,"prerenderedAt":669},["Reactive",2],{"navigation-list":3,"page-/examples/stations/station-info-navigation-name":460,"page-/examples/stations/station-info":461},{"api-reference":4,"basics":312,"examples":353,"tree":440},{"asideHeader":5,"sectionList":6,"mainHeader":311},"API reference",[7,29,50,95,120,142,155,188,217,249,270],{"label":8,"navigation":-1,"to":9,"icon":10,"itemList":11},"API","/api-reference/api","medium/products/api",[12,17,21,25],{"label":13,"navigation":14,"to":15,"icon":-1,"itemList":16},"Quick setup guide","api-reference","/api-reference/api/quick-setup-guide",[],{"label":18,"navigation":14,"to":19,"icon":-1,"itemList":20},"Pagination","/api-reference/api/pagination",[],{"label":22,"navigation":14,"to":23,"icon":-1,"itemList":24},"API lifecycle","/api-reference/api/api-lifecycle",[],{"label":26,"navigation":14,"to":27,"icon":-1,"itemList":28},"Beta features","/api-reference/api/beta-features",[],{"label":30,"navigation":-1,"to":31,"icon":32,"itemList":33},"Vehicles","/api-reference/vehicle","medium/products/vehicle",[34,38,42,46],{"label":35,"navigation":14,"to":36,"icon":-1,"itemList":37},"Vehicle introduction","/api-reference/vehicle/introduction",[],{"label":39,"navigation":14,"to":40,"icon":-1,"itemList":41},"Query vehicles","/api-reference/vehicle/query-vehicles",[],{"label":43,"navigation":14,"to":44,"icon":-1,"itemList":45},"Query vehicle details","/api-reference/vehicle/query-vehicle-details",[],{"label":47,"navigation":14,"to":48,"icon":-1,"itemList":49},"Query premium vehicle details","/api-reference/vehicle/query-premium-vehicle-details",[],{"label":51,"navigation":-1,"to":52,"icon":53,"itemList":54},"Stations","/api-reference/stations","medium/products/charge-station",[55,59,63,67,71,75,79,83,87,91],{"label":56,"navigation":14,"to":57,"icon":-1,"itemList":58},"Station introduction","/api-reference/stations/introduction",[],{"label":60,"navigation":14,"to":61,"icon":-1,"itemList":62},"Query station details","/api-reference/stations/query-station-details",[],{"label":64,"navigation":14,"to":65,"icon":-1,"itemList":66},"Query stations around a GeoJSON point","/api-reference/stations/query-stations-around",[],{"label":68,"navigation":14,"to":69,"icon":-1,"itemList":70},"Query station reviews","/api-reference/stations/query-stations-reviews",[],{"label":72,"navigation":14,"to":73,"icon":-1,"itemList":74},"Mutate to create a station review","/api-reference/stations/mutate-station-reviews",[],{"label":76,"navigation":14,"to":77,"icon":-1,"itemList":78},"Query station operators","/api-reference/stations/query-station-operators",[],{"label":80,"navigation":14,"to":81,"icon":-1,"itemList":82},"Query station operator details","/api-reference/stations/query-station-operator-details",[],{"label":84,"navigation":14,"to":85,"icon":-1,"itemList":86},"Query station tariffs","/api-reference/stations/query-station-tariffs",[],{"label":88,"navigation":14,"to":89,"icon":-1,"itemList":90},"Query station tariff details","/api-reference/stations/query-station-tariff-details",[],{"label":92,"navigation":14,"to":93,"icon":-1,"itemList":94},"Query station amenities","/api-reference/stations/query-station-amenities",[],{"label":96,"navigation":-1,"to":97,"icon":98,"itemList":99},"Legacy | Routes","/api-reference/routes-legacy","medium/products/route",[100,104,108,112,116],{"label":101,"navigation":14,"to":102,"icon":-1,"itemList":103},"Route legacy introduction","/api-reference/routes-legacy/introduction",[],{"label":105,"navigation":14,"to":106,"icon":-1,"itemList":107},"Mutate to create a new legacy route","/api-reference/routes-legacy/mutate-route",[],{"label":109,"navigation":14,"to":110,"icon":-1,"itemList":111},"Subscribe to route updates","/api-reference/routes-legacy/subscribe-to-route-updates",[],{"label":113,"navigation":14,"to":114,"icon":-1,"itemList":115},"Query route details","/api-reference/routes-legacy/query-route-details",[],{"label":117,"navigation":14,"to":118,"icon":-1,"itemList":119},"Query route path","/api-reference/routes-legacy/query-route-path",[],{"label":121,"navigation":-1,"to":122,"icon":98,"itemList":123},"Routes","/api-reference/routes",[124,128,132,136,139],{"label":125,"navigation":14,"to":126,"icon":-1,"itemList":127},"Route introduction","/api-reference/routes/introduction",[],{"label":129,"navigation":14,"to":130,"icon":-1,"itemList":131},"Migration from Route Legacy","/api-reference/routes/migration",[],{"label":133,"navigation":14,"to":134,"icon":-1,"itemList":135},"Mutate to create a new route","/api-reference/routes/mutate-route",[],{"label":109,"navigation":14,"to":137,"icon":-1,"itemList":138},"/api-reference/routes/subscribe-to-route-updates",[],{"label":113,"navigation":14,"to":140,"icon":-1,"itemList":141},"/api-reference/routes/query-route-details",[],{"label":143,"navigation":-1,"to":144,"icon":145,"itemList":146},"Emissions","/api-reference/route-emissions","medium/content/leaf",[147,151],{"label":148,"navigation":14,"to":149,"icon":-1,"itemList":150},"Route emissions introduction","/api-reference/route-emissions/introduction",[],{"label":152,"navigation":14,"to":153,"icon":-1,"itemList":154},"Query route emissions","/api-reference/route-emissions/query-route-emissions",[],{"label":156,"navigation":-1,"to":157,"icon":158,"itemList":159},"Navigation","/api-reference/navigation","medium/products/navigation",[160,164,168,172,176,180,184],{"label":161,"navigation":14,"to":162,"icon":-1,"itemList":163},"Navigation introduction","/api-reference/navigation/introduction",[],{"label":165,"navigation":14,"to":166,"icon":-1,"itemList":167},"Mutate to start a new navigation session","/api-reference/navigation/mutate-start-navigation",[],{"label":169,"navigation":14,"to":170,"icon":-1,"itemList":171},"Subscribe to navigation updates","/api-reference/navigation/subscribe-to-navigation-updates",[],{"label":173,"navigation":14,"to":174,"icon":-1,"itemList":175},"Query navigation session","/api-reference/navigation/query-a-navigation-session",[],{"label":177,"navigation":14,"to":178,"icon":-1,"itemList":179},"Mutate to update a navigation session","/api-reference/navigation/mutate-update-navigation",[],{"label":181,"navigation":14,"to":182,"icon":-1,"itemList":183},"Mutate to recalculate navigation","/api-reference/navigation/mutate-recalculate-navigation",[],{"label":185,"navigation":14,"to":186,"icon":-1,"itemList":187},"Mutate to finish navigation","/api-reference/navigation/mutate-to-finish-navigation",[],{"label":189,"navigation":-1,"to":190,"icon":191,"itemList":192},"Legacy | Tile service","/api-reference/tile-service-legacy","medium/products/tile-set",[193,197,201,205,209,213],{"label":194,"navigation":14,"to":195,"icon":-1,"itemList":196},"Legacy | Tile service introduction","/api-reference/tile-service-legacy/introduction",[],{"label":198,"navigation":14,"to":199,"icon":-1,"itemList":200},"Legacy | Mapbox Vector Tile","/api-reference/tile-service-legacy/mvt",[],{"label":202,"navigation":14,"to":203,"icon":-1,"itemList":204},"Legacy | JSON Tile","/api-reference/tile-service-legacy/json",[],{"label":206,"navigation":14,"to":207,"icon":-1,"itemList":208},"Legacy | Filters","/api-reference/tile-service-legacy/filters",[],{"label":210,"navigation":14,"to":211,"icon":-1,"itemList":212},"Legacy | Selectors","/api-reference/tile-service-legacy/selectors",[],{"label":214,"navigation":14,"to":215,"icon":-1,"itemList":216},"Legacy | Integration","/api-reference/tile-service-legacy/integration",[],{"label":218,"navigation":-1,"to":219,"icon":191,"itemList":220},"Tile service","/api-reference/tile-service",[221,225,229,233,237,241,245],{"label":222,"navigation":14,"to":223,"icon":-1,"itemList":224},"Tile service introduction","/api-reference/tile-service/introduction",[],{"label":226,"navigation":14,"to":227,"icon":-1,"itemList":228},"Mapbox Vector Tile","/api-reference/tile-service/mvt",[],{"label":230,"navigation":14,"to":231,"icon":-1,"itemList":232},"JSON Tile","/api-reference/tile-service/json",[],{"label":234,"navigation":14,"to":235,"icon":-1,"itemList":236},"Filters","/api-reference/tile-service/filters",[],{"label":238,"navigation":14,"to":239,"icon":-1,"itemList":240},"Selectors","/api-reference/tile-service/selectors",[],{"label":242,"navigation":14,"to":243,"icon":-1,"itemList":244},"Station count","/api-reference/tile-service/count",[],{"label":246,"navigation":14,"to":247,"icon":-1,"itemList":248},"Integration","/api-reference/tile-service/integration",[],{"label":250,"navigation":-1,"to":251,"icon":252,"itemList":253},"Isolines","/api-reference/isolines","medium/products/isoline",[254,258,262,266],{"label":255,"navigation":14,"to":256,"icon":-1,"itemList":257},"Isoline introduction","/api-reference/isolines/introduction",[],{"label":259,"navigation":14,"to":260,"icon":-1,"itemList":261},"Mutation to create an isoline","/api-reference/isolines/mutate-isoline",[],{"label":263,"navigation":14,"to":264,"icon":-1,"itemList":265},"Subscribe to isoline details","/api-reference/isolines/subscribe-to-isoline",[],{"label":267,"navigation":14,"to":268,"icon":-1,"itemList":269},"Query isoline details","/api-reference/isolines/query-isoline",[],{"label":271,"navigation":-1,"to":272,"icon":273,"itemList":274},"Vehicle connectivity","/api-reference/vehicle-connectivity","medium/products/connectivity",[275,279,283,287,291,295,299,303,307],{"label":276,"navigation":14,"to":277,"icon":-1,"itemList":278},"Introduction","/api-reference/vehicle-connectivity/introduction",[],{"label":280,"navigation":14,"to":281,"icon":-1,"itemList":282},"Mutate to create a new connected vehicle","/api-reference/vehicle-connectivity/mutate-create-connected-vehicle",[],{"label":284,"navigation":14,"to":285,"icon":-1,"itemList":286},"Subscribe to a connected vehicle","/api-reference/vehicle-connectivity/subscribe-connected-vehicle",[],{"label":288,"navigation":14,"to":289,"icon":-1,"itemList":290},"Mutate to authorize a connected vehicle","/api-reference/vehicle-connectivity/mutate-authorize-connected-vehicle",[],{"label":292,"navigation":14,"to":293,"icon":-1,"itemList":294},"Query connected vehicle list","/api-reference/vehicle-connectivity/query-connected-vehicle-list",[],{"label":296,"navigation":14,"to":297,"icon":-1,"itemList":298},"Query data from vehicle","/api-reference/vehicle-connectivity/query-connected-vehicle-data",[],{"label":300,"navigation":14,"to":301,"icon":-1,"itemList":302},"Query connected vehicle","/api-reference/vehicle-connectivity/query-connected-vehicle",[],{"label":304,"navigation":14,"to":305,"icon":-1,"itemList":306},"Mutate to update a connected vehicle","/api-reference/vehicle-connectivity/mutate-update-connected-vehicle",[],{"label":308,"navigation":14,"to":309,"icon":-1,"itemList":310},"Mutate to remove a connected vehicle","/api-reference/vehicle-connectivity/mutate-remove-connected-vehicle",[],"Sections",{"asideHeader":313,"sectionList":314,"mainHeader":311},"Basics",[315,341],{"label":316,"navigation":-1,"to":317,"icon":318,"itemList":319},"API Basics","/basics/api-basics","medium/code/code",[320,325,329,333,337],{"label":321,"navigation":322,"to":323,"icon":-1,"itemList":324},"Getting started","basics","/basics/api-basics/getting-started",[],{"label":326,"navigation":322,"to":327,"icon":-1,"itemList":328},"Authorization","/basics/api-basics/authorization",[],{"label":330,"navigation":322,"to":331,"icon":-1,"itemList":332},"Security","/basics/api-basics/security",[],{"label":334,"navigation":322,"to":335,"icon":-1,"itemList":336},"Status & error codes","/basics/api-basics/status-and-error-codes",[],{"label":338,"navigation":322,"to":339,"icon":-1,"itemList":340},"Subscriptions","/basics/api-basics/subscriptions",[],{"label":342,"navigation":-1,"to":343,"icon":318,"itemList":344},"Learn more","/basics/other-basics",[345,349],{"label":346,"navigation":322,"to":347,"icon":-1,"itemList":348},"GraphQL Basics","/basics/other-basics/graphql-basics",[],{"label":350,"navigation":322,"to":351,"icon":-1,"itemList":352},"EV basics","/basics/other-basics/ev-basics",[],{"asideHeader":354,"sectionList":355,"mainHeader":439},"API Section",[356,369,380,420,432],{"label":30,"navigation":-1,"to":357,"icon":358,"itemList":359},"/examples/vehicles","car",[360,365],{"label":361,"navigation":362,"to":363,"icon":-1,"itemList":364},"Vehicle list","examples","/examples/vehicles/vehicle-list",[],{"label":366,"navigation":362,"to":367,"icon":-1,"itemList":368},"Vehicle details","/examples/vehicles/vehicle-details",[],{"label":51,"navigation":-1,"to":370,"icon":371,"itemList":372},"/examples/stations","charge-stations",[373,376],{"label":51,"navigation":362,"to":374,"icon":-1,"itemList":375},"/examples/stations/station-list",[],{"label":377,"navigation":362,"to":378,"icon":-1,"itemList":379},"Station details","/examples/stations/station-info",[],{"label":121,"navigation":-1,"to":381,"icon":382,"itemList":383},"/examples/routes","route",[384,388,392,396,400,404,408,412,416],{"label":385,"navigation":362,"to":386,"icon":-1,"itemList":387},"Route","/examples/routes/route",[],{"label":389,"navigation":362,"to":390,"icon":-1,"itemList":391},"Route (NEW)","/examples/routes/route-new",[],{"label":393,"navigation":362,"to":394,"icon":-1,"itemList":395},"Alternative routes","/examples/routes/alternative-routes",[],{"label":397,"navigation":362,"to":398,"icon":-1,"itemList":399},"Alternative stations","/examples/routes/stations-along-route",[],{"label":401,"navigation":362,"to":402,"icon":-1,"itemList":403},"Operator preference","/examples/routes/preferred-operator",[],{"label":405,"navigation":362,"to":406,"icon":-1,"itemList":407},"Elevation plot","/examples/routes/elevation-plot",[],{"label":409,"navigation":362,"to":410,"icon":-1,"itemList":411},"Battery capacity","/examples/routes/battery-capacity",[],{"label":413,"navigation":362,"to":414,"icon":-1,"itemList":415},"State of charge","/examples/routes/state-of-charge",[],{"label":417,"navigation":362,"to":418,"icon":-1,"itemList":419},"Toll roads and Ferries","/examples/routes/tolls-and-ferries",[],{"label":218,"navigation":-1,"to":421,"icon":422,"itemList":423},"/examples/tile-service","layers",[424,428],{"label":425,"navigation":362,"to":426,"icon":-1,"itemList":427},"Mapbox Vector Tiles","/examples/tile-service/tile-server",[],{"label":429,"navigation":362,"to":430,"icon":-1,"itemList":431},"GeoJSON tiles","/examples/tile-service/tile-json",[],{"label":250,"navigation":-1,"to":433,"icon":434,"itemList":435},"/examples/isolines","isoline",[436],{"label":250,"navigation":362,"to":437,"icon":-1,"itemList":438},"/examples/isolines/isoline",[],"Examples",[441,445,447,452,457],{"label":313,"navigation":442,"to":443,"icon":444,"itemList":314},"main","/basics","medium/content/bookmark",{"label":5,"navigation":442,"to":446,"icon":318,"itemList":6},"/api-reference",{"label":448,"navigation":442,"to":449,"icon":450,"itemList":451},"Release notes","/release-notes","medium/content/megaphone",[],{"label":453,"navigation":442,"to":454,"icon":455,"itemList":456},"Deprecations","/deprecations","medium/content/shredded",[],{"label":439,"navigation":442,"to":458,"icon":459,"itemList":355},"/examples","code",{"navigation":362},{"_path":378,"_dir":462,"_draft":463,"_partial":463,"_locale":464,"title":377,"description":465,"img":466,"background":467,"navigation":362,"body":468,"_type":664,"_id":665,"_source":666,"_file":667,"_extension":668},"stations",false,"","Example of how to query and parse station data","/examples/stations/station-info.png","note",{"type":469,"children":470,"toc":661},"root",[471,490],{"type":472,"tag":473,"props":474,"children":477},"element","ct-section",{"className":475},[476],"!pt-6",[478],{"type":472,"tag":479,"props":480,"children":489},"ct-iframe-wrapper",{"className":481,"src":488},[482,483,484,485,486,487],"w-full","h-[640px]","relative","overflow-hidden","rounded-lg","shadow-sm","https://examples.chargetrip.com/station-info/",[],{"type":472,"tag":491,"props":492,"children":493},"ct-grid-section",{},[494,648],{"type":472,"tag":495,"props":496,"children":499},"ct-content",{"className":497},[498],"col-span-6",[500,507,529,542,549,592,598,637,643],{"type":472,"tag":501,"props":502,"children":504},"h1",{"id":503},"query-station-details",[505],{"type":506,"value":60},"text",{"type":472,"tag":508,"props":509,"children":510},"p",{},[511,513,519,521,527],{"type":506,"value":512},"To query the details of astation, a station ",{"type":472,"tag":459,"props":514,"children":516},{"className":515},[],[517],{"type":506,"value":518},"id",{"type":506,"value":520}," is required. This can be passed into the ",{"type":472,"tag":459,"props":522,"children":524},{"className":523},[],[525],{"type":506,"value":526},"station",{"type":506,"value":528}," query. From there, amenities, predicted availability and other details can be used.",{"type":472,"tag":530,"props":531,"children":536},"ct-button",{":is-rounded":532,"href":533,"icon-right":534,"type":535},"true","https://github.com/chargetrip/examples/tree/main/examples/2.stations/2.station-info","IconName.MD_NAVIGATION_ARROW_UP_RIGHT","primary",[537],{"type":472,"tag":508,"props":538,"children":539},{},[540],{"type":506,"value":541},"View on Github",{"type":472,"tag":543,"props":544,"children":546},"h2",{"id":545},"requirements",[547],{"type":506,"value":548},"Requirements",{"type":472,"tag":550,"props":551,"children":552},"ul",{},[553,568,580],{"type":472,"tag":554,"props":555,"children":556},"li",{},[557,566],{"type":472,"tag":558,"props":559,"children":563},"a",{"href":560,"rel":561},"https://account.chargetrip.com",[562],"nofollow",[564],{"type":506,"value":565},"Chargetrip API key",{"type":506,"value":567}," - to fetch stations all over Europe instead of a subset",{"type":472,"tag":554,"props":569,"children":570},{},[571,578],{"type":472,"tag":558,"props":572,"children":575},{"href":573,"rel":574},"https://www.mapbox.com",[562],[576],{"type":506,"value":577},"Mapbox API key",{"type":506,"value":579}," - to display the map",{"type":472,"tag":554,"props":581,"children":582},{},[583,590],{"type":472,"tag":558,"props":584,"children":587},{"href":585,"rel":586},"https://formidable.com/open-source/urql/",[562],[588],{"type":506,"value":589},"URQL",{"type":506,"value":591}," - a lightweight graphQL client",{"type":472,"tag":543,"props":593,"children":595},{"id":594},"steps-to-take",[596],{"type":506,"value":597},"Steps to take",{"type":472,"tag":599,"props":600,"children":601},"ol",{},[602,615,620,632],{"type":472,"tag":554,"props":603,"children":604},{},[605,607,613],{"type":506,"value":606},"Just like the previous example, the ",{"type":472,"tag":459,"props":608,"children":610},{"className":609},[],[611],{"type":506,"value":612},"stationAround",{"type":506,"value":614}," query is used to display stations around a GeoJSON location.",{"type":472,"tag":554,"props":616,"children":617},{},[618],{"type":506,"value":619},"With stations available on the map, click interactions can be added.",{"type":472,"tag":554,"props":621,"children":622},{},[623,625,630],{"type":506,"value":624},"A click handler on the station icon will initiate the ",{"type":472,"tag":459,"props":626,"children":628},{"className":627},[],[629],{"type":506,"value":526},{"type":506,"value":631}," query. This example will request the chargers, amenities, predicted availability and operator details. More fields are available within the API reference.",{"type":472,"tag":554,"props":633,"children":634},{},[635],{"type":506,"value":636},"After receiving the data, it will be rendered on the screen.",{"type":472,"tag":543,"props":638,"children":640},{"id":639},"next-steps",[641],{"type":506,"value":642},"Next steps",{"type":472,"tag":508,"props":644,"children":645},{},[646],{"type":506,"value":647},"After stations are available on a map, fetching additional station data on interaction is a logical next step. So let's move onto the next example to fetch data such as chargers, predicted availability, amenities or operator details.",{"type":472,"tag":649,"props":650,"children":652},"div",{"className":651},[498],[653],{"type":472,"tag":654,"props":655,"children":660},"ct-code-tabs",{":codeList":656,":is-inversed":532,"className":657},"[{\"label\":\"client.js\",\"code\":\"import { createClient, defaultExchanges } from '@urql/core';\\nimport { getStationDataQuery, getStationsAroundQuery } from './queries';\\n\\n/**\\n * For the purpose of this example we use urgl - lightweights GraphQL client.\\n * To establish a connection with Chargetrip GraphQL API you need to have an API key.\\n * The key in this example is a public one and gives access only to a part of our extensive database.\\n * You need a registered `x-client-id` to access the full database.\\n * Read more about an authorisation in our documentation (https://docs.chargetrip.com/#authorisation).\\n */\\nconst headers = {\\n  //Replace this x-client-id and app-id with your own to get access to more cars\\n  'x-client-id': '5ed1175bad06853b3aa1e492',\\n  'x-app-id': '623998b2c35130073829b2d2',\\n};\\n\\nconst client = createClient({\\n  url: 'https://api.chargetrip.io/graphql',\\n  fetchOptions: {\\n    method: 'POST',\\n    headers,\\n  },\\n  exchanges: [...defaultExchanges],\\n});\\n\\n/**\\n * Fetch 20 station around the city center of Hamburg, Germany.\\n * We set the radius around the geolocation in which we fetch stations to 3km\\n */\\nexport const getStations = () => {\\n  return client\\n    .query(getStationsAroundQuery, {\\n      query: {\\n        location: { type: 'Point', coordinates: [9.9801115, 53.5475679] },\\n        distance: 3000,\\n      },\\n    })\\n    .toPromise()\\n    .then(response => {\\n      return response.data?.stationAround;\\n    })\\n    .catch(error => console.log(error));\\n};\\n\\n/**\\n * Fetch the detail data of a specific station\\n * @param { string } id - the id of the station\\n */\\nexport const getStationData = id => {\\n  return client\\n    .query(getStationDataQuery, {\\n      stationId: id,\\n    })\\n    .toPromise()\\n    .then(response => {\\n      return response.data;\\n    })\\n    .catch(error => console.log(error));\\n};\\n\"},{\"label\":\"index.js\",\"code\":\"import { getStations, getStationData } from './client';\\nimport { showStations } from './map.js';\\nimport { attachEventListeners, renderGraph, renderStationData } from './interface';\\n\\n/**\\n * This project shows you how to fetch station details\\n * The project structure contains;\\n *\\n *    - client.js - All networking requests\\n *    - interface.js - All interface rendering\\n *    - map.js - All map rendering (including routes and waypoints)\\n *    - queries.js - The GraphQL queries used in the networking requests\\n *    - utils.js - Some helpers to format station data for rendering\\n */\\n\\ngetStations()\\n  .then(stations => {\\n    showStations(stations);\\n    getStationData(stations[0].id).then(data => {\\n      renderStationData(data);\\n      renderGraph(data.station.predicted_occupancy, 0);\\n      attachEventListeners(data.station.predicted_occupancy);\\n    });\\n  })\\n  .catch(error => console.log(error));\\n\"},{\"label\":\"interface.js\",\"code\":\"import {\\n  ConnectorStatus,\\n  getConnectorStatusLabel,\\n  getConnectorIcon,\\n  getConnectorName,\\n  getConnectorStatus,\\n  getParkingType,\\n} from './utils';\\nimport Chart from 'chart.js/auto';\\n\\n// Keep chart global so we know whether we need to update or construct the chart.\\n// Only one instance is allowed to run.\\nlet chart = null;\\n\\n/**\\n * Display raw station data.\\n *\\n * Additionally:\\n *\\n *  - provide address of the station as a Google link (see https://developers.google.com/maps/documentation/urls/get-started#search-action)\\n *  - provide direction URL via Google (see https://developers.google.com/maps/documentation/urls/get-started#forming-the-directions-url)\\n *  - show amenities\\n *  - show connectors availability\\n *\\n * @param { Object } data - all details of the selected station\\n **/\\nexport const renderStationData = data => {\\n  const { station } = data;\\n\\n  const what3wordsURL = `https://what3words.com/${station.physical_address?.what3Words}`;\\n  const readableAddress = data.station?.physical_address?.formattedAddress?.join(', ') || '';\\n  const googleAddress = `https://www.google.com/maps/search/?api=1&query=${station.coordinates?.latitude},${station.coordinates?.longitude}`;\\n  const directionURL = `https://www.google.com/maps/dir/?api=1&travelmode=driving&dir_action=navigate&destination=${station.coordinates?.latitude},${station.coordinates?.longitude}`;\\n\\n  // Format the connectors so they can be rendered\\n  const connectors = station.chargers?.map(charger => {\\n    const status = getConnectorStatus(charger);\\n    return {\\n      name: getConnectorName(charger.standard),\\n      icon: getConnectorIcon(charger.standard),\\n      power: charger.power,\\n      status,\\n      standard: charger.standard,\\n      availabilityInfo: `${status === ConnectorStatus.UNKNOWN ? '-' : charger.status.free}/${charger.total}`,\\n      availabilityLabel: getConnectorStatusLabel(status),\\n    };\\n  });\\n\\n  // Format the station details so it's easy to render\\n  const details = [\\n    {\\n      title: 'Address',\\n      subtitle: readableAddress,\\n      url: googleAddress,\\n    },\\n    {\\n      title: 'Operator',\\n      subtitle: station.operator?.name,\\n    },\\n    {\\n      title: 'Twenty 4 seven',\\n      subtitle: station.opening_times?.twentyfourseven ? '24/7' : 'Unknown',\\n    },\\n    {\\n      title: 'Parking',\\n      subtitle: getParkingType(station.parking_type),\\n    },\\n    {\\n      title: 'Station Id',\\n      subtitle: station.id,\\n    },\\n    {\\n      title: 'What 3 words',\\n      subtitle: station.physical_address?.what3Words,\\n      url: what3wordsURL,\\n    },\\n  ];\\n\\n  // Now that we have a navigationURL, enable the navigate button\\n  const navigateButton = document.getElementById('navigate');\\n  navigateButton.disabled = false;\\n  navigateButton.addEventListener('click', () => {\\n    window.open(directionURL);\\n  });\\n\\n  // Render the different parts of the station details\\n  renderHeader(station);\\n  renderConnectors(connectors);\\n  renderAmenities(station.amenities);\\n  renderDetails(details);\\n};\\n\\n/**\\n * Render the station name and operator inside the sticky header\\n * @param { Object } station - Every bit of station data\\n */\\nconst renderHeader = station => {\\n  document.getElementById('station-name').innerHTML = station.name;\\n  document.getElementById('station-operator').innerHTML = station.operator?.name;\\n};\\n\\n/**\\n * Render the connectors and their details on cards based on their status\\n * @param { Array } connectors - An array of connectors alongside their details\\n */\\nconst renderConnectors = connectors => {\\n  let connectorList = document.getElementById('connector-list');\\n  connectorList.textContent = '';\\n\\n  connectors.forEach(connector => {\\n    connectorList.insertAdjacentHTML(\\n      'afterbegin',\\n      `\\n        \u003Cli class=${connector.status}>\\n          \u003Cdiv class=\\\"charger\\\">\\n            \u003Cdiv class=\\\"charger-plug\\\">\\n              \u003Cobject type=\\\"image/svg+xml\\\" data=\\\"images/plugs/${connector.icon}.svg\\\">\\n              \u003C/object>\\n            \u003C/div>\\n            \u003Cdiv class=\\\"charger-details\\\">\\n              \u003Cdiv class=\\\"row\\\">\\n                \u003Cp>${connector.name}\u003C/p>\\n                \u003Cp>${connector.availabilityInfo}\u003C/p>\\n              \u003C/div>\\n              \u003Cdiv class=\\\"row\\\">\\n                \u003Cp>${connector.power} kW\u003C/p>\\n                \u003Cp>${connector.availabilityLabel}\u003C/p>\\n              \u003C/div>\\n            \u003C/div>\\n          \u003C/div>\\n        \u003C/li>\\n        `,\\n    );\\n  });\\n};\\n\\n/**\\n * Render a horizontal list of amenity icons\\n * @param { Object } amenities - an object that contains all amenities and their details\\n */\\nconst renderAmenities = amenities => {\\n  let amenityList = document.getElementById('amenity-list');\\n  amenityList.textContent = '';\\n\\n  Object.keys(amenities || {})?.forEach(amenity => {\\n    amenityList.insertAdjacentHTML(\\n      'beforeend',\\n      `\\n        \u003Cli>\\n        \u003Cdiv class=\\\"amenity\\\">\\n          \u003Cobject type=\\\"image/svg+xml\\\" data=\\\"images/amenities/${amenity}.svg\\\">\\n          \u003C/object>\\n        \u003C/div>\\n        \u003C/li>\\n        `,\\n    );\\n  });\\n};\\n\\n/**\\n * Render a vertical list of station details\\n * @param { Object } details - a preformatted object that contains all list data\\n */\\nconst renderDetails = details => {\\n  let stationDetails = document.getElementById('station-details');\\n  stationDetails.textContent = '';\\n\\n  details.forEach(detail => {\\n    stationDetails.insertAdjacentHTML(\\n      'beforeend',\\n      `\\n        \u003Cli>\\n          ${detail.url !== undefined ? `\u003Ca target=\\\"_blank\\\" href=${detail.url}>` : ``}\\n            \u003Cdiv class=\\\"row\\\">\\n              \u003Cp>${detail.title}\u003C/p>\\n            \u003C/div>\\n            \u003Cdiv class=\\\"row\\\">\\n              \u003Cp>${detail.subtitle}\u003C/p>\\n            \u003C/div>\\n          ${detail.url !== undefined ? `\u003C/a>` : ``}\\n        \u003C/li>\\n        `,\\n    );\\n  });\\n};\\n\\n/**\\n * Helper function that handles all clicks and data updates on the day of the week tabs\\n * @param { object } data - The occupancy data\\n */\\nexport const attachEventListeners = data => {\\n  const dayOptions = document.querySelectorAll('.tab');\\n  const tabHighlighter = document.getElementById('tab-highlighter');\\n\\n  dayOptions.forEach((option, index) => {\\n    option.addEventListener('click', event => {\\n      event.preventDefault();\\n      dayOptions.forEach(option => option.classList.remove('active'));\\n      dayOptions[index].classList.add('active');\\n      tabHighlighter.style.transform = `translateX(calc(${index * 100}% + ${index * 4}px)`;\\n      renderGraph(data, index);\\n    });\\n  });\\n};\\n\\n/**\\n * Function that renders the occupancy data\\n * @param { object } data - occupancy data that is coming from our API\\n * @param { number } tabbarIndex - current day of the week that is selected\\n */\\nexport const renderGraph = (data, tabbarIndex) => {\\n  const occupancyEl = document.getElementById('occupancy');\\n\\n  // Check whether we have occupancy data.\\n  // If there is no data available we hide the occupancy content\\n  if (!data.length) {\\n    occupancyEl.style.display = 'none';\\n    return;\\n  }\\n\\n  occupancyEl.style.display = 'block';\\n  const { labels, occupancyData } = formatGraphData(data, tabbarIndex);\\n\\n  // Check whether we already have a Chart JS object\\n  // If not we draw the Graph, otherwise we update the current data.\\n  if (!chart) {\\n    drawGraph(labels, occupancyData);\\n  } else {\\n    chart.data.labels = labels;\\n    chart.data.datasets.forEach(dataset => {\\n      dataset.data = occupancyData;\\n    });\\n    chart.update();\\n  }\\n};\\n\\n/**\\n * Small helper function to format data to a format that is usable for the graph\\n * @param { object } data - occupancy data that is coming from our API\\n * @param { number } tabbarIndex - current day of the week that is selected\\n * @returns { object } - object that contains labels and formatted data to use inside the graph\\n */\\nconst formatGraphData = (data, tabbarIndex) => {\\n  // Get data for the selected day\\n  // Map data to new format that supports labels\\n  const formattedData = data\\n    .filter(({ weekday }) => weekday === tabbarIndex + 1)\\n    .map((item, i) => {\\n      const hour = parseInt(item?.period_begin || '');\\n\\n      return {\\n        ...item,\\n        hour,\\n        label: i === 0 || i === 23 ? `${hour.toString()}:00` : '',\\n      };\\n    });\\n\\n  // Flatten data so we got one array for labels and one array for data\\n  const labels = formattedData.map(data => data.label);\\n  const occupancyData = formattedData.map(data => data.occupancy);\\n\\n  return { labels, occupancyData };\\n};\\n\\n/**\\n * Constructs the graph with the correct configuration and initial dataset.\\n * @param { array } labels - An array with labels that our graph needs to render\\n * @param { array } occupancyData - An array with occupancy integers ranging from 1 - 10\\n */\\nconst drawGraph = (labels, occupancyData) => {\\n  const ctx = document.getElementById('occupancy-graph').getContext('2d');\\n\\n  chart = new Chart(ctx, {\\n    type: 'bar',\\n    data: {\\n      datasets: [\\n        {\\n          data: occupancyData,\\n          fill: true,\\n          hoverBackgroundColor: 'rgba(0, 120, 255, 1)',\\n          backgroundColor: 'rgba(0, 120, 255, 0.2)',\\n          borderRadius: 2,\\n        },\\n      ],\\n      labels: labels,\\n    },\\n    options: {\\n      animations: {\\n        tension: {\\n          duration: 300,\\n          easing: 'linear',\\n          from: 1,\\n          to: 0,\\n        },\\n      },\\n      elements: {\\n        point: {\\n          radius: 0,\\n        },\\n      },\\n      scales: {\\n        y: {\\n          suggestedMax: 10,\\n          ticks: {\\n            display: false,\\n          },\\n          grid: {\\n            tickLength: 0,\\n            borderColor: '#FFFFFF',\\n            color: '#E5F0F5',\\n            borderDash: [4, 6],\\n          },\\n        },\\n        x: {\\n          grid: {\\n            display: false,\\n            borderColor: '#E5F0F5',\\n          },\\n          ticks: {\\n            autoSkip: false,\\n            maxRotation: 0,\\n            color: '#566A75',\\n            font: {\\n              family: 'Inter',\\n              size: 12,\\n              weight: 600,\\n            },\\n          },\\n        },\\n      },\\n      plugins: {\\n        legend: {\\n          display: false,\\n        },\\n        tooltip: {\\n          enabled: false,\\n          position: 'nearest',\\n          external: tooltipHandler,\\n        },\\n      },\\n    },\\n  });\\n};\\n\\n/**\\n * Small helper function that draws a new element for our custom tooltip\\n * @param { Chart } chart - The chart.js main chart property\\n * @returns A HTML object that is added to the chart\\n */\\nconst renderToolTip = chart => {\\n  let tooltipEl = chart.canvas.parentNode.querySelector('div');\\n\\n  if (!tooltipEl) {\\n    tooltipEl = document.createElement('div');\\n    tooltipEl.classList.add('custom-tooltip');\\n\\n    chart.canvas.parentNode.appendChild(tooltipEl);\\n  }\\n\\n  return tooltipEl;\\n};\\n\\n/**\\n * Our external tooltip helper for positioning and formatting the data to show alongside the graph\\n * @param { context } context - The canvas context\\n */\\nconst tooltipHandler = context => {\\n  const { chart, tooltip } = context;\\n  const tooltipEl = renderToolTip(chart);\\n\\n  if (tooltip.opacity === 0) {\\n    tooltipEl.style.opacity = 0;\\n    return;\\n  }\\n\\n  if (tooltip.body) {\\n    const lines = tooltip.body.map(b => {\\n      return b.lines.map(line => {\\n        switch (line) {\\n          case '1':\\n            return 'Not busy';\\n          case '2':\\n          case '3':\\n            return 'Not too busy';\\n          case '4':\\n          case '5':\\n            return 'A little busy';\\n          case '6':\\n          case '7':\\n            return 'Busy';\\n          case '8':\\n          case '9':\\n            return 'Very busy';\\n          case '10':\\n            return 'Extremely busy';\\n        }\\n      });\\n    });\\n\\n    tooltipEl.innerHTML = `${lines}`;\\n  }\\n\\n  const { offsetLeft: positionX } = chart.canvas;\\n  const tooltipElWidth = tooltipEl.offsetWidth / 2;\\n\\n  tooltipEl.style.opacity = 1;\\n  tooltipEl.style.left = `calc(${positionX + tooltip.caretX}px - ${tooltipElWidth}px)`;\\n};\\n\"},{\"label\":\"map.js\",\"code\":\"import mapboxgl from 'mapbox-gl';\\nimport { getStationData } from './client';\\nimport { renderGraph, renderStationData } from './interface';\\n\\nmapboxgl.accessToken = 'pk.eyJ1IjoiY2hhcmdldHJpcCIsImEiOiJjazhpaG8ydTIwNWNpM21ud29xeXc2amhlIn0.rGKgR3JfG9Z5dCWjUI_oGA';\\n\\nconst map = new mapboxgl.Map({\\n  cooperativeGestures: true,\\n  container: 'map',\\n  style: 'mapbox://styles/chargetrip/ckgcbf3kz0h8819qki8uwhe0k',\\n  zoom: 14,\\n  center: [9.9801115, 53.5475679],\\n});\\n\\n/**\\n * Attach a click handler to the map features so we can fetch details of the clicked station.\\n */\\nmap.on('click', 'stations', function(e) {\\n  const stationId = e.features[0]?.properties?.stationId;\\n  if (stationId) {\\n    getStationData(stationId).then(data => {\\n      renderStationData(data);\\n      renderGraph(data.station.predicted_occupancy, 0);\\n    });\\n  }\\n\\n  const navigateButton = document.getElementById('navigate');\\n  navigateButton.disabled = true;\\n\\n  map.flyTo({\\n    center: e.features[0].geometry.coordinates,\\n    offset: [80, 0],\\n  });\\n});\\n\\n/**\\n * Icon for the charging station differs base on the speed (slow, fast, turbo),\\n * and status(available, busy, unkown or broken).\\n *\\n * If a charging station has multiple speeds the fastest speed will be shown.\\n * @param { object } station - Station data\\n */\\nconst selectPinlet = station => `${station.status}-${station.speed}`;\\n\\n/**\\n * Draw the stations on the map.\\n *\\n * @param { Array } stations - Array of stations\\n */\\nexport const showStations = stations => {\\n  if (!stations) return;\\n\\n  if (map.getLayer('path')) map.removeLayer('path');\\n  if (map.getSource('path')) map.removeSource('path');\\n\\n  const points = stations.map(station => ({\\n    type: 'Feature',\\n    properties: {\\n      icon: selectPinlet(station),\\n      stationId: station.id,\\n    },\\n    geometry: station.location,\\n  }));\\n\\n  map.addLayer({\\n    id: 'stations',\\n    type: 'symbol',\\n    layout: {\\n      'icon-image': '{icon}',\\n      'icon-allow-overlap': true,\\n      'icon-size': 0.9,\\n      'icon-offset': [0, -18],\\n    },\\n    source: {\\n      type: 'geojson',\\n      data: {\\n        type: 'FeatureCollection',\\n        features: points,\\n      },\\n    },\\n  });\\n};\\n\"},{\"label\":\"queries.js\",\"code\":\"import qql from 'graphql-tag';\\n\\n/**\\n * For this query we are requesting data about a specific station\\n */\\nexport const getStationDataQuery = qql`\\nquery station($stationId: ID!){\\n  station(id: $stationId) {\\n    id\\n    name\\n    coordinates {\\n      latitude\\n      longitude\\n    }\\n    parking_type\\n    operator {\\n      name\\n    }\\n    predicted_occupancy {\\n      weekday\\n      occupancy\\n      period_begin\\n      period_end\\n    }\\n    opening_times {\\n      twentyfourseven\\n    }\\n    chargers {\\n      standard\\n      power\\n      price\\n      speed\\n      status {\\n        free\\n        busy\\n        unknown\\n        error\\n      }\\n      total\\n    }\\n    physical_address {\\n      continent\\n      country\\n      county\\n      city\\n      street\\n      number\\n      postalCode\\n      what3Words\\n      formattedAddress\\n    }\\n    amenities\\n    status\\n  }\\n}\\n`;\\n\\n/**\\n * For this query we are requesting the 20 closest stations.\\n * The default for this query is 10.\\n */\\nexport const getStationsAroundQuery = qql`\\nquery stationAround($query: StationAroundQuery!){\\n  stationAround(\\n      query: $query\\n      size: 20\\n      page: 0\\n    ) {\\n      id\\n      location {\\n        type\\n        coordinates\\n      }\\n      status\\n      speed\\n    }\\n  }\\n`;\\n\"},{\"label\":\"utils.js\",\"code\":\"export const ConnectorName = {\\n  CHADEMO: 'CHAdeMO',\\n  DOMESTIC_A: 'Domestic A (Nema)',\\n  DOMESTIC_B: 'Domestic B (Nema)',\\n  DOMESTIC_C: 'Domestic C (CEE)',\\n  DOMESTIC_D: 'Domestic D (IS)',\\n  DOMESTIC_E: 'Domestic E (CEE)',\\n  DOMESTIC_F: 'Domestic F (Schuko)',\\n  DOMESTIC_G: 'Domestic G (UK)',\\n  DOMESTIC_H: 'Domestic H (SI)',\\n  DOMESTIC_I: 'Domestic I (AS/MZS)',\\n  DOMESTIC_J: 'Domestic J (SEV)',\\n  DOMESTIC_K: 'Domestic K (DS)',\\n  DOMESTIC_L: 'Domestic L (CEI)',\\n  IEC_60309_2_single_16: 'CENELEC 16 (Single)',\\n  IEC_60309_2_three_16: 'CENELEC 16 (Three)',\\n  IEC_60309_2_three_32: 'CENELEC 32',\\n  IEC_60309_2_three_64: 'CENELEC 64',\\n  IEC_62196_T1: 'Type 1 (J1172)',\\n  IEC_62196_T1_COMBO: 'CCS 1',\\n  IEC_62196_T2: 'Type 2',\\n  IEC_62196_T2_COMBO: 'CCS 2',\\n  IEC_62196_T3A: 'Type 3A',\\n  IEC_62196_T3C: 'Type 3C',\\n  PANTOGRAPH_BOTTOM_UP: 'Panto Up',\\n  PANTOGRAPH_TOP_DOWN: 'Panto Down',\\n  TESLA_R: 'Tesla R',\\n  TESLA_S: 'Tesla',\\n};\\n\\nexport const ConnectorStatus = {\\n  FREE: 'free',\\n  BUSY: 'busy',\\n  UNKNOWN: 'unknown',\\n  ERROR: 'error',\\n};\\n\\nexport const ParkingType = {\\n  ALONG_MOTORWAY: 'Along motorway',\\n  PARKING_GARAGE: 'Parking garage',\\n  PARKING_LOT: 'Parking lot',\\n  ON_DRIVEWAY: 'On driveway',\\n  ON_STREET: 'On street',\\n  UNDERGROUND_GARAGE: 'Underground garage',\\n};\\n\\nexport const getParkingType = type => ParkingType[type] || 'Unknown';\\nexport const getConnectorName = name => ConnectorName[name] || 'Unknown';\\n\\n/* We don't provide icon for these plug types. The default plug icon is shown instead.*/\\nconst noPlugIcon = [\\n  ConnectorName.IEC_60309_2_single_16,\\n  ConnectorName.IEC_60309_2_three_16,\\n  ConnectorName.IEC_60309_2_three_32,\\n  ConnectorName.IEC_60309_2_three_64,\\n  ConnectorName.PANTOGRAPH_BOTTOM_UP,\\n  ConnectorName.PANTOGRAPH_TOP_DOWN,\\n];\\nexport const getConnectorIcon = standard =>\\n  `${ConnectorName[standard] && noPlugIcon.indexOf(standard) === -1 ? standard.toUpperCase() : 'DEFAULT'}`;\\n\\n/**\\n * We are interested only in the availability of the station, so we first check if there are available connectors.\\n *\\n * @param { Object } charger - a small subset of charger details\\n * @returns { string } - Status of a connector\\n */\\nexport const getConnectorStatus = charger => {\\n  if (charger.status.free) {\\n    return ConnectorStatus.FREE;\\n  } else if (charger.status.busy) {\\n    return ConnectorStatus.BUSY;\\n  } else if (charger.status.unknown) {\\n    return ConnectorStatus.UNKNOWN;\\n  } else {\\n    return ConnectorStatus.ERROR;\\n  }\\n};\\n\\n/**\\n * Format the enum status to a human readable string\\n * @param { Enum } status - The current status of the connector\\n * @returns { String } - Status of the connector\\n */\\nexport const getConnectorStatusLabel = status => {\\n  switch (status) {\\n    case ConnectorStatus.FREE:\\n      return 'Available';\\n    case ConnectorStatus.BUSY:\\n      return 'All in use';\\n    case ConnectorStatus.UNKNOWN:\\n      return 'Unknown';\\n    case ConnectorStatus.ERROR:\\n      return 'Broken';\\n  }\\n};\\n\"}]",[658,659],"stick","top-6",[],{"title":464,"searchDepth":662,"depth":662,"links":663},2,[],"markdown","content:5.examples:2.stations:2.station-info.md","content","5.examples/2.stations/2.station-info.md","md",1775054251916]