summaryrefslogtreecommitdiffstats
path: root/tkblt/generic/tkbltGrElemBar.C
diff options
context:
space:
mode:
Diffstat (limited to 'tkblt/generic/tkbltGrElemBar.C')
-rw-r--r--tkblt/generic/tkbltGrElemBar.C1315
1 files changed, 0 insertions, 1315 deletions
diff --git a/tkblt/generic/tkbltGrElemBar.C b/tkblt/generic/tkbltGrElemBar.C
deleted file mode 100644
index 6698760..0000000
--- a/tkblt/generic/tkbltGrElemBar.C
+++ /dev/null
@@ -1,1315 +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 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.
- */
-
-#include <float.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <cmath>
-
-#include "tkbltGraphBar.h"
-#include "tkbltGrElemBar.h"
-#include "tkbltGrElemOption.h"
-#include "tkbltGrAxis.h"
-#include "tkbltGrMisc.h"
-#include "tkbltGrDef.h"
-#include "tkbltConfig.h"
-#include "tkbltGrPSOutput.h"
-#include "tkbltInt.h"
-
-using namespace Blt;
-
-#define CLAMP(x,l,h) ((x) = (((x)<(l))? (l) : ((x)>(h)) ? (h) : (x)))
-#define MIN3(a,b,c) (((a)<(b))?(((a)<(c))?(a):(c)):(((b)<(c))?(b):(c)))
-
-#define PointInRectangle(r,x0,y0) \
- (((x0) <= (int)((r)->x + (r)->width - 1)) && ((x0) >= (int)(r)->x) && \
- ((y0) <= (int)((r)->y + (r)->height - 1)) && ((y0) >= (int)(r)->y))
-
-// OptionSpecs
-
-static Tk_ObjCustomOption styleObjOption =
- {
- "style", StyleSetProc, StyleGetProc, StyleRestoreProc, StyleFreeProc,
- (ClientData)sizeof(BarStyle)
- };
-
-extern Tk_ObjCustomOption penObjOption;
-extern Tk_ObjCustomOption pairsObjOption;
-extern Tk_ObjCustomOption valuesObjOption;
-extern Tk_ObjCustomOption xAxisObjOption;
-extern Tk_ObjCustomOption yAxisObjOption;
-
-static Tk_OptionSpec optionSpecs[] = {
- {TK_OPTION_CUSTOM, "-activepen", "activePen", "ActivePen",
- "active", -1, Tk_Offset(BarElementOptions, activePenPtr),
- TK_OPTION_NULL_OK, &penObjOption, LAYOUT},
- {TK_OPTION_SYNONYM, "-background", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-color", 0},
- {TK_OPTION_DOUBLE, "-barwidth", "barWidth", "BarWidth",
- "0", -1, Tk_Offset(BarElementOptions, barWidth), 0, NULL, LAYOUT},
- {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-color", 0},
- {TK_OPTION_CUSTOM, "-bindtags", "bindTags", "BindTags",
- "all", -1, Tk_Offset(BarElementOptions, tags),
- TK_OPTION_NULL_OK, &listObjOption, 0},
- {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- STD_BORDERWIDTH, -1, Tk_Offset(BarElementOptions, builtinPen.borderWidth),
- 0, NULL, CACHE},
- {TK_OPTION_BORDER, "-color", "color", "color",
- STD_NORMAL_FOREGROUND, -1, Tk_Offset(BarElementOptions, builtinPen.fill),
- 0, NULL, CACHE},
- {TK_OPTION_CUSTOM, "-data", "data", "Data",
- NULL, -1, Tk_Offset(BarElementOptions, coords),
- TK_OPTION_NULL_OK, &pairsObjOption, RESET},
- {TK_OPTION_COLOR, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
- NULL, -1, Tk_Offset(BarElementOptions, builtinPen.errorBarColor),
- TK_OPTION_NULL_OK, NULL, CACHE},
- {TK_OPTION_PIXELS,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth",
- "1", -1, Tk_Offset(BarElementOptions, builtinPen.errorBarLineWidth),
- 0, NULL, CACHE},
- {TK_OPTION_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap",
- "0", -1, Tk_Offset(BarElementOptions, builtinPen.errorBarCapWidth),
- 0, NULL, LAYOUT},
- {TK_OPTION_SYNONYM, "-fg", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-outline", 0},
- {TK_OPTION_SYNONYM, "-fill", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-color", 0},
- {TK_OPTION_SYNONYM, "-foreground", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-outline", 0},
- {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
- "no", -1, Tk_Offset(BarElementOptions, hide), 0, NULL, LAYOUT},
- {TK_OPTION_STRING, "-label", "label", "Label",
- NULL, -1, Tk_Offset(BarElementOptions, label),
- TK_OPTION_NULL_OK, NULL, LAYOUT},
- {TK_OPTION_RELIEF, "-legendrelief", "legendRelief", "LegendRelief",
- "flat", -1, Tk_Offset(BarElementOptions, legendRelief), 0, NULL, LAYOUT},
- {TK_OPTION_CUSTOM, "-mapx", "mapX", "MapX",
- "x", -1, Tk_Offset(BarElementOptions, xAxis), 0, &xAxisObjOption, RESET},
- {TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY",
- "y", -1, Tk_Offset(BarElementOptions, yAxis), 0, &yAxisObjOption, RESET},
- {TK_OPTION_COLOR, "-outline", "outline", "Outline",
- NULL, -1, Tk_Offset(BarElementOptions, builtinPen.outlineColor),
- TK_OPTION_NULL_OK, NULL, CACHE},
- {TK_OPTION_CUSTOM, "-pen", "pen", "Pen",
- NULL, -1, Tk_Offset(BarElementOptions, normalPenPtr),
- TK_OPTION_NULL_OK, &penObjOption, LAYOUT},
- {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- "raised", -1, Tk_Offset(BarElementOptions, builtinPen.relief),
- 0, NULL, LAYOUT},
- {TK_OPTION_STRING_TABLE, "-showerrorbars", "showErrorBars", "ShowErrorBars",
- "both", -1, Tk_Offset(BarElementOptions, builtinPen.errorBarShow),
- 0, &fillObjOption, LAYOUT},
- {TK_OPTION_STRING_TABLE, "-showvalues", "showValues", "ShowValues",
- "none", -1, Tk_Offset(BarElementOptions, builtinPen.valueShow),
- 0, &fillObjOption, CACHE},
- {TK_OPTION_STRING, "-stack", "stack", "Stack",
- NULL, -1, Tk_Offset(BarElementOptions, groupName),
- TK_OPTION_NULL_OK, NULL, RESET},
- {TK_OPTION_CUSTOM, "-styles", "styles", "Styles",
- "", -1, Tk_Offset(BarElementOptions, stylePalette),
- 0, &styleObjOption, RESET},
- {TK_OPTION_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
- "s", -1, Tk_Offset(BarElementOptions, builtinPen.valueStyle.anchor),
- 0, NULL, CACHE},
- {TK_OPTION_COLOR, "-valuecolor", "valueColor", "ValueColor",
- STD_NORMAL_FOREGROUND, -1,
- Tk_Offset(BarElementOptions,builtinPen.valueStyle.color), 0, NULL, CACHE},
- {TK_OPTION_FONT, "-valuefont", "valueFont", "ValueFont",
- STD_FONT_SMALL, -1, Tk_Offset(BarElementOptions, builtinPen.valueStyle.font),
- 0, NULL, CACHE},
- {TK_OPTION_STRING, "-valueformat", "valueFormat", "ValueFormat",
- "%g", -1, Tk_Offset(BarElementOptions, builtinPen.valueFormat),
- TK_OPTION_NULL_OK, NULL, CACHE},
- {TK_OPTION_DOUBLE, "-valuerotate", "valueRotate", "ValueRotate",
- "0", -1, Tk_Offset(BarElementOptions, builtinPen.valueStyle.angle),
- 0, NULL, CACHE},
- {TK_OPTION_CUSTOM, "-weights", "weights", "Weights",
- NULL, -1, Tk_Offset(BarElementOptions, w),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_SYNONYM, "-x", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-xdata", 0},
- {TK_OPTION_CUSTOM, "-xdata", "xData", "XData",
- NULL, -1, Tk_Offset(BarElementOptions, coords.x),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_CUSTOM, "-xerror", "xError", "XError",
- NULL, -1, Tk_Offset(BarElementOptions, xError),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_CUSTOM, "-xhigh", "xHigh", "XHigh",
- NULL, -1, Tk_Offset(BarElementOptions, xHigh),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_CUSTOM, "-xlow", "xLow", "XLow",
- NULL, -1, Tk_Offset(BarElementOptions, xLow),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_SYNONYM, "-y", NULL, NULL,
- NULL, 0, -1, 0, (ClientData)"-ydata", 0},
- {TK_OPTION_CUSTOM, "-ydata", "yData", "YData",
- NULL, -1, Tk_Offset(BarElementOptions, coords.y),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_CUSTOM, "-yerror", "yError", "YError",
- NULL, -1, Tk_Offset(BarElementOptions, yError),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_CUSTOM, "-yhigh", "yHigh", "YHigh",
- NULL, -1, Tk_Offset(BarElementOptions, yHigh),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_CUSTOM, "-ylow", "yLow", "YLow",
- NULL, -1, Tk_Offset(BarElementOptions, yLow),
- TK_OPTION_NULL_OK, &valuesObjOption, RESET},
- {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
-};
-
-BarElement::BarElement(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
- : Element(graphPtr, name, hPtr)
-{
- barToData_ =NULL;
- bars_ =NULL;
- activeToData_ =NULL;
- activeRects_ =NULL;
- nBars_ =0;
- nActive_ =0;
-
- xeb_.segments =NULL;
- xeb_.map =NULL;
- xeb_.length =0;
- yeb_.segments =NULL;
- yeb_.map =NULL;
- yeb_.length =0;
-
- ops_ = (BarElementOptions*)calloc(1, sizeof(BarElementOptions));
- BarElementOptions* ops = (BarElementOptions*)ops_;
- ops->elemPtr = (Element*)this;
-
- builtinPenPtr = new BarPen(graphPtr_, "builtin", &ops->builtinPen);
- ops->builtinPenPtr = builtinPenPtr;
-
- optionTable_ = Tk_CreateOptionTable(graphPtr->interp_, optionSpecs);
-
- ops->stylePalette = new Chain();
-
- // this is an option and will be freed via Tk_FreeConfigOptions
- // By default an element's name and label are the same
- ops->label = Tcl_Alloc(strlen(name)+1);
- if (name)
- strcpy((char*)ops->label,(char*)name);
-
- Tk_InitOptions(graphPtr_->interp_, (char*)&(ops->builtinPen),
- builtinPenPtr->optionTable(), graphPtr->tkwin_);
-}
-
-BarElement::~BarElement()
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- delete builtinPenPtr;
-
- reset();
-
- if (ops->stylePalette) {
- freeStylePalette(ops->stylePalette);
- delete ops->stylePalette;
- }
-}
-
-int BarElement::configure()
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- if (builtinPenPtr->configure() != TCL_OK)
- return TCL_ERROR;
-
- // Point to the static normal pen if no external pens have been selected.
- ChainLink* link = Chain_FirstLink(ops->stylePalette);
- if (!link) {
- link = new ChainLink(sizeof(BarStyle));
- ops->stylePalette->linkAfter(link, NULL);
- }
- BarStyle* stylePtr = (BarStyle*)Chain_GetValue(link);
- stylePtr->penPtr = NORMALPEN(ops);
-
- return TCL_OK;
-}
-
-void BarElement::map()
-{
- BarGraph* barGraphPtr_ = (BarGraph*)graphPtr_;
- BarElementOptions* ops = (BarElementOptions*)ops_;
- BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
-
- if (!link)
- return;
-
- reset();
- if (!ops->coords.x || !ops->coords.y ||
- !ops->coords.x->nValues() || !ops->coords.y->nValues())
- return;
- int nPoints = NUMBEROFPOINTS(ops);
-
- double barWidth = (ops->barWidth > 0.0) ? ops->barWidth : gops->barWidth;
- AxisOptions* axisyops = (AxisOptions*)ops->yAxis->ops();
- double baseline = (axisyops->logScale) ? 0.0 : gops->baseline;
- double barOffset = barWidth * 0.5;
-
- // Create an array of bars representing the screen coordinates of all the
- // segments in the bar.
- Rectangle* bars = new Rectangle[nPoints];
- int* barToData = new int[nPoints];
-
- double* x = ops->coords.x->values_;
- double* y = ops->coords.y->values_;
- int count = 0;
-
- int ii;
- Rectangle* rp;
- for (rp=bars, ii=0; ii<nPoints; ii++) {
- // Two opposite corners of the rectangle in graph coordinates
- Point2d c1, c2;
-
- // check Abscissa is out of range of the x-axis
- if (((x[ii] - barWidth) > ops->xAxis->axisRange_.max) ||
- ((x[ii] + barWidth) < ops->xAxis->axisRange_.min))
- continue;
-
- c1.x = x[ii] - barOffset;
- c1.y = y[ii];
- c2.x = c1.x + barWidth;
- c2.y = baseline;
-
- // If the mode is "aligned" or "stacked" we need to adjust the x or y
- // coordinates of the two corners.
- if ((barGraphPtr_->nBarGroups_ > 0) &&
- ((BarGraph::BarMode)gops->barMode != BarGraph::INFRONT) &&
- (!gops->stackAxes)) {
-
- BarSetKey key;
- key.value =x[ii];
- key.xAxis =ops->xAxis;
- key.yAxis =NULL;
- Tcl_HashEntry* hPtr =
- Tcl_FindHashEntry(&barGraphPtr_->setTable_, (char*)&key);
-
- if (hPtr) {
- Tcl_HashTable *tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
- const char *name = (ops->groupName) ? ops->groupName:ops->yAxis->name_;
- Tcl_HashEntry* hPtr2 = Tcl_FindHashEntry(tablePtr, name);
- if (hPtr2) {
- BarGroup* groupPtr = (BarGroup*)Tcl_GetHashValue(hPtr2);
- double slice = barWidth / (double)barGraphPtr_->maxBarSetSize_;
- double offset = (slice * groupPtr->index);
- if (barGraphPtr_->maxBarSetSize_ > 1) {
- offset += slice * 0.05;
- slice *= 0.90;
- }
-
- switch ((BarGraph::BarMode)gops->barMode) {
- case BarGraph::STACKED:
- groupPtr->count++;
- c2.y = groupPtr->lastY;
- c1.y += c2.y;
- groupPtr->lastY = c1.y;
- c1.x += offset;
- c2.x = c1.x + slice;
- break;
-
- case BarGraph::ALIGNED:
- slice /= groupPtr->nSegments;
- c1.x += offset + (slice * groupPtr->count);
- c2.x = c1.x + slice;
- groupPtr->count++;
- break;
-
- case BarGraph::OVERLAP:
- {
- slice /= (groupPtr->nSegments + 1);
- double width = slice + slice;
- groupPtr->count++;
- c1.x += offset +
- (slice * (groupPtr->nSegments - groupPtr->count));
- c2.x = c1.x + width;
- }
- break;
-
- case BarGraph::INFRONT:
- break;
- }
- }
- }
- }
-
- int invertBar = 0;
- if (c1.y < c2.y) {
- // Handle negative bar values by swapping ordinates
- double temp = c1.y;
- c1.y = c2.y;
- c2.y = temp;
- invertBar = 1;
- }
-
- // Get the two corners of the bar segment and compute the rectangle
- double ybot = c2.y;
- c1 = graphPtr_->map2D(c1.x, c1.y, ops->xAxis, ops->yAxis);
- c2 = graphPtr_->map2D(c2.x, c2.y, ops->xAxis, ops->yAxis);
- if ((ybot == 0.0) && (axisyops->logScale))
- c2.y = graphPtr_->bottom_;
-
- if (c2.y < c1.y) {
- double t = c1.y;
- c1.y = c2.y;
- c2.y = t;
- }
-
- if (c2.x < c1.x) {
- double t = c1.x;
- c1.x = c2.x;
- c2.x = t;
- }
-
- if ((c1.x > graphPtr_->right_) || (c2.x < graphPtr_->left_) ||
- (c1.y > graphPtr_->bottom_) || (c2.y < graphPtr_->top_))
- continue;
-
- // Bound the bars horizontally by the width of the graph window
- // Bound the bars vertically by the position of the axis.
- double right =0;
- double left =0;
- double top =0;
- double bottom =0;
- if (gops->stackAxes) {
- top = ops->yAxis->screenMin_;
- bottom = ops->yAxis->screenMin_ + ops->yAxis->screenRange_;
- left = graphPtr_->left_;
- right = graphPtr_->right_;
- }
- else {
- bottom = right = 10000;
- // Shouldn't really have a call to Tk_Width or Tk_Height in
- // mapping routine. We only want to clamp the bar segment to the
- // size of the window if we're actually mapped onscreen
- if (Tk_Height(graphPtr_->tkwin_) > 1)
- bottom = Tk_Height(graphPtr_->tkwin_);
- if (Tk_Width(graphPtr_->tkwin_) > 1)
- right = Tk_Width(graphPtr_->tkwin_);
- }
-
- CLAMP(c1.y, top, bottom);
- CLAMP(c2.y, top, bottom);
- CLAMP(c1.x, left, right);
- CLAMP(c2.x, left, right);
- double dx = fabs(c1.x - c2.x);
- double dy = fabs(c1.y - c2.y);
- if ((dx == 0) || (dy == 0))
- continue;
-
- int height = (int)dy;
- int width = (int)dx;
- if (invertBar)
- rp->y = (int)MIN(c1.y, c2.y);
- else
- rp->y = (int)(MAX(c1.y, c2.y)) - height;
-
- rp->x = (int)MIN(c1.x, c2.x);
-
- rp->width = width + 1;
- rp->width |= 0x1;
- if (rp->width < 1)
- rp->width = 1;
-
- rp->height = height + 1;
- if (rp->height < 1)
- rp->height = 1;
-
- // Save the data index corresponding to the rectangle
- barToData[count] = ii;
- count++;
- rp++;
- }
- nBars_ = count;
- bars_ = bars;
- barToData_ = barToData;
- if (nActiveIndices_ > 0)
- mapActive();
-
- int size = 20;
- if (count > 0)
- size = bars->width;
-
- // Set the symbol size of all the pen styles
- for (ChainLink* link = Chain_FirstLink(ops->stylePalette); link;
- link = Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- BarPen* penPtr = stylePtr->penPtr;
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
- stylePtr->symbolSize = size;
- stylePtr->errorBarCapWidth = pops->errorBarCapWidth;
- }
-
- BarStyle** dataToStyle = (BarStyle**)StyleMap();
- if (((ops->yHigh && ops->yHigh->nValues() > 0) &&
- (ops->yLow && ops->yLow->nValues() > 0)) ||
- ((ops->xHigh && ops->xHigh->nValues() > 0) &&
- (ops->xLow && ops->xLow->nValues() > 0)) ||
- (ops->xError && ops->xError->nValues() > 0) ||
- (ops->yError && ops->yError->nValues() > 0)) {
- mapErrorBars(dataToStyle);
- }
-
- mergePens(dataToStyle);
- delete [] dataToStyle;
-}
-
-void BarElement::extents(Region2d *regPtr)
-{
- BarGraph* barGraphPtr_ = (BarGraph*)graphPtr_;
- BarElementOptions* ops = (BarElementOptions*)ops_;
- BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
-
- regPtr->top = regPtr->left = DBL_MAX;
- regPtr->bottom = regPtr->right = -DBL_MAX;
-
- if (!ops->coords.x || !ops->coords.y ||
- !ops->coords.x->nValues() || !ops->coords.y->nValues())
- return;
-
- int nPoints = NUMBEROFPOINTS(ops);
-
- double middle = 0.5;
- regPtr->left = ops->coords.x->min() - middle;
- regPtr->right = ops->coords.x->max() + middle;
-
- regPtr->top = ops->coords.y->min();
- regPtr->bottom = ops->coords.y->max();
- if (regPtr->bottom < gops->baseline)
- regPtr->bottom = gops->baseline;
-
- // 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 (((BarGraph::BarMode)gops->barMode == BarGraph::STACKED) &&
- (barGraphPtr_->nBarGroups_ > 0))
- checkStacks(ops->xAxis, ops->yAxis, &regPtr->top, &regPtr->bottom);
-
- // Warning: You get what you deserve if the x-axis is logScale
- AxisOptions* axisxops = (AxisOptions*)ops->xAxis->ops();
- AxisOptions* axisyops = (AxisOptions*)ops->yAxis->ops();
- if (axisxops->logScale)
- regPtr->left = FindElemValuesMinimum(ops->coords.x, DBL_MIN) + middle;
-
- // Fix y-min limits for barchart
- if (axisyops->logScale) {
- if ((regPtr->top <= 0.0) || (regPtr->top > 1.0))
- regPtr->top = 1.0;
- }
- else {
- if (regPtr->top > 0.0)
- regPtr->top = 0.0;
- }
-
- // Correct the extents for error bars if they exist
- if (ops->xError && (ops->xError->nValues() > 0)) {
- nPoints = MIN(ops->xError->nValues(), nPoints);
- for (int ii=0; ii<nPoints; ii++) {
- double x = ops->coords.x->values_[ii] + ops->xError->values_[ii];
- if (x > regPtr->right)
- regPtr->right = x;
-
- x = ops->coords.x->values_[ii] - ops->xError->values_[ii];
- if (axisxops->logScale) {
- // Mirror negative values, instead of ignoring them
- if (x < 0.0)
- x = -x;
-
- if ((x > DBL_MIN) && (x < regPtr->left))
- regPtr->left = x;
-
- }
- else if (x < regPtr->left)
- regPtr->left = x;
- }
- }
- else {
- if ((ops->xHigh) &&
- (ops->xHigh->nValues() > 0) &&
- (ops->xHigh->max() > regPtr->right))
- regPtr->right = ops->xHigh->max();
-
- if (ops->xLow && (ops->xLow->nValues() > 0)) {
- double left;
- if ((ops->xLow->min() <= 0.0) && (axisxops->logScale))
- left = FindElemValuesMinimum(ops->xLow, DBL_MIN);
- else
- left = ops->xLow->min();
-
- if (left < regPtr->left)
- regPtr->left = left;
- }
- }
-
- if (ops->yError && (ops->yError->nValues() > 0)) {
- nPoints = MIN(ops->yError->nValues(), nPoints);
-
- for (int ii=0; ii<nPoints; ii++) {
- double y = ops->coords.y->values_[ii] + ops->yError->values_[ii];
- if (y > regPtr->bottom)
- regPtr->bottom = y;
-
- y = ops->coords.y->values_[ii] - ops->yError->values_[ii];
- if (axisyops->logScale) {
- // Mirror negative values, instead of ignoring them
- if (y < 0.0)
- y = -y;
-
- if ((y > DBL_MIN) && (y < regPtr->left))
- regPtr->top = y;
-
- }
- else if (y < regPtr->top)
- regPtr->top = y;
- }
- }
- else {
- if ((ops->yHigh) &&
- (ops->yHigh->nValues() > 0) &&
- (ops->yHigh->max() > regPtr->bottom))
- regPtr->bottom = ops->yHigh->max();
-
- if (ops->yLow && ops->yLow->nValues() > 0) {
- double top;
- if ((ops->yLow->min() <= 0.0) &&
- (axisyops->logScale))
- top = FindElemValuesMinimum(ops->yLow, DBL_MIN);
- else
- top = ops->yLow->min();
-
- if (top < regPtr->top)
- regPtr->top = top;
- }
- }
-}
-
-void BarElement::closest()
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
- BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
-
- ClosestSearch* searchPtr = &gops->search;
- double minDist = searchPtr->dist;
- int imin = 0;
-
- int ii;
- Rectangle* bp;
- for (bp=bars_, ii=0; ii<nBars_; ii++, bp++) {
- if (PointInRectangle(bp, searchPtr->x, searchPtr->y)) {
- imin = barToData_[ii];
- minDist = 0.0;
- break;
- }
- double left = bp->x;
- double top = bp->y;
- double right = (double)(bp->x + bp->width);
- double bottom = (double)(bp->y + bp->height);
-
- Point2d outline[5];
- outline[4].x = outline[3].x = outline[0].x = left;
- outline[4].y = outline[1].y = outline[0].y = top;
- outline[2].x = outline[1].x = right;
- outline[3].y = outline[2].y = bottom;
-
- Point2d *pp, *pend;
- for (pp=outline, pend=outline+4; pp<pend; pp++) {
- Point2d t = getProjection(searchPtr->x, searchPtr->y, pp, pp + 1);
- if (t.x > right)
- t.x = right;
- else if (t.x < left)
- t.x = left;
-
- if (t.y > bottom)
- t.y = bottom;
- else if (t.y < top)
- t.y = top;
-
- double dist = hypot((t.x - searchPtr->x), (t.y - searchPtr->y));
- if (dist < minDist) {
- minDist = dist;
- imin = barToData_[ii];
- }
- }
- }
- if (minDist < searchPtr->dist) {
- searchPtr->elemPtr = (Element*)this;
- searchPtr->dist = minDist;
- searchPtr->index = imin;
- searchPtr->point.x =
- ops->coords.x ? (double)ops->coords.x->values_[imin] : 0;
- searchPtr->point.y =
- ops->coords.y ? (double)ops->coords.y->values_[imin] : 0;
- }
-}
-
-void BarElement::draw(Drawable drawable)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- if (ops->hide)
- return;
-
- int count = 0;
- for (ChainLink* link = Chain_FirstLink(ops->stylePalette); link;
- link = Chain_NextLink(link)) {
-
- BarStyle* stylePtr = (BarStyle*)Chain_GetValue(link);
- BarPen* penPtr = (BarPen*)stylePtr->penPtr;
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
-
- if (stylePtr->nBars > 0)
- drawSegments(drawable, penPtr, stylePtr->bars, stylePtr->nBars);
-
- if ((stylePtr->xeb.length > 0) && (pops->errorBarShow & SHOW_X))
- graphPtr_->drawSegments(drawable, penPtr->errorBarGC_,
- stylePtr->xeb.segments, stylePtr->xeb.length);
-
- if ((stylePtr->yeb.length > 0) && (pops->errorBarShow & SHOW_Y))
- graphPtr_->drawSegments(drawable, penPtr->errorBarGC_,
- stylePtr->yeb.segments, stylePtr->yeb.length);
-
- if (pops->valueShow != SHOW_NONE)
- drawValues(drawable, penPtr, stylePtr->bars, stylePtr->nBars,
- barToData_ + count);
-
- count += stylePtr->nBars;
- }
-}
-
-void BarElement::drawActive(Drawable drawable)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- if (ops->hide || !active_)
- return;
-
- BarPen* penPtr = (BarPen*)ops->activePenPtr;
- if (!penPtr)
- return;
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
-
- if (nActiveIndices_ > 0) {
- mapActive();
-
- drawSegments(drawable, penPtr, activeRects_, nActive_);
- if (pops->valueShow != SHOW_NONE)
- drawValues(drawable, penPtr, activeRects_, nActive_, activeToData_);
- }
- else if (nActiveIndices_ < 0) {
- drawSegments(drawable, penPtr, bars_, nBars_);
- if (pops->valueShow != SHOW_NONE)
- drawValues(drawable, penPtr, bars_, nBars_, barToData_);
- }
-}
-
-void BarElement::drawSymbol(Drawable drawable, int x, int y, int size)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- BarPen* penPtr = NORMALPEN(ops);
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
-
- int radius = (size / 2);
- size--;
-
- x -= radius;
- y -= radius;
-
- Tk_Fill3DRectangle(graphPtr_->tkwin_, drawable,
- pops->fill, x, y, size, size,
- pops->borderWidth, pops->relief);
-
- if (pops->outlineColor)
- XDrawRectangle(graphPtr_->display_, drawable, penPtr->outlineGC_,
- x, y, size, size);
-}
-
-void BarElement::print(PSOutput* psPtr)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- if (ops->hide)
- return;
-
- psPtr->format("\n%% Element \"%s\"\n\n", name_);
-
- int count = 0;
- for (ChainLink* link = Chain_FirstLink(ops->stylePalette); link;
- link = Chain_NextLink(link)) {
-
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- BarPen* penPtr = (BarPen*)stylePtr->penPtr;
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
-
- if (stylePtr->nBars > 0)
- printSegments(psPtr, penPtr, stylePtr->bars, stylePtr->nBars);
-
- XColor* colorPtr = pops->errorBarColor;
- if (!colorPtr)
- colorPtr = pops->outlineColor;
- if (!colorPtr)
- colorPtr = Tk_3DBorderColor(pops->fill);
-
- if ((stylePtr->xeb.length > 0) && (pops->errorBarShow & SHOW_X)) {
- psPtr->setLineAttributes(colorPtr, pops->errorBarLineWidth,
- NULL, CapButt, JoinMiter);
- psPtr->printSegments(stylePtr->xeb.segments, stylePtr->xeb.length);
- }
-
- if ((stylePtr->yeb.length > 0) && (pops->errorBarShow & SHOW_Y)) {
- psPtr->setLineAttributes(colorPtr, pops->errorBarLineWidth,
- NULL, CapButt, JoinMiter);
- psPtr->printSegments(stylePtr->yeb.segments, stylePtr->yeb.length);
- }
-
- if (pops->valueShow != SHOW_NONE)
- printValues(psPtr, penPtr, stylePtr->bars, stylePtr->nBars,
- barToData_ + count);
-
- count += stylePtr->nBars;
- }
-}
-
-void BarElement::printActive(PSOutput* psPtr)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- if (ops->hide || !active_)
- return;
-
- BarPen* penPtr = (BarPen*)ops->activePenPtr;
- if (!penPtr)
- return;
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
-
- psPtr->format("\n%% Active Element \"%s\"\n\n", name_);
-
- if (nActiveIndices_ > 0) {
- mapActive();
-
- printSegments(psPtr, penPtr, activeRects_, nActive_);
- if (pops->valueShow != SHOW_NONE)
- printValues(psPtr, penPtr, activeRects_, nActive_,activeToData_);
- }
- else if (nActiveIndices_ < 0) {
- printSegments(psPtr, penPtr, bars_, nBars_);
- if (pops->valueShow != SHOW_NONE)
- printValues(psPtr, penPtr, bars_, nBars_, barToData_);
- }
-}
-
-void BarElement::printSymbol(PSOutput* psPtr, double x, double y, int size)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- BarPen* penPtr = NORMALPEN(ops);
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
-
- x -= size/2.;
- y -= size/2.;
-
- psPtr->fill3DRectangle(pops->fill, x, y, size, size,
- pops->borderWidth, pops->relief);
-
- if (pops->outlineColor) {
- psPtr->setForeground(pops->outlineColor);
- psPtr->printRectangle(x, y, size, size);
- }
-}
-
-// Support
-
-void BarElement::ResetStylePalette(Chain* stylePalette)
-{
- for (ChainLink* link = Chain_FirstLink(stylePalette); link;
- link = Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- stylePtr->xeb.length = 0;
- stylePtr->yeb.length = 0;
- stylePtr->nBars = 0;
- }
-}
-
-void BarElement::checkStacks(Axis* xAxis, Axis* yAxis,
- double* minPtr, double* maxPtr)
-{
- BarGraph* barGraphPtr_ = (BarGraph*)graphPtr_;
- BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
- if (((BarGraph::BarMode)gops->barMode != BarGraph::STACKED) ||
- barGraphPtr_->nBarGroups_ == 0)
- return;
-
- for (BarGroup *gp = barGraphPtr_->barGroups_,
- *gend = gp + barGraphPtr_->nBarGroups_; gp < gend; gp++) {
- if ((gp->xAxis == xAxis) && (gp->yAxis == yAxis)) {
-
- // Check if any of the y-values (because of stacking) are greater
- // than the current limits of the graph.
- if (gp->sum < 0.0) {
- if (*minPtr > gp->sum)
- *minPtr = gp->sum;
- }
- else {
- if (*maxPtr < gp->sum)
- *maxPtr = gp->sum;
- }
- }
- }
-}
-
-void BarElement::mergePens(BarStyle** dataToStyle)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- if (Chain_GetLength(ops->stylePalette) < 2) {
- ChainLink* link = Chain_FirstLink(ops->stylePalette);
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- stylePtr->nBars = nBars_;
- stylePtr->bars = bars_;
- stylePtr->symbolSize = bars_->width / 2;
- stylePtr->xeb.length = xeb_.length;
- stylePtr->xeb.segments = xeb_.segments;
- stylePtr->yeb.length = yeb_.length;
- stylePtr->yeb.segments = yeb_.segments;
- return;
- }
-
- // We have more than one style. Group bar segments of like pen styles together
- if (nBars_ > 0) {
- Rectangle* bars = new Rectangle[nBars_];
- int* barToData = new int[nBars_];
- Rectangle* bp = bars;
- int* ip = barToData;
- for (ChainLink* link = Chain_FirstLink(ops->stylePalette); link;
- link = Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- stylePtr->symbolSize = bp->width / 2;
- stylePtr->bars = bp;
- for (int ii=0; ii<nBars_; ii++) {
- int iData = barToData[ii];
- if (dataToStyle[iData] == stylePtr) {
- *bp++ = bars[ii];
- *ip++ = iData;
- }
- }
- stylePtr->nBars = bp - stylePtr->bars;
- }
- delete [] bars_;
- bars_ = bars;
- delete [] barToData_;
- barToData_ = barToData;
- }
-
- if (xeb_.length > 0) {
- Segment2d* bars = new Segment2d[xeb_.length];
- Segment2d *sp = bars;
- int* map = new int[xeb_.length];
- int* ip = map;
- for (ChainLink* link = Chain_FirstLink(ops->stylePalette); link;
- link = Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- stylePtr->xeb.segments = sp;
- for (int ii=0; ii<xeb_.length; ii++) {
- int iData = xeb_.map[ii];
- if (dataToStyle[iData] == stylePtr) {
- *sp++ = xeb_.segments[ii];
- *ip++ = iData;
- }
- }
- stylePtr->xeb.length = sp - stylePtr->xeb.segments;
- }
- delete [] xeb_.segments;
- xeb_.segments = bars;
- delete [] xeb_.map;
- xeb_.map = map;
- }
-
- if (yeb_.length > 0) {
- Segment2d* bars = new Segment2d[yeb_.length];
- Segment2d* sp = bars;
- int* map = new int[yeb_.length];
- int* ip = map;
- for (ChainLink* link = Chain_FirstLink(ops->stylePalette); link;
- link = Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Chain_GetValue(link);
- stylePtr->yeb.segments = sp;
- for (int ii=0; ii<yeb_.length; ii++) {
- int iData = yeb_.map[ii];
- if (dataToStyle[iData] == stylePtr) {
- *sp++ = yeb_.segments[ii];
- *ip++ = iData;
- }
- }
- stylePtr->yeb.length = sp - stylePtr->yeb.segments;
- }
- delete [] yeb_.segments;
- yeb_.segments = bars;
- delete [] yeb_.map;
- yeb_.map = map;
- }
-}
-
-void BarElement::mapActive()
-{
- delete [] activeRects_;
- activeRects_ = NULL;
-
- delete [] activeToData_;
- activeToData_ = NULL;
-
- nActive_ = 0;
-
- if (nActiveIndices_ > 0) {
- Rectangle* activeRects = new Rectangle[nActiveIndices_];
- int* activeToData = new int[nActiveIndices_];
- int count = 0;
- for (int ii=0; ii<nBars_; ii++) {
- for (int *ip = activeIndices_, *iend = ip + nActiveIndices_;
- ip < iend; ip++) {
- if (barToData_[ii] == *ip) {
- activeRects[count] = bars_[ii];
- activeToData[count] = ii;
- count++;
- }
- }
- }
- nActive_ = count;
- activeRects_ = activeRects;
- activeToData_ = activeToData;
- }
-}
-
-void BarElement::reset()
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- ResetStylePalette(ops->stylePalette);
-
- delete [] activeRects_;
- activeRects_ = NULL;
- delete [] activeToData_;
- activeToData_ = NULL;
-
- delete [] xeb_.segments;
- xeb_.segments = NULL;
- delete [] xeb_.map;
- xeb_.map = NULL;
- xeb_.length = 0;
-
- delete [] yeb_.segments;
- yeb_.segments = NULL;
- delete [] yeb_.map;
- yeb_.map = NULL;
- yeb_.length = 0;
-
- delete [] bars_;
- bars_ = NULL;
- delete [] barToData_;
- barToData_ = NULL;
-
- nActive_ = 0;
- nBars_ = 0;
-}
-
-void BarElement::mapErrorBars(BarStyle **dataToStyle)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
-
- Region2d reg;
- graphPtr_->extents(&reg);
-
- int nPoints = NUMBEROFPOINTS(ops);
- int nn =0;
- if (ops->coords.x && ops->coords.y) {
- if (ops->xError && (ops->xError->nValues() > 0))
- nn = MIN(ops->xError->nValues(), nPoints);
- else
- if (ops->xHigh && ops->xLow)
- nn = MIN3(ops->xHigh->nValues(), ops->xLow->nValues(), nPoints);
- }
-
- if (nn) {
- Segment2d* bars = new Segment2d[nn * 3];
- Segment2d* segPtr = bars;
- int* map = new int[nn * 3];
- int* indexPtr = map;
-
- for (int ii=0; ii<nn; ii++) {
- double x = ops->coords.x->values_[ii];
- double y = ops->coords.y->values_[ii];
- BarStyle* stylePtr = dataToStyle[ii];
-
- if ((isfinite(x)) && (isfinite(y))) {
- double high, low;
- if (ops->xError->nValues() > 0) {
- high = x + ops->xError->values_[ii];
- low = x - ops->xError->values_[ii];
- }
- else {
- high = ops->xHigh ? ops->xHigh->values_[ii] : 0;
- low = ops->xLow ? ops->xLow->values_[ii] : 0;
- }
- if ((isfinite(high)) && (isfinite(low))) {
- Point2d p = graphPtr_->map2D(high, y, ops->xAxis, ops->yAxis);
- Point2d q = graphPtr_->map2D(low, y, ops->xAxis, ops->yAxis);
- segPtr->p = p;
- segPtr->q = q;
- if (lineRectClip(&reg, &segPtr->p, &segPtr->q)) {
- segPtr++;
- *indexPtr++ = ii;
- }
- // Left cap
- segPtr->p.x = p.x;
- segPtr->q.x = p.x;
- segPtr->p.y = p.y - stylePtr->errorBarCapWidth;
- segPtr->q.y = p.y + stylePtr->errorBarCapWidth;
- if (lineRectClip(&reg, &segPtr->p, &segPtr->q)) {
- segPtr++;
- *indexPtr++ = ii;
- }
- // Right cap
- segPtr->p.x = q.x;
- segPtr->q.x = q.x;
- segPtr->p.y = q.y - stylePtr->errorBarCapWidth;
- segPtr->q.y = q.y + stylePtr->errorBarCapWidth;
- if (lineRectClip(&reg, &segPtr->p, &segPtr->q)) {
- segPtr++;
- *indexPtr++ = ii;
- }
- }
- }
- }
- xeb_.segments = bars;
- xeb_.length = segPtr - bars;
- xeb_.map = map;
- }
-
- nn =0;
- if (ops->coords.x && ops->coords.y) {
- if (ops->yError && (ops->yError->nValues() > 0))
- nn = MIN(ops->yError->nValues(), nPoints);
- else
- if (ops->yHigh && ops->yLow)
- nn = MIN3(ops->yHigh->nValues(), ops->yLow->nValues(), nPoints);
- }
-
- if (nn) {
- Segment2d* bars = new Segment2d[nn * 3];
- Segment2d* segPtr = bars;
- int* map = new int[nn * 3];
- int* indexPtr = map;
-
- for (int ii=0; ii<nn; ii++) {
- double x = ops->coords.x->values_[ii];
- double y = ops->coords.y->values_[ii];
- BarStyle *stylePtr = dataToStyle[ii];
-
- if ((isfinite(x)) && (isfinite(y))) {
- double high, low;
- if (ops->yError->nValues() > 0) {
- high = y + ops->yError->values_[ii];
- low = y - ops->yError->values_[ii];
- }
- else {
- high = ops->yHigh->values_[ii];
- low = ops->yLow->values_[ii];
- }
- if ((isfinite(high)) && (isfinite(low))) {
- Point2d p = graphPtr_->map2D(x, high, ops->xAxis, ops->yAxis);
- Point2d q = graphPtr_->map2D(x, low, ops->xAxis, ops->yAxis);
- segPtr->p = p;
- segPtr->q = q;
- if (lineRectClip(&reg, &segPtr->p, &segPtr->q)) {
- segPtr++;
- *indexPtr++ = ii;
- }
- // Top cap
- segPtr->p.y = p.y;
- segPtr->q.y = p.y;
- segPtr->p.x = p.x - stylePtr->errorBarCapWidth;
- segPtr->q.x = p.x + stylePtr->errorBarCapWidth;
- if (lineRectClip(&reg, &segPtr->p, &segPtr->q)) {
- segPtr++;
- *indexPtr++ = ii;
- }
- // Bottom cap
- segPtr->p.y = q.y;
- segPtr->q.y = q.y;
- segPtr->p.x = q.x - stylePtr->errorBarCapWidth;
- segPtr->q.x = q.x + stylePtr->errorBarCapWidth;
- if (lineRectClip(&reg, &segPtr->p, &segPtr->q)) {
- segPtr++;
- *indexPtr++ = ii;
- }
- }
- }
- }
- yeb_.segments = bars;
- yeb_.length = segPtr - bars;
- yeb_.map = map;
- }
-}
-
-void BarElement::drawSegments(Drawable drawable, BarPen* penPtr,
- Rectangle *bars, int nBars)
-{
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
- for (Rectangle *rp = bars, *rend = rp + nBars; rp < rend; rp++) {
- if ((rp->width < 1) || (rp->height < 1))
- continue;
-
- Tk_Fill3DRectangle(graphPtr_->tkwin_, drawable,
- pops->fill, rp->x, rp->y, rp->width, rp->height,
- pops->borderWidth, pops->relief);
-
- if (pops->outlineColor)
- XDrawRectangle(graphPtr_->display_, drawable, penPtr->outlineGC_,
- rp->x, rp->y, rp->width, rp->height);
- }
-}
-
-void BarElement::drawValues(Drawable drawable, BarPen* penPtr,
- Rectangle *bars, int nBars, int *barToData)
-{
- BarElementOptions* ops = (BarElementOptions*)ops_;
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
- BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
-
- const char *fmt = pops->valueFormat;
- if (!fmt)
- fmt = "%g";
- TextStyle ts(graphPtr_, &pops->valueStyle);
-
- int count = 0;
- for (Rectangle *rp = bars, *rend = rp + nBars; rp < rend; rp++) {
- Point2d anchorPos;
- char string[TCL_DOUBLE_SPACE * 2 + 2];
-
- double x = ops->coords.x->values_[barToData[count]];
- double y = ops->coords.y->values_[barToData[count]];
-
- count++;
- if (pops->valueShow == SHOW_X)
- snprintf(string, TCL_DOUBLE_SPACE, fmt, x);
- else if (pops->valueShow == SHOW_Y)
- snprintf(string, TCL_DOUBLE_SPACE, fmt, y);
- else if (pops->valueShow == SHOW_BOTH) {
- snprintf(string, TCL_DOUBLE_SPACE, fmt, x);
- strcat(string, ",");
- snprintf(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
- }
-
- if (gops->inverted) {
- anchorPos.y = rp->y + rp->height * 0.5;
- anchorPos.x = rp->x + rp->width;
- if (x < gops->baseline)
- anchorPos.x -= rp->width;
- }
- else {
- anchorPos.x = rp->x + rp->width * 0.5;
- anchorPos.y = rp->y;
- if (y < gops->baseline)
- anchorPos.y += rp->height;
- }
-
- ts.drawText(drawable, string, anchorPos.x, anchorPos.y);
- }
-}
-
-void BarElement::printSegments(PSOutput* psPtr, BarPen* penPtr,
- Rectangle *bars, int nBars)
-{
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
- for (Rectangle *rp = bars, *rend = rp + nBars; rp < rend; rp++) {
- if ((rp->width < 1) || (rp->height < 1))
- continue;
-
- psPtr->fill3DRectangle(pops->fill, (double)rp->x, (double)rp->y,
- (int)rp->width, (int)rp->height,
- pops->borderWidth, pops->relief);
-
- if (pops->outlineColor) {
- psPtr->setForeground(pops->outlineColor);
- psPtr->printRectangle((double)rp->x, (double)rp->y,
- (int)rp->width, (int)rp->height);
- }
- }
-}
-
-void BarElement::printValues(PSOutput* psPtr, BarPen* penPtr,
- Rectangle *bars, int nBars, int *barToData)
-{
- BarPenOptions* pops = (BarPenOptions*)penPtr->ops();
- BarElementOptions* ops = (BarElementOptions*)ops_;
- BarGraphOptions* gops = (BarGraphOptions*)graphPtr_->ops_;
-
- int count = 0;
- const char* fmt = pops->valueFormat;
- if (!fmt)
- fmt = "%g";
- TextStyle ts(graphPtr_, &pops->valueStyle);
-
- for (Rectangle *rp = bars, *rend = rp + nBars; rp < rend; rp++) {
- double x = ops->coords.x->values_[barToData[count]];
- double y = ops->coords.y->values_[barToData[count]];
-
- count++;
- char string[TCL_DOUBLE_SPACE * 2 + 2];
- if (pops->valueShow == SHOW_X)
- snprintf(string, TCL_DOUBLE_SPACE, fmt, x);
- else if (pops->valueShow == SHOW_Y)
- snprintf(string, TCL_DOUBLE_SPACE, fmt, y);
- else if (pops->valueShow == SHOW_BOTH) {
- snprintf(string, TCL_DOUBLE_SPACE, fmt, x);
- strcat(string, ",");
- snprintf(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
- }
-
- Point2d anchorPos;
- if (gops->inverted) {
- anchorPos.y = rp->y + rp->height * 0.5;
- anchorPos.x = rp->x + rp->width;
- if (x < gops->baseline)
- anchorPos.x -= rp->width;
- }
- else {
- anchorPos.x = rp->x + rp->width * 0.5;
- anchorPos.y = rp->y;
- if (y < gops->baseline)
- anchorPos.y += rp->height;
- }
-
- ts.printText(psPtr, string, anchorPos.x, anchorPos.y);
- }
-}
-