{"id":43774,"date":"2026-02-20T15:14:13","date_gmt":"2026-02-20T09:44:13","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=43774"},"modified":"2026-02-20T15:14:13","modified_gmt":"2026-02-20T09:44:13","slug":"creating-engaging-animated-line-charts-in-power-bi-with-custom-visuals","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2026\/02\/creating-engaging-animated-line-charts-in-power-bi-with-custom-visuals\/","title":{"rendered":"Creating Engaging, Animated Line Charts in Power BI with Custom Visuals"},"content":{"rendered":"<p><img decoding=\"async\" class=\"alignnone size-full wp-image-43775\" style=\"border: 1px solid #000000; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1.png\" alt=\"Custom Visuals (pbiviz + D3.js )\" width=\"2100\" height=\"1200\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1.png 2100w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1-300x171.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1-1024x585.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1-768x439.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1-1536x878.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1-2048x1170.png 2048w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/How-to-Reduce-AI-Testing-Risk-in-Dynamics-365-Using-Copilot-Studio-1-660x377.png 660w\" sizes=\"(max-width: 2100px) 100vw, 2100px\" \/><\/p>\n<p>Power BI provides powerful built-in visuals, but sometimes you need custom behavior\u2014such as animated line transitions when filters change. In this blog, we\u2019ll build a custom animated line chart using pbiviz, TypeScript, and D3.js.<\/p>\n<p>By the end of this article, you\u2019ll know how to:<\/p>\n<ul>\n<li>Create a custom Power BI visual using <strong>pbiviz<\/strong><\/li>\n<li>Bind categorical data dynamically<\/li>\n<li>Animate line transitions when filters or slicers change<\/li>\n<li>Package and import a .pbiviz file into Power BI Desktop<\/li>\n<\/ul>\n<h3><strong>Why Custom Visual Animation?<\/strong><\/h3>\n<p>Native Power BI line charts don\u2019t provide fine-grained animation control. With a custom visual, you can:<\/p>\n<ul>\n<li>Animate lines smoothly on filter change<\/li>\n<li>Highlight trends more clearly<\/li>\n<li>Create interactive storytelling dashboards<\/li>\n<\/ul>\n<p><strong>Prerequisites<\/strong><\/p>\n<p>Before we begin, ensure you have:<\/p>\n<ul>\n<li>Node.js (LTS)<\/li>\n<li>Power BI Desktop<\/li>\n<li>pbiviz CLI<\/li>\n<li>Basic knowledge of TypeScript and D3.js<\/li>\n<\/ul>\n<p>Install pbiviz:<\/p>\n<p>npm install -g powerbi-visuals-tools<\/p>\n<p><strong>Step 1: Create the Custom Visual Project<\/strong><\/p>\n<p>pbiviz new animatedLineChart<\/p>\n<p>cd animatedLineChart<\/p>\n<p>pbiviz start<\/p>\n<p>This scaffolds a Power BI custom visual project with:<\/p>\n<ul>\n<li>visual.ts<\/li>\n<li>capabilities.json<\/li>\n<li>visual.less<\/li>\n<\/ul>\n<p><strong>\u00a0Step 2: Define Data Roles in capabilities.json<\/strong><\/p>\n<pre class=\"lang:css gutter:true start:1\">{\r\n\r\n\"dataRoles\": [\r\n\r\n{\r\n\r\n\"name\": \"category\",\r\n\r\n\"kind\": \"Grouping\",\r\n\r\n\"displayName\": \"X-Axis\"\r\n\r\n},\r\n\r\n{\r\n\r\n\"name\": \"values\",\r\n\r\n\"kind\": \"Measure\",\r\n\r\n\"displayName\": \"Y-Axis\"\r\n\r\n}\r\n\r\n],\r\n\r\n\"dataViewMappings\": [\r\n\r\n{\r\n\r\n\"categorical\": {\r\n\r\n\"categories\": {\r\n\r\n\"for\": { \"in\": \"category\" }\r\n\r\n},\r\n\r\n\"values\": {\r\n\r\n\"select\": [{ \"bind\": { \"to\": \"values\" } }]\r\n\r\n}\r\n\r\n}\r\n\r\n}\r\n\r\n]\r\n\r\n}<\/pre>\n<p>This configuration allows users to drag:<\/p>\n<ul>\n<li>A <strong>date or category<\/strong> to the X-axis<\/li>\n<li>One or more <strong>measures<\/strong> to the Y-axis<\/li>\n<\/ul>\n<p><strong>Step 3: Create Scales Dynamically<\/strong><\/p>\n<pre class=\"lang:css gutter:true start:1\">const xScale = d3.scalePoint()\r\n\r\n.domain(data.map(d =&gt; d.category))\r\n\r\n.range([margin.left, width - margin.right]);\r\n\r\n\u00a0\r\n\r\nconst yScale = d3.scaleLinear()\r\n\r\n.domain([0, d3.max(data, d =&gt; d.value)!])\r\n\r\n.nice()\r\n\r\n.range([height - margin.bottom, margin.top]);<\/pre>\n<p>Scales update automatically when filters change.<\/p>\n<p><strong>Step 4: Animate Line Transitions<\/strong><\/p>\n<p>This is where the magic happens<\/p>\n<pre class=\"lang:css gutter:true start:1\">this.linePath\r\n\r\n.datum(this.data)\r\n\r\n.transition()\r\n\r\n.duration(800)\r\n\r\n.ease(d3.easeCubicInOut)\r\n\r\n.attr(\"d\", this.lineGenerator);<\/pre>\n<p>Every time a slicer or filter changes:<\/p>\n<ul>\n<li>Power BI calls update()<\/li>\n<li>The line smoothly animates to the new shape<\/li>\n<\/ul>\n<p><strong>Step 5: Handle Filter Changes<\/strong><\/p>\n<p>Power BI automatically triggers update() when:<\/p>\n<ul>\n<li>Slicers change<\/li>\n<li>Filters are applied<\/li>\n<li>Visual interactions occur<\/li>\n<\/ul>\n<p>No extra event handling is required\u2014just redraw using transitions.<\/p>\n<p><strong>Step 6: Add Styling &amp; Formatting<\/strong><\/p>\n<p>You can expose formatting options like:<\/p>\n<ul>\n<li>Line thickness<\/li>\n<li>Line color<\/li>\n<li>Animation duration<\/li>\n<li>Axis labels<\/li>\n<\/ul>\n<p>Using enumerateObjectInstances():<\/p>\n<pre class=\"lang:css gutter:true start:1\">instances.push({\r\n\r\nobjectName: \"lineSettings\",\r\n\r\nproperties: {\r\n\r\nlineWidth: this.settings.lineWidth\r\n\r\n},\r\n\r\nselector: null\r\n\r\n});<\/pre>\n<p><strong>\u00a0Step 7: Package and Import the Visual<\/strong><\/p>\n<p>pbiviz package<\/p>\n<p>This generates:<\/p>\n<p>dist\/animatedLineChart.pbiviz<\/p>\n<p>Import it into Power BI Desktop:<\/p>\n<ul>\n<li><strong>Visualizations \u2192 (\u2026) \u2192 Import a visual<\/strong><\/li>\n<\/ul>\n<h3><img decoding=\"async\" class=\"alignnone size-full wp-image-43778\" style=\"border: 1px solid #000000; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart.jpg\" alt=\"Creating Engaging, Animated Line Charts in Power BI \" width=\"1696\" height=\"1622\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart.jpg 1696w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart-300x287.jpg 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart-1024x979.jpg 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart-768x734.jpg 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart-1536x1469.jpg 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2026\/02\/Animated-Line-Chart-660x631.jpg 660w\" sizes=\"(max-width: 1696px) 100vw, 1696px\" \/><\/h3>\n<h3><strong>Conclusion:<\/strong><\/h3>\n<p>Animated line charts significantly enhance Power BI dashboards by making data transitions easier to follow especially when users interact with filters and slicers.<\/p>\n<p>By leveraging custom visuals with D3.js, organizations can:<\/p>\n<ul>\n<li>Improve visual continuity<\/li>\n<li>Reduce cognitive load during data exploration<\/li>\n<li>Support clearer discussions around trends and performance<\/li>\n<li>Enable more engaging executive dashboards<\/li>\n<\/ul>\n<p>This approach transforms dashboards from static reporting tools into dynamic, insight-driven experiences, making them particularly valuable for executive reviews, operational analysis, and advanced data storytelling.<\/p>\n<h3><strong>FAQs <\/strong><\/h3>\n<p><strong>Can Power BI create animated charts without custom visuals?<\/strong><\/p>\n<p>Native visuals offer limited animation control. For advanced animations, a custom visual built with pbiviz and D3.js is required.<\/p>\n<p><strong>Does Power BI automatically trigger updates on filter changes?<\/strong><\/p>\n<p>Yes. Power BI automatically calls the update() method whenever filters, slicers, or interactions modify the data context.<\/p>\n<p><strong>Is D3.js supported in Power BI custom visuals?<\/strong><\/p>\n<p>Yes. D3.js is commonly used inside Power BI custom visuals to create advanced SVG-based charts and animations.<\/p>\n<p><strong>Can this visual be published to the Power BI Service?<\/strong><\/p>\n<p>Yes. Once packaged, the .pbiviz file can be uploaded and used in both Power BI Desktop and Power BI Service reports.<\/p>\n<p><strong>Is animation performance impacted with large datasets?<\/strong><\/p>\n<p>Yes. For large datasets, you may need to optimize transitions and reduce DOM elements to maintain performance.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Power BI provides powerful built-in visuals, but sometimes you need custom behavior\u2014such as animated line transitions when filters change. In this blog, we\u2019ll build a custom animated line chart using pbiviz, TypeScript, and D3.js. By the end of this article, you\u2019ll know how to: Create a custom Power BI visual using pbiviz Bind categorical data\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2026\/02\/creating-engaging-animated-line-charts-in-power-bi-with-custom-visuals\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[3307,45,2361],"tags":[],"class_list":["post-43774","post","type-post","status-publish","format-standard","hentry","category-custom-visuals","category-power-bi","category-technical"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/43774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/comments?post=43774"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/43774\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=43774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=43774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=43774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}