{"id":1768,"date":"2017-01-24T14:09:13","date_gmt":"2017-01-24T14:09:13","guid":{"rendered":"http:\/\/mindfusion.eu\/blog\/?p=1768"},"modified":"2021-01-21T14:09:25","modified_gmt":"2021-01-21T14:09:25","slug":"a-funnel-chart-in-javascript","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/a-funnel-chart-in-javascript\/","title":{"rendered":"A Funnel Chart in JavaScript"},"content":{"rendered":"<p>In this blog post we will create a funnel chart that demonstrates education enrollment. We will use the JavaScript chart library.<\/p>\n<p><strong>I. Chart Setup.<\/strong><\/p>\n<p>The Charting library requires a few JavaScript files, which we copy in a folder named Scripts. The files are:<\/p>\n<ul>\n<li>config.js<\/li>\n<li>MindFusion.Charting.js<\/li>\n<li>MindFusion.Common.js<\/li>\n<li>MindFusion.Gauges.js<\/li>\n<li>require.js<\/li>\n<\/ul>\n<p>Those files are redistributed with the chart library. If you plan to use different directory structure in your project you must edit the config.js file.<\/p>\n<p>Now we create two files &#8211; an HTML page FunnelChart.html and a funnelchart.js file, which will contain the code for the chart. In the FunnelChart.html file we add two references:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">script<\/span> <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">text\/javascript<\/a>\" <span class=\"attribute-name\">src<\/span>=\"<a class=\"attribute-value\" href=\"view-source:https:\/\/mindfusion.dev\/blog\/a-funnel-chart-in-javascript\/Scripts\/config.js\">Scripts\/config.js<\/a>\"&gt;&lt;\/<span class=\"end-tag\">script<\/span>&gt;\n<span id=\"line259\"><\/span>&lt;<span class=\"start-tag\">script<\/span> <span class=\"attribute-name\">data-main<\/span>=\"<a class=\"attribute-value\">funnelchart<\/a>\" <span class=\"attribute-name\">src<\/span>=\"<a class=\"attribute-value\" href=\"view-source:https:\/\/mindfusion.dev\/blog\/a-funnel-chart-in-javascript\/Scripts\/require.js\">Scripts\/require.js<\/a>\"&gt;&lt;\/<span class=\"end-tag\">script<\/span>&gt;<\/pre>\n<p>One to the config file and the other to the require.js file. Note that the data-main attribute points exactly to the name of the javascript code-behind file that we&#8217;ll use to create and customize the chart.<\/p>\n<p><strong>II. Create the Chart<\/strong><\/p>\n<p>The chart needs a canvas and we add one to the web page:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">canvas<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">funnelChart<\/a>\" <span class=\"attribute-name\">width<\/span>=\"<a class=\"attribute-value\">400<\/a>\" <span class=\"attribute-name\">height<\/span>=\"<a class=\"attribute-value\">500<\/a>\"&gt;&lt;\/<span class=\"end-tag\">canvas<\/span>&gt;<\/pre>\n<p>The size determines the size of the chart, the id is important because we&#8217;ll use it to access the canvas from code.<\/p>\n<p>The code for each JavaScript chart is in a single method:<\/p>\n<pre>define([\"require\", \"exports\", 'MindFusion.Charting'], function (require, exports, m) {\n    \"use strict\";\n    var Charting = m.MindFusion.Charting;\n    var Controls = m.MindFusion.Charting.Controls;\n    var Collections = m.MindFusion.Charting.Collections;\n    var Drawing = m.MindFusion.Charting.Drawing;\n\n    \/\/create the chart\n    var funnelChartEl = document.getElementById('funnelChart');\n\t\n    var funnelChart = new Controls.FunnelChart(funnelChartEl);\n\n     .......\n     \/\/chart customization\n     .......\n     .......\n     funnelChart.draw();\n});\n<\/pre>\n<p>\u00a0<\/p>\n<p>The chart object is created with the help of the <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_Controls_FunnelChart.htm\">FunnelChart<\/a> canvas element, which we get from the html page using the id.<\/p>\n<p><strong>III. Data<\/strong><\/p>\n<p>Data for the funnel chart is a single list with values. That is why we use the <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_SimpleSeries_0.htm\">SimpleSeries<\/a> class. It takes two arguments &#8211; one list with the data and one with the labels. We initialize the two arrays:<\/p>\n<pre>\/\/initialize data and labels\nvar data = new Collections.List([100, 90, 80, 37, 17, 7]);\nvar labels = new Collections.List([\"Elementary school\", \"Middle School\", \"High school\", \"Bachelor\", \"Master\", \"Doc\"]);\n<\/pre>\n<p>\u00a0<\/p>\n<p>Then we create the series and assign it to the series property of the funnelChart object.<\/p>\n<pre>\/\/assign a series\nfunnelChart.series = new Charting.SimpleSeries(data, labels); \n<\/pre>\n<p>\u00a0<\/p>\n<p><strong>IV. Appearance Customization<\/strong><\/p>\n<p>We don&#8217;t need a legend for the chart that is why we set:<\/p>\n<pre>funnelChart.showLegend = false;\n<\/pre>\n<p>\u00a0<\/p>\n<p>A chart needs a title and we set one:<\/p>\n<pre>funnelChart.title = \"Education Enrollment\";\n<\/pre>\n<p>\u00a0<\/p>\n<p>MindFusion JavaScript chart library has a flexible styling model, which allows us to customize the pens and brushes of a chart either directly through the theme property or through styles. A combination of both is possible and that&#8217;s what we&#8217;ll use. First, we will use the <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_PerElementSeriesStyle_0.htm\">PerElementSeriesStyle<\/a> for coloring the chart element. This style uses each of the Brush-es that were added to it to paint just one element from the chart. If necessary, the control cycles through the provided <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_Drawing_Brush.htm\">Brush<\/a> -es.<\/p>\n<pre>var brushes = new Collections.List([\t\n\tnew Drawing.Brush(\"#193e4e\"),\n        new Drawing.Brush(\"#5a7444\"),\n        new Drawing.Brush(\"#8eb848\"),\n        new Drawing.Brush(\"#678b99\"),\n        new Drawing.Brush(\"#a1d0d8\"),\n        new Drawing.Brush(\"#c5b28a\"),\n\t\t\n\t]);\n\t\n\tvar seriesBrushes = new Collections.List();\n\tseriesBrushes.add(brushes);\n<\/pre>\n<p>\u00a0<\/p>\n<p>The <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_PerElementSeriesStyle_0.htm\">PerElementSeriesStyle<\/a> expects a nested list with Brushes &#8211; because a chart can have many series with many elements into it. The same is true for the strokes, but we will add just one Brush, because we want all elements to have one common outlinig:<\/p>\n<pre>var strokes = new Collections.List([\n\tnew Drawing.Brush(\"#f2ebcf\"),\n        ]);\n\t\nvar seriesStrokes = new Collections.List();\nseriesStrokes.add(strokes);\n<\/pre>\n<p>\u00a0<\/p>\n<p>We repeat the process for StrokeThickness-es and then we create the style object:<\/p>\n<pre>funnelChart.plot.seriesStyle = new Charting.PerElementSeriesStyle(seriesBrushes, seriesStrokes, serieStrokeThicknesses);\n<\/pre>\n<p>\u00a0<\/p>\n<p>The theme property exposes many fields that help us customize our chart. We adjust the font and change the highlight stroke, which renders when a chart element is selected:<\/p>\n<pre>funnelChart.theme.titleFontSize = 18;\nfunnelChart.theme.titleFontName = \"Roboto\";\nfunnelChart.theme.titleFontStyle = Drawing.FontStyle.Bold;\n\t\nfunnelChart.theme.dataLabelsFontName = \"Roboto\";\nfunnelChart.theme.dataLabelsFontSize = 14;\n\t\nfunnelChart.theme.highlightStroke = new Drawing.Brush(\"#ffcc33\");\n<\/pre>\n<p>\u00a0<\/p>\n<p><strong>V. Tooltips<\/strong><\/p>\n<p>We want our chart to render tooltips. The <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_SimpleSeries_0.htm\">SimpleSeries<\/a> does not include tooltips by default and we must do some code twisting to make it show them. First, we create a field tooltips, that is assigned to a list with the desired tooltips:<\/p>\n<pre>var tooltips = new Collections.List([\"32.7%\", \"29.5%\", \"26.2%\", \"12%\", \"5%\", \"2%\"]);\nfunnelChart.series.tooltips = tooltips; \n<\/pre>\n<p>\u00a0<\/p>\n<p>Then we have to override the <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Series_supportedLabels_0_0.htm\">supportedLabels<\/a> property of the Series class to make it return LabelKinds.ToolTip in addition to <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_LabelKinds_0.htm\">LabelKinds<\/a>.InnerLabel.<\/p>\n<pre>Object.defineProperty(m.MindFusion.Charting.SimpleSeries.prototype, \"supportedLabels\", {\n            get: function () { return m.MindFusion.Charting.LabelKinds.InnerLabel | m.MindFusion.Charting.LabelKinds.ToolTip; },\n            enumerable: true,\n            configurable: true\n });\n<\/pre>\n<p>\u00a0<\/p>\n<p>Finally, we must return the appropriate tooltip and the appropriate label, when asked. This is done by overriding the getLabel method of the <a href=\"http:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_SimpleSeries_0.htm\">SimpleSeries<\/a> class.<\/p>\n<pre>m.MindFusion.Charting.SimpleSeries.prototype.getLabel = function (index, kind) {\n\tif ((kind &amp; m.MindFusion.Charting.LabelKinds.ToolTip) != 0 &amp;&amp; this.tooltips)\n\t\treturn this.tooltips.items()[index];\n\t\n\tif (this.labels == null)\n\t\treturn null;\n\treturn this.labels.items()[index];\n};\n\n<\/pre>\n<p>\u00a0<\/p>\n<p>With that the work on our funnel chart is done and we can enjoy the result:<\/p>\n<div id=\"attachment_1773\" style=\"width: 476px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/01\/javascript-funnel-chart.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1773\" class=\"size-full wp-image-1773\" src=\"http:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/01\/javascript-funnel-chart.png\" alt=\"A Funnel chart in JavaScript\" width=\"466\" height=\"525\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/01\/javascript-funnel-chart.png 466w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/01\/javascript-funnel-chart-266x300.png 266w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/a><p id=\"caption-attachment-1773\" class=\"wp-caption-text\">A Funnel chart in JavaScript<\/p><\/div>\n<p>Complete source code including the libraries is available for direct download from the link below:<\/p>\n<p align=\"center\"><a href=\"https:\/\/mindfusion.dev\/samples\/javascript\/chart\/FunnelChart.zip\">Download the Funnel Chart Sample<\/a><\/p>\n<p><em>About MindFusion JavaScript Chart Library:<\/em> MindFusion JS Chart is an interactive library for charts and gauges written purely in <a href=\"http:\/\/www.javascript.com\">JavaScript<\/a>. It supports all common chart types, multiple series, custom data,financial charts, funnel charts, a large selection of gauges and rich styling capabilities. The elegant architecture of the library allows you to create dashboards, charts with multiple different types of series in a single plot, unlimited number of axes, reusable styling themes, various oval and linear gauges. The innovative approach to data lets you define your own data classes by implementing a single interface.<br \/>The library also boasts a rich event set, zoom, pan, dragging of the legend and a set of many popular gauges. It is designed and implemented to provide JS developers with the perfect tool to create beautiful, interactive dashboards fast and easy. Download trial directly at <a href=\"https:\/\/mindfusion.dev\/JavaScript.Chart.zip\">http:\/\/mindfusion.dev\/JavaScript.Chart.zip<\/a> Get your license today at <a href=\"http:\/\/www.mindfusion.dev\/javascript-chart-buy.html\">http:\/\/www.javascript-chart-buy.html<\/a><\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post we will create a funnel chart that demonstrates education enrollment. We will use the JavaScript chart library. I. Chart Setup. The Charting library requires a few JavaScript files, which we copy in a folder named Scripts. &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/a-funnel-chart-in-javascript\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"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":true,"_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":[61,74],"tags":[425,443,453],"class_list":["post-1768","post","type-post","status-publish","format-standard","hentry","category-charting-2","category-sample-code","tag-javascript-chart","tag-javascript-chart-library","tag-javascript-funnel-chart"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-sw","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/1768","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\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=1768"}],"version-history":[{"count":7,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/1768\/revisions"}],"predecessor-version":[{"id":2615,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/1768\/revisions\/2615"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=1768"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=1768"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=1768"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}