{"id":52061,"date":"2024-07-31T00:00:00","date_gmt":"2024-07-31T07:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/"},"modified":"2026-03-30T12:19:14","modified_gmt":"2026-03-30T19:19:14","slug":"creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs","status":"publish","type":"post","link":"https:\/\/www.griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/","title":{"rendered":"Creating a Mind Map for Data Visualization using GridDB and Nodejs"},"content":{"rendered":"<p>In this article, we&#8217;ll explore the power of visualization and practical application by building a fullstack web mind map application using technologies such as <a href=\"https:\/\/react.dev\/\">ReactJS<\/a>, <a href=\"https:\/\/reactflow.dev\/\">ReactFlow<\/a>, <a href=\"https:\/\/expressjs.com\/\">ExpressJS<\/a>, GridDB, and <a href=\"https:\/\/nodejs.org\/en\">NodeJS<\/a>.<\/p>\n<p>For those who do not know, GridDB is a highly scalable, in-memory NoSQL time-series database optimized for IoT and Big Data. While GridDB is optimized for IoT and Big Data, it can also be used for other purposes such as gaming and web applications.<\/p>\n<h2>Source Code<\/h2>\n<p>Found on Github:<\/p>\n<p>`$ git clone https:\/\/github.com\/griddbnet\/Blogs.git &#8211;branch mind-map<\/p>\n<h2>The Application<\/h2>\n<p>GridDB can be used on any of the Windows, Linux, or Mac operating systems.<\/p>\n<p>While I installed <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/wsl\/\">WSL<\/a> (Windows Subsystem for Linux) on my Windows to have access to Linux (Ubuntu) on my machine, you could also follow along with this tutorial using Docker or MacOS. The <a href=\"https:\/\/docs.griddb.net\/installation\/misc.html\">GridDB documentation<\/a> provides you with a detailed installation process to successfully install the database on your computer.<\/p>\n<p>There are also top-notch YouTube videos on their <a href=\"https:\/\/www.youtube.com\/@GridDB\">YouTube channel<\/a> for those who prefer videos to written documentation. The entire code for the web application is available on <a href=\"https:\/\/github.com\/Babajide777\/grid-db-mind-map\">Github<\/a>.<\/p>\n<p>Open your terminal and clone the repo using this command<\/p>\n<div class=\"clipboard\">\n<pre><code>git clone https:\/\/github.com\/Babajide777\/grid-db-mind-map.git<\/code><\/pre>\n<\/div>\n<p>Then,<\/p>\n<div class=\"clipboard\">\n<pre><code>cd grid-db-mind-map<\/code><\/pre>\n<\/div>\n<p>To change to the grid db mind map app directory.<\/p>\n<h2>The App Classification<\/h2>\n<p>This application is divided into 3 parts \u2013<\/p>\n<ol>\n<li>The Backend<\/li>\n<li>The Frontend<\/li>\n<li>Frontend and Backend connected<\/li>\n<\/ol>\n<h2>Prerequisites<\/h2>\n<ul>\n<li>GridDB version 5.3.0<\/li>\n<li>Node v12.22.9<\/li>\n<\/ul>\n<h2>The Frontend<\/h2>\n<p>The UI of this mind map app allows users to add new map items, edit map items, and a delete map item. The following libraries were used to build the UI for this project:<\/p>\n<h3><a href=\"https:\/\/react.dev\/\">ReactJs<\/a>:<\/h3>\n<p>ReactJS is a JavaScript library built and maintained by Meta for building user interfaces.<\/p>\n<h3><a href=\"https:\/\/mui.com\/\">Material UI<\/a>:<\/h3>\n<p>Material UI is a comprehensive library of components from Google&#8217;s Material Design system.<\/p>\n<h3><a href=\"https:\/\/redux-toolkit.js.org\/rtk-query\/overview\">RTK Query<\/a>:<\/h3>\n<p>Redux Toolkit is a state management library.<\/p>\n<h3><a href=\"https:\/\/reactflow.dev\/\">React Flow<\/a>:<\/h3>\n<p>React Flow a customizable React component for building node-based editors and interactive diagrams<\/p>\n<p>To view the frontend of the app change to the client directory.<\/p>\n<div class=\"clipboard\">\n<pre><code>cd client<\/code><\/pre>\n<\/div>\n<p>Now install the required dependencies<\/p>\n<div class=\"clipboard\">\n<pre><code>npm i<\/code><\/pre>\n<\/div>\n<p>Then run the app using<\/p>\n<div class=\"clipboard\">\n<pre><code>npm start<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/1.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/1.png\" alt=\"\" width=\"1366\" height=\"590\" class=\"aligncenter size-full wp-image-30201\" srcset=\"\/wp-content\/uploads\/2024\/07\/1.png 1366w, \/wp-content\/uploads\/2024\/07\/1-300x130.png 300w, \/wp-content\/uploads\/2024\/07\/1-1024x442.png 1024w, \/wp-content\/uploads\/2024\/07\/1-768x332.png 768w, \/wp-content\/uploads\/2024\/07\/1-600x259.png 600w\" sizes=\"(max-width: 1366px) 100vw, 1366px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/2.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/2.png\" alt=\"\" width=\"1366\" height=\"590\" class=\"aligncenter size-full wp-image-30202\" srcset=\"\/wp-content\/uploads\/2024\/07\/2.png 1366w, \/wp-content\/uploads\/2024\/07\/2-300x130.png 300w, \/wp-content\/uploads\/2024\/07\/2-1024x442.png 1024w, \/wp-content\/uploads\/2024\/07\/2-768x332.png 768w, \/wp-content\/uploads\/2024\/07\/2-600x259.png 600w\" sizes=\"(max-width: 1366px) 100vw, 1366px\" \/><\/a><\/p>\n<p>On the top right corner, we have the form that allows you to enter the details of a new idea. There are 4 input fields. Source is a dropdown of the node your idea is to be linked to. For example, the source for \u201cFrontend developer\u201d is \u201csoftware developer\u201d.<\/p>\n<p>positionX is the position of the node on the x axis, positionY is the position of the ode on the Y axis, both of which are numbers, while label is the name of the node.<\/p>\n<p>On the bottom left corner, there are 4 buttons, the + sign is to zoom in, the \u2013 sign is to zoom out, the box sign is to centralize all the nodes, while the padlock sign is to lock or unlock things in place. On the bottom right, we have a min map that shows a miniature version of the entire canvas.<\/p>\n<p>Each node comes with a delete and edit button that allows you to both delete and edit details of a node.<\/p>\n<h2>The Backend<\/h2>\n<p>The backend in this project ensures the correct map item data is gotten from the frontend, and then save to the GridDB database. We are able to perform functionalities with the GridDB database.<\/p>\n<p>The proper CRUD functionalities are carried out in the app.<\/p>\n<p>These are the packages that are needed to build the backend.<\/p>\n<ul>\n<li><a href=\"https:\/\/expressjs.com\/\">ExpressJs<\/a>: A minimalist NodeJS framework that is used for building RESTful APIs.<\/p>\n<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/morgan\">Morgan<\/a>: A NodeJS middleware that is used to log HTTP requests.<\/p>\n<\/li>\n<li><a href=\"https:\/\/github.com\/griddb\/node-api\">GridDB Node API<\/a>: The GridDB client for NodeJS<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/joi.dev\/api\/18.x.x\">Joi<\/a>: A schema description language and data validator for JavaScript<\/p>\n<\/li>\n<\/ul>\n<h3>Step-by-Step Guide to Building the Meal Plan App<\/h3>\n<p>Follow the steps as explained below;<\/p>\n<h4>Step 1: Create a Server Folder<\/h4>\n<p>Create a \u201cserver\u201d folder and initialize npm to generate a package.json file.<br \/>\nYou can name the folder anything you want:<\/p>\n<div class=\"clipboard\">\n<pre><code>npm i<\/code><\/pre>\n<\/div>\n<h4>Step 2: Install Required Packages<\/h4>\n<p>We are going to install all the required packages at once by running the following line of code:<\/p>\n<div class=\"clipboard\">\n<pre><code>npm i express morgan joi griddb-node-api cors<\/code><\/pre>\n<\/div>\n<p><strong><em>Addition<\/em><\/strong><\/p>\n<p>While it is not required to install nodemon, it&#8217;s nice to have in development so that the server would restart automatically when any change is saved.<br \/>\nThis is the command to install nodemon as a dev dependency:<\/p>\n<div class=\"clipboard\">\n<pre><code>npm i -D nodemon<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">{\n  \"name\": \"grid-db-mind-map-server\",\n  \"version\": \"1.0.0\",\n  \"description\": \"backend for grid db mind-map\",\n  \"main\": \"server.js\",\n  \"scripts\": {\n    \"test\": \"echo \"Error: no test specified\" && exit 1\",\n    \"dev\": \"nodemon server.js\"\n  },\n  \"keywords\": [\n    \"mind-map\",\n    \"griddb\",\n    \"griddb_node\"\n  ],\n  \"author\": \"Oyafemi Babajide\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"cors\": \"^2.8.5\",\n    \"express\": \"^4.18.2\",\n    \"griddb_node\": \"^0.8.4\",\n    \"griddb-node-api\": \"^0.8.6\",\n    \"joi\": \"^17.11.0\",\n    \"morgan\": \"^1.10.0\"\n  },\n  \"devDependencies\": {\n    \"nodemon\": \"^3.0.1\"\n  }\n}\n<\/code><\/pre>\n<\/div>\n<h4>Step 3: Create Server.js File<\/h4>\n<p>Create an server.js file and insert the following code:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const express = require(\"express\");\nconst morgan = require(\"morgan\");\nconst app = express();\nconst cors = require(\"cors\");\n\nconst PORT = 4000 || process.env.PORT;\n\napp.use(morgan(\"dev\"));\napp.use(express.json());\napp.use(express.urlencoded({ extended: false }));\napp.use(cors(\"*\"));\n\napp.get(\"\/\", (req, res) => {\n  res.send(\"GridDB mind map Backend API\");\n});\n\napp.use(\"\/api\", require(\".\/routes\/mindMapRoutes\"));\n\napp.listen(PORT, () => {\n  console.log(`Server started on ${PORT}`);\n});\n<\/code><\/pre>\n<\/div>\n<p>If you installed nodemon as a dev dependency, you\u2019ll need to add this line of code to the \u201cscripts\u201d section in your package.json file:<\/p>\n<div class=\"clipboard\">\n<pre><code>\"dev\": \"nodemon index.js\"<\/code><\/pre>\n<\/div>\n<h4>Step 4: Run the Application<\/h4>\n<p>If you installed nodemon, you could use \u2018npm start\u2019 to start the application, however, this would require you to restart the application any time you make changes, going against what nodemon is intended for. The following method doesn\u2019t require you to restart the application when you make any changes (the benefit of nodemon):<\/p>\n<div class=\"clipboard\">\n<pre><code>npm run dev<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/3.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/3.png\" alt=\"\" width=\"659\" height=\"191\" class=\"aligncenter size-full wp-image-30203\" srcset=\"\/wp-content\/uploads\/2024\/07\/3.png 659w, \/wp-content\/uploads\/2024\/07\/3-300x87.png 300w, \/wp-content\/uploads\/2024\/07\/3-600x174.png 600w, \/wp-content\/uploads\/2024\/07\/3-350x100.png 350w\" sizes=\"(max-width: 659px) 100vw, 659px\" \/><\/a><\/p>\n<h4>Step 5: Setup the GridDB Database<\/h4>\n<p>We will connect to the GridDB database using the griddb-node-api package.<br \/>\nWe then set the container name of the project. I chose <em>\u201cmind-map\u201d<\/em> because it is related to the project. However, you can call it whatever you want.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const griddb = require(\"griddb-node-api\");\n\nconst containerName = \"mind-map\";\n\nconst initStore = async () => {\n  const factory = griddb.StoreFactory.getInstance();\n  try {\n    \/\/ Connect to GridDB Cluster\n    const store = await factory.getStore({\n      host: \"127.0.0.1\",\n      port: 10001,\n      clusterName: \"myCluster\",\n      username: \"admin\",\n      password: \"admin\",\n    });\n    return store;\n  } catch (e) {\n    throw e;\n  }\n};\n\nfunction initContainer() {\n  const conInfo = new griddb.ContainerInfo({\n    name: containerName,\n    columnInfoList: [\n      [\"id\", griddb.Type.STRING],\n      [\"source\", griddb.Type.STRING],\n      [\"target\", griddb.Type.STRING],\n      [\"x\", griddb.Type.DOUBLE],\n      [\"y\", griddb.Type.DOUBLE],\n      [\"label\", griddb.Type.STRING],\n      [\"lineId\", griddb.Type.STRING],\n    ],\n    type: griddb.ContainerType.COLLECTION,\n    rowKey: true,\n  });\n\n  return conInfo;\n}\n\nasync function createContainer(store, conInfo) {\n  try {\n    const collectionDB = await store.putContainer(conInfo);\n    return collectionDB;\n  } catch (err) {\n    console.error(err);\n    throw err;\n  }\n}\n\nasync function initGridDbTS() {\n  try {\n    const store = await initStore();\n    const conInfo = await initContainer();\n    const collectionDb = await createContainer(store, conInfo);\n    return { collectionDb, store, conInfo };\n  } catch (err) {\n    console.error(err);\n    throw err;\n  }\n}\n\nasync function containersInfo(store) {\n  for (\n    var index = 0;\n    index < store.partitionController.partitionCount;\n    index++\n  ) {\n    store.partitionController\n      .getContainerNames(index, 0, -1)\n      .then((nameList) => {\n        nameList.forEach((element) => {\n          \/\/ Get container information\n          store.getContainerInfo(element).then((info) => {\n            if (info.name === containerName) {\n              console.log(\"Container Info: n  %s\", info.name);\n              if (info.type == griddb.ContainerType.COLLECTION) {\n                console.log(\"  Type: Collection\");\n              } else {\n                console.log(\"  Type: TimeSeries\");\n              }\n              \/\/console.log(\"rowKeyAssigned=%s\", info.rowKey.toString());\n              console.log(\" \ufe0f  Column Count: %d\", info.columnInfoList.length);\n              info.columnInfoList.forEach((element) =>\n                console.log(\"  Column (%s, %d)\", element[0], element[1])\n              );\n            }\n          });\n        });\n        return true;\n      })\n      .catch((err) => {\n        if (err.constructor.name == \"GSException\") {\n          for (var i = 0; i < err.getErrorStackSize(); i++) {\n            console.log(\"[%d]\", i);\n            console.log(err.getErrorCode(i));\n            console.log(err.getMessage(i));\n          }\n        } else {\n          console.log(err);\n        }\n      });\n  }\n}\n\n\/**\n * Insert data to GridDB\n *\/\nasync function insert(data, container) {\n  try {\n    let savedData = await container.put(data);\n\n    console.log(savedData);\n    return { status: true };\n  } catch (err) {\n    if (err.constructor.name == \"GSException\") {\n      for (var i = 0; i < err.getErrorStackSize(); i++) {\n        console.log(\"[%d]\", i);\n        console.log(err.getErrorCode(i));\n        console.log(err.getMessage(i));\n      }\n\n      return { status: false, error: err.toString() };\n    } else {\n      console.log(err);\n      return { status: false, error: err };\n    }\n  }\n}\n\nasync function multiInsert(data, db) {\n  try {\n    await db.multiPut(data);\n    return { ok: true };\n  } catch (err) {\n    console.log(err);\n    return { ok: false, error: err };\n  }\n}\n\nasync function queryAll(conInfo, store) {\n  const sql = `SELECT *`;\n  const cont = await store.putContainer(conInfo);\n  const query = await cont.query(sql);\n  try {\n    const rowset = await query.fetch();\n    const results = [];\n\n    while (rowset.hasNext()) {\n      const row = rowset.next();\n      results.push(row);\n    }\n    return { results, length: results.length };\n  } catch (err) {\n    console.log(err);\n    return err;\n  }\n}\n\nasync function queryByID(id, conInfo, store) {\n  try {\n    const cont = await store.putContainer(conInfo);\n    const row = await cont.get(id);\n    return row;\n  } catch (err) {\n    console.log(err, \"here\");\n  }\n}\n\n\/\/ Delete container\nasync function dropContainer(store, containerName) {\n  store\n    .dropContainer(containerName)\n    .then(() => {\n      console.log(\"drop ok\");\n      return store.putContainer(conInfo);\n    })\n    .catch((err) => {\n      if (err.constructor.name == \"GSException\") {\n        for (var i = 0; i < err.getErrorStackSize(); i++) {\n          console.log(\"[%d]\", i);\n          console.log(err.getErrorCode(i));\n          console.log(err.getMessage(i));\n        }\n      } else {\n        console.log(err);\n      }\n    });\n}\n\n\/\/Delete entry\nconst deleteByID = async (store, id, conInfo) => {\n  try {\n    const cont = await store.putContainer(conInfo);\n    let res = await cont.remove(id);\n\n    return [true, res];\n  } catch (error) {\n    return [false, error];\n  }\n};\n\nconst editByID = async (store, conInfo, data) => {\n  try {\n    const cont = await store.putContainer(conInfo);\n    const res = await cont.put(data);\n    return [true, \"\"];\n  } catch (err) {\n    return [false, err];\n  }\n};\n\nmodule.exports = {\n  initStore,\n  initContainer,\n  initGridDbTS,\n  createContainer,\n  insert,\n  multiInsert,\n  queryAll,\n  dropContainer,\n  containersInfo,\n  containerName,\n  queryByID,\n  deleteByID,\n  editByID,\n};\n<\/code><\/pre>\n<\/div>\n<p>The initStore function connects the app to the GridDB Cluster using the host, port, clusterName, username, and password.<\/p>\n<p>The initContainer function is used to set the columns for the container and the datatypes for the different columns.<\/p>\n<p>The createContainer creates the container while initGridDbTS initializes the database connection.<\/p>\n<h4>Step 6: Create a Meal plan<\/h4>\n<p>To create a mind map item<\/p>\n<div class=\"clipboard\">\n<pre><code>router.post(\"\/add-meal\", addMealPlan);<\/code><\/pre>\n<\/div>\n<p>We use the Joi package to validate the request body sent from the frontend and then insert into the container that as created in step 6.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const Joi = require(\"joi\");\n\n\/\/map item validation rules\nconst mapItemValidation = async (field) => {\n  const schema = Joi.object({\n    id: Joi.string().required(),\n    source: Joi.string().required(),\n    target: Joi.string().required(),\n    x: Joi.number().integer().required(),\n    y: Joi.number().integer().required(),\n    label: Joi.string().required(),\n    lineId: Joi.string().required(),\n  });\n  try {\n    return await schema.validateAsync(field, { abortEarly: false });\n  } catch (err) {\n    return err;\n  }\n};\n\nmodule.exports = {\n  mapItemValidation,\n};\n\n<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">async function insert(data, container) {\n  try {\n    let savedData = await container.put(data);\n\n    console.log(savedData);\n    return { status: true };\n  } catch (err) {\n    if (err.constructor.name == \"GSException\") {\n      for (var i = 0; i < err.getErrorStackSize(); i++) {\n        console.log(\"[%d]\", i);\n        console.log(err.getErrorCode(i));\n        console.log(err.getMessage(i));\n      }\n\n      return { status: false, error: err.toString() };\n    } else {\n      console.log(err);\n      return { status: false, error: err };\n    }\n  }\n}\n<\/code><\/pre>\n<\/div>\n<p>The id and lineId are randomly generated on the frontend and sent along with the source, target, x, y, and label. After the map item is saved to the database, we then query the map item using the created random id to get the details of the saved map item.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">async function queryByID(id, conInfo, store) {\n  try {\n    const cont = await store.putContainer(conInfo);\n    const row = await cont.get(id);\n    return row;\n  } catch (err) {\n    console.log(err, \"here\");\n  }\n}\n\n<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const addMealItem = async (req, res) => {\n  \/\/validate req.body\n  const { collectionDb, store, conInfo } = await initGridDbTS();\n\n  const { details } = await mapItemValidation(req.body);\n  if (details) {\n    let allErrors = details.map((detail) => detail.message.replace(\/\"\/g, \"\"));\n    return responseHandler(res, allErrors, 400, false, \"\");\n  }\n\n  try {\n    const { id, source, target, x, y, label, lineId } = req.body;\n\n    const data = [id, source, target, x, y, label, lineId];\n\n    const saveStatus = await insert(data, collectionDb);\n\n    if (saveStatus.status) {\n      const result = await queryByID(id, conInfo, store);\n      let returnData = {\n        id: result[0],\n        source: result[1],\n        target: result[2],\n        x: result[3],\n        y: result[4],\n        label: result[5],\n        lineId: result[6],\n      };\n\n      return responseHandler(\n        res,\n        \"Map Item saved successfully\",\n        201,\n        true,\n        returnData\n      );\n    }\n\n    return responseHandler(\n      res,\n      \"Unable to save map item\",\n      400,\n      false,\n      saveStatus.error\n    );\n  } catch (error) {\n    responseHandler(res, \"Error saving map item\", 400, false, error.message);\n  }\n};\n\n<\/code><\/pre>\n<\/div>\n<p>The map plan item details are then sent to the frontend as a json response.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/4.png\" alt=\"\" width=\"409\" height=\"60\" class=\"aligncenter size-full wp-image-30204\" srcset=\"\/wp-content\/uploads\/2024\/07\/4.png 409w, \/wp-content\/uploads\/2024\/07\/4-300x44.png 300w, \/wp-content\/uploads\/2024\/07\/4-400x60.png 400w\" sizes=\"(max-width: 409px) 100vw, 409px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/5.png\" alt=\"\" width=\"940\" height=\"337\" class=\"aligncenter size-full wp-image-30205\" srcset=\"\/wp-content\/uploads\/2024\/07\/5.png 940w, \/wp-content\/uploads\/2024\/07\/5-300x108.png 300w, \/wp-content\/uploads\/2024\/07\/5-768x275.png 768w, \/wp-content\/uploads\/2024\/07\/5-600x215.png 600w\" sizes=\"(max-width: 940px) 100vw, 940px\" \/><\/a><\/p>\n<h4>Step 7: Get a Map Item Detail<\/h4>\n<p>The id of the map item that is required is gotten from the params of the request data.<\/p>\n<div class=\"clipboard\">\n<pre><code>router.get(\"\/map-detail\/:id\", mapItemDetails);<\/code><\/pre>\n<\/div>\n<p>Then id of the map item is then queried with the data in the database and a 200 response with the map item data is sent if the map item is found.<\/p>\n<p>This route will mostly be used to get the details of a map item that is to be edited.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const mapItemDetails = async (req, res) => {\n  try {\n    const { store, conInfo } = await initGridDbTS();\n    const { id } = req.params;\n\n    const result = await queryByID(id, conInfo, store);\n\n    let returnData = {\n      id: result[0],\n      source: result[1],\n      target: result[2],\n      x: result[3],\n      y: result[4],\n      label: result[5],\n      lineId: result[6],\n    };\n\n    return result\n      ? responseHandler(res, \"map item detail found\", 200, true, returnData)\n      : responseHandler(res, \"No map item detail found\", 400, false, \"\");\n  } catch (error) {\n    responseHandler(res, \"Error saving map item\", 400, false, error.message);\n  }\n};\n<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/6.png\" alt=\"\" width=\"413\" height=\"160\" class=\"aligncenter size-full wp-image-30206\" srcset=\"\/wp-content\/uploads\/2024\/07\/6.png 413w, \/wp-content\/uploads\/2024\/07\/6-300x116.png 300w\" sizes=\"(max-width: 413px) 100vw, 413px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/7.png\" alt=\"\" width=\"942\" height=\"381\" class=\"aligncenter size-full wp-image-30195\" srcset=\"\/wp-content\/uploads\/2024\/07\/7.png 942w, \/wp-content\/uploads\/2024\/07\/7-300x121.png 300w, \/wp-content\/uploads\/2024\/07\/7-768x311.png 768w, \/wp-content\/uploads\/2024\/07\/7-600x243.png 600w\" sizes=\"(max-width: 942px) 100vw, 942px\" \/><\/a><\/p>\n<h4>Step 8: Edit a Map Item<\/h4>\n<div class=\"clipboard\">\n<pre><code>router.put(\"\/edit-map-item\/:id\", editMapItem);<\/code><\/pre>\n<\/div>\n<p>To edit a map item, again the id of the required map item is sent in the params of the request. The map item is queried using the given id and the old details of the map item is replaced by the new ones.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const editMapItem = async (req, res) => {\n  try {\n    const { store, conInfo } = await initGridDbTS();\n    const { id } = req.params;\n\n    const result = await queryByID(id, conInfo, store);\n\n    if (!result) {\n      return responseHandler(res, \"incorrect map item ID\", 400, false, \"\");\n    }\n\n    const { source, target, x, y, label, lineId } = req.body;\n\n    const data = [id, source, target, x, y, label, lineId];\n\n    const check = await editByID(store, conInfo, data);\n\n    if (check[0]) {\n      const result2 = await queryByID(id, conInfo, store);\n\n      let returnData = {\n        id: result2[0],\n        source: result2[1],\n        target: result2[2],\n        x: result2[3],\n        y: result2[4],\n        label: result2[5],\n        lineId: result2[6],\n      };\n\n      return responseHandler(\n        res,\n        \"map item edited successfully\",\n        200,\n        true,\n        returnData\n      );\n    }\n    return responseHandler(res, \"Error editing map item \", 400, false, \"\");\n  } catch (error) {\n    responseHandler(res, \"Error saving map item\", 400, false, error.message);\n  }\n};\n\n<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const editByID = async (store, conInfo, data) => {\n  try {\n    const cont = await store.putContainer(conInfo);\n    const res = await cont.put(data);\n    return [true, \"\"];\n  } catch (err) {\n    return [false, err];\n  }\n};\n\n<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/8.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/8.png\" alt=\"\" width=\"925\" height=\"369\" class=\"aligncenter size-full wp-image-30196\" srcset=\"\/wp-content\/uploads\/2024\/07\/8.png 925w, \/wp-content\/uploads\/2024\/07\/8-300x120.png 300w, \/wp-content\/uploads\/2024\/07\/8-768x306.png 768w, \/wp-content\/uploads\/2024\/07\/8-600x239.png 600w\" sizes=\"(max-width: 925px) 100vw, 925px\" \/><\/a><\/p>\n<h3>Step 9: Delete a Map Item<\/h3>\n<div class=\"clipboard\">\n<pre><code>router.delete(\"\/delete-map-item\/:id\", deleteMapItem);<\/code><\/pre>\n<\/div>\n<p>The id is gotten from the params or the request data and that is used to delete the row containing the specified map item.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const deleteMapItem = async (req, res) => {\n  try {\n    const { store, conInfo } = await initGridDbTS();\n    const { id } = req.params;\n\n    const result = await deleteByID(store, id, conInfo);\n\n    return result[0]\n      ? responseHandler(res, \"map item deleted successfully\", 200, true, \"\")\n      : responseHandler(res, \"Error deleting map item\", 400, false, \"\");\n  } catch (error) {\n    responseHandler(res, \"Error saving map item\", 400, false, error.message);\n  }\n};\n\n<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const deleteByID = async (store, id, conInfo) => {\n  try {\n    const cont = await store.putContainer(conInfo);\n    let res = await cont.remove(id);\n\n    return [true, res];\n  } catch (error) {\n    return [false, error];\n  }\n};\n\n<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/9.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/9.png\" alt=\"\" width=\"438\" height=\"29\" class=\"aligncenter size-full wp-image-30197\" srcset=\"\/wp-content\/uploads\/2024\/07\/9.png 438w, \/wp-content\/uploads\/2024\/07\/9-300x20.png 300w\" sizes=\"(max-width: 438px) 100vw, 438px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/10.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/10.png\" alt=\"\" width=\"936\" height=\"329\" class=\"aligncenter size-full wp-image-30198\" srcset=\"\/wp-content\/uploads\/2024\/07\/10.png 936w, \/wp-content\/uploads\/2024\/07\/10-300x105.png 300w, \/wp-content\/uploads\/2024\/07\/10-768x270.png 768w, \/wp-content\/uploads\/2024\/07\/10-600x211.png 600w\" sizes=\"(max-width: 936px) 100vw, 936px\" \/><\/a><\/p>\n<h3>Step 10: Get List of All Map Items in the Database<\/h3>\n<p>To get list of all map items in the database, you have to do this;<\/p>\n<div class=\"clipboard\">\n<pre><code>router.get(\"\/all-map-items\", getAllMapItems);<\/code><\/pre>\n<\/div>\n<p>This returns all the map items in the database.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const getAllMapItems = async (req, res) => {\n  try {\n    const { store, conInfo } = await initGridDbTS();\n    const result = await queryAll(conInfo, store);\n    let data = [];\n\n    result.results.forEach((result) => {\n      let returnData = {\n        id: result[0],\n        source: result[1],\n        target: result[2],\n        x: result[3],\n        y: result[4],\n        label: result[5],\n        lineId: result[6],\n      };\n      data.push(returnData);\n\n      return result;\n    });\n\n    return responseHandler(\n      res,\n      \"all map items in the database successfully retrieved\",\n      200,\n      true,\n      data\n    );\n  } catch (error) {\n    return responseHandler(\n      res,\n      \"Unable to retrieve meal plans\",\n      400,\n      false,\n      \"\"\n    );\n  }\n};\n\n\n<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">async function queryAll(conInfo, store) {\n  const sql = `SELECT *`;\n  const cont = await store.putContainer(conInfo);\n  const query = await cont.query(sql);\n  try {\n    const rowset = await query.fetch();\n    const results = [];\n\n    while (rowset.hasNext()) {\n      const row = rowset.next();\n      results.push(row);\n    }\n    return { results, length: results.length };\n  } catch (err) {\n    console.log(err);\n    return err;\n  }\n}\n\n<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/11.png\" alt=\"\" width=\"366\" height=\"117\" class=\"aligncenter size-full wp-image-30199\" srcset=\"\/wp-content\/uploads\/2024\/07\/11.png 366w, \/wp-content\/uploads\/2024\/07\/11-300x96.png 300w\" sizes=\"(max-width: 366px) 100vw, 366px\" \/><\/a><\/p>\n<h2>Frontend and Backend connected<\/h2>\n<p>The essence of this app is to connect the backend with the frontend to ensure the app is fully functional. I built a short software developer roadmap to test the functionality of the app.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/12.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/07\/12.png\" alt=\"\" width=\"967\" height=\"606\" class=\"aligncenter size-full wp-image-30200\" srcset=\"\/wp-content\/uploads\/2024\/07\/12.png 967w, \/wp-content\/uploads\/2024\/07\/12-300x188.png 300w, \/wp-content\/uploads\/2024\/07\/12-768x481.png 768w, \/wp-content\/uploads\/2024\/07\/12-600x376.png 600w\" sizes=\"(max-width: 967px) 100vw, 967px\" \/><\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>In this comprehensive guide, we've embarked on a journey of innovation, inspired by the visionary creators of history who turned simple ideas into transformative realities.<\/p>\n<p>From the foundational work of Charles Babbage to the groundbreaking achievements of modern-day innovators like Thomas Edison, Steve Jobs, and Bill Gates, we've witnessed the power of mapping out ideas and translating them into tangible outcomes.<\/p>\n<p>By delving into the realm of frontend software engineering, we've explored the potential to reshape our lives and the world around us. Leveraging the latest technologies such as ReactJS, ReactFlow, ExpressJS, GridDB, and NodeJS, we've embarked on the creation of a fullstack web mind map application, bridging the gap between imagination and implementation.<\/p>\n<p>At the heart of our journey lies GridDB, a versatile and scalable NoSQL time-series database optimized for IoT and Big Data applications. Through its integration into our project, we've unlocked new possibilities for data visualization and management, empowering us to bring our ideas to life with precision and efficiency.<\/p>\n<p>From the installation process to the development of frontend and backend components, we've navigated through each step with clarity and purpose. By following our step-by-step guide, you've gained the knowledge and tools necessary to embark on your own journey of innovation, armed with the skills to create impactful solutions in the digital landscape.<\/p>\n<p>As we conclude our exploration, remember that innovation knows no bounds.<\/p>\n<p>Whether you're a seasoned developer or a budding enthusiast, the path to discovery awaits. Embrace the spirit of creativity, challenge the status quo, and let your ideas soar.<\/p>\n<p>With determination and perseverance, you have the power to shape the future.<\/p>\n<p>Let's continue to innovate, inspire, and make a difference in the world.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we&#8217;ll explore the power of visualization and practical application by building a fullstack web mind map application using technologies such as ReactJS, ReactFlow, ExpressJS, GridDB, and NodeJS. For those who do not know, GridDB is a highly scalable, in-memory NoSQL time-series database optimized for IoT and Big Data. While GridDB is optimized [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":52062,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-52061","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Creating a Mind Map for Data Visualization using GridDB and Nodejs | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"In this article, we&#039;ll explore the power of visualization and practical application by building a fullstack web mind map application using technologies\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating a Mind Map for Data Visualization using GridDB and Nodejs | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"In this article, we&#039;ll explore the power of visualization and practical application by building a fullstack web mind map application using technologies\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-31T07:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-30T19:19:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.griddb.net\/wp-content\/uploads\/2025\/12\/12.png\" \/>\n\t<meta property=\"og:image:width\" content=\"967\" \/>\n\t<meta property=\"og:image:height\" content=\"606\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Creating a Mind Map for Data Visualization using GridDB and Nodejs\",\"datePublished\":\"2024-07-31T07:00:00+00:00\",\"dateModified\":\"2026-03-30T19:19:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\"},\"wordCount\":1517,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2025\/12\/12.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\",\"name\":\"Creating a Mind Map for Data Visualization using GridDB and Nodejs | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2025\/12\/12.png\",\"datePublished\":\"2024-07-31T07:00:00+00:00\",\"dateModified\":\"2026-03-30T19:19:14+00:00\",\"description\":\"In this article, we'll explore the power of visualization and practical application by building a fullstack web mind map application using technologies\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2025\/12\/12.png\",\"contentUrl\":\"\/wp-content\/uploads\/2025\/12\/12.png\",\"width\":967,\"height\":606},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.griddb.net\/en\/#website\",\"url\":\"https:\/\/www.griddb.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/www.griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/www.griddb.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Creating a Mind Map for Data Visualization using GridDB and Nodejs | GridDB: Open Source Time Series Database for IoT","description":"In this article, we'll explore the power of visualization and practical application by building a fullstack web mind map application using technologies","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/","og_locale":"en_US","og_type":"article","og_title":"Creating a Mind Map for Data Visualization using GridDB and Nodejs | GridDB: Open Source Time Series Database for IoT","og_description":"In this article, we'll explore the power of visualization and practical application by building a fullstack web mind map application using technologies","og_url":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2024-07-31T07:00:00+00:00","article_modified_time":"2026-03-30T19:19:14+00:00","og_image":[{"width":967,"height":606,"url":"https:\/\/www.griddb.net\/wp-content\/uploads\/2025\/12\/12.png","type":"image\/png"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/"},"author":{"name":"griddb-admin","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Creating a Mind Map for Data Visualization using GridDB and Nodejs","datePublished":"2024-07-31T07:00:00+00:00","dateModified":"2026-03-30T19:19:14+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/"},"wordCount":1517,"commentCount":0,"publisher":{"@id":"https:\/\/www.griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2025\/12\/12.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/","url":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/","name":"Creating a Mind Map for Data Visualization using GridDB and Nodejs | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/www.griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2025\/12\/12.png","datePublished":"2024-07-31T07:00:00+00:00","dateModified":"2026-03-30T19:19:14+00:00","description":"In this article, we'll explore the power of visualization and practical application by building a fullstack web mind map application using technologies","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/creating-a-mind-map-for-data-visualization-using-griddb-and-nodejs\/#primaryimage","url":"\/wp-content\/uploads\/2025\/12\/12.png","contentUrl":"\/wp-content\/uploads\/2025\/12\/12.png","width":967,"height":606},{"@type":"WebSite","@id":"https:\/\/www.griddb.net\/en\/#website","url":"https:\/\/www.griddb.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/www.griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/www.griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/www.griddb.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/52061","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/comments?post=52061"}],"version-history":[{"count":2,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/52061\/revisions"}],"predecessor-version":[{"id":55120,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/52061\/revisions\/55120"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media\/52062"}],"wp:attachment":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media?parent=52061"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/categories?post=52061"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/tags?post=52061"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}