Platforms to show: All Mac Windows Linux Cross-Platform

/ChartDirector/symbolline zoom improved


Required plugins for this example: MBS ChartDirector Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /ChartDirector/symbolline zoom improved

This example is the version from Mon, 12th Jan 2020.

Project "symbolline zoom improved.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
Class PicWindow Inherits Window
Const zoomInRatio = 2.0
Const zoomOutRatio = 0.5
Control cntSymbolLineZoom1 Inherits cntSymbolLineZoom
ControlInstance cntSymbolLineZoom1 Inherits cntSymbolLineZoom
End Control
Sub getXY(x as integer, y as integer) ////Private Sub ChtImage_Mousemove(Button As Integer, Shift As Integer, X As Single, Y As Single) // //'Translate the VB coordinates (typically in TWIPS) to pixel coordinates //xPixel = ScaleX(X, Me.ScaleMode, vbPixels) //yPixel = ScaleY(Y, Me.ScaleMode, vbPixels) // //out.AcceptFileDrop //'get the axis scale //maxX1 = chtDist.xAxis.getMaxValue //minX1 = chtDist.xAxis.getMinValue //minY1 = chtDist.yAxis.getMinValue //maxY1 = chtDist.yAxis.getMaxValue // //'with the above information, you can get the x and y data value //xValue = (xPixel - plotAreaLeft) / plotAreaWidth * (maxX1 - minX1) //xValue = (plotAreaBottom - yPixel) / plotAreaHeight * (maxY1 - minY1) // //Debug.Print xValue & "," & yValue End Sub
End Class
Class zoomLineCanvas Inherits canvas
Const allowDrag = true
Const allowMove = true
Const allowZoom = true
Const zoomInRatio = 2.0
Const zoomOutRatio = 0.5
EventHandler Function MouseDown(X As Integer, Y As Integer) As Boolean isMouseDown = true //if cntSymbolLineZoom(window).ToolMove.Value then if allowMove and (not Keyboard.AsyncAltKey) and (not Keyboard.AsyncShiftKey) then me.MouseCursor=System.Cursors.HandClosed StartX=X StartY=Y viewport.startDrag else // zoom StartX=X StartY=Y StartX2=X StartY2=Y end if Return true End EventHandler
EventHandler Sub MouseDrag(X As Integer, Y As Integer) If (Not Keyboard.AsyncShiftKey) And (Not Keyboard.AsyncAltKey) And allowMove Then// cntSymbolLineZoom(window).ToolMove.Value then if viewport.dragTo(CDBaseChartMBS.kDirectionHorizontalVertical, x-Startx,y-Starty) then redraw cntSymbolLineZoom(window).LabelX.Text="x: "+str(getXdata(x)) cntSymbolLineZoom(window).LabelY.Text="y: "+str(getYdata(y)) end if else StartX2=X StartY2=Y dim l,t as integer dim w,h as integer l=min(StartX,StartX2) t=min(StartY,StartY2) w=StartX2-StartX h=StartY2-StartY if w<0 then w=-w if h<0 then h=-h cntSymbolLineZoom(Window).LabelX.Text="x: "+Str(getXdata(x)) cntSymbolLineZoom(Window).LabelY.Text="y: "+Str(getYdata(y)) // trigger refresh RectangleTop = t rectangleLeft = l rectangleWidth = w rectangleHeight = h me.Invalidate end if End EventHandler
EventHandler Sub MouseMove(X As Integer, Y As Integer) //cntSymbolLineZoom(parent).LabelX.Text=str(me.viewport.getViewPortLeft) //cntSymbolLineZoom(parent).LabelY.Text=str(me.viewport.getViewPortTop) If (AllowZoom = True) And (Keyboard.AsyncOptionKey = True) Then // Zoom In MouseCursor = System.Cursors.MagnifyLarger CleanUp // Finalize redraw ElseIf (AllowZoom = True) And (Keyboard.AsyncShiftKey = True) Then // Zoom Out MouseCursor = System.Cursors.MagnifySmaller CleanUp // Finalize redraw Else Dim HotSpotID As Integer // Check if over a hotspot; Nil check prevents spurious NilObjectExceptions If (ImageMapHandler <> Nil) Then HotSpotID = ImageMapHandler.getHotSpot(X, Y) If (HotSpotID > 0) Then cntSymbolLineZoom(window).Timer1.Mode=0 MouseCursor = System.Cursors.StandardPointer DrawItemInfo(X, Y) ElseIf (AllowMove = True) Then MouseCursor = System.Cursors.HandOpen CleanUp // Finalize redraw cntSymbolLineZoom(window).Timer1.Mode=2 Else MouseCursor = System.Cursors.StandardPointer CleanUp // Finalize redraw cntSymbolLineZoom(window).Timer1.Mode=2 End If End If //dim maxX,maxY,curX,curY as integer //dim maxXdata,maxYdata,minXdata,minYdata,curXdata,curYdata as double // //maxX=c.getPlotArea.getWidth-1 //maxY=c.getPlotArea.getHeight-1 // //minXdata=c.xAxis.getMinValue //maxXdata=c.xAxis.getMaxValue //minYdata=c.yAxis.getMinValue //maxYdata=c.yAxis.getMaxValue // //curX=x-c.getPlotArea.getLeftX //curY=c.getPlotArea.getHeight+c.getPlotArea.getTopY-y // //curXdata=minXdata+curX*(maxXdata-minXdata)/maxX //curYdata=minYdata+curY*(maxYdata-minYdata)/maxY cntSymbolLineZoom(window).LabelX.Text="x: "+str(getXdata(x)) cntSymbolLineZoom(window).LabelY.Text="y: "+str(getYdata(y)) //cntSymbolLineZoom(window).LabelXax.Text="xax: "+str(minXdata)+","+str(maxXdata) //cntSymbolLineZoom(window).LabelYax.Text="yax: "+str(minYdata)+","+str(maxYdata) exception End EventHandler
EventHandler Sub MouseUp(X As Integer, Y As Integer) Me.rectangleWidth = 0 isMouseDown = false if allowMove and (not Keyboard.AsyncAltKey) and (not Keyboard.AsyncShiftKey) then //cntSymbolLineZoom(window).ToolMove.Value then me.MouseCursor=System.Cursors.HandOpen elseif allowZoom and Keyboard.AsyncAltKey then //cntSymbolLineZoom(window).ToolZoomIn.Value then // zoom on point? if abs(X-StartX)<3 and abs(Y-StartY)<3 then // zoom in on point if viewport.canZoomIn(CDBaseChartMBS.kDirectionHorizontalVertical) then if viewport.zoomAt(CDBaseChartMBS.kDirectionHorizontalVertical, x, y, me.zoomInRatio) then redraw end if else redraw beep end if else // zoom in on a rectangle if viewport.canZoomIn(CDBaseChartMBS.kDirectionHorizontalVertical) then if viewport.zoomTo(CDBaseChartMBS.kDirectionHorizontalVertical, x, y, StartX, StartY) then redraw end if else redraw beep end if end if elseif allowZoom and Keyboard.AsyncShiftKey then //cntSymbolLineZoom(window).ToolZoomOut.Value then // zoom out on point if viewport.canZoomOut(CDBaseChartMBS.kDirectionHorizontalVertical) then if viewport.zoomAt(CDBaseChartMBS.kDirectionHorizontalVertical, x, y, zoomOutRatio) then redraw end if else redraw beep end if end if End EventHandler
EventHandler Sub Open() Me.viewport=New CDViewPortManagerMBS viewport.setViewPortHeight 1 viewport.setViewPortTop 0 viewport.setViewPortWidth 1 viewport.setViewPortLeft 0 viewport.setZoomInWidthLimit 0.001 'viewport.setZoomInHeightLimit 0.01 viewport.setZoomOutWidthLimit 0.2 'viewport.setZoomOutHeightLimit 1.0 dim x0 as Double=70 dim x1 as Double=50 dim x2 as Double=30 data0.Append x0 data1.Append x1 data2.Append x2 for i as integer=1 to 100 x0=x0+rnd*5.0-2.5 x1=x1+rnd*5.0-2.5 x2=x2+rnd*5.0-2.5 data0.Append x0 data1.Append x1 data2.Append x2 next // for the selection box rectanglePicture=New Picture(32,32,32) rectanglePicture.Graphics.ForeColor=&cFF0000 rectanglePicture.Graphics.FillRect 0,0,32,32 rectanglePicture.mask.Graphics.ForeColor=&cCCCCCC rectanglePicture.mask.Graphics.FillRect 0,0,32,32 me.MouseCursor=System.Cursors.HandOpen // fix some properties if set wrong in IDE me.DoubleBuffer = false me.EraseBackground = false #if RBVersion >= 2013.0 then me.Transparent = False #endif redraw End EventHandler
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect) If g <> Nil Then If overlay <> Nil Then g.DrawPicture overlay,0,0 Else g.DrawPicture lastpicture,0,0 If rectangleWidth > 0 Then g.DrawPicture rectanglePicture, rectangleLeft, rectangleTop, rectangleWidth, rectangleHeight, 0, 0, rectanglePicture.Width, rectanglePicture.Height End If end if End If End EventHandler
Private Sub CleanUp() // Finalize redraw Me.rectangleWidth = 0 Me.Invalidate Me.NeedClear = False Me.Overlay = Nil End Sub
Private Sub DrawItemInfo(X As Integer, Y As Integer) Dim Index As Integer Dim Key, KeyValue As String Dim XLabel As String Dim XValue As String Dim DataSet As String Dim DataSetName As String Dim Value As String Dim Title As String Dim Sector As String Dim Label As String // Error check If (ImageMapHandler = Nil) Then Return // Do key/value pair priming calls Index = 0 Key = ImageMapHandler.getKey(Index) KeyValue = ImageMapHandler.getValue(Index) Do // NOTE: This is not the complete supported list of parameters; Refer to ChartDirector documentation on 'Parameter Substitution and Formatting' for additional parameters Select Case Key Case "xlabel" XLabel = KeyValue Case "x" XValue = KeyValue Case "dataset" DataSet = KeyValue Case "datasetname" DataSetName = KeyValue Case "value" Value = KeyValue Case "title" Title = KeyValue Case "sector" Sector = KeyValue Case "label" Label = KeyValue End Select Index = Index + 1 // Get next key/value pair Key = ImageMapHandler.getKey(Index) KeyValue = ImageMapHandler.getValue(Index) Loop Until Key.Len = 0 // Compose label graphic If (Label <> "") Then Value = Label + ": " + Value Dim B As Picture = New Picture(Width, Height, 32) Dim G As Graphics = B.Graphics Dim W As Integer = 6 + G.StringWidth(Value) Dim H As Integer = 20 // Add some space between the cursor position and the initial label drawing position X = X + 10 Y = Y + 10 // If we are too close to the right, we need to move our label drawing position left If (X + W > G.Width) Then X = X - 20 - W // If we are too close to the bottom, we need to move our label drawing position up If (Y + H > G.Height) Then Y = Y - 20 - H // Draw in the current composited chart image B.Graphics.DrawPicture(LastPicture, 0, 0) B.Mask.Graphics.DrawPicture(LastPicture.Mask, 0, 0) // Draw the label graphic G.ForeColor = &cCCCC00 G.FillRect(X, Y, W, H) G.ForeColor = &c000000 G.DrawString(Value, X + 3, Y + 15) // Update the composited chart image Overlay = b Me.Invalidate NeedClear = True End Sub
Sub UpdateMouseCursor() // call from a timer in your window to keep the mouse cursor change with pressing alt and shift keys. // zoom allowed? if not AllowZoom then Return if isMouseDown then Return dim x as integer = me.MouseX dim y as integer = me.MouseY // check if mouse is inside if X<0 then Return if Y<0 then Return if X>me.Width then Return if Y>me.Height then Return // now update If Keyboard.AsyncOptionKey Then // Zoom In MouseCursor = System.Cursors.MagnifyLarger ElseIf Keyboard.AsyncShiftKey Then // Zoom Out MouseCursor = System.Cursors.MagnifySmaller Else Dim HotSpotID As Integer // Check if over a hotspot; Nil check prevents spurious NilObjectExceptions If (ImageMapHandler <> Nil) Then HotSpotID = ImageMapHandler.getHotSpot(X, Y) If (HotSpotID > 0) Then MouseCursor = System.Cursors.StandardPointer ElseIf (AllowMove = True) Then MouseCursor = System.Cursors.HandOpen Else MouseCursor = System.Cursors.StandardPointer End If End If End Sub
Function getXdata(x as integer) As double dim maxX,curX as integer dim maxXdata,minXdata as double maxX=c.getPlotArea.getWidth-1 minXdata=c.xAxis.getMinValue maxXdata=c.xAxis.getMaxValue curX=x-c.getPlotArea.getLeftX return minXdata+curX*(maxXdata-minXdata)/maxX End Function
Function getYdata(y as Integer) As Double dim maxY,curY as integer dim maxYdata,minYdata as double maxY=c.getPlotArea.getHeight//-1 minYdata=c.yAxis.getMinValue maxYdata=c.yAxis.getMaxValue curY=c.getPlotArea.getHeight+c.getPlotArea.getTopY-y return minYdata+curY*(maxYdata-minYdata)/maxY End Function
Protected Sub redraw() // The data for the line chart Dim i As Integer viewport.validateViewPort // Create a XYChart object of size 600 x 375 pixels c = New CDXYChartMBS(Me.width, Me.height) // Add a title to the chart using 18 pts Times Bold Italic font Call c.addTitle("Product Line Global Revenue", "timesbi.ttf", 18) // Set the plotarea at (50, 55) and of 500 x 280 pixels in size. Use a vertical // gradient color from light blue (f9f9ff) to sky blue (aaccff) as background. // Set border to transparent and grid lines to white (ffffff). Call c.setPlotArea(50, 55, Me.width-100, Me.height-110, c.linearGradientColor(0, 55, 0, 335, &hf9fcff, &haaccff), -1, c.kTransparent, &hffffff) Call c.setClipping // Add a legend box at (50, 28) using horizontal layout. Use 10pts Arial Bold as // font, with transparent background. c.addLegend(50, 28, False, "arialbd.ttf", 10).setBackground(c.kTransparent) // Set the x axis labels 'call c.xAxis.setLabels(labels) // Set y-axis tick density to 30 pixels. ChartDirector auto-scaling will use this // as the guideline when putting ticks on the y-axis. c.yAxis.setTickDensity(30) c.yAxis2.setTickDensity(30) // 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 axis line width to 2 pixels c.xAxis.setWidth(2) c.yAxis.setWidth(2) c.yAxis2.setWidth(2) // Add axis title using 10pts Arial Bold Italic font Call c.yAxis.setTitle("Revenue in US millions", "arialbi.ttf", 10) Call c.yAxis2.setTitle("Revenue in US millions", "arialbi.ttf", 10) // scroll Dim axisLowerLimit As Double Dim axisUpperLimit As Double axisUpperLimit = 100.0 *(viewport.getViewPortLeft + viewport.getViewPortWidth) axisLowerLimit = 100.0 * viewport.getViewPortLeft c.xAxis.setLinearScale(axisLowerLimit,axisUpperLimit) c.xAxis.setRounding(False, False) axisLowerLimit = 100.0-100.0 *(viewport.getViewPortTop + viewport.getViewPortHeight) axisUpperLimit = 100.0-100.0 * viewport.getViewPortTop c.yAxis.setLinearScale(axisLowerLimit,axisUpperLimit) c.yAxis.setRounding(False, False) c.yAxis2.setLinearScale(axisLowerLimit,axisUpperLimit) c.yAxis2.setRounding(False, False) // Add a line layer to the chart Dim layer As CDLineLayerMBS layer = c.addLineLayer // Set the line width to 3 pixels layer.setLineWidth(3) // Add the three data sets to the line layer, using circles, diamands and X // shapes as symbols layer.addDataSet(data0, &hff0000, "Quantum Computer").setDataSymbol(c.kCircleSymbol, 9) layer.addDataSet(data1, &h00ff00, "Atom Synthesizer").setDataSymbol(c.kDiamondSymbol, 11) layer.addDataSet(data2, &hff6600, "Proton Cannon").setDataSymbol(c.Cross2Shape, 11) lastpicture=c.makeChartPicture viewport.setChartMetrics c.getChartMetrics // Process ImageMap data to support data point rollovers, etc. Dim ImageMapString As String ImageMapString = c.getHTMLImageMap("myurl" ) ImageMapHandler = New CDImageMapHandlerMBS(ImageMapString) // trigger refresh me.Invalidate End Sub
Property CleanGraphicsBeforeDrawing As Boolean
Property Private ImageMapHandler As CDImageMapHandlerMBS
Property Private NeedClear As Boolean
Property Overlay As Picture
Property Protected StartX As Integer
Property Protected StartX2 As Integer
Property Protected StartY As Integer
Property Protected StartY2 As Integer
Property Protected c As CDXYChartMBS
Property Protected data0() As double
Property Protected data1() As double
Property Protected data2() As double
Property Private isMouseDown As Boolean
Property Protected lastpicture As picture
Property Protected maxvalue As double
Property Protected minvalue As double
Property mouseXvalue As double
Property mouseYvalue As double
Property rectangleHeight As Integer
Property rectangleLeft As Integer
Property Protected rectanglePicture As picture
Property rectangleTop As Integer
Property rectangleWidth As Integer
Property Protected viewport As cdviewPortManagerMBS
End Class
Class cntSymbolLineZoom Inherits ContainerControl
Control out Inherits zoomLineCanvas
ControlInstance out Inherits zoomLineCanvas
End Control
Control LabelX Inherits Label
ControlInstance LabelX Inherits Label
End Control
Control LabelY Inherits Label
ControlInstance LabelY Inherits Label
End Control
Control Timer1 Inherits Timer
ControlInstance Timer1 Inherits Timer
EventHandler Sub Action() out.UpdateMouseCursor End EventHandler
End Control
Control LabelZoomOut Inherits Label
ControlInstance LabelZoomOut Inherits Label
End Control
Control LabelZoomIn Inherits Label
ControlInstance LabelZoomIn Inherits Label
End Control
End Class
End Project

See also:

The items on this page are in the following plugins: MBS ChartDirector Plugin.


The biggest plugin in space...