#include <Xint/EditObject.h>
#include <Xint/Chart.h>
#include <Xint/DataGroup.h>
#include <Xint/DataSampled.h>
#include <Xint/BarLine.h>
static String x_labels[] = {"Houston", "Dallas", "Austin", "San Antonio"};
static float d1992[] = { 10.0, 20.0, 20.0, 8};
static float d1993[] = { 20.0, 35.0, 32.0, 17};
static float d1994[] = { 39.0, 41.0, 37.0, 21};
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
Widget top_level;
Widget edit;
Object data_group;
Object chart, plot;
XintGeometry chart_geometry;
top_level = XtAppInitialize(&app_context, "Chart Example",
(XrmOptionDescList)NULL, 0,
&argc, argv, NULL, NULL, 0);
/* Create an EditObject widget*/
edit = XtVaCreateManagedWidget("edit_object",
xintEditObjectWidgetClass,
top_level,
XmNwidth, 400,
XmNheight, 250,
/* make the chart editable */
XmNobjectEditMode, XintEDIT_ADJUST,
NULL);
/* Create Chart object */
chart_geometry.x1 = 0;
chart_geometry.y1 = 0;
chart_geometry.x2 = 100;
chart_geometry.y2 = 100;
chart = (Object) XtVaCreateWidget("BarPlot",
(WidgetClass)xintChartObjectClass,
edit,
XmNgeometry, &chart_geometry,
XmNchartType, XintCHART_TYPE_BAR,
XmNchartTitle, "Yearly Sales",
XmNshowLegend, True,
NULL);
/*
* I want the bars to be horizontal and stacked, with no space
* between the bars
*/
plot = XintChartGetComponent(chart, XintCHART_COMPONENT_PLOT);
XtVaSetValues((Widget) plot,
XmNbarOrientation, XintHORIZONTAL,
XmNbarStyle, XintSTACKED,
XmNclusterWidth, 100,
NULL);
/* Create a data group */
data_group = XintCreateDataGroup(edit, "Yearly Sales", NULL, 0);
XtVaCreateWidget("Cities", (WidgetClass)xintDataLabelObjectClass,
edit,
XmNlabelStrings, x_labels,
XmNlabelCount, sizeof(x_labels)/sizeof(String),
XmNlabelOrientation, XintLABEL_X,
XmNdataGroup, data_group,
NULL);
XtVaCreateWidget("1992",
(WidgetClass)xintDataSampledObjectClass, edit,
XmNdataArray, d1992,
XmNcount, sizeof(d1992)/sizeof(float),
XmNdataType, XintDATA_TYPE_FLOAT,
XmNdataGroup, data_group,
NULL);
XtVaCreateWidget("1993",
(WidgetClass)xintDataSampledObjectClass, edit,
XmNdataArray, d1993,
XmNcount, sizeof(d1993)/sizeof(float),
XmNdataType, XintDATA_TYPE_FLOAT,
XmNdataGroup, data_group,
NULL);
XtVaCreateWidget("1994",
(WidgetClass)xintDataSampledObjectClass, edit,
XmNdataArray, d1994,
XmNcount, sizeof(d1994)/sizeof(float),
XmNdataType, XintDATA_TYPE_FLOAT,
XmNdataGroup, data_group,
NULL);
/* Associate the data group with the chart object */
XintChartAssociateData(chart, data_group);
/* Loop forever */
XtRealizeWidget(top_level);
XtAppMainLoop(app_context);
}
The output from this example is shown below:

Figure 6: Horizontal Stacked Bars Example

In the figure above, Plot2D is the base class for all 2D plots. Depending on the type of chart selected it could be a BarLine object, a Pie object, a XYPlot object, etc. Series are generic objects that are associated with the data objects. See each appropriate plot section (such as BarLine or Pie) in Chapter 5 for a more complete description of the type of series created.

Figure 8: Components of a 2D chart.
The following table summarizes all the components that may be created inside a Chart object when a 2D plot is displayed.
| Component | Object Class | Description |
|---|---|---|
| Vertical Axis | AxisObject | Vertical axis associated with the plot area. |
| Horizontal Axis | AxisObject | Horizontal axis associated with the plot area. |
| Plot2D | BarLine CelllArray HighLow Histogram Pie XYPlot | Bar chart Grid of colored cells High-Low-Open-Close chart Histogram chart Pie chart Line, scattered or area charts. |
| Title | Text | Title for the chart. |
| Footer | Text | Footer for the chart. |
| Legend | Legend | Legend for the chart. |
| Series | Graphic | Object representing a data series. Type can vary (polyline, bars, wedge, etc.) based on the Plot2D class. Unless specified otherwise, use only resources defined in the Graphic class to customize attributes. |

Figure 9: Components created by a Chart in the case of a 3D plot.
In the figure above, Plot3D is the base class for all 3D plots. Depending on the type of chart selected it could be a Bar3D or a Surface object. See chart_demo.c in the demos directory, ChartDemo1 subdirectory. Selection 8 is illustrated in Figure 10.

