summaryrefslogtreecommitdiffstats
path: root/tkblt/generic/tkbltGraphBar.C
diff options
context:
space:
mode:
Diffstat (limited to 'tkblt/generic/tkbltGraphBar.C')
-rw-r--r--tkblt/generic/tkbltGraphBar.C516
1 files changed, 0 insertions, 516 deletions
diff --git a/tkblt/generic/tkbltGraphBar.C b/tkblt/generic/tkbltGraphBar.C
deleted file mode 100644
index 861c12a..0000000
--- a/tkblt/generic/tkbltGraphBar.C
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdlib.h>
-
-#include "tkbltGraphBar.h"
-#include "tkbltGraphOp.h"
-
-#include "tkbltGrAxis.h"
-#include "tkbltGrXAxisOp.h"
-#include "tkbltGrPen.h"
-#include "tkbltGrPenOp.h"
-#include "tkbltGrPenBar.h"
-#include "tkbltGrPenLine.h"
-#include "tkbltGrElem.h"
-#include "tkbltGrElemOp.h"
-#include "tkbltGrElemBar.h"
-#include "tkbltGrElemLine.h"
-#include "tkbltGrMarker.h"
-#include "tkbltGrLegd.h"
-#include "tkbltGrHairs.h"
-#include "tkbltGrPostscript.h"
-#include "tkbltGrDef.h"
-
-using namespace Blt;
-
-// BarGroup
-
-BarGroup::BarGroup()
-{
- nSegments =0;
- xAxis =NULL;
- yAxis =NULL;
- sum =0;
- count =0;
- lastY =0;
- index =0;
-}
-
-// BarGraph
-
-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},
- {TK_OPTION_BORDER, "-background", "background", "Background",
- STD_NORMAL_BACKGROUND, -1, Tk_Offset(BarGraphOptions, normalBg),
- 0, NULL, CACHE},
- {TK_OPTION_STRING_TABLE, "-barmode", "barMode", "BarMode",
- "normal", -1, Tk_Offset(BarGraphOptions, barMode),
- 0, &barmodeObjOption, RESET},
- {TK_OPTION_DOUBLE, "-barwidth", "barWidth", "BarWidth",
- ".9", -1, Tk_Offset(BarGraphOptions, barWidth), 0, NULL, RESET},
- {TK_OPTION_DOUBLE, "-baseline", "baseline", "Baseline",
- "0", -1, Tk_Offset(BarGraphOptions, baseline), 0, NULL, RESET},
- {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-background", 0},
- {TK_OPTION_SYNONYM, "-bm", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-bottommargin", 0},
- {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- STD_BORDERWIDTH, -1, Tk_Offset(BarGraphOptions, borderWidth),
- 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-bottommargin", "bottomMargin", "BottomMargin",
- "0", -1, Tk_Offset(BarGraphOptions, bottomMargin.reqSize), 0, NULL, RESET},
- {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, 0, -1, 0, (ClientData)"-foreground", 0},
- {TK_OPTION_FONT, "-font", "font", "Font",
- STD_FONT_MEDIUM, -1, Tk_Offset(BarGraphOptions, titleTextStyle.font),
- 0, NULL, RESET},
- {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
- STD_NORMAL_FOREGROUND, -1, Tk_Offset(BarGraphOptions, titleTextStyle.color),
- 0, NULL, CACHE},
- {TK_OPTION_SYNONYM, "-halo", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-searchhalo", 0},
- {TK_OPTION_PIXELS, "-height", "height", "Height",
- "4i", -1, Tk_Offset(BarGraphOptions, reqHeight), 0, NULL, RESET},
- {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
- "HighlightBackground",
- STD_NORMAL_BACKGROUND, -1, Tk_Offset(BarGraphOptions, highlightBgColor),
- 0, NULL, CACHE},
- {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
- STD_NORMAL_FOREGROUND, -1, Tk_Offset(BarGraphOptions, highlightColor),
- 0, NULL, CACHE},
- {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness",
- "2", -1, Tk_Offset(BarGraphOptions, highlightWidth), 0, NULL, RESET},
- {TK_OPTION_BOOLEAN, "-invertxy", "invertXY", "InvertXY",
- "no", -1, Tk_Offset(BarGraphOptions, inverted), 0, NULL, RESET},
- {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
- "center", -1, Tk_Offset(BarGraphOptions, titleTextStyle.justify),
- 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-leftmargin", "leftMargin", "Margin",
- "0", -1, Tk_Offset(BarGraphOptions, leftMargin.reqSize), 0, NULL, RESET},
- {TK_OPTION_SYNONYM, "-lm", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-leftmargin", 0},
- {TK_OPTION_BORDER, "-plotbackground", "plotbackground", "PlotBackground",
- STD_NORMAL_BACKGROUND, -1, Tk_Offset(BarGraphOptions, plotBg),
- 0, NULL, CACHE},
- {TK_OPTION_PIXELS, "-plotborderwidth", "plotBorderWidth", "PlotBorderWidth",
- STD_BORDERWIDTH, -1, Tk_Offset(BarGraphOptions, plotBW), 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-plotpadx", "plotPadX", "PlotPad",
- "0", -1, Tk_Offset(BarGraphOptions, xPad), 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-plotpady", "plotPadY", "PlotPad",
- "0", -1, Tk_Offset(BarGraphOptions, yPad), 0, NULL, RESET},
- {TK_OPTION_RELIEF, "-plotrelief", "plotRelief", "Relief",
- "flat", -1, Tk_Offset(BarGraphOptions, plotRelief), 0, NULL, RESET},
- {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- "flat", -1, Tk_Offset(BarGraphOptions, relief), 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-rightmargin", "rightMargin", "Margin",
- "0", -1, Tk_Offset(BarGraphOptions, rightMargin.reqSize), 0, NULL, RESET},
- {TK_OPTION_SYNONYM, "-rm", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-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, RESET},
- {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},
- {TK_OPTION_SYNONYM, "-tm", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-topmargin", 0},
- {TK_OPTION_PIXELS, "-topmargin", "topMargin", "TopMargin",
- "0", -1, Tk_Offset(BarGraphOptions, topMargin.reqSize), 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-width", "width", "Width",
- "5i", -1, Tk_Offset(BarGraphOptions, reqWidth), 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-plotwidth", "plotWidth", "PlotWidth",
- "0", -1, Tk_Offset(BarGraphOptions, reqPlotWidth), 0, NULL, RESET},
- {TK_OPTION_PIXELS, "-plotheight", "plotHeight", "PlotHeight",
- "0", -1, Tk_Offset(BarGraphOptions, reqPlotHeight), 0, NULL, RESET},
- {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
-};
-
-// Create
-
-BarGraph::BarGraph(ClientData clientData, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
- : Graph(clientData, interp, objc, objv)
-{
- // problems so far?
- if (!valid_)
- return;
-
- ops_ = (BarGraphOptions*)calloc(1, sizeof(BarGraphOptions));
- BarGraphOptions* ops = (BarGraphOptions*)ops_;
-
- Tk_SetClass(tkwin_, "Barchart");
-
- 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;
-
- ops->titleTextStyle.anchor = TK_ANCHOR_N;
- ops->titleTextStyle.color =NULL;
- ops->titleTextStyle.font =NULL;
- ops->titleTextStyle.angle =0;
- ops->titleTextStyle.justify =TK_JUSTIFY_LEFT;
-
- optionTable_ = Tk_CreateOptionTable(interp_, optionSpecs);
- if ((Tk_InitOptions(interp_, (char*)ops_, optionTable_, tkwin_) != TCL_OK) || (GraphObjConfigure(this, interp_, objc-2, objv+2) != TCL_OK)) {
- valid_ =0;
- return;
- }
-
- // do this last after Tk_SetClass set
- legend_ = new Legend(this);
- crosshairs_ = new Crosshairs(this);
- postscript_ = new Postscript(this);
-
- if (createPen("active", 0, NULL) != TCL_OK) {
- valid_ =0;
- return;
- }
-
- if (createAxes() != TCL_OK) {
- valid_ =0;
- return;
- }
-
- adjustAxes();
-
- Tcl_SetStringObj(Tcl_GetObjResult(interp_), Tk_PathName(tkwin_), -1);
-}
-
-BarGraph::~BarGraph()
-{
- destroyBarSets();
-}
-
-int BarGraph::configure()
-{
- BarGraphOptions* ops = (BarGraphOptions*)ops_;
- // Don't allow negative bar widths. Reset to an arbitrary value (0.1)
- if (ops->barWidth <= 0.0)
- ops->barWidth = 0.9;
-
- return 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(this, penPtr, interp_, objc-4, objv+4) != TCL_OK)) {
- delete penPtr;
- return TCL_ERROR;
- }
-
- flags |= RESET;
- 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(elemPtr, interp_, objc-4, objv+4) != TCL_OK)) {
- delete elemPtr;
- return TCL_ERROR;
- }
-
- elemPtr->link = elements_.displayList->append(elemPtr);
-
- return TCL_OK;
-}
-
-void BarGraph::mapElements()
-{
- BarGraphOptions* ops = (BarGraphOptions*)ops_;
- if ((BarMode)ops->barMode != INFRONT)
- resetBarSets();
-
- 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.
- */
- initBarSets();
- if (((BarMode)ops->barMode == STACKED) && (nBarGroups_ > 0))
- computeBarStacks();
-
- Graph::resetAxes();
-}
-
-void BarGraph::initBarSets()
-{
- BarGraphOptions* ops = (BarGraphOptions*)ops_;
-
- // Free resources associated with a previous frequency table. This includes
- // the array of frequency information and the table itself
- destroyBarSets();
- if ((BarMode)ops->barMode == INFRONT)
- return;
-
- // Initialize a hash table and fill it with unique abscissas. Keep track
- // of the frequency of each x-coordinate and how many abscissas have
- // duplicate mappings.
- Tcl_HashTable setTable;
- Tcl_InitHashTable(&setTable, sizeof(BarSetKey)/sizeof(int));
- int nSegs =0;
-
- for (ChainLink* link = Chain_FirstLink(elements_.displayList);
- link; link = Chain_NextLink(link)) {
- BarElement* bePtr = (BarElement*)Chain_GetValue(link);
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops();
- if (ops->hide)
- continue;
-
- nSegs++;
- if (ops->coords.x) {
- int nPoints = ops->coords.x->nValues();
- for (double *x=ops->coords.x->values_, *xend=x+nPoints; x<xend; x++) {
- BarSetKey key;
- key.value =*x;
- key.xAxis =ops->xAxis;
- key.yAxis =NULL;
-
- int isNew;
- Tcl_HashEntry* hhPtr =
- Tcl_CreateHashEntry(&setTable, (char*)&key, &isNew);
- Tcl_HashTable* tablePtr;
- if (isNew) {
- tablePtr = (Tcl_HashTable*)malloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(tablePtr, TCL_STRING_KEYS);
- Tcl_SetHashValue(hhPtr, tablePtr);
- }
- else
- tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hhPtr);
-
- const char* name = ops->groupName ? ops->groupName : ops->yAxis->name_;
- Tcl_HashEntry* hhPtr2 = Tcl_CreateHashEntry(tablePtr, name, &isNew);
- size_t count =1;
- if (!isNew) {
- count = (size_t)Tcl_GetHashValue(hhPtr2);
- count++;
- }
- Tcl_SetHashValue(hhPtr2, count);
- }
- }
- }
-
- // no bar elements to be displayed
- if (setTable.numEntries == 0)
- return;
-
- int sum =0;
- int max =0;
- Tcl_HashSearch iter;
- for (Tcl_HashEntry *hhPtr = Tcl_FirstHashEntry(&setTable, &iter); hhPtr;
- hhPtr = Tcl_NextHashEntry(&iter)) {
- BarSetKey* keyPtr = (BarSetKey*)Tcl_GetHashKey(&setTable, hhPtr);
- Tcl_HashTable* tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hhPtr);
-
- int isNew;
- Tcl_HashEntry* hPtr =
- Tcl_CreateHashEntry(&setTable_, (char*)keyPtr, &isNew);
- Tcl_SetHashValue(hPtr, tablePtr);
-
- if (max < tablePtr->numEntries)
- max = tablePtr->numEntries; // # of stacks in group
- sum += tablePtr->numEntries;
- }
-
- Tcl_DeleteHashTable(&setTable);
-
- if (sum > 0) {
- barGroups_ = new BarGroup[sum];
- BarGroup* groupPtr = barGroups_;
- Tcl_HashSearch iter;
- for (Tcl_HashEntry* hPtr = Tcl_FirstHashEntry(&setTable_, &iter);
- hPtr; hPtr = Tcl_NextHashEntry(&iter)) {
- BarSetKey* keyPtr = (BarSetKey*)Tcl_GetHashKey(&setTable_, hPtr);
- Tcl_HashTable* tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
-
- size_t xcount = 0;
- Tcl_HashSearch iter2;
- for (Tcl_HashEntry *hPtr2 = Tcl_FirstHashEntry(tablePtr, &iter2);
- hPtr2; hPtr2 = Tcl_NextHashEntry(&iter2)) {
- size_t count = (size_t)Tcl_GetHashValue(hPtr2);
- groupPtr->nSegments = count;
- groupPtr->xAxis = keyPtr->xAxis;
- groupPtr->yAxis = keyPtr->yAxis;
- groupPtr->index = xcount++;
- Tcl_SetHashValue(hPtr2, groupPtr);
-
- groupPtr++;
- }
- }
- }
-
- maxBarSetSize_ = max;
- nBarGroups_ = sum;
-}
-
-void BarGraph::destroyBarSets()
-{
- delete [] barGroups_;
- barGroups_ = NULL;
-
- nBarGroups_ = 0;
- Tcl_HashSearch iter;
- for (Tcl_HashEntry* hPtr=Tcl_FirstHashEntry(&setTable_, &iter); hPtr;
- hPtr=Tcl_NextHashEntry(&iter)) {
- Tcl_HashTable* tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
- Tcl_DeleteHashTable(tablePtr);
- free(tablePtr);
- }
-
- Tcl_DeleteHashTable(&setTable_);
- Tcl_InitHashTable(&setTable_, sizeof(BarSetKey)/sizeof(int));
-}
-
-void BarGraph::resetBarSets()
-{
- for (BarGroup *gp = barGroups_, *gend = gp + nBarGroups_; gp < gend; gp++) {
- gp->lastY = 0.0;
- gp->count = 0;
- }
-}
-
-void BarGraph::computeBarStacks()
-{
- BarGraphOptions* ops = (BarGraphOptions*)ops_;
-
- if (((BarMode)ops->barMode != STACKED) || (nBarGroups_ == 0))
- return;
-
- // Initialize the stack sums to zero
- for (BarGroup *gp = barGroups_, *gend = gp + nBarGroups_; gp < gend; gp++)
- gp->sum = 0.0;
-
- // Consider each bar x-y coordinate. Add the ordinates of duplicate
- // abscissas
-
- for (ChainLink* link = Chain_FirstLink(elements_.displayList); link;
- link = Chain_NextLink(link)) {
- BarElement* bePtr = (BarElement*)Chain_GetValue(link);
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops();
- if (ops->hide)
- continue;
-
- if (ops->coords.x && ops->coords.y) {
- for (double *x=ops->coords.x->values_, *y=ops->coords.y->values_,
- *xend=x+ops->coords.x->nValues(); x<xend; x++, y++) {
- BarSetKey key;
- key.value =*x;
- key.xAxis =ops->xAxis;
- key.yAxis =NULL;
- Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&setTable_, (char*)&key);
- if (!hPtr)
- continue;
-
- Tcl_HashTable *tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
- const char *name = ops->groupName ? ops->groupName : ops->yAxis->name_;
- hPtr = Tcl_FindHashEntry(tablePtr, name);
- if (!hPtr)
- continue;
-
- BarGroup *groupPtr = (BarGroup*)Tcl_GetHashValue(hPtr);
- groupPtr->sum += *y;
- }
- }
- }
-}
-