📄 attributevisualizationpanel.java
字号:
" sumResult:"+
(m_data.instance(k).value(m_attribIndex)-m_as.numericStats.min)+
" divideResult:"+
(float)((m_data.instance(k).value(m_attribIndex) -
m_as.numericStats.min)/barRange)+
" finalResult:"+
Math.ceil( (float)((m_data.instance(k).value(m_attribIndex) -
m_as.numericStats.min) / barRange)) );
}
}
m_histBarCounts = histCounts;
m_barRange = barRange;
}
m_threadRun=false;
//Image tmpImg = new BufferedImage(getWidth(), getHeight(),
// BufferedImage.TYPE_INT_RGB);
//drawGraph( tmpImg.getGraphics() );
//img = tmpImg;
AttributeVisualizationPanel.this.repaint();
}
}
/****Code for M.P.Wand's method of histogram bin width selection.
* There is some problem with it. It always comes up -ve value
* which is raised to the power 1/3 and gives an NAN.
* private static final int M=400;
* private double psi(int r, double g) {
* double val;
*
* double sum=0.0;
* for(int i=0; i<M; i++) {
* double valCjKj=0.0;
* for(int j=0; j<M; j++) {
* valCjKj += c(j) * k(r, j-i, g);
* }
* sum += valCjKj*c(i);
* }
*
* val = Math.pow(m_data.numInstances(), -2) * sum;
* //System.out.println("psi returns: "+val);
* return val;
* }
* private double g21() {
* double val;
*
* val = Math.pow(2 / ( Math.sqrt(2D*Math.PI)*psi(4, g22()) *
* m_data.numInstances() ), 1/5D)
* * Math.sqrt(2) * m_as.numericStats.stdDev;
* //System.out.println("g21 returns: "+val);
* return val;
* }
* private double g22() {
* double val;
*
* val = Math.pow( 2D/(5*m_data.numInstances()), 1/7D) *
* Math.sqrt(2) * m_as.numericStats.stdDev;
* //System.out.println("g22 returns: "+val);
* return val;
* }
* private double c(int j) {
* double val=0.0;
* double sigma = (m_as.numericStats.max - m_as.numericStats.min)/(M-1);
*
* //System.out.println("In c before doing the sum we have");
* //System.out.println("max: " +m_as.numericStats.max+" min: "+
* // m_as.numericStats.min+" sigma: "+sigma);
*
* for(int i=0; i<m_data.numInstances(); i++) {
* if(!m_data.instance(i).isMissing(m_attribIndex))
* val += Math.max( 0,
* ( 1 - Math.abs( Math.pow(sigma, -1)*(m_data.instance(i).value(m_attribIndex) - j) ) )
* );
* }
* //System.out.println("c returns: "+val);
* return val;
* }
* private double k(int r, int j, double g) {
* double val;
* double sigma = (m_as.numericStats.max - m_as.numericStats.min)/(M-1);
* //System.out.println("Before calling L we have");
* //System.out.println("Max: "+m_as.numericStats.max+" Min: "+m_as.numericStats.min+"\n"+
* // "r: "+r+" j: "+j+" g: "+g);
* val = Math.pow( g, -r-1) * L(sigma*j/g);
* //System.out.println("k returns: "+val);
* return val;
* }
* private double L(double x) {
* double val;
*
* val = Math.pow( 2*Math.PI, -1/2D ) * Math.exp( -(x*x)/2D );
* //System.out.println("L returns: "+val);
* return val;
* }
*******End of Wand's method
*/
}
/**
* Returns "<nominal value> [<nominal value count>]"
* if displaying a bar plot and mouse is on some bar.
* If displaying histogram then it
* <li>returns "count <br> [<bars Range>]" if mouse is
* on the first bar. </li>
* <li>returns "count <br> (<bar's Range>]" if mouse is
* on some bar other than the first one. </li>
* Otherwise it returns ""
*
* @param ev The mouse event
*/
public String getToolTipText(MouseEvent ev) {
if(m_as!=null && m_as.nominalCounts!=null) { //if current attrib is nominal
float intervalWidth = this.getWidth() / (float)m_as.nominalCounts.length;
float heightRatio;
int barWidth, x=0, y=0;
//if intervalWidth is at least six then bar width is 80% of intervalwidth
if(intervalWidth>5) //the rest is padding
barWidth = (int)Math.floor(intervalWidth*0.8F);
else
barWidth = 1; //Otherwise barwidth is 1 & padding would be at least 1.
//initializing x to maximum of 1 or 10% of interval width (i.e. half of
//the padding which is 20% of interval width, as there is 10% on each
//side of the bar) so that it points to the start of the 1st bar
x = x + (int)( (Math.floor(intervalWidth*0.1F))<1 ?
1:(Math.floor(intervalWidth*0.1F)) );
//Adding to x the appropriate value so that it points to the 1st bar of
//our "centered" barplot. If subtracting barplots width from panel width
//gives <=2 then the barplot is not centered.
if(this.getWidth() - (m_as.nominalCounts.length*barWidth+
(int)( (Math.floor(intervalWidth*0.2F))<1 ?
1:(Math.floor(intervalWidth*0.2F)) ) *
m_as.nominalCounts.length) > 2 ) {
//The following amounts to adding to x the half of the area left after
//subtracting from the components width the width of the whole barplot
//(i.e. width of all the bars plus the width of all the bar paddings,
//thereby equaling to the whole barplot), since our barplot is centered.
x += ( this.getWidth() - (m_as.nominalCounts.length*barWidth +
(int)( (Math.floor(intervalWidth*0.2F))<1 ?
1:(Math.floor(intervalWidth*0.2F)) ) *
m_as.nominalCounts.length) ) / 2;
}
for(int i=0; i<m_as.nominalCounts.length; i++) {
heightRatio = (this.getHeight()-(float)m_fm.getHeight())/m_maxValue;
//initializing y to point to (from top) the start of the bar
y = this.getHeight()-Math.round(m_as.nominalCounts[i]*heightRatio);
//if our mouse is on a bar then return the count of this bar in our
//barplot
if(ev.getX() >= x && ev.getX()<=x+barWidth &&
ev.getY() >= this.getHeight() -
Math.round(m_as.nominalCounts[i]*heightRatio) )
return(m_data.attribute(m_attribIndex).value(i)+
" ["+m_as.nominalCounts[i]+"]");
//otherwise advance x to next bar and check that. Add barwidth to x
//and padding which is max(1, 20% of interval width)
x = x+barWidth+(int)( (Math.floor(intervalWidth*0.2F))<1 ?
1:(Math.floor(intervalWidth*0.2F)) );
}
}
else if(m_threadRun==false && //if attrib is numeric
(m_histBarCounts!=null || m_histBarClassCounts!=null)) {
float heightRatio, intervalWidth;
int x=0, y=0, barWidth;
double bar = m_as.numericStats.min;
//if the class attribute is set and it is nominal
if((m_classIndex >= 0) && (m_data.attribute(m_classIndex).isNominal())) {
//there is 3 pixels of padding on each side of the histogram
//the barwidth is 1 if after removing the padding its width is less
//then the displayable width
barWidth = ((this.getWidth()-6)/m_histBarClassCounts.length)<1 ?
1:((this.getWidth()-6)/m_histBarClassCounts.length);
//initializing x to 3 adding appropriate value to make it point to the
//start of the 1st bar of our "centered" histogram.
x = 3;
if( (this.getWidth() - (x + m_histBarClassCounts.length*barWidth)) > 5 )
x += (this.getWidth() - (x + m_histBarClassCounts.length*barWidth))/2;
heightRatio = (this.getHeight()-(float)m_fm.getHeight())/m_maxValue;
if( ev.getX()-x >= 0) {
//The temp holds the index of the current interval that we are looking
//at
int temp = (int)((ev.getX()-x)/(barWidth+0.0000000001));
if(temp == 0){ //handle the special case temp==0. see footnote 1
int sum=0;
for(int k=0; k<m_histBarClassCounts[0].length; k++)
sum += m_histBarClassCounts[0][k];
//return the count of the interval mouse is pointing to plus
//the range of values that fall into this interval
return ("<html><center><font face=Dialog size=-1>"+sum+"<br>"+
"["+Utils.doubleToString(bar+m_barRange*temp,3)+
", "+Utils.doubleToString((bar+m_barRange*(temp+1)),3)+
"]"+"</font></center></html>");
}
else if( temp < m_histBarClassCounts.length ) { //handle case temp!=0
int sum=0;
for(int k=0; k<m_histBarClassCounts[temp].length; k++)
sum+=m_histBarClassCounts[temp][k];
//return the count of the interval mouse is pointing to plus
//the range of values that fall into this interval
return ("<html><center><font face=Dialog size=-1>"+sum+"<br>("+
Utils.doubleToString(bar+m_barRange*temp,3)+", "+
Utils.doubleToString((bar+m_barRange*(temp+1)),3)+
"]</font></center></html>");
}
}
}
else { //else if the class attribute is not set or is numeric
barWidth = ((this.getWidth()-6)/m_histBarCounts.length) < 1 ?
1 : ((this.getWidth()-6)/m_histBarCounts.length);
//initializing x to 3 adding appropriate value to make it point to the
//start of the 1st bar of our "centered" histogram.
x = 3;
if( (this.getWidth() - (x + m_histBarCounts.length*barWidth)) > 5 )
x += (this.getWidth() - (x + m_histBarCounts.length*barWidth))/2;
heightRatio = (this.getHeight()-(float)m_fm.getHeight())/m_maxValue;
if( ev.getX()-x >= 0) {
//Temp holds the index of the current bar we are looking at.
int temp = (int)((ev.getX()-x)/(barWidth+0.0000000001));
//return interval count as well as its range
if(temp == 0) //handle special case temp==0. see footnote 1.
return ("<html><center><font face=Dialog size=-1>"+
m_histBarCounts[0]+"<br>"+
"["+Utils.doubleToString(bar+m_barRange*temp,3)+", "+
Utils.doubleToString((bar+m_barRange*(temp+1)),3)+
"]"+
"</font></center></html>");
else if(temp < m_histBarCounts.length) //handle case temp!=0
return ("<html><center><font face=Dialog size=-1>"+
m_histBarCounts[temp]+"<br>"+
"("+Utils.doubleToString(bar+m_barRange*temp,3)+", "+
Utils.doubleToString((bar+m_barRange*(temp+1)),3)+
"]"+
"</font></center></html>");
}
}
}
return PrintableComponent.getToolTipText(m_Printer);
}
/**
* Paints this component
*
* @param g The graphics object for this component
*/
public void paintComponent(Graphics g) {
g.clearRect(0,0,this.getWidth(), this.getHeight());
if(m_as!=null) { //If calculations have been done and histogram/barplot
if(m_threadRun==false) { //calculation thread is not running
int buttonHeight=0;
if(m_colorAttrib!=null)
buttonHeight =m_colorAttrib.getHeight()+m_colorAttrib.getLocation().y;
//if current attribute is nominal then draw barplot.
if(m_as.nominalCounts != null &&
(m_histBarClassCounts!=null || m_histBarCounts!=null) ) {
float heightRatio, intervalWidth;
int x=0, y=0, barHeight, barWidth;
//if the class attribute is set and is nominal then draw coloured
//subbars for each bar
if((m_classIndex >= 0) &&
(m_data.attribute(m_classIndex).isNominal())) {
intervalWidth=(this.getWidth()/(float)m_histBarClassCounts.length);
//Barwidth is 80% of interval width.The remaining 20% is padding,
//10% on each side of the bar. If interval width is less then 5 the
//20% of that value is less than 1, in that case we use bar width of
//1 and padding of 1 pixel on each side of the bar.
if(intervalWidth>5)
barWidth = (int)Math.floor(intervalWidth*0.8F);
else
barWidth = 1;
//initializing x to 10% of interval width or to 1 if 10% is <1. This
//is essentially the LHS padding of the 1st bar.
x = x + (int)( (Math.floor(intervalWidth*0.1F))<1 ?
1 : (Math.floor(intervalWidth*0.1F)) );
//Add appropriate value to x so that it starts at the 1st bar of
//a "centered" barplot.
if(this.getWidth() - (m_histBarClassCounts.length*barWidth +
(int)( (Math.floor(intervalWidth*0.2F))<1 ?
1 :(Math.floor(intervalWidth*0.2F))
) * m_histBarClassCounts.length) > 2 ) {
//We take the width of all the bars and all the paddings (20%
//of interval width), and subtract it from the width of the panel
//to get the extra space that would be left after drawing. We
//divide that space by 2 to get its mid-point and add that to our
//x, thus making the whole bar plot drawn centered in our
//component.
x += (this.getWidth()-(m_histBarClassCounts.length*barWidth+
(int)( (Math.floor(intervalWidth*0.2F))<1 ?
1 : (Math.floor(intervalWidth*0.2F))
) * m_histBarClassCounts.length))/2;
}
//this holds the count of the bar and will be calculated by adding
//up the counts of individual subbars. It is displayed at the top
//of each bar.
int sum=0;
for(int i=0; i<m_histBarClassCounts.length; i++) {
//calculating the proportion of the components height compared to
//the maxvalue in our attribute, also taking into account the
//height of font to display bars count and the height of the class
//ComboBox.
heightRatio = ( this.getHeight()-(float)m_fm.getHeight() -
buttonHeight ) / m_maxValue;
y=this.getHeight();
for(int j=0; j<m_histBarClassCounts[i].length; j++) {
sum = sum + m_histBarClassCounts[i][j];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -