/** ************************************************************* * * Draw the actual text and bars onto the pie chart. * * occurrs by generating the appropriate set of CIUPrimitives * and drawing them onto the IUGraphicsContext. * * A cache is used for the CIUText primitives so they can be * resused. These are expensive primitives to generate. * * @exception Exception On fatal rendering error * @throws Exception On fatal rendering error * */ public boolean pollUpdate() throws Exception { CIUCacheEntry cacheEntry = null; // A cache entry CIUPrimitive gp = null; // The current primitive to draw String key = null; int NC = CIUGraphicsContext.NoClip; // ID for "no clipping" int HC = CIUGraphicsContext.HClip; // ID for horizontal clipping int VC = CIUGraphicsContext.VClip; // ID for vertical clipping int HVC = CIUGraphicsContext.HVClip; // IF for clipping in both directions int resize = NC; int counter = 0; boolean horzClip = false; // Was there horizontal clipping? boolean vertClip = false; // Was there vertical clipping? int iStrMaxWidth; // Max width [in pixels] of a string byte black; // The LUT index for black int MARGIN = 5; // The size [in pixels] of the margin int cX = MARGIN; // Current x-position int cY = MARGIN; // Current y-position int H; // The height of a primitive int W; // The width of a primitive PollDraw.consoleLog("\nPieChart::pollUpdate> begin"); // // Get the 4 necessary CIUFonts // this.retrieveIUFonts( m_IUFontHash ); // // Some initializations // StrMaxWidth = m_width - (MARGIN*2); black = (byte)m_cc.toLUTIndex( "000000" ); // // I need a graphics context to draw on // m_gc = new CIUGraphicsContext( m_width, cY, m_bgcolor, m_cc ); PollDraw.consoleLog("PieChart::pollUpdate> gc is " + m_width + " by " + cY + " big"); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Add the title as a child if(m_strTitle != null) { key = null; cacheEntry = null; key = ( m_strTitle + m_cfTitle.key() ); cacheEntry = m_primitiveCache.get( key ); if ( null == cacheEntry ) { gp = new CIUText( m_strTitle, iStrMaxWidth, m_cfTitle, m_frame, black ).translate( cX, cY ); m_primitiveCache.add( key, gp ); } else { gp = (CIUPrimitive)cacheEntry.m_object; gp.zero().translate( cX, cY ); } if ( null!=gp ) { m_gc.draw( gp ); cY += ( gp.height() + MARGIN ); gp = null; } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Add the question as a child String question = m_PollQuestionData.getQuestion(); cacheEntry = null; key = null; key = ( question + m_cfText.key() ); cacheEntry = m_primitiveCache.get( key ); if ( null == cacheEntry ) { gp = new CIUText( question, iStrMaxWidth, m_cfText, m_frame, black ).translate( cX, cY ); m_primitiveCache.add( key, gp ); } else { gp = (CIUPrimitive)cacheEntry.m_object; gp.zero().translate( cX, cY ); } m_gc.draw( gp ); cY += ( gp.height() + MARGIN + MARGIN); gp = null; // Dereference the poll answers PollAnswer[] answers = m_PollQuestionData.getAnswers(); float top_percent = answers[0].percentage(); double [] sizes = new double[ answers.length ]; for( int a = 0; a < answers.length; ++a ) sizes[a] = (double)answers[a].percentage(); // Draw The pie chart.... int radius = (int) ((m_width/2.0) - MARGIN*2); gp = new CIUPieChart( radius, false, sizes, m_frame, m_pieColors, "000000", m_bgcolor, m_cc ).translate( cX+MARGIN, cY ); m_gc.draw( gp ); cY += ( gp.height() + MARGIN*3 ); gp = null; // Draw the poll answers themselves for( int a = 0; a < answers.length; ++a ) { // Some preparatory values float fPer = answers[a].percentage(); byte byteColor = (byte)m_cc.toLUTIndex( m_pieColors[a % m_pieColors.length] ); int intColor = CIUBitArray.byteToInt( byteColor ); PollDraw.consoleLog("PieChart::pollUpdate> color: " + m_pieColors[a % m_pieColors.length] ); PollDraw.consoleLog("PieChart::pollUpdate> color: " + intColor ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Draw percentage string. // String sPer = getPercentString( fPer ); cacheEntry = null; key = null; key = ( sPer + m_cfPercent.key() ); cacheEntry = m_primitiveCache.get( key ); if ( null == cacheEntry ) { PollDraw.consoleLog("PieChart::pollUpdate> Did not find cache entry: " + sPer); gp = new CIUText( sPer, 1000, m_cfPercent, m_frame, black ).translate( cX, cY ); } else { PollDraw.consoleLog("PieChart::pollUpdate> Found cache entry: " + sPer); gp = (CIUPrimitive)cacheEntry.m_object; gp.zero().translate( cX, cY ); } m_gc.draw( gp ); cY += gp.height(); gp = null; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Draw the answer String answer = answers[a].answer(); cacheEntry = null; key = null; key = ( answer + m_cfText.key() + intColor ); cacheEntry = m_primitiveCache.get( key ); if ( null == cacheEntry ) { PollDraw.consoleLog("PieChart::pollUpdate> Did not find cache entry: " + answer); gp = new CIUText( answer, iStrMaxWidth, m_cfText, m_frame, byteColor ).translate( cX, cY ); m_primitiveCache.add( key, gp ); } else { PollDraw.consoleLog("PieChart::pollUpdate> Found cache entry: " + answer); gp = (CIUPrimitive)cacheEntry.m_object; gp.zero().translate( cX, cY ); } m_gc.draw( gp ); cY += ( MARGIN + gp.height() ); gp = null; } // Translate cY += MARGIN; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Draw the string for the total votes... String total = "Total Votes: "; cacheEntry = null; key = null; key = ( total + m_cfTotal.key() ); cacheEntry = m_primitiveCache.get( key ); if ( null == cacheEntry ) { PollDraw.consoleLog("PieChart::pollUpdate> Did not find cache entry: " + total); gp = new CIUText( total, iStrMaxWidth, m_cfTotal, m_frame, black ).translate( cX, cY ); m_primitiveCache.add( key, gp ); } else { PollDraw.consoleLog("PieChart::pollUpdate> Found cache entry: " + total); gp = (CIUPrimitive)cacheEntry.m_object; gp.zero().translate( cX, cY ); } m_gc.draw( gp ); W = gp.width(); gp = null; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Draw the string for the number of votes... // String votes = commaAbsInteger( m_PollQuestionData.totalVotes() ); cacheEntry = null; key = null; key = ( votes + m_cfTotal.key() ); cacheEntry = m_primitiveCache.get( key ); if ( null == cacheEntry ) { PollDraw.consoleLog("PieChart::pollUpdate> Did not find cache entry: " + votes ); gp = new CIUText( votes, iStrMaxWidth, m_cfTotal, m_frame, black ).translate( (cX + W), cY ); m_primitiveCache.add( key, gp ); } else { PollDraw.consoleLog("PieChart::pollUpdate> Found cache entry: " + votes ); gp = (CIUPrimitive)cacheEntry.m_object; gp.zero().translate( (cX + W), cY ); } m_gc.draw( gp ); cY += ( MARGIN + gp.height() ); gp = null; cacheEntry = null; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Resize the GC so we know it is big enough.... // resize = m_gc.resize( m_width, cY ); if ( VC == resize ) { vertClip=true; } else if ( HC == resize ) { horzClip=true; } else if ( HVC == resize ) { horzClip=true; vertClip=true; } PollDraw.consoleLog("PieChart::pollUpdate> gc is " + m_width + " by " + cY + " big"); PollDraw.consoleLog("PieChart::pollUpdate> clip: h:" + horzClip + " v:" + vertClip ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // For very small polls, the GC can clip the percentage text. // Try to resize horizontally 3 times... if we need any more // than 3 tries (15 pixels), then there's more wrong here // than simple resizing. // while ( (HC==resize) && (counter<4) ) { ++counter; m_width+=MARGIN; resize = m_gc.resize( m_width, cY ); if ( VC == resize ) { vertClip=true; } else if ( HC == resize ) { horzClip=true; } else if ( HVC == resize ) { horzClip=true; vertClip=true; } PollDraw.consoleLog("PieChart::pollUpdate> gc is " + m_width + " by " + cY + " big"); PollDraw.consoleLog("PieChart::pollUpdate> clip: h:" + horzClip + " v:" + vertClip ); } PollDraw.consoleLog("PieChart::pollUpdate> end\n"); return true; }