The Chart library facilitates the creation of zoom applications by providing the XmNareaSelectionCallback resource and the XintChartZoom convenience function. They enable the application designer to change the data displayed in the viewport easily.
In the figure shown below, a subset of the data between 1993 and 2003 has been zoomed from the background plot to fill the viewport in the foreground plot. The code which produced this display follows a discussion of the viewport.


If XintLimits is NULL, autoranging is performed and the minimum and maximum data values will be used. Either raw data values or rounded data values can be selected through the use of the XmNxAutoRange and XmNyAutoRange resources. Autoranging of a single parameter in the XintLimits structure may be achieved by setting it to XintUNDEFINED_FLOAT. The following code segments illustrate these capabilities.
/* Define the Y Axis Range */
XintLimits yRange;
yRange.minimum = 0.0;
yRange.maximum = XintUNDEFINED_FLOAT;
/* Create a Chart object */
chart = (Object) XtVaCreateWidget("BarPlot",
(WidgetClass)xintChartObjectClass,
edit,
XmNgeometry, &chart_geometry,
XmNchartType, XintCHART_TYPE_BAR,
XmNchartTitle, "Yearly Sales",
XmNshowLegend, True,
NULL);
/*
* Get the plot object ID.
*/
plot = XintChartGetComponent(chart, XintCHART_COMPONENT_PLOT);
XtVaSetValues((Widget) plot,
XmNxLimits, NULL,
XmNxAutoRange, XintROUND_MIN_MAX,
XmNyLimits, &yRange,
NULL);
The XintChartZoom convenience function zooms the selected area by mapping it to the plot area. XmNxLimits and XmNyLimits are set to the range of the selected area.
XintChartZoom(zoom_chart, cb->x, cb->y, cb->width, cb->height);
#include <Xm/Form.h>
#include <Xm/Separator.h>
#include <Xm/PushBG.h>
#include <Xm/RowColumn.h>
#include <Xint/Chart.h>
#include <Xint/EditObject.h>
/*
* Define PushButton controls
*/
#define k_zoom 0
#define k_zoom_reset 1
#define k_exit 2
#define k_num_controls 3
static char *control_pb_names[] = {"Zoom", "Zoom Reset", "Exit"};
/*
* Create two translation tables; one as the default and the other
* specifically for zoom actions.
*/
static char default_translations[] =
"None <Btn1Down>: TraverseCurrent() \
ObjectSelect(single)\
ObjectEditStart() Locator() SelectionCallback()\
InitAreaSelection(single) ResourceDialog()";
static char zoom_translations[] =
"None <Btn1Down>: TraverseCurrent() \
InitAreaSelection(callback)";
XtTranslations default_translations_parsed;
XtTranslations zoom_translations_parsed;
/*
* Other Global Variables
*/
Widget edit;
Object zoom_chart = NULL;
/*
* The ZoomCallback illustrates an easy method to zoom a plot. It is
* activated by the Btn1Down zoom button translation. To perform the
* zoom, it calls the XintChartZoom convenience function with argument
* values from the XintEditObjectAreaSelectionCallbackStruct.
*/
static void ZoomCallback(widget, data, cb)
Widget widget;
XtPointer data;
XintEditObjectAreaSelectionCallbackStruct *cb;
{
Object chart = (Object) data;
if (zoom_chart == NULL) return;
XintChartZoom(zoom_chart, cb->x, cb->y, cb->width, cb->height);
zoom_chart = NULL;
}
/*
* The following code defines the callback that controls the action for
* all of the pushbuttons.
*/
static void ControlsProc(widget, client_data, cb)
Widget widget;
XtPointer client_data;
XmAnyCallbackStruct *cb;
{
int code = (int) client_data;
Object chart, plot;
Object *list;
int count;
register int i;
if (code == k_exit) exit (0);
/*
* Retrieve object list to find ID of chart
*/
list = XintEditObjectGetList(edit, &count);
for (i=0; i<count; i++)
if (XintIsChart(list[i])) break;
if (i <= count) return;
plot = XintChartGetComponent(list[i], XintCHART_COMPONENT_PLOT);
/*
* Return if it is a 3D plot
*/
if (XintIsPlot3D(plot)) return;
if (code == k_zoom) {
/*
* Merge zoom_translations_parsed with the EditObject
* widget's existing translations. Zoom will be activated
* when the end-user defines a rectangle with Button1
*/
XtOverrideTranslations(edit, zoom_translations_parsed);
zoom_chart = list[i];
} else if (code == k_zoom_reset) {
/*
* Reset the zoom. The plot is restored to its original
* size by autoranging each axis.
*/
XtVaSetValues((Widget) plot, XmNxLimits, NULL, XmNyLimits,
NULL, NULL);
}
}
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
Widget top_level, main_form, separator, controls_box, pb;
Object chart;
XmString cstring;
register int i;
top_level = XtAppInitialize(&app_context, "Zoom Example",
(XrmOptionDescList)NULL, 0,
&argc, argv, NULL, NULL, 0);
/*
* Parse and compile the default and zoom translation tables.
*/
default_translations_parsed = XtParseTranslationTable(
default_translations);
zoom_translations_parsed = XtParseTranslationTable(zoom_translations);
/*
* Create form to contain all other widgets
*/
main_form = XtVaCreateManagedWidget("main_form",
xmFormWidgetClass, top_level,
NULL);
/*
* Create an EditObject widget
*/
edit = XtVaCreateManagedWidget("edit_object",
xintEditObjectWidgetClass,main_form,
XmNwidth, 600,
XmNheight, 600,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
/*
* Register callback to zoom a plot. The function is called when
* a rectangle is selected if zoom has been activated
*/
XtAddCallback(edit, XmNareaSelectionCallback,
(XtCallbackProc) ZoomCallback, NULL);
/*
* Create a Separator widget
*/
separator = XtVaCreateManagedWidget("separator",
xmSeparatorWidgetClass, main_form,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, edit,
XmNtopOffset, 20,
XmNbottomOffset, 20,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
/*
* Create controls box
*/
controls_box = XtVaCreateManagedWidget("controls_box",
xmRowColumnWidgetClass, main_form,
XmNspacing, 15,
XmNorientation, XmHORIZONTAL,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, separator,
NULL)
/*
* Create control pushbuttons
*/
for (i=0; i<k_num_controls; i++) {
cstring = XmStringCreateSimple(control_pb_names[i]);
pb = XtVaCreateManagedWidget("control_buttons",
xmPushButtonGadgetClass, controls_box,
XmNpushButtonEnabled, True,
XmNmarginWidth, 4,
XmNmarginHeight, 4,
XmNlabelString, cstring,
NULL);
XtAddCallback(pb, XmNactivateCallback,
(XtCallbackProc) ControlsProc, (XtPointer)i);
XmStringFree(cstring);
}
/*
* Read chart description from file
*/
if (!XintEditObjectReadFile(edit, "chart_zoom.obj")) {
fprintf(stderr, "Cannot find file chart_zoom.obj");
exit(1);
}
XtRealizeWidget(top_level);
XtAppMainLoop(app_context);
}