2010-10-20 20:11:15 +02:00
/ *
Copyright 2010 , Google Inc .
All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are
met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above
copyright notice , this list of conditions and the following disclaimer
in the documentation and / or other materials provided with the
distribution .
* Neither the name of Google Inc . nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
2010-03-13 10:32:06 +01:00
function ClusteringDialog ( columnName , expression ) {
2010-03-02 20:58:47 +01:00
this . _columnName = columnName ;
2010-03-02 21:33:11 +01:00
this . _expression = expression ;
2010-03-06 11:17:58 +01:00
this . _method = "binning" ;
this . _function = "fingerprint" ;
this . _params = { } ;
2010-03-02 20:58:47 +01:00
2010-03-09 00:05:44 +01:00
this . _facets = [ ] ;
2010-03-02 20:58:47 +01:00
this . _createDialog ( ) ;
this . _cluster ( ) ;
}
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _createDialog = function ( ) {
2010-03-02 20:58:47 +01:00
var self = this ;
2010-06-21 23:59:53 +02:00
var dialog = $ ( DOM . loadHTML ( "core" , "scripts/dialogs/clustering-dialog.html" ) ) ;
this . _elmts = DOM . bind ( dialog ) ;
this . _elmts . dialogHeader . text ( 'Cluster & Edit column "' + this . _columnName + '"' ) ;
2010-03-06 11:17:58 +01:00
this . _elmts . methodSelector . change ( function ( ) {
var selection = $ ( this ) . find ( "option:selected" ) . text ( ) ;
if ( selection == 'key collision' ) {
2010-06-30 19:29:03 +02:00
dialog . find ( ".binning-controls" ) . show ( ) ;
dialog . find ( ".knn-controls" ) . hide ( ) ;
2010-03-06 11:17:58 +01:00
self . _method = "binning" ;
self . _elmts . keyingFunctionSelector . change ( ) ;
2010-04-20 09:26:07 +02:00
} else if ( selection === 'nearest neighbor' ) {
2010-06-30 19:29:03 +02:00
dialog . find ( ".binning-controls" ) . hide ( ) ;
dialog . find ( ".knn-controls" ) . show ( ) ;
2010-03-06 11:17:58 +01:00
self . _method = "knn" ;
self . _elmts . distanceFunctionSelector . change ( ) ;
}
} ) ;
var changer = function ( ) {
self . _function = $ ( this ) . find ( "option:selected" ) . text ( ) ;
$ ( ".function-params" ) . hide ( ) ;
$ ( "#" + self . _function + "-params" ) . show ( ) ;
2010-03-10 02:18:41 +01:00
params _changer ( ) ;
2010-03-06 11:17:58 +01:00
} ;
this . _elmts . keyingFunctionSelector . change ( changer ) ;
this . _elmts . distanceFunctionSelector . change ( changer ) ;
2010-03-10 02:18:41 +01:00
var params _changer = function ( ) {
self . _params = { } ;
$ ( ".dialog-body input.param:visible" ) . each ( function ( ) {
var e = $ ( this ) ;
var name = e . attr ( 'name' ) ;
var datatype = e . attr ( 'datatype' ) || 'string' ;
var value = e . val ( ) ;
if ( datatype == 'int' ) {
2010-04-08 20:21:28 +02:00
value = parseInt ( value , 10 ) ;
2010-03-10 02:18:41 +01:00
} else if ( datatype == 'float' ) {
value = parseFloat ( value ) ;
}
self . _params [ name ] = value ;
} ) ;
self . _cluster ( ) ;
} ;
this . _elmts . ngramSize . change ( params _changer ) ;
this . _elmts . radius . change ( params _changer ) ;
this . _elmts . ngramBlock . change ( params _changer ) ;
2010-03-07 09:27:13 +01:00
2010-06-21 23:59:53 +02:00
this . _elmts . selectAllButton . click ( function ( ) { self . _selectAll ( ) ; } ) ;
this . _elmts . deselectAllButton . click ( function ( ) { self . _deselectAll ( ) ; } ) ;
this . _elmts . applyReClusterButton . click ( function ( ) { self . _onApplyReCluster ( ) ; } ) ;
this . _elmts . applyCloseButton . click ( function ( ) { self . _onApplyClose ( ) ; } ) ;
this . _elmts . closeButton . click ( function ( ) { self . _dismiss ( ) ; } ) ;
2010-03-02 20:58:47 +01:00
2010-06-21 23:59:53 +02:00
this . _level = DialogSystem . showDialog ( dialog ) ;
2010-03-02 20:58:47 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _renderTable = function ( clusters ) {
2010-03-02 20:58:47 +01:00
var self = this ;
2010-03-07 00:01:46 +01:00
var container = this . _elmts . tableContainer ;
2010-03-02 20:58:47 +01:00
2010-03-13 10:32:06 +01:00
if ( clusters . length > 0 ) {
var table = $ ( '<table></table>' ) . addClass ( "clustering-dialog-entry-table" ) [ 0 ] ;
2010-03-07 00:01:46 +01:00
2010-03-13 10:32:06 +01:00
var trHead = table . insertRow ( table . rows . length ) ;
trHead . className = "header" ;
$ ( trHead . insertCell ( 0 ) ) . text ( "Cluster Size" ) ;
$ ( trHead . insertCell ( 1 ) ) . text ( "Row Count" ) ;
$ ( trHead . insertCell ( 2 ) ) . text ( "Values in Cluster" ) ;
$ ( trHead . insertCell ( 3 ) ) . text ( "Merge?" ) ;
$ ( trHead . insertCell ( 4 ) ) . text ( "New Cell Value" ) ;
var renderCluster = function ( cluster ) {
var tr = table . insertRow ( table . rows . length ) ;
2010-04-08 20:21:28 +02:00
tr . className = table . rows . length % 2 === 0 ? "odd" : "even" ;
2010-03-13 10:32:06 +01:00
$ ( tr . insertCell ( 0 ) ) . text ( cluster . choices . length ) ;
$ ( tr . insertCell ( 1 ) ) . text ( cluster . rowCount ) ;
2010-03-16 07:53:08 +01:00
var facet = {
"c" : {
"type" : "list" ,
"name" : self . _columnName ,
"columnName" : self . _columnName ,
"expression" : "value"
} ,
"o" : {
"sort" : "name"
} ,
"s" : [
]
} ;
2010-03-13 10:32:06 +01:00
var ul = $ ( '<ul></ul>' ) ;
var choices = cluster . choices ;
var rowCount = 0 ;
2010-04-08 20:21:28 +02:00
var onClick = function ( ) {
var parent = $ ( this ) . closest ( "tr" ) ;
2010-09-30 19:18:19 +02:00
var value = $ ( this ) . text ( ) ;
cluster . value = value ;
parent . find ( "input[type='text']" ) . val ( value ) ;
2010-04-08 20:21:28 +02:00
parent . find ( "input:not(:checked)" ) . attr ( 'checked' , true ) . change ( ) ;
return false ;
} ;
2010-03-13 10:32:06 +01:00
for ( var c = 0 ; c < choices . length ; c ++ ) {
var choice = choices [ c ] ;
var li = $ ( '<li></li>' ) ;
2010-04-08 20:21:28 +02:00
$ ( '<a href="javascript:{}" title="Use this value"></a>' ) . text ( choice . v ) . click ( onClick ) . appendTo ( li ) ;
2010-03-13 10:32:06 +01:00
$ ( '<span></span>' ) . text ( "(" + choice . c + " rows)" ) . addClass ( "clustering-dialog-entry-count" ) . appendTo ( li ) ;
rowCount += choice . c ;
2010-03-16 07:53:08 +01:00
facet . s [ c ] = {
"v" : {
"v" : choice . v ,
"l" : choice . v
}
} ;
2010-03-13 10:32:06 +01:00
li . appendTo ( ul ) ;
}
2010-03-16 07:53:08 +01:00
var params = [
"project=" + escape ( theProject . id ) ,
"ui=" + escape ( JSON . stringify ( {
"facets" : [ facet ]
} ) )
] ;
2010-07-01 09:47:45 +02:00
var url = "project?" + params . join ( "&" ) ;
2010-03-16 07:53:08 +01:00
var div = $ ( '<div></div>' ) . addClass ( "clustering-dialog-value-focus" ) ;
var browseLink = $ ( '<a target="_new" title="Browse only these values">Browse this cluster</a>' )
. addClass ( "clustering-dialog-browse-focus" )
. attr ( "href" , url )
. css ( "visibility" , "hidden" )
. appendTo ( div ) ;
$ ( tr . insertCell ( 2 ) )
. mouseenter ( function ( ) { browseLink . css ( "visibility" , "visible" ) ; } )
. mouseleave ( function ( ) { browseLink . css ( "visibility" , "hidden" ) ; } )
. append ( ul )
. append ( div ) ;
2010-03-13 10:32:06 +01:00
var editCheck = $ ( '<input type="checkbox" />' )
. change ( function ( ) {
cluster . edit = ! cluster . edit ;
} ) . appendTo ( tr . insertCell ( 3 ) ) ;
if ( cluster . edit ) {
editCheck . attr ( "checked" , "true" ) ;
}
var input = $ ( '<input size="25" />' )
. attr ( "value" , cluster . value )
. keyup ( function ( ) {
cluster . value = this . value ;
} ) . appendTo ( tr . insertCell ( 4 ) ) ;
} ;
2010-03-09 00:05:44 +01:00
2010-03-13 10:32:06 +01:00
for ( var i = 0 ; i < clusters . length ; i ++ ) {
renderCluster ( clusters [ i ] ) ;
2010-03-02 20:58:47 +01:00
}
2010-03-13 10:32:06 +01:00
container . empty ( ) . append ( table ) ;
2010-03-02 20:58:47 +01:00
2010-03-13 10:32:06 +01:00
this . _elmts . resultSummary . html (
( clusters . length === this . _clusters . length ) ?
( "<b>" + this . _clusters . length + "</b> cluster" + ( ( this . _clusters . length != 1 ) ? "s" : "" ) + " found" ) :
( "<b>" + clusters . length + "</b> cluster" + ( ( clusters . length != 1 ) ? "s" : "" ) + " filtered from <b>" + this . _clusters . length + "</b> total" )
) ;
} else {
container . html (
'<div style="margin: 2em;"><div style="font-size: 130%; color: #333;">No clusters were found with the selected method</div><div style="padding-top: 1em; font-size: 110%; color: #888;">Try selecting another method above or changing its parameters</div></div>'
) ;
2010-03-02 20:58:47 +01:00
}
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _cluster = function ( ) {
2010-03-06 11:17:58 +01:00
var self = this ;
2010-03-02 20:58:47 +01:00
2010-03-06 11:17:58 +01:00
var container = this . _elmts . tableContainer . html (
2010-03-09 21:58:51 +01:00
'<div style="margin: 1em; font-size: 130%; color: #888;">Clustering... <img src="/images/small-spinner.gif"></div>'
2010-03-06 11:17:58 +01:00
) ;
2010-03-07 00:01:46 +01:00
this . _elmts . resultSummary . empty ( ) ;
2010-03-02 20:58:47 +01:00
2010-03-06 11:17:58 +01:00
$ . post (
2010-08-22 08:16:13 +02:00
"/command/core/compute-clusters?" + $ . param ( { project : theProject . id } ) ,
2010-03-06 11:17:58 +01:00
{
engine : JSON . stringify ( ui . browsingEngine . getJSON ( ) ) ,
clusterer : JSON . stringify ( {
'type' : this . _method ,
'function' : this . _function ,
'column' : this . _columnName ,
'params' : this . _params
} )
} ,
function ( data ) {
2010-03-09 00:05:44 +01:00
self . _updateData ( data ) ;
2010-03-06 11:17:58 +01:00
} ,
"json"
) ;
2010-04-08 20:21:28 +02:00
} ;
2010-03-02 21:33:11 +01:00
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _updateData = function ( data ) {
2010-03-09 00:05:44 +01:00
var clusters = [ ] ;
$ . each ( data , function ( ) {
var cluster = {
2010-03-09 21:58:51 +01:00
edit : false ,
2010-03-09 00:05:44 +01:00
choices : this ,
value : this [ 0 ] . v ,
size : this . length
} ;
var sum = 0 ;
var sumSquared = 0 ;
var rowCount = 0 ;
$ . each ( cluster . choices , function ( ) {
rowCount += this . c ;
var l = this . v . length ;
sum += l ;
sumSquared += l * l ;
} ) ;
cluster . rowCount = rowCount ;
cluster . avg = sum / cluster . choices . length ;
cluster . variance = Math . sqrt ( sumSquared / cluster . choices . length - cluster . avg * cluster . avg ) ;
clusters . push ( cluster ) ;
} ) ;
this . _clusters = clusters ;
this . _resetFacets ( ) ;
this . _updateAll ( ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _selectAll = function ( ) {
$ ( ".clustering-dialog-entry-table input:not(:checked)" ) . attr ( 'checked' , true ) . change ( ) ;
2010-03-09 21:58:51 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _deselectAll = function ( ) {
$ ( ".clustering-dialog-entry-table input:checked" ) . attr ( 'checked' , false ) . change ( ) ;
2010-03-09 21:58:51 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _onApplyClose = function ( ) {
2010-03-07 00:34:27 +01:00
var self = this ;
this . _apply ( function ( ) {
self . _dismiss ( ) ;
} ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _onApplyReCluster = function ( ) {
2010-03-07 00:34:27 +01:00
var self = this ;
this . _apply ( function ( ) {
self . _cluster ( ) ;
} ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _apply = function ( onDone ) {
2010-03-09 00:05:44 +01:00
var clusters = this . _getRestrictedClusters ( ) ;
2010-03-02 21:33:11 +01:00
var edits = [ ] ;
2010-03-09 00:05:44 +01:00
for ( var i = 0 ; i < clusters . length ; i ++ ) {
var cluster = clusters [ i ] ;
2010-03-02 21:33:11 +01:00
if ( cluster . edit ) {
var values = [ ] ;
for ( var j = 0 ; j < cluster . choices . length ; j ++ ) {
2010-03-06 11:17:58 +01:00
values . push ( cluster . choices [ j ] . v ) ;
2010-03-02 21:33:11 +01:00
}
edits . push ( {
from : values ,
to : cluster . value
} ) ;
}
}
if ( edits . length > 0 ) {
2010-09-23 00:55:28 +02:00
Refine . postCoreProcess (
2010-03-07 01:25:00 +01:00
"mass-edit" ,
2010-03-02 21:33:11 +01:00
{ } ,
{
columnName : this . _columnName ,
expression : this . _expression ,
edits : JSON . stringify ( edits )
} ,
2010-03-07 00:34:27 +01:00
{ cellsChanged : true } ,
{
onError : function ( o ) {
alert ( "Error: " + o . message ) ;
} ,
onDone : onDone
}
2010-03-02 21:33:11 +01:00
) ;
} else {
alert ( "You must check some Edit? checkboxes for your edits to be applied." ) ;
}
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _dismiss = function ( ) {
2010-03-02 21:33:11 +01:00
DialogSystem . dismissUntil ( this . _level - 1 ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _getBaseClusters = function ( ) {
2010-03-09 00:05:44 +01:00
return [ ] . concat ( this . _clusters ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _getRestrictedClusters = function ( except ) {
2010-03-09 00:05:44 +01:00
var clusters = this . _getBaseClusters ( ) ;
for ( var i = 0 ; i < this . _facets . length ; i ++ ) {
var facet = this . _facets [ i ] . facet ;
if ( except !== facet ) {
clusters = facet . restrict ( clusters ) ;
}
}
return clusters ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _updateAll = function ( ) {
2010-03-09 00:05:44 +01:00
for ( var i = 0 ; i < this . _facets . length ; i ++ ) {
var facet = this . _facets [ i ] . facet ;
var clusters = this . _getRestrictedClusters ( facet ) ;
facet . update ( clusters ) ;
}
this . _renderTable ( this . _getRestrictedClusters ( ) ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _resetFacets = function ( ) {
2010-03-09 00:05:44 +01:00
for ( var i = 0 ; i < this . _facets . length ; i ++ ) {
var r = this . _facets [ i ] ;
r . facet . dispose ( ) ;
r . elmt . remove ( ) ;
}
this . _facets = [ ] ;
2010-10-25 03:07:25 +02:00
this . _createFacet ( "# Choices in Cluster" , "size" ) ;
this . _createFacet ( "# Rows in Cluster" , "rowCount" ) ;
this . _createFacet ( "Average Length of Choices" , "avg" ) ;
this . _createFacet ( "Length Variance of Choices" , "variance" ) ;
2010-03-09 00:05:44 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . prototype . _createFacet = function ( title , property ) {
2010-03-09 00:05:44 +01:00
var elmt = $ ( '<div>' ) . appendTo ( this . _elmts . facetContainer ) ;
this . _facets . push ( {
elmt : elmt ,
2010-03-13 10:32:06 +01:00
facet : new ClusteringDialog . Facet ( this , title , property , elmt , this . _getBaseClusters ( ) )
2010-03-09 00:05:44 +01:00
} ) ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . Facet = function ( dialog , title , property , elmt , clusters ) {
2010-03-09 00:05:44 +01:00
this . _dialog = dialog ;
this . _property = property ;
var self = this ;
var max = Number . NEGATIVE _INFINITY ;
var min = Number . POSITIVE _INFINITY ;
for ( var i = 0 ; i < clusters . length ; i ++ ) {
var cluster = clusters [ i ] ;
var val = cluster [ property ] ;
max = Math . max ( max , val ) ;
min = Math . min ( min , val ) ;
}
this . _min = min ;
this . _max = max ;
if ( min >= max ) {
this . _step = 0 ;
2010-03-09 01:41:33 +01:00
this . _baseBins = [ ] ;
2010-03-09 00:05:44 +01:00
} else {
var diff = max - min ;
this . _step = 1 ;
if ( diff > 10 ) {
while ( this . _step * 100 < diff ) {
this . _step *= 10 ;
}
} else {
while ( this . _step * 100 > diff ) {
this . _step /= 10 ;
}
}
this . _min = ( Math . floor ( this . _min / this . _step ) * this . _step ) ;
this . _max = ( Math . ceil ( this . _max / this . _step ) * this . _step ) ;
this . _binCount = 1 + Math . ceil ( ( this . _max - this . _min ) / this . _step ) ;
if ( this . _binCount > 100 ) {
this . _step *= 2 ;
this . _binCount = Math . round ( ( 1 + this . _binCount ) / 2 ) ;
2010-03-18 23:58:06 +01:00
} else if ( this . _binCount < 3 ) {
this . _step /= 2 ;
this . _binCount *= 2 ;
this . _max = ( Math . ceil ( this . _max / this . _step ) * this . _step ) ;
2010-03-09 00:05:44 +01:00
}
this . _baseBins = this . _computeDistribution ( clusters ) ;
this . _from = this . _min ;
this . _to = this . _max ;
2010-03-13 10:32:06 +01:00
elmt . addClass ( "clustering-dialog-facet" ) ;
2010-03-09 00:05:44 +01:00
var html = $ (
2010-03-13 10:32:06 +01:00
'<div class="clustering-dialog-facet-header">' + title + '</div>' +
2010-04-20 01:27:57 +02:00
'<div class="clustering-dialog-facet-slider" bind="sliderWidgetDiv">' +
'<div class="clustering-dialog-facet-histogram" bind="histogramContainer"></div>' +
'</div>' +
2010-03-13 10:32:06 +01:00
'<div class="clustering-dialog-facet-selection" bind="selectionContainer"></div>'
2010-03-09 00:05:44 +01:00
) . appendTo ( elmt ) ;
this . _elmts = DOM . bind ( html ) ;
2010-03-18 21:45:52 +01:00
2010-03-18 23:58:06 +01:00
this . _histogram = new HistogramWidget ( this . _elmts . histogramContainer , { binColors : [ "#ccccff" , "#6666ff" ] } ) ;
2010-04-20 01:27:57 +02:00
this . _sliderWidget = new SliderWidget ( this . _elmts . sliderWidgetDiv ) ;
this . _elmts . sliderWidgetDiv . bind ( "slide" , function ( evt , data ) {
self . _from = data . from ;
self . _to = data . to ;
self . _setRangeIndicators ( ) ;
} ) . bind ( "stop" , function ( evt , data ) {
self . _from = data . from ;
self . _to = data . to ;
self . _setRangeIndicators ( ) ;
self . _dialog . _updateAll ( ) ;
2010-03-09 00:05:44 +01:00
} ) ;
2010-04-20 01:27:57 +02:00
2010-03-09 00:05:44 +01:00
this . _setRangeIndicators ( ) ;
}
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . Facet . prototype . dispose = function ( ) {
2010-03-09 00:05:44 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . Facet . prototype . restrict = function ( clusters ) {
2010-04-08 20:21:28 +02:00
if ( ! this . _baseBins . length || ( this . _from == this . _min && this . _to == this . _max ) ) {
2010-03-09 00:05:44 +01:00
return clusters ;
}
var clusters2 = [ ] ;
for ( var i = 0 ; i < clusters . length ; i ++ ) {
var cluster = clusters [ i ] ;
var val = cluster [ this . _property ] ;
if ( val >= this . _from && val <= this . _to ) {
clusters2 . push ( cluster ) ;
}
}
return clusters2 ;
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . Facet . prototype . update = function ( clusters ) {
2010-04-08 20:21:28 +02:00
if ( ! this . _baseBins . length ) {
2010-03-09 00:05:44 +01:00
return ;
}
var bins = this . _computeDistribution ( clusters ) ;
2010-03-18 21:45:52 +01:00
2010-04-20 01:27:57 +02:00
this . _sliderWidget . update (
2010-03-18 21:45:52 +01:00
this . _min ,
this . _max ,
this . _step ,
2010-03-18 23:58:06 +01:00
this . _from ,
this . _to
2010-03-18 21:45:52 +01:00
) ;
2010-04-20 01:27:57 +02:00
this . _histogram . update (
this . _min ,
this . _max ,
this . _step ,
[ this . _baseBins , bins ]
) ;
2010-03-09 00:05:44 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . Facet . prototype . _setRangeIndicators = function ( ) {
2010-04-20 01:27:57 +02:00
this . _elmts . selectionContainer . html ( this . _from + " — " + this . _to ) ;
2010-03-09 00:05:44 +01:00
} ;
2010-03-13 10:32:06 +01:00
ClusteringDialog . Facet . prototype . _computeDistribution = function ( clusters ) {
2010-03-09 00:05:44 +01:00
var bins = [ ] ;
for ( var b = 0 ; b < this . _binCount ; b ++ ) {
bins . push ( 0 ) ;
}
for ( var i = 0 ; i < clusters . length ; i ++ ) {
var cluster = clusters [ i ] ;
var val = cluster [ this . _property ] ;
var bin = Math . round ( ( val - this . _min ) / this . _step ) ;
bins [ bin ] ++ ;
}
return bins ;
} ;