/***************************************************************************** * * Copyright (c) 1999, KL GROUP INC. All Rights Reserved. * http://www.klgroup.com * * This file is provided for demonstration and educational uses only. * Permission to use, copy, modify and distribute this file for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of KL Group not be used in advertising * or publicity pertaining to this material without the specific, * prior written permission of an authorized representative of * KL Group. * * KL GROUP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. KL GROUP SHALL NOT BE LIABLE FOR ANY * DAMAGES SUFFERED BY USERS AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ // golfersDlg.cpp : implementation file // #include "stdafx.h" #include "golfers.h" #include "golfersDlg.h" #include "3dconst.h" #include "oc_color.h" #include "DataColor.h" #include "DataColorCollection.h" #include "Border.h" #include "Font.h" #include "Axis.h" #include "AxisCollection.h" #include "Label.h" #include "LabelCollection.h" #include "Title.h" #include "Bar.h" #include "ChartArea.h" #include "Elevation.h" #include "ChartGroup.h" #include "ChartGroupCollection.h" #include "PlotCube.h" #include "Interior.h" #include "Gridlines.h" #include "LineStyle.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGolfersDlg dialog CGolfersDlg::CGolfersDlg(CWnd* pParent /*=NULL*/) : CDialog(CGolfersDlg::IDD, pParent) { //{{AFX_DATA_INIT(CGolfersDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pChart = NULL; } void CGolfersDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CGolfersDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CGolfersDlg, CDialog) //{{AFX_MSG_MAP(CGolfersDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_SIZE() ON_WM_QUERYNEWPALETTE() ON_WM_PALETTECHANGED() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGolfersDlg message handlers static const COLORREF crSelected = ocColorRed; static const COLORREF crChart = ocColorGreen; BOOL CGolfersDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon InitChart(); return TRUE; // return TRUE unless you set the focus to a control } static const long gridx = 10; static const long gridy = 5; void CGolfersDlg::SetText() { static char *xlabels[] = { "Arnold Palmer", "Sam Snead", "Gene Sarazen", "Bobby Jones", "Harry Vardon", "Tom Watson", "Gary Player", "Ben Hogan", "Walter Hagen", "Jack Nicklaus", NULL }; static char *ylabels[] = { "British Open", "US Open", "US PGA", "US Masters", "Total", NULL }; static char *header = "These ten great golfers have won seven or more 'Majors' - US Masters,\n" "The Open, US PGA - and, as the graph shows, the greatest of these is\n" "Jack Nicklaus. He is the only golfer to have won each of these titles\n" "twice and holds the record for the lowest four round total in both\n" "the US Masters and US Open"; static char *footer = "Select or deselect bars by clicking\non them with the left mouse button."; m_pChart->GetHeader().GetText().SetText(header); m_pChart->GetFooter().GetText().SetText(footer); // set header/footer font point size CY cy; cy.Lo = 50000; cy.Hi = 0; m_pChart->GetHeader().GetFont().SetSize(cy); m_pChart->GetHeader().GetFont().SetBold(TRUE); m_pChart->GetFooter().GetFont().SetSize(cy); m_pChart->GetFooter().GetFont().SetBold(TRUE); m_pChart->GetHeader().GetBorder().SetType(oc3dBorderEtchedIn); // Setup some golfing colors m_pChart->GetHeader().GetInterior().SetBackgroundColor(ocColorYellowGreen); m_pChart->GetFooter().GetInterior().SetBackgroundColor(ocColorSandyBrown); m_pChart->GetInterior().SetBackgroundColor(ocColorGainsboro); m_pChart->GetChartArea().GetInterior().SetBackgroundColor(ocColorLightYellow); m_pChart->GetChartArea().GetPlotCube().GetInterior().SetBackgroundColor(ocColorForestGreen); // Emphasize the (x,y) dimensions slightly m_pChart->GetChartArea().GetPlotCube().SetXScale(150); m_pChart->GetChartArea().GetPlotCube().SetYScale(150); // Get access to the axis objects CAxis axisX(m_pChart->GetChartArea().GetAxes().GetItem(COleVariant("x"))); CAxis axisY(m_pChart->GetChartArea().GetAxes().GetItem(COleVariant("y"))); CAxis axisZ(m_pChart->GetChartArea().GetAxes().GetItem(COleVariant("z"))); // Turn on the Z Axis grid lines axisZ.GetMajorGrid().SetIsOnXZPlane(TRUE); axisZ.GetMajorGrid().SetIsOnYZPlane(TRUE); // Set the gridline styles axisZ.GetMajorGrid().GetStyle().SetColor(ocColorWheat); axisZ.GetMajorGrid().GetStyle().SetPattern(oc3dLineDotted); axisZ.GetMajorGrid().GetStyle().SetWidth(2); // Set up axis annotations and titles axisX.SetAnnotationMethod(oc3dAnnotateDataLabels); axisY.SetAnnotationMethod(oc3dAnnotateDataLabels); axisX.GetTitle().SetText("Golf Master"); axisY.GetTitle().SetText("Golf tournament"); axisZ.GetTitle().SetText("Number won"); CLabelCollection labelCollX(m_pChart->GetChartGroups().GetItem(COleVariant(short(1))).GetRowLabels()); for (char ** pszLabel = xlabels; *pszLabel; pszLabel++) { labelCollX.Add(*pszLabel, COleVariant()); } CLabelCollection labelCollY(m_pChart->GetChartGroups().GetItem(COleVariant(short(1))).GetColumnLabels()); for (pszLabel = ylabels; *pszLabel; pszLabel++) { labelCollY.Add(*pszLabel, COleVariant()); } } void CGolfersDlg::SetGrid() { static double values[gridx][gridy] = { {2, 1, 0, 4, 7}, {1, 0, 3, 3, 7}, {1, 2, 3, 1, 7}, {3, 4, 0, 0, 7}, {6, 1, 0, 0, 7}, {5, 1, 0, 2, 8}, {3, 1, 2, 3, 9}, {1, 4, 2, 2, 9}, {4, 2, 5, 0, 11}, {3, 4, 5, 6, 18} }; CChartGroup chGroup(m_pChart->GetChartGroups().GetItem(COleVariant(short(1)))); CChart3DData data(chGroup.GetElevationData()); // batch for efficiency data.SetIsBatched(TRUE); chGroup.SetChartType(oc3dTypeBar); chGroup.GetElevation().SetIsMeshed(TRUE); chGroup.GetElevation().SetIsShaded(TRUE); m_pChart->GetChartArea().GetBar().SetRowSpacing(100); m_pChart->GetChartArea().GetBar().SetColumnSpacing(100); data.SetRowCount(gridx); data.SetColumnCount(gridy); data.SetRowOrigin(0); data.SetColumnOrigin(0); data.SetRowDelta(1, 1); data.SetColumnDelta(1, 1); for (long lRow = 1; lRow <= gridx; lRow++) { for (long lColumn = 1; lColumn <= gridy; lColumn++) { data.SetValue(lRow, lColumn, values[lRow - 1][lColumn - 1]); } } data.SetIsBatched(FALSE); } BOOL CGolfersDlg::InitChart() { // get pointer to Chart3D control embedded in dialog m_pChart = (CChart3D *) GetDlgItem(IDC_CHART3D); SetGrid(); SetText(); // give the chart a deselected color m_pChart->GetChartArea().GetBar().GetColors().Add(COleVariant((long)0), COleVariant((long)0), crChart); return TRUE; } void CGolfersDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CGolfersDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CGolfersDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } BEGIN_EVENTSINK_MAP(CGolfersDlg, CDialog) //{{AFX_EVENTSINK_MAP(CGolfersDlg) ON_EVENT(CGolfersDlg, IDC_CHART3D, -605 /* MouseDown */, OnMouseDownChart3d, VTS_I2 VTS_I2 VTS_I4 VTS_I4) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CGolfersDlg::OnMouseDownChart3d(short Button, short Shift, long x, long y) { long lRow, lColumn, lDistance; // only check for the left mouse button if (Button != MK_LBUTTON) { return; } // convert the pixel coordinates to a specific bar m_pChart->GetChartGroups().GetItem(COleVariant(short(1))). CoordToDataIndex(x, y, &lRow, &lColumn, &lDistance); // clicked outside the bars if ((lRow == 0) || (lColumn == 0)) { return; } COleVariant oleRow(lRow); COleVariant oleCol(lColumn); CDataColorCollection colors(m_pChart->GetChartArea().GetBar().GetColors()); // exceptions are thrown if the item does not exist try { CDataColor thiscolor(colors.GetItem(oleRow, oleCol)); OLE_COLOR color = thiscolor.GetColor(); COLORREF crColor; OleTranslateColor(color, NULL, &crColor); if (crColor == crSelected) { // deselect it colors.Remove(oleRow, oleCol); } else { // select it colors.Add(oleRow, oleCol, crSelected); } } // if it doesn't exist, it can't be already selected, so select it catch (COleDispatchException* e) { if (SCODE_CODE(e->m_scError) == (m_pChart->GetErrorOffset() + ocErrorNoSuchItem)) { colors.Add(oleRow, oleCol, crSelected); e->Delete(); } else { // Not the exception we expected, pass it on throw; } } } void CGolfersDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); // size the chart to fit the window if (m_pChart && (cx > 0) && (cy > 0)) { m_pChart->MoveWindow(0, 0, cx, cy); } } BOOL CGolfersDlg::OnQueryNewPalette() { return(m_pChart->SendMessage(WM_QUERYNEWPALETTE, 0, 0)); } void CGolfersDlg::OnPaletteChanged(CWnd* pFocusWnd) { m_pChart->SendMessage(WM_PALETTECHANGED, (WPARAM)pFocusWnd->GetSafeHwnd(), 0); }