Página 1 de 1

[RESUELTO]Prob en definición de series de Gráf con OOo Basic

Publicado: Dom Nov 08, 2015 10:38 pm
por valenteres
Saludos:

La pregunta es ¿Cómo puedo incluir en un gráfico series de datos con valores de “x” específico para determinadas series de datos?

El punto de partida es una hoja de cálculo con dos columnas (x,y). A partir de estas dos columnas se calculan otras dos con unos nuevos valores de (x,y).
Necesito representar en una gráfica las dos series de datos cada una con sus valores de x e y.
Utilizo como libro de cabecera el manual de Mauricio Baeza. Siguiendo el ejemplo de la página 353 lo he modificado obteniendo el siguiente código que funciona correctamente:

Código: Seleccionar todo

Sub MainGrf01

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

	opDoc = ThisComponent
	'Referencia a TODAS las hojas del documento
	opHojas = opDoc.getSheets()	' El objeto opHojas contiene todas las hojas de cálculo

	'El nombre de nuestro gráfico
	sNombre = "Grafico01"

'msgbox opHojas(0).Name

	With oRec
		.X = 0			'Distancia desde la izquierda de la hoja
		.Y = 0			'Distancia desde la parte superior
		.Width = 27000		'El ancho del gráfico
		.Height = 21000		'El alto del gráfico
	End With
	'La dirección del rango de datos para el gráfico
	With oDir
		.Sheet = opHojas(0).getRangeAddress.Sheet
		.StartColumn = 0
		.EndColumn = 2
		.StartRow = 3
		.EndRow = 1000
	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 = opHojas(10).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)
		'Accedemos al nuevo gráfico
		oGrafico = oGraficos.getBYName( sNombre ).getEmbeddedObject()
		oGrafico.setDiagram( oGrafico.createInstance("com.sun.star.chart.XYDiagram"))
	End If


End Sub
Intento añadirle series adicionales modificando el rango de datos en los siguientes términos:

Código: Seleccionar todo

Dim mRangos(1)
…
With oDir
		.Sheet = opHojas(0).getRangeAddress.Sheet
		.StartColumn = 0
		.EndColumn = 2
		.StartRow = 3
		.EndRow = 1000
	End With

	mRangos(0) = oDir
…
With oDir
		.Sheet = opHojas(0).getRangeAddress.Sheet
		.StartColumn = 3
		.EndColumn = 4
		.StartRow = 3
		.EndRow = 1000
	End With

	'Es una matriz de rangos, pues se pueden establecer más de uno
	mRangos(1) = oDir
No da error. Genera un gráfico, pero considera la columna 0, como valores de X y las columnas 1, 2 y 3 como tres series diferentes.
Lo que pretendía, y no he conseguido, es considerar una series con las columnas 0 y 1 como valores de x e y, y otra serie con las columnas 2 y 3 como valores de x e y respectivamente.

Muchas gracias por vuestra ayuda

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Vie Nov 13, 2015 2:50 am
por mauricio
¿Lo que quieres es como el siguiente gráfico?
foro.png

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Vie Nov 13, 2015 2:55 pm
por valenteres
Efectivamente.

Aprovecho la ocasión para agradecerte por proporcionarnos el manual

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Sab Nov 14, 2015 2:07 am
por mauricio
La parte de agregar nuevas series lo encontré por aquí: https://forum.openoffice.org/en/forum/v ... =20&t=8991
pero... el código es horrible... veamos...

Abres el archivo que te anexo, ejecutas las macros Graficando y después addDataSerie

Código: Seleccionar todo

 Sub Graficando()
 Dim oHojaActiva As Object
 Dim oSel As Object
 Dim oCursor As Object
 Dim oGraficos As Object
 Dim oGrafico As Object
 Dim mRangos(0) As New com.sun.star.table.CellRangeAddress 
 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()
                           
         sNombre = "GraficoXY"
         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 = True
         End If
     Else
         MsgBox "Selecciona solo una celda con datos"
     End If    
 
End Sub


