[
Windows Version (in Visual Basic)] vbdemo\frmZoomScrollDemo2.frm
Option Explicit
Private cd As New ChartDirector.API
' XY data points for the chart
Private dataX0()
Private dataY0()
Private dataX1()
Private dataY1()
Private dataX2()
Private dataY2()
' The full x-axis and y-axis scales at no zooming.
Private minX As Double
Private maxX As Double
Private minY As Double
Private maxY As Double
' Internal variables to keep track of which navigation button is pushed
Private activeNavigateButton As Long
' The index of the navigation buttons in the NavigatePB array
Private Const upLeftPB = 0
Private Const upPB = 1
Private Const upRightPB = 2
Private Const LeftPB = 3
Private Const CenterPB = 4
Private Const RightPB = 5
Private Const downLeftPB = 6
Private Const downPB = 7
Private Const downRightPB = 8
' Internal variables to keep track of dragging of the navigation window
Private isDraggingNavigatePad As Boolean
Private mouseDownXCoor As Double
Private mouseDownYCoor As Double
'
' Initialize the form
'
Private Sub Form_Load()
' Initially, set mouse usage to pointer mode
Call PointerPB_Click
' Load the data
Call loadData
' Can draw the chart now
Call ChartViewer1.UpdateViewPort(True, True)
End Sub
'
' Load the data
'
Private Sub loadData()
'
' For simplicity, in this demo, we just use hard coded data. In a real application,
' the data probably read from a dynamic source such as a database. (See the
' ChartDirector documentation on "Using Data Sources with ChartDirector" if you need
' some sample code on how to read data from database to array variables.)
'
dataX0 = Array(10, 15, 6, -12, 14, -8, 13, -3, 16, 12, 10.5, -7, 3, -10, -5, 2, 5)
dataY0 = Array(130, 150, 80, 110, -110, -105, -130, -15, -170, 125, 125, 60, 25, 150, 150, 15, _
120)
dataX1 = Array(6, 7, -4, 3.5, 7, 8, -9, -10, -12, 11, 8, -3, -2, 8, 4, -15, 15)
dataY1 = Array(65, -40, -40, 45, -70, -80, 80, 10, -100, 105, 60, 50, 20, 170, -25, 50, 75)
dataX2 = Array(-10, -12, 11, 8, 6, 12, -4, 3.5, 7, 8, -9, 3, -13, 16, -7.5, -10, -15)
dataY2 = Array(65, -80, -40, 45, -70, -80, 80, 90, -100, 105, 60, -75, -150, -40, 120, -50, _
-30)
End Sub
'
' User clicks on the Pointer pushbutton
'
Private Sub PointerPB_Click()
ChartViewer1.MouseUsage = cvScrollOnDrag
End Sub
'
' User clicks on the Zoom In pushbutton
'
Private Sub ZoomInPB_Click()
ChartViewer1.MouseUsage = cvZoomIn
End Sub
'
' User clicks on the Zoom Out pushbutton
'
Private Sub ZoomOutPB_Click()
ChartViewer1.MouseUsage = cvZoomOut
End Sub
'
' User presses on one of the navigation buttons
'
Private Sub NavigatePB_MouseDown(Index As Integer, Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Index = CenterPB Then
' Center button - center the view port at the origin (0, 0)
Call scrollChartTo(ChartViewer1, 0.5 - ChartViewer1.ViewportWidth / 2, _
0.5 - ChartViewer1.ViewportHeight / 2)
Else
' Enable the timer to shift the view port once per 100ms until button is released
activeNavigateButton = Index
ButtonTimer.Enabled = True
End If
End Sub
'
' User releases the navigation button
'
Private Sub NavigatePB_MouseUp(Index As Integer, Button As Integer, Shift As Integer, _
X As Single, Y As Single)
' Stop the button timer
activeNavigateButton = -1
ButtonTimer.Enabled = False
End Sub
'
' Navigation button timer - fires once per 100ms if navigation button is pressed
'
Private Sub ButtonTimer_Timer()
If activeNavigateButton <> -1 Then
' Get current view port position
Dim vpLeft As Double
Dim vpTop As Double
vpLeft = ChartViewer1.ViewportLeft
vpTop = ChartViewer1.ViewportTop
' Each tick scroll the chart by 5% in the button direction
If activeNavigateButton = LeftPB Or activeNavigateButton = upLeftPB Or _
activeNavigateButton = downLeftPB Then
vpLeft = vpLeft - ChartViewer1.ViewportWidth * 0.05
End If
If activeNavigateButton = RightPB Or activeNavigateButton = upRightPB Or _
activeNavigateButton = downRightPB Then
vpLeft = vpLeft + ChartViewer1.ViewportWidth * 0.05
End If
If activeNavigateButton = upPB Or activeNavigateButton = upLeftPB Or _
activeNavigateButton = upRightPB Then
vpTop = vpTop - ChartViewer1.ViewportHeight * 0.05
End If
If activeNavigateButton = downPB Or activeNavigateButton = downLeftPB Or _
activeNavigateButton = downRightPB Then
vpTop = vpTop + ChartViewer1.ViewportHeight * 0.05
End If
' Scroll to the new view port position
Call scrollChartTo(ChartViewer1, vpLeft, vpTop)
End If
End Sub
'
' User moves zoom control slide bar
'
Private Sub ZoomBar_Scroll()
' Remember the center point
Dim centerX As Double, centerY As Double
centerX = ChartViewer1.ViewportLeft + ChartViewer1.ViewportWidth / 2
centerY = ChartViewer1.ViewportTop + ChartViewer1.ViewportHeight / 2
' Aspect ratio and zoom factor
Dim aspectRatio As Double, zoomTo As Double
aspectRatio = ChartViewer1.ViewportWidth / ChartViewer1.ViewportHeight
zoomTo = CDbl(ZoomBar.value) / ZoomBar.Max
' Zoom while preserving aspect ratio
ChartViewer1.ViewportWidth = zoomTo * IIf(aspectRatio > 1, aspectRatio, 1)
ChartViewer1.ViewportHeight = zoomTo * IIf(aspectRatio > 1, 1, 1 / aspectRatio)
' Adjust ViewPortLeft and ViewPortTop to keep center point unchanged
ChartViewer1.ViewportLeft = centerX - ChartViewer1.ViewportWidth / 2
ChartViewer1.ViewportTop = centerY - ChartViewer1.ViewportHeight / 2
' Update the chart
Call ChartViewer1.UpdateViewPort(True, False)
End Sub
'
' User click on the navigate window
'
Private Sub NavigateWindow_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
' Save the mouse coordinates to keep track of how far the navigateWindow has been dragged.
isDraggingNavigatePad = True
mouseDownXCoor = X
mouseDownYCoor = Y
End If
End Sub
'
' User drags the navigate window
'
Private Sub NavigateWindow_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If isDraggingNavigatePad Then
' Is currently dragging - compute where is the navigateWindow being dragged to
Dim newLabelLeft As Double, newLabelTop As Double
newLabelLeft = NavigateWindow.Left + X - mouseDownXCoor
newLabelTop = NavigateWindow.Top + Y - mouseDownYCoor
' Ensure the navigateWindow is within the navigatePad container
Dim internalPadWidth As Long, internalPadHeight As Long
internalPadWidth = NavigatePad.Width - ScaleX(2, vbPixels, ScaleMode)
internalPadHeight = NavigatePad.height - ScaleY(2, vbPixels, ScaleMode)
If newLabelLeft < 0 Then
newLabelLeft = 0
ElseIf newLabelLeft > internalPadWidth - NavigateWindow.Width Then
newLabelLeft = internalPadWidth - NavigateWindow.Width
End If
If newLabelTop < 0 Then
newLabelTop = 0
ElseIf newLabelTop > internalPadHeight - NavigateWindow.height Then
newLabelTop = internalPadHeight - NavigateWindow.height
End If
' Update the navigateWindow position as it is being dragged
NavigateWindow.Left = newLabelLeft
NavigateWindow.Top = newLabelTop
' Update the view port to reflect the navigation window
ChartViewer1.ViewportLeft = CDbl(NavigateWindow.Left) / internalPadWidth
ChartViewer1.ViewportTop = CDbl(NavigateWindow.Top) / internalPadHeight
Call ChartViewer1.UpdateViewPort(True, False)
End If
End Sub
'
' User release mouse button on the navigate window
'
Private Sub NavigateWindow_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
isDraggingNavigatePad = False
End Sub
'
' Utility to scroll the view port to the given position if necessary
'
Private Sub scrollChartTo(viewer As ChartViewer, vpLeft As Double, vpTop As Double)
' Validate the parameters
Call viewer.validateViewPort
' Update chart only if the view port has changed
If vpLeft <> viewer.ViewportLeft Or vpTop <> viewer.ViewportTop Then
viewer.ViewportLeft = vpLeft
viewer.ViewportTop = vpTop
Call viewer.UpdateViewPort(True, False)
End If
End Sub
'
' Mouse moves over ChartViewer
'
Private Sub ChartViewer1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = 0 Then
' Mouse is over chart with mouse button released (not dragging)
' Update image map if necessary
Call updateImageMap(ChartViewer1)
End If
End Sub
'
' User clicks on a hot spot on the chart
'
Private Sub ChartViewer1_ClickHotSpot(hotSpot As Collection, Button As Integer, Shift As Integer, _
X As Single, Y As Single)
' We show the pop up dialog only when the mouse action is not zoom in or zoom out
If ChartViewer1.MouseUsage <> cvZoomIn And ChartViewer1.MouseUsage <> cvZoomOut Then
'In this demo, just list out the information provided by ChartDirector about hot spot
ParamViewer.Display hotSpot
End If
End Sub
'
' The ViewPortChanged event handler. This event occurs when the user changes the ChartViewer
' view port by dragging scrolling, or by zoom in/out, or the ChartViewer.updateViewPort method
' is being called.
'
Private Sub ChartViewer1_ViewPortChanged(needUpdateChart As Boolean, needUpdateImageMap As Boolean)
If Not isDraggingNavigatePad Then
' Update the navigator window size and position to reflect the view port
Dim internalPadWidth As Long, internalPadHeight As Long
internalPadWidth = NavigatePad.Width - ScaleX(2, vbPixels, ScaleMode)
internalPadHeight = NavigatePad.height - ScaleY(2, vbPixels, ScaleMode)
NavigateWindow.Left = CInt(ChartViewer1.ViewportLeft * internalPadWidth)
NavigateWindow.Top = CInt(ChartViewer1.ViewportTop * internalPadHeight)
NavigateWindow.Width = Int(ChartViewer1.ViewportWidth * internalPadWidth)
NavigateWindow.height = Int(ChartViewer1.ViewportHeight * internalPadHeight)
End If
' Synchronize the zoom bar value with the view port width/height
ZoomBar.value = Int(0.5 + IIf(ChartViewer1.ViewportWidth > ChartViewer1.ViewportHeight, _
ChartViewer1.ViewportHeight, ChartViewer1.ViewportWidth) * ZoomBar.Max)
' Update chart and image map if necessary
If needUpdateChart Then
Call drawChart(ChartViewer1)
End If
If needUpdateImageMap Then
Call updateImageMap(ChartViewer1)
End If
End Sub
'
' Draw the chart
'
Private Sub drawChart(viewer As ChartViewer)
' Create an XYChart object 500 x 480 pixels in size, with light blue (c0c0ff) as background
' color
Dim c As XYChart
Set c = cd.XYChart(500, 480, &HC0C0FF)
' Set the plotarea at (50, 40) and of size 400 x 400 pixels. Use light grey (c0c0c0) horizontal
' and vertical grid lines. Set 4 quadrant coloring, where the colors of the quadrants alternate
' between lighter and deeper grey (dddddd/eeeeee).
Call c.setPlotArea(50, 40, 400, 400, -1, -1, -1, &HC0C0C0, &HC0C0C0).set4QBgColor(&HDDDDDD, _
&HEEEEEE, &HDDDDDD, &HEEEEEE, &H0)
' Enable clipping mode to clip the part of the data that is outside the plot area.
Call c.setClipping
' Set 4 quadrant mode, with both x and y axes symetrical around the origin
Call c.setAxisAtOrigin(cd.XYAxisAtOrigin, cd.XAxisSymmetric + cd.YAxisSymmetric)
' Add a legend box at (450, 40) (top right corner of the chart) with vertical layout and 8 pts
' Arial Bold font. Set the background color to semi-transparent grey (40dddddd).
Dim legendBox As legendBox
Set legendBox = c.addLegend(450, 40, True, "arialbd.ttf", 8)
Call legendBox.setAlignment(cd.TopRight)
Call legendBox.setBackground(&H40DDDDDD)
' Add titles to axes
Call c.xAxis().setTitle("Alpha Index")
Call c.yAxis().setTitle("Beta Index")
' Set axes line width to 2 pixels
Call c.xAxis().setWidth(2)
Call c.yAxis().setWidth(2)
' The default ChartDirector settings has a denser y-axis grid spacing and less-dense x-axis grid
' spacing. In this demo, we want the tick spacing to be symmetrical. We use around 40 pixels
' between major ticks and 20 pixels between minor ticks.
Call c.xAxis().setTickDensity(40, 20)
Call c.yAxis().setTickDensity(40, 20)
'
' In this example, we represent the data by scatter points. If you want to represent the data by
' somethings else (lines, bars, areas, floating boxes, etc), just modify the code below to use
' the layer type of your choice.
'
' Add scatter layer, using 11 pixels red (ff33333) X shape symbols
Call c.addScatterLayer(dataX0, dataY0, "Group A", cd.Cross2Shape(), 11, &HFF3333)
' Add scatter layer, using 11 pixels green (33ff33) circle symbols
Call c.addScatterLayer(dataX1, dataY1, "Group B", cd.CircleShape, 11, &H33FF33)
' Add scatter layer, using 11 pixels blue (3333ff) triangle symbols
Call c.addScatterLayer(dataX2, dataY2, "Group C", cd.TriangleSymbol, 11, &H3333FF)
If maxX = minX Then
' The axis scale has not yet been set up. This means this is the first time the chart is
' drawn and it is drawn with no zooming. We can use auto-scaling to determine the
' axis-scales, then remember them for future use.
' explicitly auto-scale axes so we can get the axis scales
Call c.layout
' save the axis scales for future use
minX = c.xAxis().getMinValue()
maxX = c.xAxis().getMaxValue()
minY = c.yAxis().getMinValue()
maxY = c.yAxis().getMaxValue()
Else
' Compute the zoomed-in axis scales using the overall axis scales and ViewPort size
Dim xScaleMin As Double
Dim xScaleMax As Double
Dim yScaleMin As Double
Dim yScaleMax As Double
xScaleMin = minX + (maxX - minX) * ChartViewer1.ViewportLeft
xScaleMax = minX + (maxX - minX) * (ChartViewer1.ViewportLeft + ChartViewer1.ViewportWidth)
yScaleMin = maxY - (maxY - minY) * (ChartViewer1.ViewportTop + ChartViewer1.ViewportHeight)
yScaleMax = maxY - (maxY - minY) * ChartViewer1.ViewportTop
' *** use the following formula if you are using a log scale axis ***
' xScaleMin = minX * ((maxX / minX) ^ ChartViewer1.ViewPortLeft)
' xScaleMax = minX * ((maxX / minX) ^ (ChartViewer1.ViewPortLeft + _
' ChartViewer1.ViewPortWidth))
' yScaleMin = maxY * ((minY / maxY) ^ (ChartViewer1.ViewPortTop + _
' ChartViewer1.ViewPortHeight))
' yScaleMax = maxY * ((minY / maxY) ^ ChartViewer1.ViewPortTop)
' Set the axis scales
Call c.xAxis().setLinearScale(xScaleMin, xScaleMax)
Call c.xAxis().setRounding(False, False)
Call c.yAxis().setLinearScale(yScaleMin, yScaleMax)
Call c.yAxis().setRounding(False, False)
End If
' Set the chart image to the ChartViewer
Set viewer.Chart = c
End Sub
'
' Apply image map used on the chart if not already applied
'
Private Sub updateImageMap(viewer As ChartViewer)
If viewer.ImageMap = "" Then
viewer.ImageMap = viewer.Chart.getHTMLImageMap("clickable", "", _
"title='[{dataSetName}] Alpha = {x}, Beta = {value}'")
End If
End Sub
© 2021 Advanced Software Engineering Limited. All rights reserved.