Move ng2-nouislider to project and remove dependency. Fix some issues regarding EventTarget and ng2-nouislider
This commit is contained in:
parent
a7c8ffb49c
commit
6a269ec1e9
|
@ -1,6 +1,4 @@
|
|||
{
|
||||
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
|
||||
"whitelistedNonPeerDependencies": [
|
||||
"."
|
||||
]
|
||||
"allowedNonPeerDependencies": ["."]
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
"core-js": "^2.4.1",
|
||||
"file-saver": "^2.0.2",
|
||||
"jquery": "^3.4.1",
|
||||
"ng2-nouislider": "^1.8.2",
|
||||
"ngx-pagination": "^3.2.1",
|
||||
"nouislider": "^13.1.5",
|
||||
"rxjs": "^6.5.1",
|
||||
|
@ -56,4 +55,4 @@
|
|||
"ts-node": "~8.2.0",
|
||||
"typescript": "~4.6.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { SettingsComponent } from './settings/settings.component';
|
|||
import { ResultspreviewComponent } from './resultspreview/resultspreview.component';
|
||||
import {ConfigurationService} from './configuration.service';
|
||||
import {StepsnavbarModule} from '../stepsnvabar/stepsnavbar.module';
|
||||
import { NouisliderModule } from 'ng2-nouislider';
|
||||
import {NouisliderModule} from '../ng2-nouislider/ng2-nouislider.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<span>High<br>recall</span>
|
||||
</div>
|
||||
<div class="uk-width-expand@m">
|
||||
<nouislider [config]="sliderConfig" [(ngModel)]="settings.wordssplitnum" (ngModelChange)="onSliderChange($event)"></nouislider>
|
||||
<nouislider [ngModel]="settings.wordssplitnum" [config]="sliderConfig" (change)="onSliderChange($event)"></nouislider>
|
||||
</div>
|
||||
<div class="uk-width-auto uk-grid-item-match">
|
||||
<span>High<br>precision</span>
|
||||
|
@ -121,19 +121,19 @@
|
|||
<p class="uk-text-small">Select among the following text preprocessing steps.</p>
|
||||
<form class="uk-form-stacked">
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="stop-words-filter"><input id="stop-words-filter" class="uk-checkbox" type="checkbox" [checked]="settings.stopwords===1" (change)="stopwordsCheckBoxChange($event.target.checked)"> Stopword removal <span class="cm-tooltip" uk-icon="icon: info" title="<b>Remove</b> common words (e.g., <b>articles</b> like an, the etc., <b>prepositions</b> like after, to etc.)" uk-tooltip="pos: right"></span></label>
|
||||
<label class="uk-form-label" for="stop-words-filter"><input id="stop-words-filter" class="uk-checkbox" type="checkbox" [checked]="settings.stopwords===1" (change)="stopwordsCheckBoxChange($event.target)"> Stopword removal <span class="cm-tooltip" uk-icon="icon: info" title="<b>Remove</b> common words (e.g., <b>articles</b> like an, the etc., <b>prepositions</b> like after, to etc.)" uk-tooltip="pos: right"></span></label>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="punctuation-filter"><input id="punctuation-filter" class="uk-checkbox" type="checkbox" [checked]="settings.punctuation===1" (change)="punctuationCheckBoxChange($event.target.checked)"> Punctuation removal</label>
|
||||
<label class="uk-form-label" for="punctuation-filter"><input id="punctuation-filter" class="uk-checkbox" type="checkbox" [checked]="settings.punctuation===1" (change)="punctuationCheckBoxChange($event.target)"> Punctuation removal</label>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="all-lowercase-filter"><input id="all-lowercase-filter" class="uk-checkbox" type="checkbox" [checked]="settings.allLowercase===1" (change)="allLowercaseCheckBoxChange($event.target.checked)"> Convert everything to lower case</label>
|
||||
<label class="uk-form-label" for="all-lowercase-filter"><input id="all-lowercase-filter" class="uk-checkbox" type="checkbox" [checked]="settings.allLowercase===1" (change)="allLowercaseCheckBoxChange($event.target)"> Convert everything to lower case</label>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="lowercase-filter"><input id="lowercase-filter" class="uk-checkbox" type="checkbox" [checked]="settings.lowercase===1" (change)="lowercaseCheckBoxChange($event.target.checked)"> Convert to lower-case only during evaluation of phrases</label>
|
||||
<label class="uk-form-label" for="lowercase-filter"><input id="lowercase-filter" class="uk-checkbox" type="checkbox" [checked]="settings.lowercase===1" (change)="lowercaseCheckBoxChange($event.target)"> Convert to lower-case only during evaluation of phrases</label>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="stemming-filter"><input id="stemming-filter" class="uk-checkbox" type="checkbox" [checked]="settings.stemming===1" (change)="stemmingCheckBoxChange($event.target.checked)"> Word stemming <span class="cm-tooltip" uk-icon="icon: info" title="Stemming is a process of text normalisation, in which the <b>variant forms of a word are reduced to a common form</b>, for <b>example</b>:<br>connection, connections, connective, connected, connecting<br><b>are reduced to connect</b>" uk-tooltip="pos: right"></span></label>
|
||||
<label class="uk-form-label" for="stemming-filter"><input id="stemming-filter" class="uk-checkbox" type="checkbox" [checked]="settings.stemming===1" (change)="stemmingCheckBoxChange($event.target)"> Word stemming <span class="cm-tooltip" uk-icon="icon: info" title="Stemming is a process of text normalisation, in which the <b>variant forms of a word are reduced to a common form</b>, for <b>example</b>:<br>connection, connections, connective, connected, connecting<br><b>are reduced to connect</b>" uk-tooltip="pos: right"></span></label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -173,13 +173,13 @@
|
|||
<div class="cm-match-area left">
|
||||
<label class="uk-form-label" for="context-prev-words">Number of words before the match</label>
|
||||
<div class="uk-form-controls">
|
||||
<input class="uk-input" type="number" name="context-prev-words" min="0" max="50" id="context-prev-words" placeholder="Before match, words" value="20" [value]="settings.contextprev" (change)="contextprevChange($event.target.value)"/>
|
||||
<input class="uk-input" type="number" name="context-prev-words" min="0" max="50" id="context-prev-words" placeholder="Before match, words" value="20" [value]="settings.contextprev" (change)="contextprevChange($event.target)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cm-match-area right cm-margin-medium-bottom">
|
||||
<label class="uk-form-label" for="context-next-words">Number of words after the match</label>
|
||||
<div class="uk-form-controls">
|
||||
<input class="uk-input" type="number" name="context-next-words" min="0" max="50" id="context-next-words" placeholder="After match, words" value="10" [value]="settings.contextnext" (change)="contextnextChange($event.target.value)"/>
|
||||
<input class="uk-input" type="number" name="context-next-words" min="0" max="50" id="context-next-words" placeholder="After match, words" value="10" [value]="settings.contextnext" (change)="contextnextChange($event.target)"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -191,45 +191,47 @@ export class SettingsComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
contextprevChange(value): void {
|
||||
contextprevChange(eventTarget: EventTarget): void {
|
||||
let value = +(eventTarget as HTMLInputElement).value;
|
||||
if (value < 0 || value > 20) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('contextprev', value);
|
||||
localStorage.setItem('contextprev', value.toString());
|
||||
this.getSettingsFromLocalStorage();
|
||||
}
|
||||
|
||||
contextnextChange(value): void {
|
||||
contextnextChange(eventTarget: EventTarget): void {
|
||||
let value = +(eventTarget as HTMLInputElement).value;
|
||||
if (value < 0 || value > 20) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('contextnext', value);
|
||||
localStorage.setItem('contextnext', value.toString());
|
||||
this.getSettingsFromLocalStorage();
|
||||
}
|
||||
|
||||
stopwordsCheckBoxChange(value: boolean): void {
|
||||
localStorage.setItem('stopwords', value ? '1' : '0');
|
||||
this.settings.stopwords = value ? 1 : 0;
|
||||
stopwordsCheckBoxChange(eventTarget: EventTarget): void {
|
||||
localStorage.setItem('stopwords', (eventTarget as HTMLInputElement).checked ? '1' : '0');
|
||||
this.settings.stopwords = (eventTarget as HTMLInputElement).checked ? 1 : 0;
|
||||
}
|
||||
|
||||
punctuationCheckBoxChange(value: boolean): void {
|
||||
localStorage.setItem('punctuation', value ? '1' : '0');
|
||||
this.settings.punctuation = value ? 1 : 0;
|
||||
punctuationCheckBoxChange(eventTarget: EventTarget): void {
|
||||
localStorage.setItem('punctuation', (eventTarget as HTMLInputElement).checked ? '1' : '0');
|
||||
this.settings.punctuation = (eventTarget as HTMLInputElement).checked ? 1 : 0;
|
||||
}
|
||||
|
||||
allLowercaseCheckBoxChange(value: boolean): void {
|
||||
localStorage.setItem('allLowercase', value ? '1' : '0');
|
||||
this.settings.allLowercase = value ? 1 : 0;
|
||||
allLowercaseCheckBoxChange(eventTarget: EventTarget): void {
|
||||
localStorage.setItem('allLowercase', (eventTarget as HTMLInputElement).checked ? '1' : '0');
|
||||
this.settings.allLowercase = (eventTarget as HTMLInputElement).checked ? 1 : 0;
|
||||
}
|
||||
|
||||
lowercaseCheckBoxChange(value: boolean): void {
|
||||
localStorage.setItem('lowercase', value ? '1' : '0');
|
||||
this.settings.lowercase = value ? 1 : 0;
|
||||
lowercaseCheckBoxChange(eventTarget: EventTarget): void {
|
||||
localStorage.setItem('lowercase', (eventTarget as HTMLInputElement).checked ? '1' : '0');
|
||||
this.settings.lowercase = (eventTarget as HTMLInputElement).checked ? 1 : 0;
|
||||
}
|
||||
|
||||
stemmingCheckBoxChange(value: boolean): void {
|
||||
localStorage.setItem('stemming', value ? '1' : '0');
|
||||
this.settings.stemming = value ? 1 : 0;
|
||||
stemmingCheckBoxChange(eventTarget: EventTarget): void {
|
||||
localStorage.setItem('stemming', (eventTarget as HTMLInputElement).checked ? '1' : '0');
|
||||
this.settings.stemming = (eventTarget as HTMLInputElement).checked ? 1 : 0;
|
||||
}
|
||||
|
||||
documentAreaChange(value: string): void {
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div uk-form-custom>
|
||||
<input type="file" name="upload" id="codes-file-input" class="inputfile" (change)="onFilesChange($event.srcElement.files[0])" />
|
||||
<input type="file" name="upload" id="codes-file-input" class="inputfile" (change)="onFilesChange($event.srcElement)" />
|
||||
<button class="uk-button uk-button-default cm-main-button" type="button" tabindex="-1">Choose file</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -87,7 +87,8 @@ export class ContentComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
onFilesChange(file: File) {
|
||||
onFilesChange(event: File | EventTarget) {
|
||||
let file = (event instanceof File)?event:(<HTMLInputElement>event).files[0];
|
||||
if (file !== null && file !== undefined) {
|
||||
const ext = file.name.split('.')[file.name.split('.').length - 1];
|
||||
const allowedExtensions = ['tsv', 'txt'];
|
||||
|
|
|
@ -0,0 +1,304 @@
|
|||
import * as noUiSlider from 'nouislider';
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
forwardRef,
|
||||
Input,
|
||||
OnInit,
|
||||
OnChanges,
|
||||
Output,
|
||||
Renderer2,
|
||||
NgZone,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormControl,
|
||||
NG_VALUE_ACCESSOR
|
||||
} from '@angular/forms';
|
||||
|
||||
export interface NouiFormatter {
|
||||
to(value: number): string;
|
||||
from(value: string): number;
|
||||
}
|
||||
|
||||
export class DefaultFormatter implements NouiFormatter {
|
||||
to(value: number): string {
|
||||
// formatting with http://stackoverflow.com/a/26463364/478584
|
||||
return String(parseFloat(parseFloat(String(value)).toFixed(2)));
|
||||
};
|
||||
|
||||
from(value: string): number {
|
||||
return parseFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'nouislider',
|
||||
host: {
|
||||
'[class.ng2-nouislider]': 'true'
|
||||
},
|
||||
template: '<div [attr.disabled]="disabled ? true : undefined"></div>',
|
||||
styles: [`
|
||||
:host {
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
`],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => NouisliderComponent),
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class NouisliderComponent implements ControlValueAccessor, OnInit, OnChanges, OnDestroy {
|
||||
|
||||
public slider: any;
|
||||
public handles: any[];
|
||||
@Input() public disabled: boolean; // tslint:disable-line
|
||||
@Input() public behaviour: string;
|
||||
@Input() public connect: boolean[];
|
||||
@Input() public limit: number;
|
||||
@Input() public min: number;
|
||||
@Input() public max: number;
|
||||
@Input() public snap: boolean;
|
||||
@Input() public animate: boolean | boolean[];
|
||||
@Input() public range: any;
|
||||
@Input() public step: number;
|
||||
@Input() public format: NouiFormatter;
|
||||
@Input() public pageSteps: number;
|
||||
@Input() public config: any = {};
|
||||
@Input() public ngModel: number | number[];
|
||||
@Input() public keyboard: boolean;
|
||||
@Input() public onKeydown: any;
|
||||
@Input() public formControl: FormControl;
|
||||
@Input() public tooltips: Array<any>;
|
||||
@Output() public change: EventEmitter<any> = new EventEmitter(true);
|
||||
@Output() public update: EventEmitter<any> = new EventEmitter(true);
|
||||
@Output() public slide: EventEmitter<any> = new EventEmitter(true);
|
||||
@Output() public set: EventEmitter<any> = new EventEmitter(true);
|
||||
@Output() public start: EventEmitter<any> = new EventEmitter(true);
|
||||
@Output() public end: EventEmitter<any> = new EventEmitter(true);
|
||||
private value: any;
|
||||
private onChange: any = Function.prototype;
|
||||
private cleanups: VoidFunction[] = [];
|
||||
|
||||
constructor(private ngZone: NgZone, private el: ElementRef, private renderer : Renderer2) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let inputsConfig = JSON.parse(
|
||||
JSON.stringify({
|
||||
behaviour: this.behaviour,
|
||||
connect: this.connect,
|
||||
limit: this.limit,
|
||||
start: this.formControl !== undefined ? this.formControl.value : this.ngModel,
|
||||
step: this.step,
|
||||
pageSteps: this.pageSteps,
|
||||
keyboard: this.keyboard,
|
||||
onKeydown: this.onKeydown,
|
||||
range: this.range || this.config.range || { min: this.min, max: this.max },
|
||||
tooltips: this.tooltips,
|
||||
snap: this.snap,
|
||||
animate: this.animate,
|
||||
}),
|
||||
);
|
||||
inputsConfig.tooltips = this.tooltips || this.config.tooltips;
|
||||
inputsConfig.format = this.format || this.config.format || new DefaultFormatter();
|
||||
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.slider = noUiSlider.create(
|
||||
this.el.nativeElement.querySelector('div'),
|
||||
Object.assign(this.config, inputsConfig)
|
||||
);
|
||||
});
|
||||
|
||||
this.handles = [].slice.call(this.el.nativeElement.querySelectorAll('.noUi-handle'));
|
||||
|
||||
if (this.config.keyboard) {
|
||||
if (this.config.pageSteps === undefined) {
|
||||
this.config.pageSteps = 10;
|
||||
}
|
||||
|
||||
for (const handle of this.handles) {
|
||||
handle.setAttribute('tabindex', 0);
|
||||
|
||||
const onKeydown = this.config.onKeydown || this.defaultKeyHandler;
|
||||
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.cleanups.push(
|
||||
this.renderer.listen(handle, 'keydown', onKeydown),
|
||||
this.renderer.listen(handle, 'click', () => {
|
||||
handle.focus();
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.slider.on('set', (values: string[], handle: number, unencoded: number[]) => {
|
||||
this.eventHandler(this.set, values, handle, unencoded);
|
||||
});
|
||||
|
||||
this.slider.on('update', (values: string[], handle: number, unencoded: number[]) => {
|
||||
if (this.update.observers.length > 0) {
|
||||
this.ngZone.run(() => {
|
||||
this.update.emit(this.toValues(values));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.slider.on('change', (values: string[], handle: number, unencoded: number[]) => {
|
||||
if (this.change.observers.length > 0) {
|
||||
this.ngZone.run(() => {
|
||||
this.change.emit(this.toValues(values));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.slider.on('slide', (values: string[], handle: number, unencoded: number[]) => {
|
||||
this.eventHandler(this.slide, values, handle, unencoded);
|
||||
});
|
||||
|
||||
this.slider.on('start', (values: string[], handle: number, unencoded: number[]) => {
|
||||
if (this.start.observers.length > 0) {
|
||||
this.ngZone.run(() => {
|
||||
this.start.emit(this.toValues(values));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.slider.on('end', (values: string[], handle: number, unencoded: number[]) => {
|
||||
if (this.end.observers.length > 0) {
|
||||
this.ngZone.run(() => {
|
||||
this.end.emit(this.toValues(values));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: any) {
|
||||
if (this.slider && (changes.min || changes.max || changes.step || changes.range)) {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
setTimeout(() => {
|
||||
this.slider.updateOptions({
|
||||
range: Object.assign({}, {
|
||||
min: this.min,
|
||||
max: this.max
|
||||
}, this.range || {}),
|
||||
step: this.step
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.slider.destroy();
|
||||
|
||||
while (this.cleanups.length) {
|
||||
this.cleanups.pop()();
|
||||
}
|
||||
}
|
||||
|
||||
toValues(values: string[]): any | any[] {
|
||||
let v = values.map(this.config.format.from);
|
||||
return (v.length == 1 ? v[0] : v);
|
||||
}
|
||||
|
||||
writeValue(value: any): void {
|
||||
if (this.slider) {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
setTimeout(() => {
|
||||
this.slider.set(value);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => {}): void {}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
isDisabled
|
||||
? this.renderer.setAttribute(this.el.nativeElement.childNodes[0], 'disabled', 'true')
|
||||
: this.renderer.removeAttribute(this.el.nativeElement.childNodes[0], 'disabled');
|
||||
}
|
||||
|
||||
private eventHandler = (emitter: EventEmitter<any>, values: string[], handle: number, unencoded: number[]) => {
|
||||
let v = this.toValues(values);
|
||||
let emitEvents = false;
|
||||
if(this.value === undefined) {
|
||||
this.value = v;
|
||||
return;
|
||||
}
|
||||
if(Array.isArray(v) && this.value[handle] != v[handle]) {
|
||||
emitEvents = true;
|
||||
}
|
||||
if(!Array.isArray(v) && this.value != v) {
|
||||
emitEvents = true;
|
||||
}
|
||||
if(emitEvents) {
|
||||
this.ngZone.run(() => {
|
||||
if (emitter.observers.length > 0) {
|
||||
emitter.emit(v);
|
||||
}
|
||||
this.onChange(v);
|
||||
});
|
||||
}
|
||||
if(Array.isArray(v)) {
|
||||
this.value[handle] = v[handle];
|
||||
} else {
|
||||
this.value = v;
|
||||
}
|
||||
}
|
||||
|
||||
private defaultKeyHandler = (e: KeyboardEvent) => {
|
||||
let stepSize: any[] = this.slider.steps();
|
||||
let index = parseInt((<HTMLElement>e.target).getAttribute('data-handle'));
|
||||
let sign = 1;
|
||||
let multiplier: number = 1;
|
||||
let step = 0;
|
||||
let delta = 0;
|
||||
|
||||
switch ( e.which ) {
|
||||
case 34: // PageDown
|
||||
multiplier = this.config.pageSteps;
|
||||
case 40: // ArrowDown
|
||||
case 37: // ArrowLeft
|
||||
sign = -1;
|
||||
step = stepSize[index][0];
|
||||
e.preventDefault();
|
||||
break;
|
||||
|
||||
case 33: // PageUp
|
||||
multiplier = this.config.pageSteps;
|
||||
case 38: // ArrowUp
|
||||
case 39: // ArrowRight
|
||||
step = stepSize[index][1];
|
||||
e.preventDefault();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
delta = sign * multiplier * step;
|
||||
let newValue: number | number[];
|
||||
|
||||
if(Array.isArray(this.value)) {
|
||||
newValue = [].concat(this.value);
|
||||
newValue[index] = newValue[index] + delta;
|
||||
} else {
|
||||
newValue = this.value + delta;
|
||||
}
|
||||
|
||||
this.slider.set(newValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {NouisliderComponent} from "./ng2-nouislider.component";
|
||||
|
||||
@NgModule({
|
||||
exports: [NouisliderComponent],
|
||||
declarations: [NouisliderComponent],
|
||||
})
|
||||
export class NouisliderModule { }
|
Loading…
Reference in New Issue