Sub addDataSerie()
	util = createUnoService("org.universolibre.EasyDev")	
    chart = ThisComponent.getCurrentController.getActiveSheet().getCharts().getByName("GraficoXY").getEmbeddedObject()
	'util.mri(chart)

    ' adding new series
      oDataProvider = chart.getDataProvider()
      oDiagram = chart.getFirstDiagram() ' chart2
      oCooSys = oDiagram.getCoordinateSystems()
      oCoods = oCooSys(0) ' this chart has only a coordinate system
     
      oChartTypes = oCoods.getChartTypes() ' chart type one by one
      oChartType = oChartTypes(0)
     
      ' all data series belongs the chart type
      'oDataSeriesList = oChartType.getDataSeries()
     
      Dim oNewDataSeriesList(2) As Object ' new data series
     
      ' create series
      oSeries1 = CreateDataSeries_XYDiagram(oDataProvider, _
          "Hoja1.A2:A9", "Hoja1.B2:B9", "Hoja1.B1")
      oSeries2 = CreateDataSeries_XYDiagram(oDataProvider, _
          "Hoja1.C2:C9", "Hoja1.D2:D9", "Hoja1.D1")
     
      ' set series properties see com.sun.star.chart2.DataSeries
      oSeries1.Color = 17798
      oSeries2.Color = 16728590
     
      oNewDataSeriesList(0) = oSeries1 ' first one
      oNewDataSeriesList(1) = oSeries2
     
      ' update chart (only the charttype is updated)
      oChartType.setDataSeries(oNewDataSeriesList)

End Sub


' create new series for XYDiagram
' a series has two or more LabeledDataSequence that is named by Label DataSequence.
' oDataProvider: com.sun.star.chart2.data.XDataProvider
' sXRangeRepresentation: X
' sYRangeRepresentation: Y
' sLabelRangeRepresentation: range representation for name of the series
Function CreateDataSeries_XYDiagram( _
    oDataProvider As Object, _
    sXRangeRepresentation As String, _
    sYRangeRepresentation As String, _
    Optional sLabelRangeRepresentation As String ) As Object
 
  Dim oNewDataSeries As Object
  ' create new DataSeries
  oNewDataSeries = CreateUnoService("com.sun.star.chart2.DataSeries")
 
  Dim oData(1) As Object ' x and y: .chart2.data.XLabeledDataSequence
 
  ' Y
  oDataY = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence")
  oSequenceY = CreateDataSequence(oDataProvider, _
      sYRangeRepresentation, "values-y")
  If NOT IsNull(oSequenceY) Then
    oDataY.setValues(oSequenceY)
 
    If NOT ((IsMissing(sLabelRangeRepresentation)) AND _
                      (sLabelRangeRepresentation <> "")) Then
      oSequenceLabel = CreateDataSequence(oDataProvider, _
        sLabelRangeRepresentation, "")
      oDataY.setLabel(oSequenceLabel) ' label is used as name
    End If
  End If
 
  ' X
  oDataX = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence")
  oSequenceX = CreateDataSequence(oDataProvider, _
      sXRangeRepresentation, "values-x")
  If NOT IsNull(oSequenceX) Then
    oDataX.setValues(oSequenceX)
  End If
 
  ' set x and y data to series
  aData = Array(oDataY, oDataX)
  oNewDataSeries.setData(aData)
 
  CreateDataSeries_XYDiagram = oNewDataSeries
End Function


' creat new DataSequence from range representaion
' that provides real data and its role in the series
' oDataProvider: com.sun.star.chart2.data.XDataProvider
' sRangeRepresentation: range address e.g. Sheet1.A1:B2
' sRole: role is defined in com.sun.star.chart2.data.DataSequenceRole
Function CreateDataSequence( _
    oDataProvider As Object, _
    sRangeRepresentation As String, sRole As String ) As Object
 
  Dim oDataSequence As Object
  On Error GoTo Handler
  ' create .chart2.data.DataSequence from range representation
  oDataSequence = oDataProvider._
      createDataSequenceByRangeRepresentation(sRangeRepresentation)
  If NOT IsNull(oDataSequence) Then
    oDataSequence.Role = sRole
  End If
 
  Handler:
    CreateDataSequence = oDataSequence
End Function
Ya que veas lo horrible que es... instalas la versión de desarrollo de EasyDev: https://github.com/UniversoLibreMexicoA ... v2.2.0.oxt
y ejecutas la macro: UsandoEasyDev

Código: Seleccionar todo

Sub UsandoEasyDev()
	Dim pos_size As New com.sun.star.awt.Rectangle
	Dim series(1) As New org.universolibre.EasyDev.ChartSerie
	util = createUnoService("org.universolibre.EasyDev")
	
	address = createUnoStruct("org.universolibre.EasyDev.CellRangeAddress")
	data = createUnoStruct("org.universolibre.EasyDev.ChartData")
	
	doc = ThisComponent
	address.Doc = doc
	
	series(0).X = "Hoja1.A2:A9"
	series(0).Y = "Hoja1.B2:B9"
	series(0).Title = "Hoja1.B1"
	series(0).Color = 17798
	series(1).X = "Hoja1.C2:C9"
	series(1).Y = "Hoja1.D2:D9"
	series(1).Title = "Hoja1.D1"
	series(1).Color = 16728590

	pos_size.X = 0
	pos_size.Y = 5000
	pos_size.Width = 12000
	pos_size.Height = 7000
	
	data.Doc = doc
	data.Sheet = util.getSheet(address)
	data.Name = "Grafico01"
	data.Type = "XYDiagram"
	data.PosSize = pos_size
	data.Series = series
	
	chart = util.chartAdd(data)
	
