PBToolboxAI v5 ← Site

chartcartesian — u_pbt_chartcartesian #

← Component reference · Guide contents

Cartesian chart: columns, bars, lines, areas and scatter, on one category axis and one or two value axes. The type is set per series.

▶ See it live — Demo application, Cartesian chart tile: the preview, the code behind it and this page, side by side.


In brief #

Userobjectu_pbt_chartcartesian
Item classn_pbt_chartcartesian_series (of_item(key)) · n_pbt_chartcartesian_axis (of_axis(axis))
Used forComparing values along an axis — months, products, regions
PrincipleYou set the categories then the series; the scales, the grid and the animation are ours

Quick start #

// Local variables
string ls_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun"}
double ld_sales[] = {420, 510, 480, 620, 700, 660}

// The categories FIRST : they fix how many values a series carries
uo_chart.of_set_categories(/*labels*/ ls_months)
uo_chart.of_add_series(/*key*/ "sales", /*label*/ "Revenue", /*type*/ u_pbt_chartcartesian.TYPE_BAR, /*values*/ ld_sales)

The type belongs to the SERIES, not to the component #

This is the decision everything else follows from. One component per type — one for bars, one for lines — can never produce a combination: bars with a target line over them, on a second axis. Yet that is the most asked-for shape on a dashboard.

Here there is one component, and each series carries its is_type (TYPE_BAR, TYPE_LINE, TYPE_AREA, TYPE_SCATTER, TYPE_STEPLINE). Changing one series' type leaves the others alone.

ib_secondary puts a series on the second value axis. That is what lets an order count and a revenue figure live together: without it, one of the two is a flat line along the axis.

of_set_categories comes before the series: their number fixes how many values each series must carry.

// Local variables
double ld_target[] = {400, 500, 550, 600, 680, 720}

// Bars and a line in the SAME chart : the type belongs to the series
uo_chart.of_add_series(/*key*/ "target", /*label*/ "Target", /*type*/ u_pbt_chartcartesian.TYPE_LINE, /*values*/ ld_target)

// And its own scale, when the two do not share a unit
uo_chart.of_item(/*key*/ "target").ib_secondary = true

Properties #

