summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure4
-rwxr-xr-xconfigure.in4
-rw-r--r--src/bltGrElemBar.C74
-rw-r--r--src/bltGraph.C363
-rw-r--r--src/bltGraph.h42
-rw-r--r--src/bltGraphBar.C334
-rw-r--r--src/bltGraphBar.h110
-rw-r--r--src/bltGraphLine.C277
-rw-r--r--src/bltGraphLine.h77
-rw-r--r--src/bltGraphOp.C7
10 files changed, 890 insertions, 402 deletions
diff --git a/configure b/configure
index f788081..a22d204 100755
--- a/configure
+++ b/configure
@@ -5557,8 +5557,10 @@ done
bltGrPenLine.C
bltGrPs.C
bltGraph.C
- bltGraphSup.C
+ bltGraphBar.C
+ bltGraphLine.C
bltGraphOp.C
+ bltGraphSup.C
bltInt.C
bltList.C
bltNsUtil.C
diff --git a/configure.in b/configure.in
index 16029d7..17b3d99 100755
--- a/configure.in
+++ b/configure.in
@@ -102,8 +102,10 @@ TEA_ADD_SOURCES([
bltGrPenLine.C
bltGrPs.C
bltGraph.C
- bltGraphSup.C
+ bltGraphBar.C
+ bltGraphLine.C
bltGraphOp.C
+ bltGraphSup.C
bltInt.C
bltList.C
bltNsUtil.C
diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C
index d755566..ea193db 100644
--- a/src/bltGrElemBar.C
+++ b/src/bltGrElemBar.C
@@ -31,6 +31,7 @@
extern "C" {
#include "bltInt.h"
+#include "bltGraphBar.h"
};
#include "bltGrElemBar.h"
@@ -257,8 +258,9 @@ int BarElement::configure()
void BarElement::map()
{
+ BarGraph* barGraphPtr_ = (BarGraph*)graphPtr_;
BarElementOptions* ops = (BarElementOptions*)ops_;
- GraphOptions* gops = (GraphOptions*)graphPtr_->ops_;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
if (!link)
return;
@@ -308,7 +310,7 @@ void BarElement::map()
* coordinates of the two corners.
*/
- if ((graphPtr_->nBarGroups_ > 0) && (gops->barMode != BARS_INFRONT) &&
+ if ((barGraphPtr_->nBarGroups_ > 0) && (gops->barMode != BARS_INFRONT) &&
(!gops->stackAxes)) {
Tcl_HashEntry *hPtr;
BarSetKey key;
@@ -316,7 +318,7 @@ void BarElement::map()
key.value = (float)x[i];
key.axes = ops->axes;
key.axes.y = NULL;
- hPtr = Tcl_FindHashEntry(&graphPtr_->setTable_, (char *)&key);
+ hPtr = Tcl_FindHashEntry(&barGraphPtr_->setTable_, (char *)&key);
if (hPtr) {
Tcl_HashTable *tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
@@ -327,9 +329,9 @@ void BarElement::map()
double slice, width, offset;
BarGroup *groupPtr = (BarGroup*)Tcl_GetHashValue(hPtr);
- slice = barWidth / (double)graphPtr_->maxBarSetSize_;
+ slice = barWidth / (double)barGraphPtr_->maxBarSetSize_;
offset = (slice * groupPtr->index);
- if (graphPtr_->maxBarSetSize_ > 1) {
+ if (barGraphPtr_->maxBarSetSize_ > 1) {
offset += slice * 0.05;
slice *= 0.90;
}
@@ -483,8 +485,9 @@ void BarElement::map()
void BarElement::extents(Region2d *regPtr)
{
+ BarGraph* barGraphPtr_ = (BarGraph*)graphPtr_;
BarElementOptions* ops = (BarElementOptions*)ops_;
- GraphOptions* gops = (GraphOptions*)graphPtr_->ops_;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
regPtr->top = regPtr->left = DBL_MAX;
regPtr->bottom = regPtr->right = -DBL_MAX;
@@ -510,7 +513,7 @@ void BarElement::extents(Region2d *regPtr)
// Handle stacked bar elements specially.
// If element is stacked, the sum of its ordinates may be outside the
// minimum/maximum limits of the element's data points.
- if ((gops->barMode == BARS_STACKED) && (graphPtr_->nBarGroups_ > 0))
+ if ((gops->barMode == BARS_STACKED) && (barGraphPtr_->nBarGroups_ > 0))
CheckBarStacks(&ops->axes, &regPtr->top, &regPtr->bottom);
// Warning: You get what you deserve if the x-axis is logScale
@@ -614,7 +617,7 @@ void BarElement::extents(Region2d *regPtr)
void BarElement::closest()
{
BarElementOptions* ops = (BarElementOptions*)ops_;
- GraphOptions* gops = (GraphOptions*)graphPtr_->ops_;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
ClosestSearch* searchPtr = &gops->search;
double minDist = searchPtr->dist;
@@ -888,12 +891,13 @@ void BarElement::ResetStylePalette(Blt_Chain stylePalette)
void BarElement::CheckBarStacks(Axis2d *pairPtr, double *minPtr, double *maxPtr)
{
- GraphOptions* gops = (GraphOptions*)graphPtr_->ops_;
- if ((gops->barMode != BARS_STACKED) || (graphPtr_->nBarGroups_ == 0))
+ BarGraph* barGraphPtr_ = (BarGraph*)graphPtr_;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
+ if ((gops->barMode != BARS_STACKED) || barGraphPtr_->nBarGroups_ == 0)
return;
BarGroup *gp, *gend;
- for (gp = graphPtr_->barGroups_, gend = gp + graphPtr_->nBarGroups_; gp < gend;
+ for (gp = barGraphPtr_->barGroups_, gend = gp + barGraphPtr_->nBarGroups_; gp < gend;
gp++) {
if ((gp->axes.x == pairPtr->x) && (gp->axes.y == pairPtr->y)) {
@@ -1305,7 +1309,7 @@ void BarElement::DrawBarValues(Drawable drawable, BarPen* penPtr,
{
BarElementOptions* ops = (BarElementOptions*)ops_;
BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
- GraphOptions* gops = (GraphOptions*)graphPtr_->ops_;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
const char *fmt = penOps->valueFormat;
if (!fmt)
@@ -1393,7 +1397,7 @@ void BarElement::BarValuesToPostScript(Blt_Ps ps, BarPen* penPtr,
{
BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
BarElementOptions* ops = (BarElementOptions*)ops_;
- GraphOptions* gops = (GraphOptions*)graphPtr_->ops_;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
XRectangle *rp, *rend;
char string[TCL_DOUBLE_SPACE * 2 + 2];
@@ -1440,7 +1444,8 @@ void BarElement::BarValuesToPostScript(Blt_Ps ps, BarPen* penPtr,
void Blt_InitBarSetTable(Graph* graphPtr)
{
- GraphOptions* gops = (GraphOptions*)graphPtr->ops_;
+ BarGraph* barGraphPtr = (BarGraph*)graphPtr;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr->ops_;
Blt_ChainLink link;
int nStacks, nSegs;
Tcl_HashTable setTable;
@@ -1455,7 +1460,7 @@ void Blt_InitBarSetTable(Graph* graphPtr)
Blt_DestroyBarSets(graphPtr);
if (gops->barMode == BARS_INFRONT)
return;
- Tcl_InitHashTable(&graphPtr->setTable_, sizeof(BarSetKey) / sizeof(int));
+ Tcl_InitHashTable(&barGraphPtr->setTable_, sizeof(BarSetKey) / sizeof(int));
/*
* Initialize a hash table and fill it with unique abscissas. Keep track
@@ -1522,7 +1527,7 @@ void Blt_InitBarSetTable(Graph* graphPtr)
int isNew;
keyPtr = (BarSetKey *)Tcl_GetHashKey(&setTable, hPtr);
- hPtr2 = Tcl_CreateHashEntry(&graphPtr->setTable_, (char *)keyPtr,&isNew);
+ hPtr2 = Tcl_CreateHashEntry(&barGraphPtr->setTable_, (char *)keyPtr,&isNew);
Tcl_HashTable *tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
Tcl_SetHashValue(hPtr2, tablePtr);
if (max < tablePtr->numEntries) {
@@ -1535,9 +1540,9 @@ void Blt_InitBarSetTable(Graph* graphPtr)
Tcl_HashEntry *hPtr;
Tcl_HashSearch iter;
- graphPtr->barGroups_ = (BarGroup*)calloc(sum, sizeof(BarGroup));
- BarGroup* groupPtr = graphPtr->barGroups_;
- for (hPtr = Tcl_FirstHashEntry(&graphPtr->setTable_, &iter);
+ barGraphPtr->barGroups_ = (BarGroup*)calloc(sum, sizeof(BarGroup));
+ BarGroup* groupPtr = barGraphPtr->barGroups_;
+ for (hPtr = Tcl_FirstHashEntry(&barGraphPtr->setTable_, &iter);
hPtr; hPtr = Tcl_NextHashEntry(&iter)) {
BarSetKey *keyPtr;
Tcl_HashEntry *hPtr2;
@@ -1560,22 +1565,23 @@ void Blt_InitBarSetTable(Graph* graphPtr)
}
}
}
- graphPtr->maxBarSetSize_ = max;
- graphPtr->nBarGroups_ = sum;
+ barGraphPtr->maxBarSetSize_ = max;
+ barGraphPtr->nBarGroups_ = sum;
}
void Blt_ComputeBarStacks(Graph* graphPtr)
{
- GraphOptions* gops = (GraphOptions*)graphPtr->ops_;
+ BarGraph* barGraphPtr = (BarGraph*)graphPtr;
+ BarGraphOptions* gops = (BarGraphOptions*)graphPtr->ops_;
Blt_ChainLink link;
- if ((gops->barMode != BARS_STACKED) || (graphPtr->nBarGroups_ == 0))
+ if ((gops->barMode != BARS_STACKED) || (barGraphPtr->nBarGroups_ == 0))
return;
/* Initialize the stack sums to zero. */
{
BarGroup *gp, *gend;
- for (gp = graphPtr->barGroups_, gend = gp + graphPtr->nBarGroups_;
+ for (gp = barGraphPtr->barGroups_, gend = gp + barGraphPtr->nBarGroups_;
gp < gend; gp++) {
gp->sum = 0.0;
}
@@ -1603,7 +1609,7 @@ void Blt_ComputeBarStacks(Graph* graphPtr)
key.value = *x;
key.axes = ops->axes;
key.axes.y = NULL;
- hPtr = Tcl_FindHashEntry(&graphPtr->setTable_, (char *)&key);
+ hPtr = Tcl_FindHashEntry(&barGraphPtr->setTable_, (char *)&key);
if (!hPtr)
continue;
@@ -1622,9 +1628,10 @@ void Blt_ComputeBarStacks(Graph* graphPtr)
void Blt_ResetBarGroups(Graph* graphPtr)
{
+ BarGraph* barGraphPtr = (BarGraph*)graphPtr;
BarGroup* gp;
BarGroup* gend;
- for (gp = graphPtr->barGroups_, gend = gp + graphPtr->nBarGroups_; gp < gend;
+ for (gp = barGraphPtr->barGroups_, gend = gp + barGraphPtr->nBarGroups_; gp < gend;
gp++) {
gp->lastY = 0.0;
gp->count = 0;
@@ -1633,19 +1640,20 @@ void Blt_ResetBarGroups(Graph* graphPtr)
void Blt_DestroyBarSets(Graph* graphPtr)
{
- if (graphPtr->barGroups_) {
- free(graphPtr->barGroups_);
- graphPtr->barGroups_ = NULL;
+ BarGraph* barGraphPtr = (BarGraph*)graphPtr;
+ if (barGraphPtr->barGroups_) {
+ free(barGraphPtr->barGroups_);
+ barGraphPtr->barGroups_ = NULL;
}
- graphPtr->nBarGroups_ = 0;
+ barGraphPtr->nBarGroups_ = 0;
Tcl_HashSearch iter;
- for (Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&graphPtr->setTable_, &iter);
+ for (Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&barGraphPtr->setTable_, &iter);
hPtr; hPtr = Tcl_NextHashEntry(&iter)) {
Tcl_HashTable* tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
Tcl_DeleteHashTable(tablePtr);
free(tablePtr);
}
- Tcl_DeleteHashTable(&graphPtr->setTable_);
- Tcl_InitHashTable(&graphPtr->setTable_, sizeof(BarSetKey) / sizeof(int));
+ Tcl_DeleteHashTable(&barGraphPtr->setTable_);
+ Tcl_InitHashTable(&barGraphPtr->setTable_, sizeof(BarSetKey) / sizeof(int));
}
diff --git a/src/bltGraph.C b/src/bltGraph.C
index 7c65b39..463c2e6 100644
--- a/src/bltGraph.C
+++ b/src/bltGraph.C
@@ -66,140 +66,8 @@ static Blt_BindPickProc PickEntry;
// OptionSpecs
-static const char* barmodeObjOption[] =
- {"normal", "stacked", "aligned", "overlap", NULL};
-const char* searchModeObjOption[] = {"points", "traces", "auto", NULL};
-const char* searchAlongObjOption[] = {"x", "y", "both", NULL};
-
-static Tk_OptionSpec optionSpecs[] = {
- {TK_OPTION_DOUBLE, "-aspect", "aspect", "Aspect",
- "0", -1, Tk_Offset(GraphOptions, aspect),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_BORDER, "-background", "background", "Background",
- STD_NORMAL_BACKGROUND, -1, Tk_Offset(GraphOptions, normalBg),
- 0, NULL, CACHE_DIRTY},
- {TK_OPTION_STRING_TABLE, "-barmode", "barMode", "BarMode",
- "normal", -1, Tk_Offset(GraphOptions, barMode),
- 0, &barmodeObjOption, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_DOUBLE, "-barwidth", "barWidth", "BarWidth",
- ".9", -1, Tk_Offset(GraphOptions, barWidth),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_DOUBLE, "-baseline", "baseline", "Baseline",
- "0", -1, Tk_Offset(GraphOptions, baseline), 0, NULL, 0},
- {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, -1, 0, 0, "-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, -1, 0, 0, "-background", 0},
- {TK_OPTION_SYNONYM, "-bm", NULL, NULL, NULL, -1, 0, 0, "-bottommargin", 0},
- {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- STD_BORDERWIDTH, -1, Tk_Offset(GraphOptions, borderWidth), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-bottommargin", "bottomMargin", "BottomMargin",
- "0", -1, Tk_Offset(GraphOptions, bottomMargin.reqSize), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_STRING, "-bottomvariable", "bottomVariable", "BottomVariable",
- NULL, -1, Tk_Offset(GraphOptions, bottomMargin.varName),
- TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_BOOLEAN, "-bufferelements", "bufferElements", "BufferElements",
- "yes", -1, Tk_Offset(GraphOptions, backingStore), 0, NULL, 0},
- {TK_OPTION_BOOLEAN, "-buffergraph", "bufferGraph", "BufferGraph",
- "yes", -1, Tk_Offset(GraphOptions, doubleBuffer), 0, NULL, 0},
- {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
- "crosshair", -1, Tk_Offset(GraphOptions, cursor),
- TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
- {TK_OPTION_FONT, "-font", "font", "Font",
- STD_FONT_MEDIUM, -1, Tk_Offset(GraphOptions, titleTextStyle.font), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
- STD_NORMAL_FOREGROUND, -1, Tk_Offset(GraphOptions, titleTextStyle.color),
- 0, NULL,
- CACHE_DIRTY},
- {TK_OPTION_SYNONYM, "-halo", NULL, NULL, NULL, -1, 0, 0, "-searchhalo", 0},
- {TK_OPTION_PIXELS, "-height", "height", "Height",
- "4i", -1, Tk_Offset(GraphOptions, reqHeight),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
- "HighlightBackground",
- STD_NORMAL_BACKGROUND, -1, Tk_Offset(GraphOptions, highlightBgColor),
- 0, NULL,
- CACHE_DIRTY},
- {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
- STD_NORMAL_FOREGROUND, -1, Tk_Offset(GraphOptions, highlightColor),
- 0, NULL, 0},
- {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness",
- "2", -1, Tk_Offset(GraphOptions, highlightWidth), 0, NULL, 0},
- {TK_OPTION_BOOLEAN, "-invertxy", "invertXY", "InvertXY",
- "no", -1, Tk_Offset(GraphOptions, inverted), 0, NULL,
- RESET_WORLD | CACHE_DIRTY | RESET_AXES},
- {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
- "center", -1, Tk_Offset(GraphOptions, titleTextStyle.justify), 0, NULL, 0},
- {TK_OPTION_PIXELS, "-leftmargin", "leftMargin", "Margin",
- "0", -1, Tk_Offset(GraphOptions, leftMargin.reqSize), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_STRING, "-leftvariable", "leftVariable", "LeftVariable",
- NULL, -1, Tk_Offset(GraphOptions, leftMargin.varName),
- TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_SYNONYM, "-lm", NULL, NULL, NULL, -1, 0, 0, "-leftmargin", 0},
- {TK_OPTION_BORDER, "-plotbackground", "plotbackground", "PlotBackground",
- STD_NORMAL_BACKGROUND, -1, Tk_Offset(GraphOptions, plotBg), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-plotborderwidth", "plotBorderWidth", "PlotBorderWidth",
- STD_BORDERWIDTH, -1, Tk_Offset(GraphOptions, plotBW), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-plotpadx", "plotPadX", "PlotPad",
- "0", -1, Tk_Offset(GraphOptions, xPad), 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-plotpady", "plotPadY", "PlotPad",
- "0", -1, Tk_Offset(GraphOptions, yPad), 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_RELIEF, "-plotrelief", "plotRelief", "Relief",
- "flat", -1, Tk_Offset(GraphOptions, plotRelief), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- "flat", -1, Tk_Offset(GraphOptions, relief), 0, NULL, 0},
- {TK_OPTION_PIXELS, "-rightmargin", "rightMargin", "Margin",
- "0", -1, Tk_Offset(GraphOptions, rightMargin.reqSize), 0, NULL,
- RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_STRING, "-rightvariable", "rightVariable", "RightVariable",
- NULL, -1, Tk_Offset(GraphOptions, rightMargin.varName),
- TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_SYNONYM, "-rm", NULL, NULL, NULL, -1, 0, 0, "-rightmargin", 0},
- {TK_OPTION_PIXELS, "-searchhalo", "searchhalo", "SearchHalo",
- "2m", -1, Tk_Offset(GraphOptions, search.halo), 0, NULL, 0},
- {TK_OPTION_STRING_TABLE, "-searchmode", "searchMode", "SearchMode",
- "points", -1, Tk_Offset(GraphOptions, search.mode),
- 0, &searchModeObjOption, 0},
- {TK_OPTION_STRING_TABLE, "-searchalong", "searchAlong", "SearchAlong",
- "both", -1, Tk_Offset(GraphOptions, search.along),
- 0, &searchAlongObjOption, 0},
- {TK_OPTION_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes",
- "no", -1, Tk_Offset(GraphOptions, stackAxes), 0, NULL, 0},
- {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
- NULL, -1, Tk_Offset(GraphOptions, takeFocus), TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_STRING, "-title", "title", "Title",
- NULL, -1, Tk_Offset(GraphOptions, title),
- TK_OPTION_NULL_OK, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_SYNONYM, "-tm", NULL, NULL, NULL, -1, 0, 0, "-topmargin", 0},
- {TK_OPTION_PIXELS, "-topmargin", "topMargin", "TopMargin",
- "0", -1, Tk_Offset(GraphOptions, topMargin.reqSize),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_STRING, "-topvariable", "topVariable", "TopVariable",
- NULL, -1, Tk_Offset(GraphOptions, topMargin.varName),
- TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_PIXELS, "-width", "width", "Width",
- "5i", -1, Tk_Offset(GraphOptions, reqWidth),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-plotwidth", "plotWidth", "PlotWidth",
- "0", -1, Tk_Offset(GraphOptions, reqPlotWidth),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-plotheight", "plotHeight", "PlotHeight",
- "0", -1, Tk_Offset(GraphOptions, reqPlotHeight),
- 0, NULL, RESET_WORLD | CACHE_DIRTY},
- {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
-};
-
-// Create
-
Graph::Graph(ClientData clientData, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[], ClassId classId)
+ int objc, Tcl_Obj* const objv[])
{
valid_ =1;
interp_ = interp;
@@ -215,22 +83,7 @@ Graph::Graph(ClientData clientData, Tcl_Interp* interp,
cmdToken_ = Tcl_CreateObjCommand(interp_, Tk_PathName(tkwin_),
GraphInstCmdProc, this,
GraphInstCmdDeleteProc);
- optionTable_ = Tk_CreateOptionTable(interp_, optionSpecs);
- ops_ = (GraphOptions*)calloc(1, sizeof(GraphOptions));
- GraphOptions* ops = (GraphOptions*)ops_;
- switch (classId) {
- case CID_ELEM_LINE:
- Tk_SetClass(tkwin_, "Graph");
- break;
- case CID_ELEM_BAR:
- Tk_SetClass(tkwin_, "Barchart");
- break;
- default:
- break;
- }
-
- classId_ = classId;
flags = MAP_WORLD | REDRAW_WORLD;
nextMarkerId_ = 1;
@@ -261,18 +114,6 @@ Graph::Graph(ClientData clientData, Tcl_Interp* interp,
cacheWidth_ =0;
cacheHeight_ =0;
- barGroups_ =NULL;
- nBarGroups_ =0;
- maxBarSetSize_ =0;
-
- ops->bottomMargin.site = MARGIN_BOTTOM;
- ops->leftMargin.site = MARGIN_LEFT;
- ops->topMargin.site = MARGIN_TOP;
- ops->rightMargin.site = MARGIN_RIGHT;
-
- Blt_Ts_InitStyle(ops->titleTextStyle);
- ops->titleTextStyle.anchor = TK_ANCHOR_N;
-
Tcl_InitHashTable(&axes_.table, TCL_STRING_KEYS);
Tcl_InitHashTable(&axes_.tagTable, TCL_STRING_KEYS);
Tcl_InitHashTable(&elements_.table, TCL_STRING_KEYS);
@@ -280,7 +121,7 @@ Graph::Graph(ClientData clientData, Tcl_Interp* interp,
Tcl_InitHashTable(&markers_.table, TCL_STRING_KEYS);
Tcl_InitHashTable(&markers_.tagTable, TCL_STRING_KEYS);
Tcl_InitHashTable(&penTable_, TCL_STRING_KEYS);
- Tcl_InitHashTable(&setTable_, sizeof(BarSetKey) / sizeof(int));
+
axes_.displayList = Blt_Chain_Create();
elements_.displayList = Blt_Chain_Create();
markers_.displayList = Blt_Chain_Create();
@@ -292,28 +133,6 @@ Graph::Graph(ClientData clientData, Tcl_Interp* interp,
return;
}
- switch (classId) {
- case CID_ELEM_LINE:
- if (createPen("active", 0, NULL) != TCL_OK) {
- valid_ =0;
- return;
- }
- break;
- case CID_ELEM_BAR:
- if (createPen("active", 0, NULL) != TCL_OK) {
- valid_ =0;
- return;
- }
- break;
- default:
- break;
- }
-
- if (Blt_CreatePageSetup(this) != TCL_OK) {
- valid_ =0;
- return;
- }
-
// Keep a hold of the associated tkwin until we destroy the graph,
// otherwise Tk might free it while we still need it.
Tcl_Preserve(tkwin_);
@@ -321,15 +140,6 @@ Graph::Graph(ClientData clientData, Tcl_Interp* interp,
Tk_CreateEventHandler(tkwin_,
ExposureMask|StructureNotifyMask|FocusChangeMask,
GraphEventProc, this);
-
- if ((Tk_InitOptions(interp_, (char*)ops_, optionTable_, tkwin_) != TCL_OK) || (GraphObjConfigure(interp_, this, objc-2, objv+2) != TCL_OK)) {
- valid_ =0;
- return;
- }
-
- adjustAxes();
-
- Tcl_SetStringObj(Tcl_GetObjResult(interp_), Tk_PathName(tkwin_), -1);
}
Graph::~Graph()
@@ -347,7 +157,6 @@ Graph::~Graph()
destroyAxes();
destroyPens();
Blt_DestroyPageSetup(this);
- Blt_DestroyBarSets(this);
if (bindTable_)
Blt_DestroyBindingTable(bindTable_);
@@ -371,10 +180,6 @@ void Graph::configure()
{
GraphOptions* ops = (GraphOptions*)ops_;
- // Don't allow negative bar widths. Reset to an arbitrary value (0.1)
- if (ops->barWidth <= 0.0f)
- ops->barWidth = 0.8f;
-
inset_ = ops->borderWidth + ops->highlightWidth;
if ((ops->reqHeight != Tk_ReqHeight(tkwin_)) ||
(ops->reqWidth != Tk_ReqWidth(tkwin_)))
@@ -573,7 +378,7 @@ void Graph::drawPlot(Drawable drawable)
int Graph::print(const char *ident, Blt_Ps ps)
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
PageSetup *setupPtr = pageSetup_;
// We need to know how big a graph to print. If the graph hasn't been drawn
@@ -598,19 +403,19 @@ int Graph::print(const char *ident, Blt_Ps ps)
reconfigure();
map();
- int x = left_ - gops->plotBW;
- int y = top_ - gops->plotBW;
+ int x = left_ - ops->plotBW;
+ int y = top_ - ops->plotBW;
- int w = (right_ - left_ + 1) + (2*gops->plotBW);
- int h = (bottom_ - top_ + 1) + (2*gops->plotBW);
+ int w = (right_ - left_ + 1) + (2*ops->plotBW);
+ int h = (bottom_ - top_ + 1) + (2*ops->plotBW);
int result = PostScriptPreamble(this, ident, ps);
if (result != TCL_OK)
goto error;
- Blt_Ps_XSetFont(ps, gops->titleTextStyle.font);
+ Blt_Ps_XSetFont(ps, ops->titleTextStyle.font);
if (pageSetup_->decorations)
- Blt_Ps_XSetBackground(ps, Tk_3DBorderColor(gops->plotBg));
+ Blt_Ps_XSetBackground(ps, Tk_3DBorderColor(ops->plotBg));
else
Blt_Ps_SetClearBackground(ps);
@@ -764,7 +569,7 @@ void Graph::drawMargins(Drawable drawable)
void Graph::printMargins(Blt_Ps ps)
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
PageSetup *setupPtr = pageSetup_;
XRectangle margin[4];
@@ -781,7 +586,7 @@ void Graph::printMargins(Blt_Ps ps)
// Clear the surrounding margins and clip the plotting surface
if (setupPtr->decorations)
- Blt_Ps_XSetBackground(ps, Tk_3DBorderColor(gops->normalBg));
+ Blt_Ps_XSetBackground(ps, Tk_3DBorderColor(ops->normalBg));
else
Blt_Ps_SetClearBackground(ps);
@@ -789,18 +594,18 @@ void Graph::printMargins(Blt_Ps ps)
Blt_Ps_XFillRectangles(ps, margin, 4);
Blt_Ps_Append(ps, "% Interior 3D border\n");
- if (gops->plotBW > 0) {
- int x = left_ - gops->plotBW;
- int y = top_ - gops->plotBW;
- int w = (right_ - left_) + (2*gops->plotBW);
- int h = (bottom_ - top_) + (2*gops->plotBW);
- Blt_Ps_Draw3DRectangle(ps, gops->normalBg, (double)x, (double)y, w, h,
- gops->plotBW, gops->plotRelief);
+ if (ops->plotBW > 0) {
+ int x = left_ - ops->plotBW;
+ int y = top_ - ops->plotBW;
+ int w = (right_ - left_) + (2*ops->plotBW);
+ int h = (bottom_ - top_) + (2*ops->plotBW);
+ Blt_Ps_Draw3DRectangle(ps, ops->normalBg, (double)x, (double)y, w, h,
+ ops->plotBW, ops->plotRelief);
}
- if (gops->title) {
+ if (ops->title) {
Blt_Ps_Append(ps, "% Graph title\n");
- Blt_Ps_DrawText(ps, gops->title, &gops->titleTextStyle,
+ Blt_Ps_DrawText(ps, ops->title, &ops->titleTextStyle,
(double)titleX_, (double)titleY_);
}
}
@@ -840,44 +645,6 @@ void Graph::disableCrosshairs()
// Pens
-int Graph::createPen(const char* penName, int objc, Tcl_Obj* const objv[])
-{
- int isNew;
- Tcl_HashEntry *hPtr =
- Tcl_CreateHashEntry(&penTable_, penName, &isNew);
- if (!isNew) {
- Tcl_AppendResult(interp_, "pen \"", penName, "\" already exists in \"",
- Tk_PathName(tkwin_), "\"", (char *)NULL);
- return TCL_ERROR;
- }
-
- Pen* penPtr;
- switch (classId_) {
- case CID_ELEM_BAR:
- penPtr = new BarPen(this, penName, hPtr);
- break;
- case CID_ELEM_LINE:
- penPtr = new LinePen(this, penName, hPtr);
- break;
- default:
- return TCL_ERROR;
- }
- if (!penPtr)
- return TCL_ERROR;
-
- Tcl_SetHashValue(hPtr, penPtr);
-
- if ((Tk_InitOptions(interp_, (char*)penPtr->ops(), penPtr->optionTable(), tkwin_) != TCL_OK) || (PenObjConfigure(interp_, this, penPtr, objc-4, objv+4) != TCL_OK)) {
- delete penPtr;
- return TCL_ERROR;
- }
-
- flags |= CACHE_DIRTY;
- eventuallyRedraw();
-
- return TCL_OK;
-}
-
void Graph::destroyPens()
{
Tcl_HashSearch iter;
@@ -910,51 +677,6 @@ int Graph::getPen(Tcl_Obj* objPtr, Pen** penPtrPtr)
// Elements
-int Graph::createElement(int objc, Tcl_Obj* const objv[])
-{
- char *name = Tcl_GetString(objv[3]);
- if (name[0] == '-') {
- Tcl_AppendResult(interp_, "name of element \"", name,
- "\" can't start with a '-'", NULL);
- return TCL_ERROR;
- }
-
- int isNew;
- Tcl_HashEntry* hPtr =
- Tcl_CreateHashEntry(&elements_.table, name, &isNew);
- if (!isNew) {
- Tcl_AppendResult(interp_, "element \"", name,
- "\" already exists in \"", Tcl_GetString(objv[0]),
- "\"", NULL);
- return TCL_ERROR;
- }
-
- Element* elemPtr;
- switch (classId_) {
- case CID_ELEM_BAR:
- elemPtr = new BarElement(this, name, hPtr);
- break;
- case CID_ELEM_LINE:
- elemPtr = new LineElement(this, name, hPtr);
- break;
- default:
- return TCL_ERROR;
- }
- if (!elemPtr)
- return TCL_ERROR;
-
- Tcl_SetHashValue(hPtr, elemPtr);
-
- if ((Tk_InitOptions(interp_, (char*)elemPtr->ops(), elemPtr->optionTable(), tkwin_) != TCL_OK) || (ElementObjConfigure(interp_, elemPtr, objc-4, objv+4) != TCL_OK)) {
- delete elemPtr;
- return TCL_ERROR;
- }
-
- elemPtr->link = Blt_Chain_Append(elements_.displayList, elemPtr);
-
- return TCL_OK;
-}
-
void Graph::destroyElement(Element* elemPtr)
{
Blt_DeleteBindings(bindTable_, elemPtr);
@@ -991,10 +713,6 @@ void Graph::configureElements()
void Graph::mapElements()
{
- GraphOptions* gops = (GraphOptions*)ops_;
- if (gops->barMode != BARS_INFRONT)
- Blt_ResetBarGroups(this);
-
for (Blt_ChainLink link =Blt_Chain_FirstLink(elements_.displayList);
link; link = Blt_Chain_NextLink(link)) {
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
@@ -1292,28 +1010,28 @@ void Graph::configureAxes()
void Graph::mapAxes()
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
for (int ii=0; ii<4; ii++) {
int count =0;
int offset =0;
- Blt_Chain chain = gops->margins[ii].axes;
+ Blt_Chain chain = ops->margins[ii].axes;
for (Blt_ChainLink link=Blt_Chain_FirstLink(chain); link;
link = Blt_Chain_NextLink(link)) {
Axis *axisPtr = (Axis*)Blt_Chain_GetValue(link);
- AxisOptions* ops = (AxisOptions*)axisPtr->ops();
+ AxisOptions* aops = (AxisOptions*)axisPtr->ops();
if (!axisPtr->use_)
continue;
- if (ops->reqNumMajorTicks <= 0)
- ops->reqNumMajorTicks = 4;
+ if (aops->reqNumMajorTicks <= 0)
+ aops->reqNumMajorTicks = 4;
- if (gops->stackAxes)
+ if (ops->stackAxes)
axisPtr->mapStacked(count, ii);
else
axisPtr->map(offset, ii);
- if (ops->showGrid)
+ if (aops->showGrid)
axisPtr->mapGridlines();
offset += axisPtr->isHorizontal() ? axisPtr->height_ : axisPtr->width_;
@@ -1324,10 +1042,10 @@ void Graph::mapAxes()
void Graph::drawAxes(Drawable drawable)
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
for (int ii=0; ii<4; ii++) {
- for (Blt_ChainLink link = Blt_Chain_LastLink(gops->margins[ii].axes);
+ for (Blt_ChainLink link = Blt_Chain_LastLink(ops->margins[ii].axes);
link != NULL; link = Blt_Chain_PrevLink(link)) {
Axis *axisPtr = (Axis*)Blt_Chain_GetValue(link);
axisPtr->draw(drawable);
@@ -1347,10 +1065,10 @@ void Graph::drawAxesLimits(Drawable drawable)
void Graph::drawAxesGrids(Drawable drawable)
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
for (int ii=0; ii<4; ii++) {
- for (Blt_ChainLink link = Blt_Chain_FirstLink(gops->margins[ii].axes);
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->margins[ii].axes);
link; link = Blt_Chain_NextLink(link)) {
Axis *axisPtr = (Axis*)Blt_Chain_GetValue(link);
axisPtr->drawGrids(drawable);
@@ -1360,10 +1078,10 @@ void Graph::drawAxesGrids(Drawable drawable)
void Graph::printAxes(Blt_Ps ps)
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
Margin *mp, *mend;
- for (mp = gops->margins, mend = mp + 4; mp < mend; mp++) {
+ for (mp = ops->margins, mend = mp + 4; mp < mend; mp++) {
for (Blt_ChainLink link=Blt_Chain_FirstLink(mp->axes); link;
link = Blt_Chain_NextLink(link)) {
Axis *axisPtr = (Axis*)Blt_Chain_GetValue(link);
@@ -1374,10 +1092,10 @@ void Graph::printAxes(Blt_Ps ps)
void Graph::printAxesGrids(Blt_Ps ps)
{
- GraphOptions* gops = (GraphOptions*)ops_;
+ GraphOptions* ops = (GraphOptions*)ops_;
for (int ii=0; ii<4; ii++) {
- for (Blt_ChainLink link=Blt_Chain_FirstLink(gops->margins[ii].axes);
+ for (Blt_ChainLink link=Blt_Chain_FirstLink(ops->margins[ii].axes);
link; link = Blt_Chain_NextLink(link)) {
Axis *axisPtr = (Axis*)Blt_Chain_GetValue(link);
axisPtr->printGrids(ps);
@@ -1472,17 +1190,6 @@ Point2d Graph::invMap2D(double x, double y, Axis2d* axesPtr)
void Graph::resetAxes()
{
- GraphOptions* gops = (GraphOptions*)ops_;
-
- /* FIXME: This should be called whenever the display list of
- * elements change. Maybe yet another flag INIT_STACKS to
- * indicate that the element display list has changed.
- * Needs to be done before the axis limits are set.
- */
- Blt_InitBarSetTable(this);
- if ((gops->barMode == BARS_STACKED) && (nBarGroups_ > 0))
- Blt_ComputeBarStacks(this);
-
/*
* Step 1: Reset all axes. Initialize the data limits of the axis to
* impossible values.
diff --git a/src/bltGraph.h b/src/bltGraph.h
index f2de09b..326c5f0 100644
--- a/src/bltGraph.h
+++ b/src/bltGraph.h
@@ -67,24 +67,6 @@ typedef struct {
} ClosestSearch;
typedef struct {
- int nSegments;
- Axis2d axes;
- float sum;
- int count;
- float lastY;
- size_t index;
-} BarGroup;
-
-typedef struct {
- float value;
- Axis2d axes;
-} BarSetKey;
-
-typedef enum {
- BARS_INFRONT, BARS_STACKED, BARS_ALIGNED, BARS_OVERLAP
-} BarMode;
-
-typedef struct {
short int width;
short int height;
short int axesOffset;
@@ -136,11 +118,6 @@ typedef struct {
int reqWidth;
int reqPlotWidth;
int reqPlotHeight;
-
- // bar graph
- BarMode barMode;
- double barWidth;
- double baseline;
} GraphOptions;
class Graph {
@@ -192,12 +169,6 @@ class Graph {
short int cacheWidth_;
short int cacheHeight_;
- // barchart specific information
- BarGroup *barGroups_;
- int nBarGroups_;
- Tcl_HashTable setTable_;
- int maxBarSetSize_;
-
protected:
void drawPlot(Drawable);
void layoutGraph();
@@ -211,7 +182,7 @@ class Graph {
void destroyElements();
void configureElements();
- void mapElements();
+ virtual void mapElements();
void drawElements(Drawable);
void drawActiveElements(Drawable);
void printElements(Blt_Ps);
@@ -234,11 +205,10 @@ class Graph {
void adjustAxes();
public:
- Graph(ClientData clientData, Tcl_Interp*interp,
- int objc, Tcl_Obj* const objv[], ClassId classId);
+ Graph(ClientData, Tcl_Interp*, int, Tcl_Obj* const []);
virtual ~Graph();
- void configure();
+ virtual void configure();
void map();
void draw();
void eventuallyRedraw();
@@ -257,19 +227,19 @@ class Graph {
ClientData axisTag(const char*);
Point2d map2D(double, double, Axis2d*);
Point2d invMap2D(double, double, Axis2d*);
- void resetAxes();
+ virtual void resetAxes();
Axis* nearestAxis(int, int);
ClientData markerTag(const char*);
Blt::Marker* nearestMarker(int, int, int);
int isElementHidden(Blt::Marker*);
- int createElement(int, Tcl_Obj* const []);
+ virtual int createElement(int, Tcl_Obj* const []) =0;
void destroyElement(Element*);
int getElement(Tcl_Obj*, Element**);
ClientData elementTag(const char*);
- int createPen(const char*, int, Tcl_Obj* const []);
+ virtual int createPen(const char*, int, Tcl_Obj* const []) =0;
int getPen(Tcl_Obj*, Pen**);
};
diff --git a/src/bltGraphBar.C b/src/bltGraphBar.C
new file mode 100644
index 0000000..39ab46b
--- /dev/null
+++ b/src/bltGraphBar.C
@@ -0,0 +1,334 @@
+/*
+ * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+ * This code has been modified under the terms listed below and is made
+ * available under the same terms.
+ */
+
+/*
+ * Copyright 1991-2004 George A Howlett.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+extern "C" {
+#include "bltGraphBar.h"
+}
+
+#include "bltGraphOp.h"
+
+#include "bltGrAxis.h"
+#include "bltGrAxisOp.h"
+#include "bltGrXAxisOp.h"
+#include "bltGrPen.h"
+#include "bltGrPenBar.h"
+#include "bltGrPenLine.h"
+#include "bltGrPenOp.h"
+#include "bltGrElem.h"
+#include "bltGrElemBar.h"
+#include "bltGrElemLine.h"
+#include "bltGrElemOp.h"
+#include "bltGrMarker.h"
+#include "bltGrMarkerOp.h"
+#include "bltGrLegd.h"
+#include "bltGrLegdOp.h"
+#include "bltGrHairs.h"
+#include "bltGrHairsOp.h"
+#include "bltGrDef.h"
+
+using namespace Blt;
+
+static const char* barmodeObjOption[] =
+ {"normal", "stacked", "aligned", "overlap", NULL};
+static const char* searchModeObjOption[] = {"points", "traces", "auto", NULL};
+static const char* searchAlongObjOption[] = {"x", "y", "both", NULL};
+
+static Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_DOUBLE, "-aspect", "aspect", "Aspect",
+ "0", -1, Tk_Offset(BarGraphOptions, aspect),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_BORDER, "-background", "background", "Background",
+ STD_NORMAL_BACKGROUND, -1, Tk_Offset(BarGraphOptions, normalBg),
+ 0, NULL, CACHE_DIRTY},
+ {TK_OPTION_STRING_TABLE, "-barmode", "barMode", "BarMode",
+ "normal", -1, Tk_Offset(BarGraphOptions, barMode),
+ 0, &barmodeObjOption, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_DOUBLE, "-barwidth", "barWidth", "BarWidth",
+ ".9", -1, Tk_Offset(BarGraphOptions, barWidth),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_DOUBLE, "-baseline", "baseline", "Baseline",
+ "0", -1, Tk_Offset(BarGraphOptions, baseline), 0, NULL, 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, -1, 0, 0, "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, -1, 0, 0, "-background", 0},
+ {TK_OPTION_SYNONYM, "-bm", NULL, NULL, NULL, -1, 0, 0, "-bottommargin", 0},
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
+ STD_BORDERWIDTH, -1, Tk_Offset(BarGraphOptions, borderWidth), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-bottommargin", "bottomMargin", "BottomMargin",
+ "0", -1, Tk_Offset(BarGraphOptions, bottomMargin.reqSize), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-bottomvariable", "bottomVariable", "BottomVariable",
+ NULL, -1, Tk_Offset(BarGraphOptions, bottomMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_BOOLEAN, "-bufferelements", "bufferElements", "BufferElements",
+ "yes", -1, Tk_Offset(BarGraphOptions, backingStore), 0, NULL, 0},
+ {TK_OPTION_BOOLEAN, "-buffergraph", "bufferGraph", "BufferGraph",
+ "yes", -1, Tk_Offset(BarGraphOptions, doubleBuffer), 0, NULL, 0},
+ {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
+ "crosshair", -1, Tk_Offset(BarGraphOptions, cursor),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ STD_FONT_MEDIUM, -1, Tk_Offset(BarGraphOptions, titleTextStyle.font),
+ 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
+ STD_NORMAL_FOREGROUND, -1, Tk_Offset(BarGraphOptions, titleTextStyle.color),
+ 0, NULL,
+ CACHE_DIRTY},
+ {TK_OPTION_SYNONYM, "-halo", NULL, NULL, NULL, -1, 0, 0, "-searchhalo", 0},
+ {TK_OPTION_PIXELS, "-height", "height", "Height",
+ "4i", -1, Tk_Offset(BarGraphOptions, reqHeight),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
+ "HighlightBackground",
+ STD_NORMAL_BACKGROUND, -1, Tk_Offset(BarGraphOptions, highlightBgColor),
+ 0, NULL,
+ CACHE_DIRTY},
+ {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
+ STD_NORMAL_FOREGROUND, -1, Tk_Offset(BarGraphOptions, highlightColor),
+ 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
+ "HighlightThickness",
+ "2", -1, Tk_Offset(BarGraphOptions, highlightWidth), 0, NULL, 0},
+ {TK_OPTION_BOOLEAN, "-invertxy", "invertXY", "InvertXY",
+ "no", -1, Tk_Offset(BarGraphOptions, inverted), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY | RESET_AXES},
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ "center", -1, Tk_Offset(BarGraphOptions, titleTextStyle.justify),
+ 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-leftmargin", "leftMargin", "Margin",
+ "0", -1, Tk_Offset(BarGraphOptions, leftMargin.reqSize), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-leftvariable", "leftVariable", "LeftVariable",
+ NULL, -1, Tk_Offset(BarGraphOptions, leftMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, "-lm", NULL, NULL, NULL, -1, 0, 0, "-leftmargin", 0},
+ {TK_OPTION_BORDER, "-plotbackground", "plotbackground", "PlotBackground",
+ STD_NORMAL_BACKGROUND, -1, Tk_Offset(BarGraphOptions, plotBg), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotborderwidth", "plotBorderWidth", "PlotBorderWidth",
+ STD_BORDERWIDTH, -1, Tk_Offset(BarGraphOptions, plotBW), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotpadx", "plotPadX", "PlotPad",
+ "0", -1, Tk_Offset(BarGraphOptions, xPad),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotpady", "plotPadY", "PlotPad",
+ "0", -1, Tk_Offset(BarGraphOptions, yPad),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_RELIEF, "-plotrelief", "plotRelief", "Relief",
+ "flat", -1, Tk_Offset(BarGraphOptions, plotRelief), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
+ "flat", -1, Tk_Offset(BarGraphOptions, relief), 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-rightmargin", "rightMargin", "Margin",
+ "0", -1, Tk_Offset(BarGraphOptions, rightMargin.reqSize), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-rightvariable", "rightVariable", "RightVariable",
+ NULL, -1, Tk_Offset(BarGraphOptions, rightMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, "-rm", NULL, NULL, NULL, -1, 0, 0, "-rightmargin", 0},
+ {TK_OPTION_PIXELS, "-searchhalo", "searchhalo", "SearchHalo",
+ "2m", -1, Tk_Offset(BarGraphOptions, search.halo), 0, NULL, 0},
+ {TK_OPTION_STRING_TABLE, "-searchmode", "searchMode", "SearchMode",
+ "points", -1, Tk_Offset(BarGraphOptions, search.mode),
+ 0, &searchModeObjOption, 0},
+ {TK_OPTION_STRING_TABLE, "-searchalong", "searchAlong", "SearchAlong",
+ "both", -1, Tk_Offset(BarGraphOptions, search.along),
+ 0, &searchAlongObjOption, 0},
+ {TK_OPTION_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes",
+ "no", -1, Tk_Offset(BarGraphOptions, stackAxes), 0, NULL, 0},
+ {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
+ NULL, -1, Tk_Offset(BarGraphOptions, takeFocus), TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_STRING, "-title", "title", "Title",
+ NULL, -1, Tk_Offset(BarGraphOptions, title),
+ TK_OPTION_NULL_OK, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_SYNONYM, "-tm", NULL, NULL, NULL, -1, 0, 0, "-topmargin", 0},
+ {TK_OPTION_PIXELS, "-topmargin", "topMargin", "TopMargin",
+ "0", -1, Tk_Offset(BarGraphOptions, topMargin.reqSize),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-topvariable", "topVariable", "TopVariable",
+ NULL, -1, Tk_Offset(BarGraphOptions, topMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_PIXELS, "-width", "width", "Width",
+ "5i", -1, Tk_Offset(BarGraphOptions, reqWidth),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotwidth", "plotWidth", "PlotWidth",
+ "0", -1, Tk_Offset(BarGraphOptions, reqPlotWidth),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotheight", "plotHeight", "PlotHeight",
+ "0", -1, Tk_Offset(BarGraphOptions, reqPlotHeight),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
+};
+
+// Create
+
+BarGraph::BarGraph(ClientData clientData, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+ : Graph(clientData, interp, objc, objv)
+{
+ Tk_SetClass(tkwin_, "Barchart");
+ classId_ = CID_ELEM_BAR;
+
+ optionTable_ = Tk_CreateOptionTable(interp_, optionSpecs);
+ ops_ = (BarGraphOptions*)calloc(1, sizeof(BarGraphOptions));
+ BarGraphOptions* ops = (BarGraphOptions*)ops_;
+
+ barGroups_ =NULL;
+ nBarGroups_ =0;
+ maxBarSetSize_ =0;
+
+ Tcl_InitHashTable(&setTable_, sizeof(BarSetKey) / sizeof(int));
+
+ ops->bottomMargin.site = MARGIN_BOTTOM;
+ ops->leftMargin.site = MARGIN_LEFT;
+ ops->topMargin.site = MARGIN_TOP;
+ ops->rightMargin.site = MARGIN_RIGHT;
+
+ Blt_Ts_InitStyle(ops->titleTextStyle);
+ ops->titleTextStyle.anchor = TK_ANCHOR_N;
+
+ if (createPen("active", 0, NULL) != TCL_OK) {
+ valid_ =0;
+ return;
+ }
+
+ if ((Tk_InitOptions(interp_, (char*)ops_, optionTable_, tkwin_) != TCL_OK) || (GraphObjConfigure(interp_, this, objc-2, objv+2) != TCL_OK)) {
+ valid_ =0;
+ return;
+ }
+
+ adjustAxes();
+
+ Tcl_SetStringObj(Tcl_GetObjResult(interp_), Tk_PathName(tkwin_), -1);
+}
+
+BarGraph::~BarGraph()
+{
+ Blt_DestroyBarSets(this);
+}
+
+void BarGraph::configure()
+{
+ BarGraphOptions* ops = (BarGraphOptions*)ops_;
+ // Don't allow negative bar widths. Reset to an arbitrary value (0.1)
+ if (ops->barWidth <= 0.0f)
+ ops->barWidth = 0.8f;
+
+ Graph::configure();
+}
+
+int BarGraph::createPen(const char* penName, int objc, Tcl_Obj* const objv[])
+{
+ int isNew;
+ Tcl_HashEntry *hPtr =
+ Tcl_CreateHashEntry(&penTable_, penName, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp_, "pen \"", penName, "\" already exists in \"",
+ Tk_PathName(tkwin_), "\"", (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ Pen* penPtr = new BarPen(this, penName, hPtr);
+ if (!penPtr)
+ return TCL_ERROR;
+
+ Tcl_SetHashValue(hPtr, penPtr);
+
+ if ((Tk_InitOptions(interp_, (char*)penPtr->ops(), penPtr->optionTable(), tkwin_) != TCL_OK) || (PenObjConfigure(interp_, this, penPtr, objc-4, objv+4) != TCL_OK)) {
+ delete penPtr;
+ return TCL_ERROR;
+ }
+
+ flags |= CACHE_DIRTY;
+ eventuallyRedraw();
+
+ return TCL_OK;
+}
+
+int BarGraph::createElement(int objc, Tcl_Obj* const objv[])
+{
+ char *name = Tcl_GetString(objv[3]);
+ if (name[0] == '-') {
+ Tcl_AppendResult(interp_, "name of element \"", name,
+ "\" can't start with a '-'", NULL);
+ return TCL_ERROR;
+ }
+
+ int isNew;
+ Tcl_HashEntry* hPtr =
+ Tcl_CreateHashEntry(&elements_.table, name, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp_, "element \"", name,
+ "\" already exists in \"", Tcl_GetString(objv[0]),
+ "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ Element* elemPtr = new BarElement(this, name, hPtr);
+ if (!elemPtr)
+ return TCL_ERROR;
+
+ Tcl_SetHashValue(hPtr, elemPtr);
+
+ if ((Tk_InitOptions(interp_, (char*)elemPtr->ops(), elemPtr->optionTable(), tkwin_) != TCL_OK) || (ElementObjConfigure(interp_, elemPtr, objc-4, objv+4) != TCL_OK)) {
+ delete elemPtr;
+ return TCL_ERROR;
+ }
+
+ elemPtr->link = Blt_Chain_Append(elements_.displayList, elemPtr);
+
+ return TCL_OK;
+}
+
+void BarGraph::mapElements()
+{
+ BarGraphOptions* ops = (BarGraphOptions*)ops_;
+ if (ops->barMode != BARS_INFRONT)
+ Blt_ResetBarGroups(this);
+
+ Graph::mapElements();
+}
+
+void BarGraph::resetAxes()
+{
+ BarGraphOptions* ops = (BarGraphOptions*)ops_;
+
+ /* FIXME: This should be called whenever the display list of
+ * elements change. Maybe yet another flag INIT_STACKS to
+ * indicate that the element display list has changed.
+ * Needs to be done before the axis limits are set.
+ */
+ Blt_InitBarSetTable(this);
+ if ((ops->barMode == BARS_STACKED) && (nBarGroups_ > 0))
+ Blt_ComputeBarStacks(this);
+
+ Graph::resetAxes();
+}
diff --git a/src/bltGraphBar.h b/src/bltGraphBar.h
new file mode 100644
index 0000000..4caae15
--- /dev/null
+++ b/src/bltGraphBar.h
@@ -0,0 +1,110 @@
+/*
+ * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+ * This code has been modified under the terms listed below and is made
+ * available under the same terms.
+ */
+
+/*
+ * Copyright 1993-2004 George A Howlett.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __BltGraphBar_h__
+#define __BltGraphBar_h__
+
+extern "C" {
+#include "bltGraph.h"
+};
+
+typedef struct {
+ int nSegments;
+ Axis2d axes;
+ float sum;
+ int count;
+ float lastY;
+ size_t index;
+} BarGroup;
+
+typedef struct {
+ float value;
+ Axis2d axes;
+} BarSetKey;
+
+typedef enum {
+ BARS_INFRONT, BARS_STACKED, BARS_ALIGNED, BARS_OVERLAP
+} BarMode;
+
+typedef struct {
+ double aspect;
+ Tk_3DBorder normalBg;
+ int borderWidth;
+ Margin margins[4];
+ int backingStore;
+ int doubleBuffer;
+ Tk_Cursor cursor;
+ TextStyle titleTextStyle;
+ int reqHeight;
+ XColor* highlightBgColor;
+ XColor* highlightColor;
+ int highlightWidth;
+ int inverted;
+ Tk_3DBorder plotBg;
+ int plotBW;
+ int xPad;
+ int yPad;
+ int plotRelief;
+ int relief;
+ ClosestSearch search;
+ int stackAxes;
+ const char *takeFocus; // nor used in C code
+ const char *title;
+ int reqWidth;
+ int reqPlotWidth;
+ int reqPlotHeight;
+
+ // bar graph
+ BarMode barMode;
+ double barWidth;
+ double baseline;
+} BarGraphOptions;
+
+class BarGraph : public Graph {
+ public:
+ BarGroup *barGroups_;
+ int nBarGroups_;
+ Tcl_HashTable setTable_;
+ int maxBarSetSize_;
+
+ protected:
+ void resetAxes();
+ void mapElements();
+
+ public:
+ BarGraph(ClientData, Tcl_Interp*, int, Tcl_Obj* const []);
+ virtual ~BarGraph();
+
+ void configure();
+ int createPen(const char*, int, Tcl_Obj* const []);
+ int createElement(int, Tcl_Obj* const []);
+
+};
+
+#endif
diff --git a/src/bltGraphLine.C b/src/bltGraphLine.C
new file mode 100644
index 0000000..0480c71
--- /dev/null
+++ b/src/bltGraphLine.C
@@ -0,0 +1,277 @@
+/*
+ * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+ * This code has been modified under the terms listed below and is made
+ * available under the same terms.
+ */
+
+/*
+ * Copyright 1991-2004 George A Howlett.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+extern "C" {
+#include "bltGraphLine.h"
+}
+
+#include "bltGraphOp.h"
+
+#include "bltGrAxis.h"
+#include "bltGrAxisOp.h"
+#include "bltGrXAxisOp.h"
+#include "bltGrPen.h"
+#include "bltGrPenBar.h"
+#include "bltGrPenLine.h"
+#include "bltGrPenOp.h"
+#include "bltGrElem.h"
+#include "bltGrElemBar.h"
+#include "bltGrElemLine.h"
+#include "bltGrElemOp.h"
+#include "bltGrMarker.h"
+#include "bltGrMarkerOp.h"
+#include "bltGrLegd.h"
+#include "bltGrLegdOp.h"
+#include "bltGrHairs.h"
+#include "bltGrHairsOp.h"
+#include "bltGrDef.h"
+
+using namespace Blt;
+
+static const char* searchModeObjOption[] = {"points", "traces", "auto", NULL};
+static const char* searchAlongObjOption[] = {"x", "y", "both", NULL};
+
+static Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_DOUBLE, "-aspect", "aspect", "Aspect",
+ "0", -1, Tk_Offset(GraphOptions, aspect),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_BORDER, "-background", "background", "Background",
+ STD_NORMAL_BACKGROUND, -1, Tk_Offset(GraphOptions, normalBg),
+ 0, NULL, CACHE_DIRTY},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, -1, 0, 0, "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, -1, 0, 0, "-background", 0},
+ {TK_OPTION_SYNONYM, "-bm", NULL, NULL, NULL, -1, 0, 0, "-bottommargin", 0},
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
+ STD_BORDERWIDTH, -1, Tk_Offset(GraphOptions, borderWidth), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-bottommargin", "bottomMargin", "BottomMargin",
+ "0", -1, Tk_Offset(GraphOptions, bottomMargin.reqSize), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-bottomvariable", "bottomVariable", "BottomVariable",
+ NULL, -1, Tk_Offset(GraphOptions, bottomMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_BOOLEAN, "-bufferelements", "bufferElements", "BufferElements",
+ "yes", -1, Tk_Offset(GraphOptions, backingStore), 0, NULL, 0},
+ {TK_OPTION_BOOLEAN, "-buffergraph", "bufferGraph", "BufferGraph",
+ "yes", -1, Tk_Offset(GraphOptions, doubleBuffer), 0, NULL, 0},
+ {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
+ "crosshair", -1, Tk_Offset(GraphOptions, cursor),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ STD_FONT_MEDIUM, -1, Tk_Offset(GraphOptions, titleTextStyle.font), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
+ STD_NORMAL_FOREGROUND, -1, Tk_Offset(GraphOptions, titleTextStyle.color),
+ 0, NULL,
+ CACHE_DIRTY},
+ {TK_OPTION_SYNONYM, "-halo", NULL, NULL, NULL, -1, 0, 0, "-searchhalo", 0},
+ {TK_OPTION_PIXELS, "-height", "height", "Height",
+ "4i", -1, Tk_Offset(GraphOptions, reqHeight),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
+ "HighlightBackground",
+ STD_NORMAL_BACKGROUND, -1, Tk_Offset(GraphOptions, highlightBgColor),
+ 0, NULL,
+ CACHE_DIRTY},
+ {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
+ STD_NORMAL_FOREGROUND, -1, Tk_Offset(GraphOptions, highlightColor),
+ 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
+ "HighlightThickness",
+ "2", -1, Tk_Offset(GraphOptions, highlightWidth), 0, NULL, 0},
+ {TK_OPTION_BOOLEAN, "-invertxy", "invertXY", "InvertXY",
+ "no", -1, Tk_Offset(GraphOptions, inverted), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY | RESET_AXES},
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ "center", -1, Tk_Offset(GraphOptions, titleTextStyle.justify), 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-leftmargin", "leftMargin", "Margin",
+ "0", -1, Tk_Offset(GraphOptions, leftMargin.reqSize), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-leftvariable", "leftVariable", "LeftVariable",
+ NULL, -1, Tk_Offset(GraphOptions, leftMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, "-lm", NULL, NULL, NULL, -1, 0, 0, "-leftmargin", 0},
+ {TK_OPTION_BORDER, "-plotbackground", "plotbackground", "PlotBackground",
+ STD_NORMAL_BACKGROUND, -1, Tk_Offset(GraphOptions, plotBg), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotborderwidth", "plotBorderWidth", "PlotBorderWidth",
+ STD_BORDERWIDTH, -1, Tk_Offset(GraphOptions, plotBW), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotpadx", "plotPadX", "PlotPad",
+ "0", -1, Tk_Offset(GraphOptions, xPad), 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotpady", "plotPadY", "PlotPad",
+ "0", -1, Tk_Offset(GraphOptions, yPad), 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_RELIEF, "-plotrelief", "plotRelief", "Relief",
+ "flat", -1, Tk_Offset(GraphOptions, plotRelief), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
+ "flat", -1, Tk_Offset(GraphOptions, relief), 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-rightmargin", "rightMargin", "Margin",
+ "0", -1, Tk_Offset(GraphOptions, rightMargin.reqSize), 0, NULL,
+ RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-rightvariable", "rightVariable", "RightVariable",
+ NULL, -1, Tk_Offset(GraphOptions, rightMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_SYNONYM, "-rm", NULL, NULL, NULL, -1, 0, 0, "-rightmargin", 0},
+ {TK_OPTION_PIXELS, "-searchhalo", "searchhalo", "SearchHalo",
+ "2m", -1, Tk_Offset(GraphOptions, search.halo), 0, NULL, 0},
+ {TK_OPTION_STRING_TABLE, "-searchmode", "searchMode", "SearchMode",
+ "points", -1, Tk_Offset(GraphOptions, search.mode),
+ 0, &searchModeObjOption, 0},
+ {TK_OPTION_STRING_TABLE, "-searchalong", "searchAlong", "SearchAlong",
+ "both", -1, Tk_Offset(GraphOptions, search.along),
+ 0, &searchAlongObjOption, 0},
+ {TK_OPTION_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes",
+ "no", -1, Tk_Offset(GraphOptions, stackAxes), 0, NULL, 0},
+ {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
+ NULL, -1, Tk_Offset(GraphOptions, takeFocus), TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_STRING, "-title", "title", "Title",
+ NULL, -1, Tk_Offset(GraphOptions, title),
+ TK_OPTION_NULL_OK, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_SYNONYM, "-tm", NULL, NULL, NULL, -1, 0, 0, "-topmargin", 0},
+ {TK_OPTION_PIXELS, "-topmargin", "topMargin", "TopMargin",
+ "0", -1, Tk_Offset(GraphOptions, topMargin.reqSize),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_STRING, "-topvariable", "topVariable", "TopVariable",
+ NULL, -1, Tk_Offset(GraphOptions, topMargin.varName),
+ TK_OPTION_NULL_OK, NULL, 0},
+ {TK_OPTION_PIXELS, "-width", "width", "Width",
+ "5i", -1, Tk_Offset(GraphOptions, reqWidth),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotwidth", "plotWidth", "PlotWidth",
+ "0", -1, Tk_Offset(GraphOptions, reqPlotWidth),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_PIXELS, "-plotheight", "plotHeight", "PlotHeight",
+ "0", -1, Tk_Offset(GraphOptions, reqPlotHeight),
+ 0, NULL, RESET_WORLD | CACHE_DIRTY},
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
+};
+
+// Create
+
+LineGraph::LineGraph(ClientData clientData, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+ : Graph(clientData, interp, objc, objv)
+{
+ optionTable_ = Tk_CreateOptionTable(interp_, optionSpecs);
+ ops_ = (LineGraphOptions*)calloc(1, sizeof(LineGraphOptions));
+ LineGraphOptions* ops = (LineGraphOptions*)ops_;
+
+ Tk_SetClass(tkwin_, "Graph");
+ classId_ = CID_ELEM_LINE;
+ if (createPen("active", 0, NULL) != TCL_OK) {
+ valid_ =0;
+ return;
+ }
+
+ ops->bottomMargin.site = MARGIN_BOTTOM;
+ ops->leftMargin.site = MARGIN_LEFT;
+ ops->topMargin.site = MARGIN_TOP;
+ ops->rightMargin.site = MARGIN_RIGHT;
+
+ Blt_Ts_InitStyle(ops->titleTextStyle);
+ ops->titleTextStyle.anchor = TK_ANCHOR_N;
+
+ if ((Tk_InitOptions(interp_, (char*)ops_, optionTable_, tkwin_) != TCL_OK) || (GraphObjConfigure(interp_, this, objc-2, objv+2) != TCL_OK)) {
+ valid_ =0;
+ return;
+ }
+
+ adjustAxes();
+
+ Tcl_SetStringObj(Tcl_GetObjResult(interp_), Tk_PathName(tkwin_), -1);
+}
+
+LineGraph::~LineGraph()
+{
+}
+
+int LineGraph::createPen(const char* penName, int objc, Tcl_Obj* const objv[])
+{
+ int isNew;
+ Tcl_HashEntry *hPtr =
+ Tcl_CreateHashEntry(&penTable_, penName, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp_, "pen \"", penName, "\" already exists in \"",
+ Tk_PathName(tkwin_), "\"", (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ Pen* penPtr = new LinePen(this, penName, hPtr);
+ if (!penPtr)
+ return TCL_ERROR;
+
+ Tcl_SetHashValue(hPtr, penPtr);
+
+ if ((Tk_InitOptions(interp_, (char*)penPtr->ops(), penPtr->optionTable(), tkwin_) != TCL_OK) || (PenObjConfigure(interp_, this, penPtr, objc-4, objv+4) != TCL_OK)) {
+ delete penPtr;
+ return TCL_ERROR;
+ }
+
+ flags |= CACHE_DIRTY;
+ eventuallyRedraw();
+
+ return TCL_OK;
+}
+
+int LineGraph::createElement(int objc, Tcl_Obj* const objv[])
+{
+ char *name = Tcl_GetString(objv[3]);
+ if (name[0] == '-') {
+ Tcl_AppendResult(interp_, "name of element \"", name,
+ "\" can't start with a '-'", NULL);
+ return TCL_ERROR;
+ }
+
+ int isNew;
+ Tcl_HashEntry* hPtr =
+ Tcl_CreateHashEntry(&elements_.table, name, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp_, "element \"", name,
+ "\" already exists in \"", Tcl_GetString(objv[0]),
+ "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ Element* elemPtr = new LineElement(this, name, hPtr);
+ if (!elemPtr)
+ return TCL_ERROR;
+
+ Tcl_SetHashValue(hPtr, elemPtr);
+
+ if ((Tk_InitOptions(interp_, (char*)elemPtr->ops(), elemPtr->optionTable(), tkwin_) != TCL_OK) || (ElementObjConfigure(interp_, elemPtr, objc-4, objv+4) != TCL_OK)) {
+ delete elemPtr;
+ return TCL_ERROR;
+ }
+
+ elemPtr->link = Blt_Chain_Append(elements_.displayList, elemPtr);
+
+ return TCL_OK;
+}
diff --git a/src/bltGraphLine.h b/src/bltGraphLine.h
new file mode 100644
index 0000000..595a10e
--- /dev/null
+++ b/src/bltGraphLine.h
@@ -0,0 +1,77 @@
+/*
+ * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+ * This code has been modified under the terms listed below and is made
+ * available under the same terms.
+ */
+
+/*
+ * Copyright 1993-2004 George A Howlett.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __BltGraphLine_h__
+#define __BltGraphLine_h__
+
+extern "C" {
+#include "bltGraph.h"
+};
+
+typedef struct {
+ double aspect;
+ Tk_3DBorder normalBg;
+ int borderWidth;
+ Margin margins[4];
+ int backingStore;
+ int doubleBuffer;
+ Tk_Cursor cursor;
+ TextStyle titleTextStyle;
+ int reqHeight;
+ XColor* highlightBgColor;
+ XColor* highlightColor;
+ int highlightWidth;
+ int inverted;
+ Tk_3DBorder plotBg;
+ int plotBW;
+ int xPad;
+ int yPad;
+ int plotRelief;
+ int relief;
+ ClosestSearch search;
+ int stackAxes;
+ const char *takeFocus; // nor used in C code
+ const char *title;
+ int reqWidth;
+ int reqPlotWidth;
+ int reqPlotHeight;
+
+ // line graph
+} LineGraphOptions;
+
+class LineGraph : public Graph {
+ public:
+ LineGraph(ClientData, Tcl_Interp*, int objc, Tcl_Obj* const []);
+ virtual ~LineGraph();
+
+ int createElement(int, Tcl_Obj* const []);
+ int createPen(const char*, int, Tcl_Obj* const []);
+};
+
+#endif
diff --git a/src/bltGraphOp.C b/src/bltGraphOp.C
index 2798fed..3de03aa 100644
--- a/src/bltGraphOp.C
+++ b/src/bltGraphOp.C
@@ -32,7 +32,8 @@
extern "C" {
#include "bltInt.h"
#include "bltList.h"
-#include "bltGraph.h"
+#include "bltGraphLine.h"
+#include "bltGraphBar.h"
#include "bltOp.h"
}
@@ -83,7 +84,7 @@ static int GraphObjCmd(ClientData clientData, Tcl_Interp* interp, int objc,
return TCL_ERROR;
}
- Graph* graphPtr = new Graph(clientData, interp, objc, objv, CID_ELEM_LINE);
+ Graph* graphPtr = new LineGraph(clientData, interp, objc, objv);
return graphPtr->valid_ ? TCL_OK : TCL_ERROR;
}
@@ -95,7 +96,7 @@ static int BarchartObjCmd(ClientData clientData, Tcl_Interp* interp, int objc,
return TCL_ERROR;
}
- Graph* graphPtr = new Graph(clientData, interp, objc, objv, CID_ELEM_BAR);
+ Graph* graphPtr = new BarGraph(clientData, interp, objc, objv);
return graphPtr->valid_ ? TCL_OK : TCL_ERROR;
}