1 /**
  2  * @fileOverview
  3  * @author <a href="https://www.labkey.org">LabKey</a> (<a href="mailto:info@labkey.com">info@labkey.com</a>)
  4  * @license Copyright (c) 2008-2016 LabKey Corporation
  5  * <p/>
  6  * Licensed under the Apache License, Version 2.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at
  9  * <p/>
 10  * http://www.apache.org/licenses/LICENSE-2.0
 11  * <p/>
 12  * Unless required by applicable law or agreed to in writing, software
 13  * distributed under the License is distributed on an "AS IS" BASIS,
 14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing permissions and
 16  * limitations under the License.
 17  * <p/>
 18  */
 19 (function($) {
 20 
 21     /**
 22      * @description Chart class to create and render live charts and imagemaps.
 23      *            <p>Additional Documentation:
 24      *              <ul>
 25      *                  <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=charts">LabKey Chart Views</a></li>
 26      *              </ul>
 27      *            </p>
 28      * @class Chart class to create and render live charts and imagemaps.
 29      *            <p>Additional Documentation:
 30      *              <ul>
 31      *                  <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=charts">LabKey Chart Views</a></li>
 32      *              </ul>
 33      *            </p>
 34      * @constructor
 35      * @param {Object} config Describes the chart's properties.
 36      * @param {String} config.schemaName Name of a schema defined within the current
 37      *                 container.  Example: 'study'.  See also: <a class="link"
 38      href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames">
 39      How To Find schemaName, queryName & viewName</a>.
 40      * @param {String} config.queryName Name of a query table associated with the
 41      *                 chosen schema. Details below. Example: The name of one of
 42      *                 the study demo datasets: 'Physical Exam'.  See also: <a class="link"
 43      href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames">
 44      How To Find schemaName, queryName & viewName</a>.
 45      * @param {String} [config.viewName] Name of a custom view associated with the
 46      *                 chosen query. Details below. Example: The name of a custom
 47      *                 view for the 'Physical Exam' study demo dataset: 'Custom Grid
 48      *                 View: Join for Cohort Views'. See also: <a class="link"
 49      href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames">
 50      How To Find schemaName, queryName & viewName</a>.
 51      * @param {String} config.renderTo Element on the page where the chart will render.
 52      * @param {String} [config.renderImageMapTo] Element on the page where the imagemap will render.
 53      * @param {Function} [config.failure] Javascript function that can be used as a callback
 54      *                   if an error occurs. Otherwise, a standard listener will be used.
 55      * @param {String} config.columnXName Name of the column to plot on the X axis.
 56      * @param {String|[String]} config.columnYName Name of the column (or columns)
 57      *                 to plot on the Y axis. If multiple columns are desired, use array
 58      *                 format. Example: ['APXwtkg', 'APXbpsys', 'APXbpdia'].
 59      * @param {Bool} [config.logX='false'] Log scale X axis.
 60      * @param {Bool} [config.logY='false'] Log scale Y axis.
 61      * @param {LABKEY.Chart.TIME|LABKEY.Chart.XY} config.chartType The type of chart to plot.
 62      *                 You must use a TIME plot if you wish to plot a time variable on the X axis.
 63      * @param {Integer} [config.height='480'] Height in pixels
 64      * @param {Integer} [config.width='640'] Width in pixels
 65      * @param {Bool} [config.showMultipleYAxis='false'] If there are multiple Y axis
 66      *                 columns, display a separate Y axis for each column on the same plot.
 67      *                 This option is mutually exclusive with showMultipleCharts.
 68      * @param {Bool} [config.showLines='false']	Show lines between symbols.
 69      * @param {Bool} [config.showMultipleCharts='false'] If multiple Y columns are specified,
 70      *                 display each in its own plot.
 71      * @param {Bool} [config.verticalOrientation='false'] If showMultipleCharts is 'true' this
 72      *                 option controls whether charts are plotted vertically or
 73      *                 horizontally (the default).
 74      * @param {Function} [config.imageMapCallback] Javascript function that will be used in the URL's of the generated image map.
 75      *                 The specified function will be invoked with a single argument, a JSON object with : key, x, and y as fields. If
 76      *                 no function is specified, then the image map will show only tooltips.
 77      * @param {String|[String]} [config.imageMapCallbackColumns] Name(s) of additional columns whose names and values should be added
 78      *               To the JSON object for the config.imageMapCallback function.
 79      * @param {String} [config.containerPath] The container path in which the data for this chart is defined. If not supplied,
 80      *                  the current container path will be used.
 81      * @example Example #1 uses the "Physical Exam" dataset in the <a href = "https://www.labkey.org/Project/home/Study/demo/start.view?">Demo Study</a>
 82      * to plot a simple chart with one y-value:
 83      <pre name="code" class="xml">
 84      <script type="text/javascript">
 85      var chartConfig = {
 86         schemaName: 'study',
 87         queryName: 'Physical Exam',
 88         renderTo: 'chartDiv',
 89         chartType: LABKEY.Chart.XY,
 90         columnXName: 'APXbpsys',
 91         columnYName: 'APXbpdia',
 92     };
 93      var chart = new LABKEY.Chart(chartConfig);
 94      chart.render();
 95      </script>
 96      <div id="chartDiv"></div>
 97 
 98      Example #2 demonstrates plotting of multiple y-values:
 99 
100      <script type="text/javascript">
101      var chartConfig2 = {
102         queryName: 'Physical Exam',
103         schemaName: 'study',
104         chartType: LABKEY.Chart.XY,
105         renderTo: 'chartDiv2',
106         columnXName: 'APXwtkg',
107         columnYName: ['APXwtkg', 'APXbpsys', 'APXbpdia']
108     };
109      var chart = new LABKEY.Chart(chartConfig2);
110      chart.render();
111      </script>
112      <div id="chartDiv2"></div>
113 
114      Example #3 demonstrates image map support:
115 
116      <script type="text/javascript">
117 
118      var chartConfig = {
119         schemaName: 'study',
120         queryName: 'Physical Exam',
121         renderTo: 'chartDiv3',
122         renderImageMapTo: 'imageDiv',
123         chartType: LABKEY.Chart.XY,
124         columnXName: 'APXbpsys',
125         columnYName: 'APXbpdia',
126         imageMapCallback: 'showInfo'
127     };
128      var chart = new LABKEY.Chart(chartConfig);
129      chart.render();
130 
131      function showInfo(info)
132      {
133          alert("key: " + info.key + "x: " + info.x + "y: " + info.y);
134      }
135      </script>
136      <div id="chartDiv3"></div>
137      <div id="imageDiv"></div>
138      </pre>
139      */
140     LABKEY.Chart = function(config)
141     {
142         // private member variables:
143         this.config = config || {};
144 
145         var chartDivName = config.renderTo;
146         var imageDivName = config.renderImageMapTo;
147         var containerPath = config.containerPath;
148 
149         // private methods:
150         var renderChartInternal = function(response)
151         {
152             var data = LABKEY.Utils.decode(response.responseText);
153 
154             // render the image tag inside the chart div
155             if (imageDivName && data.imageMap)
156             {
157                 $('#'+chartDivName).append('<img src="' + data.imageURL + '" usemap="' + imageDivName + '"/>');
158                 $('#'+imageDivName).append(data.imageMap);
159             }
160             else
161             {
162                 $('#'+chartDivName).append('<img src="' + data.imageURL + '"/>')
163             }
164         };
165 
166         // public methods:
167         /** @scope LABKEY.Chart.prototype */
168         return {
169             /**
170              * Renders the chart to the div tags as specified in the config object passed to the constructor.
171              */
172             render : function()
173             {
174                 if (!config.schemaName || !config.queryName)
175                 {
176                     console.error("Configuration Error: config.schemaName and config.queryName are required parameters");
177                     return;
178                 }
179                 if (!chartDivName)
180                 {
181                     config.error("Configuration Error: config.renderTo is a required parameter.");
182                     return;
183                 }
184                 if (imageDivName)
185                 {
186                     config.imageMapName = imageDivName;
187                 }
188 
189                 LABKEY.Ajax.request({
190                     url: LABKEY.ActionURL.buildURL("reports", "plotChartApi", containerPath),
191                     success: renderChartInternal,
192                     failure: LABKEY.Utils.getOnFailure(config) || LABKEY.Utils.displayAjaxErrorResponse,
193                     params: config
194                 });
195             }
196         };
197     };
198 
199     /**
200      * Scatterplot-type chart
201      * @constant
202      */
203     LABKEY.Chart.XY = "1";
204     /**
205      * Time-based chart
206      * @constant
207      */
208     LABKEY.Chart.TIME = "2";
209 
210 })(jQuery);
211