Graficando datos

From Apache OpenOffice Wiki
Jump to: navigation, search


Editing.png Esta página está en estado borrador.

Dicen que una imagen vale más que mil palabras, y si damos por cierta tal aseveración necesitaremos aprender como dar “imagen” a nuestros datos, que de eso se trata cuando hacemos gráficos.


Vamos a crear el siguiente gráfico de la población de cinco países de América Latina.


ES StarBasic GraficandoDatos.12.png


Agregar un nuevo gráfico

Lo creamos con la siguiente macro.


 Sub Graficando1() 
 Dim oHojaActiva As Object
 Dim oGraficos As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oDir As New com.sun.star.table.CellRangeAddress
 
     'Acceso a la hoja activa
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 
     'El nombre de nuestro gráfico
     sNombre = "Grafico01"
     'El tamaño y la posición del nuevo gráfico, todas las medidas
     'en centésimas de milímetro
     With oRec
         .X = 5500            'Distancia desde la izquierda de la hoja
         .Y = 0            'Distancia desde la parte superior
         .Width = 10000        'El ancho del gráfico
         .Height = 10000        'El alto del gráfico
     End With
     'La dirección del rango de datos para el gráfico
     With oDir
         .Sheet = oHojaActiva.getRangeAddress.Sheet
         .StartColumn = 0
         .EndColumn = 1
         .StartRow = 0
         .EndRow = 5
     End With
     'Es una matriz de rangos, pues se pueden establecer más de uno
     mRangos(0) = oDir
     'Accedemos al conjunto de todos los gráficos de la hoja
     oGraficos = oHojaActiva.getCharts()
     'Verificamos que no exista el nombre
     If oGraficos.hasByName( sNombre ) Then
         MsgBox "Ya existe este nombre de gráfico, escoge otro"
     Else
         'Si no existe lo agregamos
         oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
     End If
 
 End Sub


El método para agregar un nuevo gráfico es sencillo (addNewByName) y consta de cinco argumentos.


     addNewByName(Nombre, Rectangulo, Rangos, EncabezadoColumna, EncabezadoFila)


  1. Nombre: es el nombre del objeto a nivel código, este nombre es diferente del que puede establecer el usuario en la interfaz de la aplicación, es indispensable que no exista otro gráfico con este valor.
  2. Rectángulo: es una estructura com.sun.star.awt.Rectangle que permite establecer el tamaño y la posición del gráfico, las unidades están especificadas en centésimas de milímetro, 1000 = 1 cm
  3. Rangos: es una matriz de rangos, es decir, de estructuras com.sun.star.table.CellRangeAddress que guardan la dirección del rango para los datos de origen del gráfico.
  4. EncabezadoColumna: valor booleano, establecido en verdadero (True) sirve para indicar si la fila superior se usara como titulo de etiquetas para eje o leyenda.
  5. EncabezadoFila: valor booleano, establecido en verdadero (True) sirve para indicar si se usará la columna de la izquierda como etiquetas de eje o leyenda.

