Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
5.2 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. scale.cpp
  5. Abstract:
  6. Implements display of the scale numbers on the graph y-axis.
  7. --*/
  8. #include "polyline.h"
  9. #include <strsafe.h>
  10. #define SCALE_MARGIN 10
  11. CGraphScale::CGraphScale( void )
  12. : m_iMaxValue(100),
  13. m_iMinValue(0),
  14. m_nTics(0),
  15. m_iTextHeight(0)
  16. {
  17. }
  18. CGraphScale::~CGraphScale( void )
  19. {
  20. }
  21. void CGraphScale::SetRect( PRECT pRect )
  22. {
  23. m_Rect = *pRect;
  24. SetTicPositions();
  25. }
  26. void CGraphScale::SetMaxValue( INT iMaxValue )
  27. {
  28. m_iMaxValue = iMaxValue;
  29. SetTicPositions();
  30. }
  31. void CGraphScale::SetMinValue( INT iMinValue )
  32. {
  33. m_iMinValue = iMinValue;
  34. SetTicPositions();
  35. }
  36. void CGraphScale::SetTicPositions( void )
  37. {
  38. INT iHeight;
  39. INT nMaxTics;
  40. INT i;
  41. CStepper stepper;
  42. static INT aiTicTable[] = {25,20,10,5,4,2,1,0};
  43. iHeight = m_Rect.bottom - m_Rect.top;
  44. if (!(iHeight > 0 && m_iTextHeight > 0)) {
  45. m_nTics = 0;
  46. return;
  47. }
  48. // Determine number of labels that will fit
  49. nMaxTics = iHeight / (m_iTextHeight + m_iTextHeight/2);
  50. for (i=0; nMaxTics < aiTicTable[i]; i++) {};
  51. m_nTics = aiTicTable[i];
  52. // Don't have more labels than values
  53. if (m_iMaxValue - m_iMinValue < m_nTics)
  54. m_nTics = m_iMaxValue - m_iMinValue;
  55. // Locate equally spaced tic marks
  56. if (m_nTics > 0)
  57. {
  58. m_aiTicPos[0] = 0;
  59. stepper.Init(iHeight,m_nTics);
  60. for (i = 1; i <= m_nTics; i++)
  61. {
  62. m_aiTicPos[i] = stepper.NextPosition();
  63. }
  64. }
  65. }
  66. INT CGraphScale::GetTicPositions( INT **piTics )
  67. {
  68. *piTics = m_aiTicPos;
  69. return m_nTics;
  70. }
  71. INT CGraphScale::GetWidth (HDC hDC)
  72. {
  73. WCHAR szMaxValue [MAX_VALUE_LEN] ;
  74. SIZE Size;
  75. INT iWidth;
  76. // compute size of largest possible numerical label plus space
  77. if ( 0 != FormatNumber (
  78. (double)m_iMaxValue,
  79. szMaxValue,
  80. MAX_VALUE_LEN,
  81. eMinimumWidth,
  82. eFloatPrecision) ) {
  83. GetTextExtentPoint32(hDC, szMaxValue, lstrlen(szMaxValue), &Size);
  84. // Save Text height for tic calculations
  85. m_iTextHeight = Size.cy;
  86. iWidth = Size.cx + SCALE_MARGIN;
  87. } else {
  88. iWidth = 0;
  89. }
  90. return iWidth;
  91. }
  92. void CGraphScale::Draw (HDC hDC)
  93. {
  94. WCHAR szScale [MAX_VALUE_LEN] ;
  95. INT iRetChars,
  96. i,
  97. iUnitsPerLine ;
  98. INT iRange;
  99. FLOAT ePercentOfTotal ;
  100. FLOAT eDiff ;
  101. BOOL bUseFloatingPt = FALSE ;
  102. RECT rectClip;
  103. // nTicks may be zero if the screen size if getting too small
  104. if (m_nTics < 1 || m_iMaxValue <= m_iMinValue)
  105. return;
  106. iRange = m_iMaxValue - m_iMinValue;
  107. // Calculate what percentage of the total each line represents.
  108. ePercentOfTotal = ((FLOAT) 1.0) / ((FLOAT) m_nTics) ;
  109. // Calculate the amount (number of units) of the Vertical max each
  110. // each line in the graph represents.
  111. iUnitsPerLine = (INT) ((FLOAT) iRange * ePercentOfTotal) ;
  112. ePercentOfTotal *= (FLOAT) iRange;
  113. eDiff = (FLOAT)iUnitsPerLine - ePercentOfTotal ;
  114. if (eDiff < (FLOAT) 0.0)
  115. eDiff = -eDiff ;
  116. if ( (iUnitsPerLine < 100) && (eDiff > (FLOAT) 0.1) ) {
  117. bUseFloatingPt = TRUE ;
  118. }
  119. SetTextAlign (hDC, TA_TOP | TA_RIGHT) ;
  120. rectClip.left = m_Rect.left;
  121. rectClip.right = m_Rect.right - SCALE_MARGIN;
  122. // Now Output each string.
  123. for (i = 0; i < m_nTics; i++) {
  124. if (bUseFloatingPt) {
  125. FLOAT fValue = (FLOAT)m_iMaxValue - ((FLOAT)i * ePercentOfTotal);
  126. iRetChars = FormatNumber (
  127. (double)fValue,
  128. szScale,
  129. MAX_VALUE_LEN,
  130. eMinimumWidth,
  131. eFloatPrecision);
  132. } else {
  133. iRetChars = StringCchPrintf (szScale, MAX_VALUE_LEN, L"%d", m_iMaxValue - (i * iUnitsPerLine)) ;
  134. }
  135. rectClip.top = m_aiTicPos[i] + m_Rect.top - m_iTextHeight/2;
  136. rectClip.bottom = rectClip.top + m_iTextHeight;
  137. ExtTextOut (
  138. hDC,
  139. rectClip.right,
  140. rectClip.top,
  141. 0,
  142. &rectClip,
  143. szScale,
  144. lstrlen(szScale),
  145. NULL );
  146. }
  147. // Make sure the last value is the specified Minimum.
  148. if (bUseFloatingPt) {
  149. iRetChars = FormatNumber (
  150. (double)m_iMinValue,
  151. szScale,
  152. MAX_VALUE_LEN,
  153. eMinimumWidth,
  154. eFloatPrecision);
  155. } else {
  156. iRetChars = StringCchPrintf (szScale, MAX_VALUE_LEN, L"%d", m_iMinValue) ;
  157. }
  158. rectClip.top = m_aiTicPos[i] + m_Rect.top - m_iTextHeight/2;
  159. rectClip.bottom = rectClip.top + m_iTextHeight;
  160. ExtTextOut (
  161. hDC,
  162. rectClip.right,
  163. rectClip.top,
  164. 0,
  165. &rectClip,
  166. szScale,
  167. lstrlen(szScale),
  168. NULL);
  169. }