diff --git a/dist/PublicLab.Grapher.js b/dist/PublicLab.Grapher.js index 7cf656f..603dfa8 100644 --- a/dist/PublicLab.Grapher.js +++ b/dist/PublicLab.Grapher.js @@ -1,1652 +1,2908 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= maxval) { - break; - } else if (this.completeCsvMatrix[i][j] !== null || this.completeCsvMatrix[i][j] !== undefined) { - if (typeof this.completeCsvMatrix[i][j] === 'number') { - bool = true; - } - - counter += 1; - csvSampleDataLocal[i].push(this.completeCsvMatrix[i][j]); - } - } - - if (bool) { - csvValidForYAxisLocal.push(this.csvHeaders[i]); - } - } - - totalDataLocal = [csvSampleDataLocal, csvValidForYAxisLocal]; - return totalDataLocal; - } //makes a 2D matrix with the transpose of the CSV file, each column having the same index as its column heading - - }, { - key: "matrixForCompleteData", - value: function matrixForCompleteData() { - var completeCsvMatrixLocal = []; - - for (var i = 0; i < this.csvHeaders.length; i++) { - completeCsvMatrixLocal[i] = []; - } - - for (var i = this.csvFileStart; i < this.csvMatrix.length; i++) { - for (var j = 0; j < this.csvHeaders.length; j++) { - completeCsvMatrixLocal[j].push(this.csvMatrix[i][j]); - } - } - - return completeCsvMatrixLocal; - } //Google Sheet's data is in a JSON, traversal through the JSON and string manipulation are used to extract the data - - }, { - key: "completeMatrixForGoogleSheet", - value: function completeMatrixForGoogleSheet() { - var matrixComplete = []; - - for (var i = 0; i < this.csvHeaders.length; i++) { - matrixComplete[i] = []; - } - - for (var i = 0; i < this.csvHeaders.length; i++) { - for (var key in this.csvFile) { - var valueCell = this.csvFile[key][this.csvHeaders[i]]["$t"]; - - if (!isNaN(valueCell)) { - matrixComplete[i].push(+valueCell); - } else { - matrixComplete[i].push(valueCell); - } - } - } - - for (var i = 0; i < this.csvHeaders.length; i++) { - this.csvHeaders[i] = this.csvHeaders[i].slice(4, this.csvHeaders[i].length); - } - - return matrixComplete; - } // matrix in JSON form for CODAP export - - }, { - key: "completeMatrixForCodap", - value: function completeMatrixForCodap() { - var codapMatrix = []; - - for (var i = 1; i < this.completeCsvMatrixTranspose.length; i++) { - var element = {}; - - for (var j = 0; j < this.csvHeaders.length; j++) { - element[this.csvHeaders[j]] = this.completeCsvMatrixTranspose[i][j]; - } - - codapMatrix.push(element); - } - - return codapMatrix; - } //checks if the first row has most of the potential header names, if not, assign dummy headers to the file. - - }, { - key: "determineHeaders", - value: function determineHeaders() { - var csvHeadersLocal = []; - var flag = false; - - for (var i = 0; i < this.csvMatrix[0].length; i++) { - if (i == 0) { - if (typeof this.csvMatrix[0][i] == "string") { - csvHeadersLocal[i] = this.csvMatrix[0][i]; - } else { - flag = true; - break; - } - } else { - if (_typeof(this.csvMatrix[0][i]) == _typeof(this.csvMatrix[0][i - 1]) && _typeof(this.csvMatrix[0][i]) != 'object' || _typeof(this.csvMatrix[0][i]) != _typeof(this.csvMatrix[0][i - 1]) && csvHeadersLocal[i - 1].substring(0, 6) == "Column") { - csvHeadersLocal[i] = this.csvMatrix[0][i]; - } //in case of an unnamed column - else if (_typeof(this.csvMatrix[0][i]) == 'object') { - csvHeadersLocal[i] = "Column" + (i + 1); - } else { - flag = true; - break; - } - } - } //if there are no headers present, make dummy header names - - - if (flag && csvHeadersLocal.length != this.csvMatrix[0].length) { - this.csvFileStart = 0; - - for (var i = 0; i < this.csvMatrix[0].length; i++) { - csvHeadersLocal[i] = "Column" + (i + 1); - } - } - - return csvHeadersLocal; - } //Google Sheet's data is in a JSON, extracting column names by string slicing - - }, { - key: "headersForGoogleSheet", - value: function headersForGoogleSheet() { - var headers_sheet = []; - - for (var key in this.csvFile) { - var h = this.csvFile[key]; - - for (var headKey in h) { - if (headKey.slice(0, 4) == "gsx$") { - headers_sheet.push(headKey); - } - } - - break; - } - - return headers_sheet; - } //determine a JSON for headers for CODAP - - }, { - key: "headersForCodap", - value: function headersForCodap() { - var codapHeaders = []; - - for (var i = 0; i < this.csvHeaders.length; i++) { - var element = {}; - element["name"] = this.csvHeaders[i]; - codapHeaders.push(element); - } - - return codapHeaders; - } // creating the transpose of the entire data ie complete data + headers, for createSpreadsheet in View.js - - }, { - key: "createTranspose", - value: function createTranspose() { - var completeCsvMatrixTransposeLocal = []; - - for (var i = 0; i <= this.completeCsvMatrix[0].length; i++) { - completeCsvMatrixTransposeLocal[i] = []; - } - - for (var i = 0; i < this.completeCsvMatrix.length; i++) { - completeCsvMatrixTransposeLocal[0][i] = this.csvHeaders[i]; - } - - for (var i = 0; i < this.completeCsvMatrix.length; i++) { - for (var j = 0; j < this.completeCsvMatrix[0].length; j++) { - completeCsvMatrixTransposeLocal[j + 1][i] = this.completeCsvMatrix[i][j]; - } - } - - return completeCsvMatrixTransposeLocal; - } - }]); - - return CsvParser; -}(); - -; -module.exports = CsvParser; -},{"./SimpleDataGrapher":4,"papaparse":11}],3:[function(require,module,exports){ -"use strict"; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var PlotlyjsPlotter = -/*#__PURE__*/ -function () { - _createClass(PlotlyjsPlotter, [{ - key: "determineType2", - value: function determineType2() { - if (this.graphType == "Horizontal" || this.graphType == "Vertical") { - return "bar"; - } else if (this.graphType == "Pie" || this.graphType == "Doughnut" || this.graphType == "Radar") { - return "pie"; - } else if (this.graphType == "Basic" || this.graphType == "Stepped" || this.graphType == "Point") { - return "scatter"; - } - } - }, { - key: "layoutMaker", - value: function layoutMaker() { - var layout = {}; - - if (this.graphType == "Horizontal" || this.graphType == "Vertical") { - layout["barmode"] = "group"; - } - - return layout; - } - }, { - key: "traceMaker", - value: function traceMaker() { - var trace = {}; - trace["type"] = this.determineType2(); - - if (this.graphType == "Horizontal") { - trace["orientation"] = "h"; - } else if (this.graphType == "Doughnut") { - trace["hole"] = 0.5; - } else if (this.graphType == "Basic") { - trace["mode"] = "lines"; - } else if (this.graphType == "Point") { - trace["mode"] = "markers"; - } else if (this.graphType == "Stepped") { - trace["mode"] = "lines+markers"; - trace["line"] = { - "shape": 'hv' - }; - } - - return trace; - } - }, { - key: "keyDeterminer", - value: function keyDeterminer() { - var keys = ["x", "y"]; - - if (this.graphType == "Pie" || this.graphType == "Doughnut") { - keys[1] = "values"; - keys[0] = "labels"; - } else if (this.graphType == "Horizontal") { - keys[0] = "y"; - keys[1] = "x"; - } - - return keys; - } - }, { - key: "plotGraph2", - value: function plotGraph2() { - if (this.flag) { - document.getElementById(this.canvasContainerId).innerHTML = ""; - } - - var layout = this.layoutMaker(); - var data = []; - var keySet = this.keyDeterminer(); - - for (var i = 0; i < this.length; i++) { - var new_trace = this.traceMaker(); - new_trace[keySet[0]] = this.dataHash['x_axis_labels']; - new_trace[keySet[1]] = this.dataHash['y_axis_values' + i]; - new_trace["name"] = this.dataHash['labels'][1][i]; - data.push(new_trace); - } - - var div = document.createElement('div'); - div.id = this.elementId + '_chart_container_' + this.graphCounting; - document.getElementById(this.canvasContainerId).appendChild(div); - Plotly.newPlot(div.id, data, layout); - } - }]); - - function PlotlyjsPlotter(hash, length, type, flag, canvasContainerId, elementId, graphCounting) { - _classCallCheck(this, PlotlyjsPlotter); - - _defineProperty(this, 'use strict', void 0); - - _defineProperty(this, "dataHash", {}); - - _defineProperty(this, "elementId", null); - - _defineProperty(this, "graphCounting", 0); - - _defineProperty(this, "canvasContainerId", null); - - _defineProperty(this, "graphType", null); - - _defineProperty(this, "length", 0); - - _defineProperty(this, "flag", false); - - this.dataHash = hash; - this.length = length; - this.graphType = type; - this.flag = flag; - this.canvasContainerId = canvasContainerId; - this.elementId = elementId; - this.graphCounting = graphCounting; - this.plotGraph2(); - } - - return PlotlyjsPlotter; -}(); - -module.exports = PlotlyjsPlotter; -},{}],4:[function(require,module,exports){ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SimpleDataGrapher = void 0; - -var _View = require("./View"); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var SimpleDataGrapher = function SimpleDataGrapher(elementId) { - _classCallCheck(this, SimpleDataGrapher); - - _defineProperty(this, 'use strict', void 0); - - _defineProperty(this, "elementId", null); - - _defineProperty(this, "view", null); - - this.elementId = elementId; - SimpleDataGrapher.elementIdSimpleDataGraphInstanceMap[this.elementId] = this; - this.view = new _View.View(elementId); -}; - -exports.SimpleDataGrapher = SimpleDataGrapher; - -_defineProperty(SimpleDataGrapher, "elementIdSimpleDataGraphInstanceMap", {}); - -; -window.SimpleDataGrapher = SimpleDataGrapher; -},{"./View":5}],5:[function(require,module,exports){ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.View = void 0; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var CsvParser = require('./CsvParser'); - -var SimpleDataGrapher = require('./SimpleDataGrapher'); - -var ChartjsPlotter = require('./ChartjsPlotter'); - -var PlotlyjsPlotter = require('./PlotlyjsPlotter'); - -var iframe_phone = require('iframe-phone'); - -var View = -/*#__PURE__*/ -function () { - _createClass(View, [{ - key: "handleFileSelectlocal", - //extracts the uploaded file from input field and creates an object of CsvParser class with the file as one of the parameters - value: function handleFileSelectlocal(event) { - this.csvFile = event.target.files[0]; - - if (this.csvFile['name'].split(".")[1] != "csv") { - alert("Invalid file type"); - } else { - $('#' + this.dragDropHeadingId).text(this.csvFile['name']); - var self = this; - - document.getElementById(this.uploadButtonId).onclick = function (e) { - self.csvParser = new CsvParser(self.csvFile, self.elementId, "local"); - }; - } - } //receives the string value and creates an object of CsvParser class with the string as one of the parameters - - }, { - key: "handleFileSelectstring", - value: function handleFileSelectstring(val) { - // var csv_string = val.split("\n"); - this.csvFile = val; - var self = this; - - document.getElementById(this.uploadButtonId).onclick = function (e) { - self.csvParser = new CsvParser(self.csvFile, self.elementId, "csvstring"); - }; - } // function for using a previously uploaded and saved file from the data base - - }, { - key: "usingPreviouslyUploadedFile", - value: function usingPreviouslyUploadedFile() { - var self = this; - self.csvParser = new CsvParser("dummy", self.elementId, "prevfile"); - } //receives the JSON file value and creates an object of CsvParser class with the file as one of the parameters - - }, { - key: "handleFileSelectGoogleSheet", - value: function handleFileSelectGoogleSheet(googleSheetData) { - this.csvFile = googleSheetData; - var self = this; - - document.getElementById(this.uploadButtonId).onclick = function (e) { - self.csvParser = new CsvParser(self.csvFile, self.elementId, "googleSheet"); - }; - } // get's the JSON form of the Google Sheet through Google Sheet's URL and passes it to the handler - - }, { - key: "getValueGoogleSheet", - value: function getValueGoogleSheet(googleSheetLink) { - var self = this; - $.getJSON(googleSheetLink, function (data) { - self.handleFileSelectGoogleSheet(data.feed.entry); - }); - } // uses a CORS proxy to fetch the value of a remote files and passes the received value to a callback function - - }, { - key: "sendRemoteFileToHandler", - value: function sendRemoteFileToHandler(val) { - var _this = this; - - var proxyurl = "https://cors-anywhere.herokuapp.com/"; - var url = val; - fetch(proxyurl + url).then(function (response) { - return response.text(); - }).then(function (contents) { - return _this.handleFileSelectremote(contents); - })["catch"](function (e) { - return console.log(e); - }); - } // callback function which receives the remote file's value and creates an object of CsvParser class with the file as one of the parameters - - }, { - key: "handleFileSelectremote", - value: function handleFileSelectremote(remoteVal) { - this.csvFile = remoteVal; - var self = this; - - document.getElementById(this.uploadButtonId).onclick = function (e) { - self.csvParser = new CsvParser(self.csvFile, self.elementId, "remote"); - }; - } // adapter function which switches between Plotly.js and Chart.js as a graph plotting library and creates theri respective objects which take over the graph plotting - - }, { - key: "plotGraph", - value: function plotGraph(hash, length, type, flag, library) { - if (library == "chartjs") { - this.chartjsPlotter = new ChartjsPlotter(hash, length, type, flag, this.canvasContinerId, this.elementId, this.graphCounting); - } else { - this.plotlyjsPlotter = new PlotlyjsPlotter(hash, length, type, flag, this.canvasContinerId, this.elementId, this.graphCounting); - } - - $('.' + this.carousalClass).carousel(2); - } //set tool tip for impot options - - }, { - key: "setTooltip", - value: function setTooltip(importType) { - if (importType === "container_drag_drop") { - return "Select a local file from your system"; - } else if (importType === "container_csv_string") { - var x = "Type in or Paste a CSV string. \r\n"; - x += "Example: \r\n"; - x += "A,B,C \r\n"; - x += "1,2,3"; - return x; - } else if (importType === "container_remote_link") { - return "Type in or Paste the link of a remote CSV file. Example: \ - http://example.com/example.csv"; - } else if (importType === "container_google_sheet") { - return "Type in or Paste the link of a Published Google Sheet. To publish a Google Sheet: 1. File -> Publish to the web -> Publish 2. Share -> Get shareable link -> Anyone with the link can -> More -> On - Public on the web -> Save 3. Copy link"; - } - } //set tool tip for graph tips - - }, { - key: "setTooltipGraph", - value: function setTooltipGraph(graphType) { - if (graphType == "Horizontal") { - return "Data is categorical and tells how many, widths proportional to the values"; - } else if (graphType === "Vertical") { - return "Data is categorical and tells how many, heights proportional to the values"; - } else if (graphType == "Stacked") { - return "Ideal for comparing the total amounts across each group/segmented bar"; - } else if (graphType == "Basic") { - return "Used to visualize a trend in data over intervals of time or to see the growth of a quantity"; - } else if (graphType == "Stepped") { - return "Vertical parts of a step chart denote changes in the data and their magnitude"; - } else if (graphType == "Point") { - return "Used to show the relationship between two data variables"; - } else if (graphType == "Pie") { - return "Used to show percentage or proportional data, should be used for less number of categories"; - } else if (graphType == "Doughnut") { - return "Used to show percentage or proportional data, but have better data intensity ratio and space efficiency"; - } else if (graphType == "Radar") { - return "Used to display multivariate observations with an arbitrary number of variables"; - } - } // create a popover against each import method for adding a file title and description - - }, { - key: "createPopover", - value: function createPopover(buttonId) { - var self = this; - var html = '
'; - $('#' + buttonId).popover({ - placement: 'bottom', - title: 'Add Description', - html: true, - content: html - }).on('click', function () { - $('#save').click(function (e) { - e.preventDefault(); - self.fileTitle = $('#' + "title" + buttonId).val(); - self.fileDescription = $('#' + "desc" + buttonId).val(); - }); - }); - } // renders the required buttons for saving the files if the use is logged in - - }, { - key: "createButtons", - value: function createButtons(userLoginCheck) { - this.listenersForIntegration(); - - if (userLoginCheck == "yes") { - var save_file_button = document.createElement('button'); - save_file_button.classList.add("btn"); - save_file_button.classList.add("btn-primary"); - save_file_button.innerHTML = "Save CSV"; - save_file_button.id = this.elementId + "_save_CSV"; - var upload_prev_file = document.createElement('button'); - upload_prev_file.classList.add("btn"); - upload_prev_file.classList.add("btn-primary"); - upload_prev_file.innerHTML = "Choose a previously uploaded file"; - upload_prev_file.id = this.elementId + "_prev_file"; - var publish_research_button = document.createElement('button'); - publish_research_button.classList.add("btn"); - publish_research_button.classList.add("btn-primary"); - publish_research_button.innerHTML = "Publish as a Research Note"; - publish_research_button.id = this.elementId + "_publish"; - var container = document.getElementById(this.upload_button_container); - var div_container = document.createElement('div'); - div_container.appendChild(save_file_button); - div_container.appendChild(upload_prev_file); - var container2 = document.getElementById(this.feature_button_container); - container2.appendChild(publish_research_button); - container.prepend(div_container); - } - } // create dataset for CODAP table - - }, { - key: "createDataset", - value: function createDataset() { - var dataset = {}; - dataset["action"] = "create"; - dataset["resource"] = "dataContext"; - var values = {}; - values["name"] = "my dataset"; - values["title"] = "Case Table"; - var collections = []; - var hashCollections = {}; - hashCollections["name"] = "cases"; - hashCollections["attrs"] = this.csvParser.codapHeaders; - collections.push(hashCollections); - values["collections"] = collections; - dataset["values"] = values; - var dataset2 = {}; - dataset2["action"] = "create"; - dataset2["resource"] = "dataContext[my dataset].item"; - dataset2["values"] = this.csvParser.codapMatrix; - var dataset3 = {}; - dataset3["action"] = "create"; - dataset3["resource"] = "component"; - var values3 = {}; - values3["type"] = "caseTable"; - values3["dataContext"] = "my dataset"; - dataset3["values"] = values3; - return [dataset, dataset2, dataset3]; - } - }, { - key: "iframePhoneHandler", - value: function iframePhoneHandler() {} //callbackforCODAP - // renders the iframe for CODAP export - - }, { - key: "codapExport", - value: function codapExport() { - var self = this; - var iframeBody = ''; - var modal_body = document.getElementById("body_for_CODAP"); - modal_body.innerHTML = iframeBody; - var iframe = document.getElementById("codap-iframe"); - modal_body.style.height = "500px"; - iframe.style.width = "750px"; - iframe.style.height = "90%"; - var codapIframe = document.getElementById('codap-iframe'); - var rpcHandler = new iframe_phone.IframePhoneRpcEndpoint(self.iframePhoneHandler, "data-interactive", codapIframe); - var createCodapButton = document.createElement("button"); - createCodapButton.classList.add("btn"); - createCodapButton.classList.add("btn-primary"); - createCodapButton.innerHTML = "Go!"; - createCodapButton.id = this.elementId + "_create_codap"; - modal_body.prepend(createCodapButton); - var apiCall = this.createDataset(); - $("#" + this.elementId + "_create_codap").click(function () { - rpcHandler.call(apiCall, function (resp) { - console.log('Response:' + JSON.stringify(resp)); - }); - }); - } // creates a downloadable spreadsheet for the imported data using SheetJS - - }, { - key: "createSheet", - value: function createSheet() { - var wb = XLSX.utils.book_new(); - wb.Props = { - Title: "New Spreadsheet" + this.elementId, - CreatedDate: new Date() - }; - wb.SheetNames.push("Sheet" + this.elementId); - var ws_data = this.csvParser.completeCsvMatrixTranspose; - var ws = XLSX.utils.aoa_to_sheet(ws_data); - wb.Sheets["Sheet" + this.elementId] = ws; - var wbout = XLSX.write(wb, { - bookType: 'xlsx', - type: 'binary' - }); - - function s2ab(s) { - var buf = new ArrayBuffer(s.length); - var view = new Uint8Array(buf); - - for (var i = 0; i < s.length; i++) { - view[i] = s.charCodeAt(i) & 0xFF; - } - - return buf; - } - - saveAs(new Blob([s2ab(wbout)], { - type: "application/octet-stream" - }), 'newSpreadsheet' + this.elementId + '.xlsx'); - } // creates a hash of the entire data in an accesible format for the charting libraries {labels: [legendx, [legendy0, legendy1 ... lengendyn]], x_axis_values: [...], y_axis_0: [...], y_axis_1: [...], ... y_axis_n: [...]} n: selected number of columns - // flag is just for seeing if we're plotting the graph for the first time, if yes, we will have to clear the canvas. - - }, { - key: "afterSampleData", - value: function afterSampleData(flag, type) { - var _this2 = this; - - document.getElementById(this.plotGraphId).onclick = function (e) { - e.preventDefault(); - var hash = {}; - var ix = $('input[name=' + _this2.tableXInputName + ']:checked').val(); - hash["x_axis_labels"] = _this2.csvParser.completeCsvMatrix[ix]; - var columns = new Array(); - var y_axis_names = new Array(); - $("input:checkbox[name=" + _this2.tableYInputName + "]:checked").each(function (index, element) { - columns.push(element.value); - }); - - for (var i = 0; i < columns.length; i++) { - hash["y_axis_values" + i] = _this2.csvParser.completeCsvMatrix[columns[i]]; - y_axis_names.push(_this2.csvParser.csvHeaders[columns[i]]); - } - - var labels = [_this2.csvParser.csvHeaders[ix], y_axis_names]; - hash["labels"] = labels; - var selectedGraph = $('.selected'); - var type = selectedGraph.attr('data-value'); - - _this2.plotGraph(hash, columns.length, type, flag, "plotly"); - }; - } // generates a graph menu with different graph options - - }, { - key: "graphMenu", - value: function graphMenu(flag) { - var self = this; - $('.' + this.carousalClass).carousel(1); - var menuDiv = document.getElementById("menu_holder"); - menuDiv.innerHTML = '