Ya creado el gráfico, podemos personalizarlo completamente a nuestro gusto. En el siguiente ejemplo, creamos tres nuevos gráficos, de tres estilos diferentes: columnas, barras y circular, uno al lado de otro, teniendo como origen de datos, el mismo del ejemplo anterior.


 Sub Graficando2()
 Dim oHojaActiva As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oDir As New com.sun.star.table.CellRangeAddress
 
     'Acceso a la hoja activa
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 
     'El nombre de nuestro gráfico
     sNombre = "GraficoA"
     'El tamaño y la posición del nuevo gráfico, todas las medidas
     'en centésimas de milímetro
     With oRec
         .X = 0                'Distancia desde la izquierda de la hoja
         .Y = 4000            'Distancia desde la parte superior
         .Width = 10000        'El ancho del gráfico
         .Height = 10000        'El alto del gráfico
     End With
     'La dirección del rango de datos para el gráfico
     With oDir
         .Sheet = oHojaActiva.getRangeAddress.Sheet
         .StartColumn = 0
         .EndColumn = 1
         .StartRow = 0
         .EndRow = 5
     End With
     'Es una matriz de rangos, pues se pueden establecer más de uno
     mRangos(0) = oDir
     'Accedemos al conjunto de todos los gráficos de la hoja
     oGraficos = oHojaActiva.getCharts()
     'Verificamos que no exista el nombre
     If oGraficos.hasByName( sNombre ) Then
         MsgBox "Ya existe este nombre de gráfico, escoge otro"
     Else
         'Si no existe lo agregamos, de forma predeterminada se crea
         'un gráfico de columnas
         oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
     End If
 
     'Cambiamos el nombre y la posición para un segundo gráfico
     sNombre = "GraficoB"
     With oRec
         .X = 10000
         .Y = 4000
     End With
     If oGraficos.hasByName( sNombre ) Then
         MsgBox "Ya existe este nombre de gráfico, escoge otro"
     Else
         oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
         'Accedemos al nuevo gráfico
         oGrafico = oGraficos.getBYName( sNombre ).getEmbeddedObject()
         'Establecemos que sean barras en vez de columnas
         oGrafico.getDiagram.Vertical = True
     End If
 
     'Volvemos a cambiar el nombre y la posición para un tercer gráfico
     sNombre = "GraficoC"
     With oRec
         .X = 20000
         .Y = 4000
     End With
     If oGraficos.hasByName( sNombre ) Then
         MsgBox "Ya existe este nombre de gráfico, escoge otro"
     Else
         oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
         oGrafico = oGraficos.getBYName( sNombre ).getEmbeddedObject()
         oGrafico.setDiagram( oGrafico.createInstance("com.sun.star.chart.PieDiagram"))
     End If
 
 End Sub


Tipos de gráficos

Los gráficos de columnas y barras son el mismo tipo de gráfico, excepto por la orientación, uno es vertical y otro es horizontal, para el tercer gráfico, cambiamos completamente su tipo (setDiagram), lo establecemos circular, toma en cuenta que cada gráfico esta pensado para un determinado tipo de datos, los tipos de gráficos que puedes establecer son.


com.sun.star.chart Tipo
com.sun.star.chart.BarDiagram Barras (y columnas)
com.sun.star.chart.AreaDiagram Áreas
com.sun.star.chart.LineDiagram Líneas
com.sun.star.chart.PieDiagram Circular
com.sun.star.chart.DonutDiagram Dona
com.sun.star.chart.NetDiagram Red
com.sun.star.chart.XYDiagram Dispersión XY
com.sun.star.chart.StockDiagram Stock
com.sun.star.chart.BubbleDiagram Burbujas


Cada uno de estos tipos, tiene variantes que multiplican las posibilidades para graficar la información, por ejemplo, representaciones en 3D, agregar líneas y puntos, entre otras características que veremos más adelante.


Dando forma al gráfico

