{"id":3184,"date":"2026-10-05T11:51:18","date_gmt":"2026-10-05T11:51:18","guid":{"rendered":"https:\/\/mindfusion.dev\/blog\/?p=3184"},"modified":"2026-10-05T12:00:01","modified_gmt":"2026-10-05T12:00:01","slug":"building-a-high-performance-operations-dashboard-with-mindfusion-pack-for-javascript","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/building-a-high-performance-operations-dashboard-with-mindfusion-pack-for-javascript\/","title":{"rendered":"Building a High-Performance Operations Dashboard with MindFusion Pack for JavaScript"},"content":{"rendered":"<p>In this blog post we will create a product inventory and customer satisfaction dashboard in pure JavaScript with a data grid that spans over 10 000 rows and includes real-time bar chart and a KPI gauge. The data is generated dynamically. Here is the ready dashboard:<\/p>\n<p><a href=\"https:\/\/mindfusion.dev\/javascript-demo.html?sample=OperationsDashboard\" title=\"Operations Dashboard in pure JavaScript\"><img decoding=\"async\" src=\"https:\/\/mindfusion.dev\/samples\/javascript\/dashboard_javascript.jpeg\" title=\"Operational dashboard in pure JavaScript\" \/><\/a><\/p>\n<h3>Our sample features the following components:<\/h3>\n<ol>\n<li>MindFusion.DataViews (Grid): provides virtualized DOM rendering that handles 10,000 live rows with sorting, instant filtering, and inline editing.<\/li>\n<li>MindFusion.Charting: used to create an interactive bar chart that displays inventory stock units and financial valuation grouped by category.<\/li>\n<li>MindFusion.Gauges: the OvalGauge is customized to render a circular meter that indicas operational fulfillment rate with color-code zones according to stock availability.<\/li>\n<li>Dynamic Client-Side Dataset: A lightweight pseudo-random data generator producing 10,000 consistent records in ~18ms with no backend server required.<\/li>\n<\/ol>\n<p>The full source code for this sample is available on Mindfusion JavaScript GitHub Repository: <a href=\"https:\/\/github.com\/MindFusionComponents\/JavaScript-Dashboard-Samples\" title=\"JavaScript Dashboard Samples\">https:\/\/github.com\/MindFusionComponents\/JavaScript-Dashboard-Samples<\/a><\/p>\n<p><!--more--><\/p>\n<h2>Dashboard Architecture at a Glance<\/h2>\n<p>The dashboard uses the flex layout to arrange the DOM elements that are used by Mindfusion to render its components: Canvas elements for the chart and gauge and a DIV element for the data grid.<\/p>\n<ul>\n<li>Top Half (~50%): A full-width virtualized data grid with a search and filter toolbar.<\/li>\n<li>Bottom-Left (2\/3 width): An interactive canvas bar chart comparing stock volume and gross inventory valuation across categories, complete with metric toggles.<\/li>\n<li>Bottom-Right (1\/3 width): A dynamic gauge that indicates real-time fulfillment capacity alongside summary KPI stat cards.<\/li>\n<\/ul>\n<pre>\n+------------------------------------------------------------------------+\n| Search & Category Filter Toolbar | Items: 10,000 | Valuation: $2.5M   |\n+------------------------------------------------------------------------+\n|                                                                        |\n|  MindFusion DataViews (Grid): 10,000 Virtualized Rows                  |\n|  [#] [Product Name] [Category] [Price] [Stock] [Rating] [Restocked]    |\n|                                                                        |\n+---------------------------------------------------+--------------------+\n|  MindFusion Charting (BarChart)                   | MindFusion Gauges  |\n|  Inventory Stock & Valuation by Category          | Fulfillment Health |\n|  [Stock Units] [Valuation ($)]                    | (OvalGauge: 0-100%)|\n|  [==============================================]  | [ KPI Stat Cards ] |\n+---------------------------------------------------+--------------------+\n<\/pre>\n<h2>Step 1: Lightweight Client-Side Data Generation (data.js)<\/h2>\n<p>To demonstrate high-volume performance without requiring backend databases or multi-megabyte JSON payloads, we implemented a deterministic, seedable PRNG using the mulberry32 algorithm:<\/p>\n<pre>\n\/\/ data.js\nfunction mulberry32(a) {\n  return function () {\n    a |= 0; a = a + 0x6D2B79F5 | 0;\n    let t = Math.imul(a ^ a >>> 15, 1 | a);\n    t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;\n    return ((t ^ t >>> 14) >>> 0) \/ 4294967296;\n  };\n}\n\n\n\nconst categories = [\"Electronics\", \"Home\", \"Garden\", \"Sports\", \"Office\"];\nconst names = [\"Desk Lamp\", \"Monitor Stand\", \"Trail Backpack\", \"Garden Hose\", \"Wireless Mouse\"];\n\nfunction generateOrders(count, seed = 42) {\n  const rnd = mulberry32(seed);\n  const rows = [];\n  for (let i = 1; i <= count; i++) {\n    rows.push({\n      ID: i,\n      Product: names[Math.floor(rnd() * names.length)] + \" \" + (100 + Math.floor(rnd() * 900)),\n      Category: categories[Math.floor(rnd() * categories.length)],\n      Price: Math.round((5 + rnd() * 495) * 100) \/ 100,\n      Stock: Math.floor(rnd() * 500),\n      Rating: Math.round((1 + rnd() * 4) * 10) \/ 10,\n      Restocked: new Date(2026, Math.floor(rnd() * 12), 1 + Math.floor(rnd() * 28))\n    });\n  }\n  return rows;\n}\n<\/pre>\n<p>Generating 10,000 structured inventory records takes less than 18 milliseconds on modern browsers thus we have an instant launch of the sample loaded with data and no lag time on start.<\/p>\n<h2>Step 2: The Virtualized Data Grid (MindFusion.DataViews)<\/h2>\n<p>Standard HTML tables or naive grid components struggle once data volumes exceed a few hundred rows. MindFusion.DataViews uses DOM virtualization, rendering only the rows and cells currently visible inside the viewport.<\/p>\n<h3>Configuring Typed Columns<\/h3>\n<p>Each column is typed (IntegerType, StringType, LookupType, CurrencyType, RealNumberType, DateType), granting built-in data formatters, natural sorting algorithms, and the built-in inplace editors:<\/p>\n<pre>\nvar dv = MindFusion.DataViews;\nvar columns = [];\n\n\/\/ index\nvar colId = new dv.GridColumn(\"ID\");\ncolId.dataType = dv.IntegerType;\ncolId.caption = \"#\";\ncolId.editable = false;\ncolId.sortable = true;\ncolumns.push(colId);\n\n\/\/ product name\nvar colProduct = new dv.GridColumn(\"Product\");\ncolProduct.dataType = dv.StringType;\ncolProduct.caption = \"Product Name\";\ncolProduct.editable = true;\ncolProduct.sortable = true;\ncolumns.push(colProduct);\n\n\/\/ category - uses a dropdown\nvar colCategory = new dv.GridColumn(\"Category\");\ncolCategory.dataType = dv.LookupType;\ncolCategory.caption = \"Category\";\ncolCategory.editable = true;\ncolCategory.sortable = true;\ncolCategory.metaData.set(\"values\", categories.map(c => [c]));\ncolumns.push(colCategory);\n\n\/\/ price - format is currency\nvar colPrice = new dv.GridColumn(\"Price\");\ncolPrice.dataType = dv.CurrencyType;\ncolPrice.caption = \"Price\";\ncolPrice.editable = true;\ncolPrice.sortable = true;\ncolumns.push(colPrice);\n\n\/\/ stock level - integer\nvar colStock = new dv.GridColumn(\"Stock\");\ncolStock.dataType = dv.IntegerType;\ncolStock.caption = \"Stock Level\";\ncolStock.editable = true;\ncolStock.sortable = true;\ncolumns.push(colStock);\n\n\/\/ rstock data with date-time picker\n\/\/ ... (attached similarly)\n\n\/\/ initialize and bind the grid\nvar grid = new dv.Grid(document.getElementById(\"grid\"));\ngrid.theme = \"business\";\ngrid.model = new dv.ArrayModel(allOrders, columns, \"ID\");\ngrid.allowEdit = true;\ngrid.allowCellSelect = true;\ngrid.render();\n<\/pre>\n<ul>\n<li>Sorting: Click any column header to sort ascending or descending.<\/li>\n<li>Inline Editing: Double-click any cell to edit values directly with type-appropriate controls (e.g., datepicker calendar for dates, dropdown menus for categories, and formatted inputs for numbers).<\/li>\n<\/ul>\n<h2>Step 3: Executive KPI Gauge (MindFusion.Gauges)<\/h2>\n<p>For our operational KPI, we track the Fulfillment Rate, which is the percentage of catalog items with sufficient stock on hand.<\/p>\n<p>We use an OvalGauge with custom arc angles and colour-coded operational zones:<\/p>\n<pre>\nvar Gauges = MindFusion.Gauges;\nvar gauge = Gauges.OvalGauge.create(document.getElementById(\"gauge\"), false);\n\nvar scale = new Gauges.OvalScale(gauge);\nscale.minValue = 0;\nscale.maxValue = 100;\nscale.startAngle = 140;\nscale.endAngle = 400;\nscale.fill = \"transparent\";\nscale.stroke = \"#cbd5e1\";\nscale.scaleRelativeRadius = 0.68;\nscale.scaleRelativeCenter = new MindFusion.Drawing.Point(0.5, 0.52);\nscale.margin = new MindFusion.Drawing.Thickness(0.14, 0.14, 0.14, 0.14);\n\n\/\/ operational zones\nfunction addZone(min, max, color) {\n    var range = new Gauges.Range();\n    range.minValue = min;\n    range.maxValue = max;\n    range.fill = color;\n    range.stroke = \"transparent\";\n    range.startWidth = new Gauges.Length(6, Gauges.LengthType.Relative);\n    range.endWidth = new Gauges.Length(6, Gauges.LengthType.Relative);\n    scale.addRange(range);\n}\n\naddZone(0, 50, \"#ef4444\");   \/\/ critical - low stock (red)\naddZone(50, 80, \"#f59e0b\");  \/\/ moderate capacity (amber)\naddZone(80, 100, \"#10b981\"); \/\/ optimal fulfillment (green)\n\n\/\/ pointer\nvar pointer = new Gauges.Pointer();\npointer.pointerWidth = new Gauges.Length(62, Gauges.LengthType.Relative);\npointer.pointerHeight = new Gauges.Length(6, Gauges.LengthType.Relative);\npointer.shape = Gauges.PointerShape.Needle;\npointer.fill = \"#dc2626\";\npointer.stroke = \"#991b1b\";\nscale.addPointer(pointer);\n<\/pre>\n<p>Whenever the dataset changes, we update the gauge needle the following way:<\/p>\n<pre>\npointer.value = calculatedFulfillmentRate;\n<\/pre>\n<h2>Step 4: The Reactive Bar Chart<\/h2>\n<p>The inventory bar chart summarizes data across categories (Electronics, Home, Garden, Sports, Office). It supports two modes:<\/p>\n<ol>\n<li>Stock Units: Physical count of units on warehouse shelves.<\/li>\n<li>Inventory Valuation: Gross dollar value calculated as Stock * Price.<\/li>\n<\/ol>\n<pre>\nvar Charting = MindFusion.Charting;\nvar chartCanvas = document.getElementById(\"barChart\");\nvar chart = new Charting.Controls.BarChart(chartCanvas);\n\nchart.barLayout = Charting.BarLayout.SideBySide;\nchart.barSpacingRatio = 2;\nchart.showLegend = false;\nchart.xAxis.title = \"Category\";\nchart.yAxis.title = \"Stock Units\";\n\nfunction updateChart(categoryData, isValuationMode) {\n    var catValues = [];\n    var catLabels = [];\n    var brushes = [];\n\n    categoryList.forEach(category => {\n        var item = categoryData[category];\n        var val = isValuationMode ? Math.round(item.valuation) : item.stock;\n        catValues.push(val);\n        catLabels.push(category);\n        brushes.push(new MindFusion.Drawing.Brush(categoryPalette[category]));\n    });\n\n    \/\/ data labels displaying values under each bar\n    var barLabels = new MindFusion.Common.Collections.List(\n        catValues.map(v => isValuationMode ? \"$\" + (v \/ 1000).toFixed(1) + \"k\" : v.toLocaleString())\n    );\n\n    var barSeries = new Charting.BarSeries(\n        new MindFusion.Common.Collections.List(catValues),\n        null,\n        barLabels,\n        new MindFusion.Common.Collections.List(catLabels)\n    );\n    barSeries.supportedLabels = Charting.LabelKinds.XAxisLabel;\n\n    \/\/ add 18% headroom on Y-Axis so top labels never clip\n    var maxVal = Math.max(...catValues);\n    chart.yAxis.minValue = 0;\n    chart.yAxis.maxValue = Math.ceil(maxVal * 1.18);\n    chart.series = new MindFusion.Common.Collections.ObservableCollection([barSeries]);\n\n    \/\/ apply palette brushes per element\n    var seriesBrushes = new MindFusion.Common.Collections.List();\n    seriesBrushes.add(new MindFusion.Common.Collections.List(brushes));\n    chart.plot.seriesStyle = new Charting.PerElementSeriesStyle(seriesBrushes);\n\n    chart.draw();\n}\n<\/pre>\n<h2>Step 5: Connecting the Dots \u2014 Bi-Directional Interactivity<\/h2>\n<p>The real power of our operations dashboard is that all its components respond dynamically to every user interaction in real time:<\/p>\n<p><strong>1. Instant Filtering (grid.filter)<\/strong><br \/>\nMindFusion Grid provides a functional filter callback that executes on data evaluation without creating duplicate array clones:<\/p>\n<pre>\nfunction applyFilters() {\n    var searchVal = searchInput.value.trim().toLowerCase();\n    var catFilter = categoryFilter.value;\n    var stockFilterVal = stockFilter.value;\n\n    grid.filter = function (rowIdx, srcModel) {\n        var row = srcModel.getRowData(rowIdx);\n        if (!row) return false;\n\n        if (catFilter && row.Category !== catFilter) return false;\n\n        var stock = Number(row.Stock) || 0;\n        if (stockFilterVal === \"low\" && stock >= 50) return false;\n        if (stockFilterVal === \"optimal\" && (stock < 50 || stock > 300)) return false;\n        if (stockFilterVal === \"high\" && stock <= 300) return false;\n\n        if (searchVal &#038;&#038; row.Product.toLowerCase().indexOf(searchVal) === -1) {\n            return false;\n        }\n\n        return true;\n    };\n\n    updateDashboard(); \/\/ Recalculates metrics and redraws chart &#038; gauge!\n}\n<\/pre>\n<p><strong>2. Bi-Directional Chart Clicking<\/strong><br \/>\nClicking a bar on the chart automatically filters the grid to show only products in that category:<\/p>\n<pre>\nchart.dataItemClicked.addEventListener(function (sender, args) {<br \/>\n    if (args && args.index !== undefined) {<br \/>\n        var clickedCategory = categoryList[args.index];<br \/>\n        categoryFilter.value = (categoryFilter.value === clickedCategory) ? \"\" : clickedCategory;<br \/>\n        applyFilters();<br \/>\n    }<br \/>\n});\n<\/pre\n\n<strong>3. Row Selection & In-Line Edits<\/strong><\/p>\n<ul>\n<li>When a row is selected (grid.rowSelected), the chart highlights that item's category and dims the others.<\/li>\n<li>When any cell is modified inline (grid.rowUpdated), inventory totals recalculate immediately, moving the gauge pointer and adjusting bar heights on the fly.<\/li>\n<\/ul>\n<h2>Key Performance Takeaways<\/h2>\n<ul>\n<li>Zero Server Overhead: The entire dashboard runs 100% in the client's browser.<\/li>\n<li>Instant Virtualization: 10,000 rows scroll at a steady 60 frames per second because only the visible ~25 rows reside in the active DOM tree at any given moment.<\/li>\n<li>Pixel-Perfect Scaling: Using proper flexbox constraints and dynamic canvas buffer sizing (fitChartCanvas(), fitGaugeCanvas()), the layout adapts gracefully to full HD monitors, laptop screens, or mobile viewports without clipping.<\/li>\n<\/ul>\n<h2>Try It Yourself<\/h3>\n<p>Run online <a href=\"https:\/\/mindfusion.dev\/javascript-demo.html?sample=OperationsDashboard\" title=\"Operations Dashboard\">https:\/\/mindfusion.dev\/javascript-demo.html?sample=OperationsDashboard<\/a><br \/>\nDownload the sample: <a href=\"https:\/\/mindfusion.dev\/samples\/javascript\/applications\/OperationsDashboard.zip\" title=\"Operations Dashboard in pure JavaScript: download sample\">https:\/\/mindfusion.dev\/samples\/javascript\/applications\/OperationsDashboard.zip<\/a><\/p>\n<p>You can explore the live code, clone the project, or integrate MindFusion components into your own applications:<\/p>\n<ul>\n<li>Download MindFusion JsPack Free Trial: <a href=\"https:\/\/mindfusion.dev\/javascript-pack.html\" title=\"MindFusion Pack for JavaScript\">https:\/\/mindfusion.dev\/javascript-pack.html<\/a><\/li>\n<li>GitHub Corporate Repository: <a href=\"https:\/\/github.com\/MindFusionComponents\/JavaScript-Dashboard-Samples\" title=\"JavaScript Dashboard\">https:\/\/github.com\/MindFusionComponents\/JavaScript-Dashboard-Samples<\/a><\/li>\n<li>Online Documentation & Component Samples: <a href=\"https:\/\/mindfusion.dev\/docs\/javascript\/pack\/Introduction_19.htm\" title=\"JavaScript Pack: Online Documentation\">https:\/\/mindfusion.dev\/docs\/javascript\/pack\/Introduction_19.htm<\/a><\/li>\n<\/ul>\n<p>Have questions or recommendations? Reach out on our Community Forum: <a href=\"https:\/\/mindfusion.dev\/Forum\/YaBB.pl?board=jschart_disc\" title=\"Mindfusion JavaScript Dashboards Discussion Board\">https:\/\/mindfusion.dev\/Forum\/YaBB.pl?board=jschart_disc<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post we will create a product inventory and customer satisfaction dashboard in pure JavaScript with a data grid that spans over 10 000 rows and includes real-time bar chart and a KPI gauge. The data is generated &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/building-a-high-performance-operations-dashboard-with-mindfusion-pack-for-javascript\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[2],"tags":[],"class_list":["post-3184","post","type-post","status-publish","format-standard","hentry","category-product-releases"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-Pm","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/3184","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=3184"}],"version-history":[{"count":5,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/3184\/revisions"}],"predecessor-version":[{"id":3189,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/3184\/revisions\/3189"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=3184"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=3184"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=3184"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}