blahhhhh

Horizontal Bar

Vertical Bar

Stacked Bar

Basic Line

Stepped Line

Point

Pie

Doughnut

Radar

blahhh

'; - $('.radio-group .radio').click(function () { - $(this).parent().find('.radio').removeClass('selected'); - var l = document.getElementsByClassName('hmm'); - - for (var i = 0; i < l.length; i++) { - l[i].style.backgroundColor = "#cccccc"; - } - - $(this).addClass('selected'); - var type = $(this).attr('data-value'); - $('#' + type + "Type").css('backgroundColor', '#1ad1ff'); - }); - $('.radio').hover(function () { - var tooltipVal = self.setTooltipGraph($(this).attr('data-value')); - $('#graph_description').text(tooltipVal); - $('#graph_description').css({ - opacity: 0.0, - visibility: "visible" - }).animate({ - opacity: 1.0 - }, 800); - }, function () { - $('#graph_description').css('visibility', 'hidden'); - }); - this.afterSampleData(flag); - } // generates the sample table data with checkboxes for y-axis and radio buttons for x-axis - - }, { - key: "tableGenerator", - value: function tableGenerator(name, tableId, typeOfInput, validValues, flag, tableType, badgeType) { - document.getElementById(tableId).innerHTML = ""; - var trhead = document.createElement('tr'); - - for (var i = 0; i < this.csvParser.csvHeaders.length; i++) { - var td = document.createElement('td'); - var span = document.createElement('span'); - var textnode = document.createTextNode(this.csvParser.csvHeaders[i]); - span.appendChild(textnode); - span.classList.add("badge"); - span.classList.add("badge-pill"); - span.classList.add(badgeType); - td.appendChild(span); - - for (var j = 0; j < validValues.length; j++) { - if (validValues[j] == this.csvParser.csvHeaders[i]) { - var checkbox = document.createElement('input'); - checkbox.type = typeOfInput; - checkbox.value = i; - checkbox.name = name; - checkbox.id = name + i; - checkbox.classList.add("check-inputs"); - span.appendChild(checkbox); - } - } - - trhead.appendChild(td); - } - - trhead.classList.add(tableType); - document.getElementById(tableId).appendChild(trhead); - - for (var i = 0; i < this.csvParser.csvSampleData[0].length; i++) { - var tr = document.createElement('tr'); - - for (var j = 0; j < this.csvParser.csvHeaders.length; j++) { - var td = document.createElement('td'); - td.appendChild(document.createTextNode(this.csvParser.csvSampleData[j][i])); - tr.appendChild(td); - } - - document.getElementById(tableId).appendChild(tr); - } - - this.graphMenu(flag); - } // renders the sample tables - - }, { - key: "showSampleDataXandY", - value: function showSampleDataXandY() { - var _this3 = this; - - document.getElementById(this.addGraphButtonId).onclick = function (e) { - _this3.graphCounting++; - $('.' + _this3.carousalClass).carousel(1); /// ---------------> after - - _this3.tableGenerator(_this3.tableXInputName, _this3.tableXId, 'radio', _this3.csvParser.csvHeaders, false, 'table-success', 'badge-success'); - - _this3.tableGenerator(_this3.tableYInputName, _this3.tableYId, 'checkbox', _this3.csvParser.csvValidForYAxis, false, 'table-warning', 'badge-warning'); - - _this3.graphMenu(); - }; - - this.tableGenerator(this.tableXInputName, this.tableXId, 'radio', this.csvParser.csvHeaders, true, 'table-success', 'badge-success'); - this.tableGenerator(this.tableYInputName, this.tableYId, 'checkbox', this.csvParser.csvValidForYAxis, true, 'table-warning', 'badge-warning'); - this.graphMenu(); - } // view manipulation resumes after the CsvParser object is created and returned - - }, { - key: "continueViewManipulation", - value: function continueViewManipulation(x) { - if (x != "prevfile") { - this.csvParser = x; - } - - this.showSampleDataXandY(); // this.showSampleDataXandY(this.csvParser.csvSampleData, this.csvParser.csvHeaders, this.csvParser.csvValidForYAxis, this.csvParser.csvSampleData); - // sampleDataXandY(this.csvSampleData,this.csvHeaders,this.csvValidForYAxis,this.completeCsvMatrix); - // matrixForCompleteData(headers,this.csvMatrix,start); - } - }, { - key: "listenersForIntegration", - value: function listenersForIntegration() { - var _this4 = this; - - $("#" + this.fileUploadId).change(function (e) { - document.getElementById("popover" + _this4.fileUploadId).style.display = "inline"; - document.getElementById("popover" + _this4.csvStringUploadId).style.display = "none"; - document.getElementById("popover" + _this4.googleSheetUploadId).style.display = "none"; - document.getElementById("popover" + _this4.remoteFileUploadId).style.display = "none"; - - _this4.createPopover("popover" + _this4.fileUploadId); - - _this4.handleFileSelectlocal(e); - }); - $("#" + this.csvStringUploadId).change(function () { - document.getElementById("popover" + _this4.csvStringUploadId).style.display = "inline"; - document.getElementById("popover" + _this4.googleSheetUploadId).style.display = "none"; - document.getElementById("popover" + _this4.remoteFileUploadId).style.display = "none"; - document.getElementById("popover" + _this4.fileUploadId).style.display = "none"; - - _this4.createPopover("popover" + _this4.csvStringUploadId); - - _this4.handleFileSelectstring(document.getElementById(_this4.csvStringUploadId).value); - }); - $("#" + this.googleSheetUploadId).change(function () { - document.getElementById("popover" + _this4.googleSheetUploadId).style.display = "inline"; - document.getElementById("popover" + _this4.csvStringUploadId).style.display = "none"; - document.getElementById("popover" + _this4.remoteFileUploadId).style.display = "none"; - document.getElementById("popover" + _this4.fileUploadId).style.display = "none"; - - _this4.createPopover("popover" + _this4.googleSheetUploadId); - - var sheetLink = document.getElementById(_this4.googleSheetUploadId).value; - var sheetURL = "https://spreadsheets.google.com/feeds/list/" + sheetLink.split("/")[5] + "/od6/public/values?alt=json"; - - _this4.getValueGoogleSheet(sheetURL); - }); - $("#" + this.remoteFileUploadId).change(function () { - document.getElementById("popover" + _this4.remoteFileUploadId).style.display = "inline"; - document.getElementById("popover" + _this4.csvStringUploadId).style.display = "none"; - document.getElementById("popover" + _this4.googleSheetUploadId).style.display = "none"; - document.getElementById("popover" + _this4.fileUploadId).style.display = "none"; - - _this4.createPopover("popover" + _this4.remoteFileUploadId); - - _this4.sendRemoteFileToHandler(document.getElementById(_this4.remoteFileUploadId).value); - }); - } - }]); - - function View(elementId) { - var _this5 = this; - - _classCallCheck(this, View); - - _defineProperty(this, 'use strict', void 0); - - _defineProperty(this, "elementId", null); - - _defineProperty(this, "element", null); - - _defineProperty(this, "fileUploadId", null); - - _defineProperty(this, "remoteFileUploadId", null); - - _defineProperty(this, "csvStringUploadId", null); - - _defineProperty(this, "googleSheetUploadId", null); - - _defineProperty(this, "csvFile", null); - - _defineProperty(this, "dragDropHeadingId", null); - - _defineProperty(this, "uploadButtonId", null); - - _defineProperty(this, "csvParser", null); - - _defineProperty(this, "chartjsPlotter", null); - - _defineProperty(this, "plotlyjsPlotter", null); - - _defineProperty(this, "graphCounting", 0); - - _defineProperty(this, "addGraphButtonId", null); - - _defineProperty(this, "tableXId", null); - - _defineProperty(this, "tableYId", null); - - _defineProperty(this, "tableXInputName", null); - - _defineProperty(this, "tableYInputName", null); - - _defineProperty(this, "carousalClass", null); - - _defineProperty(this, "carousalId", null); - - _defineProperty(this, "graphMenuId", null); - - _defineProperty(this, "plotGraphId", null); - - _defineProperty(this, "graphMenuTypeInputName", null); - - _defineProperty(this, "canvasContinerId", null); - - _defineProperty(this, "xyToggle", null); - - _defineProperty(this, "xyToggleName", null); - - _defineProperty(this, "tableXParentId", null); - - _defineProperty(this, "tableYParentId", null); - - _defineProperty(this, "upload_button_container", null); - - _defineProperty(this, "fileTitle", ""); - - _defineProperty(this, "fileDescription", ""); - - _defineProperty(this, "codapExportButton", null); - - this.elementId = elementId; - this.element = document.getElementById(elementId); - - if (this.element == null) { - throw "No element exist with this id"; - } - - this.fileUploadId = elementId + "_csv_file"; - this.remoteFileUploadId = elementId + "_remote_file"; - this.csvStringUploadId = elementId + "_csv_string"; - this.googleSheetUploadId = elementId + "_google_sheet"; - this.dragDropHeadingId = elementId + "_drag_drop_heading"; - this.uploadButtonId = elementId + "_file_upload_button"; - this.addGraphButtonId = elementId + "_add_graph"; - this.createSpreadsheetButtonId = elementId + "_save_as_spreadsheet"; - this.tableXId = elementId + "_tableX"; - this.tableYId = elementId + "_tableY"; - this.tableXParentId = elementId + "_Xtable"; - this.tableYParentId = elementId + "_Ytable"; - this.tableXInputName = elementId + "_x_axis_input_columns"; - this.tableYInputName = elementId + "_y_axis_input_columns"; - this.carousalClass = elementId + "_carousal"; - this.carousalId = elementId + "_carousalId"; - this.graphMenuId = elementId + "_graph_menu"; - this.plotGraphId = elementId + "_plot_graph"; - this.graphMenuTypeInputName = elementId + "_types"; - this.canvasContinerId = elementId + "_canvas_container"; - this.xyToggleName = elementId + "_xytoggle"; - this.saveAsImageId = elementId + "save-as-image"; - this.upload_button_container = elementId + "upload_button_container"; - this.feature_button_container = elementId + "feature_button_container"; - this.codapExportButton = elementId + "codap_export_button"; - this.drawHTMLView(); - this.addListeners(); - var self = this; - $('.xytoggle').bootstrapToggle({ - on: 'X-Axis', - off: 'Y-Axis' - }); - $('input[name=' + this.xyToggleName + ']:checked').change(function () { - var ixy = $('input[name=' + _this5.xyToggleName + ']:checked').val(); - var ixx = 0; - - if (ixy == undefined) { - ixx = 1; - } - - $('#' + _this5.tableXParentId).toggle(ixx === 0); - $('#' + _this5.tableYParentId).toggle(ixx === 1); - }); - $('.imports').hover(function () { - var tooltipVal = self.setTooltip(this.classList[0]); - $('#import_description').text(tooltipVal); - $('#import_description').css({ - opacity: 0.0, - visibility: "visible" - }).animate({ - opacity: 1.0 - }, 800); - }, function () { - $('#import_description').css('visibility', 'hidden'); - }); - } //listen for different inputs for import by the user - - - _createClass(View, [{ - key: "addListeners", - value: function addListeners() { - var _this6 = this; - - $("#" + this.fileUploadId).change(function (e) { - _this6.handleFileSelectlocal(e); - }); - $("#" + this.csvStringUploadId).change(function () { - _this6.handleFileSelectstring(document.getElementById(_this6.csvStringUploadId).value); - }); - $("#" + this.googleSheetUploadId).change(function () { - var sheetURL = "https://spreadsheets.google.com/feeds/list/" + sheetLink.split("/")[5] + "/od6/public/values?alt=json"; - - _this6.getValueGoogleSheet(sheetURL); - }); - $("#" + this.remoteFileUploadId).change(function () { - _this6.sendRemoteFileToHandler(document.getElementById(_this6.remoteFileUploadId).value); - }); - $("#" + this.createSpreadsheetButtonId).click(function () { - _this6.createSheet(); - }); - $("#" + this.codapExportButton).click(function () { - _this6.codapExport(); - }); - } //renders the entire HTML view - - }, { - key: "drawHTMLView", - value: function drawHTMLView() { - this.element.innerHTML = '

