Commit e659894b authored by Gabriel Gutu-Robu's avatar Gabriel Gutu-Robu

CSCL New Demo is now main demo for CSCL

parent 36384fcb
......@@ -33,7 +33,8 @@
"src/assets/styles/icomoon.css",
"src/assets/styles/main.css",
"src/assets/styles/screen.css",
"./node_modules/ngx-ui-switch/ui-switch.component.css"
"node_modules/ngx-ui-switch/ui-switch.component.css",
"node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
......@@ -151,7 +152,8 @@
"src/assets/styles/icomoon.css",
"src/assets/styles/main.css",
"src/assets/styles/screen.css",
"./node_modules/ngx-ui-switch/ui-switch.component.css"
"node_modules/ngx-ui-switch/ui-switch.component.css",
"node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css"
],
"assets": [
"src/assets",
......
......@@ -8,7 +8,7 @@ import { TextualComplexityComponent } from '../pages/demo/textual-complexity/tex
import { KeywordsComponent } from '../pages/demo/keywords/keywords.component';
import { SemanticAnnotationComponent } from '../pages/demo/semantic-annotation/semantic-annotation.component';
import { SelfExplanationComponent } from '../pages/demo/self-explanation/self-explanation.component';
import { CsclComponent } from '../pages/demo/cscl/cscl.component';
import { CsclOldComponent } from '../pages/demo/cscl-old/cscl-old.component';
import { CvAnalysisComponent } from '../pages/demo/cv-analysis/cv-analysis.component';
import { LakComponent } from '../pages/demo/lak/lak.component';
import { CommunityComponent } from '../pages/demo/community/community.component';
......@@ -21,7 +21,7 @@ import { ComprehensionModelComponent } from '../pages/demo/comprehension-model/c
import { KeywordsHeatmapComponent } from '../pages/demo/keywords-heatmap/keywords-heatmap.component';
import { CurriculumRecommendationComponent } from '../pages/demo/curriculum-recomandation/curriculum-recommendation.component';
import { DocumentAnalysisComponent } from "../pages/demo/document-analysis/document-analysis";
import { CsclNewComponent } from '../pages/demo/cscl-new/cscl-new.component';
import { CsclComponent } from '../pages/demo/cscl/cscl.component';
import { EssayFeedbackComponent } from '../pages/demo/essay-feedback/essay-feedback.component';
import { IntellitComponent } from '../pages/experiments/intellit/intellit.component';
......@@ -71,12 +71,12 @@ const routes: Routes = [
component: SelfExplanationComponent,
},
{
path: 'demo/cscl',
component: CsclComponent,
path: 'demo/cscl-old',
component: CsclOldComponent,
},
{
path: 'demo/cscl-new',
component: CsclNewComponent,
path: 'demo/cscl',
component: CsclComponent,
},
{
path: 'demo/cv-analysis',
......
......@@ -25,7 +25,7 @@ import { EdgeBundlingDiagramComponent } from './pages/demo/comprehension-model/e
import { KeywordsComponent } from './pages/demo/keywords/keywords.component';
import { SemanticAnnotationComponent } from './pages/demo/semantic-annotation/semantic-annotation.component';
import { SelfExplanationComponent } from './pages/demo/self-explanation/self-explanation.component';
import { CsclComponent } from './pages/demo/cscl/cscl.component';
import { CsclOldComponent } from './pages/demo/cscl-old/cscl-old.component';
import { CvAnalysisComponent } from './pages/demo/cv-analysis/cv-analysis.component';
import { LakComponent } from './pages/demo/lak/lak.component';
import { CommunityComponent } from './pages/demo/community/community.component';
......@@ -53,7 +53,7 @@ import { EssayFeedbackComponent } from './pages/demo/essay-feedback/essay-feedba
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
// Import library module
import { NgxSpinnerModule } from "ngx-spinner";
import { NgxSpinnerModule } from 'ngx-spinner';
import 'jquery';
import { PeopleComponent } from './pages/people/people.component';
......@@ -75,12 +75,14 @@ import {NgbAccordion, NgbAccordionModule, NgbModule, NgbRatingModule} from '@ng-
import { DocumentAnalysisComponent } from './pages/demo/document-analysis/document-analysis';
import { Ng5SliderModule } from 'ng5-slider';
import { MultiDocumentCohesionGridComponent } from './pages/demo/document-analysis/multi-document-cohesion-grid/multi-document-cohesion-grid';
import { CsclNewComponent } from './pages/demo/cscl-new/cscl-new.component';
import { CsclComponent } from './pages/demo/cscl/cscl.component';
import { DropzoneModule, DropzoneConfigInterface, DROPZONE_CONFIG } from 'ngx-dropzone-wrapper';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar';
import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
import {MatSliderModule} from '@angular/material/slider';
const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
// Change this to your upload POST address:
url: '//readerbench.com/api/v2/file-upload',
......@@ -116,8 +118,8 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
IntellitComponent,
SemanticAnnotationComponent,
SelfExplanationComponent,
CsclOldComponent,
CsclComponent,
CsclNewComponent,
CvAnalysisComponent,
ComprehensionModelComponent,
CMScoresTableComponent,
......@@ -164,7 +166,8 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
UiSwitchModule,
DropzoneModule,
PerfectScrollbarModule,
NgxSpinnerModule
NgxSpinnerModule,
MatSliderModule
],
exports: [
KeywordsComponent
......
.dropzone.dropzone-default.dropzone-success {
border-color: #0abb87;
}
.dropzone.dropzone-default {
/* min-height: 350px; */
padding: 20px;
text-align: center;
cursor: pointer;
border: 2px dashed #ebedf2;
border-radius: 4px;
}
.dropzone {
min-height: 150px;
border: 2px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 20px 20px;
}
.dropzone,
.dropzone * {
box-sizing: border-box;
}
.dropzone {
min-height: auto;
}
.contributions-indices td,
.contributions-indices th {
font-size: 12px;
padding: 0 5px;
text-align: left;
vertical-align: top;
}
.contributions-indices>thead th,
.contributions-indices>tbody td.contribution-id,
.contributions-indices>tfoot td {
color: #43b9c7;
font-weight: bold;
}
.contributions-indices td.value {
text-align: right;
}
#cscl-tabs ul {
display: inline-block;
list-style-type: none;
}
#cscl-tabs ul li {
display: inline-block;
}
#cscl-tabs ul li a {
cursor: pointer;
}
#cscl-tabs ul li a span {
vertical-align: middle;
display: inline-block;
padding: 10px 25px;
color: #43b9c7;
font-size: 12px;
line-height: 1em;
font-weight: 400;
letter-spacing: 0.2em;
text-transform: uppercase;
}
This diff is collapsed.
This diff is collapsed.
<div class="row">
<div class="page-wrapper">
<!-- <search-box></search-box> -->
<div id="page">
<app-header></app-header>
<div class="content-wrapper">
<app-carousel></app-carousel>
<div class="container">
<div class="row top-buffer">
<app-demo-menu></app-demo-menu>
</div>
</div>
<div class="container">
<div class="section-header">
<h1>Computer Supported Collaborative Learning</h1>
</div>
</div>
<div class="container">
<div class="form-group">
<div class="input">
<div class="row">
<div class="col-xs-3 col-md-3">
<label for="file">CSCL file <span class="required">*</span><br /><small>(only XML files
allowed)</small></label>
</div>
<div class="col-xs-4 col-md-4">
<input id="file" class="btn theme-btn-1" type="file" (change)="fileChange($event)"
placeholder="Upload file" accept=".xml" valie="Select File: " />
File:
<small>{{uploadedFileName}}
<span class="progress" ng-show="csclFile.progress >= 0">
<!-- <div style="width:{{csclFile.progress}}%" ng-bind="csclFile.progress + '%'"></div> -->
</span>
</small>
{{csclErrorMsg}}
<input type="hidden" ng-model="formData.csclFile" />
</div>
<div class="col-xs-3 col-md-3">
<a href="{{sampleFileUrl}}" target="_blank">Sample CSCL file</a>
</div>
</div>
<app-demo-common-fields [formData]="formData" [language]="language" [languages]="languages"
(advancedEmitter)="advancedEmitter($event)" (languageEmitter)="languageEmitter($event)">
</app-demo-common-fields>
<div class="row top-buffer" *ngIf="!loading">
<div class="col-xs-12 col-md-12">
<div class="bottom-buttons" *ngIf="!loading">
<button class="btn theme-btn-1" (click)="process()">
<span class="button">Process</span>
</button>
</div>
</div>
</div>
</div>
<div id="results">
<div class="row" *ngIf="loading">
<div class="col-xs-12 col-md-12">
<img src="../../../../assets/img/loading.gif" alt="Loading..." />
</div>
</div>
<div *ngIf="showResults === true">
<div class="col-xs-12 col-md-3">
<h4>Participant Interaction</h4>
<ul class="course-description-list">
<li class="lesson" *ngFor="let participant of participants">
<div class="heading">
<span class="lesson-nr no-select"></span>
</div>
<div class="body">
<p>{{participant.displayName}}</p>
</div>
</li>
</ul>
</div>
<!-- <div class="col-xs-12 col-md-9">
<two-mode-graph [graph]="participantInteractionGraph"></two-mode-graph>
</div> -->
<div class="col-xs-12 col-md-9" id="participantInteractionMap"></div> -->
<div class="col-xs-12 col-md-12">
<h4>CSCL Indices</h4>
<table class="cscl-indices">
<tbody>
<tr class="entry" *ngFor="let csclIndex of csclIndices | keyvalue">
<td class="participant">{{csclIndex.key}}</td>
<td class="value" *ngFor="let csclIndexInner of csclIndex.value | keyvalue">
{{csclIndexInner.value}}
</td>
</tr>
</tbody>
<thead>
<tr class="entry" *ngFor="let csclIndex of csclIndices | keyvalue; first as isFirst">
<ng-container *ngIf="isFirst">
<td class="participant">Participant</td>
<td class="value" *ngFor="let csclIndexInner of csclIndex.value | keyvalue">
{{csclIndexInner.key}}
</td>
</ng-container>
</tr>
</thead>
</table>
</div>
<div class="col-xs-12 col-md-12">
<h5>CSCL Indices Description</h5>
<ul class="course-description-list">
<li class="lesson cscl-indices-description"
*ngFor="let csclIndexDescription of csclIndicesDescription | keyvalue">
<div class="heading">
<span class="lesson-nr no-select">{{csclIndexDescription.key}}</span>
</div>
<div class="body">
<p>{{csclIndexDescription.value}}</p>
</div>
</li>
</ul>
</div>
<div class="col-xs-12 col-md-12">
<h4>Participant evolution</h4>
</div>
<div class="col-xs-12 col-md-12">
<svg id="participantEvolution" width="100%" height="300"></svg>
</div>
<div class="row">
<div class="col-xs-12 col-md-12">
<h4>Collaboration - Social Knowledge Building</h4>
</div>
<div class="col-xs-12 col-md-12">
<svg id="collaborationSocialKB" width="100%" height="300"></svg>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-12">
<h4>Collaboration - Voice Overlap</h4>
</div>
<div class="col-xs-12 col-md-12">
<svg id="collaborationVoiceOverlap" width="100%" height="300"></svg>
</div>
</div>
<div class="col-xs-12 col-md-3">
<h4>Concept Map</h4>
<ul class="course-description-list">
<li class="lesson" *ngFor="let topic of topics">
<div class="heading">
<span class="lesson-nr no-select">{{topic.degree | number}}</span>
</div>
<div class="body">
<p>{{topic.uri}}</p>
</div>
</li>
</ul>
</div>
<div class="col-xs-12 col-md-9">
<two-mode-graph [graph]="conceptMap"></two-mode-graph>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CsclNewComponent } from './cscl-new.component';
import { CsclOldComponent } from './cscl-old.component';
describe('CsclNewComponent', () => {
let component: CsclNewComponent;
let fixture: ComponentFixture<CsclNewComponent>;
describe('CsclOldComponent', () => {
let component: CsclOldComponent;
let fixture: ComponentFixture<CsclOldComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CsclNewComponent]
declarations: [CsclOldComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CsclNewComponent);
fixture = TestBed.createComponent(CsclOldComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
......
import { Component, OnInit, Input } from '@angular/core';
import { ApiRequestService } from '../api-request.service';
import { DefaultInputData } from '../demo.component.data';
import { CsclOldData } from './cscl-old.data';
import { isNil } from 'lodash';
import { TwoModeGraphService } from '../../../two-mode-graph.service';
import { ReaderBenchService } from '../../../readerbench.service';
@Component({
selector: 'app-old-cscl',
templateUrl: './cscl-old.component.html',
styleUrls: ['./cscl-old.component.css'],
providers: [ApiRequestService, TwoModeGraphService]
})
export class CsclOldComponent implements OnInit {
formData: any;
@Input() advanced: boolean;
loading: boolean;
showResults: boolean;
languages: any;
language: any;
response: any;
errors: any;
warnings: any;
isFileUploaded: boolean;
uploadedFileName: string;
topics: any;
topicEdges: any;
participants: any;
participantEdges: any;
participantEvolution: any;
collaborationSocialKBNodes: any;
voiceOverlapNodes: any;
csclIndices: any;
csclIndicesDescription: any;
conceptMap: any;
error: string;
participantInteractionGraph: any;
constructor(
private apiRequestService: ApiRequestService,
private twoModeGraphService: TwoModeGraphService,
private readerbenchService: ReaderBenchService
) {
}
ngOnInit() {
this.isFileUploaded = false;
this.languages = CsclOldData.languages;
this.language = CsclOldData.defaultLanguage;
this.formData = {
'language': this.language,
'pos-tagging': DefaultInputData.defaultPosTaggingOption(),
'dialogism': DefaultInputData.defaultDialogismOption(),
'threshold': DefaultInputData.semanticSimilarityThreshold
};
this.loadSemanticModels();
this.loading = false;
this.showResults = false;
}
loadSemanticModels() {
const languageValue = this.language.value;
this.formData['lsa'] = DefaultInputData.defaultMetricOptions.lsa[languageValue]();
this.formData['lda'] = DefaultInputData.defaultMetricOptions.lda[languageValue]();
this.formData['word2vec'] = DefaultInputData.defaultMetricOptions.word2vec[languageValue]();
}
advancedEmitter($event) {
this.advanced = $event;
}
languageEmitter($event) {
this.language = $event;
this.loadSemanticModels();
}
process() {
this.apiRequestService.setApiService(CsclOldData.serviceName);
this.apiRequestService.setHeaders(this.apiRequestService.HEADERS_TYPE_COMMON_REQUEST);
this.loading = true;
this.showResults = false;
const data = {
'cscl-file': this.uploadedFileName,
'language': this.formData['language'].value,
'lsa': this.formData['lsa'].value,
'lda': this.formData['lda'].value,
'w2v': this.formData['word2vec'].value,
'pos-tagging': this.formData['pos-tagging'],
'dialogism': this.formData['dialogism'],
'threshold': this.formData['threshold']
};
const process = this.apiRequestService.process(data);
process.subscribe(response => {
const _this = this;
this.response = response;
this.loading = false;
if (response.success !== true) {
if (!isNil(response.data.errorMsg)) {
alert(response.data.errorMsg);
} else {
alert('Server error occured!');
}
return;
}
this.showResults = true;
// build concept map
this.topics = response.data.conceptMap.nodeList;
const conceptGraph = {
nodeList: response.data.conceptMap.nodeList,
edgeList: response.data.conceptMap.edgeList,
};
this.twoModeGraphService.getGraph(conceptGraph).subscribe(
graph => { this.conceptMap = graph; },
error => { this.error = error.message; },
() => {
}
);
// participant interaction graph
// this.participantInteractionGraph = {
// 'nodeList': response.data.participantInteractionGraph.nodeList,
// 'edgeList': response.data.participantInteractionGraph.edgeList
// };
// this.twoModeGraphService.getGraph(this.participantInteractionGraph).subscribe(
// graph => { this.participantInteractionGraph = graph; },
// error => { this.error = error.message; },
// () => { }
// );
this.participants = response.data.participantInteractionGraph.nodeList;
this.participantEdges = response.data.participantInteractionGraph.edgeList;
const intervalParticipantInteraction = setInterval(function () {
if (_this.participantEdges.count === response.data.participantInteractionGraph.edgeList.count) {
clearInterval(intervalParticipantInteraction);
const participantInteractionGraph = {
'nodes': response.data.participantInteractionGraph.nodeList,
'links': response.data.participantInteractionGraph.edgeList
};
_this.readerbenchService.d3jsForTopics(
participantInteractionGraph,
'#participantInteractionMap',
false
);
}
}, 1000);
// build participant evolution graph
this.participantEvolution = response.data.participantEvolution;
const intervalParticipantEvolution = setInterval(function () {
if (_this.participantEvolution.count === response.data.participantEvolution.count) {
clearInterval(intervalParticipantEvolution);
_this.readerbenchService.d3jsMultipleLinesGraph(
response.data.participantEvolution,
'#participantEvolution',
'Contribution ID',
'value');
}
}, 1000);
// build collaboration kb graph
this.collaborationSocialKBNodes = response.data.socialKB;
const intervalCollaborationSocialKB = setInterval(function () {
if (_this.collaborationSocialKBNodes.count === response.data.socialKB.count) {
clearInterval(intervalCollaborationSocialKB);
_this.readerbenchService.d3jsLineGraph(
response.data.socialKB,
'#collaborationSocialKB',
'Contribution ID',
'Social KB value'
);
}
}, 1000);
// build collaboration voice graph
this.voiceOverlapNodes = response.data.voiceOverlap;
const intervalCollaborationVoiceOverlap = setInterval(function () {
if (_this.voiceOverlapNodes.count === response.data.voiceOverlap.count) {
clearInterval(intervalCollaborationVoiceOverlap);
_this.readerbenchService.d3jsLineGraph(
response.data.voiceOverlap,
'#collaborationVoiceOverlap',
'Contribution ID',
'Voice PMI'
);
}
}, 1000);
// build cscl indices
this.csclIndices = response.data.csclIndices;
const intervalCsclIndices = setInterval(function () {
if (_this.csclIndices.count === response.data.csclIndices.count) {
clearInterval(intervalCsclIndices);
}
}, 1000);
// build cscl indices description
this.csclIndicesDescription = response.data.csclIndicesDescription;
const intervalCsclIndicesDescription = setInterval(function () {
if (_this.csclIndicesDescription.count === response.data.csclIndicesDescription.count) {
clearInterval(intervalCsclIndicesDescription);
}
}, 1000);
});
}
fileChange(event) {
this.apiRequestService.setApiService(CsclOldData.fileUploadEndpointKey);
this.apiRequestService.setHeaders(this.apiRequestService.HEADERS_TYPE_FILE_UPLOAD);
const fileList: FileList = event.target.files;
if (fileList.length > 0) {
const file: File = fileList[0];
const formData: FormData = new FormData();
formData.append('file', file, file.name);
const process = this.apiRequestService.process(formData);
process.subscribe(response => {
if (!isNil(response.data.errors)) {
this.errors = response.data.errors;
}
if (!isNil(response.data.warnings)) {
this.warnings = response.data.warnings;
}
this.uploadedFileName = response.data.name;
this.isFileUploaded = true;
// jQuery('#submit-button').prop('disabled', false);
});
}
}
}
import { DefaultInputData } from '../demo.component.data';
export let CsclData = {
export let CsclOldData = {
'fileUploadEndpointKey': 'fileUpload',
'serviceName': 'csclProcessingNew',
'title': 'Computer-Supported Collaborative Learning (New)',
'serviceName': 'csclProcessingOld',
'title': 'Computer-Supported Collaborative Learning',
'languages': [
DefaultInputData.languages[0], // en
DefaultInputData.languages[1], // fr
DefaultInputData.languages[2], // ro
],
'defaultLanguage': DefaultInputData.languages[0] // en
};
......@@ -7,4 +7,4 @@ import { CommonModule } from '@angular/common';
],
declarations: []
})
export class CsclNewModule { }
export class CsclOldModule { }
.dropzone.dropzone-default.dropzone-success {
border-color: #0abb87;
}
.dropzone.dropzone-default {
/* min-height: 350px; */
padding: 20px;
text-align: center;
cursor: pointer;
border: 2px dashed #ebedf2;
border-radius: 4px;
}
.dropzone {
min-height: 150px;
border: 2px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 20px 20px;
}
.dropzone,
.dropzone * {
box-sizing: border-box;
}
.dropzone {
min-height: auto;
}
.contributions-indices td,
.contributions-indices th {
font-size: 12px;
padding: 0 5px;
text-align: left;
vertical-align: top;
}
.contributions-indices>thead th,
.contributions-indices>tbody td.contribution-id,
.contributions-indices>tfoot td {
color: #43b9c7;
font-weight: bold;
}
.contributions-indices td.value {
text-align: right;
}
#cscl-tabs ul {
display: inline-block;
list-style-type: none;
}
#cscl-tabs ul li {
display: inline-block;