Chart (class)
public abstract Chart {inherits Shape}
Package: CURL.GUI.CHARTS
Direct Known Subclasses: LayeredChart, PieChart

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.

Constructors
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,
    ...
}
Properties
bottom-margin:The amount of space allocated to the Chart's bottom margin.
local option public Chart.bottom-margin:any =null
color-palette:An array of FillPatterns to be used when plotting data series.
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
display-context:The DisplayContext associated with this object.
nonlocal option public Chart.display-context:#DisplayContext
font-family:Sets the font family for text.
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
layout-scheduled?:Indicates whether a layout operation is pending on this Chart.
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
legend-alignment:The alignment of the legend along the side of the chart chosen by Chart.legend-location.
accessor public Chart.legend-alignment:double
setter public Chart.legend-alignment:double
legend-enabled?:A bool that can be used to enable or disable legend creation for a Chart.
nonlocal option public Chart.legend-enabled?:bool
legend-entry-factory:The factory procedure used to generate individual legend entries for a Chart's legend.
nonlocal option public Chart.legend-entry-factory:LegendEntryFactory
legend-factory:A factory for the production of Graphics representing the legend of a Chart.
local option public Chart.legend-factory:Chart.LegendFactory =Chart.default-legend-factory
legend-location:The location of the chart's legend, defined using LegendLocation.
accessor public Chart.legend-location:LegendLocation
setter public Chart.legend-location:LegendLocation
legend-shape:The GraphicShape object used to contain the legend, if any.
field public constant Chart.legend-shape:GraphicShape
plot-area-bounds:The area within this chart used for plotting.
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
style-element:The "element" or "type" of this Visual, for the purpose of styling.
accessor public Chart.style-element:String
text-line-through?:Specifies whether to apply a line through the text within this object.
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 ShapeContainerBase: as-ShapeRoot, shape-children
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
Properties inherited from DataBindingTarget: data-binding-context, data-bindings
Properties inherited from EventTarget: event-handlers
Properties inherited from OptionListInterface: option-register-proc, registered-option-keys
Class Variables and Constants
LegendFactory:The Type of factory procedure used for the generation of a Chart's legend. This is the type of the option Chart.legend-factory.
public constant Chart.LegendFactory:ProcType ={proc-type {chart:Chart, include-scrollbox?:bool }:#Graphic }
Class Procedures
default-legend-entry-factory:Create a standard legend entry.
public {Chart.default-legend-entry-factory
    chart:Chart,
    data-series:ChartDataSeries,
    record:#Record,
    color:FillPattern,
    legend-index:int
}:Graphic
default-legend-factory:Create a standard, vertically laid out legend.
public {Chart.default-legend-factory
    chart:Chart,
    include-scrollbox?:bool
}:#Graphic
Methods
constrain-own-layout-bounds:Apply a bounds constraint (in the local coordinate system) to this Shape.
public {Chart.constrain-own-layout-bounds
    lc:LayoutContext,
    bounds:GRect
}:void
create-legend:Create the legend Graphic for this chart.
public {Chart.create-legend include-scrollbox?:bool = false}:#Graphic
draw:Draw this object's visual representation.
public {Chart.draw renderer2d:Renderer2d}:void
ensure-layout-valid:Force any pending layout process to occur immediately.
public {Chart.ensure-layout-valid force-layout?:bool = false}:void
estimate-margins:Approximate the margin requirements of this Chart.
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)
get-actual-bottom-margin:Return the actual value to be used for the Chart's bottom margin.
public final {Chart.get-actual-bottom-margin}:Distance
get-actual-left-margin:Return the actual value to be used for the Chart's left margin.
public final {Chart.get-actual-left-margin}:Distance
get-actual-right-margin:Return the actual value to be used for the Chart's right margin.
public final {Chart.get-actual-right-margin}:Distance
get-actual-top-margin:Return the actual value to be used for the Chart's top margin.
public final {Chart.get-actual-top-margin}:Distance
get-legend-entries:Create all entries required for this Chart's legend.
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.get-shape-layout-bounds
    lc:LayoutContext,
    width-first?:bool = true,
    dest:GRect = {GRect.empty}
}:GRect
invalidate-layout:Request that the Chart perform layout soon.
public {Chart.invalidate-layout}:void
layout-chart:Perform the actual process of layout for this chart.
public {Chart.layout-chart}:void
note-color-palette-changed:Notify this Chart that the contents of Chart.color-palette has changed.
public {Chart.note-color-palette-changed}:void
position-legend:Position the legend within the Chart.
public {Chart.position-legend}:void
request-draw:Ask for the pixels belonging to a Visual to be redrawn.
public {Chart.request-draw
    layout-context:LayoutContext = {self.get-layout-context}
}:void
self-contains-point?:Determine whether or not a point lies within this Shape.
public {Chart.self-contains-point? x:Distance, y:Distance}:bool
self-intersects-polygon?:Determine whether a polygon intersects this Shape.
public {Chart.self-intersects-polygon?
    polygon:ShapeSelectionPolygon
}:bool
set-chart-size:Set the size of the Chart.
public {Chart.set-chart-size width:Distance, height:Distance}:void
to-Graphic:Return the Graphic equivalent of this object.
public {Chart.to-Graphic}:Graphic
transformation-changed:Notification that Shape.transformation has changed.
public {Chart.transformation-changed}:void
update-layout:Perform layout based on Chart.plot-area-bounds.
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 GraphicOptions: any-to-Distance
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 DataBindingTarget: add-data-binding, get-data-binding, refresh-data-binding, remove-data-binding, unset-property, update-data-binding, validate-data-binding
Methods inherited from EventTarget: accepts-event-class?, add-event-handler, event-handler-present?, remove-event-handler, verify-event
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
Methods inherited from BasicEventTarget: enqueue-event
Methods inherited from InitRestArgParser: process-rest-args
Methods inherited from Object: object-describe, object-describe-for-debugging, object-serialize