La mayor parte de los elementos de un gráfico, son en realidad una forma (Shape), a la cual le puedes establecer sus propiedades, principalmente; el estilo de letra (tipo de fuente, color, negritas, tamaño, etc), el estilo de fondo (estilo, color, etc), y el estilo de borde (tipo de línea, color, ancho, etc), entre otras más, vamos a mostrar como modificar los principales elementos de un gráfico, los siguientes ejemplos manipulan el gráfico seleccionado, pero todas las propiedades que veremos, las puedes establecer perfectamente al crearlo de modo que tu gráfico este configurado completamente a tu gusto y necesidad a la primera. Vamos a hacer uso de las siguientes subrutinas para dar formato.


 'Subrutina para formatear el texto de una forma, si no quieres cambiar alguna
 'propiedad, solo pasa una cadena vacía en los textos y un 0 en los números
 
 Sub FormatoTexto(Obj As Object, Texto As String, Fuente As String, Neg As Integer, Tam As Integer, Color As Long)
 Dim oTexto As Object
 Dim mTexto(0)
 
     'El titulo del gráfico es algo especial
     If Obj.supportsService("com.sun.star.chart2.Title") Then
         'Requiere un objeto "Cadena Formateada" (FormattedString)
         oTexto = createUnoService("com.sun.star.comp.chart.FormattedString")
         'Y agregarse a una matriz
         mTexto(0) = oTexto
         'Establecer el texto
         Obj.setText( mTexto )
     Else
         oTexto = Obj
     End If
     'Cambiamos el formato del texto
     With oTexto
         If Texto <> "" Then .String = Texto
         If Fuente <> "" Then .CharFontName = Fuente
         If Neg > 0 Then .CharWeight = Neg
         If Tam > 0 Then .CharHeight = Tam
         If Color > 0 Then .CharColor = Color
     End With
 
 End Sub
 
 
 'Subrutina para cambiar el fondo de una forma, 
 'Estilo 0 = Ninguno, 1 = Color, 2 = Gradiente, 3 = Trama, 4 = Mapa de bits
 'Color puede ser un número o una cadena con el nombre del gradiente, trama o mapa de bits
 
 
 Sub FormatoFondo(Obj As Object, Estilo As Integer, Color)
     With Obj
         .FillBackground = True
         .FillStyle = Estilo
         Select Case Estilo
             Case 1 
                 If Color > 0 Then .FillColor = Color
             Case 2
                 .FillGradientName = Color
             Case 3
                 .FillHachName = Color
             Case 4
                 .FillBitmapName = Color
         End Select        
     End With
 
 End Sub
 
 
 
 'Subrutina para cambiar la línea de una forma, si no quieres línea, 
 'establece el estilo en 0
 
 
 Sub FormatoLinea(Obj As Object, Estilo As Integer, Color As Long, Ancho As Integer)
     With Obj
         .LineStyle = Estilo
         If Color > 0 Then .LineColor = Color
         If Ancho > 0 Then .LineWidth = Ancho
     End With
 
 End Sub
 
 
 'Función para devolver el gráfico activo
 'devuelve NULL si no es un gráfico
 Function getGrafico() As Object
 Dim oHojaActiva As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim oSel As Object
 Dim sNombre As String
 Dim sInfo As String
 
     oSel = ThisComponent.getCurrentSelection()    
     If oSel.getImplementationName = "com.sun.star.drawing.SvxShapeCollection" Then
         oSel = oSel.getByIndex(0)
         If oSel.supportsService("com.sun.star.drawing.OLE2Shape") Then
             sNombre = oSel.PersistName
             oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 
             oGraficos = oHojaActiva.getCharts()
             If oGraficos.hasByName( sNombre ) Then
                 getGrafico = oGraficos.getByName( sNombre ).getEmbeddedObject()
             End If
         End If
     End If
 
 End Function


En el siguiente ejemplo, agregamos y damos formato al titulo y al subtitulo del gráfico, observa que si no existe el titulo lo creamos, el subtitulo siempre existe, solo hay que determinar si lo mostramos o no, como se indica en los comentarios.


 Sub Graficando3()
 Dim oGrafico As Object
 Dim oTitulo As Object
 Dim oSubTitulo As Object
 
     'Accedemos al gráfico seleccionado
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
 
         'Si hay un gráfico, seleccionamos el título
         oTitulo = oGrafico.getTitleObject()
         If IsNull(oTitulo) Then
             'Si no existe el título lo creamos
             oTitulo = createUnoService("com.sun.star.chart2.Title")
         End If
         'Le damos formato al texto del título
         Call FormatoTexto( oTitulo, "Habitantes Por País", "Liberation Serif", 150, 15, RGB(255,0,0) )
         'Le damos formato al fondo del titulo
         Call FormatoFondo( oTitulo, 1, RGB(220,220,220) )
         'Le damos formato a la línea
         Call FormatoLinea( oTitulo, 1, RGB(100,50,25), 100 )
         'Si estableces la línea, tal vez sea buena idea, establecer los margenes
         'al texto para que no se vea tan pegado
         With oTitulo
             .ParaLeftMargin = 300
             .ParaRightMargin = 300
             .ParaTopMargin = 200
             .ParaBottomMargin = 200
         End With
         'Y lo establecemos
         oGrafico.setTitleObject( oTitulo )
 
         'Establecemos que se muestre el subtitulo
         oGrafico.HasSubTitle = True
         'Accedemos al subtitulo
         oSubTitulo = oGrafico.SubTitle
         'Le damos formato al texto, fondo y línea
         Call FormatoTexto( oSubTitulo, "América Latina", "Liberation Serif", 150, 12, RGB(255,150,0) )
         Call FormatoFondo( oSubTitulo, 1, RGB(240,240,240) )
         Call FormatoLinea( oSubTitulo, 2, RGB(100,50,25), 50 )
     Else
         MsgBox "Selecciona un gráfico"
     End If    
 
 End Sub


