- 1 :
/**
- 2 :
* Corpus Terms tool, a grid that shows the terms in the corpus.
- 3 :
*
- 4 :
* @example
- 5 :
*
- 6 :
* let config = {
- 7 :
* columns: null,
- 8 :
* comparisonCorpus: null,
- 9 :
* dir: null,
- 10 :
* maxBins: null,
- 11 :
* query: null,
- 12 :
* sort: null,
- 13 :
* stopList: null,
- 14 :
* termColors: null
- 15 :
* };
- 16 :
*
- 17 :
* loadCorpus("austen").tool("corpusterms", config);
- 18 :
*
- 19 :
*
- 20 :
* @class CorpusTerms
- 21 :
* @tutorial corpusterms
- 22 :
* @memberof Tools
- 23 :
*/
- 24 :
Ext.define('Voyant.panel.CorpusTerms', {
- 25 :
extend: 'Ext.grid.Panel',
- 26 :
mixins: ['Voyant.panel.Panel'],
- 27 :
alias: 'widget.corpusterms',
- 28 :
statics: {
- 29 :
i18n: {
- 30 :
comparisonCorpus: 'Comparison Corpus'
- 31 :
},
- 32 :
api: {
- 33 :
- 34 :
/**
- 35 :
* @memberof Tools.CorpusTerms
- 36 :
* @instance
- 37 :
* @property {stopList}
- 38 :
* @default
- 39 :
*/
- 40 :
stopList: 'auto',
- 41 :
- 42 :
/**
- 43 :
* @memberof Tools.CorpusTerms
- 44 :
* @instance
- 45 :
* @property {query}
- 46 :
*/
- 47 :
query: undefined,
- 48 :
- 49 :
/**
- 50 :
* @memberof Tools.CorpusTerms
- 51 :
* @instance
- 52 :
* @property {Number} maxBins The maximum number of bins to use for distributions in Trend.
- 53 :
*
- 54 :
* 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).
- 55 :
* 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).
- 56 :
* @default
- 57 :
*/
- 58 :
maxBins: 100,
- 59 :
- 60 :
/**
- 61 :
* @memberof Tools.CorpusTerms
- 62 :
* @instance
- 63 :
* @property {termColors}
- 64 :
* @default
- 65 :
*/
- 66 :
termColors: 'categories',
- 67 :
- 68 :
/**
- 69 :
* @memberof Tools.CorpusTerms
- 70 :
* @instance
- 71 :
* @property {String} comparisonCorpus An existing corpus to be used for comparison purposes.
- 72 :
*
- 73 :
* None of the columns visible by default use comparisonCorpus so this is an advanced parameter used when the "Comparison" column is shown.
- 74 :
* 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.
- 75 :
*/
- 76 :
comparisonCorpus: undefined,
- 77 :
- 78 :
/**
- 79 :
* @memberof Tools.CorpusTerms
- 80 :
* @instance
- 81 :
* @property {columns} columns 'term', 'rawFreq', 'relativeFreq', 'relativePeakedness', 'relativeSkewness', 'comparisonRelativeFreqDifference', 'distributions'
- 82 :
*/
- 83 :
columns: undefined,
- 84 :
- 85 :
/**
- 86 :
* @memberof Tools.CorpusTerms
- 87 :
* @instance
- 88 :
* @property {sort}
- 89 :
*/
- 90 :
sort: undefined,
- 91 :
- 92 :
/**
- 93 :
* @memberof Tools.CorpusTerms
- 94 :
* @instance
- 95 :
* @property {dir}
- 96 :
*/
- 97 :
dir: undefined,
- 98 :
},
- 99 :
glyph: 'xf0ce@FontAwesome'
- 100 :
},
- 101 :
config: {
- 102 :
/**
- 103 :
* @private
- 104 :
*/
- 105 :
options: [{
- 106 :
xtype: 'stoplistoption'
- 107 :
},{
- 108 :
xtype: 'categoriesoption'
- 109 :
},{
- 110 :
xtype: 'termcolorsoption'
- 111 :
},{
- 112 :
xtype: 'corpusselector',
- 113 :
name: 'comparisonCorpus'
- 114 :
}]
- 115 :
},
- 116 :
- 117 :
/**
- 118 :
* @private
- 119 :
*/
- 120 :
constructor: function(config) {
- 121 :
this.mixins['Voyant.util.Api'].constructor.apply(this, arguments);
- 122 :
this.callParent(arguments);
- 123 :
this.getOptions().filter(function(option) { return option.xtype === 'corpusselector'})[0].fieldLabel = this.localize('comparisonCorpus');
- 124 :
this.mixins['Voyant.panel.Panel'].constructor.apply(this, arguments);
- 125 :
},
- 126 :
- 127 :
- 128 :
initComponent: function() {
- 129 :
var me = this;
- 130 :
- 131 :
var store = Ext.create("Voyant.data.store.CorpusTermsBuffered", {
- 132 :
parentPanel: this,
- 133 :
proxy: {
- 134 :
extraParams: {
- 135 :
withDistributions: 'relative',
- 136 :
forTool: 'corpusterms'
- 137 :
}
- 138 :
}
- 139 :
});
- 140 :
- 141 :
Ext.apply(me, {
- 142 :
title: this.localize('title'),
- 143 :
emptyText: this.localize("emptyText"),
- 144 :
store : store,
- 145 :
selModel: Ext.create('Ext.selection.CheckboxModel', {
- 146 :
pruneRemoved: false,
- 147 :
listeners: {
- 148 :
selectionchange: {
- 149 :
fn: function(sm, selections) {
- 150 :
if (selections && selections.length>0) {
- 151 :
this.getApplication().dispatchEvent('corpusTermsClicked', this, selections);
- 152 :
}
- 153 :
},
- 154 :
scope: this
- 155 :
}
- 156 :
},
- 157 :
mode: 'SIMPLE'
- 158 :
}),
- 159 :
dockedItems: [{
- 160 :
dock: 'bottom',
- 161 :
xtype: 'toolbar',
- 162 :
overflowHandler: 'scroller',
- 163 :
items: [{
- 164 :
xtype: 'querysearchfield'
- 165 :
}, {
- 166 :
xtype: 'totalpropertystatus'
- 167 :
}]
- 168 :
}],
- 169 :
- 170 :
plugins: [{
- 171 :
ptype: 'rowexpander',
- 172 :
rowBodyTpl: new Ext.XTemplate('')
- 173 :
}],
- 174 :
viewConfig: {
- 175 :
listeners: {
- 176 :
// TODO widget disappears when scrolled off screen
- 177 :
expandbody: function(rowNode, record, expandRow, eOpts) {
- 178 :
if (expandRow.textContent==='' || (eOpts && eOpts.force)) {
- 179 :
Ext.create('Voyant.widget.CorpusTermSummary', {
- 180 :
record: record,
- 181 :
header: false,
- 182 :
renderTo: expandRow.querySelector('div')
- 183 :
});
- 184 :
}
- 185 :
},
- 186 :
scope: this
- 187 :
}
- 188 :
},
- 189 :
columns: [{
- 190 :
xtype: 'rownumberer',
- 191 :
width: 'autoSize',
- 192 :
sortable: false
- 193 :
},{
- 194 :
text: this.localize("term"),
- 195 :
tooltip: this.localize("termTip"),
- 196 :
dataIndex: 'term',
- 197 :
flex: 1,
- 198 :
sortable: true,
- 199 :
xtype: 'coloredtermfield',
- 200 :
useCategoriesMenu: true
- 201 :
},{
- 202 :
text: this.localize("rawFreq"),
- 203 :
tooltip: this.localize("rawFreqTip"),
- 204 :
dataIndex: 'rawFreq',
- 205 :
width: 'autoSize',
- 206 :
sortable: true
- 207 :
},{
- 208 :
text: this.localize("relativeFreq"),
- 209 :
tooltip: this.localize("relativeFreqTip"),
- 210 :
dataIndex: 'relativeFreq',
- 211 :
renderer: function(val) {
- 212 :
return Ext.util.Format.number(val*1000000, "0,000")
- 213 :
},
- 214 :
width: 'autoSize',
- 215 :
hidden: true,
- 216 :
sortable: true
- 217 :
},{
- 218 :
text: this.localize("relativePeakedness"),
- 219 :
tooltip: this.localize("relativePeakednessTip"),
- 220 :
dataIndex: 'relativePeakedness',
- 221 :
renderer: Ext.util.Format.numberRenderer("0,000.0"),
- 222 :
width: 'autoSize',
- 223 :
hidden: true,
- 224 :
sortable: true
- 225 :
},{
- 226 :
text: this.localize("relativeSkewness"),
- 227 :
tooltip: this.localize("relativeSkewnessTip"),
- 228 :
dataIndex: 'relativeSkewness',
- 229 :
renderer: Ext.util.Format.numberRenderer("0,000.0"),
- 230 :
width: 'autoSize',
- 231 :
hidden: true,
- 232 :
sortable: true
- 233 :
},{
- 234 :
text: this.localize("corpusComparisonDifference"),
- 235 :
tooltip: this.localize("corpusComparisonDifferenceTip"),
- 236 :
dataIndex: 'comparisonRelativeFreqDifference',
- 237 :
renderer: Ext.util.Format.numberRenderer("0,000.00000"),
- 238 :
width: 'autoSize',
- 239 :
hidden: !this.getApiParam('comparisonCorpus'),
- 240 :
sortable: true,
- 241 :
listeners: {
- 242 :
show: function(ct, column, eopts) {
- 243 :
if (!me.getApiParam('comparisonCorpus')) {
- 244 :
me.showError(me.localize('noCorpusComparison'))
- 245 :
}
- 246 :
}
- 247 :
}
- 248 :
},{
- 249 :
xtype: 'widgetcolumn',
- 250 :
text: this.localize("trend"),
- 251 :
tooltip: this.localize("trendTip"),
- 252 :
flex: 1,
- 253 :
dataIndex: 'distributions',
- 254 :
widget: {
- 255 :
xtype: 'sparklineline',
- 256 :
tipTpl: new Ext.XTemplate('{[this.getDocumentTitle(values.x,values.y)]}', {
- 257 :
getDocumentTitle: function(docIndex, relativeFreq) {
- 258 :
return this.panel.store.getCorpus().getDocument(docIndex).getTitle()+"<br>"+this.panel.localize("relativeFreqLabel")+" "+Ext.util.Format.number(relativeFreq*1000000, "0,000")
- 259 :
},
- 260 :
panel: me
- 261 :
})
- 262 :
}
- 263 :
}]
- 264 :
});
- 265 :
- 266 :
me.on('loadedCorpus', function(src, corpus) {
- 267 :
if (corpus.getDocumentsCount()>100) {
- 268 :
this.getStore().getProxy().setExtraParam('bins', this.getApiParam('maxBins'));
- 269 :
}
- 270 :
if (this.isVisible()) {
- 271 :
if (corpus.getDocumentsCount() === 1) {
- 272 :
this.getColumns().filter(function(col) { return col.dataIndex === 'distributions'})[0].hide();
- 273 :
}
- 274 :
this.getStore().load();
- 275 :
}
- 276 :
}, me);
- 277 :
- 278 :
me.on("activate", function() { // load after tab activate (if we're in a tab panel)
- 279 :
if (me.getStore().getCorpus()) {
- 280 :
if (me.getStore().getCorpus().getDocumentsCount() === 1) {
- 281 :
this.getColumns().filter(function(col) { return col.dataIndex === 'distributions'})[0].hide();
- 282 :
}
- 283 :
me.getStore().load({params: this.getApiParams()});
- 284 :
}
- 285 :
}, me);
- 286 :
- 287 :
- 288 :
me.on("query", function(src, query) {
- 289 :
this.setApiParam('query', query);
- 290 :
this.getStore().removeAll();
- 291 :
this.getStore().load();
- 292 :
}, me);
- 293 :
- 294 :
- 295 :
me.callParent(arguments);
- 296 :
- 297 :
}
- 298 :
})