Rotating a 3D Chart Using Mouse Events

ricemcm

New Member
Joined
Jan 7, 2012
Messages
7
All,

I'm using Excel 2007 and I have a reasonable level of experience with VBA coding in normal / object modules, but I have no experience with class modules or events ... so I do not have a good command on what goes into a normal module vice a class module if I want to use mouse events to rotate a chart.

I am looking to rotate a chart ... Since I am not allowed to post a file, I will give the 3D array here:

1.00002.00003.00004.00005.00006.00007.00008.0000
1.00000.05710.06290.06910.07610.08370.08850.33530.2794
2.00000.08000.08800.09680.10650.11710.14160.36880.3074
3.00000.11200.12320.13550.14910.16400.22660.40570.3381
4.00000.15680.17250.18970.20870.22960.36250.44630.3719
5.00000.21950.24150.26560.29220.32140.58000.49090.4091
6.00000.30740.33810.37190.40910.45000.60000.54000.4500
7.00000.29370.32310.35540.39090.43000.59000.45000.3750
8.00000.26700.29370.32310.35540.39090.53640.34620.2885
9.00000.24270.26700.29370.32310.35540.48760.26630.2219
10.00000.22070.24270.26700.29370.32310.44330.20480.1707
11.00000.20060.22070.24270.26700.29370.40300.15760.1313
12.00000.18240.20060.22070.24270.26700.36630.12120.1010
13.00000.16580.18240.20060.22070.24270.33300.09320.0777
14.00000.15070.16580.18240.20060.22070.30280.07170.0598
15.00000.13700.15070.16580.18240.20060.27520.05520.0460
16.00000.12460.13700.15070.16580.18240.25020.04240.0354
17.00000.11320.12460.13700.15070.16580.19250.03260.0218
18.00000.10290.11320.12460.13700.15070.14810.02510.0167
19.00000.09360.10290.11320.12460.13700.11390.01930.0129
20.00000.08510.09360.10290.11320.12460.08760.01760.0117
21.00000.07730.08510.09360.10290.11320.06740.01600.0106
22.00000.07030.07730.08510.09360.10290.05180.01450.0097
23.00000.06390.07030.07730.08510.09360.03990.01320.0088
24.00000.05810.06390.07030.07730.08510.03070.01200.0080
25.00000.05280.05810.06390.07030.07730.02360.01090.0073
26.00000.04800.05280.05810.06390.07030.01820.00990.0066
27.00000.04370.04800.05280.05810.06390.01400.00900.0060
28.00000.03970.04370.04800.05280.05810.01070.00820.0055
29.00000.03610.03970.04370.04800.05280.00830.00740.0050
30.00000.03280.03610.03970.04370.04800.00640.00680.0045

<tbody>
</tbody>

I have placed into a
normal module the following code (based on what I was able to pick up from MSDN):