Los margenes del borde al texto, solo existen en el título, no así en el subtítulo. Si usas normalmente un conjunto de fuentes, podrías usar una matriz de texto (string) con los nombres de las fuentes que más uses, por ejemplo.


 Dim mFuentes(4) As String
 
     mFuentes(0) = "Liberation Serif"
     mFuentes(1) = "Liberation Sans"
     mFuentes(2) = "Liberation Mono"
     mFuentes(3) = "FreeMono"
     mFuentes(4) = "FreeSans"


Y mira que bien nos va quedando, bueno, no tan bien, ya sabes que soy muy malo para el diseño, así que no te me pongas exigente.


ES StarBasic GraficandoDatos.11.png


Ahora, cambiaremos el formato de la leyenda, el circulo (bueno, intento de circulo) rojo en la imagen anterior. Nota que en la llamada a la subrutina FormatoTexto, el argumento Texto, que nos sirve para establecer el título y el subtítulo, ahora, le pasamos una cadena vacía, esto es muy importante, pues la leyenda no implementa la propiedad String, por lo que si intentas establecerla, te dará un error en tiempo de ejecución, que claro, puedes interceptar y manipular.


 Sub Graficando4()
 Dim oGrafico As Object
 Dim oLeyenda As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Accedemos a la leyenda
         oLeyenda = oGrafico.Legend()
         'Le damos formato al texto, fondo y línea
         Call FormatoTexto( oLeyenda, "", "Liberation Sans", 150, 10, RGB(255,150,100) )
         Call FormatoFondo( oLeyenda, 1, RGB(240,240,240) )
         Call FormatoLinea( oLeyenda, 3, RGB(100,50,25), 50 )
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


En algunos casos, como en este ejemplo, no tiene mucho sentido mostrar la leyenda, pues es una sola serie de datos, así que mejor la ocultamos y establecemos el titulo de el eje X y el eje Y, así como su formato.


 Sub Graficando5()
 Dim oGrafico As Object
 Dim oTituloEje As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Ocultamos la leyenda
         oGrafico.HasLegend = False
         'Accedemos al titulo del eje X
         oTituloEje = oGrafico.getDiagram.XAxisTitle
         'Establecemos que se muestre
         oGrafico.getDiagram.HasXAxisTitle = True
         Call FormatoTexto( oTituloEje, "Países", "Liberation Sans", 150, 11, RGB(100,150,100) )
         Call FormatoFondo( oTituloEje, 1, RGB(240,240,240) )
         Call FormatoLinea( oTituloEje, 1, RGB(200,200,200), 20 )
 
         'Accedemos al titulo del eje Y
         oTituloEje = oGrafico.getDiagram.YAxisTitle
         'Establecemos que se muestre
         oGrafico.getDiagram.HasYAxisTitle = True
         Call FormatoTexto( oTituloEje, "Habitantes", "Liberation Sans", 150, 11, RGB(100,150,100) )
         Call FormatoFondo( oTituloEje, 1, RGB(240,240,240) )
         Call FormatoLinea( oTituloEje, 1, RGB(200,200,200), 20 )
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


