Both of these features are made possible because of the object oriented nature of ChartObject, which gives the application the ability to create and insert inside a chart any object from the GraphicObject library.
Objects inserted inside a chart use the chart coordinate system, which ranges from 0 to 100, with the origin at the upper left corner. Objects inserted in a chart object are clipped to the chart object boundaries.
Objects inserted inside a Plot2D (BarLine, XYPlot, etc.) use the user coordinates specified by the axes attached to the plot. Objects in a plot object are clipped to the plot boundaries. Also, objects inserted in a plot object will be destroyed when the application changes plot type. Use the function XintChartGetComponent to get the object ID of the plot object to use in the XintChartInsertObject function call.
The following code sample illustrates how to insert an object inside a chart.
XintLine gline;
Object chart, line;
...
/* create a line object */
gline.start_x = gline.start_y = 0;
gline.end_x = gline.end_y = 10;
line = (Object) XtVaCreateWidget ("Line",
(WidgetClass)xintLineObjectClass, edit,
XmNline, &gline,
XmNlineThickness, 3, NULL);
/* insert line object inside a chart object */
XintChartInsertObject(chart, line);
Object chart, plot, image;
Pixel pixel_array[32];
int ncolors = 32;
XintRectangle rect;
...
/*
* We assume we have allocated 32 colors containing a continuous
* color spectrum. We now create a pixmap of width 1 and
* height 32. The ImageObject will automatically interpolate the
* pixmap to fit the chart size.
*/
pixmap = XCreatePixmap(display,
RootWindow(display, IntScreenNumber(top_level)),
1, ncolors,
DefaultDepth(display, IntScreenNumber(top_level)));
gc = XCreateGC(display, pixmap, 0, NULL);
for (i=0; i<ncolors; i++) {
XSetForeground(display, gc, pixel_array[ncolors-i-1]);
XDrawPoint(display, pixmap, gc, 0, i);
}
...
/* Create a chart inside the edit object */
chart_geometry.x1 = chart_geometry.y1 = 0;
chart_geometry.x2 = chart_geometry.y2 = 100;
chart = (Object) XtVaCreateWidget("combination_chart",
(WidgetClass)xintChartObjectClass, edit,
XmNgeometry, &chart_geometry,
XmNchartType, XintCHART_TYPE_COMBINATION,
XmNchartTitle, "Dow Jones Industrial Average",
NULL);
...
/*
* Create image object, "pixmap", as the background of the chart
*/
rect.x1 = 0;
rect.y1 = 0;
rect.x2 = 100;
rect.y2 = 100;
image = (Object) XtVaCreateWidget("Image",
(WidgetClass)xintImageObjectClass,
edit,
XmNsensitive, False,
XmNimagePixmap, pixmap,
XmNimageColorRecord, color_record,
XmNrectangle, &rect,
NULL);
plot = XintChartGetComponent(chart, XintCHART_COMPONENT_PLOT);
/*
* Make plot transparent so that we can see the image
*/
XtVaSetValues((Widget) plot, XmNfillStyle, XintFILL_NONE, NULL);
/*
* Insert object into to the chart and lower it
*/
XintChartInsertObject(chart, image);
XintEditObjectBack(edit, image);
...

Figure 22: Customized Chart
#include <Xint/Chart.h>
#include <Xint/EditObject.h>
#include <Xint/Line.h>
#include <math.h>
extern double drand48();
#define COUNT 1000
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
Widget top_level;
Widget edit;
Object chart, plot;
XintGeometry chart_geometry;
XintLimits limits;
XintIncrements increment;
Pixel pixel;
register int i;
top_level = XtAppInitialize(&app_context, "chart_field",
(XrmOptionDescList)NULL, 0,
&argc, argv, NULL, NULL, 0);
/* Create an EditObject widget*/
edit = XtVaCreateManagedWidget("edit_object",
xintEditObjectWidgetClass,top_level,
XmNwidth, 600, XmNheight, 600,
XmNtitle, "Vector Field", NULL);
/* Create Chart object */
chart_geometry.x1 = 0;
chart_geometry.y1 = 0;
chart_geometry.x2 = 100;
chart_geometry.y2 = 100;
chart = (Object) XtVaCreateWidget("LinePlot",
(WidgetClass)xintChartObjectClass,
edit,
XmNgeometry, &chart_geometry,
XmNchartType, XintCHART_TYPE_LINE,
XmNchartTitle, "Vector FieldPlot",
XmNresourceDialog, False,
NULL);
plot = XintChartGetComponent(chart, XintCHART_COMPONENT_PLOT);
/* Set the plot limits and increments */
limits.minimum = 0;
limits.maximum = 1.0;
increment.minor_increment = .25;
increment.major_increment = .5;
XtVaSetValues(plot,
XmNxLimits, &limits,
XmNyLimits, &limits,
XmNxIncrements, &increment,
XmNyIncrements, &increment,
XmNxAxisPlacement, XintPLACEMENT_TOP_BOTTOM,
XmNyAxisPlacement, XintPLACEMENT_LEFT_RIGHT,
XmNresourceDialog, False,
NULL);
srand48((long) 100);
pixel = XintLoadColor(XtDisplay(edit), "red");
for (i=0; i<COUNT; i++) {
Object arrow;
XintLine line;
float x = drand48();
float y = drand48();
float size = .05;
float angle = sin((double) 3.14 * x) + .2 * cos((double) 3.14 * y);
line.start_x = x;
line.start_y = y;
line.end_x = x + size * cos((double) angle);
line.end_y = y + size * sin((double) angle);
/*
* Create arrow object
* Note: the color and the size of the arrows are the same here,
* but they could be set to be different for each object.
*/
arrow = (Object) XtVaCreateWidget("arrow",
(WidgetClass)xintLineObjectClass,
edit,
XmNlineEnd, XintEND_ARROW,
XmNarrowStyle, XintSTICK,
XmNarrowLength, 4,
XmNtipAngle, 15,
XmNline, &line,
XmNlineThickness, 1,
XmNsensitive, False,
XmNcolor, pixel,
NULL);
/*
* Insert arrow object inside the plot
*/
XintChartInsertObject(plot, arrow);
}
XtRealizeWidget(top_level);
XtAppMainLoop(app_context);
}

Figure 23: Creating a New Chart Type