Constructor Details
default (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.

width: Initial width of the chart; see Chart.width.
height: Initial height of the chart; see Chart.height.
legend-location: Initial location of the legend; see Chart.legend-location.
legend-alignment: Initial alignment of the legend; see Chart.legend-alignment.
color-palette: An array of FillPatterns to be used when plotting data series. See Chart.color-palette for more information.
...: 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.


Property Details
bottom-margin (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:

Please see Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.

Example

See Chart.left-margin for an example.


color-palette (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

An alternate built-in palette exists; see pastel-chart-color-palette.

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}
    }
}


default-height (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.


default-width (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.


display-context (nonlocal option)
public Chart.display-context:#DisplayContext

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.


font-family (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
    }
}


font-size (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

The character formats: tiny, small, big, huge


font-style (nonlocal option)
public Chart.font-style:FontStyle

Specifies whether text within the object should be a slanted font such as italic or oblique.

Description

Valid values are as follows:

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

The character format: italic


font-weight (nonlocal option)
public Chart.font-weight:FontWeight

Specifies whether text within the object should be specially weighted as bold.

Description

Valid values are as follows:

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


height (field)
public-get private-set Chart.height:Distance =-1m

The current height of the chart.

Description

If positive, this measurement includes all elements, but is not a strict constraint. (In some cases, elements such as axis or tick labels may extend beyond this dimension.)

Specifically, this measurement includes Chart.plot-area-bounds, Chart.top-margin, and Chart.bottom-margin.

This value can be controlled using Chart.set-chart-size, or by the constructor Chart.default. Chart supports adaptation to its container's size; see Chart.set-chart-size.


layout-scheduled? (accessor)
accessor public final Chart.layout-scheduled?:bool

Indicates whether a layout operation is pending on this Chart.

Description

Layouts may be scheduled using Chart.invalidate-layout, and may be triggered using Chart.ensure-layout-valid. Otherwise, the layout will occur as soon as any pending Events are dealt with.


left-margin (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:

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
        }
    }
}


legend-alignment (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}
    }
}


legend-enabled? (nonlocal option)
public Chart.legend-enabled?:bool

A bool that can be used to enable or disable legend creation for a Chart.

Description

See legend-enabled?.


legend-entry-factory (nonlocal option)
public Chart.legend-entry-factory:LegendEntryFactory

The factory procedure used to generate individual legend entries for a Chart's legend.

Description

See legend-entry-factory.


legend-factory (local option)
public Chart.legend-factory:Chart.LegendFactory =Chart.default-legend-factory

A factory for the production of Graphics representing the legend of a Chart.

Description

Setting this option is the easiest way to modify the top-level look of the legend. See Chart.default-legend-factory for details on the way this is done by default. You may also wish to change the appearance of the legend entries using legend-entry-factory.

See Chart.LegendFactory for an explanation of the procedure's parameters.

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
}


legend-location (accessor)
accessor public Chart.legend-location:LegendLocation
setter public Chart.legend-location:LegendLocation

The location of the chart's legend, defined using LegendLocation.

Notes

For an example, see Chart.legend-alignment.


legend-shape (field)
public constant Chart.legend-shape:GraphicShape

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.


