[{"data":1,"prerenderedAt":704},["Reactive",2],{"navigation-list":3,"page-/examples/routes/alternative-routes-navigation-name":460,"page-/examples/routes/alternative-routes":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":394,"_dir":462,"_draft":463,"_partial":463,"_locale":464,"title":393,"description":465,"img":466,"background":467,"navigation":362,"body":468,"_type":699,"_id":700,"_source":701,"_file":702,"_extension":703},"routes",false,"","Display alternative routes on a map","/examples/routes/alternative-routes.png","accent",{"type":469,"children":470,"toc":696},"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/alternative-routes/",[],{"type":472,"tag":491,"props":492,"children":493},"ct-grid-section",{},[494,683],{"type":472,"tag":495,"props":496,"children":499},"ct-content",{"className":497},[498],"col-span-6",[500,508,514,527,534,577,583,672,678],{"type":472,"tag":501,"props":502,"children":504},"h1",{"id":503},"mutate-to-display-alternative-routes",[505],{"type":506,"value":507},"text","Mutate to display alternative routes",{"type":472,"tag":509,"props":510,"children":511},"p",{},[512],{"type":506,"value":513},"One route is good, but three routes is better. That's why alternatives can be displayed alongside the preferred route. These alternatives are usually the next fastest route and are easy to implement.",{"type":472,"tag":515,"props":516,"children":521},"ct-button",{":is-rounded":517,"href":518,"icon-right":519,"type":520},"true","https://github.com/chargetrip/examples/tree/main/examples/3.routes/3.alternative-routes","IconName.MD_NAVIGATION_ARROW_UP_RIGHT","primary",[522],{"type":472,"tag":509,"props":523,"children":524},{},[525],{"type":506,"value":526},"View on Github",{"type":472,"tag":528,"props":529,"children":531},"h2",{"id":530},"requirements",[532],{"type":506,"value":533},"Requirements",{"type":472,"tag":535,"props":536,"children":537},"ul",{},[538,553,565],{"type":472,"tag":539,"props":540,"children":541},"li",{},[542,551],{"type":472,"tag":543,"props":544,"children":548},"a",{"href":545,"rel":546},"https://account.chargetrip.com",[547],"nofollow",[549],{"type":506,"value":550},"Chargetrip API key",{"type":506,"value":552}," - to plot routes outside this region",{"type":472,"tag":539,"props":554,"children":555},{},[556,563],{"type":472,"tag":543,"props":557,"children":560},{"href":558,"rel":559},"https://www.mapbox.com",[547],[561],{"type":506,"value":562},"Mapbox API key",{"type":506,"value":564}," - to display the map",{"type":472,"tag":539,"props":566,"children":567},{},[568,575],{"type":472,"tag":543,"props":569,"children":572},{"href":570,"rel":571},"https://formidable.com/open-source/urql/",[547],[573],{"type":506,"value":574},"URQL",{"type":506,"value":576}," - a lightweight graphQL client",{"type":472,"tag":528,"props":578,"children":580},{"id":579},"steps-to-take",[581],{"type":506,"value":582},"Steps to take",{"type":472,"tag":584,"props":585,"children":586},"ol",{},[587,608,628],{"type":472,"tag":539,"props":588,"children":589},{},[590,592,598,600,606],{"type":506,"value":591},"Plotting alternative routes starts by executing the ",{"type":472,"tag":459,"props":593,"children":595},{"className":594},[],[596],{"type":506,"value":597},"newRoute",{"type":506,"value":599}," mutation. This mutation requires information about the car, origin and destination. After the mutation is finished executing a route ",{"type":472,"tag":459,"props":601,"children":603},{"className":602},[],[604],{"type":506,"value":605},"id",{"type":506,"value":607}," will be returned.",{"type":472,"tag":539,"props":609,"children":610},{},[611,613,618,620,626],{"type":506,"value":612},"This ",{"type":472,"tag":459,"props":614,"children":616},{"className":615},[],[617],{"type":506,"value":605},{"type":506,"value":619}," can be used to request route updates through the ",{"type":472,"tag":459,"props":621,"children":623},{"className":622},[],[624],{"type":506,"value":625},"routeUpdatedById",{"type":506,"value":627}," subscription. This subscription receives dynamic updates.",{"type":472,"tag":539,"props":629,"children":630},{},[631,633,639,641,646,648,654,656,662,664,670],{"type":506,"value":632},"After the subscription returns ",{"type":472,"tag":459,"props":634,"children":636},{"className":635},[],[637],{"type":506,"value":638},"done",{"type":506,"value":640}," as status, the ",{"type":472,"tag":459,"props":642,"children":644},{"className":643},[],[645],{"type":506,"value":382},{"type":506,"value":647}," and ",{"type":472,"tag":459,"props":649,"children":651},{"className":650},[],[652],{"type":506,"value":653},"alternatives",{"type":506,"value":655}," fields can be used to plot the routes on a map. Both are utilizing the same object so the ",{"type":472,"tag":459,"props":657,"children":659},{"className":658},[],[660],{"type":506,"value":661},"polyline",{"type":506,"value":663}," and the ",{"type":472,"tag":459,"props":665,"children":667},{"className":666},[],[668],{"type":506,"value":669},"legs",{"type":506,"value":671}," object are the ones to display a line and charge stations on a map. Additional data such as distance, duration and consumption can also be rendered per alternative. The route field will always be preferred over the alternatives.",{"type":472,"tag":528,"props":673,"children":675},{"id":674},"next-steps",[676],{"type":506,"value":677},"Next steps",{"type":472,"tag":509,"props":679,"children":680},{},[681],{"type":506,"value":682},"Now that everything about basic routing is explained, it's time to add additional features to the route. Let's learn about stations along routes, preferred operators and more in the next examples.",{"type":472,"tag":684,"props":685,"children":687},"div",{"className":686},[498],[688],{"type":472,"tag":689,"props":690,"children":695},"ct-code-tabs",{":codeList":691,":is-inversed":517,"className":692},"[{\"label\":\"client.js\",\"code\":\"import { createClient, createRequest, defaultExchanges, subscriptionExchange } from '@urql/core';\\nimport { pipe, subscribe } from 'wonka';\\nimport { SubscriptionClient } from 'subscriptions-transport-ws';\\nimport { createRoute, routeUpdate } from './queries.js';\\n\\n/**\\n * For the purpose of this example we use urql - 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 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};\\nconst subscriptionClient = new SubscriptionClient('wss://api.chargetrip.io/graphql', {\\n  reconnect: true,\\n  connectionParams: headers,\\n});\\n\\nconst client = createClient({\\n  url: 'https://api.chargetrip.io/graphql',\\n  fetchOptions: {\\n    method: 'POST',\\n    headers,\\n  },\\n  exchanges: [\\n    ...defaultExchanges,\\n    subscriptionExchange({\\n      forwardSubscription(operation) {\\n        return subscriptionClient.request(operation);\\n      },\\n    }),\\n  ],\\n});\\n\\n/**\\n * To create a route you need:\\n *\\n * 1. Create a new route and receive back its ID;\\n * 2. Subscribe to route updates in order to receive its details.\\n */\\nexport const getRoute = callback => {\\n  client\\n    .mutation(createRoute)\\n    .toPromise()\\n    .then(response => {\\n      const routeId = response.data.newRoute;\\n      if (!routeId) return Promise.reject('Could not retrieve Route ID. The response is not valid.');\\n\\n      const { unsubscribe } = pipe(\\n        client.executeSubscription(createRequest(routeUpdate, { id: routeId })),\\n        subscribe(result => {\\n          const { status, route, alternatives } = result.data.routeUpdatedById;\\n\\n          // you can keep listening to the route changes to update route information\\n          // for this example we want to only draw the initial route\\n          if (status === 'done' && route) {\\n            unsubscribe();\\n            callback(route, alternatives);\\n          }\\n        }),\\n      );\\n    })\\n    .catch(error => console.log(error));\\n};\\n\"},{\"label\":\"index.js\",\"code\":\"import { getRoute } from './client.js';\\nimport { decodePolylines } from './map.js';\\nimport { attachEventListeners, renderRouteDetails, renderRouteHeader, renderTabData } from './interface.js';\\n\\n/**\\n * This project shows you how to render alternative routes.\\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 */\\n\\ngetRoute((route, alternatives) => {\\n  decodePolylines(route, alternatives);\\n\\n  renderTabData(route, alternatives);\\n  renderRouteHeader(route);\\n  renderRouteDetails(route);\\n\\n  attachEventListeners();\\n});\\n\"},{\"label\":\"interface.js\",\"code\":\"import { getDurationString } from '../../../utils';\\nimport { highlightRoute, routes } from './map';\\n\\n/**\\n * Attach event listeners to our tabs\\n */\\nexport const attachEventListeners = () => {\\n  const routeOptions = document.querySelectorAll('.tab');\\n  const tabHighlighter = document.getElementById('tab-highlighter');\\n\\n  routeOptions.forEach((option, index) => {\\n    option.addEventListener('click', didClickTab.bind(null, index, routeOptions, tabHighlighter));\\n  });\\n};\\n\\n/**\\n * Small helper function that sets the font color and tab highlight\\n * @param { object } routeOptions - All possible route options that are available in the tabs\\n * @param { number } index - Current active index\\n * @param { element } tabHighlighter - The highlight element that indicates the active tab\\n */\\nexport const tabHandler = (index, routeOptions, tabHighlighter) => {\\n  routeOptions.forEach(option => option.classList.remove('active'));\\n  routeOptions[index].classList.add('active');\\n  tabHighlighter.style.transform = `translateX(calc(${index * 100}% + ${index * 4}px)`;\\n};\\n\\n/**\\n * Small function that sets the time on how much longer the different routes are\\n * @param { object } route - The fastest route\\n * @param { array } alternatives - The alternative route objects\\n */\\nexport const renderTabData = (route, alternatives) => {\\n  const tabsWrapper = document.getElementById('tabs-wrapper');\\n  const tabHighlighter = document.getElementById('tab-highlighter');\\n  const routeDurations = alternatives.map(\\n    alternative => `+${getDurationString(alternative.duration - route.duration)}`,\\n  );\\n\\n  routeDurations.unshift('Fastest');\\n  tabsWrapper.textContent = '';\\n  tabHighlighter.style.width = `calc(${100 / routeDurations.length}% - 4px)`;\\n\\n  routeDurations.forEach((routeDuration, idx) => {\\n    tabsWrapper.insertAdjacentHTML(\\n      'beforeend',\\n      `\u003Cdiv class=\\\"tab ${idx === 0 ? 'active' : ''}\\\">\\n          \u003Cp>${routeDuration}\u003C/p>\\n        \u003C/div>`,\\n    );\\n  });\\n};\\n\\n/**\\n * Function that renders the header details\\n * @param { object } data - All available route data\\n */\\nexport const renderRouteHeader = data => {\\n  const routeDistance = data.distance ? `${(data.distance / 1000).toFixed(0)} km` : 'Unknown';\\n  const routeStops = `${data.charges ?? 0} stops`;\\n  const routeEnergy = data.consumption ? `${data.consumption.toFixed(2)} kWh` : 'Unknown';\\n\\n  document.getElementById('duration').innerHTML = `${getDurationString(data.duration ?? 0)}`;\\n  document.getElementById('route-metadata').innerHTML = `${routeDistance} / ${routeStops} / ${routeEnergy}`;\\n};\\n\\n/**\\n * Function that renders a list with certainroute details\\n * @param { object } data - all available route data\\n */\\nexport const renderRouteDetails = data => {\\n  // Format route data so it is presentable\\n  const routeDetails = formatRouteDetails(data);\\n\\n  // Clear the previous rendered details\\n  document.getElementById('route-details').textContent = '';\\n\\n  // Loop over the formatted data and render lists inside the HTML\\n  Object.keys(routeDetails).forEach(key => {\\n    document.getElementById('route-details').insertAdjacentHTML(\\n      'beforeend',\\n      `\u003Cli>\\n          \u003Cp>${key}\u003C/p>\\n          \u003Cp>${routeDetails[key]}\u003C/p>\\n        \u003C/li>`,\\n    );\\n  });\\n};\\n\\n/**\\n * Small helper function that helps us map the route data to data that can be displayed\\n * @param { object } data - all available route data\\n * @returns formatted data that's ready to render */\\nconst formatRouteDetails = data => {\\n  return {\\n    'Charge duration': `${getDurationString(data.chargeTime ?? 0)}`,\\n    'Saved on fuel': `${data.saving?.currency || '€'}${data.saving?.money ?? 0}`,\\n    'Total consumption': data.consumption ? `${data.consumption.toFixed(2)} kWh` : 'Unknown',\\n    'CO2 spared': data.saving?.co2 ? `${data.saving.co2 / 1000} Kg` : 'Unknown',\\n  };\\n};\\n\\n/**\\n * The function that handles highlighting the correct tab and route when a tab is clicked\\n * @param { number } index - The index of the tab clicked\\n * @param { HTMLCollection } routeOptions - A collection of tabs\\n * @param { HTMLElement } tabHighlighter - The highlight element of the tabs\\n * @param { Event } event - The click event\\n */\\nconst didClickTab = (index, routeOptions, tabHighlighter, event) => {\\n  event.preventDefault();\\n  tabHandler(index, routeOptions, tabHighlighter);\\n  highlightRoute(index, routes);\\n};\\n\"},{\"label\":\"map.js\",\"code\":\"import mapboxgl from 'mapbox-gl';\\nimport * as mapboxPolyline from '@mapbox/polyline';\\nimport { renderRouteDetails, renderRouteHeader, tabHandler } from './interface';\\nimport { getDurationString } from '../../../utils';\\n\\nmapboxgl.accessToken = 'pk.eyJ1IjoiY2hhcmdldHJpcCIsImEiOiJjazhpaG8ydTIwNWNpM21ud29xeXc2amhlIn0.rGKgR3JfG9Z5dCWjUI_oGA';\\n\\nexport let routes;\\n\\nconst map = new mapboxgl.Map({\\n  cooperativeGestures: true,\\n  container: 'map',\\n  style: 'mapbox://styles/chargetrip/ckgcbf3kz0h8819qki8uwhe0k',\\n  zoom: 6.8,\\n  center: [8.8320104, 47.9758916],\\n});\\n\\n// Display the charge time on a hover\\nconst popup = new mapboxgl.Popup({\\n  closeButton: false,\\n  closeOnClick: false,\\n});\\n\\n/**\\n * Draw a route on a map.\\n *\\n * Route object contains `polyline` data -  the polyline encoded route (series of coordinates as a single string).\\n * We need to decode this information first. We use Mapbox polyline tool (https://www.npmjs.com/package/@mapbox/polyline) for this.\\n * As a result of decoding we get pairs [latitude, longitude].\\n * To draw a route on a map we use Mapbox GL JS. This tool uses the format [longitude,latitude],\\n * so we have to reverse every pair.\\n *\\n * @param { object } route - The fastest route\\n * @param { array } alternatives - The alternative route objects\\n */\\nexport const decodePolylines = (route, alternatives) => {\\n  const _routes = [];\\n\\n  const decodedData = mapboxPolyline.decode(route.polyline);\\n  const reversed = decodedData.map(item => item.reverse());\\n\\n  _routes.push({ data: route, polyline: reversed });\\n\\n  alternatives.map(item => {\\n    const decoded = mapboxPolyline.decode(item.polyline);\\n    const itemReversed = decoded.map(item => item.reverse());\\n    _routes.push({ data: item, polyline: itemReversed });\\n  });\\n\\n  routes = _routes;\\n\\n  drawRoutes(routes);\\n};\\n\\n/**\\n * Draw route polyline and show charging stations on the map.\\n * @param { array } routes - The route and alternative routes between two points\\n */\\nconst drawRoutes = routes => {\\n  if (map.loaded()) {\\n    routes.forEach((route, index) => drawPolyline(route, index, index === 0 ? '#0078FF' : '#9CA7B2'));\\n    map.moveLayer(`0`);\\n    showLegs(routes[0].data.legs);\\n  } else {\\n    map.on('load', () => {\\n      routes.forEach((route, index) => drawPolyline(route, index, index === 0 ? '#0078FF' : '#9CA7B2'));\\n      map.moveLayer(`0`);\\n      showLegs(routes[0].data.legs);\\n    });\\n  }\\n\\n  for (let i = 0; i \u003C routes.length; i++) {\\n    map.on('mouseenter', `${i}`, e => {\\n      map.getCanvas().style.cursor = 'pointer';\\n      const coordinates = e.lngLat;\\n      const description =\\n        `\u003Cstrong>${getDurationString(routes[i].data.duration ?? 0)}` +\\n        ` • ` +\\n        `${routes[i].data.charges ?? 0} stops\u003C/strong>`;\\n\\n      while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {\\n        coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;\\n      }\\n\\n      popup\\n        .setLngLat(coordinates)\\n        .setHTML(description)\\n        .addTo(map);\\n    });\\n\\n    map.on('click', `${i}`, () => {\\n      const routeOptions = document.querySelectorAll('.tab');\\n      const tabHighlighter = document.getElementById('tab-highlighter');\\n\\n      tabHandler(i, routeOptions, tabHighlighter);\\n      highlightRoute(i, routes);\\n    });\\n\\n    map.on('mouseleave', `${i}`, () => {\\n      map.getCanvas().style.cursor = '';\\n      popup.remove();\\n    });\\n  }\\n};\\n\\n/**\\n * Draw the polyline on the map\\n * @param { object } route - All the route data to draw the route\\n * @param { number } index - The current index of the route we are going to draw\\n * @param { string } linecolor - The line color in a hex string\\n */\\nconst drawPolyline = (route, index, linecolor) => {\\n  const geojson = {\\n    type: 'FeatureCollection',\\n    features: [\\n      {\\n        type: 'Feature',\\n        geometry: {\\n          type: 'LineString',\\n          properties: {\\n            description: route.data.duration + ' ' + route.data.charges,\\n          },\\n          coordinates: route.polyline,\\n        },\\n      },\\n    ],\\n  };\\n\\n  map.addSource(`${index}`, {\\n    type: 'geojson',\\n    lineMetrics: true,\\n    data: geojson,\\n  });\\n\\n  map.addLayer({\\n    id: `${index}`,\\n    type: 'line',\\n    options: 'beforeLayer',\\n    source: `${index}`,\\n    layout: {\\n      'line-join': 'round',\\n      'line-cap': 'round',\\n    },\\n    paint: {\\n      'line-color': linecolor,\\n      'line-width': 5,\\n    },\\n  });\\n};\\n\\n/**\\n * Helper function that draws the legs of a route. Allows us to show charging stations, origin and destination\\n * Last leg of the route is always a destination point\\n * All other legs are either charging stations or via points (if route has additional stops)\\n *\\n * @param { array } legs - The legs of the route\\n */\\nconst showLegs = legs => {\\n  if (legs.length === 0) return;\\n  if (map.getLayer('legs')) map.removeLayer('legs');\\n  if (map.getSource('legs')) map.removeSource('legs');\\n\\n  let points = [];\\n\\n  // we want to show origin point on the map\\n  // to do that we use the origin of the first leg\\n  points.push({\\n    type: 'Feature',\\n    properties: {\\n      icon: 'location_big',\\n    },\\n    geometry: legs[0].origin?.geometry,\\n  });\\n\\n  legs.map((leg, index) => {\\n    // add charging stations\\n    if (index !== legs.length - 1) {\\n      points.push({\\n        type: 'Feature',\\n        properties: {\\n          description: `${getDurationString(leg.chargeTime)}`,\\n          icon: 'unknown-turbo',\\n        },\\n        geometry: leg.destination?.geometry,\\n      });\\n    } else {\\n      // add destination point (last leg)\\n      points.push({\\n        type: 'Feature',\\n        properties: {\\n          icon: 'arrival',\\n        },\\n        geometry: leg.destination?.geometry,\\n      });\\n    }\\n  });\\n\\n  // draw route points on a map\\n  map.addLayer({\\n    id: 'legs',\\n    type: 'symbol',\\n    layout: {\\n      'icon-image': '{icon}',\\n      'icon-allow-overlap': true,\\n      'icon-ignore-placement': true,\\n      'icon-size': ['case', ['==', ['get', 'icon'], 'location-big'], ['literal', 0.7], ['literal', 0.8]],\\n      'icon-offset': ['case', ['==', ['get', 'icon'], 'location_big'], ['literal', [0, 0]], ['literal', [0, -15]]],\\n    },\\n    source: {\\n      type: 'geojson',\\n      data: {\\n        type: 'FeatureCollection',\\n        features: points,\\n      },\\n    },\\n  });\\n};\\n\\n/**\\n * Highlight the route that was clicked.\\n *\\n * @param { object } routes - All routes recieved from the route query\\n * @param { number } id - index / id of the polyline that was clicked on\\n */\\nexport const highlightRoute = (id, routes) => {\\n  map.setPaintProperty(`${id}`, 'line-color', '#0078FF');\\n  for (let j = 0; j \u003C routes.length; j++) {\\n    if (j !== id) {\\n      map.setPaintProperty(`${j}`, 'line-color', '#9CA7B2');\\n    }\\n  }\\n  map.moveLayer(`${id}`);\\n  showLegs(routes[id].data.legs);\\n  renderRouteDetails(routes[id].data);\\n  renderRouteHeader(routes[id].data);\\n};\\n\"},{\"label\":\"queries.js\",\"code\":\"import qql from 'graphql-tag';\\n\\n/*\\n * In this example we request a route from Milan, Italy to Frankfurt, Germany\\n * The changing conditions are:\\n *   - The state of charge is 72.5 kwh\\n *   - EV can charge at Tesla, CHADEMO and Type 2 changers\\n *   - should use climate (temperature and weather conditions)\\n *   - one passenger in the car (drive alone)\\n */\\nexport const createRoute = qql`\\nmutation newRoute{\\n    newRoute(\\n      input: {\\n        ev: {\\n          id: \\\"5d161be5c9eef46132d9d20a\\\"\\n          plugs: { chargingPower: 150, standard: TESLA_S }\\n          adapters: [\\n            { chargingPower: 150, standard: IEC_62196_T2_COMBO }\\n            { chargingPower: 150, standard: CHADEMO }\\n          ]\\n          climate: true\\n          numberOfPassengers: 1\\n        }\\n        routeRequest: {\\n          origin: {\\n            type: Feature\\n            geometry: { type: Point, coordinates: [9.180471169780414, 45.46866785869714] }\\n            properties: { name: \\\"Milan, Italy\\\" }\\n\\n          }\\n          destination: {\\n            type: Feature\\n            geometry: { type: Point, coordinates: [9.165197732508853, 48.785521962794526] }\\n            properties: { name: \\\"Frankfurt, Germany\\\" }\\n          }\\n        }\\n      }\\n    )\\n  }\\n`;\\n\\nexport const routeUpdate = qql`\\nsubscription routeUpdatedById($id: ID!){\\n  routeUpdatedById(id: $id) {\\n    status\\n    alternatives {\\n      type\\n      polyline\\n      charges\\n      duration\\n      distance\\n      consumption\\n      chargeTime\\n      saving {\\n        money\\n        co2\\n      }\\n      legs{\\n        distance\\n        chargeTime\\n        origin{\\n          geometry{\\n            type\\n            coordinates\\n          }\\n        }\\n        destination{\\n          geometry\\n          {\\n            type\\n            coordinates\\n          }\\n        }\\n      }\\n    }\\n    route {\\n      charges\\n      saving {\\n        money\\n        co2\\n      }\\n      chargeTime\\n      distance\\n      duration\\n      consumption\\n      polyline\\n      legs{\\n        distance\\n        chargeTime\\n        origin{\\n          geometry{\\n            type\\n            coordinates\\n          }\\n        }\\n        destination{\\n          geometry\\n          {\\n            type\\n            coordinates\\n          }\\n        }\\n      }\\n    }\\n  }\\n}\\n`;\\n\"}]",[693,694],"stick","top-6",[],{"title":464,"searchDepth":697,"depth":697,"links":698},2,[],"markdown","content:5.examples:3.routes:3.alternative-routes.md","content","5.examples/3.routes/3.alternative-routes.md","md",1775054262977]