Code:
[COLOR=#2E8B57][FONT=Monaco]Dim myClassModule As New EventClassModule[/FONT][/COLOR]

[COLOR=#2E8B57][FONT=Monaco]Sub InitializeChart()[/FONT][/COLOR]
[COLOR=#2E8B57][FONT=Monaco]    Set myClassModule.myChartClass = Worksheets(1).ChartObjects(1).Chart[/FONT][/COLOR]
[COLOR=#2E8B57][FONT=Monaco]End Sub[/FONT][/COLOR]

And I have placed the following code into a class module named EventClassModule (also based on what I was able to pick up from MSDN):

Code:
[COLOR=#2E8B57][FONT=Monaco]Public WithEvents myChartClass As Chart[/FONT][/COLOR]

I want to rotate the chart by using click and drag, and, if possible, I'd also like to be able to zoom in and out via some method (say a mouse wheel event).

In the following link, a guy named Gabor Doka has done a beautiful job of enabling scatter plot rotation using scroll bars, but I'd like to be able to use mouse events instead:

3d scatter plot for MS Excel (VBA macro)

Please help! Thanks, and I hope to hear from someone
icon_e_smile.gif


Justin
 

Excel Facts

Is there a shortcut key for strikethrough?
Ctrl+S is used for Save. Ctrl+5 is used for Strikethrough. Why Ctrl+5? When you use hashmarks to count |||| is 4, strike through to mean 5.
All,

I submitted the same question to ExcelKey.com, and they were not to happy to find a duplicate post here.

So, please accept my apologies for such duplication. I informed ExcelKey.com that I would first receive help from Mr. Excel.

I have already received a helpful PM from this site suggesting the use of transparent UserForms since the graphic object only accepts the command Shapes ... Click.

Just wanted to offer a preemptive apology for doing something that might set you off.

Thanks, and I look forward to more helpful PMs (or posts) like that identified above :)
Justin
 
Upvote 0
Okay, so I pretty much answered my own question.

In a normal module (that I named CodeModule), insert the following code:

Code:
Dim myClassModule As New ClassModule

Sub Set_This_Chart()
ActiveSheet.ChartObjects(1).Activate
Set myClassModule.myChartClass = Worksheets(1).ChartObjects(1).Chart
End Sub

Sub Reset_Chart()
Set myClassModule.myChartClass = Nothing
End Sub

In a class module (that I named ClassModule), insert the following code:

Code:
Public WithEvents myChartClass As Chart

' Site (1) http://www.computorcompanion.com/LPMArticle.asp?ID=221
' Site (2) http://www.office-archive.com/2-excel/b2554c6a146b484e.htm
' Site (3) http://social.msdn.microsoft.com/Forums/en/isvvba/thread/d4737f34-af87-4298-9997-4f39b03b7fc7


' Site (1), above, was a fantastic resource for understanding chart events.
' The key takeaway was in the section called "Identify the Point Clicked By
' the User" where the Shift argument in the mouse move event was discussed.
' Shift = 1 means that the SHIFT key is being pressed, and Shift = 2 means
' that the CTRL key is being pressed. I mention these options because they
' are what I use below.


' The rotation and elevation are adjusted by moving the mouse over the
' chart and holding down the SHIFT key, while the zoom and perspective
' are adjusted by moving the mouse over the chart and holding down the
' CTRL key. It helps to have a button on the homescreen to which you
' assign the main macro.


' Note: The x and y values provided as arguments to the mouse move event are
' in chart object client coordinate units, while the chart element dimensions
' are in points. Sites (2) and (3), above, discuss this. As it turns out, the
' x and y arguments, when multiplied by 3 / 4, give the correct chart element
' values in units of points. Go figure.


Private Sub myChartClass_MouseMove(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
    
    Range("A1").Value = ActiveChart.Parent.Width
    Range("A2").Value = ActiveChart.Parent.Height
    
    TOTAL_WDTH_IN_POINTS = ActiveChart.Parent.Width
    TOTAL_HGHT_IN_POINTS = ActiveChart.Parent.Height
    
    If Shift = 1 Then
        
        ' Range("A4").Value = x * 3 / 4
        ' Range("A5").Value = y * 3 / 4
        
        LOCAL_WDTH_IN_POINTS = x * 3 / 4
        LOCAL_HGHT_IN_POINTS = y * 3 / 4
        
        If LOCAL_WDTH_IN_POINTS >= 0 And LOCAL_WDTH_IN_POINTS <= TOTAL_WDTH_IN_POINTS And _
           LOCAL_HGHT_IN_POINTS >= 0 And LOCAL_HGHT_IN_POINTS <= TOTAL_HGHT_IN_POINTS Then
            
            ' Range("A3").Value = "Y"
            
            WDTH_FRACTION = Round(LOCAL_WDTH_IN_POINTS / TOTAL_WDTH_IN_POINTS, 2)
            HGHT_FRACTION = Round(LOCAL_HGHT_IN_POINTS / TOTAL_HGHT_IN_POINTS, 2)
            
            ' Range("A7").Value = WDTH_FRACTION
            ' Range("A8").Value = HGHT_FRACTION
            
            ' Note: Rotation must be between 0 and 360.
            ActiveChart.Rotation = Round(WDTH_FRACTION * 360, 0)
            
            ' Note: Elevation must be between -90 and 90.
            ActiveChart.Elevation = Round(180 * HGHT_FRACTION - 90, 0)
            
        Else
            
            ' Range("A3").Value = "N"
            
        End If
        
    End If
    
    If Shift = 2 Then
        
        ' Range("A4").Value = x * 3 / 4
        ' Range("A5").Value = y * 3 / 4
        
        LOCAL_WDTH_IN_POINTS = x * 3 / 4
        LOCAL_HGHT_IN_POINTS = y * 3 / 4
        
        If LOCAL_WDTH_IN_POINTS >= 0 And LOCAL_WDTH_IN_POINTS <= TOTAL_WDTH_IN_POINTS And _
           LOCAL_HGHT_IN_POINTS >= 0 And LOCAL_HGHT_IN_POINTS <= TOTAL_HGHT_IN_POINTS Then
            
            ' Range("A3").Value = "Y"
            
            WDTH_FRACTION = Round(LOCAL_WDTH_IN_POINTS / TOTAL_WDTH_IN_POINTS, 2)
            HGHT_FRACTION = Round(LOCAL_HGHT_IN_POINTS / TOTAL_HGHT_IN_POINTS, 2)
            
            ' Range("A7").Value = WDTH_FRACTION
            ' Range("A8").Value = HGHT_FRACTION
            
            ' Note: Perspective must be between 0 and 100.
            ActiveChart.Perspective = Round(WDTH_FRACTION * 100, 0)
            
            ' Should we put zooming capability here?
            ' ActiveChart.Axes(xlValue).MinimumScale
            ' ActiveChart.Axes(xlValue).MaximumScale
            ' ActiveChart.Axes(xlCategory).MinimumScale
            ' ActiveChart.Axes(xlCategory).MaximumScale
            
        Else
            
            ' Range("A3").Value = "N"
            
        End If
        
    End If
    
End Sub

Then, make a button on the same spreadsheet as your embedded chart, as in the following image:

Button.png


This solution is not PERFECT, but it's a good start at getting something Microsoft should have given us to begin with ... the ability to use our mouse to rotate a chart.

Should we add zooming capability? Look at the end of my "If Shift = 2 Then ... End If" block to see where I've included the ActiveChart.Axes() stuff.

Any feedback would be appreciated :)

Can't wait to hear what you've discovered ...

Justin
 
Upvote 0

Forum statistics

Threads
1,215,376
Messages
6,124,593
Members
449,174
Latest member
chandan4057

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top