plot-area-bounds (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.


right-margin (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:

Please see Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.

Example

See Chart.left-margin for an example.


style-element (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


text-line-through? (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

The character format: line-through


text-underline? (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

The character format: underline


top-margin (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:

Please see Shape.quantize-line-thickness for an explanation of how values are converted and quantized to pixels.

Example

See Chart.left-margin for an example.


width (field)
public-get private-set Chart.width:Distance =-1m

The current width of the chart.

Description

If positive, this measurement includes all elements, but is not a strict constraint. (In some cases, elements such as axis or tick labels may extend beyond this dimension.)

Specifically, this measurement includes Chart.plot-area-bounds, Chart.left-margin, and Chart.right-margin.

This value can be controlled using Chart.set-chart-size, or by the constructor Chart.default. Chart supports adaptation to its container's size; see Chart.set-chart-size.


Class Variable and Constant Details
LegendFactory (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

See Chart.legend-factory for more information and an example.


Class Procedure Details
default-legend-entry-factory (class proc)
public {Chart.default-legend-entry-factory
    chart:Chart,
    data-series:ChartDataSeries,
    record:#Record,
    color:FillPattern,
    legend-index:int
}:Graphic

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.
color: The FillPattern used to plot the data.
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
        }
    }
}


default-legend-factory (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 Details
constrain-own-layout-bounds (method)
public {Chart.constrain-own-layout-bounds
    lc:LayoutContext,
    bounds:GRect
}:void

Apply a bounds constraint (in the local coordinate system) to this Shape.

lc: the LayoutContext in effect for this layout negotiation.
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.


create-legend (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}
    }
}


draw (method)
public {Chart.draw renderer2d:Renderer2d}:void

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.


ensure-layout-valid (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

This method calculates the Chart's plot area (Chart.plot-area-bounds) based on its margin requirements, Chart.width, and Chart.height. It then calls Chart.update-layout to trigger layout and generation of charting objects.

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.


estimate-margins (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

This method is used internally during the layout process. It is not expected that you will ever need to directly call this method; instead, use Chart.get-actual-left-margin, Chart.get-actual-right-margin, Chart.get-actual-top-margin, or Chart.get-actual-bottom-margin. If necessary, these calls will result in calls to this method.

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.


get-actual-bottom-margin (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.


get-actual-left-margin (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.


get-actual-right-margin (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.


get-actual-top-margin (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.


get-legend-entries (method)
public abstract {Chart.get-legend-entries}:{Array-of Graphic}

Create all entries required for this Chart's legend.

Description

Generally speaking, this method iterates through the plot components of the chart (for instance, the ChartLayers of a LayeredChart) and creates all entries required for each of them.

This method is usually called by the Chart.legend-factory, itself called by Chart.create-legend. See Chart.default-legend-factory for an explanation of how the legend entries are handled by default.


get-own-bounds (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.descent

Description

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.


get-shape-layout-bounds (method)
public {Chart.get-shape-layout-bounds
    lc:LayoutContext,
    width-first?:bool = true,
    dest:GRect = {GRect.empty}
}:GRect

Calculate the rectangular layout bounds of this object and its children in the local coordinate system of this object.

lc: the LayoutContext in effect for this layout negotiation.
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.descent

Description

The bounds returned are those that best describe the object for layout purposes and do include all of the children of this object.


invalidate-layout (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.


layout-chart (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


note-color-palette-changed (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.


position-legend (method)
public {Chart.position-legend}:void

Position the legend within the Chart.

Description

This method calculates a legend position according to Chart.legend-location, Chart.legend-alignment, and Chart.plot-area-bounds. This position is then assigned to Chart.legend-shape.

If the legend is too large, this method will also directly constrain the width or height of legend-shape.graphic to fit. For this reason, a legend included within the chart is usually placed inside a ScrollBox. See Chart.create-legend for more information.

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.


request-draw (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

This method is responsible for issuing sufficient invocations of View.request-draw-rect-in-root (usually via a call to Graphic.request-draw-rect on the Visual's bounds) to cover all the pixels that require repainting.

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).


self-contains-point? (method)
public {Chart.self-contains-point? x:Distance, y:Distance}:bool

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.


self-intersects-polygon? (method)
public {Chart.self-intersects-polygon?
    polygon:ShapeSelectionPolygon
}:bool

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.


set-chart-size (method)
public {Chart.set-chart-size width:Distance, height:Distance}:void

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.


to-Graphic (method)
public {Chart.to-Graphic}:Graphic

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.


transformation-changed (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.


update-layout (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.