Simple Data Grapher

A JavaScript library that turns uploaded CSV files into customizable graphs within a few simple steps. Can be embedded on other websites!

Open Source by Public Lab

  • Upload CSV Data
  • Select Columns & Graph Type
  • Plotted Graph & Export Options
'; - } - }]); - - return View; -}(); - -exports.View = View; -},{"./ChartjsPlotter":1,"./CsvParser":2,"./PlotlyjsPlotter":3,"./SimpleDataGrapher":4,"iframe-phone":10}],6:[function(require,module,exports){ -var structuredClone = require('./structured-clone'); -var HELLO_INTERVAL_LENGTH = 200; -var HELLO_TIMEOUT_LENGTH = 60000; - -function IFrameEndpoint() { - var listeners = {}; - var isInitialized = false; - var connected = false; - var postMessageQueue = []; - var helloInterval; - - function postToParent(message) { - // See http://dev.opera.com/articles/view/window-postmessage-messagechannel/#crossdoc - // https://github.com/Modernizr/Modernizr/issues/388 - // http://jsfiddle.net/ryanseddon/uZTgD/2/ - if (structuredClone.supported()) { - window.parent.postMessage(message, '*'); - } else { - window.parent.postMessage(JSON.stringify(message), '*'); - } - } - - function post(type, content) { - var message; - // Message object can be constructed from 'type' and 'content' arguments or it can be passed - // as the first argument. - if (arguments.length === 1 && typeof type === 'object' && typeof type.type === 'string') { - message = type; - } else { - message = { - type: type, - content: content - }; - } - if (connected) { - postToParent(message); - } else { - postMessageQueue.push(message); - } - } - - function postHello() { - postToParent({ - type: 'hello' - }); - } - - function addListener(type, fn) { - listeners[type] = fn; - } - - function removeAllListeners() { - listeners = {}; - } - - function getListenerNames() { - return Object.keys(listeners); - } - - function messageListener(message) { - // Anyone can send us a message. Only pay attention to messages from parent. - if (message.source !== window.parent) return; - var messageData = message.data; - if (typeof messageData === 'string') messageData = JSON.parse(messageData); - - if (!connected && messageData.type === 'hello') { - connected = true; - stopPostingHello(); - while (postMessageQueue.length > 0) { - post(postMessageQueue.shift()); - } - } - - if (connected && listeners[messageData.type]) { - listeners[messageData.type](messageData.content); - } - } - - function disconnect() { - connected = false; - stopPostingHello(); - window.removeEventListener('message', messsageListener); - } - - /** +(function () { + function r(e, n, t) { + function o(i, f) { + if (!n[i]) { + if (!e[i]) { + var c = 'function' == typeof require && require; + if (!f && c) return c(i, !0); + if (u) return u(i, !0); + var a = new Error( + "Cannot find module '" + i + "'" + ); + throw ((a.code = 'MODULE_NOT_FOUND'), a); + } + var p = (n[i] = { exports: {} }); + e[i][0].call( + p.exports, + function (r) { + var n = e[i][1][r]; + return o(n || r); + }, + p, + p.exports, + r, + e, + n, + t + ); + } + return n[i].exports; + } + for ( + var u = 'function' == typeof require && require, + i = 0; + i < t.length; + i++ + ) + o(t[i]); + return o; + } + return r; +})()( + { + 1: [ + function (require, module, exports) { + 'use strict'; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError( + 'Cannot call a class as a function' + ); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = + descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty( + target, + descriptor.key, + descriptor + ); + } + } + + function _createClass( + Constructor, + protoProps, + staticProps + ) { + if (protoProps) + _defineProperties( + Constructor.prototype, + protoProps + ); + if (staticProps) + _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true, + }); + } else { + obj[key] = value; + } + return obj; + } + + var ChartjsPlotter = + /*#__PURE__*/ + (function () { + _createClass(ChartjsPlotter, [ + { + key: 'determineType', + value: function determineType() { + if ( + this.graphType == 'Basic' || + this.graphType == 'Stepped' || + this.graphType == 'Point' + ) { + return 'line'; + } else if ( + this.graphType == 'Horizontal' + ) { + return 'horizontalBar'; + } else if (this.graphType == 'Vertical') { + return 'bar'; + } else { + return this.graphType.toLowerCase(); + } + }, + }, + { + key: 'colorGenerator', + value: function colorGenerator( + i, + tb, + count + ) { + var colors = [ + 'rgba(255, 77, 210, 0.5)', + 'rgba(0, 204, 255, 0.5)', + 'rgba(128, 0, 255, 0.5)', + 'rgba(255, 77, 77, 0.5)', + 'rgba(0, 179, 0, 0.5)', + 'rgba(255, 255, 0, 0.5)', + 'rgba(255, 0, 102, 0.5)', + 'rgba(0, 115, 230, 0.5)', + ]; + var bordercolors = [ + 'rgb(255, 0, 191)', + 'rgb(0, 184, 230)', + 'rgb(115, 0, 230)', + 'rgb(255, 51, 51)', + 'rgb(0, 153, 0)', + 'rgb(230, 230, 0)', + 'rgb(230, 0, 92)', + 'rgb(0, 102, 204)', + ]; + var length = 8; + + if ( + this.graphType == 'Pie' || + this.graphType == 'Doughnut' + ) { + var colorSet = []; + var borderColorSet = []; + + for (var j = 0; j < count; j++) { + colorSet.push(colors[j % length]); + borderColorSet.push( + bordercolors[j % length] + ); + } + + if (tb == 'bg') { + return colorSet; + } else { + return borderColorSet; + } + } else { + if (tb == 'bg') { + return colors[i % length]; + } else { + return bordercolors[i % length]; + } + } + }, + }, + { + key: 'determineData', + value: function determineData(i) { + var h = {}; + + if (this.graphType == 'Basic') { + h['fill'] = false; + } else if (this.graphType == 'Stepped') { + h['steppedLine'] = true; + h['fill'] = false; + } else if (this.graphType == 'Point') { + h['showLine'] = false; + h['pointRadius'] = 10; + } + + h['backgroundColor'] = + this.colorGenerator( + i, + 'bg', + this.dataHash['y_axis_values' + i] + .length + ); + h['borderColor'] = this.colorGenerator( + i, + 'bo', + this.dataHash['y_axis_values' + i] + .length + ); + h['borderWidth'] = 1; + h['label'] = + this.dataHash['labels'][1][i]; + h['data'] = + this.dataHash['y_axis_values' + i]; + return h; + }, + }, + { + key: 'determineConfig', + value: function determineConfig() { + var config = {}; + config['type'] = this.determineType(); + var data = {}; + data['labels'] = + this.dataHash['x_axis_labels']; + var datasets = []; + + for (var i = 0; i < this.length; i++) { + var h = this.determineData(i); + datasets.push(h); + } + + var options = { + responsive: true, + maintainAspectRatio: true, + chartArea: { + backgroundColor: 'rgb(204, 102, 255)', + }, + }; + options['scales'] = this.scales(); + config['options'] = options; + data['datasets'] = datasets; + config['data'] = data; + return config; + }, + }, + { + key: 'scales', + value: function scales() { + var scales = { + xAxes: [ + { + display: true, + scaleLabel: { + display: true, + labelString: + this.dataHash['labels'][0], + }, + }, + ], + yAxes: [ + { + display: true, + scaleLabel: { + display: true, + labelString: 'Value', + }, + }, + ], + }; + return scales; + }, + }, + { + key: 'saveAsImageFunction', + value: function saveAsImageFunction( + canvId + ) { + var newDate = new Date(); + var timestamp = newDate.getTime(); + var temp = canvId; + temp = '#' + temp; + $(temp) + .get(0) + .toBlob(function (blob) { + saveAs(blob, 'chart' + timestamp); + }); + }, + }, + { + key: 'createSaveAsImageButton', + value: function createSaveAsImageButton( + canvasDiv, + canvasId + ) { + var saveImageButton = + document.createElement('BUTTON'); + saveImageButton.classList.add('btn'); + saveImageButton.classList.add( + 'btn-primary' + ); + saveImageButton.innerHTML = + 'Save as Image'; + saveImageButton.id = canvasId + 'image'; + canvasDiv.appendChild(saveImageButton); + var self = this; + + document.getElementById( + saveImageButton.id + ).onclick = function (e) { + self.saveAsImageFunction(canvasId); + }; + }, + }, + { + key: 'plotGraph', + value: function plotGraph() { + if (this.flag) { + document.getElementById( + this.canvasContainerId + ).innerHTML = ''; + } + + var div = document.createElement('div'); + div.classList.add( + this.elementId + + '_chart_container_' + + this.graphCounting + ); + var canv = + document.createElement('canvas'); + canv.id = + this.elementId + + '_canvas_' + + this.graphCounting; + div.appendChild(canv); + document + .getElementById(this.canvasContainerId) + .appendChild(div); + var ctx = canv.getContext('2d'); + var configuration = + this.determineConfig(); + new Chart(ctx, configuration); + this.createSaveAsImageButton( + div, + canv.id + ); // $('.'+this.carousalClass).carousel(2); + }, + }, + ]); + + function ChartjsPlotter( + hash, + length, + type, + flag, + canvasContainerId, + elementId, + graphCounting + ) { + _classCallCheck(this, ChartjsPlotter); + + _defineProperty(this, 'use strict', void 0); + + _defineProperty(this, 'dataHash', {}); + + _defineProperty(this, 'elementId', null); + + _defineProperty(this, 'graphCounting', 0); + + _defineProperty( + this, + 'canvasContainerId', + null + ); + + _defineProperty(this, 'graphType', null); + + _defineProperty(this, 'length', 0); + + _defineProperty(this, 'flag', false); + + this.dataHash = hash; + this.length = length; + this.graphType = type; + this.flag = flag; + this.canvasContainerId = canvasContainerId; + this.elementId = elementId; + this.graphCounting = graphCounting; + this.plotGraph(); + } + + return ChartjsPlotter; + })(); + + module.exports = ChartjsPlotter; + }, + {}, + ], + 2: [ + function (require, module, exports) { + 'use strict'; + + function _typeof(obj) { + if ( + typeof Symbol === 'function' && + typeof Symbol.iterator === 'symbol' + ) { + _typeof = function _typeof(obj) { + return typeof obj; + }; + } else { + _typeof = function _typeof(obj) { + return obj && + typeof Symbol === 'function' && + obj.constructor === Symbol && + obj !== Symbol.prototype + ? 'symbol' + : typeof obj; + }; + } + return _typeof(obj); + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError( + 'Cannot call a class as a function' + ); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = + descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty( + target, + descriptor.key, + descriptor + ); + } + } + + function _createClass( + Constructor, + protoProps, + staticProps + ) { + if (protoProps) + _defineProperties( + Constructor.prototype, + protoProps + ); + if (staticProps) + _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true, + }); + } else { + obj[key] = value; + } + return obj; + } + + // import {SimpleDataGrapher} from "./SimpleDataGrapher"; + var SimpleDataGrapher = require('./SimpleDataGrapher'); + + var Papa = require('papaparse'); + + var CsvParser = + /*#__PURE__*/ + (function () { + //start is variable that will be passed to the function to sort out the columns. start will tell if the existing CSV file has headers or not, therefore, to start the iteration from 0 or 1 Used in header determination + function CsvParser( + file, + elementId, + functionParameter + ) { + _classCallCheck(this, CsvParser); + + _defineProperty(this, 'use strict', void 0); + + _defineProperty(this, 'csvFile', null); + + _defineProperty(this, 'csvMatrix', []); + + _defineProperty(this, 'csvHeaders', []); + + _defineProperty(this, 'csvFileStart', 1); + + _defineProperty( + this, + 'completeCsvMatrix', + [] + ); + + _defineProperty( + this, + 'completeCsvMatrixTranspose', + [] + ); + + _defineProperty(this, 'csvSampleData', []); + + _defineProperty(this, 'csvValidForYAxis', []); + + _defineProperty(this, 'elementId', null); + + _defineProperty(this, 'codapHeaders', []); + + _defineProperty(this, 'codapMatrix', []); + + this.elementId = elementId; + this.csvFile = file; + + if (functionParameter == 'prevfile') { + return this; + } else { + this.allFunctionHandler(functionParameter); + } + } //since parsing a local file works asynchronously, a callback function is required to call the remaining functions after the parsing is complete + + _createClass(CsvParser, [ + { + key: 'callbackForLocalFile', + value: function callbackForLocalFile( + csvMatrixLocal + ) { + this.csvMatrix = csvMatrixLocal; + this.csvHeaders = this.determineHeaders(); + this.completeCsvMatrix = + this.matrixForCompleteData(); + var totalData = this.extractSampleData(); + this.csvSampleData = totalData[0]; + this.csvValidForYAxis = totalData[1]; + this.completeCsvMatrixTranspose = + this.createTranspose(); + this.codapHeaders = + this.headersForCodap(); + this.codapMatrix = + this.completeMatrixForCodap(); + this.startFileProcessing(); + }, //a function handler that calls one function after the other after assigning the correct values to different class variables. + }, + { + key: 'allFunctionHandler', + value: function allFunctionHandler( + functionParameter + ) { + if (functionParameter == 'local') { + this.csvMatrix = this.parse(); + } else { + if ( + functionParameter == 'csvstring' || + functionParameter == 'remote' + ) { + this.csvFile = + this.csvFile.split('\n'); + this.csvMatrix = this.parseString(); + this.csvHeaders = + this.determineHeaders(); + this.completeCsvMatrix = + this.matrixForCompleteData(); + } else { + this.csvHeaders = + this.headersForGoogleSheet(); + this.completeCsvMatrix = + this.completeMatrixForGoogleSheet(); + } + + var totalData = + this.extractSampleData(); + this.csvSampleData = totalData[0]; + this.csvValidForYAxis = totalData[1]; + this.completeCsvMatrixTranspose = + this.createTranspose(); + this.codapHeaders = + this.headersForCodap(); + this.codapMatrix = + this.completeMatrixForCodap(); + this.startFileProcessing(); + } + }, //parsing a local file, works asynchronously + }, + { + key: 'parse', + value: function parse() { + var _this = this; + + var csvMatrixLocal = []; + var count = 0; + var f = this.parseReturn; + Papa.parse(this.csvFile, { + download: true, + dynamicTyping: true, + comments: true, + step: function step(row) { + csvMatrixLocal[count] = row.data[0]; + count += 1; + }, + complete: function complete() { + _this.callbackForLocalFile( + csvMatrixLocal + ); + }, + }); + }, // parsing string: for remote and csvString import options. Dat is parsed line by line but NOT asynchronously. + }, + { + key: 'parseString', + value: function parseString() { + var mat = []; + + for ( + var i = 0; + i < this.csvFile.length; + i++ + ) { + if ( + this.csvFile[i] == '' || + this.csvFile[i] == ' ' + ) { + continue; + } + + var dataHash = Papa.parse( + this.csvFile[i], + { + dynamicTyping: true, + comments: true, + } + ); + mat[i] = dataHash['data'][0]; + } + + return mat; + }, // checks for the presence of the corresponding View object in elementIdSimpleDataGraphInstanceMap, if present, the CsvParser object is assigned to the View object and the flow resumes from View.js file + }, + { + key: 'startFileProcessing', + value: function startFileProcessing() { + var self = this; + + if ( + self.elementId in + SimpleDataGrapher.SimpleDataGrapher + .elementIdSimpleDataGraphInstanceMap + ) { + SimpleDataGrapher.SimpleDataGrapher.elementIdSimpleDataGraphInstanceMap[ + self.elementId + ].view.continueViewManipulation(self); + } + }, //preparing sample data for the user to choose the columns from + }, + { + key: 'extractSampleData', + value: function extractSampleData() { + var maxval = 5; + var csvSampleDataLocal = []; + var csvValidForYAxisLocal = []; + var totalDataLocal = []; + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + csvSampleDataLocal[i] = []; + } + + if ( + this.completeCsvMatrix.length[0] < 5 + ) { + maxval = + this.completeCsvMatrix[0].length; + } + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + var counter = 0; + var bool = false; + + for ( + var j = 0; + j < this.completeCsvMatrix[i].length; + j++ + ) { + if (counter >= maxval) { + break; + } else if ( + this.completeCsvMatrix[i][j] !== + null || + this.completeCsvMatrix[i][j] !== + undefined + ) { + if ( + typeof this.completeCsvMatrix[i][ + j + ] === 'number' + ) { + bool = true; + } + + counter += 1; + csvSampleDataLocal[i].push( + this.completeCsvMatrix[i][j] + ); + } + } + + if (bool) { + csvValidForYAxisLocal.push( + this.csvHeaders[i] + ); + } + } + + totalDataLocal = [ + csvSampleDataLocal, + csvValidForYAxisLocal, + ]; + return totalDataLocal; + }, //makes a 2D matrix with the transpose of the CSV file, each column having the same index as its column heading + }, + { + key: 'matrixForCompleteData', + value: function matrixForCompleteData() { + var completeCsvMatrixLocal = []; + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + completeCsvMatrixLocal[i] = []; + } + + for ( + var i = this.csvFileStart; + i < this.csvMatrix.length; + i++ + ) { + for ( + var j = 0; + j < this.csvHeaders.length; + j++ + ) { + completeCsvMatrixLocal[j].push( + this.csvMatrix[i][j] + ); + } + } + + return completeCsvMatrixLocal; + }, //Google Sheet's data is in a JSON, traversal through the JSON and string manipulation are used to extract the data + }, + { + key: 'completeMatrixForGoogleSheet', + value: + function completeMatrixForGoogleSheet() { + var matrixComplete = []; + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + matrixComplete[i] = []; + } + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + for (var key in this.csvFile) { + var valueCell = + this.csvFile[key][ + this.csvHeaders[i] + ]['$t']; + + if (!isNaN(valueCell)) { + matrixComplete[i].push( + +valueCell + ); + } else { + matrixComplete[i].push(valueCell); + } + } + } + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + this.csvHeaders[i] = this.csvHeaders[ + i + ].slice(4, this.csvHeaders[i].length); + } + + return matrixComplete; + }, // matrix in JSON form for CODAP export + }, + { + key: 'completeMatrixForCodap', + value: function completeMatrixForCodap() { + var codapMatrix = []; + + for ( + var i = 1; + i < + this.completeCsvMatrixTranspose.length; + i++ + ) { + var element = {}; + + for ( + var j = 0; + j < this.csvHeaders.length; + j++ + ) { + element[this.csvHeaders[j]] = + this.completeCsvMatrixTranspose[i][ + j + ]; + } + + codapMatrix.push(element); + } + + return codapMatrix; + }, //checks if the first row has most of the potential header names, if not, assign dummy headers to the file. + }, + { + key: 'determineHeaders', + value: function determineHeaders() { + var csvHeadersLocal = []; + var flag = false; + + for ( + var i = 0; + i < this.csvMatrix[0].length; + i++ + ) { + if (i == 0) { + if ( + typeof this.csvMatrix[0][i] == + 'string' + ) { + csvHeadersLocal[i] = + this.csvMatrix[0][i]; + } else { + flag = true; + break; + } + } else { + if ( + (_typeof(this.csvMatrix[0][i]) == + _typeof( + this.csvMatrix[0][i - 1] + ) && + _typeof(this.csvMatrix[0][i]) != + 'object') || + (_typeof(this.csvMatrix[0][i]) != + _typeof( + this.csvMatrix[0][i - 1] + ) && + csvHeadersLocal[i - 1].substring( + 0, + 6 + ) == 'Column') + ) { + csvHeadersLocal[i] = + this.csvMatrix[0][i]; + } //in case of an unnamed column + else if ( + _typeof(this.csvMatrix[0][i]) == + 'object' + ) { + csvHeadersLocal[i] = + 'Column' + (i + 1); + } else { + flag = true; + break; + } + } + } //if there are no headers present, make dummy header names + + if ( + flag && + csvHeadersLocal.length != + this.csvMatrix[0].length + ) { + this.csvFileStart = 0; + + for ( + var i = 0; + i < this.csvMatrix[0].length; + i++ + ) { + csvHeadersLocal[i] = + 'Column' + (i + 1); + } + } + + return csvHeadersLocal; + }, //Google Sheet's data is in a JSON, extracting column names by string slicing + }, + { + key: 'headersForGoogleSheet', + value: function headersForGoogleSheet() { + var headers_sheet = []; + + for (var key in this.csvFile) { + var h = this.csvFile[key]; + + for (var headKey in h) { + if (headKey.slice(0, 4) == 'gsx$') { + headers_sheet.push(headKey); + } + } + + break; + } + + return headers_sheet; + }, //determine a JSON for headers for CODAP + }, + { + key: 'headersForCodap', + value: function headersForCodap() { + var codapHeaders = []; + + for ( + var i = 0; + i < this.csvHeaders.length; + i++ + ) { + var element = {}; + element['name'] = this.csvHeaders[i]; + codapHeaders.push(element); + } + + return codapHeaders; + }, // creating the transpose of the entire data ie complete data + headers, for createSpreadsheet in View.js + }, + { + key: 'createTranspose', + value: function createTranspose() { + var completeCsvMatrixTransposeLocal = []; + + for ( + var i = 0; + i <= this.completeCsvMatrix[0].length; + i++ + ) { + completeCsvMatrixTransposeLocal[i] = []; + } + + for ( + var i = 0; + i < this.completeCsvMatrix.length; + i++ + ) { + completeCsvMatrixTransposeLocal[0][i] = + this.csvHeaders[i]; + } + + for ( + var i = 0; + i < this.completeCsvMatrix.length; + i++ + ) { + for ( + var j = 0; + j < this.completeCsvMatrix[0].length; + j++ + ) { + completeCsvMatrixTransposeLocal[ + j + 1 + ][i] = this.completeCsvMatrix[i][j]; + } + } + + return completeCsvMatrixTransposeLocal; + }, + }, + ]); + + return CsvParser; + })(); + + module.exports = CsvParser; + }, + { './SimpleDataGrapher': 4, papaparse: 11 }, + ], + 3: [ + function (require, module, exports) { + 'use strict'; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError( + 'Cannot call a class as a function' + ); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = + descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty( + target, + descriptor.key, + descriptor + ); + } + } + + function _createClass( + Constructor, + protoProps, + staticProps + ) { + if (protoProps) + _defineProperties( + Constructor.prototype, + protoProps + ); + if (staticProps) + _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true, + }); + } else { + obj[key] = value; + } + return obj; + } + + var PlotlyjsPlotter = + /*#__PURE__*/ + (function () { + _createClass(PlotlyjsPlotter, [ + { + key: 'determineType2', + value: function determineType2() { + if ( + this.graphType == 'Horizontal' || + this.graphType == 'Vertical' + ) { + return 'bar'; + } else if ( + this.graphType == 'Pie' || + this.graphType == 'Doughnut' || + this.graphType == 'Radar' + ) { + return 'pie'; + } else if ( + this.graphType == 'Basic' || + this.graphType == 'Stepped' || + this.graphType == 'Point' + ) { + return 'scatter'; + } + }, + }, + { + key: 'layoutMaker', + value: function layoutMaker() { + var layout = {}; + + if ( + this.graphType == 'Horizontal' || + this.graphType == 'Vertical' + ) { + layout['barmode'] = 'group'; + } + + return layout; + }, + }, + { + key: 'traceMaker', + value: function traceMaker() { + var trace = {}; + trace['type'] = this.determineType2(); + + if (this.graphType == 'Horizontal') { + trace['orientation'] = 'h'; + } else if (this.graphType == 'Doughnut') { + trace['hole'] = 0.5; + } else if (this.graphType == 'Basic') { + trace['mode'] = 'lines'; + } else if (this.graphType == 'Point') { + trace['mode'] = 'markers'; + } else if (this.graphType == 'Stepped') { + trace['mode'] = 'lines+markers'; + trace['line'] = { + shape: 'hv', + }; + } + + return trace; + }, + }, + { + key: 'keyDeterminer', + value: function keyDeterminer() { + var keys = ['x', 'y']; + + if ( + this.graphType == 'Pie' || + this.graphType == 'Doughnut' + ) { + keys[1] = 'values'; + keys[0] = 'labels'; + } else if ( + this.graphType == 'Horizontal' + ) { + keys[0] = 'y'; + keys[1] = 'x'; + } + + return keys; + }, + }, + { + key: 'plotGraph2', + value: function plotGraph2() { + if (this.flag) { + document.getElementById( + this.canvasContainerId + ).innerHTML = ''; + } + + var layout = this.layoutMaker(); + var data = []; + var keySet = this.keyDeterminer(); + + for (var i = 0; i < this.length; i++) { + var new_trace = this.traceMaker(); + new_trace[keySet[0]] = + this.dataHash['x_axis_labels']; + new_trace[keySet[1]] = + this.dataHash['y_axis_values' + i]; + new_trace['name'] = + this.dataHash['labels'][1][i]; + data.push(new_trace); + } + + var div = document.createElement('div'); + div.id = + this.elementId + + '_chart_container_' + + this.graphCounting; + document + .getElementById(this.canvasContainerId) + .appendChild(div); + Plotly.newPlot(div.id, data, layout); + }, + }, + ]); + + function PlotlyjsPlotter( + hash, + length, + type, + flag, + canvasContainerId, + elementId, + graphCounting + ) { + _classCallCheck(this, PlotlyjsPlotter); + + _defineProperty(this, 'use strict', void 0); + + _defineProperty(this, 'dataHash', {}); + + _defineProperty(this, 'elementId', null); + + _defineProperty(this, 'graphCounting', 0); + + _defineProperty( + this, + 'canvasContainerId', + null + ); + + _defineProperty(this, 'graphType', null); + + _defineProperty(this, 'length', 0); + + _defineProperty(this, 'flag', false); + + this.dataHash = hash; + this.length = length; + this.graphType = type; + this.flag = flag; + this.canvasContainerId = canvasContainerId; + this.elementId = elementId; + this.graphCounting = graphCounting; + this.plotGraph2(); + } + + return PlotlyjsPlotter; + })(); + + module.exports = PlotlyjsPlotter; + }, + {}, + ], + 4: [ + function (require, module, exports) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true, + }); + exports.SimpleDataGrapher = void 0; + + var _View = require('./View'); + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError( + 'Cannot call a class as a function' + ); + } + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true, + }); + } else { + obj[key] = value; + } + return obj; + } + + var SimpleDataGrapher = function SimpleDataGrapher( + elementId + ) { + _classCallCheck(this, SimpleDataGrapher); + + _defineProperty(this, 'use strict', void 0); + + _defineProperty(this, 'elementId', null); + + _defineProperty(this, 'view', null); + + this.elementId = elementId; + SimpleDataGrapher.elementIdSimpleDataGraphInstanceMap[ + this.elementId + ] = this; + this.view = new _View.View(elementId); + }; + + exports.SimpleDataGrapher = SimpleDataGrapher; + + _defineProperty( + SimpleDataGrapher, + 'elementIdSimpleDataGraphInstanceMap', + {} + ); + + window.SimpleDataGrapher = SimpleDataGrapher; + }, + { './View': 5 }, + ], + 5: [ + function (require, module, exports) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true, + }); + exports.View = void 0; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError( + 'Cannot call a class as a function' + ); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = + descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty( + target, + descriptor.key, + descriptor + ); + } + } + + function _createClass( + Constructor, + protoProps, + staticProps + ) { + if (protoProps) + _defineProperties( + Constructor.prototype, + protoProps + ); + if (staticProps) + _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true, + }); + } else { + obj[key] = value; + } + return obj; + } + + var CsvParser = require('./CsvParser'); + + var SimpleDataGrapher = require('./SimpleDataGrapher'); + + var ChartjsPlotter = require('./ChartjsPlotter'); + + var PlotlyjsPlotter = require('./PlotlyjsPlotter'); + + var iframe_phone = require('iframe-phone'); + + var View = + /*#__PURE__*/ + (function () { + _createClass(View, [ + { + key: 'handleFileSelectlocal', + //extracts the uploaded file from input field and creates an object of CsvParser class with the file as one of the parameters + value: function handleFileSelectlocal( + event + ) { + this.csvFile = event.target.files[0]; + + if ( + this.csvFile['name'].split('.')[1] != + 'csv' + ) { + alert('Invalid file type'); + } else { + $('#' + this.dragDropHeadingId).text( + this.csvFile['name'] + ); + var self = this; + + document.getElementById( + this.uploadButtonId + ).onclick = function (e) { + self.csvParser = new CsvParser( + self.csvFile, + self.elementId, + 'local' + ); + }; + } + }, //receives the string value and creates an object of CsvParser class with the string as one of the parameters + }, + { + key: 'handleFileSelectstring', + value: function handleFileSelectstring( + val + ) { + // var csv_string = val.split("\n"); + this.csvFile = val; + var self = this; + + document.getElementById( + this.uploadButtonId + ).onclick = function (e) { + self.csvParser = new CsvParser( + self.csvFile, + self.elementId, + 'csvstring' + ); + }; + }, // function for using a previously uploaded and saved file from the data base + }, + { + key: 'usingPreviouslyUploadedFile', + value: + function usingPreviouslyUploadedFile() { + var self = this; + self.csvParser = new CsvParser( + 'dummy', + self.elementId, + 'prevfile' + ); + }, //receives the JSON file value and creates an object of CsvParser class with the file as one of the parameters + }, + { + key: 'handleFileSelectGoogleSheet', + value: function handleFileSelectGoogleSheet( + googleSheetData + ) { + this.csvFile = googleSheetData; + var self = this; + + document.getElementById( + this.uploadButtonId + ).onclick = function (e) { + self.csvParser = new CsvParser( + self.csvFile, + self.elementId, + 'googleSheet' + ); + }; + }, // get's the JSON form of the Google Sheet through Google Sheet's URL and passes it to the handler + }, + { + key: 'getValueGoogleSheet', + value: function getValueGoogleSheet( + googleSheetLink + ) { + var self = this; + $.getJSON( + googleSheetLink, + function (data) { + self.handleFileSelectGoogleSheet( + data.feed.entry + ); + } + ); + }, // uses a CORS proxy to fetch the value of a remote files and passes the received value to a callback function + }, + { + key: 'sendRemoteFileToHandler', + value: function sendRemoteFileToHandler( + val + ) { + var _this = this; + + var proxyurl = + 'https://cors-anywhere.herokuapp.com/'; + var url = val; + fetch(proxyurl + url) + .then(function (response) { + return response.text(); + }) + .then(function (contents) { + return _this.handleFileSelectremote( + contents + ); + }) + ['catch'](function (e) { + return console.log(e); + }); + }, // callback function which receives the remote file's value and creates an object of CsvParser class with the file as one of the parameters + }, + { + key: 'handleFileSelectremote', + value: function handleFileSelectremote( + remoteVal + ) { + this.csvFile = remoteVal; + var self = this; + + document.getElementById( + this.uploadButtonId + ).onclick = function (e) { + self.csvParser = new CsvParser( + self.csvFile, + self.elementId, + 'remote' + ); + }; + }, // adapter function which switches between Plotly.js and Chart.js as a graph plotting library and creates theri respective objects which take over the graph plotting + }, + { + key: 'plotGraph', + value: function plotGraph( + hash, + length, + type, + flag, + library + ) { + if (library == 'chartjs') { + this.chartjsPlotter = + new ChartjsPlotter( + hash, + length, + type, + flag, + this.canvasContinerId, + this.elementId, + this.graphCounting + ); + } else { + this.plotlyjsPlotter = + new PlotlyjsPlotter( + hash, + length, + type, + flag, + this.canvasContinerId, + this.elementId, + this.graphCounting + ); + } + + $('.' + this.carousalClass).carousel(2); + }, //set tool tip for impot options + }, + { + key: 'setTooltip', + value: function setTooltip(importType) { + if ( + importType === 'container_drag_drop' + ) { + return 'Select a local file from your system'; + } else if ( + importType === 'container_csv_string' + ) { + var x = + 'Type in or Paste a CSV string. \r\n'; + x += 'Example: \r\n'; + x += 'A,B,C \r\n'; + x += '1,2,3'; + return x; + } else if ( + importType === 'container_remote_link' + ) { + return 'Type in or Paste the link of a remote CSV file. Example: \ + http://example.com/example.csv'; + } else if ( + importType === 'container_google_sheet' + ) { + return 'Type in or Paste the link of a Published Google Sheet. To publish a Google Sheet: 1. File -> Publish to the web -> Publish 2. Share -> Get shareable link -> Anyone with the link can -> More -> On - Public on the web -> Save 3. Copy link'; + } + }, //set tool tip for graph tips + }, + { + key: 'setTooltipGraph', + value: function setTooltipGraph(graphType) { + if (graphType == 'Horizontal') { + return 'Data is categorical and tells how many, widths proportional to the values'; + } else if (graphType === 'Vertical') { + return 'Data is categorical and tells how many, heights proportional to the values'; + } else if (graphType == 'Stacked') { + return 'Ideal for comparing the total amounts across each group/segmented bar'; + } else if (graphType == 'Basic') { + return 'Used to visualize a trend in data over intervals of time or to see the growth of a quantity'; + } else if (graphType == 'Stepped') { + return 'Vertical parts of a step chart denote changes in the data and their magnitude'; + } else if (graphType == 'Point') { + return 'Used to show the relationship between two data variables'; + } else if (graphType == 'Pie') { + return 'Used to show percentage or proportional data, should be used for less number of categories'; + } else if (graphType == 'Doughnut') { + return 'Used to show percentage or proportional data, but have better data intensity ratio and space efficiency'; + } else if (graphType == 'Radar') { + return 'Used to display multivariate observations with an arbitrary number of variables'; + } + }, // create a popover against each import method for adding a file title and description + }, + { + key: 'createPopover', + value: function createPopover(buttonId) { + var self = this; + var html = + '
'; + $('#' + buttonId) + .popover({ + placement: 'bottom', + title: 'Add Description', + html: true, + content: html, + }) + .on('click', function () { + $('#save').click(function (e) { + e.preventDefault(); + self.fileTitle = $( + '#' + 'title' + buttonId + ).val(); + self.fileDescription = $( + '#' + 'desc' + buttonId + ).val(); + }); + }); + }, // renders the required buttons for saving the files if the use is logged in + }, + { + key: 'createButtons', + value: function createButtons( + userLoginCheck + ) { + this.listenersForIntegration(); + + if (userLoginCheck == 'yes') { + var save_file_button = + document.createElement('button'); + save_file_button.classList.add('btn'); + save_file_button.classList.add( + 'btn-primary' + ); + save_file_button.innerHTML = 'Save CSV'; + save_file_button.id = + this.elementId + '_save_CSV'; + var upload_prev_file = + document.createElement('button'); + upload_prev_file.classList.add('btn'); + upload_prev_file.classList.add( + 'btn-primary' + ); + upload_prev_file.innerHTML = + 'Choose a previously uploaded file'; + upload_prev_file.id = + this.elementId + '_prev_file'; + var publish_research_button = + document.createElement('button'); + publish_research_button.classList.add( + 'btn' + ); + publish_research_button.classList.add( + 'btn-primary' + ); + publish_research_button.innerHTML = + 'Publish as a Research Note'; + publish_research_button.id = + this.elementId + '_publish'; + var container = document.getElementById( + this.upload_button_container + ); + var div_container = + document.createElement('div'); + div_container.appendChild( + save_file_button + ); + div_container.appendChild( + upload_prev_file + ); + var container2 = + document.getElementById( + this.feature_button_container + ); + container2.appendChild( + publish_research_button + ); + container.prepend(div_container); + } + }, // create dataset for CODAP table + }, + { + key: 'createDataset', + value: function createDataset() { + var dataset = {}; + dataset['action'] = 'create'; + dataset['resource'] = 'dataContext'; + var values = {}; + values['name'] = 'my dataset'; + values['title'] = 'Case Table'; + var collections = []; + var hashCollections = {}; + hashCollections['name'] = 'cases'; + hashCollections['attrs'] = + this.csvParser.codapHeaders; + collections.push(hashCollections); + values['collections'] = collections; + dataset['values'] = values; + var dataset2 = {}; + dataset2['action'] = 'create'; + dataset2['resource'] = + 'dataContext[my dataset].item'; + dataset2['values'] = + this.csvParser.codapMatrix; + var dataset3 = {}; + dataset3['action'] = 'create'; + dataset3['resource'] = 'component'; + var values3 = {}; + values3['type'] = 'caseTable'; + values3['dataContext'] = 'my dataset'; + dataset3['values'] = values3; + return [dataset, dataset2, dataset3]; + }, + }, + { + key: 'iframePhoneHandler', + value: function iframePhoneHandler() {}, //callbackforCODAP + // renders the iframe for CODAP export + }, + { + key: 'codapExport', + value: function codapExport() { + var self = this; + var iframeBody = + ''; + var modal_body = document.getElementById( + 'body_for_CODAP' + ); + modal_body.innerHTML = iframeBody; + var iframe = + document.getElementById('codap-iframe'); + modal_body.style.height = '500px'; + iframe.style.width = '750px'; + iframe.style.height = '90%'; + var codapIframe = + document.getElementById('codap-iframe'); + var rpcHandler = + new iframe_phone.IframePhoneRpcEndpoint( + self.iframePhoneHandler, + 'data-interactive', + codapIframe + ); + var createCodapButton = + document.createElement('button'); + createCodapButton.classList.add('btn'); + createCodapButton.classList.add( + 'btn-primary' + ); + createCodapButton.innerHTML = 'Go!'; + createCodapButton.id = + this.elementId + '_create_codap'; + modal_body.prepend(createCodapButton); + var apiCall = this.createDataset(); + $( + '#' + this.elementId + '_create_codap' + ).click(function () { + rpcHandler.call( + apiCall, + function (resp) { + console.log( + 'Response:' + JSON.stringify(resp) + ); + } + ); + }); + }, // creates a downloadable spreadsheet for the imported data using SheetJS + }, + { + key: 'createSheet', + value: function createSheet() { + var wb = XLSX.utils.book_new(); + wb.Props = { + Title: + 'New Spreadsheet' + this.elementId, + CreatedDate: new Date(), + }; + wb.SheetNames.push( + 'Sheet' + this.elementId + ); + var ws_data = + this.csvParser + .completeCsvMatrixTranspose; + var ws = XLSX.utils.aoa_to_sheet(ws_data); + wb.Sheets['Sheet' + this.elementId] = ws; + var wbout = XLSX.write(wb, { + bookType: 'xlsx', + type: 'binary', + }); + + function s2ab(s) { + var buf = new ArrayBuffer(s.length); + var view = new Uint8Array(buf); + + for (var i = 0; i < s.length; i++) { + view[i] = s.charCodeAt(i) & 0xff; + } + + return buf; + } + + saveAs( + new Blob([s2ab(wbout)], { + type: 'application/octet-stream', + }), + 'newSpreadsheet' + + this.elementId + + '.xlsx' + ); + }, // creates a hash of the entire data in an accesible format for the charting libraries {labels: [legendx, [legendy0, legendy1 ... lengendyn]], x_axis_values: [...], y_axis_0: [...], y_axis_1: [...], ... y_axis_n: [...]} n: selected number of columns + // flag is just for seeing if we're plotting the graph for the first time, if yes, we will have to clear the canvas. + }, + { + key: 'afterSampleData', + value: function afterSampleData( + flag, + type + ) { + var _this2 = this; + + document.getElementById( + this.plotGraphId + ).onclick = function (e) { + e.preventDefault(); + var hash = {}; + var ix = $( + 'input[name=' + + _this2.tableXInputName + + ']:checked' + ).val(); + hash['x_axis_labels'] = + _this2.csvParser.completeCsvMatrix[ + ix + ]; + var columns = new Array(); + var y_axis_names = new Array(); + $( + 'input:checkbox[name=' + + _this2.tableYInputName + + ']:checked' + ).each(function (index, element) { + columns.push(element.value); + }); + + for ( + var i = 0; + i < columns.length; + i++ + ) { + hash['y_axis_values' + i] = + _this2.csvParser.completeCsvMatrix[ + columns[i] + ]; + y_axis_names.push( + _this2.csvParser.csvHeaders[ + columns[i] + ] + ); + } + + var labels = [ + _this2.csvParser.csvHeaders[ix], + y_axis_names, + ]; + hash['labels'] = labels; + var selectedGraph = $('.selected'); + var type = + selectedGraph.attr('data-value'); + + _this2.plotGraph( + hash, + columns.length, + type, + flag, + 'plotly' + ); + }; + }, // generates a graph menu with different graph options + }, + { + key: 'graphMenu', + value: function graphMenu(flag) { + var self = this; + $('.' + this.carousalClass).carousel(1); + var menuDiv = + document.getElementById('menu_holder'); + menuDiv.innerHTML = + '