El punto importante, es la forma en que accedemos a los títulos de los ejes (getDiagram), estos están contenidos “dentro” del gráfico, pero también “dentro” de un forma que se llama diagrama, que es propiamente el área donde se muestra el gráfico.


 Sub Graficando6()
 Dim oGrafico As Object
 Dim oEje As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Accedemos al eje X
         oEje = oGrafico.getDiagram.getXAxis
         Call FormatoTexto( oEje, "", "Liberation Sans", 150, 10, RGB(50,50,50) )
         Call FormatoLinea( oEje, 1, RGB(0,0,255), 30 )
         'Rotamos 60º el texto
         oEje.TextRotation = 6000
         'Accedemos al eje Y
         oEje = oGrafico.getDiagram.getYAxis
         Call FormatoTexto( oEje, "", "Liberation Sans", 150, 10, RGB(50,50,50) )
         Call FormatoLinea( oEje, 1, RGB(0,0,255), 30 )
         'Establecemos el limite superior del eje
         oEje.Max = 200000000
         'Establecemos el intervalo superior
         oEje.StepMain = 50000000
         'El número de marcas secundarias
         oEje.StepHelpCount = 5
         'Líneas del eje principal
         oEje = oGrafico.getDiagram.YMainGrid
         Call FormatoLinea( oEje, 1, RGB(255,0,0), 50 )
         'Mostramos las líneas secundarias
         oGrafico.getDiagram.HasYAxisHelpGrid = True
         oEje = oGrafico.getDiagram.YHelpGrid
         Call FormatoLinea( oEje, 1, RGB(150,0,0), 25 )            
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Modificamos las propiedades de toda el área del gráfico.


 Sub Graficando7()
 Dim oGrafico As Object
 Dim oArea As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Seleccionamos el área del gráfico
         oArea = oGrafico.getArea()
         'Establecemos el fondo en gradiente y su nombre
         Call FormatoFondo( oArea, 2, "Radial red/yellow" )
         Call FormatoLinea( oArea, 1, RGB(50,255,50), 20 )
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Ahora, solo del fondo del gráfico, el área efectiva donde se muestran los datos.


 Sub Graficando8()
 Dim oGrafico As Object
 Dim oFondo As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Seleccionamos el fondo del gráfico
         oFondo = oGrafico.getDiagram.getWall
         Call FormatoFondo( oFondo, 2, 9 )
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Modificamos la serie de datos, por ahora, solo tenemos una.


 Sub Graficando9()
 Dim oGrafico As Object
 Dim oDatos As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'La primer serie de datos
         oDatos = oGrafico.getDiagram.getDataRowProperties(0)
         Call FormatoTexto( oDatos, "", "Liberation Sans", 150, 11, RGB(0,0,250) )
         Call FormatoFondo( oDatos, 4, 5 )
         'Establecemos que se muestren los valores de cada punto
         oDatos.DataCaption = 1
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Para cambiar de tamaño un gráfico, tienes que hacerlo como si fuera una forma (shape) como te muestro en el siguiente ejemplo.


 Sub Graficando10()
 Dim oGrafico As Object
 Dim oSel As Object
 Dim oTam As New com.sun.star.awt.Size
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Aquí, repetimos lo que hace la función que nos regresa el gráfico
         'esto es por que ya estamos seguros de que es un gráfico y por que,
         'para cambiar de tamaño, hay que hacerlo como si fuera una forma (shape)
         oSel = ThisComponent.getCurrentSelection()
         oSel = oSel.getByIndex(0)
         'Establecemos el nuevo tamaño
         oTam.Width = 15000
         oTam.Height = 15000
         oSel.setSize( oTam )
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Si has probado cada una de las macros de ejemplo sobre el mismo gráfico, tienes que tener algo así.


ES StarBasic GraficandoDatos.10.png


Si lo sé, esta horrible, al fin que no es curso de diseño.


