📄 attributevisualizationpanel.java
字号:
" min:"+m_as.numericStats.min+ " 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 + -