{"id":2789,"date":"2022-08-29T16:09:27","date_gmt":"2022-08-29T16:09:27","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=2789"},"modified":"2022-08-29T16:17:07","modified_gmt":"2022-08-29T16:17:07","slug":"custom-grid-drawing-in-charting-for-javascript","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/custom-grid-drawing-in-charting-for-javascript\/","title":{"rendered":"Custom Grid Drawing in Charting for JavaScript"},"content":{"rendered":"<p>In this blog post we will look in short at the steps to build this JavaScript area chart with custom grid:<\/p>\n<p><a href=\"https:\/\/mindfusion.dev\/samples\/javascript\/chart\/custom_grid.png\"><img decoding=\"async\" src=\"https:\/\/mindfusion.dev\/samples\/javascript\/chart\/custom_grid.png\" title=\"Line chart with custom grid\"><\/a><\/p>\n<p>The line chart uses <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_DateTimeSeries_Members_0.htm\" title=\"MindFusion Charting for JavaScript: DateTimeSeries\">DateTimeSeries<\/a> for the data and a standard <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_GridType_1.htm\" title=\"MindFusion Charting for JavaScript: GridType\">GridType<\/a> for the major grid lines. The auxiliary grid lines among them are made with custom drawing: we will discuss in details the code for that.<\/p>\n<p>The sample uses <a href=\"https:\/\/mindfusion.dev\/javascript-chart.html\" title=\"MindFusion JavaScript Chart Library\">MindFusion Charting library for JavaScript<\/a>, which also supports TypeScript.<\/p>\n<p>You can see the sample online at <a href=\"https:\/\/mindfusion.dev\/samples\/javascript\/chart\/CustomGrid\/DateTimeSeries.html\" title=\"Custom Grid Drawing in an Area Chart\">https:\/\/mindfusion.dev\/samples\/javascript\/chart\/CustomGrid\/DateTimeSeries.html<\/a><\/p>\n<p><!--more--><\/p>\n<p><strong>I. General Setup<\/strong><\/p>\n<p>The chart requires several JavaScript files to be included. These are:<\/p>\n<pre>&lt;script src=\"..\/Scripts\/drawing.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"..\/Scripts\/controls.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"..\/Scripts\/common.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"..\/Scripts\/common-collections.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"..\/Scripts\/charting.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n<\/pre>\n<p>We add them at the end of the web page, where we want to render the chart, straight before the closing BODY tag. The chart itsel needs a DIV element to render itself onto. It is important hat the DIV has an id. We add one to the web page:<\/p>\n<pre>&lt;div id=\"content\" style=\"top: 60px; bottom: 24px; overflow-y: scroll;\"&gt;\n\t&lt;div style=\"position: absolute; left: 0px; top: 0px; bottom: 0px; right: 0px\"&gt;\n\t\t&lt;canvas id=\"chart\" style=\"width: 100%; height: 100%; display: block;\"&gt;\n\t\t&lt;\/canvas&gt;\n\t&lt;\/div&gt;\n&lt;\/div&gt;\n<\/pre>\n<p><strong>II. Chart Initialization<\/strong><\/p>\n<p>We create the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?Chart_Controls_0.htm\" title=\"MindFusion Charting for JavaScript: Chart\">Chart<\/a> as an instance of the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_Controls_AreaChart_Members.htm\" title=\"MindFusion Charting for JavaScript: AreaChart\">AreaChart<\/a> class. First, we must get the HTML element that represents it and then we get its size. This element is used in the chart constructor &#8211; we cannot create any type of Chart without it:<\/p>\n<pre>var chartEl = document.getElementById('chart');\nchartEl.width = chartEl.offsetParent.clientWidth;\nchartEl.height = chartEl.offsetParent.clientHeight;\nvar chart = new Controls.AreaChart(chartEl);\n<\/pre>\n<p>The data for the chart is a <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_Series_0.htm\" title=\"MindFusion Charting for JavaScript: Series\">Series<\/a> instance. The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_Series_0.htm\" title=\"MindFusion Charting for JavaScript: Series\">Series<\/a> interface is implemented by various classes that allow you to choose the best one regarding your data type and project goals. In our case we use JavaScript Date objects as data for the X-axis, which is why we&#8217;ve chosen the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_DateTimeSeries_Members_0.htm\" title=\"MindFusion Charting for JavaScript: DateTimeSeries\">DateTimeSeries<\/a> to represent the data for our chart.<\/p>\n<pre>\/\/ create sample data\nvar data = new Collections.ObservableCollection();\n\nvar years = new Collections.List();\nvar dt = new Date(new Date().getFullYear() - 10, 11, 31);\nfor (; ; )\n{\n\tif (dt.getFullYear() &gt; new Date().getFullYear())\n\t\tbreak;\n\tyears.add(new Date(dt.setFullYear(dt.getFullYear() + 1)));\n}\n\nvar income = new Collections.List([52, 63.2, 35.6, 47.8, 39, 50, 29, 79, 101, 120, 112]);\n\nvar series = new Charting.DateTimeSeries(\n\tyears, income, years.item(0), years.item(years.count() - 1));\n<\/pre>\n<p>The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_DateTimeSeries_Members_0.htm\" title=\"MindFusion Charting for JavaScript: DateTimeSeries\">DateTimeSeries<\/a> instance has a variety of properties, including <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Axis_minValue_0_0.htm\" title=\"MindFusion Charting for JavaScript: minValue\">minValue<\/a> and <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Axis_maxValue_0_0.htm\" title=\"MindFusion Charting for JavaScript: maxValue,\">maxValue,<\/a> which we will set. They set the values that correspond to the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_DateTimeSeries_minDate_0_0.htm\" title=\"MindFusion Charting for JavaScript: MinDate\">MinDate<\/a> and <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_DateTimeSeries_maxDate_0_0.htm\" title=\"MindFusion Charting for JavaScript: MaxDate\">MaxDate<\/a> in the series. We also use the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_DateTimeSeries_dateTimeFormat_0_0.htm\" title=\"MindFusion Charting for JavaScript: dateTimeFormat\">dateTimeFormat<\/a> property and <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_DateTimeSeries_customDateTimeFormat_0_0.htm\" title=\"MindFusion Charting for JavaScript: customDateTimeFormat\">customDateTimeFormat<\/a> to further specify how our <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_DateTimeSeries_Members_0.htm\" title=\"MindFusion Charting for JavaScript: DateTimeSeries\">DateTimeSeries<\/a> shall look.<\/p>\n<p>Each chart <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_Axis_Members_0.htm\" title=\"MindFusion Charting for JavaScript: Axis\">Axis<\/a> has properties that specify its scale: <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Axis_minValue_0_0.htm\" title=\"MindFusion Charting for JavaScript: minValue,\">minValue,<\/a> <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Axis_maxValue_0_0.htm\" title=\"MindFusion Charting for JavaScript: maxVaue\">maxVaue<\/a> and <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Axis_interval_0_0.htm\" title=\"MindFusion Charting for JavaScript: interval\">interval<\/a> Axes can have a <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Axis_title_0_0.htm\" title=\"MindFusion Charting for JavaScript: title\">title<\/a> The labels at the X-axis can be hidden with the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Controls_BiaxialChart_showXCoordinates_0.htm\" title=\"MindFusion Charting for JavaScript: showXCoordinates\">showXCoordinates<\/a> property.<\/p>\n<pre>chart.showXCoordinates = false;\n\nchart.xAxis.title = \"\";\nchart.xAxis.minValue = 0;\nchart.xAxis.maxValue = 1;\nchart.xAxis.interval = 0.1;\nchart.yAxis.minValue = 0;\nchart.yAxis.maxValue = 130;\nchart.yAxis.interval = 10;\n<\/pre>\n<p><strong>III. The Grid<\/strong><\/p>\n<p>The default grid of the chart is set with the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Plot2D_gridType_0_0.htm\" title=\"MindFusion Charting for JavaScript: gridType\">gridType<\/a> property. The types of grid are members of the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?T_MindFusion_Charting_GridType_1.htm\" title=\"MindFusion Charting for JavaScript: GridType\">GridType<\/a> enumeration. We customize the grid with the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Theme_gridLineColor_0_0.htm\" title=\"MindFusion Charting for JavaScript: gridLineColor\">gridLineColor<\/a> and the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Plot2D_gridColor1_0_0.htm\" title=\"MindFusion Charting for JavaScript: gridColor1\">gridColor1<\/a> and <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Plot2D_gridColor2_0_0.htm\" title=\"MindFusion Charting for JavaScript: gridColor2\">gridColor2<\/a> properties for the grid stripes. The default grid draws lines and stripes between the scale divisions of the axes. We want to customize it to draw 4 more lines between the default lines for each interval. This functionality is not supported out of the box and we need to use custom drawing for that.<\/p>\n<p>The method that we need to overwrite is called drawGrid. There we get the drawing context, which we can use to perform drawing of graphic primitives. Because this is method that draws the grid, we need to call the default grid drawing code, if we want to see the default grid drawn next to our custom grid drawing code. We do it this way:<\/p>\n<pre>let originalDrawGrid = Charting.Plot2D.prototype.drawGrid;\n\nCharting.Plot2D.prototype.drawGrid = function(context) \n{\n\n     \/\/ draw the default grid\n     originalDrawGrid.call(this, context);\n\n}\n<\/pre>\n<p>Now we need to get the two axis: X and Y, and use their scale coordinates to calculate the additional points, which we will use for grid drawing.<\/p>\n<pre>let xAxis = this.xAxis == null ? context.xAxis : this.xAxis;\nlet yAxis = this.yAxis == null ? context.yAxis : this.yAxis;\n<\/pre>\n<p>Then, in a cycle, we draw 5 additional lines for each interval, as long as we haven&#8217;t reached the last coordinate of the axis:<\/p>\n<pre>let gridPen = new Drawing.Pen(\"#e8e8e8\");\n\n\tlet prevY = null;\n\tlet steps = 5;\n\tyAxis.enumerateIntervals(this.pinGrid, (y, yi) =&gt; {\n\t\tvar pixelY = yAxis.mapValueToPixelY(y, this.actualHeight);\n\n\t\tif (prevY != null) {\n\t\t\tvar dy = (prevY - pixelY) \/ steps;\n\t\t\tlet yy = prevY + dy;\n\t\t\tfor (var i = 0; i &lt; steps - 1; i++, yy += dy)\n\t\t\t\tcontext.graphics.drawLine(gridPen, 0, yy, this.actualWidth, yy);\n\t\t}\n\n\t\tprevY = pixelY;\n\t}, true);\n<\/pre>\n<p>The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?M_MindFusion_Charting_Axis_mapValueToPixelY_2_Number_Number.htm\" title=\"MindFusion Charting for JavaScript: mapValueToPixelY\">mapValueToPixelY<\/a> method is worth noting, because it is a useful public method, which converts a numeric value on the axis to a physical coordinate. The chart length can be taken from the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Components_Component_actualHeight_0_0.htm\" title=\"MindFusion Charting for JavaScript: actualHeight\">actualHeight<\/a> and <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?P_MindFusion_Charting_Components_Component_actualWidth_0_0.htm\" title=\"MindFusion Charting for JavaScript: actualWidth\">actualWidth<\/a> properties.<\/p>\n<p>With that our custom drawing method is ready. There is one method we need to call in order to see any type of chart rendered &#8211; the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/chart.javascript\/index.htm?M_MindFusion_Common_Control_draw_0.htm\" title=\"MindFusion Charting for JavaScript: draw\">draw<\/a> method.<\/p>\n<pre>chart.draw();\n<\/pre>\n<p>You can download the source code for this chart, together will all libraries used from this link:<\/p>\n<p align=\"center\"><a href=\"https:\/\/mindfusion.dev\/samples\/javascript\/chart\/MindFusionJSChart_CustomGrid.zip\" title=\"Download Area Chart with Custom Grid Sample\">Area Chart with Custom Grid in JavaScript: Download the Sample<\/a><\/p>\n<p>Technical support is available through MindFusion discussion board at <a href=\"https:\/\/mindfusion.dev\/Forum\/YaBB.pl?board=jschart_disc\" title=\"Charts and Gauges for JavaScript: Technical Support\">https:\/\/mindfusion.dev\/Forum\/YaBB.pl?board=jschart_disc<\/a>.<\/p>\n<p><i>About Charting for JavaScript:<\/i> MindFusion library for interactive charts and gauges. It supports all common chart types including 3D bar charts. Charts can have a grid, a legend, unlimited number of axes and series. Scroll, zoom and pan are supported out of the box. You can easily create your own chart series by implementing the Series interface.<br \/>\nThe gauges library is part of Charting for JavaScript. It supports oval and linear gauge with several types of labels and ticks. Various samples show you how the implement the gauges to create and customize all popular gauge types: car dashboard, clock, thermometer, compass etc. Learn more about Charting and Gauges for JavaScript at <a title=\"JavaScript Chart Library\" href=\"https:\/\/mindfusion.dev\/javascript-chart.html\">https:\/\/mindfusion.dev\/javascript-chart.html<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post we will look in short at the steps to build this JavaScript area chart with custom grid: The line chart uses DateTimeSeries for the data and a standard GridType for the major grid lines. The auxiliary &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/custom-grid-drawing-in-charting-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":[61,513,74],"tags":[705,70,106,80,654],"class_list":["post-2789","post","type-post","status-publish","format-standard","hentry","category-charting-2","category-javascript","category-sample-code","tag-areachart","tag-chart","tag-grid","tag-javascript","tag-tutorial"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-IZ","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2789","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=2789"}],"version-history":[{"count":6,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2789\/revisions"}],"predecessor-version":[{"id":2795,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2789\/revisions\/2795"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=2789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=2789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=2789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}