blahhhhh

Horizontal Bar

Vertical Bar

Stacked Bar

Basic Line

Stepped Line

Point

Pie

Doughnut

Radar

blahhh

'; + $('.radio-group .radio').click( + function () { + $(this) + .parent() + .find('.radio') + .removeClass('selected'); + var l = + document.getElementsByClassName( + 'hmm' + ); + + for (var i = 0; i < l.length; i++) { + l[i].style.backgroundColor = + '#cccccc'; + } + + $(this).addClass('selected'); + var type = $(this).attr('data-value'); + $('#' + type + 'Type').css( + 'backgroundColor', + '#1ad1ff' + ); + } + ); + $('.radio').hover( + function () { + var tooltipVal = self.setTooltipGraph( + $(this).attr('data-value') + ); + $('#graph_description').text( + tooltipVal + ); + $('#graph_description') + .css({ + opacity: 0.0, + visibility: 'visible', + }) + .animate( + { + opacity: 1.0, + }, + 800 + ); + }, + function () { + $('#graph_description').css( + 'visibility', + 'hidden' + ); + } + ); + this.afterSampleData(flag); + }, // generates the sample table data with checkboxes for y-axis and radio buttons for x-axis + }, + { + key: 'tableGenerator', + value: function tableGenerator( + name, + tableId, + typeOfInput, + validValues, + flag, + tableType, + badgeType + ) { + document.getElementById( + tableId + ).innerHTML = ''; + var trhead = document.createElement('tr'); + + for ( + var i = 0; + i < this.csvParser.csvHeaders.length; + i++ + ) { + var td = document.createElement('td'); + var span = + document.createElement('span'); + var textnode = document.createTextNode( + this.csvParser.csvHeaders[i] + ); + span.appendChild(textnode); + span.classList.add('badge'); + span.classList.add('badge-pill'); + span.classList.add(badgeType); + td.appendChild(span); + + for ( + var j = 0; + j < validValues.length; + j++ + ) { + if ( + validValues[j] == + this.csvParser.csvHeaders[i] + ) { + var checkbox = + document.createElement('input'); + checkbox.type = typeOfInput; + checkbox.value = i; + checkbox.name = name; + checkbox.id = name + i; + checkbox.classList.add( + 'check-inputs' + ); + span.appendChild(checkbox); + } + } + + trhead.appendChild(td); + } + + trhead.classList.add(tableType); + document + .getElementById(tableId) + .appendChild(trhead); + + for ( + var i = 0; + i < + this.csvParser.csvSampleData[0].length; + i++ + ) { + var tr = document.createElement('tr'); + + for ( + var j = 0; + j < this.csvParser.csvHeaders.length; + j++ + ) { + var td = document.createElement('td'); + td.appendChild( + document.createTextNode( + this.csvParser.csvSampleData[j][i] + ) + ); + tr.appendChild(td); + } + + document + .getElementById(tableId) + .appendChild(tr); + } + + this.graphMenu(flag); + }, // renders the sample tables + }, + { + key: 'showSampleDataXandY', + value: function showSampleDataXandY() { + var _this3 = this; + + document.getElementById( + this.addGraphButtonId + ).onclick = function (e) { + _this3.graphCounting++; + $('.' + _this3.carousalClass).carousel( + 1 + ); /// ---------------> after + + _this3.tableGenerator( + _this3.tableXInputName, + _this3.tableXId, + 'radio', + _this3.csvParser.csvHeaders, + false, + 'table-success', + 'badge-success' + ); + + _this3.tableGenerator( + _this3.tableYInputName, + _this3.tableYId, + 'checkbox', + _this3.csvParser.csvValidForYAxis, + false, + 'table-warning', + 'badge-warning' + ); + + _this3.graphMenu(); + }; + + this.tableGenerator( + this.tableXInputName, + this.tableXId, + 'radio', + this.csvParser.csvHeaders, + true, + 'table-success', + 'badge-success' + ); + this.tableGenerator( + this.tableYInputName, + this.tableYId, + 'checkbox', + this.csvParser.csvValidForYAxis, + true, + 'table-warning', + 'badge-warning' + ); + this.graphMenu(); + }, // view manipulation resumes after the CsvParser object is created and returned + }, + { + key: 'continueViewManipulation', + value: function continueViewManipulation( + x + ) { + if (x != 'prevfile') { + this.csvParser = x; + } + + this.showSampleDataXandY(); // this.showSampleDataXandY(this.csvParser.csvSampleData, this.csvParser.csvHeaders, this.csvParser.csvValidForYAxis, this.csvParser.csvSampleData); + // sampleDataXandY(this.csvSampleData,this.csvHeaders,this.csvValidForYAxis,this.completeCsvMatrix); + // matrixForCompleteData(headers,this.csvMatrix,start); + }, + }, + { + key: 'listenersForIntegration', + value: function listenersForIntegration() { + var _this4 = this; + + $('#' + this.fileUploadId).change( + function (e) { + document.getElementById( + 'popover' + _this4.fileUploadId + ).style.display = 'inline'; + document.getElementById( + 'popover' + _this4.csvStringUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + + _this4.googleSheetUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + + _this4.remoteFileUploadId + ).style.display = 'none'; + + _this4.createPopover( + 'popover' + _this4.fileUploadId + ); + + _this4.handleFileSelectlocal(e); + } + ); + $('#' + this.csvStringUploadId).change( + function () { + document.getElementById( + 'popover' + _this4.csvStringUploadId + ).style.display = 'inline'; + document.getElementById( + 'popover' + + _this4.googleSheetUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + + _this4.remoteFileUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + _this4.fileUploadId + ).style.display = 'none'; + + _this4.createPopover( + 'popover' + _this4.csvStringUploadId + ); + + _this4.handleFileSelectstring( + document.getElementById( + _this4.csvStringUploadId + ).value + ); + } + ); + $('#' + this.googleSheetUploadId).change( + function () { + document.getElementById( + 'popover' + + _this4.googleSheetUploadId + ).style.display = 'inline'; + document.getElementById( + 'popover' + _this4.csvStringUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + + _this4.remoteFileUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + _this4.fileUploadId + ).style.display = 'none'; + + _this4.createPopover( + 'popover' + + _this4.googleSheetUploadId + ); + + var sheetLink = + document.getElementById( + _this4.googleSheetUploadId + ).value; + var sheetURL = + 'https://spreadsheets.google.com/feeds/list/' + + sheetLink.split('/')[5] + + '/od6/public/values?alt=json'; + + _this4.getValueGoogleSheet(sheetURL); + } + ); + $('#' + this.remoteFileUploadId).change( + function () { + document.getElementById( + 'popover' + + _this4.remoteFileUploadId + ).style.display = 'inline'; + document.getElementById( + 'popover' + _this4.csvStringUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + + _this4.googleSheetUploadId + ).style.display = 'none'; + document.getElementById( + 'popover' + _this4.fileUploadId + ).style.display = 'none'; + + _this4.createPopover( + 'popover' + + _this4.remoteFileUploadId + ); + + _this4.sendRemoteFileToHandler( + document.getElementById( + _this4.remoteFileUploadId + ).value + ); + } + ); + }, + }, + ]); + + function View(elementId) { + var _this5 = this; + + _classCallCheck(this, View); + + _defineProperty(this, 'use strict', void 0); + + _defineProperty(this, 'elementId', null); + + _defineProperty(this, 'element', null); + + _defineProperty(this, 'fileUploadId', null); + + _defineProperty( + this, + 'remoteFileUploadId', + null + ); + + _defineProperty( + this, + 'csvStringUploadId', + null + ); + + _defineProperty( + this, + 'googleSheetUploadId', + null + ); + + _defineProperty(this, 'csvFile', null); + + _defineProperty( + this, + 'dragDropHeadingId', + null + ); + + _defineProperty(this, 'uploadButtonId', null); + + _defineProperty(this, 'csvParser', null); + + _defineProperty(this, 'chartjsPlotter', null); + + _defineProperty( + this, + 'plotlyjsPlotter', + null + ); + + _defineProperty(this, 'graphCounting', 0); + + _defineProperty( + this, + 'addGraphButtonId', + null + ); + + _defineProperty(this, 'tableXId', null); + + _defineProperty(this, 'tableYId', null); + + _defineProperty( + this, + 'tableXInputName', + null + ); + + _defineProperty( + this, + 'tableYInputName', + null + ); + + _defineProperty(this, 'carousalClass', null); + + _defineProperty(this, 'carousalId', null); + + _defineProperty(this, 'graphMenuId', null); + + _defineProperty(this, 'plotGraphId', null); + + _defineProperty( + this, + 'graphMenuTypeInputName', + null + ); + + _defineProperty( + this, + 'canvasContinerId', + null + ); + + _defineProperty(this, 'xyToggle', null); + + _defineProperty(this, 'xyToggleName', null); + + _defineProperty(this, 'tableXParentId', null); + + _defineProperty(this, 'tableYParentId', null); + + _defineProperty( + this, + 'upload_button_container', + null + ); + + _defineProperty(this, 'fileTitle', ''); + + _defineProperty(this, 'fileDescription', ''); + + _defineProperty( + this, + 'codapExportButton', + null + ); + + this.elementId = elementId; + this.element = + document.getElementById(elementId); + + if (this.element == null) { + throw 'No element exist with this id'; + } + + this.fileUploadId = elementId + '_csv_file'; + this.remoteFileUploadId = + elementId + '_remote_file'; + this.csvStringUploadId = + elementId + '_csv_string'; + this.googleSheetUploadId = + elementId + '_google_sheet'; + this.dragDropHeadingId = + elementId + '_drag_drop_heading'; + this.uploadButtonId = + elementId + '_file_upload_button'; + this.addGraphButtonId = + elementId + '_add_graph'; + this.createSpreadsheetButtonId = + elementId + '_save_as_spreadsheet'; + this.tableXId = elementId + '_tableX'; + this.tableYId = elementId + '_tableY'; + this.tableXParentId = elementId + '_Xtable'; + this.tableYParentId = elementId + '_Ytable'; + this.tableXInputName = + elementId + '_x_axis_input_columns'; + this.tableYInputName = + elementId + '_y_axis_input_columns'; + this.carousalClass = elementId + '_carousal'; + this.carousalId = elementId + '_carousalId'; + this.graphMenuId = elementId + '_graph_menu'; + this.plotGraphId = elementId + '_plot_graph'; + this.graphMenuTypeInputName = + elementId + '_types'; + this.canvasContinerId = + elementId + '_canvas_container'; + this.xyToggleName = elementId + '_xytoggle'; + this.saveAsImageId = + elementId + 'save-as-image'; + this.upload_button_container = + elementId + 'upload_button_container'; + this.feature_button_container = + elementId + 'feature_button_container'; + this.codapExportButton = + elementId + 'codap_export_button'; + this.drawHTMLView(); + this.addListeners(); + var self = this; + $('.xytoggle').bootstrapToggle({ + on: 'X-Axis', + off: 'Y-Axis', + }); + $( + 'input[name=' + + this.xyToggleName + + ']:checked' + ).change(function () { + var ixy = $( + 'input[name=' + + _this5.xyToggleName + + ']:checked' + ).val(); + var ixx = 0; + + if (ixy == undefined) { + ixx = 1; + } + + $('#' + _this5.tableXParentId).toggle( + ixx === 0 + ); + $('#' + _this5.tableYParentId).toggle( + ixx === 1 + ); + }); + $('.imports').hover( + function () { + var tooltipVal = self.setTooltip( + this.classList[0] + ); + $('#import_description').text(tooltipVal); + $('#import_description') + .css({ + opacity: 0.0, + visibility: 'visible', + }) + .animate( + { + opacity: 1.0, + }, + 800 + ); + }, + function () { + $('#import_description').css( + 'visibility', + 'hidden' + ); + } + ); + } //listen for different inputs for import by the user + + _createClass(View, [ + { + key: 'addListeners', + value: function addListeners() { + var _this6 = this; + + $('#' + this.fileUploadId).change( + function (e) { + _this6.handleFileSelectlocal(e); + } + ); + $('#' + this.csvStringUploadId).change( + function () { + _this6.handleFileSelectstring( + document.getElementById( + _this6.csvStringUploadId + ).value + ); + } + ); + $('#' + this.googleSheetUploadId).change( + function () { + var sheetURL = + 'https://spreadsheets.google.com/feeds/list/' + + sheetLink.split('/')[5] + + '/od6/public/values?alt=json'; + + _this6.getValueGoogleSheet(sheetURL); + } + ); + $('#' + this.remoteFileUploadId).change( + function () { + _this6.sendRemoteFileToHandler( + document.getElementById( + _this6.remoteFileUploadId + ).value + ); + } + ); + $( + '#' + this.createSpreadsheetButtonId + ).click(function () { + _this6.createSheet(); + }); + $('#' + this.codapExportButton).click( + function () { + _this6.codapExport(); + } + ); + }, //renders the entire HTML view + }, + { + key: 'drawHTMLView', + value: function drawHTMLView() { + this.element.innerHTML = + '