The following table summarizes all the components that can be created inside a Chart object when a 3D plot is displayed.
| Component | Object Class | Description |
|---|---|---|
| Plot3D | Bar3D Surface3D | Bar3D chart. Surface chart. |
| Title | Text | Title for the chart. |
| Footer | Text | Footer for the chart. |
| Legend | Legend | Legend for the chart. |

Object chart, legend;
...
legend = XintChartGetComponent (chart, XintCHART_COMPONENT_LEGEND);
/* we set the legend border thickness, the # of columns and */
/* remove the fill. */
XtVaSetValue((Widget) legend, XmNlineThickness, 3, XmNfillStyle,
XintFILL_NONE, XmNcolumns, 2, NULL);
Series objects, whose number and type depends on the data associated with the chart and the chart type, cannot be retrieved with function XintChartGetComponent. Instead, you should use function XintChartGetSeriesOfData, which requires you to specify a data component. This function returns a list, which contains in most cases one series. It can also contain more than one series, for example, if transposition is set. The following code sample illustrates how to change the line style of the series used to display DataSampled object data_sampled.
Object chart, data_sampled;
Object *series_list;
int count;
...
series_list = XintChartGetSeriesOfData(chart, data_sampled, &count);
if (series_list != (Object *) NULL) {
XtVaSetValue((Widget) series_list[0], XmNlineStyle,
XintLINE_ON_OFF_DASH, NULL);
/* don't forget to free the list */
XtFree ((char *) series_list);
}
Chart resource XmNtranspose can be used to transpose the data contained in DataSampled objects. The transpose option is honored by BarLine, Pie and Bar3D plot classes. For example, when transpose is set for a Pie, each sample of a DataSampled object is represented as a wedge inside the same pie. In this case there would be one pie for each DataSampled object connected to the chart.
The Figure below, illustrates transposition for a dataset containing three DataSampled objects as described in the following table (see chart_demo.c in the demos directory, ChartDemo1 subdirectory, selection 17):
| DataSampled Name | Range (start, inc.) | Data Values (in thousands) |
|---|---|---|
| Cars | 1991, 1 | 650, 776, 821, 910 |
| Trucks | 1991, 1 | 170, 184, 191, 203 |
| Minivans | 1992, 1 | 95, 159, 245 (production started in 1992 !) |


