(class)
public abstract Chart
{inherits
Shape}
An abstract class representing a data-driven chart. Implementations include LayeredChart and PieChart.
Description
A
Chart is a
Shape object.
Shapes are not
Graphic objects, but can be displayed in a standard graphical hierarchy using
ShapeBox,
ChartBox or
Canvas.
ChartBox will be created implicitly for you whenever you insert a
Chart into a graphical hierarchy. Most of the examples in
CURL.GUI.CHARTS make use of this property. You can also explicitly create a
ChartBox to place a border around a chart, or give it a background color. Alternatively, you can put a
Chart in a
Canvas, along with other
Shapes.
Most elements of charting are delegated to the actual implementations. The
Chart class is responsible for controlling the chart layout system and overseeing high-level legend creation and placement.
For a discussion of layout, please see
Chart.invalidate-layout. For a discussion of legend creation at the
Chart level, see
Chart.create-legend,
Chart.legend-factory, and
Chart.legend-entry-factory.
| default: | Constructs a new Chart object. |
| constructor
public
| {Chart.default width:Distance = -1m, height:Distance = -1m, legend-location:LegendLocation = LegendLocation.right, legend-alignment:double = 0.2, color-palette:{Array-of FillPattern} = default-chart-color-palette, ... } |
| bottom-margin: | The amount of space allocated to the Chart's bottom margin. |
local option public Chart.bottom-margin:
any =null
field public Chart.color-palette:{
Array-of FillPattern}
| default-height: | The height that this Chart should use when none has been specified. |
accessor public Chart.default-height:
Distance
| default-width: | The width that this Chart should use when none has been specified. |
accessor public Chart.default-width:
Distance
nonlocal option public Chart.font-family:
String
| font-size: | Specifies the default size of the text within an object. |
nonlocal option public Chart.font-size:
any
| font-style: | Specifies whether text within the object should be a slanted font such as italic or oblique. |
nonlocal option public Chart.font-style:
FontStyle
| font-weight: | Specifies whether text within the object should be specially weighted as bold. |
nonlocal option public Chart.font-weight:
FontWeight
| height: | The current height of the chart. |
field public-get private-set Chart.height:
Distance =-1m
accessor public final Chart.layout-scheduled?:
bool
| left-margin: | The amount of space allocated to the Chart's left margin. |
local option public Chart.left-margin:
any =null
accessor public Chart.legend-alignment:
double setter public Chart.legend-alignment:
double
nonlocal option public Chart.legend-enabled?:
bool
field public constant Chart.plot-area-bounds:
GRect ={GRect.empty}
| right-margin: | The amount of space allocated to the Chart's right margin. |
local option public Chart.right-margin:
any =null
accessor public Chart.style-element:
String
nonlocal option public Chart.text-line-through?:
bool
| text-underline?: | Specifies whether text within this object will be underlined. |
nonlocal option public Chart.text-underline?:
bool
| top-margin: | The amount of space allocated to the Chart's top margin. |
local option public Chart.top-margin:
any =null
| width: | The current width of the chart. |
field public-get private-set Chart.width:
Distance =-1m
Properties inherited from Shape:
as-Shape, border-color, color, draw-operation, option-parent, selection-context, shape-parent, shape-selectable, stroke-thickness, transformation, visible? Properties inherited from Visual:
_style-element, clonable-class?, completely-clonable-children?, cursor, data-source, dragee, input-method-enabled?, input-method-keyboard-mode, name, options, options-present-here, style-class, style-manager, style-options, test-description, test-name, test-parent?, test-type-name, test-visible?, tooltip, user-data
public constant Chart.LegendFactory:
ProcType ={proc-type
{chart:Chart,
include-scrollbox?:bool
}:#Graphic
}
|
public
| {Chart.default-legend-factory chart:Chart, include-scrollbox?:bool }:#Graphic |
|
public
| {Chart.create-legend include-scrollbox?:bool = false}:#Graphic |
| draw: | Draw this object's visual representation. |
|
public
| {Chart.ensure-layout-valid force-layout?:bool = false}:void |
|
protected abstract
| {Chart.estimate-margins need-left?:bool, need-right?:bool, need-top?:bool, need-bottom?:bool, left:Distance, right:Distance, top:Distance, bottom:Distance }:(left:Distance,
right:Distance,
top:Distance,
bottom:Distance) |
|
public final
| {Chart.get-actual-bottom-margin}:Distance |
|
public final
| {Chart.get-actual-left-margin}:Distance |
|
public final
| {Chart.get-actual-right-margin}:Distance |
|
public final
| {Chart.get-actual-top-margin}:Distance |
|
public abstract
| {Chart.get-legend-entries}:{Array-of Graphic} |
| get-own-bounds: | Calculate the rectangular rendering bounds of this Shape, in its local coordinate system. |
|
public
| {Chart.get-own-bounds dest:GRect = {GRect.empty}}:GRect |
| get-shape-layout-bounds: | Calculate the rectangular layout bounds of this object and its children in the local coordinate system of this object. |
|
public
| {Chart.invalidate-layout}:void |
| layout-chart: | Perform the actual process of layout for this chart. |
|
public
| {Chart.layout-chart}:void |
|
public
| {Chart.note-color-palette-changed}:void |
|
public
| {Chart.position-legend}:void |
|
public
| {Chart.request-draw layout-context:LayoutContext = {self.get-layout-context} }:void |
|
public
| {Chart.transformation-changed}:void |
|
protected abstract
| {Chart.update-layout}:void |
Methods inherited from Shape:
apply-rotation, apply-scale, apply-transformation, apply-translation, apply-translation-in-parent, constrain-shape-layout-bounds, contains-point?, detach, find-graphical-ancestor, fire-crossing-event, fire-in-child, get-display-context, get-down-orientation-in-shape-parent, get-graphical-root, get-local-device-pixel-size, get-origin-in-graphical-ancestor, get-origin-in-root, get-origin-in-shape-parent, get-origin-in-shape-root, get-own-bounds-in-shape-root, get-own-layout-bounds, get-right-orientation-in-shape-parent, get-shape-bounds, get-shape-bounds-in-shape-root, get-top-left-in-ancestor, get-transformation-to-shape-root, keyword-init-arg, option-change-notify, overdraw-for-selection, quantize-line-thickness, request-draw-self, reset-transformation, set-rotation, set-scale, set-transformation, set-translation-in-parent, transform-from-display-coordinates, transform-from-graphical-root-coordinates, transform-point-from-shape-root, transform-point-to-shape-root, transform-to-display-coordinates, transform-to-graphical-root-coordinates, transform-vector-from-shape-root, transform-vector-to-shape-root, transformation-changing Methods inherited from ShapeContainerBase:
add, clear, draw-shape-child, draw-shape-children, get-all-children-at-point, get-child-at-point, get-leaf-at-point, get-shape-root, note-attached, note-detaching, notify-option-children, on-drag-enter, on-pointer-enter, on-pointer-envelope-event, register-options, remove, set-shape-index, set-shape-index-after, set-shape-index-before, shape-container-fire-inferior-crossing-event, shape-container-handle-crossing, shape-container-pick-child, shape-container-pointer-enter-occurred, shape-container-pointer-leave-occurred Methods inherited from Visual:
add-from-init-args, add-option, add-style-option, animate, change-cursor, clonable-appearance?, clone-appearance, clone-appearance-helper, find-test-children, get-focus-manager, get-layout-context, get-test-parent, get-test-property, get-text, get-view, maybe-fire-attach-event, maybe-fire-detach-event, non-keyword-init-arg, note-caret-position, on-drag-leave, on-pointer-leave, pop-cursor, prepare-test-object, prepare-test-parent, push-cursor, quantize-width, release-key-focus, remove-option, remove-style-option, request-key-focus, scroll-to-include, test-record, test-run, xy-offset-to Methods inherited from GuiEventTarget:
handle-event, on-action, on-cancel-mode, on-command-changed, on-commit, on-composition-change-event, on-composition-result-event, on-context-menu-event, on-current-record-change-request, on-current-record-changed, on-destroy-notify, on-destroy-requested, on-drag-over, on-drag-pointer, on-drag-started, on-drop, on-end-composition-event, on-focus-event, on-focus-in, on-focus-out, on-grab-release, on-gui-event, on-input-method-event, on-inspection, on-key-event, on-key-press, on-pointer-button, on-pointer-crossing, on-pointer-event, on-pointer-motion, on-pointer-press, on-pointer-release, on-pointer-scroll, on-raw-key-event, on-raw-key-press, on-raw-key-release, on-reset, on-selectable-added, on-selectable-removed, on-selection-changed, on-selection-context-activated, on-selection-context-deactivated, on-selection-event, on-start-composition-event, on-start-event, on-stop-event, on-view-activate, on-view-deactivate, on-window-close, remove-event-handlers-for-event-class Methods inherited from OptionListInterface:
change-option-parent-notify, clone-options, get-option, get-option-by-name, local-add-notify, local-remove-notify, name-to-option-key, new-option-item, option-changed, option-lookup, option-lookup-here, option-propagate-notify, option-set?, propagate-option-change, remove-styles, set-option-by-name, set-style-option-by-name, unset-option-by-name, unset-style-option-by-name
(constructor)
| public
| {Chart.default width:Distance = -1m, height:Distance = -1m, legend-location:LegendLocation = LegendLocation.right, legend-alignment:double = 0.2, color-palette:{Array-of FillPattern} = default-chart-color-palette, ... } |
Constructs a new Chart object.
...: Arguments passed to the constructor
Shape.default. Options may be initialized using keyword arguments. Non-keyword arguments may be
EventHandlers,
DataBindings, or
Shape objects to be added as children of this object.
Description
This constructor is only used by subclasses of Chart.
(local option)
public Chart.bottom-margin:
any =null
The amount of space allocated to the Chart's bottom margin.
Description
Please see
Chart.height and
Chart.plot-area-bounds for a discussion of layout and the role margins play. See also
Chart.get-actual-bottom-margin, which computes an actual result based on this option and the contents of the chart.
Legal types of values are:
The default value is
null, which instructs the
Chart to estimate the amount of margin required to accomodate its non-plot elements and use that value.
Examples of legal values include:
- 2cm
- 1.5in
- 36pt
- 3px
- 36 (which is the same as 36pt)
Please see
Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.
Example
(field)
public Chart.color-palette:{
Array-of FillPattern}
An array of FillPatterns to be used when plotting data series.
Description
As each data series is plotted, this array is iterated through. Thus, the first
FillPattern will be used for the first data series, the second
FillPattern for the second data series, and so on. If there are more series than elements in this array, iteration will start over from the beginning.
By default, this value refers to
default-chart-color-palette, and so this array is shared by all charts within the same applet.
You may modify the colors used either by setting this field to use a different array, or by modifying
default-chart-color-palette directly. However, in either case, you are responsible for informing any charts using the array of the change by calling
Chart.note-color-palette-changed.
Notes
Example
This example demonstrates the use of
LinearGradientFillPatterns as colors for a bar chart:
| Example |
 |
{import * from CURL.GUI.CHARTS}
{import * from CHARTS-DOC,
location = "../docstring-support/gui/charts-doc.scurl"
}
{define-proc package {h-gradient
start-color:FillPattern,
highlight-color:FillPattern,
end-color:FillPattern,
highlight-pos:double = 0.2
}:FillPattern
{return
{LinearGradientFillPattern
{Fraction2d 0, 0},
{Fraction2d 1, 0},
{Spectrum.from-envelope
start-color,
0.0,
highlight-color,
highlight-pos,
end-color,
1.0
}
}
}
}
{LayeredChart
width = 15cm,
height = 6cm,
color-palette =
{new {Array-of FillPattern},
{h-gradient "gray", "white", "gray"},
{h-gradient "blue", "lavender", "steelblue"},
{h-gradient "red", "mistyrose", "crimson"},
{h-gradient "purple", "lavender", "blueviolet"},
{h-gradient "lime", "mintcream", "green"}
},
{BarLayer
sample-records,
"Wins",
"Points",
"Age"
}
}
| |
The following example allows you to change the first element of the array using a drop-down list. Note that it modifies the global array; if there were other charts in this applet, then it would need to either use a special array for this chart, or notify the other charts of modifications too.
| Example |
 |
{import * from CURL.GUI.CHARTS}
{import * from CHARTS-DOC,
location = "../docstring-support/gui/charts-doc.scurl"
}
{RecordGrid height = 6cm, record-source = sample-records}
{let chart:LayeredChart =
{LayeredChart
width = 15cm,
height = 6cm,
left-axis = {new {NumericAxis-of double}, 0, 70},
right-axis = {ChartAxis {ChartDataSeries sample-records, "Height"}},
{BarLayer
{ChartDataSeries sample-records, "Age"},
{ChartDataSeries sample-records, "Wins"},
{ChartDataSeries sample-records, "Height"},
x-axis-data = {ChartDataSeries sample-records, "Name"}
}
}
}
{value chart}
First element of color-palette:
{DropdownList
"black", "blue", "turquoise", "purple", "crimson",
list-item-creation-proc =
{proc {val:any}:ListItem
{return
{ListValueItem
value=val,
{RectangleGraphic fill-color=val,
width=50pt, height=10pt
}
}
}
},
{on ValueChanged at ddl:DropdownList do
set chart.color-palette[0] = ddl.value asa FillPattern
{chart.note-color-palette-changed}
}
}
| |
(accessor)
accessor public Chart.default-height:
Distance The height that this Chart should use when none has been specified.
Description
The
Chart must declare a size preference in
get-own-bounds, so if no preference was specified in the constructor or via
set-chart-size (or a negative value was specified), then this value will be used instead.
(accessor)
accessor public Chart.default-width:
Distance The width that this Chart should use when none has been specified.
Description
The
Chart must declare a size preference in
get-own-bounds, so if no preference was specified in the constructor or via
set-chart-size (or a negative value was specified), then this value will be used instead.
(nonlocal option)
The DisplayContext associated with this object.
Programming Notes
This option is used for communication purposes within the Curl graphics system. It should not be casually set or unset by user code. It should also not usually be read directly by user code: if you want the current
DisplayContext, you should fetch it by calling
Visual.get-display-context.
Every graphic hierarchy that can be displayed, whether in a window on the screen or on a printed page, must have at its root an object that sets the
display-context option to a
DisplayContext object that is suitable for the display medium by means of which the graphic hierarchy will be seen. Thus, an object can tell that it has been attached to a displayable graphic hierarchy by watching for the
display-context option's value to change from
null to a non-
null DisplayContext object. Accordingly, subclasses of
Visual that need to take specific actions when they become connected to a displayable graphic hierarchy monitor the
display-context option by including an option declaration such as
{nonlocal-option public display-context:#DisplayContext
change handler}where the code in
change handler looks at the current value of the
display-context option (available within the change handler as the value of the variable
display-context), watching for changes between
null and non-
null values, and takes any actions that are needed.
Programmers using this programming idiom should be aware, however, that it is fairly common when rearranging graphical displays to detach graphical objects temporarily from a graphic hierarchy and then reattach them to the same hierarchy, which will cause the detached objects to temporarily see the
display-context object become
null and then become non-
null again. Code that monitors changes in the
display-context option should take this possibility into account and avoid taking undesired actions in this case.
(nonlocal option)
public Chart.font-family:
String Sets the font family for text.
Description
Specifies a font family name (or list of names) that should be used when locating a font for rendering text.
See
Font for more information about specifying fonts.
| Example |
 |
{VBox
{text font-family = "serif", serif},
{text font-family = "sans-serif", sans-serif},
{text font-family = "monospace", monospace},
{text
font-family = "Arial, Nimbus Sans L, sans-serif",
prefer a particular sans-serif
},
{text
font-family =
"Times New Roman, Nimbus Roman No9 L, serif",
prefer a particular serif
}
}
| |
(nonlocal option)
public Chart.font-size:
any Specifies the default size of the text within an object.
Description
This size is expressed as a
Distance, which is a quantity supporting linear measures. Other quantities support weight, temperature, and another categories of measurement units.
Examples of
Distance units include
pt (point),
in (inch),
cm (centimeter), and others. The complete list of supported
Distance units is available in the
Quantities and Units chapter.
When specifying a quantity value, do not leave any space between the number and the unit;
8pt and
4mm are two examples of valid
font-size values.
Example
Here are several ways of specifying the size of text using the
font-size option. Note how the text object with the word "Medium" has obtained its font size from the text object containing it.
| Example |
 |
{text font-size=12pt,
{text font-size=8pt, Little}
{text font-size=1cm, Pretty big}
{text Medium}
{text font-size=1in, Huge!}
}
{text And this is the default}
| |
See Also
(nonlocal option)
Specifies whether text within the object should be a slanted font such as italic or oblique.
Description
Valid values are as follows:
- "italic": Either an oblique or italic font face; whichever is available.
- "normal": Do not use a slanted font.
This option affects the appearance of text in controls provided that the nonlocal option
ControlFrame.control-appearance-changeable? is true on the control. Note that if
Dialog.use-look-and-feel? is true on a
Dialog MenuPane or
MenuBar, the font-style is automatically set to a value specified by the look and feel so that setting the value on the dialog or menu will have no effect.
Example
| Example |
 |
{paragraph font-style="italic", Everything in this paragraph
should be in an italic font,
{text font-style="normal", except for this text fragment.}
}
| |
See Also
(nonlocal option)
Specifies whether text within the object should be specially weighted as bold.
Description
Valid values are as follows:
- "bold": Display the text in bold.
- "normal": Do not display the text in bold.
This option affects the appearance of text in controls provided that the nonlocal option
ControlFrame.control-appearance-changeable? is true on the control. Note that if
Dialog.use-look-and-feel? is true on a
Dialog MenuPane or
MenuBar, the font-weight is automatically set to a value specified by the look and feel so that setting the value on the dialog or menu will have no effect.
Example
| Example |
 |
{paragraph Everything in this paragraph
should be normally weighted,
{text font-weight="bold", except for this text fragment.}
}
| |
See Also
The character format:
bold
(field)
public-get private-set Chart.height:
Distance =-1m
The current height of the chart.
Description
(accessor)
accessor public final Chart.layout-scheduled?:
bool Indicates whether a layout operation is pending on this Chart.
Description
(local option)
public Chart.left-margin:
any =null
The amount of space allocated to the Chart's left margin.
Description
Please see
Chart.width and
Chart.plot-area-bounds for a discussion of layout and the role margins play. See also
Chart.get-actual-left-margin, which computes an actual result based on this option and the contents of the chart.
Legal types of values are:
The default value is
null, which instructs the
Chart to estimate the amount of margin required to accomodate its non-plot elements and use that value.
Examples of legal values include:
- 2cm
- 1.5in
- 36pt
- 3px
- 36 (which is the same as 36pt)
Please see
Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.
Example
| Example |
 |
{import * from CURL.GUI.CHARTS}
{import * from CHARTS-DOC,
location = "../docstring-support/gui/charts-doc.scurl"
}
{RecordGrid height = 6cm, record-source = sample-records}
{let chart:LayeredChart =
{LayeredChart
width = 15cm,
height = 6cm,
left-axis = {new {NumericAxis-of double}, 0, 70},
right-axis = {ChartAxis {ChartDataSeries sample-records, "Height"}},
{LineLayer
{ChartDataSeries sample-records, "Age"},
{ChartDataSeries sample-records, "Wins"},
{ChartDataSeries sample-records, "Height"},
x-axis-data = {ChartDataSeries sample-records, "Name"}
}
}
}
{let left:TextField =
{TextField
value = "null",
{on ValueFinished at tf:TextField do
let val:String = tf.value
set chart.left-margin = {evaluate val}
}
}
}
{let right:TextField =
{TextField
value = "null",
{on ValueFinished at tf:TextField do
let val:String = tf.value
set chart.right-margin = {evaluate val}
}
}
}
{let top:TextField =
{TextField
value = "null",
{on ValueFinished at tf:TextField do
let val:String = tf.value
set chart.top-margin = {evaluate val}
}
}
}
{let bottom:TextField =
{TextField
value = "null",
{on ValueFinished at tf:TextField do
let val:String = tf.value
set chart.bottom-margin = {evaluate val}
}
}
}
{Canvas
width = chart.width,
height = chart.height,
chart
}
{Fill width = 1cm}
{VBox
spacing = .25cm,
"Margins:",
{Table
cell-border-width = 1pt,
cell-border-color = "silver",
cell-border-style = "sunken",
border-width = 1pt,
border-color="silver",
border-style = "sunken",
{column-prototype
{bold side},
"left",
"right",
"top",
"bottom"
},
{column-prototype
width = 3cm,
{bold value},
left,
right,
top,
bottom
}
}
}
| |
(accessor)
accessor public Chart.legend-alignment:
double setter public Chart.legend-alignment:
double The alignment of the legend along the side of the chart chosen by Chart.legend-location.
Description
This value should be from 0.0 to 1.0, inclusive.
Example
| Example |
 |
{import * from CURL.GUI.CHARTS}
{import * from CHARTS-DOC,
location = "../docstring-support/gui/charts-doc.scurl"
}
{RecordGrid height = 6cm, record-source = sample-records}
{let chart:LayeredChart =
{LayeredChart
width = 15cm,
height = 6cm,
left-axis = {new {NumericAxis-of double}, 0, 70},
right-axis = {ChartAxis {ChartDataSeries sample-records, "Height"}},
{LineLayer
{ChartDataSeries sample-records, "Age"},
{ChartDataSeries sample-records, "Wins"},
{ChartDataSeries sample-records, "Height"},
x-axis-data = {ChartDataSeries sample-records, "Name"}
}
}
}
{Canvas
width = chart.width,
height = chart.height,
chart
}
Legend location:
{DropdownList
LegendLocation.left,
LegendLocation.right,
LegendLocation.top,
LegendLocation.bottom,
list-item-creation-proc =
{proc {val:any}:ListItem
{return
{ListValueItem
value = val,
(val asa LegendLocation).name
}
}
},
{on ValueChanged at ddl:DropdownList do
set chart.legend-location = ddl.value asa LegendLocation
},
value = LegendLocation.right
}
Legend alignment:
{TextField
value = {format "%.2f", chart.legend-alignment},
{on ValueFinished at tf:TextField do
set chart.legend-alignment = {tf.value.to-double}
}
}
| |
(nonlocal option)
public Chart.legend-enabled?:
bool A bool that can be used to enable or disable legend creation for a Chart.
Description
(nonlocal option)
The factory procedure used to generate individual legend entries for a Chart's legend.
Description
(local option)
A factory for the production of Graphics representing the legend of a Chart.
Description
Example
This code demonstrates the use of both
Chart.legend-factory and
legend-entry-factory to produce a horizontal legend that uses text color to illustrate the color of the data series.
| Example |
 |
{import * from CURL.GUI.CHARTS}
{import * from CHARTS-DOC,
location = "../docstring-support/gui/charts-doc.scurl"
}
{RecordGrid height = 6cm, record-source = sample-records}
{let chart:LayeredChart =
{LayeredChart
width = 15cm,
height = 6cm,
left-axis = {new {NumericAxis-of double}, 0, 70},
right-axis = {ChartAxis {ChartDataSeries sample-records, "Height"}},
legend-location = LegendLocation.top,
legend-alignment = 0.5,
legend-entry-factory =
{proc
{chart:Chart,
data-series:ChartDataSeries,
record:#Record,
color:FillPattern,
legend-index:int
}:Graphic
{return
{Frame
color = color,
{if-non-null record then
{data-series.field.domain.format
record[data-series.field.name]
}
else
data-series.field.caption
}
}
}
},
legend-factory =
{proc {chart:Chart, include-scrollbox?:bool}:#Graphic
let constant entries:{Array-of Graphic} =
{chart.get-legend-entries}
{if entries.empty? then
{return null}
}
let box:Box =
{HBox
margin = 4pt,
spacing = 8pt
}
{for g in entries do {box.add g}}
{return
{if include-scrollbox? then
{ScrollBox
border-width = 1px,
border-color = FillPattern.black,
box
}
else
set box.border-width = 1px
set box.border-color = FillPattern.black
{return box}
}
}
},
{LineLayer
{ChartDataSeries sample-records, "Age"},
{ChartDataSeries sample-records, "Wins"},
{ChartDataSeries sample-records, "Height"},
x-axis-data = {ChartDataSeries sample-records, "Name"}
}
}
}
{Canvas
width = chart.width,
height = chart.height,
chart
}
| |
(accessor)
The location of the chart's legend, defined using LegendLocation.
Notes
(field)
The GraphicShape object used to contain the legend, if any.
Description
If there is no legend,
legend-shape.graphic will be null.
Generally, you do not need to use the object, but it can be useful if you wish to manipulate the legend. Please note that the legend
Graphic itself may often be regenerated during the chart layout process. See
Chart.invalidate-layout and
Chart.ensure-layout-valid for more information on the layout process.
(field)
public constant Chart.plot-area-bounds:
GRect ={GRect.empty}
The area within this chart used for plotting.
Description
This value is the subset of the chart that actually contains plots. Objects typically excluded from this area include axes, ticks, tick labels, axis labels, and the legend.
Notes
This field is for information only. Do not modify the contents of the
GRect.
(local option)
public Chart.right-margin:
any =null
The amount of space allocated to the Chart's right margin.
Description
Please see
Chart.width and
Chart.plot-area-bounds for a discussion of layout and the role margins play. See also
Chart.get-actual-right-margin, which computes an actual result based on this option and the contents of the chart.
Legal types of values are:
The default value is
null, which instructs the
Chart to estimate the amount of margin required to accomodate its non-plot elements and use that value.
Examples of legal values include:
- 2cm
- 1.5in
- 36pt
- 3px
- 36 (which is the same as 36pt)
Please see
Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.
Example
(accessor)
accessor public Chart.style-element:
String The "element" or "type" of this Visual, for the purpose of styling.
Description
This implementation returns the value of
Visual._style-element but is normally overridden to return a constant value.
Overriding
If a subclass of
Visual should be stylable separately from other types of objects, this getter should be overridden to return an appropriate string. By convention, this string is the name of the class or the name of the markup that produces the object.
An override must return
self._style-element if it is not the empty string.
Introduced in:
version 6.0
(nonlocal option)
public Chart.text-line-through?:
bool Specifies whether to apply a line through the text within this object.
Description
Set it to
true or
false.
See also
line-through, which is the predefined character format for this option.
Example
| Example |
 |
{paragraph
Modified Shopping List: onions, carrots, french bread,
{text text-line-through?=true, pot roast},
London Broil, Camembert, eggs, {text
text-line-through?=true, orange juice}, butter, jam.}
| |
See Also
(nonlocal option)
public Chart.text-underline?:
bool Specifies whether text within this object will be underlined.
Description
Set it to true or false.
Example
| Example |
 |
{paragraph
This is the result of
{text text-underline?=true, setting text-underline? to true}
for a text fragment.
}
{paragraph
{underline But notice what I am doing here{em-dash}I
am using the underline character format and
{text text-underline?=false, setting text-underline? to false.}}
}
| |
See Also
(local option)
public Chart.top-margin:
any =null
The amount of space allocated to the Chart's top margin.
Description
Please see
Chart.height and
Chart.plot-area-bounds for a discussion of layout and the role margins play. See also
Chart.get-actual-top-margin, which computes an actual result based on this option and the contents of the chart.
Legal types of values are:
The default value is
null, which instructs the
Chart to estimate the amount of margin required to accomodate its non-plot elements and use that value.
Examples of legal values include:
- 2cm
- 1.5in
- 36pt
- 3px
- 36 (which is the same as 36pt)
Please see
Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.
Example
(field)
public-get private-set Chart.width:
Distance =-1m
The current width of the chart.
Description
(class constant)
public constant Chart.LegendFactory:
ProcType ={proc-type
{chart:Chart,
include-scrollbox?:bool
}:#Graphic
}
The Type of factory procedure used for the generation of a Chart's legend. This is the type of the option Chart.legend-factory.
chart: The Chart for which the legend is to be created.
include-scrollbox?: If true, then the legend returned will be enclosed by a
ScrollBox. This is useful because a
Chart may need to constrain the returned object's size by directly setting the
width and
height options. See
Chart.create-legend for more information.
When writing your own shape factory, you may regard this parameter as a suggestion rather than a requirement. The
default-legend-factory always obeys it, however.
Returns
A
Graphic representing the legend, or
null if no legend is desired.
Description
(class proc)
Create a standard legend entry.
data-series: The
ChartDataSeries for which the legend entry is to be generated.
record: The
Record for which the legend entry is to be generated, if any. For
LayeredChart objects, legend entries are generated for data series, not records, so this will be null. However, for
PieChart objects, entries are record-based, so this value will be non-null.
legend-index: The index of this particular entry in the legend, starting with zero.
Returns
A
Graphic object to be placed in the legend.
Description
This is the default value of
legend-entry-factory. It is implemented as follows:
let constant vertical?:bool =
(chart.legend-location == LegendLocation.left or
chart.legend-location == LegendLocation.right)
{return
{HBox
valign = "center",
{Fill
width = 8pt,
height = 8pt,
background = color,
border-width = 1px
},
{Fill width = {if vertical? then 10pt else 4pt}},
{if-non-null record then
{data-series.field.domain.format
record[data-series.field.name]
}
else
data-series.field.caption
}
}
}
(class proc)
| public
| {Chart.default-legend-factory chart:Chart, include-scrollbox?:bool }:#Graphic |
Create a standard, vertically laid out legend.
chart: The Chart for which to generate a legend.
include-scrollbox?: If true, then the legend returned will be enclosed by a
ScrollBox. This is useful because a
Chart may need to constrain the returned object's size by directly setting the
width and
height options. See
Chart.create-legend for more information.
Returns
A
Graphic containing the legend, or null if no legend should be displayed.
Description
This is the default value for
Chart.legend-factory. It is implemented as follows:
let constant entries:{Array-of Graphic} =
{chart.get-legend-entries}
{if entries.empty? then
{return null}
}
let constant vertical?:bool =
(chart.legend-location == LegendLocation.left or
chart.legend-location == LegendLocation.right)
let box:Box =
{if vertical? then
{VBox margin = 4pt, spacing = 2pt}
else
{HBox margin = 3pt, spacing = 7pt}
}
{for g in entries do {box.add g}}
{return
{if include-scrollbox? then
{ScrollBox
border-width = 1px,
border-color = FillPattern.black,
box
}
else
set box.border-width = 1px
set box.border-color = FillPattern.black
box
}
}
(method)
Apply a bounds constraint (in the local coordinate system) to this Shape.
bounds: The constraint to be applied.
Description
A Shape is not required to comply with the constraint. However, if it does not, the entire Shape may not be visible.
The default implementation ignores the constraint.
Notes
If the
Shape reacts to the constraint by changing its bounds, it should call
ShapeRoot.invalidate-shape-layout. To avoid infinite loops, differences in size between the constraint and the layout bounds of less than one pixel should be ignored.
(method)
| public
| {Chart.create-legend include-scrollbox?:bool = false}:#Graphic |
Create the legend Graphic for this chart.
include-scrollbox?: If true, then the legend factory will wrap the legend in a
ScrollBox. (Note that any legend factory you supply is free to ignore this parameter, but the default legend factory does not. See
Chart.LegendFactory.) When legends are created for inclusion directly into a chart, this is desirable, since oversized legends will have their width or height constrained. When you are including the legend in your own graphical hierarchy, however, you may wish to omit the automatically generated
ScrollBox since it is often easier to deal with the spatial requirements using the conventional GUI toolkit layout system, or by placing a
ScrollBox at a higher level.
Returns
The
Graphic created, or
null if no legend is created. No legend will be created if no legend entries are available to fill the legend. For example, if the nonlocal option
legend-enabled? is set to
false on a
LayeredChart, then none of the
ChartLayers will create legend entries. See below for an example that works around this.
Description
This method is usually called from within the
Chart implementations. However, you can also call it directly if you wish to use a legend external to the chart itself.
This method ignores the
legend-enabled? option at the chart level, so you can inhibit legend creation by the
Chart and still create a legend for external use. However, it is necessary to set
legend-enabled? to true for each
ChartLayer or
PieSet to ensure that they generate legend entries. The example below illustrates this.
To change the manner in which the legend container is created, you may override this method. However, it is often easier to set
Chart.legend-factory. Please see
Chart.default-legend-factory for an explanation of legend generation.
Example
| Example |
 |
{import * from CURL.GUI.CHARTS}
{import * from CHARTS-DOC,
location = "../docstring-support/gui/charts-doc.scurl"
}
{RecordGrid height = 6cm, record-source = sample-records}
{let chart:LayeredChart =
{LayeredChart
width = 15cm,
height = 6cm,
left-axis = {new {NumericAxis-of double}, 0, 70},
right-axis = {ChartAxis {ChartDataSeries sample-records, "Height"}},
legend-enabled? = false,
{LineLayer
legend-enabled? = true,
{ChartDataSeries sample-records, "Age"},
{ChartDataSeries sample-records, "Wins"},
{ChartDataSeries sample-records, "Height"},
x-axis-data = {ChartDataSeries sample-records, "Name"}
}
}
}
{Canvas
width = chart.width,
height = chart.height,
chart
}
{HBox
height = 4cm,
spacing = 1cm,
{text
The legend is placed in a height-constrained HBox, along with
this text. A Frame is used to provide an extra border.
},
{Frame
background = "#cccccc",
border-style = "sunken",
border-width = 3px,
{chart.create-legend}
}
}
| |
(method)
Draw this object's visual representation.
renderer2d: The
Renderer2d that this object should use to draw itself.
Overriding
When subclassing Shape, this method must be overridden.
(method)
| public
| {Chart.ensure-layout-valid force-layout?:bool = false}:void |
Force any pending layout process to occur immediately.
force-layout?: If true, then layout will occur even if no layout is scheduled.
Description
Notes
It is rarely necessary to call this method directly. However, it may be useful if you need to programmatically interact with elements of a
Chart which may not yet be valid. For instance, if you wish to inspect the type of a
LayeredChart's automatically generated bottom axis using
LayeredChart.bottom-axis, it would be advisable to call this method first.
Note that layout invalidation can occur for many reasons, so you should handle
ChartLayoutChanged events if you need to know when layout-dependent values have changed. In particular, if you intend to manipulate elements generated during layout, you should perform such manipulations inside a
ChartLayoutChanged event handler.
See
ChartLayer.get-data-mapping for an example of the use of an event handler for
ChartLayoutChanged.
(method)
| protected abstract
| {Chart.estimate-margins need-left?:bool, need-right?:bool, need-top?:bool, need-bottom?:bool, left:Distance, right:Distance, top:Distance, bottom:Distance }:(left:Distance,
right:Distance,
top:Distance,
bottom:Distance) |
Approximate the margin requirements of this Chart.
need-left?: Indicates whether an estimation is requried for the left margin. Otherwise, left should be returned for the left margin.
need-right?: Indicates whether an estimation is requried for the right margin. Otherwise, right should be returned for the right margin.
need-top?: Indicates whether an estimation is requried for the top margin. Otherwise, top should be returned for the top margin.
need-bottom?: Indicates whether an estimation is requried for the bottom margin. Otherwise, bottom should be returned for the bottom margin.
left: Indicates the default value of the left margin. If need-left? is true, then this value will be returned verbatim. Otherwise, it is ignored.
right: Indicates the default value of the right margin. If need-right? is true, then this value will be returned verbatim. Otherwise, it is ignored.
top: Indicates the default value of the top margin. If need-top? is true, then this value will be returned verbatim. Otherwise, it is ignored.
bottom: Indicates the default value of the bottom margin. If need-bottom? is true, then this value will be returned verbatim. Otherwise, it is ignored.
Description
Notes
Before it calls
estimate-margins, the
Chart layout system will set the chart's
plot-area-bounds to the entire chart area as a first-order approximation. Implementations of
estimate-margins are free to overwrite these during the estimation process as necessary.
(method)
| public final
| {Chart.get-actual-bottom-margin}:Distance |
Return the actual value to be used for the Chart's bottom margin.
Description
This value represents the result of computation of
Chart.bottom-margin. If
Chart.bottom-margin is
null, then this includes the approximation of the margin requirements.
(method)
| public final
| {Chart.get-actual-left-margin}:Distance |
Return the actual value to be used for the Chart's left margin.
Description
This value represents the result of computation of
Chart.left-margin. If
Chart.left-margin is
null, then this includes the approximation of the margin requirements.
(method)
| public final
| {Chart.get-actual-right-margin}:Distance |
Return the actual value to be used for the Chart's right margin.
Description
This value represents the result of computation of
Chart.right-margin. If
Chart.right-margin is
null, then this includes the approximation of the margin requirements.
(method)
| public final
| {Chart.get-actual-top-margin}:Distance |
Return the actual value to be used for the Chart's top margin.
Description
This value represents the result of computation of
Chart.top-margin. If
Chart.top-margin is
null, then this includes the approximation of the margin requirements.
(method)
| public abstract
| {Chart.get-legend-entries}:{Array-of Graphic} |
Create all entries required for this Chart's legend.
Description
(method)
| public
| {Chart.get-own-bounds dest:GRect = {GRect.empty}}:GRect |
Calculate the rectangular rendering bounds of this Shape, in its local coordinate system.
dest: An optional GRect object to be used to return the data.
Returns
A
GRect object containing the bounds. This will always be the same object as
dest. This
GRect must be well-formed; that is, the following must be true:
-dest.lextent <= dest.rextent and -dest.ascent <= dest.descentDescription
The bounds returned should cover all pixels that will be painted by this object but do not include all of the children of this object.
Notes
Rendering bounds (
get-own-bounds) and layout bounds (
get-own-layout-bounds) are typically similar, but may differ. In particular, the rendering bounds may be generously inclusive, but the layout bounds must describe the
Shape precisely in order for adjacent items to abut properly.
Overriding
When subclassing Shape, this method must be overridden. The dest parameter must be used to return the data.
(method)
Calculate the rectangular layout bounds of this object and its children in the local coordinate system of this object.
width-first?: For
GraphicShapes, indicates whether the bounds should be calculated using using width-first layout negotation. This parameter is not typically used by other subclasses.
dest: An optional GRect object to be used to return the data.
Returns
A
GRect object containing the bounds. This will always be the same object as
dest. This
GRect must be well-formed; that is, the following must be true:
-dest.lextent <= dest.rextent and -dest.ascent <= dest.descentDescription
The bounds returned are those that best describe the object for layout purposes and do include all of the children of this object.
(method)
| public
| {Chart.invalidate-layout}:void |
Request that the Chart perform layout soon.
Description
Chart layout does not usually occur immediately upon invalidation. This is because invalidating changes usually occur in batches. For instance, if the data referred to by a
ChartDataSeries changes, it is likely to trigger invalidations through multiple paths; if the data is used by both a
ChartAxis and a
ChartLayer, for example, both objects will notify the
Chart to invalidate its layout via this method.
To prevent such scenarios from causing repeated, unnecessary layout operations, a delay system is used. The first call to this method schedules a layout using an
Alarm. Subsequent calls do nothing, until layout actually occurs.
This means that when you make changes to a
Chart or its associated data, you will need to call
Chart.ensure-layout-valid if you want layout-dependent values to be updated immediately. (This should only be necessary if you intend to programmatically interact with elements of the
Chart that are subject to change upon layout, such as
ChartAxis objects, or the contents of
ChartLayers.) Alternatively, you may also use the
ChartLayoutChanged event to receive notification whenever
Chart layout finishes, and perform whatever operations depend on layout in an event handler.
Note that layout invalidation can occur for many reasons, so you should handle
ChartLayoutChanged events if you need to know when layout-dependent values have changed.
Notes
Most applications should not need to cause layout invalidation directly. You might need to do so if you write your own charting classes that have their own layout-invalidating scenarios. (For instance, if you write a
ChartAxis subclass that depends on external data, when that data changes, you might need call
Chart.invalidate-layout.)
You might also need to call this method if you supplied a factory procedure, such as
BarLayer.shape-factory, which depended on external data to calculate its shape. If that external data changes, it would be necessary to trigger layout to ensure that the shapes were regenerated.
(method)
| public
| {Chart.layout-chart}:void |
Perform the actual process of layout for this chart.
Description
You should never call this method directly; if you wish to trigger chart layout, call
Chart.ensure-layout-valid.
Chart.layout-chart is called in turn.
This method is ideal for overriding in child classes that must perform some action prior to (or after) actual layout of the chart.
Introduced in:
version 6.0
(method)
| public
| {Chart.note-color-palette-changed}:void |
Notify this Chart that the contents of Chart.color-palette has changed.
Description
You must call this method whenever you directly modify
Chart.color-palette, either by modifying the array it points to or by modifying the value of the field. This will ensure that the appropriate components of the chart are regenerated.
(method)
| public
| {Chart.position-legend}:void |
Position the legend within the Chart.
Description
Notes
Most applications should have no need to call this method. However, if you have changed the position of the legend programmatically and wish to reset it, then you could use this method to do so.
(method)
| public
| {Chart.request-draw layout-context:LayoutContext = {self.get-layout-context} }:void |
Ask for the pixels belonging to a Visual to be redrawn.
layout-context: the
LayoutContext object corresponding to the subtree of the graphic hierarchy containing this object. If this keyword parameter is not supplied, the applicable value is obtained by invoking
Visual.get-layout-context.
Notes
Programming Notes
This method is invoked when there is reason to believe that this object's pixels may need to be repainted. Examples of such situations are when the object is displayed for the first time, when the object is removed from view, or when the object is moved or resized (in which case this method must be invoked both before and after the change).
(method)
Determine whether or not a point lies within this Shape.
x: The X coordinate of the point.
y: The Y coordinate of the point.
Returns
true if this Shape contains (x, y).
Description
The point is in this object's local coordinate system. This method does not consider its children.
Overriding
When subclassing
Shape, this method must be overridden. This method determines when mouse events (such as
PointerMotion) will be delivered to this object, among other things.
Generally, you should implement this method to determine whether or not the point lies within any of the rendered primitives of the shape, not simply whether or not it is within the bounds of the shape. However, you are free to implement it using whatever metric you desire.
(method)
Determine whether a polygon intersects this Shape.
polygon: An object containing set of points that describe a polygon in this shape's local coordinate space. It is guaranteed that this polygon will be convex and will use a counter-clockwise winding order.
Description
This method is very similar to
Shape.self-contains-point?, except that it deals with an area rather than a point. It is primarily used to support area-based selection, but it may also be directly called.
Overriding
When subclassing
Shape, this method must be overridden. It need not consider children.
Generally, you should implement this method to determine whether or not the area intersects with any of the rendered primitives of the shape, not simply whether or not it is within the bounds of the shape. However, you are free to implement it using whatever metric you desire. Users will experience strange results when selecting this object if the implementation of this method disagrees with
Shape.self-contains-point?.
If you are not using any selection features, this method can be implemented to simply return false.
(method)
Set the size of the Chart.
width: The total width of the chart. See
Chart.width for more information.
height: The total height of the chart. See
Chart.height for more information.
Description
This directly sets
Chart.width and
Chart.height, invalidates the chart's layout so that it has an opportunity to conform to these values.
When layout occurs, the chart will attempt to modify its plot area such that the plot area and margins are entirely contained within the dimensions specified here. In some cases, elements such as axis labels or tick labels may extend beyond these dimensions. This may happen because there is not enough space for all chart elements even with a very small plot area, or because the chart's attempt to estimate its needed margins may be inaccurate due to automatic label staggering or other parameters that are sensitive to size changes. When there is simply not enough space for all elements, you may either give more space to the chart, or eliminate some elements (such as axis labels or the legend). When there is not enough margin space, it is usually easiest to set the margins directly (for instance, using
Chart.left-margin), though it is also possible to extend the estimation algorithm by overriding
Chart.estimate-margins.
Layout is not immediate, since chart invalidations often come in batches. See
Chart.invalidate-layout for more information. If you require immediate layout validation, you can use
Chart.ensure-layout-valid.
Notes
You may cause one or both of the dimensions to adapt to the size of a container by setting them to a negative value. This will only have an effect when this
Chart is contained within a
ChartBox or a
ShapeBox, or when
Shape.constrain-shape-layout-bounds is called under other circumstances.
Note that
Charts are placed inside a
ChartBox implicitly when added to a
Graphical hierarchy. Note also that automatic size adaptation for both dimensions is the default behavior for
Chart.
If you are interested in detecting when the
Chart does not have enough space, it is possible to determine whether any elements of the chart extend beyond its container's bounds. Get the bounds of the
Chart and all of its children using
get-shape-bounds-in-shape-root. This will give the bounds relative to the coordinate system of the shape root, which will be a
Graphic such as
Canvas,
ShapeBox or
ChartBox.
Once you have these bounds, simply compare them to the graphical layout bounds of the shape root and see if they extend beyond those bounds. You can obtain the layout bounds of a
Graphic (such as the shape root) using
Graphic.layout.get-bounds. Note that if you do not have a convenient pointer to the shape root, you can query any
Shape for the
ShapeRoot that contains it using
Shape.get-shape-root.
(method)
Return the Graphic equivalent of this object.
Description
By default, this method returns a
ChartBox that contains this
Chart.
This method is called by the Curl layout system whenever a
Chart is added to a graphical hierarchy. It is not typically called directly.
(method)
| public
| {Chart.transformation-changed}:void |
Notification that Shape.transformation has changed.
Overriding
Important note: Any overriding implementation of this method should include a call to the superclass implementation in order to ensure that the new area of the object is invalidated.
(method)
| protected abstract
| {Chart.update-layout}:void |
Perform layout based on Chart.plot-area-bounds.
Description
This method is only called from within
Chart.ensure-layout-valid.
Chart implementations perform their actual layout, such as positioning and sizing axes, in this method. Also, implementations are expected to fire
ChartLayoutChanged events at themselves and any relevant chart objects within this method.