You find this example project in your Plugins Download as a Xojo project file within the examples folder: /ChartDirector/Tracking Cursor/Track Line with Axis Labels
Class App Inherits Application
Const kEditClear = "&Löschen"
Const kFileQuit = "Beenden"
Const kFileQuitShortcut = ""
End Class
Class Window1 Inherits Window
Control Canvas1 Inherits MyControl
ControlInstance Canvas1 Inherits MyControl
End Control
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&Ablage"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Bearbeiten"
MenuItem EditUndo = "&Rückgängig"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "&Ausschneiden"
MenuItem EditCopy = "&Kopieren"
MenuItem EditPaste = "&Einfügen"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "&Alles auswählen"
End MenuBar
Class MyControl Inherits Canvas
EventHandler Sub MouseMove(X As Integer, Y As Integer)
trackLineLegend x
pic = c.makeChartPicture
me.Invalidate
End EventHandler
EventHandler Sub Open()
// Data for the chart as 2 random data series
dim r as new CDRanSeriesMBS(127)
dim data0() as double = r.getSeries(180, 10, -1.5, 1.5)
dim data1() as double = r.getSeries(180, 150, -15, 15)
dim timeStamps() as double = r.getDateSeries(180, CDBaseChartMBS.chartTime(2011, 1, 1), 86400)
// Create a XYChart object of size 670 x 400 pixels
c = new CDXYChartMBS(670, 400)
// Add a title to the chart using 18 pts Times New Roman Bold Italic font
call c.addTitle("Plasma Stabilizer Energy Usage", "timesbi.ttf", 18)
// Set the plotarea at (50, 55) with width 100 pixels less than chart width, and height 90 pixels
// less than chart height. Use a vertical gradient from light blue (f0f6ff) to sky blue (a0c0ff)
// as background. Set border to transparent and grid lines to white (ffffff).
call c.setPlotArea(50, 55, c.getWidth - 100, c.getHeight - 90, c.linearGradientColor(0, 55, 0, c.getHeight - 35, &hf0f6ff, &ha0c0ff), -1, CDBaseChartMBS.kTransparent, &hffffff, &hffffff)
// Add a legend box at (50, 25) using horizontal layout. Use 10pts Arial Bold as font. Set the
// background and border color to Transparent.
call c.addLegend(50, 25, false, "arialbd.ttf", 10).setBackground(CDBaseChartMBS.kTransparent)
// Set axis label style to 8pts Arial Bold
call c.xAxis.setLabelStyle("arialbd.ttf", 8)
call c.yAxis.setLabelStyle("arialbd.ttf", 8)
call c.yAxis2.setLabelStyle("arialbd.ttf", 8)
// Set the axis stem to transparent
c.xAxis.setColors(CDBaseChartMBS.kTransparent)
call c.yAxis.setColors(CDBaseChartMBS.kTransparent)
call c.yAxis2.setColors(CDBaseChartMBS.kTransparent)
// Configure x-axis label format
c.xAxis.setMultiFormat(CDBaseChartMBS.StartOfYearFilter, "{value|mm/yyyy} ", CDBaseChartMBS.StartOfMonthFilter, "{value|mm}")
// Add axis title using 10pts Arial Bold Italic font
call c.yAxis.setTitle("Power Usage (Watt)", "arialbi.ttf", 10)
call c.yAxis2.setTitle("Effective Load (kg)", "arialbi.ttf", 10)
// Add a line layer to the chart using a line width of 2 pixels.
dim layer as CDLineLayerMBS = c.addLineLayer
layer.setLineWidth(2)
// Add 2 data series to the line layer
layer.setXData(timeStamps)
call layer.addDataSet(data0, &hcc0000, "Power Usage")
layer.addDataSet(data1, &h008800, "Effective Load").setUseYAxis
pic = c.makeChartPicture
me.Invalidate
// fix some properties if set wrong in IDE
me.DoubleBuffer = false
me.EraseBackground = false
#if RBVersion >= 2013.0 then
me.Transparent = False
#endif
End EventHandler
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect)
if pic <> nil then
g.DrawPicture pic, 0, 0
end if
End EventHandler
Sub trackLineLegend(mouseX as integer)
// Clear the current dynamic layer and get the DrawArea object to draw on it.
dim d as CDDrawAreaMBS = c.initDynamicLayer
// The plot area object
dim plotArea as CDPlotAreaMBS = c.getPlotArea
// check if we are outside the plotArea
if mousex<plotArea.getLeftX then Return
if mousey<plotArea.getTopY then Return
if mousex>plotArea.getRightX then Return
if mousey>plotArea.getBottomY then Return
// Get the data x-value that is nearest to the mouse, and find its pixel coordinate.
dim xValue as double = c.getNearestXValue(mouseX)
dim xCoor as integer = c.getXCoor(xValue)
// The vertical track line is drawn up to the highest data point (the point with smallest
// y-coordinate). We need to iterate all datasets in all layers to determine where it is.
dim minY as integer = plotArea.getBottomY
// Iterate through all layers to find the highest data point
dim u as integer = c.getLayerCount-1
for i as integer = 0 to u
dim layer as CDLayerMBS = c.getLayerByZ(i)
// The data array index of the x-value
dim xIndex as integer = layer.getXIndexOf(xValue)
// Iterate through all the data sets in the layer
dim uu as integer = layer.getDataSetCount-1
for j as integer = 0 to uu
dim dataSet as CDDataSetMBS = layer.getDataSetByZ(j)
dim dataPoint as double = dataSet.getPosition(xIndex)
if ((dataPoint <> CDBaseChartMBS.kNoValue) and (dataSet.getDataColor <> CDBaseChartMBS.kTransparent)) then
minY = min(minY, c.getYCoor(dataPoint, dataSet.getUseYAxis))
end if
next
next
// Draw a vertical track line at the x-position up to the highest data point.
d.vline(max(minY, plotArea.getTopY), plotArea.getBottomY + 6, xCoor, d.dashLineColor(&h000000, &h0101))
// Draw a label on the x-axis to show the track line position
dim xlabel as string
xlabel = "<*font,bgColor=000000*> " + c.xAxis.getFormattedLabel(xValue, "mmm dd, yyyy") + " <*/font*>"
dim t as CDTTFTextMBS = d.text(xlabel, "arialbd.ttf", 8)
t.draw(xCoor, plotArea.getBottomY + 6, &hffffff, CDBaseChartMBS.kTop)
t.destroy
// Iterate through all layers to build the legend array
for i as integer = 0 to u
dim layer as CDLayerMBS = c.getLayerByZ(i)
// The data array index of the x-value
dim xIndex as integer = layer.getXIndexOf(xValue)
// Iterate through all the data sets in the layer
dim uu as integer = layer.getDataSetCount-1
for j as integer = 0 to uu
dim dataSet as CDDataSetMBS = layer.getDataSetByZ(j)
// The positional value, axis binding, pixel coordinate and color of the data point.
dim dataPoint as double = dataSet.getPosition(xIndex)
dim yAxis as CDAxisMBS = dataSet.getUseYAxis
dim yCoor as integer = c.getYCoor(dataPoint, yAxis)
dim colorvalue as integer = dataSet.getDataColor
// Draw the axis label only for visible data points of named data sets
if ((dataPoint <> CDBaseChartMBS.kNoValue) and (colorvalue <> CDBaseChartMBS.kTransparent) and (yCoor >= plotArea.getTopY) and (yCoor <= plotArea.getBottomY)) then
// The axis label consists of 3 parts - a track dot for the data point, an axis label,
// and a line joining the track dot to the axis label.
// Draw the line first. The end point of the line at the axis label side depends on
// whether the label is at the left or right side of the axis (that is, on whether the
// axis is on the left or right side of the plot area).
dim n as integer = 4
if yAxis.getAlignment =CDBaseChartMBS.kLeft then
n = -4
end if
dim xPos as integer = yAxis.getX + n
d.hline(xCoor, xPos, yCoor, d.dashLineColor(colorvalue, &h0101))
// Draw the track dot
d.circle(xCoor, yCoor, 4, 4, colorvalue, colorvalue)
// Draw the axis label. If the axis is on the left side of the plot area, the labels
// should right aligned to the axis, and vice versa.
dim axisLabel as string
dim h as string = hex(colorvalue)
while h.len<6
h = "0" + h
wend
axisLabel = "<*font,bgColor=" + h+ "*> " + c.formatValue(dataPoint, "{value|P4}") + " <*/font*>"
t = d.text(axisLabel, "arialbd.ttf", 8)
dim nn as integer = CDBaseChartMBS.kLeft
if yAxis.getAlignment = CDBaseChartMBS.kLeft then
nn = CDBaseChartMBS.kRight
end if
t.draw(xPos, yCoor, &hffffff, nn)
t.destroy
end if
next
next
End Sub
Note "Notes"
Property c As CDXYChartMBS
Property pic As Picture
End Class