/**
* Corpus Terms tool, a grid that shows the terms in the corpus.
*
* @example
*
* let config = {
* columns: null,
* comparisonCorpus: null,
* dir: null,
* maxBins: null,
* query: null,
* sort: null,
* stopList: null,
* termColors: null
* };
*
* loadCorpus("austen").tool("corpusterms", config);
*
*
* @class CorpusTerms
* @tutorial corpusterms
* @memberof Tools
*/
Ext.define('Voyant.panel.CorpusTerms', {
extend: 'Ext.grid.Panel',
mixins: ['Voyant.panel.Panel'],
alias: 'widget.corpusterms',
statics: {
i18n: {
comparisonCorpus: 'Comparison Corpus'
},
api: {
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {stopList}
* @default
*/
stopList: 'auto',
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {query}
*/
query: undefined,
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {Number} maxBins The maximum number of bins to use for distributions in Trend.
*
* By default this is set to 100 (in other words, if there are more than 100 documents in the corpus, they will be forced into 100 bins).
* Higher values are possible but it can cause performance issues and necessitate more data transfer (values for each one of the bins for each one of the terms).
* @default
*/
maxBins: 100,
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {termColors}
* @default
*/
termColors: 'categories',
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {String} comparisonCorpus An existing corpus to be used for comparison purposes.
*
* None of the columns visible by default use comparisonCorpus so this is an advanced parameter used when the "Comparison" column is shown.
* The comparison column shows the relative frequency of the term in the corpus compared to the relative frequency of the same term in a comparison corpus.
*/
comparisonCorpus: undefined,
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {columns} columns 'term', 'rawFreq', 'relativeFreq', 'relativePeakedness', 'relativeSkewness', 'comparisonRelativeFreqDifference', 'distributions'
*/
columns: undefined,
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {sort}
*/
sort: undefined,
/**
* @memberof Tools.CorpusTerms
* @instance
* @property {dir}
*/
dir: undefined,
},
glyph: 'xf0ce@FontAwesome'
},
config: {
/**
* @private
*/
options: [{
xtype: 'stoplistoption'
},{
xtype: 'categoriesoption'
},{
xtype: 'termcolorsoption'
},{
xtype: 'corpusselector',
name: 'comparisonCorpus'
}]
},
/**
* @private
*/
constructor: function(config) {
this.mixins['Voyant.util.Api'].constructor.apply(this, arguments);
this.callParent(arguments);
this.getOptions().filter(function(option) { return option.xtype === 'corpusselector'})[0].fieldLabel = this.localize('comparisonCorpus');
this.mixins['Voyant.panel.Panel'].constructor.apply(this, arguments);
},
initComponent: function() {
var me = this;
var store = Ext.create("Voyant.data.store.CorpusTermsBuffered", {
parentPanel: this,
proxy: {
extraParams: {
withDistributions: 'relative',
forTool: 'corpusterms'
}
}
});
Ext.apply(me, {
title: this.localize('title'),
emptyText: this.localize("emptyText"),
store : store,
selModel: Ext.create('Ext.selection.CheckboxModel', {
pruneRemoved: false,
listeners: {
selectionchange: {
fn: function(sm, selections) {
if (selections && selections.length>0) {
this.getApplication().dispatchEvent('corpusTermsClicked', this, selections);
}
},
scope: this
}
},
mode: 'SIMPLE'
}),
dockedItems: [{
dock: 'bottom',
xtype: 'toolbar',
overflowHandler: 'scroller',
items: [{
xtype: 'querysearchfield'
}, {
xtype: 'totalpropertystatus'
}]
}],
plugins: [{
ptype: 'rowexpander',
rowBodyTpl: new Ext.XTemplate('')
}],
viewConfig: {
listeners: {
// TODO widget disappears when scrolled off screen
expandbody: function(rowNode, record, expandRow, eOpts) {
if (expandRow.textContent==='' || (eOpts && eOpts.force)) {
Ext.create('Voyant.widget.CorpusTermSummary', {
record: record,
header: false,
renderTo: expandRow.querySelector('div')
});
}
},
scope: this
}
},
columns: [{
xtype: 'rownumberer',
width: 'autoSize',
sortable: false
},{
text: this.localize("term"),
tooltip: this.localize("termTip"),
dataIndex: 'term',
flex: 1,
sortable: true,
xtype: 'coloredtermfield',
useCategoriesMenu: true
},{
text: this.localize("rawFreq"),
tooltip: this.localize("rawFreqTip"),
dataIndex: 'rawFreq',
width: 'autoSize',
sortable: true
},{
text: this.localize("relativeFreq"),
tooltip: this.localize("relativeFreqTip"),
dataIndex: 'relativeFreq',
renderer: function(val) {
return Ext.util.Format.number(val*1000000, "0,000")
},
width: 'autoSize',
hidden: true,
sortable: true
},{
text: this.localize("relativePeakedness"),
tooltip: this.localize("relativePeakednessTip"),
dataIndex: 'relativePeakedness',
renderer: Ext.util.Format.numberRenderer("0,000.0"),
width: 'autoSize',
hidden: true,
sortable: true
},{
text: this.localize("relativeSkewness"),
tooltip: this.localize("relativeSkewnessTip"),
dataIndex: 'relativeSkewness',
renderer: Ext.util.Format.numberRenderer("0,000.0"),
width: 'autoSize',
hidden: true,
sortable: true
},{
text: this.localize("corpusComparisonDifference"),
tooltip: this.localize("corpusComparisonDifferenceTip"),
dataIndex: 'comparisonRelativeFreqDifference',
renderer: Ext.util.Format.numberRenderer("0,000.00000"),
width: 'autoSize',
hidden: !this.getApiParam('comparisonCorpus'),
sortable: true,
listeners: {
show: function(ct, column, eopts) {
if (!me.getApiParam('comparisonCorpus')) {
me.showError(me.localize('noCorpusComparison'))
}
}
}
},{
xtype: 'widgetcolumn',
text: this.localize("trend"),
tooltip: this.localize("trendTip"),
flex: 1,
dataIndex: 'distributions',
widget: {
xtype: 'sparklineline',
tipTpl: new Ext.XTemplate('{[this.getDocumentTitle(values.x,values.y)]}', {
getDocumentTitle: function(docIndex, relativeFreq) {
return this.panel.store.getCorpus().getDocument(docIndex).getTitle()+"<br>"+this.panel.localize("relativeFreqLabel")+" "+Ext.util.Format.number(relativeFreq*1000000, "0,000")
},
panel: me
})
}
}]
});
me.on('loadedCorpus', function(src, corpus) {
if (corpus.getDocumentsCount()>100) {
this.getStore().getProxy().setExtraParam('bins', this.getApiParam('maxBins'));
}
if (this.isVisible()) {
if (corpus.getDocumentsCount() === 1) {
this.getColumns().filter(function(col) { return col.dataIndex === 'distributions'})[0].hide();
}
this.getStore().load();
}
}, me);
me.on("activate", function() { // load after tab activate (if we're in a tab panel)
if (me.getStore().getCorpus()) {
if (me.getStore().getCorpus().getDocumentsCount() === 1) {
this.getColumns().filter(function(col) { return col.dataIndex === 'distributions'})[0].hide();
}
me.getStore().load({params: this.getApiParams()});
}
}, me);
me.on("query", function(src, query) {
this.setApiParam('query', query);
this.getStore().removeAll();
this.getStore().load();
}, me);
me.callParent(arguments);
}
})