The mechanism to combine plots is very flexible. You first create a chart with resource XmNchartType set XintCHART_TYPE_COMBINATION. You then retrieve the ID of the combo plot created and then create as many new plot types as you want inside the combo plot object using function XintComboPlotCreateNewPlot. If several plots have axes displayed on the same side, the axes will automatically be stacked next to each other.
You can combine as many primitive plot types as you want. However, since 3D plot types cannot be made transparent, you should not have more than one 3D plot in a combination plot.
#include <Xint/EditObject.h>
#include <Xint/Chart.h>
#include <Xint/ComboPlot.h>
#include <Xint/DataGroup.h>
#include <Xint/DataSampled.h>
#include <Xint/DataLabel.h>
#include <Xint/AxisObject.h>
static int high[] = { 3380, 3410, 3411, 3418, 3400, 3399, 3420, 3425, 3423,
3409, 3381, 3372, 3380, 3360, 3359, 3338, 3338, 3312,
3310, 3311, 3324, 3348, 3399, 3410, 3412, 3450 };
static int low[] = { 3321, 3360, 3350, 3350, 3348, 3349, 3370, 3366, 3369,
3350, 3339, 3324, 3322, 3339, 3309, 3268, 3297, 3263,
3256, 3264, 3268, 3286, 3325, 3361, 3378, 3390 };
static int open[] = { 3350, 3360, 3382, 3355, 3378, 3365, 3375, 3408, 3395,
3401, 3375, 3356, 3357, 3349, 3359, 3338, 3303, 3312,
3274, 3292, 3289, 3288, 3339, 3389, 3397, 3398 };
static int close[] = { 3360, 3382, 3355, 3378, 3365, 3375, 3408, 3395, 3401,
3375, 3356, 3357, 3349, 3359, 3338, 3303, 3312, 3274,
3292, 3289, 3288, 3339, 3389, 3397, 3398, 3450 };
static int volume[] = { 215123000, 192432123, 194145400, 189900143,
191893456, 204143657, 196143200, 185123456,
186458099, 194312765, 196234234, 184456567,
192334345, 196234246, 214523546, 201234566,
190233456, 199234567, 204455678, 206778456,
201233434, 189234356, 192324566, 189234567,
201232356, 196234565 };
static float label_position[] = { 0.0, 5.0, 10.0, 15., 20.0, 25 };
static char *date_strings[] = { "1/2/90", "1/9/90", "1/16/90", "1/23/30",
"1/30/90", "2/6/90" };
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
Widget top_level, edit;
Object data_group, volume_data;
Object chart, plot, bar_plot, high_low_plot, axis;
XintGeometry chart_geometry;
top_level = XtAppInitialize(&app_context, "high_low_test",
(XrmOptionDescList)NULL, 0,
&argc, argv, NULL, NULL, 0);
/* Create an edit object */
edit = XtVaCreateManagedWidget("edit", xintEditObjectWidgetClass,
top_level,
XmNwidth, 600,
XmNheight, 300,
NULL);
/* Create a data group */
data_group = XintCreateDataGroup(edit, "Dow Jones", NULL, 0);
XtVaCreateWidget("High", (WidgetClass)xintDataSampledObjectClass,
edit,
XmNdataArray, high,
XmNcount, sizeof(high)/sizeof(int),
XmNdataType, XintDATA_TYPE_INTEGER,
XmNdataGroup, data_group,
NULL);
XtVaCreateWidget("Low", (WidgetClass)xintDataSampledObjectClass,
edit,
XmNdataArray, low,
XmNcount, sizeof(low)/sizeof(int),
XmNdataType, XintDATA_TYPE_INTEGER,
XmNdataGroup, data_group,
NULL);
XtVaCreateWidget("Open", (WidgetClass)xintDataSampledObjectClass,
edit,
XmNdataArray, open,
XmNcount, sizeof(open)/sizeof(int),
XmNdataType, XintDATA_TYPE_INTEGER,
XmNdataGroup, data_group,
NULL);
XtVaCreateWidget("Close", (WidgetClass)xintDataSampledObjectClass,
edit,
XmNdataArray, close,
XmNcount, sizeof(close)/sizeof(int),
XmNdataType, XintDATA_TYPE_INTEGER,
XmNdataGroup, data_group,
NULL);
/* Create a Date label object */
XtVaCreateWidget("Date", (WidgetClass)xintDataLabelObjectClass,
edit,
XmNlabelCount, 6,
XmNlabelOrientation, XintLABEL_X,
XmNlabelPositionArray, label_position,
XmNlabelStrings, date_strings,
XmNdataGroup, data_group,
NULL);
/* Create volume data */
volume_data = (Object) XtVaCreateWidget("Volume",
(WidgetClass)xintDataSampledObjectClass,
edit,
XmNdataArray, volume,
XmNcount, sizeof(volume)/sizeof(int),
XmNdataType, XintDATA_TYPE_INTEGER,
NULL);
/* 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);
plot = XintChartGetComponent(chart, XintCHART_COMPONENT_PLOT);
bar_plot = XintComboPlotCreateNewPlot(plot, XintPLOT_TYPE_BAR);
XintChartAssociateData(bar_plot, volume_data);
high_low_plot = XintComboPlotCreateNewPlot(plot, XintPLOT_TYPE_HIGH_LOW);
XintChartAssociateData(high_low_plot, data_group);
/* Position the axes */
XtVaSetValues((Widget) bar_plot,
XmNxAxisPlacement, XintPLACEMENT_NONE,
XmNyAxisPlacement, XintPLACEMENT_RIGHT, NULL);
XtVaSetValues((Widget) high_low_plot,
XmNxAxisPlacement, XintPLACEMENT_BOTTOM,
XmNyAxisPlacement, XintPLACEMENT_LEFT, NULL);
/* Change the format of the vertical axis for the volume */
axis = XintComboPlotGetComponent(plot, XintCHART_COMPONENT_VERTICAL_AXIS,
0);
XtVaSetValues((Widget) axis, XmNannotationFormat, "%.0f", NULL);
XtRealizeWidget(top_level);
XtAppMainLoop(app_context);
}
Plot composition is handled by the ComboPlot class, which is a special class that manages multiple primitive plot types, such as BarLine, XYPlot, HighLow, etc. ComboPlot function XintComboPlotCreateNewPlot allows you to create a new plot of the type you want. The diagram below illustrates the relationships among the various objects created in the example above.

typedef struct {
float minimum;
float maximum;
} XintLimits;
If you want the auto-scaling to apply only to the minimum or the maximum, you can set one of the fields to constant XintUNDEFINED_FLOAT. For example, to set the minimum value to 0 and to let the maximum be calculated automatically you can specify the following:
Object plot;
XintLimits y_limits;
...
y_limits.minimum = 0;
y_limits.maximum = XintUNDEFINED_FLOAT;
XtVaSetValues ((Widget) Plot, XmNyLimits, &y_limits, NULL);
The code sample shown below illustrates how simple it is to save a chart object in template form.
Object chart;
...
XintChartSaveTemplate("template", &chart, 1);
Because only the visual attributes are saved, charts are associated with new data when they are restored in another application. They may then be modified by convenience functions in that application. In fact, any processing that can be performed on chart objects can be performed on the restored templates. The function, XintChartReadTemplate, reads the chart objects stored in a template file created by XintChartSaveTemplate. Using a list of data groups, it associates a data group with each chart object from the file.
The following code shows how to restore a chart from disk.
Widget edit;
Object data_group, *list;
int object_count;
...
list = XintChartReadTemplate(edit, "template", &data_group,
1, &object_count);
Two other functions, XintEditObjectWriteFile and XintEditObjectReadFile, can be used to save and restore objects. These functions read and write the entire object description, including the associated data. They are described in the EditObject Widget Class section of this manual.