{"id":1041,"date":"2014-09-06T10:05:08","date_gmt":"2014-09-06T08:05:08","guid":{"rendered":"http:\/\/www.speich.net\/articles\/?p=1041"},"modified":"2019-10-06T10:30:09","modified_gmt":"2019-10-06T08:30:09","slug":"boxplot-plugin-for-jqplot","status":"publish","type":"post","link":"https:\/\/www.speich.net\/articles\/en\/2014\/09\/06\/boxplot-plugin-for-jqplot\/","title":{"rendered":"Boxplot renderer plugin for jqPlot"},"content":{"rendered":"<p>For work I needed a way to show boxplots (see diagram to the right) using the <a href=\"http:\/\/www.jqplot.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">jqPlot library<\/a>. All I had to do was override the draw() method of <a title=\"jqplot OHLCRenderer\" href=\"http:\/\/www.jqplot.com\/docs\/files\/plugins\/jqplot-ohlcRenderer-js.html\" target=\"_blank\" rel=\"noopener noreferrer\">OHLCRenderer<\/a> (see code below).<\/p>\n<p><strong>Update 13.10.2017<\/strong>: Upon request I created a <a href=\"\/articles\/demos\/boxplot.html\" target=\"_blank\" rel=\"noopener noreferrer\">working demo of the BoxplotRenderer<\/a> using some helper classes to setup jqPlot charts from another project.<\/p>\n<figure id=\"attachment_1060\" aria-describedby=\"caption-attachment-1060\" style=\"width: 651px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1060 size-full\" src=\"https:\/\/www.speich.net\/wp\/wp-content\/uploads\/2014\/09\/boxplot.gif\" alt=\"boxplot diagram\" width=\"651\" height=\"313\"><figcaption id=\"caption-attachment-1060\" class=\"wp-caption-text\">Example of a histogram and boxplot rendered with the jqPlot library.<\/figcaption><\/figure>\n<p><!--more--><\/p>\n<pre><code class=\"language-javascript\">define(['\/library\/jqplot\/plugins\/jqplot.ohlcRenderer.min.js'], function() {\n\n\treturn function() {\n\n\t\t\/**\n\t\t * @module BoxplotRenderer\n\t\t *\/\n\t\t$.jqplot.OHLCRenderer.prototype.draw = function(ctx, gd, options) {\n\t\t\tvar d = this.data, dinterval,\n\t\t\txmin = this._xaxis.min,\n\t\t\txmax = this._xaxis.max,\n\t\t\txminidx = 0,\t\/\/ index of last value below range of plot.\n\t\t\txmaxidx = d.length,\t\/\/ index of first value above range of plot.\n\t\t\txp = this._xaxis.series_u2p,\n\t\t\typ = this._yaxis.series_u2p,\n\t\t\tops, b, h, w, a, l, median, points,\n\t\t\ti, o, r = this.renderer,\n\t\t\topts = (options !== undefined) ? options: {};\n\n\t\t\tr.bodyWidth = (opts.bodyWidth !== undefined) ? opts.bodyWidth: r.bodyWidth;\n\t\t\tr.tickLength = (opts.tickLength !== undefined) ? opts.tickLength: r.tickLength;\n\t\t\tctx.save();\n\t\t\tif (this.show) {\n\t\t\t\tvar x, open, hi, low, close;\n\t\t\t\t\/\/ need to get widths based on number of points shown,\n\t\t\t\t\/\/ not on total number of points.  Use the results\n\t\t\t\t\/\/ to speed up drawing in next step.\n\t\t\t\tfor (i = 0; i &lt; d.length; i++) {\n\t\t\t\t\tif (d[i][0] &lt; xmin) {\n\t\t\t\t\t\txminidx = i;\n\t\t\t\t\t}\n\t\t\t\t\telse if (d[i][0] &lt; xmax) {\n\t\t\t\t\t\txmaxidx = i + 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar dwidth = this.gridData[xmaxidx - 1][0] - this.gridData[xminidx][0];\n\t\t\t\tvar nvisiblePoints = xmaxidx - xminidx;\n\t\t\t\ttry {\n\t\t\t\t\tdinterval = Math.abs(this._xaxis.series_u2p(\n\t\t\t\t\t\tparseInt(this._xaxis._intervalStats[0].sortedIntervals[0].interval, 10)\n\t\t\t\t\t) - this._xaxis.series_u2p(0));\n\t\t\t\t}\n\n\t\t\t\tcatch(e) {\n\t\t\t\t\tdinterval = dwidth \/ nvisiblePoints;\n\t\t\t\t}\n\n\n\t\t\t\tif (typeof(r.bodyWidth) === 'number') {\n\t\t\t\t\tr._bodyWidth = r.bodyWidth;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tr._bodyWidth = Math.min(20, dinterval \/ 1.65);\n\t\t\t\t}\n\n\n\t\t\t\tfor (i = xminidx; i &lt; xmaxidx; i++) {\n\t\t\t\t\tx = xp(d[i][0]);\n\n\t\t\t\t\t\/\/ 25%, max, min, 75%\n\t\t\t\t\topen = yp(d[i][1]);\n\t\t\t\t\thi = yp(d[i][2]);\n\t\t\t\t\tlow = yp(d[i][3]);\n\t\t\t\t\tclose = yp(d[i][4]);\n\t\t\t\t\tmedian = yp(d[i][5]);\n\n\t\t\t\t\to = {};\n\n\t\t\t\t\tw = r._bodyWidth;\n\t\t\t\t\ta = x - w \/ 2;\n\n\t\t\t\t\t\/\/ draw candle\n\t\t\t\t\t\/\/ Remember: grid coordinates increase downward\n\n\t\t\t\t\tif (r.wickColor) {\n\t\t\t\t\t\to.color = r.wickColor;\n\t\t\t\t\t}\n\t\t\t\t\telse if (r.downBodyColor) {\n\t\t\t\t\t\to.color = r.upBodyColor;\n\t\t\t\t\t}\n\t\t\t\t\tops = $.extend(true, {}, opts, o);\n\n\t\t\t\t\t\/\/ line from box to max\n\t\t\t\t\tr.shapeRenderer.draw(ctx, [\n\t\t\t\t\t\t[x, hi],\n\t\t\t\t\t\t[x, close]\n\t\t\t\t\t], ops);\n\n\t\t\t\t\t\/\/ line from box to min\n\t\t\t\t\tr.shapeRenderer.draw(ctx, [\n\t\t\t\t\t\t[x, open],\n\t\t\t\t\t\t[x, low]\n\t\t\t\t\t], ops);\n\t\t\t\t\to = {};\n\t\t\t\t\tb = close;\n\t\t\t\t\th = open - close;\n\t\t\t\t\t\/\/ if color specified, use it\n\t\t\t\t\tif (r.fillUpBody) {\n\t\t\t\t\t\to.fillRect = true;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\to.strokeRect = true;\n\t\t\t\t\t\tw = w - this.lineWidth;\n\t\t\t\t\t\ta = x - w \/ 2;\n\t\t\t\t\t}\n\n\t\t\t\t\t\/\/ max\n\t\t\t\t\tl = x + w \/ 2;\n\t\t\t\t\tr.shapeRenderer.draw(ctx, [\n\t\t\t\t\t\t[a, hi],\n\t\t\t\t\t\t[l, hi]\n\t\t\t\t\t], ops);\n\n\t\t\t\t\t\/\/ min\n\t\t\t\t\tr.shapeRenderer.draw(ctx, [\n\t\t\t\t\t\t[a, low],\n\t\t\t\t\t\t[l, low]\n\t\t\t\t\t], ops);\n\n\t\t\t\t\t\/\/ median\n\t\t\t\t\tr.shapeRenderer.draw(ctx, [\n\t\t\t\t\t\t[a, median],\n\t\t\t\t\t\t[l, median]\n\t\t\t\t\t], ops);\n\n\t\t\t\t\tif (r.upBodyColor) {\n\t\t\t\t\t\to.color = r.upBodyColor;\n\t\t\t\t\t\to.fillStyle = r.upBodyColor;\n\t\t\t\t\t}\n\n\t\t\t\t\t\/\/ draw box\n\t\t\t\t\tpoints = [a, b, w, h];\n\t\t\t\t\tops = $.extend(true, {}, opts, o);\n\t\t\t\t\tr.shapeRenderer.draw(ctx, points, ops);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.restore();\n\t\t};\n\n\t\treturn new $.jqplot.OHLCRenderer;\n\t};\n});<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For work I needed a way to show boxplots (see diagram to the right) using the jqPlot library. All I had to do was override the draw() method of OHLCRenderer (see code below). Update 13.10.2017: Upon request I created a working demo of the BoxplotRenderer using some helper classes to setup jqPlot charts from another &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.speich.net\/articles\/en\/2014\/09\/06\/boxplot-plugin-for-jqplot\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Boxplot renderer plugin for jqPlot&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[47],"class_list":["post-1041","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-jqplot","entry"],"_links":{"self":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts\/1041","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/comments?post=1041"}],"version-history":[{"count":5,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts\/1041\/revisions"}],"predecessor-version":[{"id":1668,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts\/1041\/revisions\/1668"}],"wp:attachment":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/media?parent=1041"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/categories?post=1041"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/tags?post=1041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}