PropertyTypeDefaultRole
is_titlestring""Chart title, shown above
ib_show_legendbooleantrueShows the legend. Clicking an entry hides its series — the cheapest way to compare two series out of five
is_legend_locationstringbottomWhere the legend goes (LEGEND_* constants): above or below the plot, or beside it — START/END put it in a column on one side, and the plot gives up that room. START/END are logical: they follow the reading direction. An unknown place is the bottom, and reads back as such
ib_show_gridbooleantrueThe rules behind the plot, at every round value. Without them only the shape stays readable, never a value
ib_value_tooltipbooleantrueThe value panel: when the mouse passes over a category, every series and its value there, at once, and a crosshair marks the column. It is not is_tooltip (inherited), which is the tooltip of the whole component — this one follows the pointer and says what the chart is made of. Each series writes its line with its own is_label_format; a missing value has no line. The tooltip of a series (its is_tooltip) is written in this panel, under the row of the series pointed at, even at false
is_orientationstringverticalColumns or bars (ORIENTATION_* constants). Turns the whole frame of reference, lines and areas included
ib_stackedbooleanfalseStacks the bar series instead of setting them side by side; the area series stack among themselves — never bars with areas. A line is never stacked: it says a level. The bars of the second axis make their own stack, beside the stack of the main axis
is_stack_modestringvalueSum or share (STACK_* constants). In percentage every stack is brought to 100: the axis then reads shares, not totals — down to -100 when some shares are negative. Means nothing outside stacking
ib_enabledbooleantrueGreyed out: the component keeps showing what it shows — a chart with no data is a different thing from a chart the application has switched off — but it stops answering: no click, no key, no legend entry, and it leaves the Tab order. true by default
ib_animatedbooleantrueThe chart arrives animated: the shapes rise from the axis — the whole chart when it goes from empty to drawn and when a series is added. New values slide to their place, and a shape a live chart pushes (of_append_values) rises alone: a dashboard that refreshes itself can keep the animation. A workstation set to reduce motion does not animate, unless the application insists (PBT_SetAnimationPolicy, section 4.8)
ii_anim_durationinteger450Duration of that arrival, in milliseconds (0 to 5000)
is_anim_easingstringease-outCurve of the arrival (EASING_* constants): linear, ease-out, back-out which overshoots and comes back, bounce-out which bounces, elastic-out which snaps. This is what gives an animation its character
ii_anim_delayinteger0Delay between two series on arrival, in milliseconds (0 to 1000). They then come in one after another instead of appearing together, which gives the chart its reading order. 0 = all at once
is_formatstring""The format of every number the chart writes — value axes, data labels and value panel — in the syntax of a DataWindow format: #,##0.00, $#,##0, #,##0 "units", sections positive;negative;zero. The separators are those of the display language. An axis may carry its own (of_axis(AXIS_VALUE2).is_format), which wins over this one. Empty (or a format that is not a numeric one) = the number as it is, to the thousandth
is_theme_stylestring""Visual style of the component (THEME_STYLE_* constants); empty = the application's, followed at every change
is_theme_modestring""Light or dark variant (THEME_MODE_* constants); empty = the application's, followed at every change
il_theme_accentlong-1Accent colour of this component (-1 = the theme's accent)
is_tooltipstring""Plain tooltip shown when hovering the component
is_super_tooltip_titlestring""Title of the rich tooltip (takes precedence over is_tooltip)
is_super_tooltip_textstring""Text of the rich tooltip (rich markup accepted)
is_super_tooltip_imagestring""Image of the rich tooltip

Methods #

MethodRole
of_set_categories ( string as_labels[] )The labels of the category axis — text: a markup tag in them is dropped, so the axis, the panel and #x# say the same thing. Call it before the series. Returns 0 once applied, -2 when the component is not created
of_set_value_labels ( string as_labels[] )Labels on the value axis. Empty — the normal case — that axis carries numbers. Filled, it carries bands like the category axis: the two-categorical frame a heat map is drawn in. Returns 0 once applied, -2 when the component is not created
of_get_value_labels ( ref string as_labels[] )Fills as_labels[] with what the value axis carries right now and returns the count. Zero = it carries numbers; a label holding `` reads back whole
of_get_categories ( ref string as_labels[] )Fills as_labels[] with the categories the chart carries right now — after of_append_categories dropped the oldest, after of_from_datastore read them — and returns their number
of_get_last_error ( )Why the last call was refused (a role of of_map the rows do not have, a NULL bound, a position outside a series…), or how many rows the last of_from_datastore skipped and why; else the last error of the DLL, as for every component
of_add_heat_series ( string as_key, string as_label, long al_x[], long al_y[], double ad_weight[] )A heat map: one cell per (category, value label) pair, coloured by its weight. al_x is the rank of the category and al_y the rank of the label, both from 1 — the ranks a PowerScript array is indexed by, which a double loop writes without arithmetic. Set both label lists first. A NULL weight is an empty cell: nothing is drawn, labelled or clickable there. Returns 0 once added, -5 when the key is empty, holds / or `, or is already held, -2` when the component is not created
of_add_ohlc_series ( string as_key, string as_label, double ad_open[], double ad_high[], double ad_low[], double ad_close[] )An OHLC series: the range from low to high, a tick on the left for the open and one on the right for the close. Four numbers per point, and the axis is read against the high and the low — the other two are inside them by construction. The four arrays are truncated to the shortest. Returns 0 once added, -5 when the key is empty, holds / or `, or is already held, -2` when the component is not created
of_add_candle_series ( string as_key, string as_label, double ad_open[], double ad_high[], double ad_low[], double ad_close[] )The same four numbers, drawn as candles: a wick from low to high and a filled body between the open and the close. A doji — open equal to close — keeps one pixel of body, so it stays a line the eye can find. Returns 0 once added, -5 when the key is empty, holds / or `, or is already held, -2` when the component is not created
of_set_series_ohlc ( string as_key, double ad_open[], double ad_high[], double ad_low[], double ad_close[] )New quotes for a financial series already on the chart. What of_set_series_values is to a series of values. Returns 0 once applied, -5 when no series has this key or when it is not a financial series, -2 when the component is not created
of_get_series_ohlc ( string as_key, ref double ad_open[], ref double ad_high[], ref double ad_low[], ref double ad_close[] )Fills the four arrays with what the series carries right now and returns the number of points. A series that is not financial answers 0
of_add_series ( string as_key, string as_label, string as_type, double ad_values[] { , long al_color } )Adds a series with its type — TYPE_BAR, TYPE_LINE, TYPE_AREA, TYPE_SCATTER or TYPE_STEPLINE; the overload also takes its colour (RGB()), otherwise the palette picks. A NULL value (SetNull) is a gap: nothing is drawn, labelled or clickable there, and a line is cut. A key already held is refused, never replaced: of_set_series_values and the of_item handle change a series that exists. Returns 0 once added, -5 when the type is not one of those five (a heat map and the financial series have their own method), or when the key is empty, holds / or `, or is already held, -2` when the component is not created
of_set_series_values ( string as_key, double ad_values[] )New values for a series already drawn, everything else untouched. This is what a live dashboard calls: the series keeps its identity, so the shapes slide instead of jumping. A NULL value is a gap. Returns 0 once applied, -5 when no series has this key or when it carries points or quotes (of_set_series_points, of_set_series_ohlc replace those), -2 when the component is not created
of_set_point_color ( string as_key, long al_position, long al_color )The colour of one point — the month that passed its limit, in red. al_position counts from 1; -1 (or NULL) gives the point the colour of its series back. Bars, line markers and scatter points take it, and it slides with its point in a live chart. Returns 0 once applied, -5 when no series has this key, when the position is outside the series, or for a heat map or a financial series (their colours are their ramp and their direction), -2 when the component is not created
of_get_point_color ( string as_key, long al_position )Returns the colour (an RGB() long) that of_set_point_color — or a ROLE_COLOR column — gave the point at al_position, counted from 1, or -1 when it has none (it takes the colour of its series), and for an unknown key or position
of_append_values ( string as_key, double ad_values[], long al_max_points )A live chart: pushes new values at the end of a series and drops the oldest once it carries more than al_max_points (0 = no limit). Only the new values travel — the series is not sent again on every tick. Pair it with of_append_categories. The new shapes rise alone, the others slide. Push every series, with the same maximum as of_append_categories: a series left behind slides out of step with its categories. Returns 0 once applied, -5 when no series has this key or when it carries points or quotes, -2 when the component is not created
of_append_categories ( string as_labels[], long al_max_count )New categories at the end of the axis, the oldest dropped beyond al_max_count (0 = no limit): the labels of a live chart slide with its values. Push every series with of_append_values and the same maximum. Returns 0 once applied, -2 when the component is not created
of_add_point_series ( string as_key, string as_label, double ad_x[], double ad_y[] { , double ad_weight[] } )A series positioned by value on both axes: x says where along the category axis, y how high. That axis then stops being a category axis — it becomes a second value axis, with its own graduations. An overload takes a weight per point, which sizes the bubble. A NULL weight keeps the default size, outside the scale of the others. Do not mix such series with series of values on a chart of categories: the category labels give way to graduations. Returns 0 once added, -5 when the key is empty, holds / or `, or is already held, -2` when the component is not created
of_set_series_points ( string as_key, double ad_x[], double ad_y[], double ad_weight[] )New points for a series that already carries some. What of_set_series_values is to a series of values. Returns 0 once applied, -5 when no series has this key or when it carries values or quotes, -2 when the component is not created
of_get_series_points ( string as_key, ref double ad_x[], ref double ad_y[], ref double ad_weight[] )Fills the three arrays with what the series carries right now and returns the number of points. A series of values answers nothing in ad_x: it has no x of its own
of_get_series_values ( string as_key, ref double ad_values[] )Fills ad_values[] with what the series carries right now and returns the count. A live read : it asks the chart, not the last push
of_remove_series ( string as_key )Removes one series; the others keep their colour — taken when they were added — and their visibility; its tooltip and item colours go with it. Its handle (of_item) is destroyed with it: a later of_item on the same key creates a fresh one. Returns 0 once removed, -5 when no series has this key, -2 when the component is not created
of_clear ( )Empties the chart — series and categories; the series handles go with them. The axes keep their settings and their sections. Returns 0 once cleared, -2 when the component is not created
of_from_datastore ( datastore ads )Feeds the chart from a DataStore (a DataWindow, a DataWindowChild: overloads), as the graph of a DataWindow does: a column of categories, a column of values and, when there is one, a column of series — a series per value found there, one series named after the value column without it. The rows sharing a category and a series are summed; the categories come in the order of the rows (sort the DataStore); a category without a row is a gap. A colour column colours its point. A column plays a role when it is named like it (category, series, value, color) or when of_map says so; regional numbers and dates are read right. Given again, the chart changes in place: a series keeps its type, colour and axis, a series added by hand is never touched; a new series is a bar. Returns 0 once loaded (rows whose series cannot be a key are skipped: of_get_last_error says how many), -5 when the DataStore is not valid or no column plays ROLE_CATEGORY or ROLE_VALUE (of_get_last_error says which), -2 when the component is not created
of_map ( string as_role, string as_column )Gives a column of the DataStore a role (ROLE_CATEGORY, ROLE_SERIES, ROLE_VALUE, ROLE_COLOR) when its name does not say it. Before of_from_datastore, or after: the rows are read again. An empty column gives the role back to the column named like it. Returns 0 once set, -5 when the role is not a ROLE_ constant or the column is not one of the last DataStore, -2 when the component is not created
of_reload ( )Reads the rows of the DataStore (or DataWindow) given to of_from_datastore again — after a Retrieve, an edit, a filter — and changes the chart in place: the shapes slide to their new values. Returns 0 once read, -5 when no DataStore was given or it is no longer valid, -2 when the component is not created
of_item ( string as_key )Returns a series handle, to change it later
of_axis ( string as_axis )Returns an axis handle (AXIS_CATEGORY, AXIS_VALUE, AXIS_VALUE2), to set it up afterwards. Any other role gives no handle (IsValid() is false)
of_add_axis_section ( string as_axis, string as_key, double ad_from, double ad_to, long al_color )A band across the plot, behind the data: "below 200 is bad". Drawn under the shapes, it never competes with them. On the category axis, ad_from and ad_to are positions counted from 1 (2 to 3 covers the second and the third category). A colour of -1 (or NULL) is a pale wash of the theme accent. Returns 0 once added, -5 when the axis is not one of AXIS_*, when a bound is NULL, or when the key is empty, holds / or `, or is already held on that axis, -2` when the component is not created
of_add_axis_threshold ( string as_axis, string as_key, double ad_at, long al_color, integer ai_thickness )A line across the plot at one value — a target, a limit. Same registry as the bands, but drawn to be seen. A colour of -1 (or NULL) draws it in the theme accent. Returns 0 once added, -5 when the axis is not one of AXIS_*, when a bound is NULL, or when the key is empty, holds / or `, or is already held on that axis, -2` when the component is not created
of_clear_axis_sections ( string as_axis )Removes every band and every threshold of one axis. Returns 0 once cleared, -5 when the axis is not one of AXIS_*, -2 when the component is not created
of_remove_axis_section ( string as_axis, string as_key )Removes one band or threshold of one axis: the others stay. Returns 0 once removed, -5 when the axis is not one of AXIS_* or holds no section with this key, -2 when the component is not created
of_reset ( )Empties the chart — series and axis handles included — and puts every property back to its default. Returns 0 once done, -2 when the component is not created

Without a key (demo mode), the chart draws only its first 3 series, legend included. The others stay in the model — of_count, of_get_series_values and their handles see them — and setting the key shows them without you sending anything again.


Events #

EventFired when
ue_point_clicked (string as_key, long al_index, double ad_value)A bar, a point, a cell or a quote was clicked — or confirmed with Enter: the series key, the position of the point in the series, counted from 1, and its value — the point's own value whatever the shape of the series: the y of a scatter, the weight of a heat cell, the close of a quote. On the keyboard Left/Right walk the categories and Up/Down choose the series the panel underlines; a point series or a heat map, once chosen, is walked point by point. A gap has nothing to click; the point the keyboard is on is ringed, and said to a screen reader
ue_point_rclicked (string as_key, long al_index, double ad_value, long al_x, long al_y)A right click on a bar, a point, a cell or a quote — or the Menu key (Shift+F10) on the point the keyboard is on: the series key, the position from 1 and the value, as ue_point_clicked gives them. Open your menu there; al_x, al_y: where to open the menu, in screen pixels — the pointer, or the middle of the point's shape from the keyboard (Menu key, Shift+F10); a contextmenu opens there as they are (uo_menu.of_show(al_x, al_y))
ue_rclicked ( )A right click on the chart where no point is drawn — the axes, the empty plot, the legend. A right click on a point raises ue_point_rclicked instead, never both
ue_series_toggled (string as_key, boolean ab_visible)The user hid or restored a series with a click in the legend. What the chart displays is then no longer what the application sent. Setting ib_visible is a value, like ticking a check box: this event reports the user's gesture

The animation is a way in, not a computation: the final geometry is written straight away, and only the arrival is played. A chart that is never displayed — born off screen, on a tab nobody opened — therefore shows the right bars, silently.


Item properties #

PropertyTypeDefaultRole
is_labelstring""The name of the series, as the legend shows it
is_typestringbarbar · line · area · scatter · stepline (TYPE_* constants). Changes the drawing of this series alone — that is what makes a combination chart. Only a type of the same family is taken: a series of values among bar, line, area, scatter and stepline, a financial series between ohlc and candle; any other is ignored and is_type reads back the type kept
il_colorlong-1Colour of the series (RGB()). -1 while none is set: the palette picks, when the series is added, and the series keeps it: removing another series never recolours it. One point may take its own (of_set_point_color). The inherited item colours (il_accent, il_back_color, il_text_color and their hover twins) have no effect on a series: il_color decides
ib_visiblebooleantruefalse hides a series without removing it — the legend keeps the way back. Like a check box, it is a value you set: ue_series_toggled reports the user's click in the legend
ib_secondarybooleanfalsePlots the series on the second axis. That is how a count and an amount live on the same chart
ib_data_labelsbooleanfalseWrites each point's value next to it. Off by default: on fifty points the labels cover the drawing they explain
is_label_formatstring""What each label and each line of the panel says: #y# the value, #x# the category (the x of a point series, the column of a heat cell), #v# the row of a heat cell, #label# the name of the series, #open# #high# #low# #close# the quotes; the rest is written as it stands — "$#y#K". Empty = the value alone. A label written inside a stacked bar takes black or white, whichever its bar carries
id_smoothnessdouble1Lines and areas only: how round the line is drawn, 0 = straight segments, 1 = fully curved, as LiveCharts draws it. A step line ignores it — it says the level HELD until the next category, and a curve would say it drifted. A curve can pass beyond its points; it is cut to the plot frame and never paints over the axis labels
ib_fillbooleantrueLines and areas: the wash under the stroke, down to the axis, in the series' own colour. It is the removal that is the deliberate act — for a line laid over something else (columns, coloured axis bands) that the wash would hide
il_fill_colorlong-1The colour of that wash. -1 = the colour of the line itself
is_markerstring"circle"Lines, step lines and scatters: the SHAPE of the marker on each point (constants MARKER_*: none, circle, square, triangle, diamond). Not decoration — two lines that cross, printed in grey, are told apart by their markers and by nothing else
ii_thicknessinteger2Lines and areas: the thickness of the stroke, in pixels
il_point_countlong0How many points this series carries — values, (x, y) pairs or quotes (read only). A long: a live series may keep more than 32,767
il_cold_colorlong-1Heat maps only: the COLD end of the ramp, the lightest reading. -1 = the component's own ramp, one blue, from very pale to deep
il_mid_colorlong-1The MIDDLE stop. Three stops and not two: interpolating from one end to the other washes out the middle of the scale, which is where most readings sit. -1 = the component's own middle blue
il_hot_colorlong-1The HOT end, the heaviest reading. It is the one the legend shows. -1 = the component's own deep blue
il_up_colorlong-1Financial series only: the colour of a point that closes above its open. -1 = the component's own green
il_down_colorlong-1And that of a point that closes below. Two colours because the direction is what such a chart is read for — one colour would hide it. -1 = the component's own red
is_tooltipstring""Its tooltip, written in the value panel, right under the row of the series — only when it is the series pointed at (its bar, point or line under the mouse, or the series chosen on the keyboard with Up / Down), never for the other series of the column, never as a second bubble. A column met where no shape is drawn points at no series. With ib_value_tooltip at false, the panel still opens for it, without the figures. A point series or a heat map shows it in the panel the keyboard opens on its point. Markup accepted
is_super_tooltip_titlestring""The bold title of its tooltip, written in the panel under its row
is_super_tooltip_textstring""The text of its tooltip, in the panel. Markup accepted
is_super_tooltip_imagestring""An image at the top of its tooltip, in the panel (bundle path, absolute path or resources.dll:name)

Axis properties #

PropertyTypeDefaultRole
is_titlestring""Title written along the axis. Empty = no title, and no room reserved for one. The tooltip and the item colours an axis handle inherits (is_tooltip, is_super_tooltip_*, il_accent, il_back_color, il_text_color…) have no effect on an axis
id_mindoubleNULLImposed lower bound. It wins over the data and is not rounded: someone who writes 0 means 0. NULL (SetNull) imposes nothing: the axis follows its data again, and a free bound reads back NULL (IsNull), never 0. Free, a value axis takes zero in only when a bar or an area stands on it: quotes and lines are read on their own range
id_maxdoubleNULLImposed upper bound, same rule. What goes past it is cut at the edge of the plot
id_stepdouble0Distance between two grid lines, in values. 0 = a round step read from the range
ii_label_rotationinteger0Rotation of this axis' labels, in degrees (-90 to 90) — category names or value graduations. Twelve month names only fit under a chart when they lean; when they still do not, the chart writes one in N, the first and the last always
ib_separatorbooleantrueIts grid lines. A category axis rarely needs them, a value axis nearly always does
ii_section_countinteger0How many bands and thresholds this axis carries (read only)
ib_logarithmicbooleanfalseValue axes only: a logarithmic scale, graduated by decades (1, 10, 100…), each decade the same height — for figures that span several orders of magnitude. Zero and negative values have no place on it and are not drawn
is_formatstring""The format of this axis — its graduations, and the labels and the panel of the series drawn on it — over the chart's is_format: an amount on one side, a count of orders on the other. Same syntax (#,##0, 0.0 "u"…). Empty = the chart's format

Examples #

Setting the animation to suit the screen #

// A dashboard that refreshes every few seconds : no arrival animation
uo_chart.ib_animated = false

// Elsewhere, a slower arrival that is actually seen
uo_chart.ii_anim_duration = 1200

Opening the rows behind a point #

// Event ue_point_clicked of uo_chart : the series key, the position of the
// point (from 1) and its value - enough to open the rows behind it
// Local variables
string ls_month

// On a series of values, the position IS the rank of the category
ls_month = is_months[al_index]
wf_open_orders(/*series*/ as_key, /*month*/ ls_month, /*amount*/ ad_value)

A live dashboard #

// Timer event of the window : new values for the same series, so the bars
// SLIDE to their new height instead of replaying their arrival
// Local variables
double ld_sales[]

// Read the figures, then hand them to the series already on the chart
ld_sales = wf_read_sales()
uo_chart.of_set_series_values(/*key*/ "sales", /*values*/ ld_sales)

A live chart that slides #

// Timer event of the window, every second : ONE new reading. Only that value
// travels ; past sixty, the oldest leaves on both the axis and the series
// Local variables
string ls_time[]
double ld_cpu[]

// The time of the reading on the axis, the reading itself in the series
ls_time[1] = String(Now(), "hh:mm:ss")
ld_cpu[1] = wf_read_cpu()
uo_chart.of_append_categories(/*labels*/ ls_time, /*max_count*/ 60)
uo_chart.of_append_values(/*key*/ "cpu", /*values*/ ld_cpu, /*max_points*/ 60)

A missing reading, and the chart as a picture #

// March was not measured : a NULL value is a gap, the line is cut there
// Local variables
double ld_temp[] = {18.5, 19.2, 0, 21.4}

// The third reading is missing : NULL, not zero
SetNull(ld_temp[3])
uo_chart.of_add_series(/*key*/ "temp", /*label*/ "Temperature", /*type*/ u_pbt_chartcartesian.TYPE_LINE, /*values*/ ld_temp)

// The chart as it is on screen, title and legend included, to a PNG file
uo_chart.of_save_as_png(/*path*/ "C:\Reports\temperature.png")

A band and a target on the value axis #

// A pale red band below 200 and a target line at 600, behind the bars
uo_chart.of_add_axis_section(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE, /*key*/ "low", /*from*/ 0, /*to*/ 200, /*color*/ RGB(/*red*/ 255, /*green*/ 220, /*blue*/ 220))
uo_chart.of_add_axis_threshold(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE, /*key*/ "target", /*at*/ 600, /*color*/ RGB(/*red*/ 200, /*green*/ 70, /*blue*/ 70), /*thickness*/ 2)

// The value axis says what it measures
uo_chart.of_axis(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE).is_title = "Sales ($K)"

A chart fed from a DataStore #

// The month on the category axis, one series per product category, the amounts
// of the rows summed by the chart - what the graph of a DataWindow does
// Local variables
datastore lds_sales

// Your DataStore and its Retrieve, sorted : the categories come in the order of the rows
lds_sales = create datastore
lds_sales.DataObject = "d_sales"
lds_sales.SetTransObject(SQLCA)
lds_sales.Retrieve()
lds_sales.SetSort("month A")
lds_sales.Sort()

// Which column plays which role, then ONE call reads every row
uo_chart.of_map(/*role*/ u_pbt_chartcartesian.ROLE_CATEGORY, /*column*/ "month")
uo_chart.of_map(/*role*/ u_pbt_chartcartesian.ROLE_SERIES, /*column*/ "category")
uo_chart.of_map(/*role*/ u_pbt_chartcartesian.ROLE_VALUE, /*column*/ "amount")
uo_chart.of_from_datastore(/*ads*/ lds_sales)

// Later, the rows changed (an edit, a new Retrieve) : read again IN PLACE, the
// bars slide and every series keeps what you set on it
lds_sales.Retrieve()
uo_chart.of_reload()

The colour of one point, a menu on another #

// May passed its limit : ONE bar of the series in red, the others keep their colour
uo_chart.of_set_point_color(/*key*/ "sales", /*position*/ 5, /*color*/ RGB(/*red*/ 200, /*green*/ 40, /*blue*/ 40))
// Event ue_point_rclicked of uo_chart : a menu about the point under the mouse
// Local variables
m_point lm_menu

// Remember which point the menu is about, then open it where the pointer is
is_menu_series = as_key
il_menu_position = al_index
lm_menu = create m_point
lm_menu.m_popup.PopMenu(w_main.PointerX(), w_main.PointerY())
destroy lm_menu

Good practice #

Inherited from the common base #

These members exist on every visual component — they are not specific to this one. They are detailed once, in the transverse chapters; this table only says where to read them.

MembersRoleDetailed in
of_count · of_keys_at · of_hasWalk what the component holds3.2 Items
of_resetPut the component back to zero3.6 Resetting a component: of_reset()
of_register_shortcut · of_clear_shortcutsThe component's keyboard chords3.5 Keyboard shortcuts
of_is_created · of_is_ready · of_get_last_errorWhether it was born, whether it is ready, what failed3.7 Diagnostics
of_save_as_png · of_save_as_jpgExport the rendering as an image3.8 Exporting the rendering as an image
of_set_redrawGroup changes into a single repaint3.10 Best practices
of_preload_iconsIcons shown with no delayInstant display: of_icon
of_set_translationTranslate one of the component's labels5.2 Adapting a label: of_set_translation
of_focus_webviewGive the component the focus6.4 Keyboard and focus
of_print · of_print_to_pdfPrint, or write a PDF6.9 Printing
of_set_property · of_get_property · of_component_nameDriving a property by its name3.1 The property engine
is_accessible_name · is_accessible_descriptionThe name and description a screen reader says3.4 Optional properties and events

Two helpers are not inherited: of_icon and of_escape_markup live on n_pbt_utils. Declare one — n_pbt_utils lnv_utils, nothing to create — and call them on it.

← Component reference · Guide contents