Encapsulates drawing commands on a graphics object.
// a line chart drawn with the Graphics object: gridlines and axes with
// drawLine(), value and category labels with drawText(), and a marker
// at each data point with drawCircle()
// the data being plotted
const labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"];
const values = [42, 58, 51, 73, 66, 89];
// the value axis is drawn in gridlines this far apart
const step = 25;
// colors used by the chart
const gridline_color = new Color(220, 220, 220);
const axis_color = new Color(120, 120, 120);
const label_color = new Color(60, 60, 60);
const line_color = new Color(0, 90, 200);
class ChartControl extends Control {
constructor(x_pos, y_pos, width, height) {
// call the Control constructor and connect
// the paint event handler
super(x_pos, y_pos, width, height);
this.paint.connect(this, this.onPaintCalled);
}
// the x position of data point |i|, spread evenly across the plot
pointX(i, left, width) {
return Math.round(left + (width * i) / (values.length - 1));
}
// the y position of |value|, measured up from the bottom of the plot
pointY(value, bottom, height, scale_max) {
return Math.round(bottom - (height * value) / scale_max);
}
onPaintCalled(sender, evt) {
// when the paint event handler is called, get the graphics
// object associated with the control and draw the chart
const gr = evt.graphics;
const size = this.getSize();
// the plot area, leaving room for the value labels along the
// left edge and the month labels underneath
const left = 44;
const top = 16;
const right = size.width - 16;
const bottom = size.height - 28;
const width = right - left;
const height = bottom - top;
// nothing legible fits in a very small control
if (width < 60 || height < 60)
return;
// round the top of the scale up to a whole step, so the
// gridlines land on round numbers
let largest = 0;
for (const value of values) {
largest = Math.max(largest, value);
}
const scale_max = Math.ceil(largest / step) * step;
// gridlines, with a value label on each one
gr.setPen(new Pen(gridline_color, 1));
gr.setTextForeground(label_color);
for (let value = 0; value <= scale_max; value += step) {
const y = this.pointY(value, bottom, height, scale_max);
gr.drawLine(left, y, right, y);
// Graphics has no getTextExtent(), so the labels sit at a
// fixed left margin rather than being right-aligned
gr.drawText(`${value}`, 8, y - 8);
}
// the two axes
gr.setPen(new Pen(axis_color, 1));
gr.drawLine(left, top, left, bottom);
gr.drawLine(left, bottom, right, bottom);
// a category label under each data point
for (let i = 0; i < labels.length; ++i) {
// likewise centered by eye rather than by measurement
gr.drawText(labels[i], this.pointX(i, left, width) - 10, bottom + 6);
}
// the line connecting the data points
gr.setPen(new Pen(line_color, 2));
for (let i = 1; i < values.length; ++i) {
gr.drawLine(this.pointX(i - 1, left, width),
this.pointY(values[i - 1], bottom, height, scale_max),
this.pointX(i, left, width),
this.pointY(values[i], bottom, height, scale_max));
}
// a filled marker at each data point
gr.setBrush(new Brush(line_color));
for (let i = 0; i < values.length; ++i) {
gr.drawCircle(this.pointX(i, left, width),
this.pointY(values[i], bottom, height, scale_max),
4);
}
}
}
// the form that hosts the chart
class MyForm extends Form {
constructor(caption, x_pos, y_pos, width, height) {
super(caption, x_pos, y_pos, width, height);
// size the chart to fill the form's client area
const client_size = this.getClientSize();
this.add(new ChartControl(0, 0, client_size.width, client_size.height));
}
}
const f = new MyForm("Graphics Example", 0, 0, 480, 320);
f.center();
f.show();
Application.run(); Draws an arc of a circle, centered at the point (x, y), starting from the point (x1, y1) on the edge of the circle and proceeding counter-clockwise to another point (x2, y2), also on the edge of the circle.
Draws a circle with the center at the point (x, y) and a radius of r.
Draws an elliptic arc contained on an ellipse that is bounded by a rectangle of a given width and height with an upper-left corner at the point (x, y), and where the arc of the bounded ellipse starts at an angle of deg1 degrees relative to a standard, positive x-axis and ends at an angle of deg2 degrees relative to the same axis.
Draws a bitmap at the position given by (x, y), with a given width and height.
Draws a line from the point (x1, y1) to the point (x2, y2).
Draws a rectangle with an upper-left at the position (x, y) and with a given width and height.
Draws the specified text at the position (x, y), using the currently set font.
Returns a new graphics object.
Creates a new graphics object from a specified bitmap.
Sets the current brush to use when drawing the background on the graphics object.
Sets the current font to use when drawing text on the graphics object.
Sets the current pen to use when drawing the foreground on the graphics object.
Sets the current color to use when drawing text on the graphics object.
Sets the current color to use when drawing text on the graphics object.