End Sub
y lo disfrutas...

todavía le faltan detalles, pero funciona muy bien...

Saludos

P.D. Gracias, ese libro tiene miles de descargas y pocos agradecimientos... de nuevo gracias...

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Lun Nov 16, 2015 11:35 pm
por valenteres
Hola Mauricio
Gracias por tu respuesta.
He bajado y ejecutado el archivo que adjuntabas. En "Mis Macros" se ha cargado una librería con el nombre EasyDevLib
He generado una hoja de cálculo con datos en los rangos que utiliza como datos
He lanzado el macro y me da "Error en tiempo de ejecución de BASIC. Variable no definida" cuando llega a la línea correspondiente a la línea "util = createUnoService("org.universolibre.EasyDev")"

No se cual es el problema

Muchas gracia

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mar Nov 17, 2015 12:02 am
por mauricio

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mar Nov 17, 2015 8:28 pm
por valenteres
Problema resuelto. Muchas gracias.

Mi problema es que tenía puesto "Option Explicit" y requería la declaración previa de las variables. Cuando la he puesto como comentario ha funcionado correctamente.

Este desarrollo es "muy amigable", y es de agradecer. Ahora me quedan unas preguntas:
- Los rangos de datos para X, Y, y título están en formato A1:A4. ¿Es posible definirlo por sus índices)
- El color viene identificado por un número. ¿Donde puedo encontrar información sobre la correspondencia entre valor y color?
- En el programa que has adjuntado, en relación a la serie, se define Rangos de datos para X, Y, titulo y color de la serie. No se si tiene la posibilidad de definir otras características como el grosor de la línea. ¿Puedo encontrar en algún sitio un tutorial sobre este extensión?

En cualquier caso muchas gracias por tu ayuda. Me ha sido de gran utilidad

Un saludo

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 1:28 am
por mauricio
valenteres escribió:Este desarrollo es "muy amigable", y es de agradecer
Esa es la idea principal de EasyDev...
valenteres escribió:- Los rangos de datos para X, Y, y título están en formato A1:A4. ¿Es posible definirlo por sus índices)
Si es posible, ahora esta el argumento como "string", puedo cambiarlo a usar una estructura universal que he creado para rangos... esta estructura es versátil y puedes usar tanto nombres como índices... creo que sería un buen cambio y ahora que casi nadie esta usando esta funcionalidad es buen momento...
valenteres escribió: - El color viene identificado por un número. ¿Donde puedo encontrar información sobre la correspondencia entre valor y color?
En la paleta de colores de AOO puedes ver cualquier color y sus valores RGB, después puedes usar estos valores en la función del mismos nombre...
valenteres escribió:- En el programa que has adjuntado, en relación a la serie, se define Rangos de datos para X, Y, titulo y color de la serie. No se si tiene la posibilidad de definir otras características como el grosor de la línea.
Dado que estos valores se pueden editar ya teniendo el gráfico, no considere agregarlos, pero dependiendo de la complejidad que sea cambiarlos después, si puedo considerar agregar estos argumentos...
valenteres escribió:¿Puedo encontrar en algún sitio un tutorial sobre este extensión?
En ingles siempre la más actualizada: http://easydev.readthedocs.org/en/latest/index.html
En español un poco desfasada: http://easydev.readthedocs.org/es/latest/index.html

Saludos

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 7:13 am
por mauricio
Ahora puedes usar rangos como texto y rangos como objeto, el rango lo obtienes previamente como te muestro en el siguiente ejemplo. También desaparece para propiedad Color y se agrega el argumento Properties, de este modo puedes pasar cualquier propiedad, como el ancho de la línea, como puedes ver también en el ejemplo.

Código: Seleccionar todo