Simple Data Grapher

A JavaScript library that turns uploaded CSV files into customizable graphs within a few simple steps. Can be embedded on other websites!

Open Source by Public Lab

  • Upload CSV Data
  • Select Columns & Graph Type
  • Plotted Graph & Export Options
'; + }, + }, + ]); + + return View; + })(); + + exports.View = View; + }, + { + './ChartjsPlotter': 1, + './CsvParser': 2, + './PlotlyjsPlotter': 3, + './SimpleDataGrapher': 4, + 'iframe-phone': 10, + }, + ], + 6: [ + function (require, module, exports) { + var structuredClone = require('./structured-clone'); + var HELLO_INTERVAL_LENGTH = 200; + var HELLO_TIMEOUT_LENGTH = 60000; + + function IFrameEndpoint() { + var listeners = {}; + var isInitialized = false; + var connected = false; + var postMessageQueue = []; + var helloInterval; + + function postToParent(message) { + // See http://dev.opera.com/articles/view/window-postmessage-messagechannel/#crossdoc + // https://github.com/Modernizr/Modernizr/issues/388 + // http://jsfiddle.net/ryanseddon/uZTgD/2/ + if (structuredClone.supported()) { + window.parent.postMessage(message, '*'); + } else { + window.parent.postMessage( + JSON.stringify(message), + '*' + ); + } + } + + function post(type, content) { + var message; + // Message object can be constructed from 'type' and 'content' arguments or it can be passed + // as the first argument. + if ( + arguments.length === 1 && + typeof type === 'object' && + typeof type.type === 'string' + ) { + message = type; + } else { + message = { + type: type, + content: content, + }; + } + if (connected) { + postToParent(message); + } else { + postMessageQueue.push(message); + } + } + + function postHello() { + postToParent({ + type: 'hello', + }); + } + + function addListener(type, fn) { + listeners[type] = fn; + } + + function removeAllListeners() { + listeners = {}; + } + + function getListenerNames() { + return Object.keys(listeners); + } + + function messageListener(message) { + // Anyone can send us a message. Only pay attention to messages from parent. + if (message.source !== window.parent) return; + var messageData = message.data; + if (typeof messageData === 'string') + messageData = JSON.parse(messageData); + + if ( + !connected && + messageData.type === 'hello' + ) { + connected = true; + stopPostingHello(); + while (postMessageQueue.length > 0) { + post(postMessageQueue.shift()); + } + } + + if (connected && listeners[messageData.type]) { + listeners[messageData.type]( + messageData.content + ); + } + } + + function disconnect() { + connected = false; + stopPostingHello(); + window.removeEventListener( + 'message', + messsageListener + ); + } + + /** Initialize communication with the parent frame. This should not be called until the app's custom listeners are registered (via our 'addListener' public method) because, once we open the communication, the parent window may send any messages it may have queued. Messages for which we don't have handlers will be silently ignored. */ - function initialize() { - if (isInitialized) { - return; - } - isInitialized = true; - if (window.parent === window) return; - - // We kick off communication with the parent window by sending a "hello" message. Then we wait - // for a handshake (another "hello" message) from the parent window. - startPostingHello(); - window.addEventListener('message', messageListener, false); - } - - function startPostingHello() { - if (helloInterval) { - stopPostingHello(); - } - helloInterval = window.setInterval(postHello, HELLO_INTERVAL_LENGTH); - window.setTimeout(stopPostingHello, HELLO_TIMEOUT_LENGTH); - // Post the first msg immediately. - postHello(); - } - - function stopPostingHello() { - window.clearInterval(helloInterval); - helloInterval = null; - } - - // Public API. - return { - initialize: initialize, - getListenerNames: getListenerNames, - addListener: addListener, - removeAllListeners: removeAllListeners, - disconnect: disconnect, - post: post - }; -} - -var instance = null; - -// IFrameEndpoint is a singleton, as iframe can't have multiple parents anyway. -module.exports = function getIFrameEndpoint() { - if (!instance) { - instance = new IFrameEndpoint(); - } - return instance; -}; - -},{"./structured-clone":9}],7:[function(require,module,exports){ -var ParentEndpoint = require('./parent-endpoint'); -var getIFrameEndpoint = require('./iframe-endpoint'); - -// Not a real UUID as there's an RFC for that (needed for proper distributed computing). -// But in this fairly parochial situation, we just need to be fairly sure to avoid repeats. -function getPseudoUUID() { - var chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; - var len = chars.length; - var ret = []; - - for (var i = 0; i < 10; i++) { - ret.push(chars[Math.floor(Math.random() * len)]); - } - return ret.join(''); -} - -module.exports = function IframePhoneRpcEndpoint(handler, namespace, targetWindow, targetOrigin, phone) { - var pendingCallbacks = Object.create({}); - - // if it's a non-null object, rather than a function, 'handler' is really an options object - if (handler && typeof handler === 'object') { - namespace = handler.namespace; - targetWindow = handler.targetWindow; - targetOrigin = handler.targetOrigin; - phone = handler.phone; - handler = handler.handler; - } - - if (!phone) { - if (targetWindow === window.parent) { - phone = getIFrameEndpoint(); - phone.initialize(); - } else { - phone = new ParentEndpoint(targetWindow, targetOrigin); - } - } - - phone.addListener(namespace, function (message) { - var callbackObj; - - if (message.messageType === 'call' && typeof this.handler === 'function') { - this.handler.call(undefined, message.value, function (returnValue) { - phone.post(namespace, { - messageType: 'returnValue', - uuid: message.uuid, - value: returnValue - }); - }); - } else if (message.messageType === 'returnValue') { - callbackObj = pendingCallbacks[message.uuid]; - - if (callbackObj) { - window.clearTimeout(callbackObj.timeout); - if (callbackObj.callback) { - callbackObj.callback.call(undefined, message.value); - } - pendingCallbacks[message.uuid] = null; - } - } - }.bind(this)); - - function call(message, callback) { - var uuid = getPseudoUUID(); - - pendingCallbacks[uuid] = { - callback: callback, - timeout: window.setTimeout(function () { - if (callback) { - callback(undefined, new Error("IframePhone timed out waiting for reply")); - } - }, 2000) - }; - - phone.post(namespace, { - messageType: 'call', - uuid: uuid, - value: message - }); - } - - function disconnect() { - phone.disconnect(); - } - - this.handler = handler; - this.call = call.bind(this); - this.disconnect = disconnect.bind(this); -}; - -},{"./iframe-endpoint":6,"./parent-endpoint":8}],8:[function(require,module,exports){ -var structuredClone = require('./structured-clone'); - -/** + function initialize() { + if (isInitialized) { + return; + } + isInitialized = true; + if (window.parent === window) return; + + // We kick off communication with the parent window by sending a "hello" message. Then we wait + // for a handshake (another "hello" message) from the parent window. + startPostingHello(); + window.addEventListener( + 'message', + messageListener, + false + ); + } + + function startPostingHello() { + if (helloInterval) { + stopPostingHello(); + } + helloInterval = window.setInterval( + postHello, + HELLO_INTERVAL_LENGTH + ); + window.setTimeout( + stopPostingHello, + HELLO_TIMEOUT_LENGTH + ); + // Post the first msg immediately. + postHello(); + } + + function stopPostingHello() { + window.clearInterval(helloInterval); + helloInterval = null; + } + + // Public API. + return { + initialize: initialize, + getListenerNames: getListenerNames, + addListener: addListener, + removeAllListeners: removeAllListeners, + disconnect: disconnect, + post: post, + }; + } + + var instance = null; + + // IFrameEndpoint is a singleton, as iframe can't have multiple parents anyway. + module.exports = function getIFrameEndpoint() { + if (!instance) { + instance = new IFrameEndpoint(); + } + return instance; + }; + }, + { './structured-clone': 9 }, + ], + 7: [ + function (require, module, exports) { + var ParentEndpoint = require('./parent-endpoint'); + var getIFrameEndpoint = require('./iframe-endpoint'); + + // Not a real UUID as there's an RFC for that (needed for proper distributed computing). + // But in this fairly parochial situation, we just need to be fairly sure to avoid repeats. + function getPseudoUUID() { + var chars = + 'abcdefghijklmnopqrstuvwxyz0123456789'; + var len = chars.length; + var ret = []; + + for (var i = 0; i < 10; i++) { + ret.push( + chars[Math.floor(Math.random() * len)] + ); + } + return ret.join(''); + } + + module.exports = function IframePhoneRpcEndpoint( + handler, + namespace, + targetWindow, + targetOrigin, + phone + ) { + var pendingCallbacks = Object.create({}); + + // if it's a non-null object, rather than a function, 'handler' is really an options object + if (handler && typeof handler === 'object') { + namespace = handler.namespace; + targetWindow = handler.targetWindow; + targetOrigin = handler.targetOrigin; + phone = handler.phone; + handler = handler.handler; + } + + if (!phone) { + if (targetWindow === window.parent) { + phone = getIFrameEndpoint(); + phone.initialize(); + } else { + phone = new ParentEndpoint( + targetWindow, + targetOrigin + ); + } + } + + phone.addListener( + namespace, + function (message) { + var callbackObj; + + if ( + message.messageType === 'call' && + typeof this.handler === 'function' + ) { + this.handler.call( + undefined, + message.value, + function (returnValue) { + phone.post(namespace, { + messageType: 'returnValue', + uuid: message.uuid, + value: returnValue, + }); + } + ); + } else if ( + message.messageType === 'returnValue' + ) { + callbackObj = + pendingCallbacks[message.uuid]; + + if (callbackObj) { + window.clearTimeout(callbackObj.timeout); + if (callbackObj.callback) { + callbackObj.callback.call( + undefined, + message.value + ); + } + pendingCallbacks[message.uuid] = null; + } + } + }.bind(this) + ); + + function call(message, callback) { + var uuid = getPseudoUUID(); + + pendingCallbacks[uuid] = { + callback: callback, + timeout: window.setTimeout(function () { + if (callback) { + callback( + undefined, + new Error( + 'IframePhone timed out waiting for reply' + ) + ); + } + }, 2000), + }; + + phone.post(namespace, { + messageType: 'call', + uuid: uuid, + value: message, + }); + } + + function disconnect() { + phone.disconnect(); + } + + this.handler = handler; + this.call = call.bind(this); + this.disconnect = disconnect.bind(this); + }; + }, + { './iframe-endpoint': 6, './parent-endpoint': 8 }, + ], + 8: [ + function (require, module, exports) { + var structuredClone = require('./structured-clone'); + + /** Call as: new ParentEndpoint(targetWindow, targetOrigin, afterConnectedCallback) targetWindow is a WindowProxy object. (Messages will be sent to it) @@ -1679,218 +2935,1664 @@ var structuredClone = require('./structured-clone'); more about this weird behavior of WindowProxies (the type returned by