{"id":46676,"date":"2021-12-03T00:00:00","date_gmt":"2021-12-03T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/"},"modified":"2025-11-13T12:55:41","modified_gmt":"2025-11-13T20:55:41","slug":"time-sampled-data-visualization-with-vuejs-and-griddb","status":"publish","type":"post","link":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/","title":{"rendered":"Time-Sampled Data Visualization with VueJS and GridDB"},"content":{"rendered":"<p>To improve a chart of time-series data we can let the user choose the time basis or &#8220;resolution&#8221; e.g. seconds, minutes, hours, etc.<\/p>\n<p>This way, they can see look for micro-trends in the data (by using high resolution e.g. seconds) or look for broader macro-trends in the same data (by using low resolution, e.g. hours).<\/p>\n<p>In this article, we&#8217;ll set up a time-series data visualization using Vue and Chart.js. We&#8217;ll allow a user to select different time resolutions which will be serviced by GridDB time sampling queries from a backend database.<\/p>\n<p>This article is a continuation of a series where we&#8217;ve been building a server monitor dashboard using a Node Express backend with GridDB, and visualizing the data in Vue. It&#8217;s a good idea to read <a href=\"https:\/\/griddb.net\/en\/blog\/part-one-vuejs-dashboard\/\">part one<\/a> and <a href=\"https:\/\/griddb.net\/en\/blog\/part-two-vuejs-dashboard\/\">part two<\/a> first.<\/p>\n<p>You can get the code for this tutorial <a href=\"https:\/\/github.com\/anthonygore\/time-sampling-vue-griddb\">here on GitHub<\/a>.<\/p>\n<h2>Charting data with Vue Chartkick<\/h2>\n<p>The Vue app we built in the previous tutorial of this series used the VueChartJs library for data visualization.<\/p>\n<p>Unfortunately, this library is not great when you need to continually update the data during the app lifecycle as we&#8217;ll be doing here.<\/p>\n<p>A library that provides more flexibility in this regard is <a href=\"https:\/\/github.com\/ankane\/vue-chartkick\/tree\/v0.6.1\">Vue Chartkick<\/a>. So let&#8217;s replace the vue-chartjs script we&#8217;re loading in the document head with vue-chartkick.<\/p>\n<p><em>index.html<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-html\">&lt;head&gt;\n  ...\n  &lt;script src=\"&lt;https:\/\/cdn.jsdelivr.net\/npm\/vue-chartkick@0.6.1\/dist\/vue-chartkick.min.js&gt;\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;<\/code><\/pre>\n<\/div>\n<p>Then we can make a minor modification to our Vue app so it uses the Chartkick line chart component instead of VueChartJs.<\/p>\n<p><em>index.html<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-html\">&lt;div id=\"app\"&gt;\n  &lt;line-chart v-if=\"serverData\" :data=\"serverData\"&gt;&lt;\/line-chart&gt;\n&lt;\/div&gt;\n&lt;script type=\"text\/javascript\"&gt;\nnew Vue({\n  el: \"#app\",\n  data: () =&gt; ({\n    serverData: []\n  }),\n  async mounted () {\n    const res = await fetch(\"\/data\");\n    this.serverData = await res.json();\n  }\n})\n&lt;\/script&gt;<\/code><\/pre>\n<\/div>\n<p>At this point, our Vue app should look the same as it did before, only now we&#8217;re using the more flexible Chartkick library.<\/p>\n<h2>Adding a resolution selector<\/h2>\n<p>Currently, our Vue app requests a time-series data payload from the server which always has the same time basis: seconds.<\/p>\n<p>To allow a user to see the monitor on an hourly or minute basis instead, we&#8217;re going to add an HTML select element to our app template which will allow the user to select a different time basis.<\/p>\n<p>Note that we have an option for a seconds, minutes, or hours time basis. Plus, we have a <code>v-model<\/code> bound to a variable <code>resolution<\/code> so that we can easily get the selected value in our Vue app.<\/p>\n<p><em>index.html<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-html\">&lt;div id=\"app\"&gt;\n  &lt;div&gt;\n    &lt;line-chart v-if=\"serverData\" :data=\"serverData\"&gt;&lt;\/line-chart&gt;\n    &lt;select name=\"resolution\" class=\"resolution-select\" v-model=\"resolution\"&gt;\n      &lt;option value=\"seconds\"&gt;Seconds&lt;\/option&gt;\n      &lt;option value=\"minutes\"&gt;Minutes&lt;\/option&gt;\n            &lt;option value=\"hours\"&gt;Hours&lt;\/option&gt;\n    &lt;\/select&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p>Let&#8217;s now add the new <code>resolution<\/code> reactive data property to the Vue instance and give it a default value of <code>seconds<\/code>.<\/p>\n<p><em>index.html<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">new Vue({\n  el: \"#app\",\n  data: () => ({\n    serverData: [],\n    resolution: 'seconds'\n  }),\n  ...\n})<\/code><\/pre>\n<\/div>\n<p>We can also add some CSS to the document head to style the select little better,<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-html\">&lt;style&gt;\n  .resolution-select {\n    margin: 2rem 0 0 1rem;\n    padding: 0.5rem;\n  }\n&lt;\/style&gt;<\/code><\/pre>\n<\/div>\n<p>With that done, we now see the selector below the chart.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2021\/11\/ss_seconds.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2021\/11\/ss_seconds.png\" alt=\"\" width=\"2560\" height=\"766\" class=\"aligncenter size-full wp-image-27902\" srcset=\"\/wp-content\/uploads\/2021\/11\/ss_seconds.png 2560w, \/wp-content\/uploads\/2021\/11\/ss_seconds-300x90.png 300w, \/wp-content\/uploads\/2021\/11\/ss_seconds-1024x306.png 1024w, \/wp-content\/uploads\/2021\/11\/ss_seconds-768x230.png 768w, \/wp-content\/uploads\/2021\/11\/ss_seconds-1536x460.png 1536w, \/wp-content\/uploads\/2021\/11\/ss_seconds-2048x613.png 2048w, \/wp-content\/uploads\/2021\/11\/ss_seconds-600x180.png 600w\" sizes=\"(max-width: 2560px) 100vw, 2560px\" \/><\/a><\/p>\n<h2>Reloading data on select change<\/h2>\n<p>When the user selects a different resolution value, the Vue app should call the server for a new data payload. Currently, the data is only requested when the app is mounted.<\/p>\n<p>To allow this, we&#8217;re going to create a method <code>getServerData<\/code> which will contain the logic for calling the server we had before.<\/p>\n<p>We&#8217;re now going to call this method in the mounted hook, so we get data when the app is initialized. But we&#8217;ll also call it whenever the value of <code>resolution<\/code> changes. We can do this by using a <code>watch<\/code> function which is called whenever the reactive value changes.<\/p>\n<p><em>index.html<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">new Vue({\n  el: \"#app\",\n  data: () => ({\n    serverData: [],\n    resolution: 'seconds'\n  }),\n  methods: {\n    async getServerData() {\n      const res = await fetch(\"\/data\");\n      this.serverData = await res.json();\n    }\n  },\n  watch: {\n    resolution() {\n      this.getServerData();\n    }\n  },\n  mounted () {\n    this.getServerData();\n  }\n})<\/code><\/pre>\n<\/div>\n<h2>Passing resolution value to the server<\/h2>\n<p>The next step is to pass the user&#8217;s chosen resolution to the server so that the server can return the correct data.<\/p>\n<p>To do this, we&#8217;re going to change our fetch request to be a <code>POST<\/code> type and send the resolution value as part of a JSON payload in the request body. We can do this by passing a config object to the <code>fetch<\/code> API. This object will have a <code>method<\/code> of <code>POST<\/code>, a <code>headers<\/code> sub-object with <code>Content-Type<\/code> of <code>application\/json<\/code> and a <code>body<\/code> property to which we create a JSON string containing the resolution value.<\/p>\n<p><em>index.html<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">async getServerData() {\n  const res = await fetch(\"\/data\", {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\/json'\n    },\n    body: JSON.stringify({ resolution: this.resolution })\n  });\n  this.serverData = await res.json();\n}<\/code><\/pre>\n<\/div>\n<h2>Handling POST with Express<\/h2>\n<p>Previously, our Express server was returning the time-series data when a GET request to <code>\/data<\/code> was received.<\/p>\n<p>Now, we want to use the POST verb so that we can receive the <code>resolution<\/code> parameter in a JSON payload. To allow for this, we&#8217;ll first add the JSON middleware to the Express server so it has this capability.<\/p>\n<p><em>server.js<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">app.use(express.json());<\/code><\/pre>\n<\/div>\n<p>Next, we&#8217;ll change the <em>GET \/data<\/em> route to <em>POST \/data<\/em>. We&#8217;ll then be able to pass the resolution paramater, which will be a property of the <code>req.body<\/code> object, to <code>getLatestRows<\/code>. This is the method we created to query data from GridDB.<\/p>\n<p><em>server.js<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">\/* Before *\/\napp.get('\/data', async (req, res) => {\n  const rows = await container.getLatestRows();\n});\n\n\/* After *\/\napp.post('\/data', async (req, res) => {\n  const rows = await container.getLatestRows(req.body.resolution);\n  res.send(rows);\n});<\/code><\/pre>\n<\/div>\n<h2>Time sampling queries<\/h2>\n<p>In the previous tutorial, we made it so that a snapshot of the server memory is taken every second the server is running.<\/p>\n<p>The concept of the <code>getLatestRows<\/code> function is that we use a query to get the last 5 minutes of data and return that as an array.<\/p>\n<p><em>db.js<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">const getLatestRows = (container) => async () => {\n  try {\n    const query = container.query(\"select * where timestamp > TIMESTAMPADD(MINUTE, NOW(), -5)\");\n    const rowset = await query.fetch();\n    const data = [];\n    while (rowset.hasNext()) {\n      data.push(rowset.next());\n    }\n    return data;\n  } catch(err) {\n    console.log(err);\n  }\n}<\/code><\/pre>\n<\/div>\n<p>Now we&#8217;re passing the <code>resolution<\/code> parameter to this function. We can use this to tell GridDB to get samples of the data on a minute or hour basis rather than just on a second basis.<\/p>\n<p>To do this, we&#8217;re going to use GridDB&#8217;s <a href=\"http:\/\/www.toshiba-sol.co.jp\/en\/pro\/griddb\/docs-en\/v4_3\/GridDB_TQL_Reference.html#time_samplingcolumn-timestamp_start-timestamp_end-interval-dayhourminutesecondmillisecond\">TIME_SAMPLING<\/a> function which will return averages of time-series data at a specified interval over a given range.<\/p>\n<p>So let&#8217;s use <code>TIME_SAMPLE<\/code> in a <code>select<\/code> statement on our database. The first argument is the data we want sampled. In this case, that will be <code>freeMemPercentage<\/code>.<\/p>\n<p>The second argument is the beginning of the range. The third argument is the end of the range. In this case, we want to begin an hour previous to the query, which we can do by subtracting 60 minutes from the current time, <code>TIMESTAMPADD(MINUTE, NOW(), -60)<\/code> and end at the current time, <code>NOW()<\/code>.<\/p>\n<p>The fourth argument is the interval you want to sample on and the fifth argument is the time basis. In this case, we&#8217;re taking samples every 1 minute. select TIME_SAMPLING(freeMemPercentage, TIMESTAMPADD(MINUTE, NOW(), -60), NOW(), 1, MINUTE)<\/p>\n<p>Let&#8217;s now modify the <code>getLatestRows<\/code> function so that the query will be dependent on the resolution parameter we send. We&#8217;ll use a switch statement for this and use a query similar to the one above.<\/p>\n<p><em>db.js<\/em><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">const getLatestRows = (container) => async (resolution) => {\n  try {\n    let tql;\n    switch(resolution) {\n      case 'hours':\n        tql = \"select TIME_SAMPLING(freeMemPercentage, TIMESTAMPADD(HOUR, NOW(), -24), NOW(), 1, HOUR)\"\n        break;\n      case 'minutes':\n        tql = \"select TIME_SAMPLING(freeMemPercentage, TIMESTAMPADD(MINUTE, NOW(), -60), NOW(), 1, MINUTE)\"\n        break;\n      default:\n        tql = \"select TIME_SAMPLING(freeMemPercentage, TIMESTAMPADD(MINUTE, NOW(), -1), NOW(), 1, SECOND)\"\n    }\n    const query = container.query(tql);\n    ...\n  }\n  ...\n}<\/code><\/pre>\n<\/div>\n<p>With that done, GridDB will return data at the correct resolution. We can go and test this in the browser now.<\/p>\n<p>Here&#8217;s what we see when selecting &#8220;seconds&#8221; as the time basis:<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2021\/11\/ss_seconds.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2021\/11\/ss_seconds.png\" alt=\"\" width=\"2560\" height=\"766\" class=\"aligncenter size-full wp-image-27902\" srcset=\"\/wp-content\/uploads\/2021\/11\/ss_seconds.png 2560w, \/wp-content\/uploads\/2021\/11\/ss_seconds-300x90.png 300w, \/wp-content\/uploads\/2021\/11\/ss_seconds-1024x306.png 1024w, \/wp-content\/uploads\/2021\/11\/ss_seconds-768x230.png 768w, \/wp-content\/uploads\/2021\/11\/ss_seconds-1536x460.png 1536w, \/wp-content\/uploads\/2021\/11\/ss_seconds-2048x613.png 2048w, \/wp-content\/uploads\/2021\/11\/ss_seconds-600x180.png 600w\" sizes=\"(max-width: 2560px) 100vw, 2560px\" \/><\/a><\/p>\n<p>Here&#8217;s what we see when selecting &#8220;minutes&#8221;:<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2021\/11\/ss_minutes.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2021\/11\/ss_minutes.png\" alt=\"\" width=\"2560\" height=\"764\" class=\"aligncenter size-full wp-image-27901\" srcset=\"\/wp-content\/uploads\/2021\/11\/ss_minutes.png 2560w, \/wp-content\/uploads\/2021\/11\/ss_minutes-300x90.png 300w, \/wp-content\/uploads\/2021\/11\/ss_minutes-1024x306.png 1024w, \/wp-content\/uploads\/2021\/11\/ss_minutes-768x229.png 768w, \/wp-content\/uploads\/2021\/11\/ss_minutes-1536x458.png 1536w, \/wp-content\/uploads\/2021\/11\/ss_minutes-2048x611.png 2048w\" sizes=\"(max-width: 2560px) 100vw, 2560px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>To improve a chart of time-series data we can let the user choose the time basis or &#8220;resolution&#8221; e.g. seconds, minutes, hours, etc. This way, they can see look for micro-trends in the data (by using high resolution e.g. seconds) or look for broader macro-trends in the same data (by using low resolution, e.g. hours). [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":27928,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46676","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>Time-Sampled Data Visualization with VueJS and GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"To improve a chart of time-series data we can let the user choose the time basis or &quot;resolution&quot; e.g. seconds, minutes, hours, etc. This way, they can see\" \/>\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\/time-sampled-data-visualization-with-vuejs-and-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Time-Sampled Data Visualization with VueJS and GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"To improve a chart of time-series data we can let the user choose the time basis or &quot;resolution&quot; e.g. seconds, minutes, hours, etc. This way, they can see\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/\" \/>\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=\"2021-12-03T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:55:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2021\/11\/vuejs.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1160\" \/>\n\t<meta property=\"og:image:height\" content=\"653\" \/>\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=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Time-Sampled Data Visualization with VueJS and GridDB\",\"datePublished\":\"2021-12-03T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:55:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/\"},\"wordCount\":1047,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2021\/11\/vuejs.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/\",\"name\":\"Time-Sampled Data Visualization with VueJS and GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2021\/11\/vuejs.png\",\"datePublished\":\"2021-12-03T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:55:41+00:00\",\"description\":\"To improve a chart of time-series data we can let the user choose the time basis or \\\"resolution\\\" e.g. seconds, minutes, hours, etc. This way, they can see\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2021\/11\/vuejs.png\",\"contentUrl\":\"\/wp-content\/uploads\/2021\/11\/vuejs.png\",\"width\":1160,\"height\":653},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb.net\/en\/#website\",\"url\":\"https:\/\/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:\/\/griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/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:\/\/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:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/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:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Time-Sampled Data Visualization with VueJS and GridDB | GridDB: Open Source Time Series Database for IoT","description":"To improve a chart of time-series data we can let the user choose the time basis or \"resolution\" e.g. seconds, minutes, hours, etc. This way, they can see","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\/time-sampled-data-visualization-with-vuejs-and-griddb\/","og_locale":"en_US","og_type":"article","og_title":"Time-Sampled Data Visualization with VueJS and GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"To improve a chart of time-series data we can let the user choose the time basis or \"resolution\" e.g. seconds, minutes, hours, etc. This way, they can see","og_url":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2021-12-03T08:00:00+00:00","article_modified_time":"2025-11-13T20:55:41+00:00","og_image":[{"width":1160,"height":653,"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2021\/11\/vuejs.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":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Time-Sampled Data Visualization with VueJS and GridDB","datePublished":"2021-12-03T08:00:00+00:00","dateModified":"2025-11-13T20:55:41+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/"},"wordCount":1047,"commentCount":0,"publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2021\/11\/vuejs.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/","url":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/","name":"Time-Sampled Data Visualization with VueJS and GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2021\/11\/vuejs.png","datePublished":"2021-12-03T08:00:00+00:00","dateModified":"2025-11-13T20:55:41+00:00","description":"To improve a chart of time-series data we can let the user choose the time basis or \"resolution\" e.g. seconds, minutes, hours, etc. This way, they can see","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/time-sampled-data-visualization-with-vuejs-and-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2021\/11\/vuejs.png","contentUrl":"\/wp-content\/uploads\/2021\/11\/vuejs.png","width":1160,"height":653},{"@type":"WebSite","@id":"https:\/\/griddb.net\/en\/#website","url":"https:\/\/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:\/\/griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/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:\/\/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:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/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:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/comments?post=46676"}],"version-history":[{"count":1,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46676\/revisions"}],"predecessor-version":[{"id":51350,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46676\/revisions\/51350"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media\/27928"}],"wp:attachment":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media?parent=46676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/categories?post=46676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/tags?post=46676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}