Sub GraficandoRangos()
   Dim pos_size As New com.sun.star.awt.Rectangle
   Dim series(1) As New org.universolibre.EasyDev.ChartSerie
   util = createUnoService("org.universolibre.EasyDev")
   
   address = createUnoStruct("org.universolibre.EasyDev.CellRangeAddress")
   data = createUnoStruct("org.universolibre.EasyDev.ChartData")
   
   doc = ThisComponent
   address.Doc = doc
   address.Sheet = "Hoja1"
   address.Col = 0
   address.Row = 1
   address.EndCol = 0
   address.EndRow = 8
   rango_X = util.getRange(address)

   address.Col = 1
   address.EndCol = 1
   rango_Y = util.getRange(address) 

   address.Col = 1
   address.Row = 0
   title_1 = util.getCell(address)
   
   	properties = Array(	_
   		Array("Color", RGB(255,0,0)), _
   		Array("LineWidth", 100), _
   	)     
      
   series(0).X = rango_X
   series(0).Y = rango_Y
   series(0).Title = title_1
   'series(0).Color = 17798
   series(0).Properties = properties

   	properties = Array(	_
   		Array("Color", RGB(255,255,0)), _
   	)
   series(1).X = "Hoja1.C2:C9"
   series(1).Y = "Hoja1.D2:D9"
   series(1).Title = "Hoja1.D1"
   'series(1).Color = 16728590
   series(1).Properties = properties

   pos_size.X = 0
   pos_size.Y = 5000
   pos_size.Width = 12000
   pos_size.Height = 7000
   
   data.Doc = doc
   data.Sheet = util.getSheet(address)
   data.Name = "Grafico01"
   data.Type = "XYDiagram"
   data.PosSize = pos_size
   data.Series = series
   
   chart = util.chartAdd(data)
   
End Sub
Te anexo el archivo de pruebas, y una lista de las propiedades de las series, toma en cuenta que NO puedes aplicarlas todas, algunas requieren estructuras especiales que podemos ir viendo conforme se requiera.

Importante, todo esto esta implementado en la versión 2.3 de desarrollo: https://github.com/UniversoLibreMexicoA ... elop/files
en cuanto lo valides puedo pasarlo a producción...

Saludos

P.D. Como pueden ver, es muy importante su participación para la mejora de EasyDev, además de que es muy lindo cuando se implementan cosas que uno desea...

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 8:29 pm
por valenteres
Buenas tardes de nuevo Mauricio

He instalado la nueva versión que me indicas. Al lanzar los dos macros que me adjuntaste se atasca. El macro que ayer me funcionaba también se atasca. He intentado volver a instalar la versión anterior, pero no me lo permite.

Te adjunto un documento con las capturas de pantalla y los mensajes que presenta en los siguientes casos:
- GraficandoRangos
- UsandoEasyDev
- Al intentar reinstalar la versión 2.2

P.D: He intentado subir el archivo pero no se si lo he conseguido. Voy a Subir adjunto --> Seleccionar archivo --> Agregar archivo. Informa del % de subida pero al final no lo veo. Espero que te llegue. Si no es así, te ruego que me indiques como te lo puedo hacer llegar

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 8:53 pm
por mauricio
Es probable que sobrepasen el tamaño permitido por nuestros foros, o que el nombre sea incompatible, de todos modos es mucho mejor uses un sistema externo de carga de imágenes como: http://imgur.com/
y solo las enlaces en el tema.

Saludos

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 9:04 pm
por valenteres
Espero haberlo echo bien
http://imgur.com/a/HLNv4

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 9:38 pm
por mauricio
Correcto, ya vi el problema... en Python3 todo es unicode, pero no en Python2 que usa AOO... dejame revisarlo...

Saludos

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 10:56 pm
por mauricio
Ahora funciona correctamente en OpenOffice...
foro.png
Por favor, descarga de nuevo la versión de desarrollo y pruebas...

Saludos

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Mié Nov 18, 2015 11:57 pm
por valenteres
Hecho

El macro GraficandoRangos funciona correctamente
El macro UsandoEasyDev da el mismo error de antes.

De momento he probado los dos ejemplos que has enviado. Mañana probaré con series de datos más extensas. Te comentaré los resultados. Muchas gracias

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Jue Nov 19, 2015 12:10 am
por mauricio
No se a que error de antes te refieres... pero esa macro todavía tiene la propiedad Color que hemos eliminado, solo comentala y debe de funcionar.

Código: Seleccionar todo

   series(0).X = "Hoja1.A2:A9"
   series(0).Y = "Hoja1.B2:B9"
   series(0).Title = "Hoja1.B1"
   'series(0).Color = 17798
   series(1).X = "Hoja1.C2:C9"
   series(1).Y = "Hoja1.D2:D9"
   series(1).Title = "Hoja1.D1"
   'series(1).Color = 16728590
Saludos

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Jue Nov 19, 2015 12:12 am
por mauricio
Por cierto, la pregunta de este tema, ha sido resuelta...

Por favor, si tienes más comentarios de EasyDev, por favor, usa este tema: https://forum.openoffice.org/es/forum/v ... 36&t=11236
mejor aun, usa este: https://github.com/UniversoLibreMexicoAC/easydev/issues

Saludos

Re: Problema en definición de series de Gráficos con OOo Bas

Publicado: Jue Nov 19, 2015 10:22 pm
por valenteres
Desde luego que está resuelto y muy satisfactoriamente.
Muchas gracias.
Ahora intentaré cerrarlo como resuelto. Espero hacerlo bien
Repito mi agradecimiento