La siguiente macro, cambiara el rango de datos origen, algo sumamente necesario para tener realmente un gráfico dinámico y podamos actualizarlo cuando sea necesario.


 Sub Graficando11()
 Dim oGrafico As Object
 Dim oHojaActiva As Object
 Dim mRangos(0)
 Dim oDir As New com.sun.star.table.CellRangeAddress
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 
     'Accedemos al gráfico
     oGrafico = getGrafico2()
     If Not IsNull( oGrafico ) Then
         'El nuevo rango de datos
         With oDir
             .Sheet = oHojaActiva.getRangeAddress.Sheet
             .StartColumn = 0
             .EndColumn = 1
             .StartRow = 0
             .EndRow = 10
         End With
         mRangos(0) = oDir
         'Establecemos el nuevo rango
         oGrafico.setRanges( mRangos )
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Nota que estamos usando una segunda versión de la función para regresar el gráfico seleccionado, la función es casi idéntica.


 Function getGrafico2() As Object
 Dim oHojaActiva As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim oSel As Object
 Dim sNombre As String
 Dim sInfo As String
 
     oSel = ThisComponent.getCurrentSelection()    
     If oSel.getImplementationName = "com.sun.star.drawing.SvxShapeCollection" Then
         oSel = oSel.getByIndex(0)
         If oSel.supportsService("com.sun.star.drawing.OLE2Shape") Then
             sNombre = oSel.PersistName
             oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 
             oGraficos = oHojaActiva.getCharts()
             If oGraficos.hasByName( sNombre ) Then
                 getGrafico2 = oGraficos.getByName( sNombre )
             End If
         End If
     End If
 
 End Function


La diferencia, es que la primera te devuelve el objeto (no me gusta la palabra pero así es) “embebido” (getEmbeddedObject), con el cual tenemos acceso a todos los objetos dentro del gráfico, esta segunda forma, accede directamente al gráfico (getByName).


Veamos algunos ejemplos más de creación de gráficos, cuando grafiques, como ya lo mencionamos, debes de cuidar la correspondencia de tus datos con el tipo de gráfico, así mismo, cuando personalices un gráfico, asegúrate de que el tipo de gráfico es correcto, por ejemplo, puedes establecerle ejes a un gráfico circular, pero dejaría de ser un gráfico circular y te aseguro que no obtendrías el resultado previsto.


El siguiente ejemplo, modifica nuestro gráfico para que se vea en 3D.


 Sub Graficando12()
 Dim oGrafico As Object
 
     oGrafico = getGrafico()
     If Not IsNull( oGrafico ) Then
         'Establecemos el gráfico en 3D
         oGrafico.getDiagram.Dim3D = True
         'Mostramos cilindros en vez de columnas
         oGrafico.getDiagram.SolidType = 1
     Else
         MsgBox "Selecciona un gráfico"
     End If
 
 End Sub


Gráficos de columnas

Observa el siguiente gráfico, para obtenerlo, es indispensable que el cursor este en “una sola celda” de los datos, lo demás se calcula, tanto el rango de datos como la posición.


ES StarBasic GraficandoDatos.09.png


 Sub Graficando13()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         'Expandimos el cursor a la región actual
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico10"
         'Celda para la posición del gráfico
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 11500        'El ancho del gráfico
             .Height = 7000        'El alto del gráfico
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos de barras

El mismo gráfico, pero ahora lo hacemos de barras.


ES StarBasic GraficandoDatos.08.png


 Sub Graficando14()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         'Expandimos el cursor a la región actual
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico10"
         'Celda para la posición del gráfico
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 11500        'El ancho del gráfico
             .Height = 7000        'El alto del gráfico
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             oGrafico.getEmbeddedObject.getDiagram.Vertical = True
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos circulares

Los gráficos circulares sirven para darnos una imagen de la relación de cada punto respecto al total.


ES StarBasic GraficandoDatos.07.png


 Sub Graficando15()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico15"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 10000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             'Cambiamos el tipo de gráfico
             oGrafico.getEmbeddedObject.setDiagram( oGrafico.getEmbeddedObject.createInstance("com.sun.star.chart.PieDiagram") )
             oDatos = oGrafico.getEmbeddedObject.getDiagram.getDataRowProperties(0)
             oGrafico.getEmbeddedObject.getDiagram.Dim3D = True
             oGrafico.HasColumnHeaders = True
             oGrafico.HasRowHeaders = True
             'Hay que reasignar el rango de datos, lo pierde al cambiar de tipo de gráfico
             oGrafico.setRanges( mRangos )
             oDatos.DataCaption = 2
             oDatos.LabelPlacement = 0
             Call FormatoTexto( oDatos, "", "Liberation Sans", 150, 15, RGB(55,55,55) )
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos de área

Los gráficos de área, destacan la magnitud de un cambio en el tiempo.


