From 554de444b87aab5f93cb1593a8095612cf9479a7 Mon Sep 17 00:00:00 2001 From: yujian <yujian@163.com> Date: 星期二, 09 六月 2020 17:34:30 +0800 Subject: [PATCH] 订单 --- fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/data.src.js | 1164 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 582 insertions(+), 582 deletions(-) diff --git a/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/data.src.js b/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/data.src.js index d344799..4bc71a4 100644 --- a/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/data.src.js +++ b/fanli/src/main/webapp/admin/new/js/third-party/highcharts/modules/data.src.js @@ -1,582 +1,582 @@ -/** - * @license Data plugin for Highcharts - * - * (c) 2012-2013 Torstein H酶nsi - * Last revision 2013-06-07 - * - * License: www.highcharts.com/license - */ - -/* - * The Highcharts Data plugin is a utility to ease parsing of input sources like - * CSV, HTML tables or grid views into basic configuration options for use - * directly in the Highcharts constructor. - * - * Demo: http://jsfiddle.net/highcharts/SnLFj/ - * - * --- OPTIONS --- - * - * - columns : Array<Array<Mixed>> - * A two-dimensional array representing the input data on tabular form. This input can - * be used when the data is already parsed, for example from a grid view component. - * Each cell can be a string or number. If not switchRowsAndColumns is set, the columns - * are interpreted as series. See also the rows option. - * - * - complete : Function(chartOptions) - * The callback that is evaluated when the data is finished loading, optionally from an - * external source, and parsed. The first argument passed is a finished chart options - * object, containing series and an xAxis with categories if applicable. Thise options - * can be extended with additional options and passed directly to the chart constructor. - * - * - csv : String - * A comma delimited string to be parsed. Related options are startRow, endRow, startColumn - * and endColumn to delimit what part of the table is used. The lineDelimiter and - * itemDelimiter options define the CSV delimiter formats. - * - * - endColumn : Integer - * In tabular input data, the first row (indexed by 0) to use. Defaults to the last - * column containing data. - * - * - endRow : Integer - * In tabular input data, the last row (indexed by 0) to use. Defaults to the last row - * containing data. - * - * - googleSpreadsheetKey : String - * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample - * for general information on GS. - * - * - googleSpreadsheetWorksheet : String - * The Google Spreadsheet worksheet. The available id's can be read from - * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic - * - * - itemDelimiter : String - * Item or cell delimiter for parsing CSV. Defaults to ",". - * - * - lineDelimiter : String - * Line delimiter for parsing CSV. Defaults to "\n". - * - * - parsed : Function - * A callback function to access the parsed columns, the two-dimentional input data - * array directly, before they are interpreted into series data and categories. - * - * - parseDate : Function - * A callback function to parse string representations of dates into JavaScript timestamps. - * Return an integer on success. - * - * - rows : Array<Array<Mixed>> - * The same as the columns input option, but defining rows intead of columns. - * - * - startColumn : Integer - * In tabular input data, the first column (indexed by 0) to use. - * - * - startRow : Integer - * In tabular input data, the first row (indexed by 0) to use. - * - * - table : String|HTMLElement - * A HTML table or the id of such to be parsed as input data. Related options ara startRow, - * endRow, startColumn and endColumn to delimit what part of the table is used. - */ - -// JSLint options: -/*global jQuery */ - -(function (Highcharts) { - - // Utilities - var each = Highcharts.each; - - - // The Data constructor - var Data = function (dataOptions, chartOptions) { - this.init(dataOptions, chartOptions); - }; - - // Set the prototype properties - Highcharts.extend(Data.prototype, { - - /** - * Initialize the Data object with the given options - */ - init: function (options, chartOptions) { - this.options = options; - this.chartOptions = chartOptions; - this.columns = options.columns || this.rowsToColumns(options.rows) || []; - - // No need to parse or interpret anything - if (this.columns.length) { - this.dataFound(); - - // Parse and interpret - } else { - - // Parse a CSV string if options.csv is given - this.parseCSV(); - - // Parse a HTML table if options.table is given - this.parseTable(); - - // Parse a Google Spreadsheet - this.parseGoogleSpreadsheet(); - } - - }, - - /** - * Get the column distribution. For example, a line series takes a single column for - * Y values. A range series takes two columns for low and high values respectively, - * and an OHLC series takes four columns. - */ - getColumnDistribution: function () { - var chartOptions = this.chartOptions, - getValueCount = function (type) { - return (Highcharts.seriesTypes[type || 'line'].prototype.pointArrayMap || [0]).length; - }, - globalType = chartOptions && chartOptions.chart && chartOptions.chart.type, - individualCounts = []; - - each((chartOptions && chartOptions.series) || [], function (series) { - individualCounts.push(getValueCount(series.type || globalType)); - }); - - this.valueCount = { - global: getValueCount(globalType), - individual: individualCounts - }; - }, - - - dataFound: function () { - // Interpret the values into right types - this.parseTypes(); - - // Use first row for series names? - this.findHeaderRow(); - - // Handle columns if a handleColumns callback is given - this.parsed(); - - // Complete if a complete callback is given - this.complete(); - - }, - - /** - * Parse a CSV input string - */ - parseCSV: function () { - var self = this, - options = this.options, - csv = options.csv, - columns = this.columns, - startRow = options.startRow || 0, - endRow = options.endRow || Number.MAX_VALUE, - startColumn = options.startColumn || 0, - endColumn = options.endColumn || Number.MAX_VALUE, - lines, - activeRowNo = 0; - - if (csv) { - - lines = csv - .replace(/\r\n/g, "\n") // Unix - .replace(/\r/g, "\n") // Mac - .split(options.lineDelimiter || "\n"); - - each(lines, function (line, rowNo) { - var trimmed = self.trim(line), - isComment = trimmed.indexOf('#') === 0, - isBlank = trimmed === '', - items; - - if (rowNo >= startRow && rowNo <= endRow && !isComment && !isBlank) { - items = line.split(options.itemDelimiter || ','); - each(items, function (item, colNo) { - if (colNo >= startColumn && colNo <= endColumn) { - if (!columns[colNo - startColumn]) { - columns[colNo - startColumn] = []; - } - - columns[colNo - startColumn][activeRowNo] = item; - } - }); - activeRowNo += 1; - } - }); - - this.dataFound(); - } - }, - - /** - * Parse a HTML table - */ - parseTable: function () { - var options = this.options, - table = options.table, - columns = this.columns, - startRow = options.startRow || 0, - endRow = options.endRow || Number.MAX_VALUE, - startColumn = options.startColumn || 0, - endColumn = options.endColumn || Number.MAX_VALUE, - colNo; - - if (table) { - - if (typeof table === 'string') { - table = document.getElementById(table); - } - - each(table.getElementsByTagName('tr'), function (tr, rowNo) { - colNo = 0; - if (rowNo >= startRow && rowNo <= endRow) { - each(tr.childNodes, function (item) { - if ((item.tagName === 'TD' || item.tagName === 'TH') && colNo >= startColumn && colNo <= endColumn) { - if (!columns[colNo]) { - columns[colNo] = []; - } - columns[colNo][rowNo - startRow] = item.innerHTML; - - colNo += 1; - } - }); - } - }); - - this.dataFound(); // continue - } - }, - - /** - * TODO: - * - switchRowsAndColumns - */ - parseGoogleSpreadsheet: function () { - var self = this, - options = this.options, - googleSpreadsheetKey = options.googleSpreadsheetKey, - columns = this.columns, - startRow = options.startRow || 0, - endRow = options.endRow || Number.MAX_VALUE, - startColumn = options.startColumn || 0, - endColumn = options.endColumn || Number.MAX_VALUE, - gr, // google row - gc; // google column - - if (googleSpreadsheetKey) { - jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' + - googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') + - '/public/values?alt=json-in-script&callback=?', - function (json) { - - // Prepare the data from the spreadsheat - var cells = json.feed.entry, - cell, - cellCount = cells.length, - colCount = 0, - rowCount = 0, - i; - - // First, find the total number of columns and rows that - // are actually filled with data - for (i = 0; i < cellCount; i++) { - cell = cells[i]; - colCount = Math.max(colCount, cell.gs$cell.col); - rowCount = Math.max(rowCount, cell.gs$cell.row); - } - - // Set up arrays containing the column data - for (i = 0; i < colCount; i++) { - if (i >= startColumn && i <= endColumn) { - // Create new columns with the length of either end-start or rowCount - columns[i - startColumn] = []; - - // Setting the length to avoid jslint warning - columns[i - startColumn].length = Math.min(rowCount, endRow - startRow); - } - } - - // Loop over the cells and assign the value to the right - // place in the column arrays - for (i = 0; i < cellCount; i++) { - cell = cells[i]; - gr = cell.gs$cell.row - 1; // rows start at 1 - gc = cell.gs$cell.col - 1; // columns start at 1 - - // If both row and col falls inside start and end - // set the transposed cell value in the newly created columns - if (gc >= startColumn && gc <= endColumn && - gr >= startRow && gr <= endRow) { - columns[gc - startColumn][gr - startRow] = cell.content.$t; - } - } - self.dataFound(); - }); - } - }, - - /** - * Find the header row. For now, we just check whether the first row contains - * numbers or strings. Later we could loop down and find the first row with - * numbers. - */ - findHeaderRow: function () { - var headerRow = 0; - each(this.columns, function (column) { - if (typeof column[0] !== 'string') { - headerRow = null; - } - }); - this.headerRow = 0; - }, - - /** - * Trim a string from whitespace - */ - trim: function (str) { - return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str; - }, - - /** - * Parse numeric cells in to number types and date types in to true dates. - * @param {Object} columns - */ - parseTypes: function () { - var columns = this.columns, - col = columns.length, - row, - val, - floatVal, - trimVal, - dateVal; - - while (col--) { - row = columns[col].length; - while (row--) { - val = columns[col][row]; - floatVal = parseFloat(val); - trimVal = this.trim(val); - - /*jslint eqeq: true*/ - if (trimVal == floatVal) { // is numeric - /*jslint eqeq: false*/ - columns[col][row] = floatVal; - - // If the number is greater than milliseconds in a year, assume datetime - if (floatVal > 365 * 24 * 3600 * 1000) { - columns[col].isDatetime = true; - } else { - columns[col].isNumeric = true; - } - - } else { // string, continue to determine if it is a date string or really a string - dateVal = this.parseDate(val); - - if (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date - columns[col][row] = dateVal; - columns[col].isDatetime = true; - - } else { // string - columns[col][row] = trimVal === '' ? null : trimVal; - } - } - - } - } - }, - //* - dateFormats: { - 'YYYY-mm-dd': { - regex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$', - parser: function (match) { - return Date.UTC(+match[1], match[2] - 1, +match[3]); - } - } - }, - // */ - /** - * Parse a date and return it as a number. Overridable through options.parseDate. - */ - parseDate: function (val) { - var parseDate = this.options.parseDate, - ret, - key, - format, - match; - - if (parseDate) { - ret = parseDate(val); - } - - if (typeof val === 'string') { - for (key in this.dateFormats) { - format = this.dateFormats[key]; - match = val.match(format.regex); - if (match) { - ret = format.parser(match); - } - } - } - return ret; - }, - - /** - * Reorganize rows into columns - */ - rowsToColumns: function (rows) { - var row, - rowsLength, - col, - colsLength, - columns; - - if (rows) { - columns = []; - rowsLength = rows.length; - for (row = 0; row < rowsLength; row++) { - colsLength = rows[row].length; - for (col = 0; col < colsLength; col++) { - if (!columns[col]) { - columns[col] = []; - } - columns[col][row] = rows[row][col]; - } - } - } - return columns; - }, - - /** - * A hook for working directly on the parsed columns - */ - parsed: function () { - if (this.options.parsed) { - this.options.parsed.call(this, this.columns); - } - }, - - /** - * If a complete callback function is provided in the options, interpret the - * columns into a Highcharts options object. - */ - complete: function () { - - var columns = this.columns, - firstCol, - type, - options = this.options, - valueCount, - series, - data, - i, - j, - seriesIndex; - - - if (options.complete) { - - this.getColumnDistribution(); - - // Use first column for X data or categories? - if (columns.length > 1) { - firstCol = columns.shift(); - if (this.headerRow === 0) { - firstCol.shift(); // remove the first cell - } - - - if (firstCol.isDatetime) { - type = 'datetime'; - } else if (!firstCol.isNumeric) { - type = 'category'; - } - } - - // Get the names and shift the top row - for (i = 0; i < columns.length; i++) { - if (this.headerRow === 0) { - columns[i].name = columns[i].shift(); - } - } - - // Use the next columns for series - series = []; - for (i = 0, seriesIndex = 0; i < columns.length; seriesIndex++) { - - // This series' value count - valueCount = Highcharts.pick(this.valueCount.individual[seriesIndex], this.valueCount.global); - - // Iterate down the cells of each column and add data to the series - data = []; - for (j = 0; j < columns[i].length; j++) { - data[j] = [ - firstCol[j], - columns[i][j] !== undefined ? columns[i][j] : null - ]; - if (valueCount > 1) { - data[j].push(columns[i + 1][j] !== undefined ? columns[i + 1][j] : null); - } - if (valueCount > 2) { - data[j].push(columns[i + 2][j] !== undefined ? columns[i + 2][j] : null); - } - if (valueCount > 3) { - data[j].push(columns[i + 3][j] !== undefined ? columns[i + 3][j] : null); - } - if (valueCount > 4) { - data[j].push(columns[i + 4][j] !== undefined ? columns[i + 4][j] : null); - } - } - - // Add the series - series[seriesIndex] = { - name: columns[i].name, - data: data - }; - - i += valueCount; - } - - // Do the callback - options.complete({ - xAxis: { - type: type - }, - series: series - }); - } - } - }); - - // Register the Data prototype and data function on Highcharts - Highcharts.Data = Data; - Highcharts.data = function (options, chartOptions) { - return new Data(options, chartOptions); - }; - - // Extend Chart.init so that the Chart constructor accepts a new configuration - // option group, data. - Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) { - var chart = this; - - if (userOptions && userOptions.data) { - Highcharts.data(Highcharts.extend(userOptions.data, { - complete: function (dataOptions) { - - // Merge series configs - if (userOptions.series) { - each(userOptions.series, function (series, i) { - userOptions.series[i] = Highcharts.merge(series, dataOptions.series[i]); - }); - } - - // Do the merge - userOptions = Highcharts.merge(dataOptions, userOptions); - - proceed.call(chart, userOptions, callback); - } - }), userOptions); - } else { - proceed.call(chart, userOptions, callback); - } - }); - -}(Highcharts)); +/** + * @license Data plugin for Highcharts + * + * (c) 2012-2013 Torstein H酶nsi + * Last revision 2013-06-07 + * + * License: www.highcharts.com/license + */ + +/* + * The Highcharts Data plugin is a utility to ease parsing of input sources like + * CSV, HTML tables or grid views into basic configuration options for use + * directly in the Highcharts constructor. + * + * Demo: http://jsfiddle.net/highcharts/SnLFj/ + * + * --- OPTIONS --- + * + * - columns : Array<Array<Mixed>> + * A two-dimensional array representing the input data on tabular form. This input can + * be used when the data is already parsed, for example from a grid view component. + * Each cell can be a string or number. If not switchRowsAndColumns is set, the columns + * are interpreted as series. See also the rows option. + * + * - complete : Function(chartOptions) + * The callback that is evaluated when the data is finished loading, optionally from an + * external source, and parsed. The first argument passed is a finished chart options + * object, containing series and an xAxis with categories if applicable. Thise options + * can be extended with additional options and passed directly to the chart constructor. + * + * - csv : String + * A comma delimited string to be parsed. Related options are startRow, endRow, startColumn + * and endColumn to delimit what part of the table is used. The lineDelimiter and + * itemDelimiter options define the CSV delimiter formats. + * + * - endColumn : Integer + * In tabular input data, the first row (indexed by 0) to use. Defaults to the last + * column containing data. + * + * - endRow : Integer + * In tabular input data, the last row (indexed by 0) to use. Defaults to the last row + * containing data. + * + * - googleSpreadsheetKey : String + * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample + * for general information on GS. + * + * - googleSpreadsheetWorksheet : String + * The Google Spreadsheet worksheet. The available id's can be read from + * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic + * + * - itemDelimiter : String + * Item or cell delimiter for parsing CSV. Defaults to ",". + * + * - lineDelimiter : String + * Line delimiter for parsing CSV. Defaults to "\n". + * + * - parsed : Function + * A callback function to access the parsed columns, the two-dimentional input data + * array directly, before they are interpreted into series data and categories. + * + * - parseDate : Function + * A callback function to parse string representations of dates into JavaScript timestamps. + * Return an integer on success. + * + * - rows : Array<Array<Mixed>> + * The same as the columns input option, but defining rows intead of columns. + * + * - startColumn : Integer + * In tabular input data, the first column (indexed by 0) to use. + * + * - startRow : Integer + * In tabular input data, the first row (indexed by 0) to use. + * + * - table : String|HTMLElement + * A HTML table or the id of such to be parsed as input data. Related options ara startRow, + * endRow, startColumn and endColumn to delimit what part of the table is used. + */ + +// JSLint options: +/*global jQuery */ + +(function (Highcharts) { + + // Utilities + var each = Highcharts.each; + + + // The Data constructor + var Data = function (dataOptions, chartOptions) { + this.init(dataOptions, chartOptions); + }; + + // Set the prototype properties + Highcharts.extend(Data.prototype, { + + /** + * Initialize the Data object with the given options + */ + init: function (options, chartOptions) { + this.options = options; + this.chartOptions = chartOptions; + this.columns = options.columns || this.rowsToColumns(options.rows) || []; + + // No need to parse or interpret anything + if (this.columns.length) { + this.dataFound(); + + // Parse and interpret + } else { + + // Parse a CSV string if options.csv is given + this.parseCSV(); + + // Parse a HTML table if options.table is given + this.parseTable(); + + // Parse a Google Spreadsheet + this.parseGoogleSpreadsheet(); + } + + }, + + /** + * Get the column distribution. For example, a line series takes a single column for + * Y values. A range series takes two columns for low and high values respectively, + * and an OHLC series takes four columns. + */ + getColumnDistribution: function () { + var chartOptions = this.chartOptions, + getValueCount = function (type) { + return (Highcharts.seriesTypes[type || 'line'].prototype.pointArrayMap || [0]).length; + }, + globalType = chartOptions && chartOptions.chart && chartOptions.chart.type, + individualCounts = []; + + each((chartOptions && chartOptions.series) || [], function (series) { + individualCounts.push(getValueCount(series.type || globalType)); + }); + + this.valueCount = { + global: getValueCount(globalType), + individual: individualCounts + }; + }, + + + dataFound: function () { + // Interpret the values into right types + this.parseTypes(); + + // Use first row for series names? + this.findHeaderRow(); + + // Handle columns if a handleColumns callback is given + this.parsed(); + + // Complete if a complete callback is given + this.complete(); + + }, + + /** + * Parse a CSV input string + */ + parseCSV: function () { + var self = this, + options = this.options, + csv = options.csv, + columns = this.columns, + startRow = options.startRow || 0, + endRow = options.endRow || Number.MAX_VALUE, + startColumn = options.startColumn || 0, + endColumn = options.endColumn || Number.MAX_VALUE, + lines, + activeRowNo = 0; + + if (csv) { + + lines = csv + .replace(/\r\n/g, "\n") // Unix + .replace(/\r/g, "\n") // Mac + .split(options.lineDelimiter || "\n"); + + each(lines, function (line, rowNo) { + var trimmed = self.trim(line), + isComment = trimmed.indexOf('#') === 0, + isBlank = trimmed === '', + items; + + if (rowNo >= startRow && rowNo <= endRow && !isComment && !isBlank) { + items = line.split(options.itemDelimiter || ','); + each(items, function (item, colNo) { + if (colNo >= startColumn && colNo <= endColumn) { + if (!columns[colNo - startColumn]) { + columns[colNo - startColumn] = []; + } + + columns[colNo - startColumn][activeRowNo] = item; + } + }); + activeRowNo += 1; + } + }); + + this.dataFound(); + } + }, + + /** + * Parse a HTML table + */ + parseTable: function () { + var options = this.options, + table = options.table, + columns = this.columns, + startRow = options.startRow || 0, + endRow = options.endRow || Number.MAX_VALUE, + startColumn = options.startColumn || 0, + endColumn = options.endColumn || Number.MAX_VALUE, + colNo; + + if (table) { + + if (typeof table === 'string') { + table = document.getElementById(table); + } + + each(table.getElementsByTagName('tr'), function (tr, rowNo) { + colNo = 0; + if (rowNo >= startRow && rowNo <= endRow) { + each(tr.childNodes, function (item) { + if ((item.tagName === 'TD' || item.tagName === 'TH') && colNo >= startColumn && colNo <= endColumn) { + if (!columns[colNo]) { + columns[colNo] = []; + } + columns[colNo][rowNo - startRow] = item.innerHTML; + + colNo += 1; + } + }); + } + }); + + this.dataFound(); // continue + } + }, + + /** + * TODO: + * - switchRowsAndColumns + */ + parseGoogleSpreadsheet: function () { + var self = this, + options = this.options, + googleSpreadsheetKey = options.googleSpreadsheetKey, + columns = this.columns, + startRow = options.startRow || 0, + endRow = options.endRow || Number.MAX_VALUE, + startColumn = options.startColumn || 0, + endColumn = options.endColumn || Number.MAX_VALUE, + gr, // google row + gc; // google column + + if (googleSpreadsheetKey) { + jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' + + googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') + + '/public/values?alt=json-in-script&callback=?', + function (json) { + + // Prepare the data from the spreadsheat + var cells = json.feed.entry, + cell, + cellCount = cells.length, + colCount = 0, + rowCount = 0, + i; + + // First, find the total number of columns and rows that + // are actually filled with data + for (i = 0; i < cellCount; i++) { + cell = cells[i]; + colCount = Math.max(colCount, cell.gs$cell.col); + rowCount = Math.max(rowCount, cell.gs$cell.row); + } + + // Set up arrays containing the column data + for (i = 0; i < colCount; i++) { + if (i >= startColumn && i <= endColumn) { + // Create new columns with the length of either end-start or rowCount + columns[i - startColumn] = []; + + // Setting the length to avoid jslint warning + columns[i - startColumn].length = Math.min(rowCount, endRow - startRow); + } + } + + // Loop over the cells and assign the value to the right + // place in the column arrays + for (i = 0; i < cellCount; i++) { + cell = cells[i]; + gr = cell.gs$cell.row - 1; // rows start at 1 + gc = cell.gs$cell.col - 1; // columns start at 1 + + // If both row and col falls inside start and end + // set the transposed cell value in the newly created columns + if (gc >= startColumn && gc <= endColumn && + gr >= startRow && gr <= endRow) { + columns[gc - startColumn][gr - startRow] = cell.content.$t; + } + } + self.dataFound(); + }); + } + }, + + /** + * Find the header row. For now, we just check whether the first row contains + * numbers or strings. Later we could loop down and find the first row with + * numbers. + */ + findHeaderRow: function () { + var headerRow = 0; + each(this.columns, function (column) { + if (typeof column[0] !== 'string') { + headerRow = null; + } + }); + this.headerRow = 0; + }, + + /** + * Trim a string from whitespace + */ + trim: function (str) { + return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str; + }, + + /** + * Parse numeric cells in to number types and date types in to true dates. + * @param {Object} columns + */ + parseTypes: function () { + var columns = this.columns, + col = columns.length, + row, + val, + floatVal, + trimVal, + dateVal; + + while (col--) { + row = columns[col].length; + while (row--) { + val = columns[col][row]; + floatVal = parseFloat(val); + trimVal = this.trim(val); + + /*jslint eqeq: true*/ + if (trimVal == floatVal) { // is numeric + /*jslint eqeq: false*/ + columns[col][row] = floatVal; + + // If the number is greater than milliseconds in a year, assume datetime + if (floatVal > 365 * 24 * 3600 * 1000) { + columns[col].isDatetime = true; + } else { + columns[col].isNumeric = true; + } + + } else { // string, continue to determine if it is a date string or really a string + dateVal = this.parseDate(val); + + if (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date + columns[col][row] = dateVal; + columns[col].isDatetime = true; + + } else { // string + columns[col][row] = trimVal === '' ? null : trimVal; + } + } + + } + } + }, + //* + dateFormats: { + 'YYYY-mm-dd': { + regex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$', + parser: function (match) { + return Date.UTC(+match[1], match[2] - 1, +match[3]); + } + } + }, + // */ + /** + * Parse a date and return it as a number. Overridable through options.parseDate. + */ + parseDate: function (val) { + var parseDate = this.options.parseDate, + ret, + key, + format, + match; + + if (parseDate) { + ret = parseDate(val); + } + + if (typeof val === 'string') { + for (key in this.dateFormats) { + format = this.dateFormats[key]; + match = val.match(format.regex); + if (match) { + ret = format.parser(match); + } + } + } + return ret; + }, + + /** + * Reorganize rows into columns + */ + rowsToColumns: function (rows) { + var row, + rowsLength, + col, + colsLength, + columns; + + if (rows) { + columns = []; + rowsLength = rows.length; + for (row = 0; row < rowsLength; row++) { + colsLength = rows[row].length; + for (col = 0; col < colsLength; col++) { + if (!columns[col]) { + columns[col] = []; + } + columns[col][row] = rows[row][col]; + } + } + } + return columns; + }, + + /** + * A hook for working directly on the parsed columns + */ + parsed: function () { + if (this.options.parsed) { + this.options.parsed.call(this, this.columns); + } + }, + + /** + * If a complete callback function is provided in the options, interpret the + * columns into a Highcharts options object. + */ + complete: function () { + + var columns = this.columns, + firstCol, + type, + options = this.options, + valueCount, + series, + data, + i, + j, + seriesIndex; + + + if (options.complete) { + + this.getColumnDistribution(); + + // Use first column for X data or categories? + if (columns.length > 1) { + firstCol = columns.shift(); + if (this.headerRow === 0) { + firstCol.shift(); // remove the first cell + } + + + if (firstCol.isDatetime) { + type = 'datetime'; + } else if (!firstCol.isNumeric) { + type = 'category'; + } + } + + // Get the names and shift the top row + for (i = 0; i < columns.length; i++) { + if (this.headerRow === 0) { + columns[i].name = columns[i].shift(); + } + } + + // Use the next columns for series + series = []; + for (i = 0, seriesIndex = 0; i < columns.length; seriesIndex++) { + + // This series' value count + valueCount = Highcharts.pick(this.valueCount.individual[seriesIndex], this.valueCount.global); + + // Iterate down the cells of each column and add data to the series + data = []; + for (j = 0; j < columns[i].length; j++) { + data[j] = [ + firstCol[j], + columns[i][j] !== undefined ? columns[i][j] : null + ]; + if (valueCount > 1) { + data[j].push(columns[i + 1][j] !== undefined ? columns[i + 1][j] : null); + } + if (valueCount > 2) { + data[j].push(columns[i + 2][j] !== undefined ? columns[i + 2][j] : null); + } + if (valueCount > 3) { + data[j].push(columns[i + 3][j] !== undefined ? columns[i + 3][j] : null); + } + if (valueCount > 4) { + data[j].push(columns[i + 4][j] !== undefined ? columns[i + 4][j] : null); + } + } + + // Add the series + series[seriesIndex] = { + name: columns[i].name, + data: data + }; + + i += valueCount; + } + + // Do the callback + options.complete({ + xAxis: { + type: type + }, + series: series + }); + } + } + }); + + // Register the Data prototype and data function on Highcharts + Highcharts.Data = Data; + Highcharts.data = function (options, chartOptions) { + return new Data(options, chartOptions); + }; + + // Extend Chart.init so that the Chart constructor accepts a new configuration + // option group, data. + Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) { + var chart = this; + + if (userOptions && userOptions.data) { + Highcharts.data(Highcharts.extend(userOptions.data, { + complete: function (dataOptions) { + + // Merge series configs + if (userOptions.series) { + each(userOptions.series, function (series, i) { + userOptions.series[i] = Highcharts.merge(series, dataOptions.series[i]); + }); + } + + // Do the merge + userOptions = Highcharts.merge(dataOptions, userOptions); + + proceed.call(chart, userOptions, callback); + } + }), userOptions); + } else { + proceed.call(chart, userOptions, callback); + } + }); + +}(Highcharts)); -- Gitblit v1.8.0