// $Revision: 1.14 $ // StockGraphConstructor.C // Copyright (C) 1994, 1995 Taligent, Inc. All rights reserved. #ifndef TaligentSamples_STOCKGRAPHCONSTRUCTOR #include "StockGraphConstructor.h" #endif #ifndef TaligentSamples_STOCKDATA #include #endif #ifndef TaligentSamples_STOCKDAY #include #endif #ifndef TaligentSamples_AXISDRAWER #include #endif #ifndef TaligentSamples_LABELDRAWER #include #endif #ifndef TaligentSamples_MARKDRAWER #include #endif #ifndef TaligentSamples_STANDARDGRAPH #include #endif #ifndef TaligentSamples_TITLEDRAWER #include #endif #ifndef Taligent_ASSERTIONS #include #endif //========================================================================= // TStockGraphConstructor const GraphValue TStockGraphConstructor::kDefaultLabelDistanceFromAxis = 9; const GraphValue TStockGraphConstructor::kDefaultXLabelInterval = 10; const GraphValue TStockGraphConstructor::kDefaultLabelPointSize = 12; const GraphValue TStockGraphConstructor::kDefaultMarkLength = 7; const GraphValue TStockGraphConstructor::kDefaultXMarkInterval = 1; const unsigned short TStockGraphConstructor::kDefaultNumberOfYMarks = 4; const GCoordinate TStockGraphConstructor::kDefaultDrawerWidth = 6; const GraphValue TStockGraphConstructor::kDefaultXAxisLocation = 0; //============================================================================== // TStockGraphConstructor TaligentTypeExtensionMacro_Abstract(TStockGraphConstructor); TStockGraphConstructor::TStockGraphConstructor() : fDescription(), fXAxisLabel(), fYAxisLabel(), fLabelDistanceFromAxis(0), fXLabelInterval(0), fLabelPointSize(0), fMarkLength(0), fXMarkInterval(0), fNumberOfYMarks(0), fDrawerWidth(0), fXAxisLocation(0) { } TStockGraphConstructor::TStockGraphConstructor(const TStockGraphConstructor& source) : fDescription(source.fDescription), fXAxisLabel(source.fXAxisLabel), fYAxisLabel(source.fYAxisLabel), fLabelDistanceFromAxis(source.fLabelDistanceFromAxis), fXLabelInterval(source.fXLabelInterval), fLabelPointSize(source.fLabelPointSize), fMarkLength(source.fMarkLength), fXMarkInterval(source.fXMarkInterval), fNumberOfYMarks(source.fNumberOfYMarks), fDrawerWidth(source.fDrawerWidth), fXAxisLocation(source.fXAxisLocation) { } TStockGraphConstructor::TStockGraphConstructor(const TStandardText& description, const TStandardText& xAxisLabel, const TStandardText& yAxisLabel, GraphValue labelDistFromAxis, GraphValue xLabelInterval, GraphValue labelPointSize, GraphValue markLength, GraphValue xMarkInterval, GraphValue xAxisLocation, unsigned short numberOfYMarks, GCoordinate drawerWidth) : fDescription(description), fXAxisLabel(xAxisLabel), fYAxisLabel(yAxisLabel), fLabelDistanceFromAxis(labelDistFromAxis), fXLabelInterval(xLabelInterval), fLabelPointSize(labelPointSize), fMarkLength(markLength), fXMarkInterval(xMarkInterval), fNumberOfYMarks(numberOfYMarks), fDrawerWidth(drawerWidth), fXAxisLocation(xAxisLocation) { } TStockGraphConstructor::~TStockGraphConstructor() { } TStockGraphConstructor& TStockGraphConstructor::operator=(const TStockGraphConstructor& source) { if (&source != this) { fDescription = source.fDescription; fXAxisLabel = source.fXAxisLabel; fYAxisLabel = source.fYAxisLabel; fLabelDistanceFromAxis = source.fLabelDistanceFromAxis; fXLabelInterval = source.fXLabelInterval; fLabelPointSize = source.fLabelPointSize; fMarkLength = source.fMarkLength; fXMarkInterval = source.fXMarkInterval; fNumberOfYMarks = source.fNumberOfYMarks; fDrawerWidth = source.fDrawerWidth; fXAxisLocation = source.fXAxisLocation; } return *this; } TStream& TStockGraphConstructor::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); fDescription >>= toStream; fXAxisLabel >>= toStream; fYAxisLabel >>= toStream; fLabelDistanceFromAxis >>= toStream; fXLabelInterval >>= toStream; fLabelPointSize >>= toStream; fMarkLength >>= toStream; fXMarkInterval >>= toStream; fNumberOfYMarks >>= toStream; fDrawerWidth >>= toStream; fXAxisLocation >>= toStream; return toStream; } TStream& TStockGraphConstructor::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); fDescription <<= fromStream; fXAxisLabel <<= fromStream; fYAxisLabel <<= fromStream; fLabelDistanceFromAxis <<= fromStream; fXLabelInterval <<= fromStream; fLabelPointSize <<= fromStream; fMarkLength <<= fromStream; fXMarkInterval <<= fromStream; fNumberOfYMarks <<= fromStream; fDrawerWidth <<= fromStream; fXAxisLocation <<= fromStream; return fromStream; } void TStockGraphConstructor::Do(TStandardGraph& theGraph, const TStockData& stock) { TDequeOf data( new TOperatorComparator, new TMonomorphicStreamer); if (stock.CopyData(data)) { HandleDoBegin(theGraph, data); TGraphRange xRange; TGraphRange yRange; CalcGraphRanges(xRange, yRange, data); AdjustGraphRanges(xRange, yRange); theGraph.SetXRange(xRange); theGraph.SetYRange(yRange); SetXAxisLocation(yRange.GetMin()); HandleAddStandardDrawers(theGraph, data, xRange, yRange); HandleAddExtendedDrawers(theGraph, data, xRange, yRange); HandleDoEnd(theGraph, data, xRange, yRange); } else { throw TStockException(TStockException::kDataInaccessible); } } void TStockGraphConstructor::AdjustGraphRanges( TGraphRange& xRange, TGraphRange& yRange) { GraphValue xLabelInterval = GetXLabelInterval(); ::Assertion(xLabelInterval > 0, "X label interval must be greater than zero."); AdjustRange(xRange, xRange.GetLength() / xLabelInterval); AdjustRange(yRange, GetNumberOfYMarks()); } void TStockGraphConstructor::HandleDoBegin( TStandardGraph& theGraph, TCollectionOf& data) { // does nothing } void TStockGraphConstructor::HandleDoEnd( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { // does nothing } void TStockGraphConstructor::HandleAddStandardDrawers( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { unsigned short numberOfYMarks = GetNumberOfYMarks(); ::Assertion(numberOfYMarks > 0, "Number of Y marks must be greater than zero."); TAxisDrawer* axisDrawer = new TAxisDrawer(GetXAxisLocation()); TLabelDrawer* xLabelDrawer = new TXLabelDrawer(GetLabelDistanceFromAxis(), GetXLabelInterval(), GetLabelPointSize()); TLabelDrawer* yLabelDrawer = new TYLabelDrawer(GetLabelDistanceFromAxis(), yRange.GetLength() / numberOfYMarks, GetLabelPointSize()); TMarkDrawer* xMarker = new TXMarkDrawer(GetMarkLength(), GetXMarkInterval()); TMarkDrawer* yMarker = new TYMarkDrawer(GetMarkLength(), yRange.GetLength() / numberOfYMarks); TStandardText axisLabel; GetXAxisLabel(axisLabel); TTitleDrawer* xTitleDrawer = new TTitleDrawer(TTitleDrawer::kXAxisTitle, GetLabelDistanceFromAxis() * 3, axisLabel); GetYAxisLabel(axisLabel); TTitleDrawer* yTitleDrawer = new TTitleDrawer(TTitleDrawer::kYAxisTitle, GetLabelDistanceFromAxis() * 3, axisLabel); theGraph.AdoptDrawer(axisDrawer); theGraph.AdoptDrawer(xLabelDrawer); theGraph.AdoptDrawer(yLabelDrawer); theGraph.AdoptDrawer(yMarker); theGraph.AdoptDrawer(xMarker); theGraph.AdoptDrawer(xTitleDrawer); theGraph.AdoptDrawer(yTitleDrawer); } void TStockGraphConstructor::HandleAddExtendedDrawers( TStandardGraph& theGraph, const TCollectionOf& data, const TGraphRange& xRange, const TGraphRange& yRange) { // does nothing } const TStandardText& TStockGraphConstructor::GetDescription() const { return fDescription; } void TStockGraphConstructor::SetDescription(const TStandardText& newDescription) { fDescription = newDescription; } void TStockGraphConstructor::GetXAxisLabel(TStandardText& label) const { label = fXAxisLabel; } void TStockGraphConstructor::GetYAxisLabel(TStandardText& label) const { label = fYAxisLabel; } GraphValue TStockGraphConstructor::GetLabelDistanceFromAxis() const { return fLabelDistanceFromAxis; } GraphValue TStockGraphConstructor::GetXLabelInterval() const { return fXLabelInterval; } GraphValue TStockGraphConstructor::GetLabelPointSize() const { return fLabelPointSize; } GraphValue TStockGraphConstructor::GetMarkLength() const { return fMarkLength; } GraphValue TStockGraphConstructor::GetXMarkInterval() const { return fXMarkInterval; } GraphValue TStockGraphConstructor::GetXAxisLocation() const { return fXAxisLocation; } unsigned short TStockGraphConstructor::GetNumberOfYMarks() const { return fNumberOfYMarks; } GCoordinate TStockGraphConstructor::GetDrawerWidth() const { return fDrawerWidth; } void TStockGraphConstructor::SetXAxisLabel(const TStandardText& label) { fXAxisLabel = label; } void TStockGraphConstructor::SetYAxisLabel(const TStandardText& label) { fYAxisLabel = label; } void TStockGraphConstructor::SetLabelDistanceFromAxis(GraphValue distFromAxis) { fLabelDistanceFromAxis = distFromAxis; } void TStockGraphConstructor::SetXLabelInterval(GraphValue interval) { fXLabelInterval = interval; } void TStockGraphConstructor::SetLabelPointSize(GraphValue size) { fLabelPointSize = size; } void TStockGraphConstructor::SetMarkLength(GraphValue markLength) { fMarkLength = markLength; } void TStockGraphConstructor::SetXMarkInterval(GraphValue interval) { fXMarkInterval = interval; } void TStockGraphConstructor::SetXAxisLocation(GraphValue xAxisLocation) { fXAxisLocation = xAxisLocation; } void TStockGraphConstructor::SetNumberOfYMarks(unsigned short numberOfYMarks) { fNumberOfYMarks = numberOfYMarks; } void TStockGraphConstructor::SetDrawerWidth(GCoordinate width) { fDrawerWidth = width; } void TStockGraphConstructor::AdjustRange(TGraphRange& theRange, GraphValue numberOfDivisions) const { ::Assertion(numberOfDivisions > 0, "The number of division must be greater than zero."); double min = theRange.GetMin(); double max = theRange.GetMax(); ::Assertion(min >= 0.0 && max > min, "This algorithm doesn't work for empty ranges or ranges starting " "below zero."); double chunk = (max - min) / numberOfDivisions; double multiplier = Power(10, Floor(Log10(chunk))); double roundedChunk = Ceiling(chunk / multiplier) * multiplier; long roundedChunkAsLong = (long)roundedChunk; long minAsLong = (long)min; long maxAsLong = (long)max; minAsLong -= minAsLong % roundedChunkAsLong; maxAsLong += roundedChunkAsLong - (maxAsLong % roundedChunkAsLong); theRange.SetMinAndMax((double)minAsLong, (double)maxAsLong); }