/***************************************************************************** * * 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. * *****************************************************************************/ //--------------------------------------------------------------------------- #include #pragma hdrstop #include "pareto1.h" #include "oc_color.h" #include //--------------------------------------------------------------------------- #pragma link "OlectraChart2D_TLB" #pragma resource "*.dfm" TfrmPareto *frmPareto; //--------------------------------------------------------------------------- __fastcall TfrmPareto::TfrmPareto(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- // Setup the form and the Chart during the Form creation process //--------------------------------------------------------------------------- void __fastcall TfrmPareto::FormCreate(TObject *Sender) { //Start with the form in the top-left corner Top = 5; Left = 5; //Batch all the updates to the Chart so all the changes occur at once Chart2D1->IsBatched = true; //Set the BackgroundColor of the Chart Variant vInterior = Chart2D1->Interior_; vInterior.OlePropertySet("BackgroundColor", (int)ocColorGray76); //Setup the Borders Variant vBorder = Chart2D1->Border_; vBorder.OlePropertySet("Type", oc2dBorder3DIn); vBorder.OlePropertySet("Width", 4); Variant vCArea = Chart2D1->ChartArea_; Variant vCABorder = vCArea.OlePropertyGet("Border"); vCABorder.OlePropertySet("Type", oc2dBorder3DIn); vCABorder.OlePropertySet("Width", 4); //Set the Chart Types Variant vCG = Chart2D1->ChartGroups; Variant vCG1 = vCG.OlePropertyGet("Item", 1); Variant vCG2 = vCG.OlePropertyGet("Item", 2); vCG1.OlePropertySet("ChartType", oc2dTypeBar); vCG2.OlePropertySet("ChartType", oc2dTypePlot); //Setup the Header Variant vHeader = Chart2D1->Header; Variant vHeaderText = vHeader.OlePropertyGet("Text"); vHeaderText.OlePropertySet("Text", "Pareto Chart"); Variant vHeaderFont = vHeader.OlePropertyGet("Font"); vHeaderFont.OlePropertySet("Size", 14); vHeaderFont.OlePropertySet("Underline", true); //Setup the Legend Variant vLegend = Chart2D1->Legend_; vLegend.OlePropertySet("Font", "Arial"); Variant vLegendFont = vLegend.OlePropertyGet("Font"); vLegendFont.OlePropertySet("Size", 10); Variant vLegendBorder = vLegend.OlePropertyGet("Border"); vLegendBorder.OlePropertySet("Type", oc2dBorderFrameIn); vLegendBorder.OlePropertySet("Width", 4); //Setup each of the ChartGroups Variant vCG1Data = vCG1.OlePropertyGet("Data"); vCG1Data.OlePropertySet("NumSeries", 10); vCG1Data.OlePropertySet("NumPoints", 1, 0); vCG1Data.OlePropertySet("NumPoints", 1, 10); Variant vCG2Data = vCG2.OlePropertyGet("Data"); vCG2Data.OlePropertySet("NumSeries", 1); vCG2Data.OlePropertySet("NumPoints", 1, 10); //Setup some Misc. properties for the Chart Variant vCABar = vCArea.OlePropertyGet("Bar"); vCABar.OlePropertySet("ClusterWidth", 75); vCABar.OlePropertySet("ClusterOverlap", 100); Variant vCAPlotArea = vCArea.OlePropertyGet("PlotArea"); vCAPlotArea.OlePropertySet("IsBoxed", true); Variant vAxes = vCArea.OlePropertyGet("Axes"); Variant vXAxis = vAxes.OlePropertyGet("Item", "X"); Variant vXAxisMGrid = vXAxis.OlePropertyGet("MajorGrid"); vXAxisMGrid.OlePropertySet("Spacing", 1); //Remove any existing Chart Labels Variant vCLabels = Chart2D1->ChartLabels; vCLabels.OleFunction("RemoveAll"); //Change the Axis font so all the ChartLabels with get the desired font vXAxis.OlePropertySet("Font", "Arial"); Variant vXAxisFont = vXAxis.OlePropertyGet("Font"); vXAxisFont.OlePropertySet("Size", 8); vXAxisFont.OlePropertySet("Bold", true); //Add 10 Chartlabels to the Chart for (int i = 1; i <= 10; i++) { Variant cLabel = vCLabels.OleFunction("Add"); cLabel.OlePropertySet("IsBatched", true); cLabel.OlePropertySet("AttachMethod", oc2dAttachDataIndex); cLabel.OlePropertySet("Text", ""); Variant cLabelBorder = cLabel.OlePropertyGet("Border"); cLabelBorder.OlePropertySet("Type", oc2dBorderNone); Variant cLabelAttach = cLabel.OlePropertyGet("AttachDataIndex"); cLabelAttach.OlePropertySet("Series", 1); cLabelAttach.OlePropertySet("Point", i); cLabelAttach.OlePropertySet("ChartGroup", 2); cLabel.OlePropertySet("IsBatched", false); } //Change the Axis font back to its default //cAxes = Chart2D1->ChartArea.OlePropertyGet("Axes").OlePropertyGet("Item", 1); vXAxis.OlePropertySet("Font", "Arial"); vXAxisFont.OlePropertySet("Size", 10); vXAxisFont.OlePropertySet("Bold", false); //Generate some data, sort its values and draw the Chart CreateData1(); SortDataGroup1(); CreateData2(); FinalizeTheChart(); //Resume regular updates to the Chart Chart2D1->IsBatched = false; } //--------------------------------------------------------------------------- // Create some random Data and put it into the Chart in Data Group 1 //--------------------------------------------------------------------------- void TfrmPareto::CreateData1() { char szNumber[3]; char szLabel[10]; int number; Variant vCG = Chart2D1->ChartGroups; Variant vCG1 = vCG.OlePropertyGet("Item", 1); //Create 10 points of random data and put them into ChartGroup 1 randomize(); //Setup the colors for the 10 bars Variant vCG1Styles = vCG1.OlePropertyGet("Styles"); Variant vCG1Style = vCG1Styles.OlePropertyGet("Item", 1); Variant vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorRed); vCG1Style = vCG1Styles.OlePropertyGet("Item", 2); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorGreen); vCG1Style = vCG1Styles.OlePropertyGet("Item", 3); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorBlue); vCG1Style = vCG1Styles.OlePropertyGet("Item", 4); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorBlanchedAlmond); vCG1Style = vCG1Styles.OlePropertyGet("Item", 5); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorPurple); vCG1Style = vCG1Styles.OlePropertyGet("Item", 6); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorYellow); vCG1Style = vCG1Styles.OlePropertyGet("Item", 7); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorMagenta); vCG1Style = vCG1Styles.OlePropertyGet("Item", 8); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorNavyBlue); vCG1Style = vCG1Styles.OlePropertyGet("Item", 9); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorWhite); vCG1Style = vCG1Styles.OlePropertyGet("Item", 10); vCG1LineStyle = vCG1Style.OlePropertyGet("Line"); vCG1LineStyle.OlePropertySet("Color", (int)ocColorSeaGreen); Variant vCG1Data = vCG1.OlePropertyGet("Data"); vCG1Data.OlePropertySet("IsBatched", true); Variant vCG1SLabels = vCG1.OlePropertyGet("SeriesLabels"); vCG1SLabels.OleFunction("RemoveAll"); for (int i = 1; i <= 10; i++) { number = ((random(25) * 45) + 1); vCG1Data.OlePropertySet("Y", i, i, number); strcpy(szLabel, "Series "); itoa(i, szNumber, 10); strcat(szLabel, szNumber); vCG1SLabels.OleFunction("Add", szLabel); } vCG1Data.OlePropertySet("IsBatched", false); } //--------------------------------------------------------------------------- // Using the data Data Group 1, create the data for Data Group 2 //--------------------------------------------------------------------------- void TfrmPareto::CreateData2() { double TotalValue = 0; double Percentage = 0; double DataValue; char szPercentage[5]; Variant vCG = Chart2D1->ChartGroups; Variant vCG1 = vCG.OlePropertyGet("Item", 1); Variant vCG2 = vCG.OlePropertyGet("Item", 2); Variant vCG1Data = vCG1.OlePropertyGet("Data"); Variant vCG2Data = vCG2.OlePropertyGet("Data"); //Add up the total of the 10 points in ChartGroup 1 for (int i = 1; i <= 10; i++) { DataValue = vCG1Data.OlePropertyGet("Y", i, i); TotalValue = TotalValue + DataValue; } //Using the values from ChartGroup 1, create the second ChartGroups data for (int i = 1; i <= 10; i++) { if (i == 1) { vCG2Data.OlePropertySet("Y", 1, i, vCG1Data.OlePropertyGet("Y", 1, i)); } else { vCG2Data.OlePropertySet("Y", 1, i, vCG1Data.OlePropertyGet("Y", i, i) + vCG2Data.OlePropertyGet("Y", 1, i - 1)); } } //Now that we have the TotalValue and each individual value, calculate the // the percentage of the the TotalValue, create a label for each point that // contains the percentage for each point Variant vCLabels = Chart2D1->ChartLabels; Variant vCLabel; for (int i = 1; i <= 10; i++) { if (i == 1) { Percentage = (vCG1Data.OlePropertyGet("Y", i, i) / TotalValue) * 100; vCLabel = vCLabels.OlePropertyGet("Item", 1); } else { Percentage = Percentage + (vCG1Data.OlePropertyGet("Y", i, i) / TotalValue) * 100; vCLabel = vCLabels.OlePropertyGet("Item", i); } itoa((int)floor(Percentage + 0.5), szPercentage, 10); strcat(szPercentage, "%"); vCLabel.OlePropertySet("Text", szPercentage); } } //--------------------------------------------------------------------------- // Sort the data using an Optimized Bubble Sort //--------------------------------------------------------------------------- void TfrmPareto::SortDataGroup1() { bool Done; double HoldValue; Variant HoldInfo; int i; double Number1; double Number2; long HoldColor; Variant vCG = Chart2D1->ChartGroups; Variant vCG1 = vCG.OlePropertyGet("Item", 1); Variant vCG2 = vCG.OlePropertyGet("Item", 2); Variant vCG1SLabels = vCG1.OlePropertyGet("SeriesLabels"); Variant vCG1Data = vCG1.OlePropertyGet("Data"); Variant vCG2Data = vCG2.OlePropertyGet("Data"); Variant vCG1SLabel, vCG1SLabelNext; Variant vCG1Styles = vCG1.OlePropertyGet("Styles"); Variant vStyle1, vStyle2; Variant vLine1, vColor1, vLine2, vColor2; //Batch all Chart updates //Batch all Data object updates for even faster processing vCG1Data.OlePropertySet("IsBatched", true); //Using a standard Bubble Sort, sort the 10 points (both data and labels) do { Done = true; for (i = 1; i < 10; i++) { Number1 = vCG1Data.OlePropertyGet("Y", i, i); Number2 = vCG1Data.OlePropertyGet("Y", i + 1, i + 1); if (Number1 < Number2) { //Sort the data values HoldValue = vCG1Data.OlePropertyGet("Y", i, i); vCG1Data.OlePropertySet("Y", i, i, vCG1Data.OlePropertyGet("Y", i + 1, i + 1)); vCG1Data.OlePropertySet("Y", i + 1, i + 1, HoldValue); //Sort the labels vCG1SLabel = vCG1SLabels.OlePropertyGet("Item", i); vCG1SLabelNext = vCG1SLabels.OlePropertyGet("Item", i + 1); HoldInfo = vCG1SLabel.OlePropertyGet("Text"); vCG1SLabel.OlePropertySet("Text", vCG1SLabelNext.OlePropertyGet("Text")); vCG1SLabelNext.OlePropertySet("Text", HoldInfo); //Sort the colors on the bars vStyle1 = vCG1Styles.OlePropertyGet("Item", i); vStyle2 = vCG1Styles.OlePropertyGet("Item", i + 1); vLine1 = vStyle1.OlePropertyGet("Line"); vLine2 = vStyle2.OlePropertyGet("Line"); vColor1 = vLine1.OlePropertyGet("Color"); vColor2 = vLine2.OlePropertyGet("Color"); HoldColor = vColor1; vLine1.OlePropertySet("Color", vColor2); vLine2.OlePropertySet("Color", HoldColor); Done = false; } } } while (Done == false); //Go back to normal Data object updates vCG1Data.OlePropertySet("IsBatched", false); } //--------------------------------------------------------------------------- // Finalize the Chart settings //--------------------------------------------------------------------------- void TfrmPareto::FinalizeTheChart() { //Setup some last minute items so the Chart looks good Variant vCArea = Chart2D1->ChartArea_; Variant vAxes = vCArea.OlePropertyGet("Axes"); Variant vYAxis = vAxes.OlePropertyGet("Item", "Y"); Variant vY2Axis = vAxes.OlePropertyGet("Item", "Y2"); Variant vYAxisMin = vYAxis.OlePropertyGet("Min"); Variant vYAxisMax = vYAxis.OlePropertyGet("Max"); Variant vY2AxisMin = vY2Axis.OlePropertyGet("Min"); Variant vY2AxisMax = vY2Axis.OlePropertyGet("Max"); vYAxisMin.OlePropertySet("Value", 0); vY2AxisMin.OlePropertySet("Value", 0); vYAxisMax.OlePropertySet("Value", vY2AxisMax.OlePropertyGet("Value")); } //--------------------------------------------------------------------------- // End the program //--------------------------------------------------------------------------- void __fastcall TfrmPareto::mnuExitClick(TObject *Sender) { exit(0); } //--------------------------------------------------------------------------- // Generate some new data //--------------------------------------------------------------------------- void __fastcall TfrmPareto::mnuGenerateClick(TObject *Sender) { //Allow the user to generate a new Chart at run-time //Batch all the updates to the Chart so all the changes occur at once Chart2D1->IsBatched = true; CreateData1(); SortDataGroup1(); CreateData2(); FinalizeTheChart(); //Resume regular updates to the Chart Chart2D1->IsBatched = false; } //--------------------------------------------------------------------------- // Show the 'About This Demo' Help Page //--------------------------------------------------------------------------- void __fastcall TfrmPareto::mnuAboutThisDemoClick(TObject *Sender) { Application->HelpContext(35); } //--------------------------------------------------------------------------- // Show the 'About Olectra Chart' Help Page //--------------------------------------------------------------------------- void __fastcall TfrmPareto::mnuAboutOlectraChartClick(TObject *Sender) { Application->HelpContext(19); } //---------------------------------------------------------------------------