ES StarBasic GraficandoDatos.06.png


 Sub Graficando16()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico16"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 10000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             'Cambiamos el tipo de gráfico
             oGrafico.getEmbeddedObject.setDiagram( oGrafico.getEmbeddedObject.createInstance("com.sun.star.chart.AreaDiagram") )
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos de líneas

Los gráficos de líneas muestran principalmente los cambios de valor en el tiempo y su relación con otros valores.


ES StarBasic GraficandoDatos.05.png


 Sub Graficando17()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico17"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 12000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             'Cambiamos el tipo de gráfico
             oGrafico.getEmbeddedObject.setDiagram( oGrafico.getEmbeddedObject.createInstance("com.sun.star.chart.LineDiagram") )
             oGrafico.getEmbeddedObject.getDiagram.SymbolType = 1
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos de anillo

Los gráficos de anillo, son parecidos a los circulares, pero pueden representar más de una serie de datos, aun así, creo, no son una buena elección.


ES StarBasic GraficandoDatos.04.png


 Sub Graficando18()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico18"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 12000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             'Cambiamos el tipo de gráfico
             oGrafico.getEmbeddedObject.setDiagram( oGrafico.getEmbeddedObject.createInstance("com.sun.star.chart.DonutDiagram") )
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos radiales

Si prefieres un gráfico radial, ahí esta el ejemplo.


ES StarBasic GraficandoDatos.03.png


 Sub Graficando19()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico19"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 12000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             'Cambiamos el tipo de gráfico
             oGrafico.getEmbeddedObject.setDiagram( oGrafico.getEmbeddedObject.createInstance("com.sun.star.chart.NetDiagram") )
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos de stock

Para un gráfico de stock, el orden de los datos es importante.


ES StarBasic GraficandoDatos.02.png


 Sub Graficando20()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico20"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 12000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre )
             'Cambiamos el tipo de gráfico
             oGrafico.getEmbeddedObject.setDiagram( oGrafico.getEmbeddedObject.createInstance("com.sun.star.chart.StockDiagram") )
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Gráficos XY (dispersión)

El gráfico XY (dispersión) muestra la relación de un valor en función de otro.


ES StarBasic GraficandoDatos.01.png


 Sub Graficando21()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0)
 Dim sNombre As String
 Dim oRec As New com.sun.star.awt.Rectangle
 Dim oCelda As Object
 Dim oDatos As Object
 
     oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
     oSel = ThisComponent.getCurrentController.getSelection()
     If oSel.getImplementationName = "ScCellObj" Then 
         oCursor = oHojaActiva.createCursorByRange( oSel )
         oCursor.collapseToCurrentRegion()
         mRangos(0) = oCursor.getRangeAddress
         sNombre = "Grafico21"
         oCelda = oHojaActiva.getCellByPosition( oCursor.getRangeAddress.StartColumn, oCursor.getRangeAddress.EndRow + 2 )
         With oRec
             .X = oCelda.Position.X
             .Y = oCelda.Position.Y                
             .Width = 12000        
             .Height = 7000        
         End With        
         oGraficos = oHojaActiva.getCharts()
         If oGraficos.hasByName( sNombre ) Then
             MsgBox "Ya existe este nombre de gráfico, escoge otro"
         Else
             oGraficos.addNewByName(sNombre, oRec, mRangos, True, True)
             oGrafico = oGraficos.getByName( sNombre ).getEmbeddedObject
             'Cambiamos el tipo de gráfico
             oGrafico.setDiagram( oGrafico.createInstance("com.sun.star.chart.XYDiagram") )
             oGrafico.HasLegend = False
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
 End Sub


Conclusión

Cada tipo de gráfico tiene sus particularidades que tendrás que considerar a la hora de graficar, la recomendación general es, inmediatamente que agregues el gráfico, cambia su tipo al que necesites y solo al final, estableces todas las propiedades que quieras.

Si sumas la importación de bases de datos, con el gráfico de datos, tienes una combinación bastante poderosa y eficiente para representar tus datos en informes.



ES.Plantillas.Logo foro es.png
Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO,
o quieres ampliar la información, no dudes en dirigirte al

Foro Oficial en español de Apache OpenOffice para Macros y API UNO

Personal tools