-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simple Data Grapher: Integration + Research Note + Tests (#6113)
* New Table for CsvFiles * belongs_to for CSV files * CSV controller code * routes for simple-data-grapher * has_many relation for users * view files for csvfiles * user data display * Added simple-data-grapher package * Delete Gemfile * Gemfile * code climate * Climate 2 * climate 3 * fix code climate issues * Update schema.rb.example * Fixing changes * Error Handling * Fixed the errors * linting * minor fix in alert * more linting * work on research note * Publish as a Research Note Ready! * updating schema * Tests for Csvfiles controller for Simple Data Grapher * Bug Fixes * Schema's time stamp * climate fixes * cc * return statement * refactor graph details method * Update node_shared.rb * Adding line break * Refactored and changes Power tag * removing spacing in rich.html.erb * trying to fix cyclomatic complexity (code climate) * Updating SDG version with new UI * refactoring js code * linting fixes * linting errors * more linting fixes * removing log statements * index * Changing routes * system test * fixing test
- Loading branch information
1 parent
3a0e974
commit 6b9d93b
Showing
22 changed files
with
1,442 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
function determineType2(graphType){ | ||
if (graphType === "Horizontal" || graphType === "Vertical"){ | ||
return "bar"; | ||
} | ||
else if (graphType === "Pie" || graphType === "Doughnut" || graphType === "Radar" ){ | ||
return "pie"; | ||
} | ||
else { | ||
return "scatter"; | ||
} | ||
} | ||
function layoutMaker(graphType){ | ||
let layout = {}; | ||
if (graphType === "Horizontal" || graphType === "Vertical"){ | ||
layout["barmode"] = "group"; | ||
} | ||
return layout; | ||
} | ||
function traceMaker(graphType){ | ||
let trace = {}; | ||
trace["type"] = determineType2(graphType); | ||
if (graphType === "Horizontal"){ | ||
trace["orientation"] = "h"; | ||
} | ||
else if (graphType === "Doughnut"){ | ||
trace["hole"] = 0.5; | ||
} | ||
else if (graphType === "Basic"){ | ||
trace["mode"] = "lines"; | ||
} | ||
else if (graphType === "Point"){ | ||
trace["mode"] = "markers"; | ||
} | ||
else if (graphType === "Stepped"){ | ||
trace["mode"] = "lines+markers"; | ||
trace["line"] = { "shape": 'hv' }; | ||
} | ||
return trace; | ||
} | ||
function keyDeterminer(graphType){ | ||
let keys = ["x", "y"]; | ||
if (graphType === "Pie" || graphType === "Doughnut"){ | ||
keys[1] = "values"; | ||
keys[0] = "labels"; | ||
} | ||
else if (graphType === "Horizontal"){ | ||
keys[0] = "y"; | ||
keys[1] = "x"; | ||
} | ||
return keys; | ||
} | ||
function plotGraph2(dataHash, length, graphType, divId){ | ||
let layout = layoutMaker(graphType); | ||
let data = []; | ||
let keySet = keyDeterminer(graphType); | ||
for (let i = 0;i < length;i++){ | ||
let new_trace = traceMaker(graphType); | ||
new_trace[keySet[0]] = dataHash['x_axis_labels']; | ||
new_trace[keySet[1]] = dataHash['y_axis_values' + i]; | ||
new_trace["name"] = dataHash['labels'][1][i]; | ||
data.push(new_trace); | ||
} | ||
Plotly.newPlot(divId, data, layout); | ||
} | ||
function graphMaker(data, divId){ | ||
let obj = data["sdgobject"]; | ||
let actualHash = JSON.parse(obj); | ||
let dataHash = actualHash["hash"]; | ||
let length = actualHash["length"]; | ||
let graphType = actualHash["graphType"]; | ||
plotGraph2(dataHash, length, graphType, divId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
class CsvfilesController < ApplicationController | ||
before_action :require_user, only: %i(delete user_files) | ||
|
||
def setter | ||
@csvfile = Csvfile.new( | ||
uid: params[:uid], | ||
filetitle: params[:filetitle], | ||
filedescription: params[:filedescription], | ||
filepath: params[:object], | ||
filename: "file" + Time.now.to_i.to_s, | ||
filestring: params[:filestring] | ||
) | ||
render json: @csvfile if @csvfile.save | ||
end | ||
|
||
def prev_files | ||
@allfile = Csvfile.where(uid: params[:uid]) | ||
render json: @allfile | ||
end | ||
|
||
def user_files | ||
@user_files = Csvfile.where(uid: params[:id]) | ||
end | ||
|
||
def add_graphobject | ||
@newfile = Csvfile.new( | ||
uid: params[:uid], | ||
filetitle: params[:filetitle], | ||
filedescription: params[:filedescription], | ||
filepath: params[:object], | ||
filename: "file" + Time.now.to_i.to_s, | ||
filestring: params[:filestring], | ||
graphobject: params[:graphobject] | ||
) | ||
@newfile.save | ||
render json: { uid: params[:uid], id: @newfile.id } | ||
end | ||
|
||
def delete | ||
return unless params[:id] && params[:uid].to_i == current_user.uid | ||
file = Csvfile.where(id: params[:id].to_i) | ||
if file.destroy(params[:id].to_i) | ||
flash[:notice] = "Deleted the file" | ||
else | ||
flash[:error] = "Could not delete the file" | ||
end | ||
redirect_to "simple-data-grapher/data/#{params[:uid]}" | ||
end | ||
|
||
def fetch_graphobject | ||
@graphobject = Csvfile.where(id: params[:id].to_i, uid: params[:uid].to_i) | ||
render json: { sdgobject: @graphobject[0].graphobject } | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module CsvfilesHelper | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class Csvfile < ApplicationRecord | ||
belongs_to :user, foreign_key: :uid | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> | ||
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.js"></script> | ||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.6.3/papaparse.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/1.33.1/plotly-basic.min.js"></script> | ||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css"> | ||
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"> | ||
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.14.3/xlsx.full.min.js"></script> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css"> | ||
<%= javascript_include_tag('/lib/simple-data-grapher/dist/PublicLab.Grapher.js')%> | ||
<%= stylesheet_link_tag '/lib/simple-data-grapher/examples/upload_file.css'%> | ||
<div id='first'></div> | ||
<script> | ||
var headerContainer = document.getElementsByClassName('body-container')[0]; | ||
SimpleDataGrapherObject = new SimpleDataGrapher('first'); | ||
var value = '<%= current_user %>'; | ||
<% if current_user %> | ||
SimpleDataGrapherObject.view.createButtons('yes'); | ||
var saveButton = SimpleDataGrapherObject.view.elementId + '_save_CSV'; | ||
var prevFile = SimpleDataGrapherObject.view.elementId + '_prev_file'; | ||
var saveFlag = false; | ||
$('#' + saveButton).click(function(){ | ||
saveFlag = true; | ||
}); | ||
$('#' + SimpleDataGrapherObject.view.plotGraphId).click(function(){ | ||
if (saveFlag){ | ||
var arr = {}; | ||
arr['completeCsvMatrix'] = SimpleDataGrapherObject.view.csvParser.completeCsvMatrix; | ||
arr['csvHeaders'] = SimpleDataGrapherObject.view.csvParser.csvHeaders; | ||
arr['csvSampleData'] = SimpleDataGrapherObject.view.csvParser.csvSampleData; | ||
arr['csvValidForYAxis'] = SimpleDataGrapherObject.view.csvParser.csvValidForYAxis; | ||
arr['completeCsvMatrixTranspose'] = SimpleDataGrapherObject.view.csvParser.completeCsvMatrixTranspose; | ||
let csvStringMatrix = SimpleDataGrapherObject.view.csvParser.completeCsvMatrixTranspose; | ||
let csvStringForDownload = encodeURI('data:text/csv;charset=utf-8,' + csvStringMatrix.map(e => e.join(',')).join('\n')); | ||
$.ajax({ | ||
url: '/graph/object', | ||
type: 'post', | ||
data: { object: JSON.stringify(arr), | ||
uid: <%= current_user.id %>, | ||
filetitle: SimpleDataGrapherObject.view.fileTitle, | ||
filedescription: SimpleDataGrapherObject.view.fileDescription, | ||
filestring: csvStringForDownload }, | ||
success: function(data){ | ||
let divAlert = document.createElement('div'); | ||
divAlert.classList.add('alert'); | ||
divAlert.classList.add('alert-success'); | ||
divAlert.innerHTML = 'File save successfully!'; | ||
headerContainer.appendChild(divAlert); | ||
}, | ||
error: function(XMLHttpRequest, textStatus, errorThrown){ | ||
console.log(errorThrown); | ||
let divAlert = document.createElement('div'); | ||
divAlert.classList.add('alert'); | ||
divAlert.classList.add('alert-danger'); | ||
divAlert.innerHTML = 'There was some error in saving the file.'; | ||
headerContainer.appendChild(divAlert); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
$('#' + prevFile).click(function(){ | ||
$.ajax({ | ||
url: '/graph/prev_file', | ||
type: 'get', | ||
data: { uid: <%= current_user.id %> }, | ||
success: function(data){ | ||
displayPreviousFiles(data); | ||
}, | ||
error: function(XMLHttpRequest, textStatus, errorThrown){ | ||
console.log(errorThrown); | ||
let divAlert = document.createElement('div'); | ||
divAlert.classList.add('alert'); | ||
divAlert.classList.add('alert-danger'); | ||
divAlert.innerHTML = 'There was some error in retrieving the file.'; | ||
headerContainer.appendChild(divAlert); | ||
} | ||
}); | ||
}); | ||
|
||
function displayPreviousFiles(data){ | ||
var table=document.createElement('table'); | ||
for (let i = 0;i<data.length;i++){ | ||
let tr = document.createElement('tr'); | ||
let td = document.createElement('td'); | ||
let radio = document.createElement('input'); | ||
radio.type = 'radio'; | ||
radio.value = i; | ||
radio.name = data[0]['csvfile']['uid'] + 'user_id'; | ||
td.appendChild(radio); | ||
td.appendChild(document.createTextNode(data[i]['csvfile']['filetitle'])); | ||
tr.appendChild(td); | ||
table.appendChild(tr); | ||
} | ||
let div = document.getElementById(SimpleDataGrapherObject.view.upload_button_container); | ||
div.appendChild(table); | ||
selectFile(data); | ||
} | ||
function selectFile(data){ | ||
$('#' + SimpleDataGrapherObject.view.uploadButtonId).click(function(){ | ||
let name = data[0]['csvfile']['uid'] + 'user_id'; | ||
let index = $('input[name=' + name + ']:checked').val(); | ||
let allfiles = JSON.parse(data[index]['csvfile']['filepath']); | ||
SimpleDataGrapherObject.view.usingPreviouslyUploadedFile(); | ||
SimpleDataGrapherObject.view.csvParser.completeCsvMatrix = allfiles['completeCsvMatrix']; | ||
SimpleDataGrapherObject.view.csvParser.csvHeaders = allfiles['csvHeaders']; | ||
SimpleDataGrapherObject.view.csvParser.csvSampleData = allfiles['csvSampleData']; | ||
SimpleDataGrapherObject.view.csvParser.csvValidForYAxis = allfiles['csvValidForYAxis']; | ||
SimpleDataGrapherObject.view.csvParser.completeCsvMatrixTranspose = allfiles['completeCsvMatrixTranspose']; | ||
SimpleDataGrapherObject.view.continueViewManipulation('prevfile'); | ||
}); | ||
} | ||
$('#' + SimpleDataGrapherObject.view.elementId + '_publish').click(function(){ | ||
var arr = {}; | ||
arr['completeCsvMatrix'] = SimpleDataGrapherObject.view.csvParser.completeCsvMatrix; | ||
arr['csvHeaders'] = SimpleDataGrapherObject.view.csvParser.csvHeaders; | ||
arr['csvSampleData'] = SimpleDataGrapherObject.view.csvParser.csvSampleData; | ||
arr['csvValidForYAxis'] = SimpleDataGrapherObject.view.csvParser.csvValidForYAxis; | ||
arr['completeCsvMatrixTranspose'] = SimpleDataGrapherObject.view.csvParser.completeCsvMatrixTranspose; | ||
let csvStringMatrix = SimpleDataGrapherObject.view.csvParser.completeCsvMatrixTranspose; | ||
let csvStringForDownload = encodeURI('data:text/csv;charset=utf-8,' + csvStringMatrix.map(e => e.join(',')).join('\n')); | ||
var dataObject = {}; | ||
dataObject['hash'] = SimpleDataGrapherObject.view.plotlyjsPlotter.dataHash; | ||
dataObject['graphType'] = SimpleDataGrapherObject.view.plotlyjsPlotter.graphType; | ||
dataObject['length'] = SimpleDataGrapherObject.view.plotlyjsPlotter.length; | ||
$.ajax({ | ||
url: '/graph/note/graphobject', | ||
type: 'post', | ||
data: { object: JSON.stringify(arr), | ||
uid: <%= current_user.id %>, | ||
filetitle: SimpleDataGrapherObject.view.fileTitle, | ||
filedescription: SimpleDataGrapherObject.view.fileDescription, | ||
filestring: csvStringForDownload, | ||
graphobject: JSON.stringify(dataObject) }, | ||
success: function(data){ | ||
window.location = '/post?body=%5Bsimple-data-grapher:i/' + data['uid'] + '/' + data['id'] + '%5D'; | ||
}, | ||
error: function(XMLHttpRequest, textStatus, errorThrown){ | ||
console.log(errorThrown); | ||
} | ||
}); | ||
}); | ||
|
||
<% end %> | ||
setTimeout("$('.alert-success .alert-danger').fadeOut('slow')", 7000) | ||
</script> | ||
|
Oops, something went wrong.