Graficando datos
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.
Contents
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)
- 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.
- 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
- 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.
- EncabezadoColumna: valor booleano, establecido en verdadero (True) sirve para indicar si la fila superior se usara como titulo de etiquetas para eje o leyenda.
- 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.
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í.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 |