{"_id":"54557a8e35f4ac0800f42bb1","version":{"_id":"5452b671b7fa011600a75c25","__v":13,"forked_from":"545285163f92fc0e009396ca","project":"545285163f92fc0e009396c7","createdAt":"2014-10-30T22:06:41.529Z","releaseDate":"2014-10-30T22:06:41.529Z","categories":["5452b671b7fa011600a75c26","545579ee35f4ac0800f42bac","54557a3135f4ac0800f42bad","54557b7b35f4ac0800f42bb3","54557c91a1e5cd0e00435ecc","54557caf35f4ac0800f42bbd","54557dc1a1e5cd0e00435ecf","54557e7ba1e5cd0e00435ed6","54557f81533d890e000cf8a9","54557fcd533d890e000cf8aa","54558020a1e5cd0e00435edf","545580b6533d890e000cf8ad","545580e1a1e5cd0e00435ee6"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.2.0","version":"0.2.0"},"__v":57,"user":"545284e73f92fc0e009396c6","category":{"_id":"54557c91a1e5cd0e00435ecc","__v":5,"pages":["54558241a1e5cd0e00435ee7","5455828da1e5cd0e00435ee9","54558344a1e5cd0e00435eec","545583a1533d890e000cf8b9","545583e0a1e5cd0e00435ef2"],"version":"5452b671b7fa011600a75c25","project":"545285163f92fc0e009396c7","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-11-02T00:36:33.382Z","from_sync":false,"order":0,"slug":"guides","title":"Guides"},"is_link":false,"project":"545285163f92fc0e009396c7","updates":[],"next":{"pages":[],"description":""},"createdAt":"2014-11-02T00:27:58.080Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"basic_auth":false,"results":{"codes":[]},"try":true,"auth":"never","params":[],"url":""},"isReference":false,"order":2,"body":"Data input and visualisation output is now controlled by the Blueprint API. It's based on the concept of **triggers** and **actions**; much like Zapier or IFTTT, just instead for geographic data visualisation. It underpins the entire system since 0.2.0 and it completely changes the way you pull data into ViziCities and how you output it. A lot of hard work went into formulating and constructing it — we're incredibly proud of it!\n\nThe Blueprint API can be a little confusing at first glance, though it's incredibly simple to use once you understand how everything fits together. Once you grasp it you'll have the full power of ViziCities at your disposal!\n\nWe're looking at creating tooling to help construct interactions with the Blueprint API but for now you need to create things by hand. Until then, [get in touch](mailto:hello:::at:::vizicities.com) if you have any questions about how to use it.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Components of the Blueprint API\"\n}\n[/block]\nIn short, the Blueprint API has 3 parts; an **input**, an **output** and a **mapping configuration**. Neither the input nor the output know about each other or care about each others data structure. Everything is neatly brought together by a configuration object that describes which input to use, which output to use, as well as how and, more importantly, when to map the data between them.\n\nYou can use the Blueprint API as many times as you want within ViziCities, though each use will always contain these 3 parts. **In reality, you'll likely only ever need to directly handle the mapping configuration part**, that is unless you're building your own custom inputs and outputs.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Triggers and actions\"\n}\n[/block]\nHow do the various components share data amongst each other? How do they even know when to do things like retrieving data or outputting results? **All communication is handled by triggers and actions.**\n\nBoth inputs and outputs can contain triggers and actions:\n\n  *  **Triggers are events that get fired at a certain point in time** (eg. after initialisation, or after you've finished moving around the city)\n  * **Actions are methods that are called after a trigger event has been fired** (eg. loading new data after you've finished moving, or outputting something when data is received)\n\nInputs should never know about or rely on triggers or actions from a specific output, and likewise outputs should never know about or rely on triggers or actions from a specific input. The linkage between the two is provided by the mapping configuration.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Input\"\n}\n[/block]\nThe input aspect of the API handles the retrieval and basic processing of data, nothing more. In most cases the input will simply request data when needed and pass it on for further processing by the chosen output (as a trigger). **Nothing in the input should know about or be dependant on a specific output.**\n\nThe purpose of the input is to turn an otherwise unreadable data source into a documented format easily readable by the rest of the system. In most cases this means simply outputting the data as a JavaScript object or array with a known, consistent format.\n\nFor example, [the KML input](https://github.com/vizicities/vizicities/blob/0.2.0/src/Blueprint/BlueprintInputKML.js) in ViziCities turns KML data (XML) into a JavaScript object ([by using the JXON library](https://developer.mozilla.org/en-US/docs/JXON)) and outputs a trigger when it's done. *That's all it does*; the rest is handled by the output and mapping configuration.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Output\"\n}\n[/block]\nThe output aspect of the API handles the processing of data for visual output. In most cases the output will simply receive data when needed (as an action), process it and output it to the world. **Nothing in the output should know about or be dependant on a specific input.**\n\nThe purpose of the output is to receive data in a documented, known format and turn that into some kind of visual output. In most cases this means receiving data as a JavaScript object and using that to create a 3D object.\n\nFor example, [the debug points output](https://github.com/vizicities/vizicities/blob/0.2.0/src/Blueprint/BlueprintOutputDebugPoints.js) takes an array of points and places a 3D object at the given coordinates for each one. *That's all it does.*\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Mapping configuration\"\n}\n[/block]\nEverything is tied together by the mapping configuration aspect of the Blueprint API. **This configuration is the public-facing part of the API and will usually be the only part of it you ever need to deal with.** Understanding how to build a mapping configuration is the key to using the Blueprint API.\n\nThe mapping configuration is a simple JavaScript object that describes which input to use, which output to use, and which actions to fire for each trigger. So far so simple.\n\nThings get a little trickier when you need to map data from the format provided by a trigger to the format expected by the output. Fortunately, the API is identical for all inputs and outputs so once you've put together your first configuration you'll have all the knowledge you need for future ones.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Example configuration\"\n}\n[/block]\nLet's run through the configuration for taking a KML input and using the debug points output to place a 3D object at each coordinate.\n\nHere's how the full configuration looks:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  input: {\\n    type: \\\"BlueprintInputKML\\\",\\n    options: {\\n      path: \\\"./data/sample.kml\\\"\\n    }\\n  },\\n  output: {\\n    type: \\\"BlueprintOutputDebugPoints\\\",\\n    options: {}\\n  },\\n  triggers: [{\\n    triggerObject: \\\"output\\\",\\n    triggerName: \\\"initialised\\\",\\n    triggerArguments: [],\\n    actionObject: \\\"input\\\",\\n    actionName: \\\"requestData\\\",\\n    actionArguments: [],\\n    actionOutput: {}\\n  }, {\\n    triggerObject: \\\"input\\\",\\n    triggerName: \\\"dataReceived\\\",\\n    triggerArguments: [\\\"kml\\\"],\\n    actionObject: \\\"output\\\",\\n    actionName: \\\"outputPoints\\\",\\n    actionArguments: [\\\"data\\\"],\\n    actionOutput: {\\n      data: {\\n        // Loop through each item in triggerArg.kml and return a new array of processed values (a map)\\n        process: \\\"map\\\",\\n        itemsObject: \\\"kml\\\",\\n        itemsProperties: \\\"document.placemark\\\",\\n        // Return a new object for each item with the given properties\\n        transformation: {\\n          coordinates: \\\"point.coordinates\\\"\\n        }\\n      }\\n    }\\n  }]\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nFirst, we'll walk though the `input` property in the configuration:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"input: {\\n  type: \\\"BlueprintInputKML\\\",\\n  options: {\\n    path: \\\"./data/sample.kml\\\"\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"`type`\",\n    \"0-1\": \"String representation of the input module you want to use (this is the same as the [input module filename](https://github.com/vizicities/vizicities/tree/0.2.0/src/Blueprint)).\",\n    \"1-0\": \"`options`\",\n    \"1-1\": \"Used to provide options for the input; in most cases this will at least include a path to the data source (local or remote).\"\n  },\n  \"cols\": 2,\n  \"rows\": 2\n}\n[/block]\nNext up is the `output` property, which is practically identical to `input`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"output: {\\n  type: \\\"BlueprintOutputDebugPoints\\\",\\n  options: {}\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"`type`\",\n    \"1-0\": \"`options`\",\n    \"0-1\": \"String representation of the output module you want to use (this is the same as the [output module filename](https://github.com/vizicities/vizicities/tree/0.2.0/src/Blueprint)).\",\n    \"1-1\": \"Used to provide options for the output.\",\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\"\n  },\n  \"cols\": 2,\n  \"rows\": 2\n}\n[/block]\nAnd finally the `triggers` property:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"triggers: [{\\n  triggerObject: \\\"output\\\",\\n  triggerName: \\\"initialised\\\",\\n  triggerArguments: [],\\n  actionObject: \\\"input\\\",\\n  actionName: \\\"requestData\\\",\\n  actionArguments: [],\\n  actionOutput: {}\\n}, {\\n  triggerObject: \\\"input\\\",\\n  triggerName: \\\"dataReceived\\\",\\n  triggerArguments: [\\\"kml\\\"],\\n  actionObject: \\\"output\\\",\\n  actionName: \\\"outputPoints\\\",\\n  actionArguments: [\\\"data\\\"],\\n  actionOutput: {\\n    data: {\\n      // Loop through each item in triggerArg.kml and return a new array of processed values (a map)\\n      process: \\\"map\\\",\\n      itemsObject: \\\"kml\\\",\\n      itemsProperties: \\\"document.placemark\\\",\\n      // Return a new object for each item with the given properties\\n      transformation: {\\n        coordinates: \\\"point.coordinates\\\"\\n      }\\n    }\\n  }\\n}]\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nThis contains an array of objects that each have the following properties:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"`triggerObject`\",\n    \"1-0\": \"`triggerName`\",\n    \"2-0\": \"`triggerArguments`\",\n    \"3-0\": \"`actionObject`\",\n    \"4-0\": \"`actionName`\",\n    \"5-0\": \"`actionArguments`\",\n    \"6-0\": \"`actionOutput`\",\n    \"0-1\": \"String defining whether this trigger is fired from the \\\"input\\\" or \\\"output\\\".\",\n    \"1-1\": \"String defining the name of the trigger event (found in the documentation for the input or output).\",\n    \"2-1\": \"String defining the names and order of the trigger arguments, if required (found in the documentation for the input or output).\",\n    \"3-1\": \"String defining whether the action is to be called on the \\\"input\\\" or \\\"output\\\".\",\n    \"4-1\": \"String defining the name of the action (found in the documentation for the input or output).\",\n    \"5-1\": \"String defining the names and order of the action arguments, if required (found in the documentation for the input or output).\",\n    \"6-1\": \"Object containing mappings between trigger arguments and action arguments (described below).\"\n  },\n  \"cols\": 2,\n  \"rows\": 7\n}\n[/block]\nThe `actionOutput` mappings differ slightly depending on whether the trigger arguments can be directly passed through or whether they require some processing.\n\nIf they can be directly passed through, the `actionOutput` mapping is as follows:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"Action argument name\",\n    \"0-1\": \"String representation of the trigger argument to pass through to the action without processing.\"\n  },\n  \"cols\": 2,\n  \"rows\": 1\n}\n[/block]\nOtherwise if the trigger arguments require some processing, the `actionOutput` mapping is as follows:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"Action argument name\",\n    \"0-1\": \"Object describing the transformation operation to perform on the trigger argument before it can be mapped to the action argument.\"\n  },\n  \"cols\": 2,\n  \"rows\": 1\n}\n[/block]\nIn this case, the transformation object will follow a different format. For example, if the following data is given by the \"kml\" trigger argument:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  document: {\\n    placemark: [{\\n      description: \\\"Some point\\\",\\n      point: {\\n        coordinates: [\\\"-0.058649\\\", \\\"51.518051\\\", \\\"0.000000\\\"]\\n      }\\n    }, {\\n      description: \\\"Some other point\\\",\\n      point: {\\n        coordinates: [\\\"-0.100551\\\", \\\"51.516354\\\", \\\"0.000000\\\"]\\n      }\\n    }]\\n  }\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThen the mapping would be as follows (in this example `data` is the name of the action argument we're mapping to):\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"data: {\\n  // Loop through each item in triggerArg.kml and return a new array of processed values (a map)\\n  process: \\\"map\\\",\\n  // Name of trigger argument\\n  itemsObject: \\\"kml\\\",\\n  // Within kml the data is stored in the document.placemark array\\n  itemsProperties: \\\"document.placemark\\\",\\n  // Return a new object for each document.placemark item with the given propertiea\\n  transformation: {\\n    // Eg. document.placemark[n].point.coordinates\\n    coordinates: \\\"point.coordinates\\\"\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"`process`\",\n    \"0-1\": \"String representation of the transformation to be applied. Only \\\"map\\\" is supported right now.\",\n    \"1-0\": \"`itemsObject`\",\n    \"2-0\": \"`itemsProperties`\",\n    \"3-0\": \"`transformation`\",\n    \"1-1\": \"String representation of the trigger argument that holds the data you're interested in.\",\n    \"2-1\": \"String representation of any object properties or array indices to get to the data list.\",\n    \"3-1\": \"Object with a property for each action argument name and a string representation of the hierarchy to get from `itemsProperties` to the specific piece of data you require.\"\n  },\n  \"cols\": 2,\n  \"rows\": 4\n}\n[/block]\nStill confused? It takes a while to grasp but once you do it becomes much easier to use. [Look at the example Blueprint API configurations](https://github.com/vizicities/vizicities/blob/0.2.0/examples/basic-example/main.js) to see how things work in practice.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Pulling everything together with the switchboard\"\n}\n[/block]\nThe Switchboard module takes a Blueprint API configuration as an input and performs all the mapping magic behind the scenes. The only thing left for you to do is to add the switchboard  to the world (along with the inputs and outputs).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var switchboardKML = new VIZI.BlueprintSwitchboard(kmlConfig);\\nswitchboardKML.addToWorld(world);\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]","excerpt":"Getting you up and running with the Blueprint API for data input and visualisation output","slug":"using-the-blueprint-api","type":"basic","title":"Using the Blueprint API"}

Using the Blueprint API

Getting you up and running with the Blueprint API for data input and visualisation output

Data input and visualisation output is now controlled by the Blueprint API. It's based on the concept of **triggers** and **actions**; much like Zapier or IFTTT, just instead for geographic data visualisation. It underpins the entire system since 0.2.0 and it completely changes the way you pull data into ViziCities and how you output it. A lot of hard work went into formulating and constructing it — we're incredibly proud of it! The Blueprint API can be a little confusing at first glance, though it's incredibly simple to use once you understand how everything fits together. Once you grasp it you'll have the full power of ViziCities at your disposal! We're looking at creating tooling to help construct interactions with the Blueprint API but for now you need to create things by hand. Until then, [get in touch](mailto:hello@vizicities.com) if you have any questions about how to use it. [block:api-header] { "type": "basic", "title": "Components of the Blueprint API" } [/block] In short, the Blueprint API has 3 parts; an **input**, an **output** and a **mapping configuration**. Neither the input nor the output know about each other or care about each others data structure. Everything is neatly brought together by a configuration object that describes which input to use, which output to use, as well as how and, more importantly, when to map the data between them. You can use the Blueprint API as many times as you want within ViziCities, though each use will always contain these 3 parts. **In reality, you'll likely only ever need to directly handle the mapping configuration part**, that is unless you're building your own custom inputs and outputs. [block:api-header] { "type": "basic", "title": "Triggers and actions" } [/block] How do the various components share data amongst each other? How do they even know when to do things like retrieving data or outputting results? **All communication is handled by triggers and actions.** Both inputs and outputs can contain triggers and actions: * **Triggers are events that get fired at a certain point in time** (eg. after initialisation, or after you've finished moving around the city) * **Actions are methods that are called after a trigger event has been fired** (eg. loading new data after you've finished moving, or outputting something when data is received) Inputs should never know about or rely on triggers or actions from a specific output, and likewise outputs should never know about or rely on triggers or actions from a specific input. The linkage between the two is provided by the mapping configuration. [block:api-header] { "type": "basic", "title": "Input" } [/block] The input aspect of the API handles the retrieval and basic processing of data, nothing more. In most cases the input will simply request data when needed and pass it on for further processing by the chosen output (as a trigger). **Nothing in the input should know about or be dependant on a specific output.** The purpose of the input is to turn an otherwise unreadable data source into a documented format easily readable by the rest of the system. In most cases this means simply outputting the data as a JavaScript object or array with a known, consistent format. For example, [the KML input](https://github.com/vizicities/vizicities/blob/0.2.0/src/Blueprint/BlueprintInputKML.js) in ViziCities turns KML data (XML) into a JavaScript object ([by using the JXON library](https://developer.mozilla.org/en-US/docs/JXON)) and outputs a trigger when it's done. *That's all it does*; the rest is handled by the output and mapping configuration. [block:api-header] { "type": "basic", "title": "Output" } [/block] The output aspect of the API handles the processing of data for visual output. In most cases the output will simply receive data when needed (as an action), process it and output it to the world. **Nothing in the output should know about or be dependant on a specific input.** The purpose of the output is to receive data in a documented, known format and turn that into some kind of visual output. In most cases this means receiving data as a JavaScript object and using that to create a 3D object. For example, [the debug points output](https://github.com/vizicities/vizicities/blob/0.2.0/src/Blueprint/BlueprintOutputDebugPoints.js) takes an array of points and places a 3D object at the given coordinates for each one. *That's all it does.* [block:api-header] { "type": "basic", "title": "Mapping configuration" } [/block] Everything is tied together by the mapping configuration aspect of the Blueprint API. **This configuration is the public-facing part of the API and will usually be the only part of it you ever need to deal with.** Understanding how to build a mapping configuration is the key to using the Blueprint API. The mapping configuration is a simple JavaScript object that describes which input to use, which output to use, and which actions to fire for each trigger. So far so simple. Things get a little trickier when you need to map data from the format provided by a trigger to the format expected by the output. Fortunately, the API is identical for all inputs and outputs so once you've put together your first configuration you'll have all the knowledge you need for future ones. [block:api-header] { "type": "basic", "title": "Example configuration" } [/block] Let's run through the configuration for taking a KML input and using the debug points output to place a 3D object at each coordinate. Here's how the full configuration looks: [block:code] { "codes": [ { "code": "{\n input: {\n type: \"BlueprintInputKML\",\n options: {\n path: \"./data/sample.kml\"\n }\n },\n output: {\n type: \"BlueprintOutputDebugPoints\",\n options: {}\n },\n triggers: [{\n triggerObject: \"output\",\n triggerName: \"initialised\",\n triggerArguments: [],\n actionObject: \"input\",\n actionName: \"requestData\",\n actionArguments: [],\n actionOutput: {}\n }, {\n triggerObject: \"input\",\n triggerName: \"dataReceived\",\n triggerArguments: [\"kml\"],\n actionObject: \"output\",\n actionName: \"outputPoints\",\n actionArguments: [\"data\"],\n actionOutput: {\n data: {\n // Loop through each item in triggerArg.kml and return a new array of processed values (a map)\n process: \"map\",\n itemsObject: \"kml\",\n itemsProperties: \"document.placemark\",\n // Return a new object for each item with the given properties\n transformation: {\n coordinates: \"point.coordinates\"\n }\n }\n }\n }]\n}", "language": "json" } ] } [/block] First, we'll walk though the `input` property in the configuration: [block:code] { "codes": [ { "code": "input: {\n type: \"BlueprintInputKML\",\n options: {\n path: \"./data/sample.kml\"\n }\n}", "language": "json" } ] } [/block] [block:parameters] { "data": { "h-0": "Property", "h-1": "Description", "0-0": "`type`", "0-1": "String representation of the input module you want to use (this is the same as the [input module filename](https://github.com/vizicities/vizicities/tree/0.2.0/src/Blueprint)).", "1-0": "`options`", "1-1": "Used to provide options for the input; in most cases this will at least include a path to the data source (local or remote)." }, "cols": 2, "rows": 2 } [/block] Next up is the `output` property, which is practically identical to `input`: [block:code] { "codes": [ { "code": "output: {\n type: \"BlueprintOutputDebugPoints\",\n options: {}\n}", "language": "json" } ] } [/block] [block:parameters] { "data": { "0-0": "`type`", "1-0": "`options`", "0-1": "String representation of the output module you want to use (this is the same as the [output module filename](https://github.com/vizicities/vizicities/tree/0.2.0/src/Blueprint)).", "1-1": "Used to provide options for the output.", "h-0": "Property", "h-1": "Description" }, "cols": 2, "rows": 2 } [/block] And finally the `triggers` property: [block:code] { "codes": [ { "code": "triggers: [{\n triggerObject: \"output\",\n triggerName: \"initialised\",\n triggerArguments: [],\n actionObject: \"input\",\n actionName: \"requestData\",\n actionArguments: [],\n actionOutput: {}\n}, {\n triggerObject: \"input\",\n triggerName: \"dataReceived\",\n triggerArguments: [\"kml\"],\n actionObject: \"output\",\n actionName: \"outputPoints\",\n actionArguments: [\"data\"],\n actionOutput: {\n data: {\n // Loop through each item in triggerArg.kml and return a new array of processed values (a map)\n process: \"map\",\n itemsObject: \"kml\",\n itemsProperties: \"document.placemark\",\n // Return a new object for each item with the given properties\n transformation: {\n coordinates: \"point.coordinates\"\n }\n }\n }\n}]", "language": "json" } ] } [/block] This contains an array of objects that each have the following properties: [block:parameters] { "data": { "h-0": "Property", "h-1": "Description", "0-0": "`triggerObject`", "1-0": "`triggerName`", "2-0": "`triggerArguments`", "3-0": "`actionObject`", "4-0": "`actionName`", "5-0": "`actionArguments`", "6-0": "`actionOutput`", "0-1": "String defining whether this trigger is fired from the \"input\" or \"output\".", "1-1": "String defining the name of the trigger event (found in the documentation for the input or output).", "2-1": "String defining the names and order of the trigger arguments, if required (found in the documentation for the input or output).", "3-1": "String defining whether the action is to be called on the \"input\" or \"output\".", "4-1": "String defining the name of the action (found in the documentation for the input or output).", "5-1": "String defining the names and order of the action arguments, if required (found in the documentation for the input or output).", "6-1": "Object containing mappings between trigger arguments and action arguments (described below)." }, "cols": 2, "rows": 7 } [/block] The `actionOutput` mappings differ slightly depending on whether the trigger arguments can be directly passed through or whether they require some processing. If they can be directly passed through, the `actionOutput` mapping is as follows: [block:parameters] { "data": { "h-0": "Property", "h-1": "Description", "0-0": "Action argument name", "0-1": "String representation of the trigger argument to pass through to the action without processing." }, "cols": 2, "rows": 1 } [/block] Otherwise if the trigger arguments require some processing, the `actionOutput` mapping is as follows: [block:parameters] { "data": { "h-0": "Property", "h-1": "Description", "0-0": "Action argument name", "0-1": "Object describing the transformation operation to perform on the trigger argument before it can be mapped to the action argument." }, "cols": 2, "rows": 1 } [/block] In this case, the transformation object will follow a different format. For example, if the following data is given by the "kml" trigger argument: [block:code] { "codes": [ { "code": "{\n document: {\n placemark: [{\n description: \"Some point\",\n point: {\n coordinates: [\"-0.058649\", \"51.518051\", \"0.000000\"]\n }\n }, {\n description: \"Some other point\",\n point: {\n coordinates: [\"-0.100551\", \"51.516354\", \"0.000000\"]\n }\n }]\n }\n}", "language": "javascript" } ] } [/block] Then the mapping would be as follows (in this example `data` is the name of the action argument we're mapping to): [block:code] { "codes": [ { "code": "data: {\n // Loop through each item in triggerArg.kml and return a new array of processed values (a map)\n process: \"map\",\n // Name of trigger argument\n itemsObject: \"kml\",\n // Within kml the data is stored in the document.placemark array\n itemsProperties: \"document.placemark\",\n // Return a new object for each document.placemark item with the given propertiea\n transformation: {\n // Eg. document.placemark[n].point.coordinates\n coordinates: \"point.coordinates\"\n }\n}", "language": "json" } ] } [/block] [block:parameters] { "data": { "h-0": "Property", "h-1": "Description", "0-0": "`process`", "0-1": "String representation of the transformation to be applied. Only \"map\" is supported right now.", "1-0": "`itemsObject`", "2-0": "`itemsProperties`", "3-0": "`transformation`", "1-1": "String representation of the trigger argument that holds the data you're interested in.", "2-1": "String representation of any object properties or array indices to get to the data list.", "3-1": "Object with a property for each action argument name and a string representation of the hierarchy to get from `itemsProperties` to the specific piece of data you require." }, "cols": 2, "rows": 4 } [/block] Still confused? It takes a while to grasp but once you do it becomes much easier to use. [Look at the example Blueprint API configurations](https://github.com/vizicities/vizicities/blob/0.2.0/examples/basic-example/main.js) to see how things work in practice. [block:api-header] { "type": "basic", "title": "Pulling everything together with the switchboard" } [/block] The Switchboard module takes a Blueprint API configuration as an input and performs all the mapping magic behind the scenes. The only thing left for you to do is to add the switchboard to the world (along with the inputs and outputs). [block:code] { "codes": [ { "code": "var switchboardKML = new VIZI.BlueprintSwitchboard(kmlConfig);\nswitchboardKML.addToWorld(world);", "language": "javascript" } ] } [/block]