Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for Simple-Data-Grapher #6104

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
//= require leaflet_helper
//= require grids.js
//= require graph.js
//= require simple-data-grapher.js
//= require wikis.js
//= require header_footer.js
//= require keybindings.js
Expand Down
3 changes: 3 additions & 0 deletions app/assets/javascripts/csvfiles.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
76 changes: 76 additions & 0 deletions app/assets/javascripts/simple-data-grapher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
function determineType2(graphType){
if (graphType=="Horizontal" || graphType=="Vertical"){
return "bar";
}
else if (graphType=="Pie" || graphType=="Doughnut" || graphType=="Radar" ){
return "pie";
}
else if (graphType=="Basic" || graphType=="Stepped" || graphType=="Point"){
return "scatter";
}
}
function layoutMaker(graphType){
var layout={};
if (graphType=="Horizontal" || graphType=="Vertical"){
layout["barmode"]="group";
}
return layout;
}
function traceMaker(graphType){
var 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){
var 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){
var layout=layoutMaker(graphType);
var data=[];
var keySet=keyDeterminer(graphType);
for (var i=0;i<length;i++){
var 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);
}
console.log(data);
Plotly.newPlot(divId,data,layout);

}
function graphMaker(data,divId){
var obj = data["sdgobject"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be possible to use let instead of var here, because limiting the scope could avoid future global variable-related bugs :) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

var string = "hash = " + obj + ";";
var actualHash = eval(string);
var dataHash = actualHash["hash"];
var length = actualHash["length"];
var graphType = actualHash["graphType"];
console.log(data,dataHash,length,graphType);
plotGraph2(dataHash,length,graphType,divId);
}
3 changes: 3 additions & 0 deletions app/assets/stylesheets/csvfiles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Place all the styles related to the csvfiles controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/
59 changes: 59 additions & 0 deletions app/controllers/csvfiles_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
class CsvfilesController < ApplicationController
before_action :require_user, only: %i(delete user_files)
before_action :add_graphobject, only: %i(fetch_graphobject)

def new
# to render the index page of simple-data-grapher
end

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
10 changes: 10 additions & 0 deletions app/controllers/editor_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ def editor
end

def post
@graphobject = ""
if params[:id] && params[:uid]
@graphobject = [params[:id],params[:uid]]
end
# byebug
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, is this required?

if params[:tags]&.include?('question:')
redirect_to "/questions/new?#{request.env['QUERY_STRING']}"
elsif params[:legacy] || params[:template] == 'event'
Expand All @@ -38,6 +43,10 @@ def rich
image if params[:i]
end

# def tempfunc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to leave this commented code?

# redirect_to editor_path(f: params[:graphobject])
# end

private

def image
Expand All @@ -50,4 +59,5 @@ def template
node = Node.find(params[:n])
params[:body] = node.body if node
end

end
2 changes: 1 addition & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def insert_extras(body)
body = NodeShared.people_grid(body, @current_user || nil) # <= to allow testing of insert_extras
body = NodeShared.graph_grid(body)
body = NodeShared.wikis_grid(body)
body
body = NodeShared.simple_data_grapher(body)
end

# we should move this to the Node model:
Expand Down
2 changes: 2 additions & 0 deletions app/helpers/csvfiles_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module CsvfilesHelper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More changes in the future I guess

end
16 changes: 16 additions & 0 deletions app/models/concerns/node_shared.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ def self.graph_grid(body, _page = 1)
end
end

def self.simple_data_grapher(body, _page=1)
start = "Power Tag: simple-data-grapher: "
ending = "]</p>"
ids = body[/#{start}(.*?)#{ending}/m, 1].split("/")
a = ActionController::Base.new
randomSeed = rand(1000).to_s
output = a.render_to_string(template: "grids/_simple-data-grapher",
layout: false,
locals: {
uid: ids[2],
id: ids[1],
idName: 'sdg-graph-' + randomSeed
})
output
end

# rubular regex: http://rubular.com/r/hBEThNL4qd
def self.notes_grid(body, _page = 1)
body.gsub(/(?<![\>`])(\<p\>)?\[notes\:(\S+)\]/) do |_tagname|
Expand Down
3 changes: 3 additions & 0 deletions app/models/csvfile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Csvfile < ApplicationRecord
belongs_to :user, foreign_key: :uid
end
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module Frequency

has_many :images, foreign_key: :uid
has_many :node, foreign_key: 'uid'
has_many :csvfiles, foreign_key: :uid
has_many :node_selections, foreign_key: :user_id
has_many :revision, foreign_key: 'uid'
has_many :user_tags, foreign_key: 'uid', dependent: :destroy
Expand Down
155 changes: 155 additions & 0 deletions app/views/csvfiles/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<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 %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I did not understand why you have JS code in an embedded ruby file. Would it make sense to move the JS code to a separate file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this file is very much like the rich.html.erb , which integrates the PL Editor in the same way as Simple-Data-Grapher, that is why it's required here!

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: '/simple-data-grapher/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: '/simple-data-grapher/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(){
console.log(SimpleDataGrapherObject.view.plotlyjsPlotter.dataHash);
console.log(SimpleDataGrapherObject.view.plotlyjsPlotter.graphType);
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: '/simple-data-grapher/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){
console.log("saved",data);
window.location = '/post?uid='+data["uid"]+'&id='+data["id"];
},
error: function(XMLHttpRequest, textStatus, errorThrown){
console.log("error");
}
});
});

<% end %>
setTimeout("$('.alert-success .alert-danger').fadeOut('slow')", 7000)
</script>

Loading